diff options
| author | Alejandro Soto <alejandro@34project.org> | 2022-10-16 16:01:47 -0600 |
|---|---|---|
| committer | Alejandro Soto <alejandro@34project.org> | 2022-10-16 16:01:47 -0600 |
| commit | 3aca2967a35d05dac3d9121a882d608b10a588bb (patch) | |
| tree | 25a8d37d6213f518b9ff95ef8b4de30a337a1b2d /tb/top/conspiracion.cpp | |
| parent | 2e6ce7931b690ccec1e41fa6847dfc1351c59d75 (diff) | |
Implement simulation testbenches
Diffstat (limited to 'tb/top/conspiracion.cpp')
| -rw-r--r-- | tb/top/conspiracion.cpp | 157 |
1 files changed, 123 insertions, 34 deletions
diff --git a/tb/top/conspiracion.cpp b/tb/top/conspiracion.cpp index 65e3634..77047e7 100644 --- a/tb/top/conspiracion.cpp +++ b/tb/top/conspiracion.cpp @@ -1,4 +1,8 @@ #include <cstdio> +#include <cstdint> +#include <cstdlib> +#include <iostream> +#include <string> #include <verilated.h> #include <verilated_vcd_c.h> @@ -7,49 +11,102 @@ #include "Vconspiracion_conspiracion.h" #include "Vconspiracion_platform.h" +#include "../args.hxx" + #include "../avalon.hpp" #include "../mem.hpp" +struct mem_region +{ + std::size_t start; + std::size_t length; +}; + + +std::istream &operator>>(std::istream &stream, mem_region ®ion) +{ + stream >> region.start; + stream.get(); + stream >> region.length; + return stream; +} + int main(int argc, char **argv) { using namespace taller::avalon; - Verilated::commandArgs(argc, argv); + Verilated::commandArgs(argc, argv); - Vconspiracion top; + args::ArgumentParser parser("Simulador proyecto final CE3201"); + + args::Flag dump_regs + ( + parser, "dump-regs", "Dump all registers", {"dump-regs"} + ); + + args::ValueFlag<unsigned> cycles + ( + parser, "cycles", "Number of core cycles to run", {"cycles"}, 256 + ); -#ifdef TRACE - Verilated::traceEverOn(true); + args::ValueFlagList<mem_region> dump_mem + ( + parser, "region", "Dump a memory region", {"dump-mem"} + ); + + args::Positional<std::string> image + ( + parser, "image", "Executable image to run", args::Options::Required + ); + + try + { + parser.ParseCLI(argc, argv); + } catch(args::Help) + { + std::cout << parser; + return EXIT_SUCCESS; + } catch(args::ParseError e) + { + std::cerr << e.what() << std::endl; + std::cerr << parser; + return EXIT_FAILURE; + } catch(args::ValidationError e) + { + std::cerr << e.what() << std::endl; + std::cerr << parser; + return EXIT_FAILURE; + } + + Vconspiracion top; VerilatedVcdC trace; - top.trace(&trace, 0); - trace.open("trace.vcd"); -#endif + bool enable_trace = std::getenv("TRACE"); + if(enable_trace) + { + Verilated::traceEverOn(true); + top.trace(&trace, 0); + trace.open("trace.vcd"); + } interconnect<Vconspiracion_platform> avl(*top.conspiracion->plat); mem hps_ddr3(0x0000'0000, 512 << 20); avl.attach(hps_ddr3); - /* mov r0, #69 - * mov r1, #-10 - * loop1: - * tst r1, r1 - * beq loop2 - * add r1, r1, #1 - * sub r0, r0, #1 - * b loop1 - * loop2: - * b loop2 - */ - hps_ddr3.write(0, 0xe3a00045); - hps_ddr3.write(1, 0xe3e01009); - hps_ddr3.write(2, 0xe1110001); - hps_ddr3.write(3, 0x0a000002); - hps_ddr3.write(4, 0xe2811001); - hps_ddr3.write(5, 0xe2400001); - hps_ddr3.write(6, 0xeafffffa); - hps_ddr3.write(7, 0xeafffffe); + FILE *img_file = std::fopen(image->c_str(), "rb"); + if(!img_file) + { + std::perror("fopen()"); + return EXIT_FAILURE; + } + + hps_ddr3.load([&](std::uint32_t *buffer, std::size_t words) + { + return std::fread(buffer, 4, words, img_file); + }); + + std::fclose(img_file); int time = 0; top.clk_clk = 1; @@ -59,9 +116,11 @@ int main(int argc, char **argv) top.clk_clk = !top.clk_clk; top.eval(); avl.tick(top.clk_clk); -#ifdef TRACE - trace.dump(time++); -#endif + + if(enable_trace) + { + trace.dump(time++); + } }; auto cycle = [&]() @@ -70,14 +129,44 @@ int main(int argc, char **argv) tick(); }; - for(int i = 0; i < 256; ++i) + for(unsigned i = 0; i < *cycles; ++i) { cycle(); } -#ifdef TRACE - trace.close(); -#endif + if(enable_trace) + { + trace.close(); + } + + if(dump_regs) + { + std::puts("=== dump-regs ==="); + } + + const auto &dumps = *dump_mem; + if(!dumps.empty()) + { + std::puts("=== dump-mem ==="); + } + + for(const auto &dump : dumps) + { + std::printf("%08x ", dump.start); + for(std::size_t i = 0; i < dump.length; ++i) + { + auto word = avl.dump(dump.start + i); + word = (word & 0xff) << 24 + | ((word >> 8) & 0xff) << 16 + | ((word >> 16) & 0xff) << 24 + | ((word >> 24) & 0xff); + + std::printf("%08x", word); + } + + std::putchar('\n'); + } - top.final(); + top.final(); + return EXIT_SUCCESS; } |
