diff --git a/scripts/gen_test.py b/scripts/gen_test.py new file mode 100644 index 0000000..d578d28 --- /dev/null +++ b/scripts/gen_test.py @@ -0,0 +1,71 @@ +import re + +source_code = open('test.S', 'r') +Lines = source_code.readlines() +test_file = [] + +def get_test(test, instr_addr, final = False): + result = "" + + pattern_r = re.compile(r'R\[(\d+)\]=(\d+)') + pattern_pc = re.compile(r'PC=(\d+)') + pattern_mem = re.compile(r'MEM\[(\d+)\]=(\d+)') + + # Use the patterns to search for matches in the input string + match_r = pattern_r.search(test) + match_pc = pattern_pc.search(test) + match_mem = pattern_mem.search(test) + + if match_r: + number1 = match_r.group(1) + number2 = match_r.group(2) + result = f"{number1}={number2}" + elif match_pc: + number_pc = match_pc.group(1) + result = f"32={number_pc}" + elif match_mem: + number1_mem = match_mem.group(1) + number2_mem = match_mem.group(2) + result = f"{int(number1_mem) + 33}={number2_mem}" + + if result != "" and not final: + result = f"{instr_addr}:{result}" + + return result + +instr_addr = 0 +for line in Lines: + if line.isspace() or ':' in line or line[0] == '#': + continue + elif '#' in line: + tests = re.split(r'\s|,', line[line.find('#') + 1:]) + for test in tests: + new_test = get_test(test, instr_addr) + if new_test != "": + test_file.append(new_test) + instr_addr += 4 + + +# save test_file to a file named test.tmp +with open('test.tmp', 'w') as f: + for item in test_file: + f.write("%s\n" % item) + +final_test_file = [] +# go through Line in reverse order +for line in reversed(Lines): + if line.isspace() or ':' in line: + continue + elif line[0] == '#': + tests = re.split(r'\s|,', line[1:]) + for test in tests: + new_test = get_test(test, instr_addr, True) + if new_test != "": + final_test_file.append(new_test) + else: + break + +# save test_file to a file named test.tmp +with open('test.final.tmp', 'w') as f: + for item in final_test_file: + f.write("%s\n" % item) diff --git a/tb/tb_risc_v_cpu-dyn.v b/tb/tb_risc_v_cpu-dyn.v index abbd224..c6fe5d3 100644 --- a/tb/tb_risc_v_cpu-dyn.v +++ b/tb/tb_risc_v_cpu-dyn.v @@ -9,11 +9,20 @@ module tb_risc_v_cpu (); /* File management variable */ integer bin_file_inputs; + integer code_file_inputs; reg [8:0] read_instruction_1; reg [8:0] read_instruction_2; reg [8:0] read_instruction_3; reg [8:0] read_instruction_4; + reg [113:0] test [0:100]; + integer instruction_addr; + reg [5:0] reg_number; + reg [31:0] reg_test_value; + integer curent_addr; + integer res; + reg [8:0] dump; + risc_v_cpu risc_v_cpu ( .clock(clk), .reset(reset), @@ -33,7 +42,7 @@ module tb_risc_v_cpu (); /* Loading Binary File */ bin_file_inputs = $fopen("./../tb/test_source_code/tb_riscv_cpu/test.bin", "r"); if (bin_file_inputs == 0) begin - $display("data_file handle was NULL"); + $display("bin file handle was NULL"); $finish; end @@ -60,13 +69,107 @@ module tb_risc_v_cpu (); end end - for (i = 0; i < 100; i = i + 1) begin - `next_cycle - // run + $fclose(bin_file_inputs); + + /* Extract Value to Test From File */ + code_file_inputs = $fopen("./../tb/test_source_code/tb_riscv_cpu/test.tmp", "r"); + if (code_file_inputs == 0) begin + $display("source code file handle was NULL"); + $finish; end - // final test - `assert_no_wait("FOR LOOP - REG[5]: 1", risc_v_cpu.registers_bank.registers[5], 32'b1010) + i = 0; + for (i = 0; i < 100; i = i + 1) begin // Fill test data structure of 1, + test[i] = {114{1'b1}}; // to represent the empty state + end + + while (!$feof(code_file_inputs)) + 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 + + $display ("Line %d: %d:%b=%b ]", res, instruction_addr, reg_number, 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 + $display ("1"); + 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 + + $fclose(code_file_inputs); + + /* Run The Program */ + + for (i = 0; i < 100; i = i + 1) begin + if (test[risc_v_cpu.program_counter.pc_addr][5:0] != 6'b111111) begin + curent_addr = risc_v_cpu.program_counter.pc_addr; + `next_cycle + if (test[curent_addr][5:0] != 6'b111111) begin + if (test[curent_addr][5:0] < 6'b100000) begin + `assert_no_wait("TEST - REG", risc_v_cpu.registers_bank.registers[test[curent_addr][4:0]], test[curent_addr][37:6]) + end else if (test[curent_addr][5:0] == 6'b100000) begin + `assert_no_wait("TEST - PC", risc_v_cpu.program_counter.pc_addr, test[curent_addr][37:6]) + end else if (test[curent_addr][5:0] > 6'b100000) begin + `assert_no_wait("TEST - MEM", risc_v_cpu.memory.memory[test[curent_addr][5:0]], test[curent_addr][37:6]) + end + end + if (test[curent_addr][43:38] != 6'b111111) begin + if (test[curent_addr][43:38] < 6'b100000) begin + `assert_no_wait("TEST - REG", risc_v_cpu.registers_bank.registers[test[curent_addr][42:38]], test[curent_addr][75:44]) + end else if (test[curent_addr][43:38] == 6'b100000) begin + `assert_no_wait("TEST - PC", risc_v_cpu.program_counter.pc_addr, test[curent_addr][75:44]) + end else if (test[curent_addr][43:38] > 6'b100000) begin + `assert_no_wait("TEST - MEM", risc_v_cpu.memory.memory[test[curent_addr][43:38]], test[curent_addr][75:44]) + end + end + if (test[curent_addr][81:76] != 6'b111111) begin + if (test[curent_addr][81:76] < 6'b100000) begin + `assert_no_wait("TEST - REG", risc_v_cpu.registers_bank.registers[test[curent_addr][80:76]], test[curent_addr][81:76]) + end else if (test[curent_addr][81:76] == 6'b100000) begin + `assert_no_wait("TEST - PC", risc_v_cpu.program_counter.pc_addr, test[curent_addr][113:83]) + end else if (test[curent_addr][81:76] > 6'b100000) begin + `assert_no_wait("TEST - MEM", risc_v_cpu.memory.memory[test[curent_addr][81:76]], test[curent_addr][81:76]) + end + end + end + else + `next_cycle + end + + /* Test State After Execution */ + code_file_inputs = $fopen("./../tb/test_source_code/tb_riscv_cpu/test.final.tmp", "r"); + if (code_file_inputs == 0) begin + $display("source code file handle was NULL"); + $finish; + end + + while (!$feof(code_file_inputs)) + begin + res = $fscanf(code_file_inputs, "%d=%d\n", reg_number, reg_test_value); + $display ("Line %d: %b=%b ]", res, 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("FINAL TEST - REG", risc_v_cpu.registers_bank.registers[reg_number[4:0]], reg_test_value) + end else if (reg_number == 6'b100000) begin + `assert_no_wait("FINAL TEST- PC", risc_v_cpu.program_counter.pc_addr, reg_test_value) + end else if (reg_number > 6'b100000) begin + `assert_no_wait("FINAL TEST - MEM", risc_v_cpu.memory.memory[test[curent_addr][5:0]], reg_test_value) + end + end `end_message end diff --git a/tb/test_source_code/tb_riscv_cpu/test.S b/tb/test_source_code/tb_riscv_cpu/test.S index bc689e5..e6a95ce 100644 --- a/tb/test_source_code/tb_riscv_cpu/test.S +++ b/tb/test_source_code/tb_riscv_cpu/test.S @@ -1,9 +1,11 @@ # t0 = 0 li t0, 0 -li t2, 10 +li t2, 10 # R[2]=10, MEM[1]=6 loop_head: bge t0, t2, loop_end # Repeated code goes here -addi t0, t0, 1 +addi t0, t0, 1 # PC=16 j loop_head -loop_end: \ No newline at end of file +loop_end: + +# R[0]=0