diff options
author | Flavian Kaufmann <flavian@flaviankaufmann.ch> | 2024-05-05 11:35:00 +0200 |
---|---|---|
committer | Flavian Kaufmann <flavian@flaviankaufmann.ch> | 2024-05-05 11:35:00 +0200 |
commit | 38e4966386672acc92834246c85c97cd0be80314 (patch) | |
tree | 2458a9c21feba8dbfc5eac0f55585a10ed9abf77 | |
parent | 8d5d730269cc94fa8d5caed0e1996e3d94be25d1 (diff) | |
download | riscv_cpu-38e4966386672acc92834246c85c97cd0be80314.tar.gz riscv_cpu-38e4966386672acc92834246c85c97cd0be80314.zip |
register file testbench
-rw-r--r-- | gentestvec/gentestvec_register_file.c | 4 | ||||
-rw-r--r-- | sim/testbench_register_file.v | 104 | ||||
-rw-r--r-- | src/register_file.v | 17 |
3 files changed, 114 insertions, 11 deletions
diff --git a/gentestvec/gentestvec_register_file.c b/gentestvec/gentestvec_register_file.c index 2533772..a9ff1c5 100644 --- a/gentestvec/gentestvec_register_file.c +++ b/gentestvec/gentestvec_register_file.c @@ -14,9 +14,9 @@ void write_reg(uint32_t addr, uint32_t data, bool we) { void test(uint32_t addr_rs0, uint32_t addr_rs1, uint32_t addr_rd2, uint32_t data_rd2, bool we) { - write_reg(addr_rd2, data_rd2, we); uint32_t data_rs0 = read_reg(addr_rs0); uint32_t data_rs1 = read_reg(addr_rs1); + write_reg(addr_rd2, data_rd2, we); printf("%08X_%08X__%08X_%08X__%08X_%08X_%01X\n", addr_rs0, data_rs0, addr_rs1, data_rs1, addr_rd2, data_rd2, we); } @@ -43,6 +43,6 @@ int main(int argc, const char *argv[]) { for (int i = 0; i < 32; ++i) test(i, i, i, 0xffffffff, true); - tests(1000); + tests(10000); return 0; } diff --git a/sim/testbench_register_file.v b/sim/testbench_register_file.v new file mode 100644 index 0000000..093a624 --- /dev/null +++ b/sim/testbench_register_file.v @@ -0,0 +1,104 @@ +`timescale 1ns / 1ps + +module testbench_register_file(); + +reg clk; +reg rst; +reg we; +reg [4:0] addr_rs0, addr_rs1, addr_rd2; +reg [31:0] data_rd2; +wire [31:0] data_rs0, data_rs1; + + +register_file uut ( + .clk(clk), + .rst(rst), + .we(we), + .addr_rs0(addr_rs0), + .addr_rs1(addr_rs1), + .addr_rd2(addr_rd2), + .data_rs0(data_rs0), + .data_rs1(data_rs1), + .data_rd2(data_rd2) +); + +integer file, r, eof; +reg [100*8:1] line; +reg [31:0] test_count, error_count; + +reg [31:0] expected_data_rs0, expected_data_rs1; + +always #5 clk = ~clk; + +reg [1023:0] testvec_filename; +reg [1023:0] waveform_filename; + +initial begin + if ($value$plusargs("testvec=%s", testvec_filename)) begin + $display("Using test vector file: %s", testvec_filename); + end else begin + $display("Error: no test vector file specified."); + $finish; + end + + if ($value$plusargs("waveform=%s", waveform_filename)) begin + $display("Using waveform file: %s", waveform_filename); + end else begin + $display("Error: no waveform file specified."); + $finish; + end +end + + initial begin + $dumpfile(waveform_filename); + $dumpvars(0,testbench_register_file); + end + + +initial begin + clk = 0; + rst = 0; + we = 0; + addr_rs0 = 0; + addr_rs1 = 0; + addr_rd2 = 0; + data_rd2 = 0; + + test_count = 0; + error_count = 0; + + rst = 1; + @(posedge clk); + rst = 0; + + file = $fopen(testvec_filename, "r"); + if (file == 0) begin + $display("Failed to open testvector file."); + $finish; + end + + while (!$feof(file)) begin + eof = $fgets(line, file); + eof = $sscanf(line, "%8h_%8h__%8h_%8h__%8h_%8h_%1h", + addr_rs0, expected_data_rs0, + addr_rs1, expected_data_rs1, + addr_rd2, data_rd2, we); + @(posedge clk); + + @(negedge clk); + if (data_rs0 !== expected_data_rs0 || data_rs1 !== expected_data_rs1) begin + $display("ERROR (register_file) in test %d: addr_rs0: %08h, addr_rs1: %08h, addr_rd2: %08h, data_rd2: %08h, we: %b", + test_count, addr_rs0, addr_rs1, addr_rd2, data_rd2, we); + $display(" data_rs0: %08h (expected: %08h)", data_rs0, expected_data_rs0); + $display(" data_rs1: %08h (expected: %08h)", data_rs1, expected_data_rs1); + error_count = error_count + 1; + end + test_count = test_count + 1; + end + $display("FINISHED with %d errors out of %d tests", error_count, test_count); + $fclose(file); + $finish; +end + +endmodule + diff --git a/src/register_file.v b/src/register_file.v index 81bce34..4846be8 100644 --- a/src/register_file.v +++ b/src/register_file.v @@ -5,25 +5,24 @@ module register_file #( input clk, rst, we, input [log2(N)-1:0] addr_rs0, addr_rs1, addr_rd2, input [N-1:0] data_rd2, - output [N-1:0] data_rs0, data_rs1 + output reg [N-1:0] data_rs0, data_rs1 ); `include "include/log2.vh" reg [N-1:0] registers[XLEN-1:1]; -assign data_rs0 = (addr_rs0 == 0) ? 0 : registers[addr_rs0]; -assign data_rs1 = (addr_rs1 == 0) ? 0 : registers[addr_rs1]; - - - integer i; -always @(posedge clk) begin +always @(posedge clk or rst) begin if (rst) begin for (i = 1; i < XLEN; i = i + 1) registers[i] <= 0; - end else if (we && (addr_rd2 != 0)) begin - registers[addr_rd2] <= data_rd2; + end else begin + data_rs0 = (addr_rs0 == 0) ? 0 : registers[addr_rs0]; + data_rs1 = (addr_rs1 == 0) ? 0 : registers[addr_rs1]; + if (we && (addr_rd2 != 0)) begin + registers[addr_rd2] = data_rd2; + end end end |