Skip to content

Commit 88cb530

Browse files
Merge pull request #47 from UTOSS/boris/move-rf-tb
Move RF testbench to `test/` and fix `lw`
2 parents 29bee9b + 184f520 commit 88cb530

6 files changed

Lines changed: 81 additions & 64 deletions

File tree

Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,9 @@ new_tb:
3232
fi
3333
m4 -D M4__TB_NAME="$(name)_tb" test/tb_template.sv.m4 > test/$(name)_tb.sv
3434

35-
build_tb: $(TB_VVPS)
35+
build_tb: $(TB_VVPS) $(TB_SRCS) $(TB_UTILS)
3636

37-
run_tb: $(TB_VVPS)
37+
run_tb: build_tb
3838
@failed=0; \
3939
for tb in $(TB_VVPS); do \
4040
echo "Running $$tb..."; \

src/ControlFSM.sv

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ module ControlFSM(
101101
Branch <= 1'b0;
102102
pc_src <= 1'b0;
103103
PCUpdate <= 1'b0;
104+
IRWrite <= 1'b0;
104105

105106
FSMState <= current_state;
106107

@@ -110,6 +111,7 @@ module ControlFSM(
110111

111112
AdrSrc <= ADR_SRC__PC;
112113
IRWrite <= 1'b1;
114+
PCUpdate <= 1'b1;
113115

114116
end
115117

src/top.v

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ module top ( input wire clk
1212

1313
addr_t pc_cur;
1414
addr_t memory_address;
15+
data_t memory_data;
1516
data_t data;
1617
instr_t instruction;
1718
opcode_t opcode;
@@ -87,11 +88,21 @@ module top ( input wire clk
8788
, .CLK ( clk )
8889

8990
// outputs
90-
, .RD ( data )
91+
, .RD ( memory_data )
9192
);
9293

94+
always @(posedge clk) begin
95+
if (cfsm__ir_write) begin
96+
instruction <= memory_data;
97+
end
98+
end
99+
100+
always @(posedge clk) begin
101+
data <= memory_data;
102+
end
103+
93104
Instruction_Decode instruction_decode
94-
( .instr ( data )
105+
( .instr ( instruction )
95106
, .clk ( clk )
96107
, .reset ( reset )
97108
, .ResultData ( result )

test/beq_tb.sv

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ module beq_tb;
1919
forever #5 clk = ~clk;
2020
end
2121

22+
task wait_till_next_cfsm_state(input [5:0] expected_state);
23+
@(posedge clk); #1;
24+
`assert_equal(uut.control_fsm.current_state, expected_state)
25+
endtask
26+
2227
initial begin
2328

2429
// initialize instruction memory
@@ -30,17 +35,17 @@ module beq_tb;
3035
// initialize registers
3136
uut.instruction_decode.instanceRegFile.RFMem[5'b00100] = 32'h0000002a; // x4 = 42
3237

33-
@(posedge clk); #1; // fetch stage
38+
wait_till_next_cfsm_state(uut.control_fsm.FETCH);
3439
reset <= `FALSE;
3540

36-
@(posedge clk); #1; // decode stage
41+
wait_till_next_cfsm_state(uut.control_fsm.DECODE);
3742

3843
assert(uut.opcode == 7'b1100011) else $fatal(1,"`uut.opcode` is `%0b`", uut.opcode);
3944

40-
assert(uut.fetch.pc_cur == 32'h00000000) else $fatal(1,"`uut.fetch.pc_cur` is `%0h`", uut.fetch.pc_cur);
45+
assert(uut.fetch.pc_cur == 32'h00000004) else $fatal(1,"`uut.fetch.pc_cur` is `%0h`", uut.fetch.pc_cur);
4146
assert(uut.fetch.imm_ext == 32'hFFFFFFF4) else $fatal(1,"`uut.fetch.imm_ext` is `%0h`", uut.fetch.imm_ext);
4247

43-
@(posedge clk); #1; // beq stage
48+
wait_till_next_cfsm_state(uut.control_fsm.BRANCHIFEQ);
4449

4550
assert(uut.alu__zero_flag == `TRUE) else $fatal(1,"`uut.alu__zero_flag` is `%0b`", uut.alu__zero_flag);
4651

@@ -49,11 +54,11 @@ module beq_tb;
4954

5055
assert(uut.cfsm__pc_src == 1 /* JUMP */) else $fatal(1,"`uut.cfsm__pc_src` is `%0b`", uut.cfsm__pc_src);
5156

52-
assert(uut.fetch.pc_cur == 32'h00000000) else $fatal(1,"`uut.fetch.pc_cur` is `%0h`", uut.fetch.pc_cur);
57+
assert(uut.fetch.pc_cur == 32'h00000004) else $fatal(1,"`uut.fetch.pc_cur` is `%0h`", uut.fetch.pc_cur);
5358

54-
@(posedge clk); #1; // fetch stage
59+
wait_till_next_cfsm_state(uut.control_fsm.FETCH);
5560

56-
assert(uut.fetch.pc_cur == 32'hFFFFFFF4) else $fatal(1,"`uut.fetch.pc_cur` is `%0h`", uut.fetch.pc_cur);
61+
assert(uut.fetch.pc_cur == 32'hFFFFFFF8) else $fatal(1,"`uut.fetch.pc_cur` is `%0h`", uut.fetch.pc_cur);
5762

5863
// beq without satisfied condition
5964
@(posedge clk); #1;
@@ -63,51 +68,50 @@ module beq_tb;
6368
uut.instruction_decode.instanceRegFile.RFMem[5'b00001] = 32'h0000002a; // x1 = 42
6469
uut.instruction_decode.instanceRegFile.RFMem[5'b00010] = 32'h0000002b; // x2 = 43
6570

66-
@(posedge clk); #1; // fetch stage
71+
wait_till_next_cfsm_state(uut.control_fsm.FETCH);
6772
reset <= `FALSE;
6873

69-
@(posedge clk); #1; // decode stage
74+
wait_till_next_cfsm_state(uut.control_fsm.DECODE);
7075

7176
assert(uut.opcode == 7'b1100011) else $fatal(1,"`uut.opcode` is `%0b`", uut.opcode);
7277

73-
assert(uut.fetch.pc_cur == 32'h00000000) else $fatal(1,"`uut.fetch.pc_cur` is `%0h`", uut.fetch.pc_cur);
78+
assert(uut.fetch.pc_cur == 32'h00000004) else $fatal(1,"`uut.fetch.pc_cur` is `%0h`", uut.fetch.pc_cur);
7479
assert(uut.fetch.imm_ext == 32'h00000010) else $fatal(1,"`uut.fetch.imm_ext` is `%0h`", uut.fetch.imm_ext);
7580

76-
@(posedge clk); #1; // beq stage
81+
wait_till_next_cfsm_state(uut.control_fsm.BRANCHIFEQ);
7782

7883
assert(uut.alu.a == 32'h0000002a) else $fatal(1,"`uut.alu.a` is `%0h`", uut.alu.a);
7984
assert(uut.alu.b == 32'h0000002b) else $fatal(1,"`uut.alu.b` is `%0h`", uut.alu.b);
8085

8186
assert(uut.alu__zero_flag == `FALSE) else $fatal(1,"`uut.alu__zero_flag` is `%0b`", uut.alu__zero_flag);
8287

8388
assert(uut.cfsm__pc_src == 0 /* +4 */) else $fatal(1,"`uut.cfsm__pc_src` is `%0b`", uut.cfsm__pc_src);
84-
assert(uut.fetch.pc_cur == 32'h00000000) else $fatal(1,"`uut.fetch.pc_cur` is `%0h`", uut.fetch.pc_cur);
89+
assert(uut.fetch.pc_cur == 32'h00000004) else $fatal(1,"`uut.fetch.pc_cur` is `%0h`", uut.fetch.pc_cur);
8590

86-
@(posedge clk); #1; // fetch stage
91+
wait_till_next_cfsm_state(uut.control_fsm.FETCH);
8792

88-
assert(uut.fetch.pc_cur == 32'h00000004) else $fatal(1,"`uut.fetch.pc_cur` is `%0h`", uut.fetch.pc_cur);
93+
assert(uut.fetch.pc_cur == 32'h00000008) else $fatal(1,"`uut.fetch.pc_cur` is `%0h`", uut.fetch.pc_cur);
8994

9095
@(posedge clk); #1; // check that zero-setting instructions do not result in a jump
9196
reset <= `TRUE;
9297

9398
uut.memory.M[0] = 32'b0100000_00001_00001_000_00001_0110011; // sub x1, x1, x1
9499
uut.instruction_decode.instanceRegFile.RFMem[5'b00001] = 32'h00000001; // x1 = 1
95100

96-
@(posedge clk); #1; // fetch stage
101+
wait_till_next_cfsm_state(uut.control_fsm.FETCH);
97102
reset <= `FALSE;
98103

99-
@(posedge clk); #1; // decode stage
104+
wait_till_next_cfsm_state(uut.control_fsm.DECODE);
100105

101-
assert(uut.fetch.pc_cur == 32'h00000000) else $fatal(1,"`uut.fetch.pc_cur` is `%0h`", uut.fetch.pc_cur);
106+
assert(uut.fetch.pc_cur == 32'h00000004) else $fatal(1,"`uut.fetch.pc_cur` is `%0h`", uut.fetch.pc_cur);
102107

103-
@(posedge clk); #1; // execute stage
108+
wait_till_next_cfsm_state(uut.control_fsm.EXECUTER);
104109

105110
assert(uut.alu__zero_flag == `TRUE) else $fatal(1,"`uut.alu__zero_flag` is `%0b`", uut.alu__zero_flag);
106111

107-
@(posedge clk); #1; // wait for pc update
112+
wait_till_next_cfsm_state(uut.control_fsm.ALUWB);
108113

109-
// pc update not implemented yet for this
110-
assert(uut.fetch.pc_cur == 32'h00000000) else $fatal(1,"`uut.fetch.pc_cur` is `%0h`", uut.fetch.pc_cur);
114+
assert(uut.fetch.pc_cur == 32'h00000004) else $fatal(1,"`uut.fetch.pc_cur` is `%0h`", uut.fetch.pc_cur);
111115

112116
$finish;
113117
end

test/lw_tb.sv

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,18 @@ module lw_tb;
2525
initial begin
2626
reset <= `TRUE;
2727

28-
// set up instructions and data memory
28+
// set up instructions and data memory; M array uses word addressing, hence the indices there
29+
// are 4 times smaller than the actual addresses corresponding to the beginning to the
30+
// corresponding word
2931
uut.memory.M[ 0] = 32'h00012083; // lw x1, 0(x2)
30-
uut.memory.M[ 4] = 32'h00412083; // lw x1, 4(x2)
31-
uut.memory.M[ 8] = 32'hff812083; // lw x1, -8(x2)
32-
uut.memory.M[34] = 32'hbadab00f; // have some data at address 34
33-
uut.memory.M[42] = 32'hdeadbeef; // have some data at address 42
34-
uut.memory.M[46] = 32'hcafebabe; // have some data at address 46
32+
uut.memory.M[ 1] = 32'h00412083; // lw x1, 4(x2)
33+
uut.memory.M[ 2] = 32'hff812083; // lw x1, -8(x2)
34+
uut.memory.M[40] = 32'hbadab00f; // have some data at address 0xa0
35+
uut.memory.M[42] = 32'hdeadbeef; // have some data at address 0xa8
36+
uut.memory.M[43] = 32'hcafebabe; // have some data at address 0xac
3537

3638
// set up register file
37-
uut.instruction_decode.instanceRegFile.RFMem[2] = 42; // x2 = 42
39+
uut.instruction_decode.instanceRegFile.RFMem[2] = 32'ha8; // x2 = 42 * 4 = 168 = 0xa8
3840

3941
wait_till_next_cfsm_state(uut.control_fsm.FETCH);
4042

@@ -49,15 +51,15 @@ module lw_tb;
4951

5052
wait_till_next_cfsm_state(uut.control_fsm.MEMADR);
5153

52-
`assert_equal(uut.instruction_decode.instanceRegFile.RFMem[2], 42)
53-
`assert_equal(uut.alu.a, 42)
54+
`assert_equal(uut.instruction_decode.instanceRegFile.RFMem[2], 32'ha8)
55+
`assert_equal(uut.alu.a, 32'ha8)
5456
`assert_equal(uut.alu.b, 0)
55-
`assert_equal(uut.alu.out, 42)
57+
`assert_equal(uut.alu.out, 32'ha8)
5658

5759
wait_till_next_cfsm_state(uut.control_fsm.MEMREAD);
5860

59-
`assert_equal(uut.result, 42)
60-
`assert_equal(uut.memory_address, 42)
61+
`assert_equal(uut.result, 32'ha8)
62+
`assert_equal(uut.memory_address, 32'ha8)
6163

6264
wait_till_next_cfsm_state(uut.control_fsm.MEMWB);
6365

@@ -67,7 +69,7 @@ module lw_tb;
6769
wait_till_next_cfsm_state(uut.control_fsm.FETCH);
6870

6971
`assert_equal(uut.instruction_decode.instanceRegFile.RFMem[1], 32'hdeadbeef)
70-
`assert_equal(uut.instruction_decode.instanceRegFile.RFMem[2], 42)
72+
`assert_equal(uut.instruction_decode.instanceRegFile.RFMem[2], 32'ha8)
7173
`assert_equal(uut.fetch.pc_cur, 4) // starting second instruction already
7274

7375
wait_till_next_cfsm_state(uut.control_fsm.DECODE);
@@ -79,15 +81,15 @@ module lw_tb;
7981

8082
wait_till_next_cfsm_state(uut.control_fsm.MEMADR);
8183

82-
`assert_equal(uut.instruction_decode.instanceRegFile.RFMem[2], 42)
83-
`assert_equal(uut.alu.a, 42)
84+
`assert_equal(uut.instruction_decode.instanceRegFile.RFMem[2], 32'ha8)
85+
`assert_equal(uut.alu.a, 32'ha8)
8486
`assert_equal(uut.alu.b, 4)
85-
`assert_equal(uut.alu.out, 46)
87+
`assert_equal(uut.alu.out, 32'hac)
8688

8789
wait_till_next_cfsm_state(uut.control_fsm.MEMREAD);
8890

89-
`assert_equal(uut.result, 46)
90-
`assert_equal(uut.memory_address, 46)
91+
`assert_equal(uut.result, 32'hac)
92+
`assert_equal(uut.memory_address, 32'hac)
9193

9294
wait_till_next_cfsm_state(uut.control_fsm.MEMWB);
9395

@@ -97,7 +99,7 @@ module lw_tb;
9799
wait_till_next_cfsm_state(uut.control_fsm.FETCH);
98100

99101
`assert_equal(uut.instruction_decode.instanceRegFile.RFMem[1], 32'hcafebabe)
100-
`assert_equal(uut.instruction_decode.instanceRegFile.RFMem[2], 42)
102+
`assert_equal(uut.instruction_decode.instanceRegFile.RFMem[2], 32'ha8)
101103
`assert_equal(uut.fetch.pc_cur, 8) // starting third instruction already
102104

103105
wait_till_next_cfsm_state(uut.control_fsm.DECODE);
@@ -109,15 +111,15 @@ module lw_tb;
109111

110112
wait_till_next_cfsm_state(uut.control_fsm.MEMADR);
111113

112-
`assert_equal(uut.instruction_decode.instanceRegFile.RFMem[2], 42)
113-
`assert_equal(uut.alu.a, 42)
114+
`assert_equal(uut.instruction_decode.instanceRegFile.RFMem[2], 32'ha8)
115+
`assert_equal(uut.alu.a, 32'ha8)
114116
`assert_equal(uut.alu.b, -8)
115-
`assert_equal(uut.alu.out, 34)
117+
`assert_equal(uut.alu.out, 32'ha0)
116118

117119
wait_till_next_cfsm_state(uut.control_fsm.MEMREAD);
118120

119-
`assert_equal(uut.result, 34)
120-
`assert_equal(uut.memory_address, 34)
121+
`assert_equal(uut.result, 32'ha0)
122+
`assert_equal(uut.memory_address, 32'ha0)
121123

122124
wait_till_next_cfsm_state(uut.control_fsm.MEMWB);
123125

@@ -127,9 +129,10 @@ module lw_tb;
127129
wait_till_next_cfsm_state(uut.control_fsm.FETCH);
128130

129131
`assert_equal(uut.instruction_decode.instanceRegFile.RFMem[1], 32'hbadab00f)
130-
`assert_equal(uut.instruction_decode.instanceRegFile.RFMem[2], 42)
132+
`assert_equal(uut.instruction_decode.instanceRegFile.RFMem[2], 32'ha8)
131133
`assert_equal(uut.fetch.pc_cur, 12)
132134

135+
$finish;
133136
end
134137

135138
`SETUP_VCD_DUMP(lw_tb)
Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
`timescale 1ns/1ps
22

3-
module tb_registerFile;
3+
`include "test/utils.svh"
4+
5+
module rf_tb;
46

57
//DUT inputs
68
logic [4:0] Addr1, Addr2, Addr3;
@@ -46,7 +48,7 @@ module tb_registerFile;
4648
//set Addr1 = 5 and Addr2 = 10 to read from registers 5 and 10
4749
Addr1 = 5;
4850
Addr2 = 10;
49-
Addr3 = 0;
51+
Addr3 = 0;
5052
dataIn = 0;
5153
regWrite = 0;
5254

@@ -61,33 +63,28 @@ module tb_registerFile;
6163
Addr3 = 15;
6264
dataIn = 32'h12345678;
6365
regWrite = 1;
64-
66+
6567
@(posedge clk); //wait one clock cycle
6668

6769
#1; //wait for written data to stabilize
6870
regWrite = 0; //de-assert write
6971
assert(dut.RFMem[15] == 32'h12345678) else $fatal(1, "WRITE FAILED: current reg 15 output: %h; expected reg 15 output: 12345678", dut.RFMem[15]);
7072
$display("PASS: Write to register 15 verified. current reg 15 output: %h; expected reg 15 output: 12345678", dut.RFMem[15]);
71-
73+
7274
//CASE 3 - Write to reg 0
7375
Addr3 = 0;
7476
dataIn = 32'h12345678;
75-
77+
7678
@(posedge clk); //wait one clock cycle
77-
79+
7880
#1; //wait for written data to stabilize
7981
regWrite = 0; //de-assert write
80-
assert(dut.RFMem[0] == 0) else $fatal(1, "WRITE FAILED: current reg 0 output: %h; expected reg 0 output: 0", dut.RFMem[0]);
82+
assert(dut.RFMem[0] == 0) else $fatal(1, "WRITE FAILED: current reg 0 output: %h; expected reg 0 output: 0", dut.RFMem[0]);
8183
$display("PASS: Write to register 0 verified. current reg 0 output: %h; expected reg 0 output: 0", dut.RFMem[0]);
8284

8385
$finish;
8486
end
85-
86-
initial begin //generate waveform
87-
88-
$dumpfile("RFTB.vcd");
89-
$dumpvars(0, tb_registerFile);
90-
91-
end
87+
88+
`SETUP_VCD_DUMP(rf_tb)
9289

9390
endmodule

0 commit comments

Comments
 (0)