From 411f89110f2d90cc91333654e7a2270ac4ea8941 Mon Sep 17 00:00:00 2001 From: jl7719 Date: Fri, 4 Dec 2020 23:44:48 +0900 Subject: [PATCH] Add testbench related files --- inputs/addu.txt | 4 ++ inputs/reference.txt | 77 +++++++++++++++++++++++++++++++++ rtl/mips_cpu_memory.v | 2 +- test/test_mips_cpu_harvard.sh | 53 ++++++++++++++++++++++- testbench/mips_cpu_bus_tb.v | 61 ++++++++++++++++++++++++++ testbench/mips_cpu_harvard_tb.v | 51 ++++++++++++++++++++++ 6 files changed, 246 insertions(+), 2 deletions(-) create mode 100644 inputs/addu.txt create mode 100644 inputs/reference.txt create mode 100644 testbench/mips_cpu_bus_tb.v create mode 100644 testbench/mips_cpu_harvard_tb.v diff --git a/inputs/addu.txt b/inputs/addu.txt new file mode 100644 index 0000000..76ae882 --- /dev/null +++ b/inputs/addu.txt @@ -0,0 +1,4 @@ +350C0003 +350D0005 +018D5021 +01000008 \ No newline at end of file diff --git a/inputs/reference.txt b/inputs/reference.txt new file mode 100644 index 0000000..8025d68 --- /dev/null +++ b/inputs/reference.txt @@ -0,0 +1,77 @@ +== Instruction == +C code +Assembly code +Hex code +Reference Output +================ + +== ADDIU Add immediate unsigned (no overflow) == + + + +== ADDU Add unsigned (no overflow) == + +int main(void) { + int a = 3 + 5; +} + +ORI $4,$0,3 +ORI $5,$0,5 +ADDU $2,$4,$5 +JR $0 + +350C0003 +350D0005 +018D5021 +01000008 + +register_vo = 8 + + +== AND Bitwise and == + +ANDI Bitwise and immediate +BEQ Branch on equal +BGEZ Branch on greater than or equal to zero +BGEZAL Branch on non-negative (>=0) and link +BGTZ Branch on greater than zero +BLEZ Branch on less than or equal to zero +BLTZ Branch on less than zero +BLTZAL Branch on less than zero and link +BNE Branch on not equal +DIV Divide +DIVU Divide unsigned +J Jump +JALR Jump and link register +JAL Jump and link +JR Jump register +LB Load byte +LBU Load byte unsigned +LH Load half-word +LHU Load half-word unsigned +LUI Load upper immediate +LW Load word +LWL Load word left +LWR Load word right +MTHI Move to HI +MTLO Move to LO +MULT Multiply +MULTU Multiply unsigned +OR Bitwise or +ORI Bitwise or immediate +SB Store byte +SH Store half-word +SLL Shift left logical +SLLV Shift left logical variable +SLT Set on less than (signed) +SLTI Set on less than immediate (signed) +SLTIU Set on less than immediate unsigned +SLTU Set on less than unsigned +SRA Shift right arithmetic +SRAV Shift right arithmetic +SRL Shift right logical +SRLV Shift right logical variable +SUBU Subtract unsigned +SW Store word +XOR Bitwise exclusive or +XORI Bitwise exclusive or immediate \ No newline at end of file diff --git a/rtl/mips_cpu_memory.v b/rtl/mips_cpu_memory.v index d08390e..15f2f0b 100644 --- a/rtl/mips_cpu_memory.v +++ b/rtl/mips_cpu_memory.v @@ -42,7 +42,7 @@ module mips_cpu_memory( //Load contents from file if specified if (RAM_INIT_FILE != "") begin $display("RAM : INIT : Loading RAM contents from %s", RAM_INIT_FILE); - $readmemh(RAM_INIT_FILE, memory); + $readmemh(RAM_INIT_FILE, memory[3217031168:0]); end end diff --git a/test/test_mips_cpu_harvard.sh b/test/test_mips_cpu_harvard.sh index bee7f43..793c4c3 100644 --- a/test/test_mips_cpu_harvard.sh +++ b/test/test_mips_cpu_harvard.sh @@ -1,4 +1,55 @@ #!/bin/bash # should not create any files in the rtl dir -# but auxiliary files / dirs can be utilised \ No newline at end of file +# but auxiliary files / dirs can be utilised + + +# Source File & Source Directory Parsing +SRC_DIR=${1?Error: no source directory given in argument}; # e.g. ./rtl +SRC=$(ls ${SRC_DIR} | grep -E "harvard|memory|alu|regfile|pc|control"); +SRC_TEMP=""; +for src in ${SRC} +do + SRC_TEMP+=${SRC_DIR}/${src}" "; +done +SRC=${SRC_TEMP} +echo ${SRC} + +# Instruction Argument +INSTR=${2:-"No instruction specified: running all testcases"}; # e.g. addiu +echo ${INSTR}; + +# Start Testing +if [[ ${INSTR} == "No instruction specified: running all testcases" ]]; +then + # All Testcase Files + TESTCASES=$(ls ./inputs | grep ".hex.txt"); + echo ${TESTCASES} + for TESTCASE in ${TESTCASES} + do + # Run Each Testcase File + echo ${TESTCASE} +# iverilog -g 2012 \ +# -s mips_cpu_harvard_tb \ +# -P mips_cpu_harvard_tb.RAM_INIT_FILE=\"inputs/"${TESTCASE}\" \ +# -o program/mips_cpu_harvard_tb_${INSTR} testbench/mips_cpu_harvard_tb.v \ +# ${SRC} + done + +else + echo "ELSE"; + # Run Testcase File Of Specified Instruction +# iverilog -g 2012 \ +# -s mips_cpu_harvard_tb \ +# -P mips_cpu_harvard_tb.RAM_INIT_FILE=\"inputs/${INSTR}.hex.txt\" \ +# -o program/mips_cpu_harvard_tb_${INSTR} testbench/mips_cpu_harvard_tb.v \ +# ${SRC} +fi + +#/mnt/c/Windows/System32/cmd.exe /C \ # need this to run verilog on windows +#iverilog -g 2012 \ +# -s mips_cpu_harvard_tb \ +# -P mips_cpu_harvard_tb.RAM_INIT_FILE=\"inputs/addiu.hex.txt\" \ +# -o program/mips_cpu_harvard_tb testbench/mips_cpu_harvard_tb.v test/mips_cpu_harvard.v \ +# test/mips_cpu_control.v test/mips_cpu_alu.v test/mips_cpu_memory.v test/mips_cpu_regfile.v test/mips_cpu_pc.v + diff --git a/testbench/mips_cpu_bus_tb.v b/testbench/mips_cpu_bus_tb.v new file mode 100644 index 0000000..94ea0fe --- /dev/null +++ b/testbench/mips_cpu_bus_tb.v @@ -0,0 +1,61 @@ +module CPU_MU0_delay1_tb; + timeunit 1ns / 10ps; + + parameter RAM_INIT_FILE = "test/01-binary/countdown.hex.txt"; + parameter TIMEOUT_CYCLES = 10000; + + logic clk; + logic rst; + + logic running; + + logic[11:0] address; + logic write; + logic read; + logic[15:0] writedata; + logic[15:0] readdata; + + RAM_16x4096_delay1 #(RAM_INIT_FILE) ramInst(clk, address, write, read, writedata, readdata); + + CPU_MU0_delay1 cpuInst(clk, rst, running, address, write, read, writedata, readdata); + + // Generate clock + initial begin + clk=0; + + repeat (TIMEOUT_CYCLES) begin + #10; + clk = !clk; + #10; + clk = !clk; + end + + $fatal(2, "Simulation did not finish within %d cycles.", TIMEOUT_CYCLES); + end + + initial begin + rst <= 0; + + @(posedge clk); + rst <= 1; + + @(posedge clk); + rst <= 0; + + @(posedge clk); + assert(running==1) + else $display("TB : CPU did not set running=1 after reset."); + + while (running) begin + @(posedge clk); + end + + $display("TB : finished; running=0"); + + $finish; + + end + + + +endmodule \ No newline at end of file diff --git a/testbench/mips_cpu_harvard_tb.v b/testbench/mips_cpu_harvard_tb.v new file mode 100644 index 0000000..53ae87e --- /dev/null +++ b/testbench/mips_cpu_harvard_tb.v @@ -0,0 +1,51 @@ +module mips_cpu_harvard_tb; + timeunit 1ns / 10ps; + + parameter RAM_INIT_FILE = "inputs/"; + parameter TIMEOUT_CYCLES = 10000; + + logic clk, clk_enable, reset, active; + logic[31:0] register_v0; + logic[31:0] instr_address, instr_readdata; + logic data_read, data_write; + logic[31:0] data_readdata, data_writedata, data_address; + + mips_cpu_memory #(RAM_INIT_FILE) ramInst(clk, data_address, data_write, data_read, data_writedata, data_readdata, instr_address, instr_readdata); + mips_cpu_harvard cpuInst(clk, reset, active, register_v0, clk_enable, instr_address, instr_readdata, data_address, data_write, data_read, data_writedata, data_readdata); + + // Generate clock + initial begin + clk=0; + + repeat (TIMEOUT_CYCLES) begin + #10; + clk = !clk; + #10; + clk = !clk; + end + + $fatal(2, "Simulation did not finish within %d cycles.", TIMEOUT_CYCLES); + end + + initial begin + reset <= 0; + + @(posedge clk); + reset <= 1; + + @(posedge clk); + reset <= 0; + + @(posedge clk); + assert(running==1) + else $display("TB : CPU did not set running=1 after reset."); + + while (running) begin + @(posedge clk); + end + + $display("TB : finished; running=0"); + $finish; + + end +endmodule \ No newline at end of file