summaryrefslogtreecommitdiff
path: root/tb/top
diff options
context:
space:
mode:
authorJulianCamacho <jjulian.341@gmail.com>2022-11-07 23:35:46 -0600
committerJulianCamacho <jjulian.341@gmail.com>2022-11-07 23:35:46 -0600
commit942461c315db3269fcbe9a9ca18beee9afa78d9c (patch)
tree5a1d3e325c5c489166569d83a3e2715a6146b284 /tb/top
parent6f08b7251f57778bd32f3cc2d44ddba63492cac8 (diff)
Añade testbench para fetch y decode
Diffstat (limited to 'tb/top')
-rw-r--r--tb/top/decode_test.cpp86
-rw-r--r--tb/top/fetch_test.cpp166
2 files changed, 234 insertions, 18 deletions
diff --git a/tb/top/decode_test.cpp b/tb/top/decode_test.cpp
index 14af035..09f973e 100644
--- a/tb/top/decode_test.cpp
+++ b/tb/top/decode_test.cpp
@@ -15,9 +15,68 @@ int main(int argc, char** argv) {
top.trace(&trace, 0);
trace.open("decode_test.vcd");
- unsigned long instructions[3] = {3766898695,
- 3825578010,
- 3120562179};
+ // sim/control_flow.c
+ uint32_t rom[] =
+ {
+ 0xea000032,
+ 0xea000034,
+ 0xea000000,
+ 0xeafffffe,
+ 0xeafffffe,
+ 0xeafffffe,
+ 0xeafffffe,
+ 0xe3500000,
+ 0xda000001,
+ 0xe3a00001,
+ 0xe1a0f00e,
+ 0x13e00000,
+ 0x03a00000,
+ 0xe1a0f00e,
+ 0xe1a02000,
+ 0xe92d4010,
+ 0xe1a00002,
+ 0xebfffff4,
+ 0xe1a03000,
+ 0xe1a00001,
+ 0xebfffff1,
+ 0xe0933000,
+ 0x0a00000c,
+ 0xe3730001,
+ 0x0a00000e,
+ 0xe3530001,
+ 0x0a00000a,
+ 0xe1a038a1,
+ 0xe1a00502,
+ 0xe1833601,
+ 0xe02023c2,
+ 0xe0831001,
+ 0xe1520001,
+ 0xcaffffed,
+ 0xe0820001,
+ 0xe8bd8010,
+ 0xe1a02822,
+ 0xe1822801,
+ 0xe1a00f62,
+ 0xe8bd8010,
+ 0xe3500000,
+ 0xda000002,
+ 0xe1a02001,
+ 0xe2611001,
+ 0xeafffff2,
+ 0xe1e02001,
+ 0xe1a00002,
+ 0xebffffd6,
+ 0xe3500000,
+ 0xdaffffed,
+ 0xe1a01002,
+ 0xeafffff5,
+ 0xe59fd008,
+ 0xebffffd7,
+ 0xeafffffe,
+ 0xeafffffe,
+ 0x20000000,
+ };
+
top.n = 0;
top.z = 0;
top.c = 0;
@@ -26,25 +85,16 @@ int main(int argc, char** argv) {
int clk_tick = 0;
int time = 0;
- for(int i = 0; i < sizeof(instructions); ++i)
+ for(int i = 0; i < sizeof(rom)/sizeof(rom[0]); ++i)
{
- top.insn = instructions[i];
- top.n = 0;
- top.z = 0;
- top.c = 0;
- top.v = 0;
+ top.insn = rom[i];
top.eval();
trace.dump(time++);
-
- std::printf(" [%c%c%c%c]\n",
- top.n ? 'N' : 'n',
- top.z ? 'Z' : 'z',
- top.c ? 'C' : 'c',
- top.v ? 'V' : 'v');
-
- std::printf("insn=%d, ctrl=%d",
- instructions[i], top.ctrl);
+
+ std::printf("insn=0x%08x, ctrl=0x%08x\n",
+ rom[i], top.ctrl);
+
}
trace.close();
diff --git a/tb/top/fetch_test.cpp b/tb/top/fetch_test.cpp
new file mode 100644
index 0000000..65124ea
--- /dev/null
+++ b/tb/top/fetch_test.cpp
@@ -0,0 +1,166 @@
+#include <cstdio>
+
+#include <verilated.h>
+#include <verilated_vcd_c.h>
+
+#include "Vfetch_test.h" // From Verilating "top.v"
+
+int main(int argc, char** argv) {
+ Verilated::commandArgs(argc, argv); // Remember args
+ Verilated::traceEverOn(true);
+
+ Vfetch_test top;
+ VerilatedVcdC trace;
+
+ top.trace(&trace, 0);
+ trace.open("fetch_test.vcd");
+
+ top.clk = 0;
+ top.stall = 0; //insn y insn_pc se detienen
+ top.branch = 0; //forma de flush -> instr saltan a la instr de la branch
+ top.flush = 0; //limpia prefetch
+ top.fetched = 1; //estado del fetch (ready)
+ top.wr_pc = 0; //cuando hay un write al pc
+ top.branch_target = 0; //direccion a la que se hace salto
+ top.wr_current = 0; //ultimo que se guardo en registros
+ top.fetch_data = 0x00000000; //data que se leyó al hacer fetch
+
+ uint32_t rom[] =
+ {
+ 0xea000032,
+ 0xea000034,
+ 0xea000000,
+ 0xeafffffe,
+ 0xeafffffe,
+ 0xeafffffe,
+ 0xeafffffe,
+ 0xe3500000,
+ 0xda000001,
+ 0xe3a00001,
+ 0xe1a0f00e,
+ 0x13e00000,
+ 0x03a00000,
+ 0xe1a0f00e,
+ 0xe1a02000,
+ 0xe92d4010,
+ 0xe1a00002,
+ 0xebfffff4,
+ 0xe1a03000,
+ 0xe1a00001,
+ 0xebfffff1,
+ 0xe0933000,
+ 0x0a00000c,
+ 0xe3730001,
+ 0x0a00000e,
+ 0xe3530001,
+ 0x0a00000a,
+ 0xe1a038a1,
+ 0xe1a00502,
+ 0xe1833601,
+ 0xe02023c2,
+ 0xe0831001,
+ 0xe1520001,
+ 0xcaffffed,
+ 0xe0820001,
+ 0xe8bd8010,
+ 0xe1a02822,
+ 0xe1822801,
+ 0xe1a00f62,
+ 0xe8bd8010,
+ 0xe3500000,
+ 0xda000002,
+ 0xe1a02001,
+ 0xe2611001,
+ 0xeafffff2,
+ 0xe1e02001,
+ 0xe1a00002,
+ 0xebffffd6,
+ 0xe3500000,
+ 0xdaffffed,
+ 0xe1a01002,
+ 0xeafffff5,
+ 0xe59fd008,
+ 0xebffffd7,
+ 0xeafffffe,
+ 0xeafffffe,
+ 0x20000000,
+ };
+
+ int clk_tick = 0;
+ int time = 0;
+
+ std::printf("CPU cycle:\n");
+ while (time < 50)
+ {
+ top.eval();
+ trace.dump(time++);
+
+ if(!top.clk)
+ {
+ std::printf("insn=0x%08x, insn_pc=0x%08x, addr=0x%08x\n",
+ top.insn, top.insn_pc, top.addr);
+ }
+
+ top.clk = !top.clk;
+
+ top.fetch_data = rom[top.addr];
+ }
+
+ std::printf("Branch, flush, stall:\n");
+ while (time < 99)
+ {
+ top.eval();
+ trace.dump(time++);
+
+ if(!top.clk)
+ {
+ std::printf("insn=0x%08x, insn_pc=0x%08x, addr=0x%08x\n",
+ top.insn, top.insn_pc, top.addr);
+ }
+
+ top.clk = !top.clk;
+
+ if(time == 55)
+ {
+ std::printf("Se hace un branch:\n");
+ top.branch = 1;
+ top.branch_target = 3;
+ }
+
+ if(time == 59)
+ {
+ std::printf("Se termina el branch:\n");
+ top.branch = 0;
+
+ }
+
+ if(time == 63){
+ std::printf("Se hace un flush:\n");
+ top.branch = 0;
+ top.branch_target = 0;
+ top.flush = 1;
+ }
+
+ if(time == 69){
+ std::printf("Se termina el flush:\n");
+ top.flush = 0;
+ }
+
+ if(time == 75)
+ {
+ std::printf("Se hace un stall:\n");
+ top.stall = 1;
+ }
+
+ if(time == 81)
+ {
+ std::printf("Se termina el stall:\n");
+ top.stall = 0;
+ }
+
+ top.fetch_data = rom[top.addr];
+ }
+
+ trace.close();
+ top.final(); // Done simulating
+}