diff options
| author | Alejandro Soto <alejandro@34project.org> | 2022-10-18 02:35:40 -0600 |
|---|---|---|
| committer | Alejandro Soto <alejandro@34project.org> | 2022-10-18 02:35:40 -0600 |
| commit | 41623edcae09bc6e4db8df3e166a20149f88db18 (patch) | |
| tree | 03ff822401b1e9aac9fb9c4c5b2ea7bbfe34ffa9 /tb | |
| parent | e81d84541c048deb4bafc7549e3feefc20482daa (diff) | |
Implement register initialization in sim
Diffstat (limited to '')
| -rwxr-xr-x | tb/sim/sim.py | 32 | ||||
| -rw-r--r-- | tb/top/conspiracion.cpp | 121 |
2 files changed, 113 insertions, 40 deletions
diff --git a/tb/sim/sim.py b/tb/sim/sim.py index 135192a..3f95c34 100755 --- a/tb/sim/sim.py +++ b/tb/sim/sim.py @@ -153,17 +153,26 @@ def test_assert(condition, message): exit(success=False) +def unsigned(n): + assert -0x8000_0000 <= n <= 0xffff_ffff + return n + 0x1_0000_0000 if n < 0 else n + +def int_bytes(n): + return n.to_bytes(4, 'little', signed=n < 0) if type(n) is int else n + def assert_reg(r, expected): actual = read_reg(r) + expected = unsigned(expected) + test_assert( \ actual == expected, \ lambda: f'register {r} = 0x{actual:08x}, expected 0x{expected:08x}') def assert_mem(base, value): - if type(value) is int: - value = value.to_bytes(4, 'little') - elif type(value) is list: - value = b''.join(w.to_bytes(4, 'little') if type(w) is int else w for w in value) + if type(value) is list: + value = b''.join(int_bytes(w) for w in value) + else: + value = int_bytes(value) actual = read_mem(base, len(value)) test_assert( \ @@ -172,11 +181,19 @@ def assert_mem(base, value): f'Memory at 0x{base:08x} holds:\n{hexdump(base, actual)}\n' + \ f'But this was expected instead:\n{hexdump(base, value)}') +init_regs = {} + +def init_reg(r, value): + global init_regs + assert init_regs is not None + init_regs[r] = unsigned(value) + prelude = { 'read_reg': read_reg, 'read_mem': read_mem, 'assert_reg': assert_reg, 'assert_mem': assert_mem, + 'init_reg': init_reg } prelude.update({k: v for k, v in all_regs}) @@ -188,6 +205,9 @@ module_get = lambda attr, default=None: getattr(module, attr, default) cycles = module_get('cycles', 1024) mem_dumps = module_get('mem_dumps', []) +if init := module_get('init'): + init() + exec_args = [verilated, '--cycles', str(cycles), '--dump-regs'] for rng in mem_dumps: @@ -197,6 +217,10 @@ for rng in mem_dumps: exec_args.extend(['--dump-mem', f'{rng.start >> 2},{length >> 2}']) +for r, value in init_regs.items(): + exec_args.extend(['--init-reg', f'{r}={value}']) + +init_regs = None exec_args.append(image) output = subprocess.run(exec_args, stdout=subprocess.PIPE, text=True) diff --git a/tb/top/conspiracion.cpp b/tb/top/conspiracion.cpp index 2408ecc..851aaa2 100644 --- a/tb/top/conspiracion.cpp +++ b/tb/top/conspiracion.cpp @@ -1,6 +1,7 @@ #include <cstdio> #include <cstdint> #include <cstdlib> +#include <cstring> #include <iostream> #include <string> @@ -21,54 +22,90 @@ namespace { + constexpr const char *gp_regs[30] = + { + [0] = "r0", + [1] = "r1", + [2] = "r2", + [3] = "r3", + [4] = "r4", + [5] = "r5", + [6] = "r6", + [7] = "r7", + [8] = "r8_usr", + [9] = "r9_usr", + [10] = "r10_usr", + [11] = "r11_usr", + [12] = "r12_usr", + [13] = "r13_usr", + [14] = "r14_usr", + [15] = "r8_fiq", + [16] = "r9_fiq", + [17] = "r10_fiq", + [18] = "r11_fiq", + [19] = "r12_fiq", + [20] = "r13_fiq", + [21] = "r14_fiq", + [22] = "r13_irq", + [23] = "r14_irq", + [24] = "r13_und", + [25] = "r14_und", + [26] = "r13_abt", + [27] = "r14_abt", + [28] = "r13_svc", + [29] = "r14_svc", + }; + struct mem_region { std::size_t start; std::size_t length; }; + struct reg_init + { + std::size_t index; + std::uint32_t value; + }; std::istream &operator>>(std::istream &stream, mem_region ®ion) { stream >> region.start; - stream.get(); - stream >> region.length; + if(stream.get() == ',') + { + stream >> region.length; + } else + { + stream.setstate(std::istream::failbit); + } + return stream; } - constexpr const char *gp_regs[30] = + std::istream &operator>>(std::istream &stream, reg_init &init) { - [0] = "0", - [1] = "1", - [2] = "2", - [3] = "3", - [4] = "4", - [5] = "5", - [6] = "6", - [7] = "7", - [8] = "8_usr", - [9] = "9_usr", - [10] = "10_usr", - [11] = "11_usr", - [12] = "12_usr", - [13] = "13_usr", - [14] = "14_usr", - [15] = "8_fiq", - [16] = "9_fiq", - [17] = "10_fiq", - [18] = "11_fiq", - [19] = "12_fiq", - [20] = "13_fiq", - [21] = "14_fiq", - [22] = "13_irq", - [23] = "14_irq", - [24] = "13_und", - [25] = "14_und", - [26] = "13_abt", - [27] = "14_abt", - [28] = "13_svc", - [29] = "14_svc", - }; + char name[16]; + stream.getline(name, sizeof name, '='); + + std::size_t index = 0; + constexpr auto total_gp_regs = sizeof gp_regs / sizeof gp_regs[0]; + + while(index < total_gp_regs && std::strcmp(name, gp_regs[index])) + { + ++index; + } + + if(stream && !stream.eof() && index < total_gp_regs) + { + init.index = index; + stream >> init.value; + } else + { + stream.setstate(std::istream::failbit); + } + + return stream; + } } int main(int argc, char **argv) @@ -79,6 +116,11 @@ int main(int argc, char **argv) args::ArgumentParser parser("Simulador proyecto final CE3201"); + args::ValueFlagList<reg_init> init_regs + ( + parser, "reg=val", "Initialize a register", {"init-reg"} + ); + args::Flag dump_regs ( parser, "dump-regs", "Dump all registers", {"dump-regs"} @@ -91,7 +133,7 @@ int main(int argc, char **argv) args::ValueFlagList<mem_region> dump_mem ( - parser, "region", "Dump a memory region", {"dump-mem"} + parser, "addr,length", "Dump a memory region", {"dump-mem"} ); args::Positional<std::string> image @@ -148,6 +190,13 @@ int main(int argc, char **argv) std::fclose(img_file); + for(const auto &init : init_regs) + { + auto ®s = *top.conspiracion->core->regs; + regs.a->file[init.index] = init.value; + regs.b->file[init.index] = init.value; + } + int time = 0; top.clk_clk = 1; @@ -188,7 +237,7 @@ int main(int argc, char **argv) int i = 0; for(const auto *name : gp_regs) { - std::printf("%08x r%s\n", regfile[i++], name); + std::printf("%08x %s\n", regfile[i++], name); } } |
