summaryrefslogtreecommitdiff
path: root/tb/top/conspiracion.cpp
diff options
context:
space:
mode:
authorAlejandro Soto <alejandro@34project.org>2022-10-16 16:01:47 -0600
committerAlejandro Soto <alejandro@34project.org>2022-10-16 16:01:47 -0600
commit3aca2967a35d05dac3d9121a882d608b10a588bb (patch)
tree25a8d37d6213f518b9ff95ef8b4de30a337a1b2d /tb/top/conspiracion.cpp
parent2e6ce7931b690ccec1e41fa6847dfc1351c59d75 (diff)
Implement simulation testbenches
Diffstat (limited to '')
-rw-r--r--tb/top/conspiracion.cpp157
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 &region)
+{
+ 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;
}