diff --git a/rtl/instruction.v b/rtl/instruction.v index ceb281f..1d39e10 100644 --- a/rtl/instruction.v +++ b/rtl/instruction.v @@ -1,7 +1,7 @@ module instruction (input [31:0] address, output [31:0] instruction); - reg [7:0] memory [127:0]; + reg [7:0] memory [1024:0]; assign instruction = {memory[address + 3], memory[address + 2], memory[address + 1], memory[address]}; diff --git a/scripts/run_test.sh b/scripts/run_test.sh index 724891c..ca60b9a 100755 --- a/scripts/run_test.sh +++ b/scripts/run_test.sh @@ -36,8 +36,7 @@ run_test () if [ -z $2 ]; then - # display only if line contains '[FAIL]' or '[PASS]' - vsim -c -do "do simu.do; quit -f" >& /dev/null # | tr -cd '[:print:]\t\n' | print_result # print_result #| sed -n 's/^# \(.*\[FAIL\|\PASS\].*\)/\1/p' + vsim -c -do "do simu.do; quit -f" >& /dev/null else vsim -do "do simu.do" fi @@ -49,7 +48,6 @@ print_result () { while read line; do if [[ $line = *"# Errors: "* ]]; then - # Errors: 0, Warnings: 0 - get only the number of errors if [ $(echo "$line" | sed 's/^# Errors: \([[:digit:]]*\).*/\1/') -ne 0 ]; then cat ./transcript return 1 diff --git a/tb/tb_risc_v_cpu-dyn.v b/tb/tb_risc_v_cpu-dyn.v index 733d621..b9b4216 100644 --- a/tb/tb_risc_v_cpu-dyn.v +++ b/tb/tb_risc_v_cpu-dyn.v @@ -88,21 +88,24 @@ module tb_risc_v_cpu (); begin res = $fscanf(code_file_inputs, "%d:%d=%d\n", instruction_addr, reg_number, reg_test_value); if (res != 3) begin // If fscanf failed, the test file structure is wrong, then exit - $display("Parsing test file failed"); - $finish; - end + res = $fgetc(code_file_inputs); // Check if the file is empty + if (!$feof(code_file_inputs)) begin + $display("Parsing test file failed"); + $finish; + end + end else begin + instruction_addr = instruction_addr / 4; - instruction_addr = instruction_addr / 4; - - if (test[instruction_addr][5:0] == 6'b111111) begin - test[instruction_addr][5:0] = reg_number; - test[instruction_addr][37:6] = reg_test_value; - end else if (test[instruction_addr][43:38] == 6'b111111) begin - test[instruction_addr][43:38] = reg_number; - test[instruction_addr][75:44] = reg_test_value; - end else if (test[instruction_addr][81:76] == 6'b111111) begin - test[instruction_addr][81:76] = reg_number; - test[instruction_addr][113:83] = reg_test_value; + if (test[instruction_addr][5:0] == 6'b111111) begin + test[instruction_addr][5:0] = reg_number; + test[instruction_addr][37:6] = reg_test_value; + end else if (test[instruction_addr][43:38] == 6'b111111) begin + test[instruction_addr][43:38] = reg_number; + test[instruction_addr][75:44] = reg_test_value; + end else if (test[instruction_addr][81:76] == 6'b111111) begin + test[instruction_addr][81:76] = reg_number; + test[instruction_addr][113:83] = reg_test_value; + end end end @@ -110,7 +113,7 @@ module tb_risc_v_cpu (); /* Run The Program */ - for (i = 0; i < 100; i = i + 1) begin + for (i = 0; i < 200; i = i + 1) begin if (test[risc_v_cpu.program_counter.pc_addr / 4][5:0] != 6'b111111) begin curent_addr = risc_v_cpu.program_counter.pc_addr / 4; `next_cycle @@ -157,16 +160,19 @@ module tb_risc_v_cpu (); begin res = $fscanf(code_file_inputs, "%d=%d\n", reg_number, reg_test_value); if (res != 2) begin // If fscanf failed, the test file structure is wrong, then exit - $display("Parsing test file failed"); - $finish; - end - - if (reg_number < 6'b100000) begin - `assert_no_wait_reg("FINAL", 1'bx, reg_number, reg_test_value, risc_v_cpu.registers_bank.registers[reg_number[4:0]]) - end else if (reg_number == 6'b100000) begin - `assert_no_wait_pc("FINAL", 1'bx, reg_test_value, risc_v_cpu.program_counter.pc_addr) - end else if (reg_number > 6'b100000) begin - `assert_no_wait_mem("FINAL", 1'bx, reg_number, reg_test_value, risc_v_cpu.memory.memory[test[curent_addr][5:0]]) + res = $fgetc(code_file_inputs); // Check if the file is empty + if (!$feof(code_file_inputs)) begin + $display("Parsing test file failed"); + $finish; + end + end else begin + if (reg_number < 6'b100000) begin + `assert_no_wait_reg("FINAL", 1'bx, reg_number, reg_test_value, risc_v_cpu.registers_bank.registers[reg_number[4:0]]) + end else if (reg_number == 6'b100000) begin + `assert_no_wait_pc("FINAL", 1'bx, reg_test_value, risc_v_cpu.program_counter.pc_addr) + end else if (reg_number > 6'b100000) begin + `assert_no_wait_mem("FINAL", 1'bx, reg_number, reg_test_value, risc_v_cpu.memory.memory[test[curent_addr][5:0]]) + end end end diff --git a/tb/test_source_code/tb_risc_v_cpu/loop.S b/tb/test_source_code/tb_risc_v_cpu/loop.S new file mode 100644 index 0000000..32b531e --- /dev/null +++ b/tb/test_source_code/tb_risc_v_cpu/loop.S @@ -0,0 +1,22 @@ +/* + * 0:zero, 1:ra, 2:sp, 3:gp, 4:tp, 5:t0-2, 8:s0/fp + * 9:s1, 10:a0-7, 18:s2-11, 28:t3-6 + */ + +li t0, 0 # R[5]=0 +li t1, 10 # R[6]=10 +loop_pos_start: +bge t0, t1, loop_pos_end +addi t0, t0, 1 +j loop_pos_start +loop_pos_end: + +li a0, 10 # R[10]=10 +loop_neg_start: +ble a0, zero, loop_neg_end +addi a0, a0, -1 +j loop_neg_start +loop_neg_end: + +# R[5]=10 +# R[10]=0 diff --git a/tb/test_source_code/tb_risc_v_cpu/multiplication.S b/tb/test_source_code/tb_risc_v_cpu/multiplication.S new file mode 100644 index 0000000..62bce31 --- /dev/null +++ b/tb/test_source_code/tb_risc_v_cpu/multiplication.S @@ -0,0 +1,63 @@ +/* + * 0:zero, 1:ra, 2:sp, 3:gp, 4:tp, 5:t0-2, 8:s0/fp + * 9:s1, 10:a0-7, 18:s2-11, 28:t3-6 + */ + +j test + +mult: +li a0, 0 +li a2, 1 +mult_loop_start: +blt t1, a2, mult_loop_end +and a1, t1, 1 +beq a1, zero, mult_even_compute +add a0, a0, t2 +mult_even_compute: +add t2, t2, t2 +srl t1, t1, 1 +j mult_loop_start +mult_loop_end: +jalr ra, t0, 0 + +test: +li t1, 0 +li t2, 0 +jal t0, mult +nop # R[10]=0 +li t1, 0 +li t2, 1 +jal t0, mult +nop # R[10]=0 +li t1, 1 +li t2, 0 +jal t0, mult +nop # R[10]=0 +li t1, 1 +li t2, 1 +jal t0, mult +nop # R[10]=1 +li t1, 2 +li t2, 1 +jal t0, mult +nop # R[10]=2 +li t1, 1 +li t2, 3 +jal t0, mult +nop # R[10]=3 +li t1, 2 +li t2, 2 +jal t0, mult +nop # R[10]=4 +li t1, 2 +li t2, 3 +jal t0, mult +nop # R[10]=6 +li t1, 5 +li t2, 3 +jal t0, mult +nop # R[10]=15 +li t1, 5 +li t2, 25 +jal t0, mult +nop # R[10]=125