diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 5b8c14d..cf22066 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -63,6 +63,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 + - run: make git.vhdl - uses: docker://ghdl/vunit:llvm with: args: python3 ./run.py -p10 diff --git a/.gitignore b/.gitignore index 0bb079e..d6da201 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,4 @@ litesdcard/build/* obj_dir/* /scripts/mw_debug/urjtag /scripts/mw_debug/mw_debug +git.vhdl diff --git a/Makefile b/Makefile index 794cbc1..6ab9efc 100644 --- a/Makefile +++ b/Makefile @@ -55,6 +55,11 @@ all = core_tb icache_tb dcache_tb dmi_dtm_tb \ all: $(all) +# This updates git.vhdl only when needed. Make runs this before doing +# dependancy checks hence make will only rebuild dependancies if the +# git status has actually changed. +$(shell scripts/make_version.sh git.vhdl) + core_files = decode_types.vhdl common.vhdl wishbone_types.vhdl fetch1.vhdl \ utils.vhdl plru.vhdl cache_ram.vhdl icache.vhdl predecode.vhdl \ decode1.vhdl helpers.vhdl insn_helpers.vhdl \ @@ -66,7 +71,7 @@ core_files = decode_types.vhdl common.vhdl wishbone_types.vhdl fetch1.vhdl \ soc_files = wishbone_arbiter.vhdl wishbone_bram_wrapper.vhdl sync_fifo.vhdl \ wishbone_debug_master.vhdl xics.vhdl syscon.vhdl gpio.vhdl soc.vhdl \ - spi_rxtx.vhdl spi_flash_ctrl.vhdl + spi_rxtx.vhdl spi_flash_ctrl.vhdl git.vhdl uart_files = $(wildcard uart16550/*.v) @@ -324,6 +329,7 @@ _clean: rm -f scripts/mw_debug/mw_debug rm -f microwatt.bin microwatt.json microwatt.svf microwatt_out.config rm -f microwatt.v microwatt-verilator + rm -f git.vhdl rm -rf obj_dir/ clean: _clean diff --git a/git.vhdl.in b/git.vhdl.in new file mode 100644 index 0000000..1130bb1 --- /dev/null +++ b/git.vhdl.in @@ -0,0 +1,9 @@ +library ieee; +use ieee.std_logic_1164.all; + +library work; + +package git is + constant GIT_HASH : std_ulogic_vector(55 downto 0) := x"@hash@"; + constant GIT_DIRTY : std_ulogic := '@dirty@'; +end git; diff --git a/include/microwatt_soc.h b/include/microwatt_soc.h index b138be1..ab55287 100644 --- a/include/microwatt_soc.h +++ b/include/microwatt_soc.h @@ -58,6 +58,8 @@ #define SYS_REG_UART0_INFO 0x40 #define SYS_REG_UART1_INFO 0x48 #define SYS_REG_UART_IS_16550 (1ull << 32) +#define SYS_REG_GIT_INFO 0x50 +#define SYS_REG_GIT_IS_DIRTY (1ull << 63) /* diff --git a/microwatt.core b/microwatt.core index 07085b1..5e603f1 100644 --- a/microwatt.core +++ b/microwatt.core @@ -51,6 +51,7 @@ filesets: - sync_fifo.vhdl - spi_rxtx.vhdl - spi_flash_ctrl.vhdl + - git.vhdl file_type : vhdlSource-2008 fpga: @@ -136,6 +137,7 @@ targets: nexys_a7: default_tool: vivado filesets: [core, nexys_a7, soc, fpga, debug_xilinx, uart16550, xilinx_specific] + generate: [git_hash] parameters : - memory_size - ram_init_file @@ -153,6 +155,7 @@ targets: acorn-cle-215-nodram: default_tool: vivado filesets: [core, acorn_cle_215, soc, fpga, debug_xilinx, uart16550, xilinx_specific] + generate: [git_hash] parameters : - memory_size - ram_init_file @@ -179,6 +182,7 @@ targets: - spi_flash_offset=10485760 - log_length=2048 - uart_is_16550=false + generate: [git_hash] tools: vivado: {part : xc7k325tffg900-2} toplevel : toplevel @@ -195,7 +199,7 @@ targets: - spi_flash_offset=10485760 - log_length=2048 - uart_is_16550 - generate: [litedram_acorn_cle_215] + generate: [litedram_acorn_cle_215, git_hash] tools: vivado: {part : xc7a200tsbg484-2} toplevel : toplevel @@ -212,7 +216,7 @@ targets: - spi_flash_offset=10485760 - log_length=2048 - uart_is_16550=false - generate: [litedram_genesys2] + generate: [litedram_genesys2, git_hash] tools: vivado: {part : xc7k325tffg900-2} toplevel : toplevel @@ -231,6 +235,7 @@ targets: - uart_is_16550 - has_fpu - has_btc + generate: [git_hash] tools: vivado: {part : xc7a200tsbg484-1} toplevel : toplevel @@ -251,7 +256,7 @@ targets: - uart_is_16550 - has_fpu - has_btc - generate: [litedram_nexys_video, liteeth_nexys_video, litesdcard_nexys_video] + generate: [litedram_nexys_video, liteeth_nexys_video, litesdcard_nexys_video, git_hash] tools: vivado: {part : xc7a200tsbg484-1} toplevel : toplevel @@ -272,6 +277,7 @@ targets: - has_fpu=false - has_btc=false - use_litesdcard + generate: [git_hash] tools: vivado: {part : xc7a35ticsg324-1L} toplevel : toplevel @@ -293,7 +299,7 @@ targets: - has_uart1 - has_fpu=false - has_btc=false - generate: [litedram_arty, liteeth_arty, litesdcard_arty] + generate: [litedram_arty, liteeth_arty, litesdcard_arty, git_hash] tools: vivado: {part : xc7a35ticsg324-1L} toplevel : toplevel @@ -314,6 +320,7 @@ targets: - has_fpu - has_btc - use_litesdcard + generate: [git_hash] tools: vivado: {part : xc7a100ticsg324-1L} toplevel : toplevel @@ -335,7 +342,7 @@ targets: - has_uart1 - has_fpu - has_btc - generate: [litedram_arty, liteeth_arty, litesdcard_arty] + generate: [litedram_arty, liteeth_arty, litesdcard_arty, git_hash] tools: vivado: {part : xc7a100ticsg324-1L} toplevel : toplevel @@ -356,7 +363,7 @@ targets: - uart_is_16550 - has_fpu - has_btc - generate: [litesdcard_wukong-v2] + generate: [litesdcard_wukong-v2, git_hash] tools: vivado: {part : xc7a100tfgg676-1} toplevel : toplevel @@ -377,7 +384,7 @@ targets: - uart_is_16550 - has_fpu - has_btc - generate: [litedram_wukong-v2, liteeth_wukong-v2, litesdcard_wukong-v2] + generate: [litedram_wukong-v2, liteeth_wukong-v2, litesdcard_wukong-v2, git_hash] tools: vivado: {part : xc7a100tfgg676-1} toplevel : toplevel @@ -396,17 +403,26 @@ targets: - uart_is_16550 - has_fpu=false - has_btc=false + generate: [git_hash] tools: vivado: {part : xc7a35tcpg236-1} toplevel : toplevel synth: filesets: [core, soc, xilinx_specific] + generate: [git_hash] tools: vivado: {pnr : none} toplevel: core +generators: + git_hash_gen: + command: scripts/make_version_fusesoc.py + generate: + git_hash: + generator : git_hash_gen + litedram_arty: generator: litedram_gen parameters: {board : arty} diff --git a/scripts/make_version.sh b/scripts/make_version.sh new file mode 100755 index 0000000..9725a5a --- /dev/null +++ b/scripts/make_version.sh @@ -0,0 +1,43 @@ +#!/bin/bash +# +# This script builds a git.vhdl which contains info on the SHA1 and +# dirty status of your git tree. It always builds but only replaces +# the file if it's changed. This way we can use Makefile $(shell ..) +# to build it which happens before make does it's dependancy checks. +# + +dirty="0" +version="00000000000000" + +usage() { + echo "$0 " + echo -e "\tSubstitute @hash@ and @dirty@ in with gathered values." +} + +src=$1 + +if test -e .git || git rev-parse --is-inside-work-tree > /dev/null 2>&1; +then + version=$(git describe --exact-match 2>/dev/null) + if [ -z "$version" ]; + then + version=$(git describe 2>/dev/null) + fi + if [ -z "$version" ]; + then + version=$(git rev-parse --verify --short=14 HEAD 2>/dev/null) + fi + if git diff-index --name-only HEAD |grep -qv '.git'; + then + dirty="1" + fi +# echo "hash=$version dirty=$dirty" +fi + +# Put it in a temp file and only update if it's change. This helps Make +sed -e "s/@hash@/$version/" -e "s/@dirty@/$dirty/" ${src}.in > ${src}.tmp +if diff -q ${src}.tmp ${src} >/dev/null 2>&1; then + rm ${src}.tmp +else + mv ${src}.tmp ${src} +fi diff --git a/scripts/make_version_fusesoc.py b/scripts/make_version_fusesoc.py new file mode 100755 index 0000000..d00bf40 --- /dev/null +++ b/scripts/make_version_fusesoc.py @@ -0,0 +1,15 @@ +#!/usr/bin/env python +# +# Simple wrapper around make_version.sh that fusesoc needs +# Just pulls out the files_root from yaml so we know where to run. +# + +import yaml +import sys +import os + +with open(sys.argv[1], 'r') as stream: + data = yaml.safe_load(stream) + +# Run make version in source dir so we can get the git version +os.system("cd %s; scripts/make_version.sh git.vhdl" % data["files_root"]) diff --git a/syscon.vhdl b/syscon.vhdl index 5e6cb00..727f4e7 100644 --- a/syscon.vhdl +++ b/syscon.vhdl @@ -4,6 +4,7 @@ use ieee.std_logic_1164.all; use ieee.numeric_std.all; library work; +use work.git.all; use work.wishbone_types.all; entity syscon is @@ -53,6 +54,7 @@ architecture behaviour of syscon is constant SYS_REG_SPIFLASHINFO : std_ulogic_vector(SYS_REG_BITS-1 downto 0) := "000111"; constant SYS_REG_UART0_INFO : std_ulogic_vector(SYS_REG_BITS-1 downto 0) := "001000"; constant SYS_REG_UART1_INFO : std_ulogic_vector(SYS_REG_BITS-1 downto 0) := "001001"; + constant SYS_REG_GIT_INFO : std_ulogic_vector(SYS_REG_BITS-1 downto 0) := "001010"; -- Muxed reg read signal signal reg_out : std_ulogic_vector(63 downto 0); @@ -91,6 +93,12 @@ architecture behaviour of syscon is -- 32 : UART is 16550 (otherwise pp) -- + -- GIT info register bits + -- + -- 0 ..55 : git hash (14 chars = 56 bits) + -- 63 : dirty flag + -- + -- Ctrl register signal reg_ctrl : std_ulogic_vector(SYS_REG_CTRL_BITS-1 downto 0); signal reg_ctrl_out : std_ulogic_vector(63 downto 0); @@ -104,6 +112,7 @@ architecture behaviour of syscon is signal reg_spiinfo : std_ulogic_vector(63 downto 0); signal reg_uart0info : std_ulogic_vector(63 downto 0); signal reg_uart1info : std_ulogic_vector(63 downto 0); + signal reg_gitinfo : std_ulogic_vector(63 downto 0); signal info_has_dram : std_ulogic; signal info_has_bram : std_ulogic; signal info_has_uart : std_ulogic; @@ -169,6 +178,11 @@ begin 31 downto 0 => uinfo_freq, others => '0'); + -- GIT info register composition + reg_gitinfo <= (63 => GIT_DIRTY, + 55 downto 0 => GIT_HASH, + others => '0'); + -- Wishbone response wb_rsp.ack <= wishbone_in.cyc and wishbone_in.stb; with wishbone_in.adr(SYS_REG_BITS downto 1) select reg_out <= @@ -182,6 +196,7 @@ begin reg_spiinfo when SYS_REG_SPIFLASHINFO, reg_uart0info when SYS_REG_UART0_INFO, reg_uart1info when SYS_REG_UART1_INFO, + reg_gitinfo when SYS_REG_GIT_INFO, (others => '0') when others; wb_rsp.dat <= reg_out(63 downto 32) when wishbone_in.adr(0) = '1' else reg_out(31 downto 0);