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/hello_world/Makefile b/hello_world/Makefile index dd51bd3..159cb86 100644 --- a/hello_world/Makefile +++ b/hello_world/Makefile @@ -25,7 +25,8 @@ hello_world.bin: hello_world.elf $(OBJCOPY) -O binary $^ $@ hello_world.hex: hello_world.bin - ../scripts/bin2hex.py $^ > $@ + ../scripts/bin2hex.py $^ > hello_world.hex.tmp + mv -f hello_world.hex.tmp hello_world.hex clean: @rm -f *.o hello_world.elf hello_world.bin hello_world.hex diff --git a/hello_world/hello_world.bin b/hello_world/hello_world.bin index a4eb88c..4c1a800 100755 Binary files a/hello_world/hello_world.bin and b/hello_world/hello_world.bin differ diff --git a/hello_world/hello_world.c b/hello_world/hello_world.c index 0f08631..c3769e1 100644 --- a/hello_world/hello_world.c +++ b/hello_world/hello_world.c @@ -2,24 +2,46 @@ #include #include "console.h" +#include "io.h" +#include "microwatt_soc.h" -static char mw_logo[] = - +static char mw_logo1[] = "\n" " .oOOo. \n" " .\" \". \n" " ; .mw. ; Microwatt, it works.\n" " . ' ' . \n" -" \\ || / \n" +" \\ || / HDL Git SHA1: "; + +static char mw_logo2[] = +"\n" " ;..; \n" " ;..; \n" -" `ww' \n"; +" `ww' \n\n"; int main(void) { + uint64_t gitinfo; + uint8_t c; + bool dirty; + console_init(); - puts(mw_logo); + puts(mw_logo1); + + gitinfo = readq(SYSCON_BASE + SYS_REG_GIT_INFO); + dirty = gitinfo >> 63; + for (int i = 0; i < 14; i++) { + c = (gitinfo >> 52) & 0xf; + if (c >= 10) + putchar(0x61 + c - 10); // a-f + else + putchar(0x30 + c); // 0-9 + gitinfo <<= 4; + } + if (dirty) + puts("-dirty"); + puts(mw_logo2); while (1) { unsigned char c = getchar(); diff --git a/hello_world/hello_world.elf b/hello_world/hello_world.elf index 3dc0cc1..90747e6 100755 Binary files a/hello_world/hello_world.elf and b/hello_world/hello_world.elf differ diff --git a/hello_world/hello_world.hex b/hello_world/hello_world.hex index c0161ad..3bc5166 100644 --- a/hello_world/hello_world.hex +++ b/hello_world/hello_world.hex @@ -48,11 +48,11 @@ a64b5a7d14004a39 782107c660210000 6021398064210000 f801ffe138000000 -3d8000007c1243a6 -798c07c6618c0000 -618c1000658c0000 -4e8004217d8903a6 -4800000000000200 +618c00003d800000 +658c0000798c07c6 +7d8903a6618c1000 +000002004e800421 +0000000048000000 0000000000000000 0000000000000000 0000000000000000 @@ -511,172 +511,172 @@ f801ffe138000000 0000000000000000 0000000000000000 384298003c400001 -fbe1fff87c0802a6 -f821ffd1f8010010 -60000000480001ed +4800042d7c0802a6 +3fe0c000f821ffc1 +7bff002063ff0050 +6000000048000269 +3862803060000000 +60000000480001d1 +7fe0feea7c0004ac +7bfd0fe03bc0000e +280300097be36720 +386300574081007c +7bff26e47c6307b4 +6000000048000119 +4082ffdc37deffff +418200142c3d0000 +38637c303c62ffff +6000000048000181 3862800060000000 -6000000048000155 -6000000048000049 +6000000048000171 +6000000048000051 5463063e7c7f1b78 -480000b957ff063e +480000cd57ff063e 2c1f000d60000000 3860000a4082ffe0 -60000000480000a5 -000000004bffffd0 -0000018001000000 +60000000480000b9 +386300304bffffd0 +000000004bffff88 +0000038001000000 384298003c400001 8922810860000000 3942810060000000 -418200302c090000 +418200382c090000 39290014e92a0000 7d204eaa7c0004ac 4182ffec71290001 -7c0004ace86a0000 -5463063e7c601eaa +e862810060000000 +7c601eaa7c0004ac +7c6307b45463063e e92a00004e800020 7c0004ac39290010 712900017d204eea -e86a00004082ffec -7c0004ac38630008 -4bffffd07c601eea -0000000000000000 -3c40000100000000 -6000000038429800 -6000000089228108 -2c09000039428100 -e92a00004182002c -7c0004ac39290014 -712900207d204eaa -e92a00004182ffec +600000004082ffec +38630008e8628100 +7c601eea7c0004ac +000000004bffffc8 +0000000000000000 +384298003c400001 +8922810860000000 +3942810060000000 +418200302c090000 +39290014e92a0000 +7d204eaa7c0004ac +4182ffec71290020 +e922810060000000 7c604faa7c0004ac e92a00004e800020 7c0004ac39290010 712900087d204eea 5469063e4082ffec -7c0004ace94a0000 -4e8000207d2057ea -0000000000000000 -3c40000100000000 -7c0802a638429800 -fbc1fff0fbe1fff8 -f80100103be3ffff -8fdf0001f821ffd1 -408200102c3e0000 -3860000038210030 -281e000a480001e8 -3860000d4082000c -7fc3f3784bffff45 -4bffffd04bffff3d -0100000000000000 -7c691b7800000280 -7d4918ae38600000 -4d8200202c0a0000 -4bfffff038630001 -0000000000000000 -3c40000100000000 -3d40c00038429800 -794a0020614a0020 -7d4056ea7c0004ac -794a06003d20c000 -7929002061290008 -7d204eea7c0004ac -4182001871290020 -612900403d20c000 +e942810060000000 +7d2057ea7c0004ac +000000004e800020 +0000000000000000 +384298003c400001 +fbe1fff87c0802a6 +3be3fffffbc1fff0 +f821ffd1f8010010 +2c1e00008fdf0001 +3821003040820010 +4800022038600000 +4082000c2c1e000a +4bffff3d3860000d +4bffff357fc307b4 +000000004bffffd0 +0000028001000000 +386000007c691b78 +2c0a00007d4918ae +386300014d820020 +000000004bfffff0 +0000000000000000 +384298003c400001 +612900203d20c000 7c0004ac79290020 -7929f8047d204eea -79290fc33d00c000 -7908002061082000 -f902810060000000 -610820003d00001c -418200847d4a4392 -3920000160000000 -3d00c00099228108 -3920ff806108200c -7c0004ac79080020 -e92281007d2047aa -7d404faa7c0004ac -794ac202e9228100 -7c0004ac39290004 +3d40c0007d204eea +614a000879290600 +7c0004ac794a0020 +714a00207d4056ea +614a20003d40c000 +40820040794a0020 +f942810060000000 +6000000039400000 +3d40001c99428108 +7d295392614a2000 +614a20183d40c000 +3929ffff794a0020 +7d2057ea7c0004ac +3d00c0004e800020 +7908002061080040 +7d0046ea7c0004ac +60000000790807e3 +3d40001cf9428100 +7d495392614a2000 +600000004182ffa0 +9922810839200001 +6108200c3d00c000 +790800203920ff80 +7d2047aa7c0004ac +7c0004ace9228100 e92281007d404faa -3929000c39400003 +39290004794ac202 7d404faa7c0004ac -39290010e9228100 +39400003e9228100 +7c0004ac3929000c +e92281007d404faa +7c0004ac39290010 +e92281007d404faa +3929000839400007 7d404faa7c0004ac -39400007e9228100 -7c0004ac39290008 -4e8000207d404faa -394affff60000000 -3d20c00099228108 -7929002061292018 -7d404fea7c0004ac 000000004e800020 0000000000000000 384298003c400001 8922810860000000 600000002c090000 -41820024e9228100 -78840e282c230000 -6084000141820008 -7c0004ac39290004 -4e8000207c804faa -418200082c240000 -3929002060630002 -7c604fea7c0004ac -000000004e800020 -0000000000000000 -e8010010ebc1fff0 -7c0803a6ebe1fff8 -000000104e800020 -00527a0100000000 -00010c1b01417804 -0000001800000018 -00000070fffffc40 -9f7e4111300e4600 -0000001000000001 -00527a0100000000 -00010c1b01417804 -0000001800000010 -00000084fffffc80 -0000001000000000 -fffffcf00000002c -0000000000000080 -0000004000000028 -00000060fffffd5c -9e019f0041094500 -447e4111300e4302 -4106dedf42000e0a -000000100000000b -fffffd900000006c -0000000000000028 -0000008000000010 -0000012cfffffda4 +41820028e9228100 +5484083c2c230000 +418200087c8a2378 +39290004608a0001 +7d404faa7c0004ac +2c2400004e800020 +6063000241820008 +7c0004ac39290020 +4e8000207c604fea +0000000000000000 +6000000000000000 +000079747269642d +fbc1fff0fba1ffe8 +f8010010fbe1fff8 +ebc1fff04e800020 +ebe1fff8e8010010 +4e8000207c0803a6 +0000000000000010 +0141780400527a01 +0000002000010c1b +fffffb8400000018 +41094300000000e0 +019f029e039d4100 +0000400e417e4111 +0000000000000010 +0141780400527a01 +0000001000010c1b +fffffc2c00000018 +0000000000000090 +0000002c00000010 +00000088fffffca8 +0000002800000000 +fffffd1c00000040 +4109450000000060 +300e43029e019f00 +42000e0a447e4111 +0000000b4106dedf +0000006c00000010 +00000028fffffd50 0000001000000000 -fffffebc00000094 -0000000000000068 -0000000000000000 -0000000000000000 -0000000000000000 -0000000000000000 -0000000000000000 -0000000000000000 -0000000000000000 -0000000000000000 -0000000000000000 -0000000000000000 -0000000000000000 -0000000000000000 -0000000000000000 -0000000000000000 -0000000000000000 -0000000000000000 -0000000000000000 -0000000000000000 -0000000000000000 -0000000000000000 -0000000000000000 -0000000000000000 -0000000000000000 -0000000000000000 +fffffd6400000080 +0000000000000140 +0000009400000010 +0000006cfffffe90 0000000000000000 0000000000000000 0000000000000000 @@ -766,6 +766,12 @@ fffffebc00000094 0000000000000000 0000000000000000 0000000000000000 +2e2e3b202020200a +0a2020202020203b +3b2e2e3b20202020 +200a202020202020 +2027777760202020 +000a0a2020202020 4f4f6f2e2020200a 0a20202020202e6f 2020202020222e20 @@ -777,9 +783,6 @@ fffffebc00000094 27202027202e2020 200a202020202e20 2f207c7c205c2020 -2020200a20202020 -2020203b2e2e3b20 -202020200a202020 -202020203b2e2e3b -60202020200a2020 -000a202020277777 +4c44482020202020 +4148532074694720 +0000000000203a31 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);