From 6ee3e16559316e358832d06ba1040edc84ae581e Mon Sep 17 00:00:00 2001 From: ChUrl Date: Thu, 30 Mar 2023 16:29:07 +0200 Subject: [PATCH] Implement a CPU TestBench --- CPU.qsf | 10 ++-- CPU_TestBench.sv | 151 ++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 155 insertions(+), 6 deletions(-) diff --git a/CPU.qsf b/CPU.qsf index 72584f6..05ebc80 100644 --- a/CPU.qsf +++ b/CPU.qsf @@ -39,7 +39,7 @@ set_global_assignment -name FAMILY "Cyclone V" set_global_assignment -name DEVICE 5CGXFC5C6F27C7 -set_global_assignment -name TOP_LEVEL_ENTITY CPU +set_global_assignment -name TOP_LEVEL_ENTITY CPU_TestBench set_global_assignment -name ORIGINAL_QUARTUS_VERSION 20.1.1 set_global_assignment -name PROJECT_CREATION_TIME_DATE "11:27:08 MäRZ 23, 2023" set_global_assignment -name LAST_QUARTUS_VERSION "20.1.1 Lite Edition" @@ -104,14 +104,10 @@ set_global_assignment -name EDA_DESIGN_INSTANCE_NAME NA -section_id Decoder_Test set_global_assignment -name EDA_TEST_BENCH_MODULE_NAME Decoder_TestBench -section_id Decoder_TestBench set_global_assignment -name SYSTEMVERILOG_FILE Decoder.sv set_global_assignment -name SYSTEMVERILOG_FILE Decoder_TestBench.sv -set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top -set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top -set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top set_global_assignment -name SYSTEMVERILOG_FILE CPU_TestBench.sv set_global_assignment -name EDA_TEST_BENCH_NAME CPU_TestBench -section_id eda_simulation set_global_assignment -name EDA_DESIGN_INSTANCE_NAME NA -section_id CPU_TestBench set_global_assignment -name EDA_TEST_BENCH_MODULE_NAME CPU_TestBench -section_id CPU_TestBench -set_global_assignment -name EDA_TEST_BENCH_FILE CPU_TestBench.sv -section_id CPU_TestBench set_global_assignment -name EDA_TEST_BENCH_FILE ALU_TestBench.sv -section_id ALU_TestBench set_global_assignment -name EDA_TEST_BENCH_FILE LogicalUnit_TestBench.sv -section_id LogicalUnit_TestBench set_global_assignment -name EDA_TEST_BENCH_FILE ArithmeticUnit_TestBench.sv -section_id ArithmeticUnit_TestBench @@ -119,4 +115,8 @@ set_global_assignment -name EDA_TEST_BENCH_FILE ConditionalUnit_TestBench.sv -se set_global_assignment -name EDA_TEST_BENCH_FILE RegisterFile_TestBench.sv -section_id RegisterFile_TestBench set_global_assignment -name EDA_TEST_BENCH_FILE Counter_TestBench.sv -section_id Counter_TestBench set_global_assignment -name EDA_TEST_BENCH_FILE Decoder.sv -section_id Decoder_TestBench +set_global_assignment -name EDA_TEST_BENCH_FILE CPU_TestBench.sv -section_id CPU_TestBench +set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top +set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top +set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top \ No newline at end of file diff --git a/CPU_TestBench.sv b/CPU_TestBench.sv index 073aa83..82f2b03 100644 --- a/CPU_TestBench.sv +++ b/CPU_TestBench.sv @@ -1 +1,150 @@ -`default_nettype none \ No newline at end of file +`default_nettype none + +module CPU_TestBench; + + var logic enable, clock, reset; + var logic[7:0] cpuin; + tri[7:0] cpuout; + + // Debug connections + tri ftch, decd, exec, wrtb; + tri[7:0] pc, rom, saveb, loadb, jmpt, aluA, aluB, aluR; + + CPU cpu( + .enable(enable), + .clock(clock), + .reset(reset), + .cpuin(cpuin), + .cpuout(cpuout), + + .dbg_fetch(ftch), + .dbg_decode(decd), + .dbg_execute(exec), + .dbg_writeback(wrtb), + .dbg_pcout(pc), + .dbg_romout(rom), + .dbg_savebus(saveb), + .dbg_loadbus(loadb), + .dbg_jumptarget(jmpt), + .dbg_aluopA(aluA), + .dbg_aluopB(aluB), + .dbg_aluresult(aluR) + ); + + // TODO: Move the disabled stuff to a separate testbench + // TODO: Move this to a ROM specific testbench, allow creating other ROM specific testbenches + // NOTE: This testbench is written for the Input/Output ROM + +// synthesis translate_off + integer ii; + initial begin + $timeformat(-9, 2, " ns", 20); + + $display("%0t Initial Reset", $time); + enable = 1'b0; + clock = 1'b0; + #20 reset = 1'b1; + #20 reset = 1'b0; + assert(cpuout == 8'b0); + + // $display("%0t Disabled CPU with Clock", $time); + // for (ii = 0; ii < 4; ii = ii + 1) begin + // #20 clock = 1'b1; + // #20 clock = 1'b0; + // assert(ftch == 1'b0); + // assert(decd == 1'b0); + // assert(exec == 1'b0); + // assert(wrtb == 1'b0); + // end + + $display("%0t Enable CPU", $time); + #20 enable = 1'b1; + #20 cpuin = 8'b00000101; + + // $display("%0t Clock => Fetch 1", $time); + // #20 clock = 1'b1; + // #20 clock = 1'b0; + // assert(ftch == 1'b1); + // assert(decd == 1'b0); + // assert(exec == 1'b0); + // assert(wrtb == 1'b0); + + // $display("%0t Clock => Decode 1", $time); + // #20 clock = 1'b1; + // #20 clock = 1'b0; + // assert(ftch == 1'b0); + // assert(decd == 1'b1); + // assert(exec == 1'b0); + // assert(wrtb == 1'b0); + + // $display("%0t Clock => Execute 1", $time); + // #20 clock = 1'b1; + // #20 clock = 1'b0; + // assert(ftch == 1'b0); + // assert(decd == 1'b0); + // assert(exec == 1'b1); + // assert(wrtb == 1'b0); + + // $display("%0t Clock => Writeback 1", $time); + // #20 clock = 1'b1; + // #20 clock = 1'b0; + // assert(ftch == 1'b0); + // assert(decd == 1'b0); + // assert(exec == 1'b0); + // assert(wrtb == 1'b1); + + // Next CPU cycle (reg1 = cpuin) + $display("%0t reg1 (aluA) = cpuin", $time); + for (ii = 0; ii < 4; ii = ii + 1) begin + #20 clock = 1'b1; + #20 clock = 1'b0; + end + assert(aluA == 8'b00000101); + + // Next CPU cycle (reg0 = 10) + $display("%0t reg0 (jmpt) = 00001010", $time); + for (ii = 0; ii < 4; ii = ii + 1) begin + #20 clock = 1'b1; + #20 clock = 1'b0; + end + assert(jmpt == 8'b00001010); + assert(aluA == 8'b00000101); + + // Next CPU cycle (reg2 = reg0) + $display("%0t reg2 (aluB) = reg0 (jmpt)", $time); + for (ii = 0; ii < 4; ii = ii + 1) begin + #20 clock = 1'b1; + #20 clock = 1'b0; + end + assert(jmpt == 8'b00001010); + assert(aluA == 8'b00000101); + assert(aluB == 8'b00001010); + + // Next CPU cycle (reg3 = reg1 + reg2) + $display("%0t reg3 (aluR) = reg1 (aluA) + reg2 (aluB)", $time); + for (ii = 0; ii < 4; ii = ii + 1) begin + #20 clock = 1'b1; + #20 clock = 1'b0; + end + assert(jmpt == 8'b00001010); + assert(aluA == 8'b00000101); + assert(aluB == 8'b00001010); + assert(aluR == 8'b00001111); + + // Next CPU cycle (cpuout = reg3) + $display("%0t cpuout = reg3 (aluR)", $time); + for (ii = 0; ii < 4; ii = ii + 1) begin + #20 clock = 1'b1; + #20 clock = 1'b0; + end + assert(jmpt == 8'b00001010); + assert(aluA == 8'b00000101); + assert(aluB == 8'b00001010); + assert(aluR == 8'b00001111); + assert(cpuout == 8'b00001111); + + $display("Success!"); + end +// synthesis translate_on + +endmodule \ No newline at end of file