This commit is contained in:
Eric Yu 2024-07-07 20:58:45 -07:00
parent 67b5b8d244
commit f1a9cae544
35 changed files with 717 additions and 2 deletions

4
.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
work/
transcript
vsim.wlf
waveform.vcd

17
Makefile Normal file
View File

@ -0,0 +1,17 @@
# Default target
all: run
# Run the simulation
run:
cd ./tools/sim && vsim -c -do run.do && cd ../..
# Clean the build files
clean:
rm -rf ./tools/sim/work ./tools/sim/transcript ./tools/sim/vsim.wlf ./tools/sim/waveform.vcd
rm -rf transcript
# View the waveform
view:
vsim -view ./tools/sim/vsim.wlf
.PHONY: all compile run clean view

View File

@ -1,3 +1,3 @@
# NAME-of-REPO
# CPU Regfiles
Blah.. blah.. blah
The 31x64-bit register file with a read and write port used on the [Arm-compliant CPU](https://git.long-vega.ts.net/eyhc/Pipline_Arm_CPU).

View File

@ -0,0 +1,16 @@
// eneabled dff using 2:1 mux and dff
`timescale 1ns/10ps
module DFF_with_enable (d, reset, clk, en, q);
input logic d, reset, clk, en;
output logic q;
// internal wire to connect mux to the dff
logic in;
// a 2:1 mux that when enabled intput d is dff's output q, otherwise loop q back into itself
mux2_1 m1 (in, q, d, en);
D_FF d1 (q, in, reset, clk);
endmodule

11
src/hdl/D_FF.sv Normal file
View File

@ -0,0 +1,11 @@
// Data Flip Flop
module D_FF (q, d, reset, clk);
output reg q;
input d, reset, clk;
always_ff @(posedge clk)
if (reset)
q <= 0; // On reset, set to 0
else
q <= d; // Otherwise out = d
endmodule

24
src/hdl/decoder_2x4.sv Normal file
View File

@ -0,0 +1,24 @@
// Test bench for Register file
`timescale 1ns/10ps
module decoder_2x4(in, en, out);
// 2 bit input, 4 bit output
input logic [1:0] in;
input logic en;
output logic [3:0] out;
// store !in
logic [1:0] not_in;
// !in inverting logic
not #0.05 not0(not_in[0], in[0]);
not #0.05 not1(not_in[1], in[1]);
// out logic
and #0.05 and0(out[0], not_in[0], not_in[1], en);
and #0.05 and1(out[1], in[0], not_in[1], en);
and #0.05 and2(out[2], not_in[0], in[1], en);
and #0.05 and3(out[3], in[0], in[1], en);
endmodule

29
src/hdl/decoder_3x8.sv Normal file
View File

@ -0,0 +1,29 @@
// a gate-level 3 by 8 decoder
`timescale 1ns/10ps
module decoder_3x8 (in, en, out);
// 3 bit input, 8 bit output
input logic [2:0] in;
input logic en;
output logic [7:0] out;
// store !in
logic [2:0] not_in;
// !in inverting logic
not #0.05 not0(not_in[0], in[0]);
not #0.05 not1(not_in[1], in[1]);
not #0.05 not2(not_in[2], in[2]);
// out logic
and #0.05 out0(out[0], not_in[0], not_in[1], not_in[2], en);
and #0.05 out1(out[1], not_in[2], not_in[1], in[0], en);
and #0.05 out2(out[2], not_in[2], in[1], not_in[0], en);
and #0.05 out3(out[3], not_in[2], in[1], in[0], en);
and #0.05 out4(out[4], in[2], not_in[1], not_in[0], en);
and #0.05 out5(out[5], in[2], not_in[1], in[0], en);
and #0.05 out6(out[6], in[2], in[1], not_in[0], en);
and #0.05 out7(out[7], in[0], in[1], in[2], en);
endmodule
// tb

19
src/hdl/decoder_5x32.sv Normal file
View File

@ -0,0 +1,19 @@
// 5 to 32 using basic gates
`timescale 1ns/10ps
module decoder_5x32(in, out, en);
// 5 bits input, 32 bit output
input logic [4:0] in;
input logic en;
output logic [31:0] out;
// create local wires for the 2x4 decoder to the four 3x8 decoders
logic [3:0] decoder_2x4_out;
// using one 2x4 decoder to conect and enable four 3x8 decoders to make a 5x32 decoder
decoder_2x4 dec0(in[4:3], en, decoder_2x4_out[3:0]);
decoder_3x8 dec1(in[2:0], decoder_2x4_out[0], out[7:0]);
decoder_3x8 dec2(in[2:0], decoder_2x4_out[1], out[15:8]);
decoder_3x8 dec3(in[2:0], decoder_2x4_out[2], out[23:16]);
decoder_3x8 dec4(in[2:0], decoder_2x4_out[3], out[31:24]);
endmodule

16
src/hdl/mux16.sv Normal file
View File

@ -0,0 +1,16 @@
// create a 16:1 mux from two 8:1 mux which by a 2:1 mux
`timescale 1ns/10ps
module mux16 (out, in, sel);
input logic [15:0] in;
input logic [3:0] sel;
output logic out;
// internal wire to connect the muxes input/output
logic w1, w2, w3;
// two mux 8:1 which output connects to a 2:1 mux
mux8 m1 (.out(w1), .in(in[7:0]), .sel(sel[2:0]));
mux8 m2 (.out(w2), .in(in[15:8]), .sel(sel[2:0]));
mux2_1 m3 (.out, .i0(w1), .i1(w2), .sel(sel[3]));
endmodule

17
src/hdl/mux2_1.sv Normal file
View File

@ -0,0 +1,17 @@
// a gate-level 2:1 mux
`timescale 1ns/10ps
module mux2_1 #(parameter DELAY_NS=0.05) (out, i0, i1, sel);
// 2 bit input, 1 bit selector, and 1 bit output
output logic out;
input logic i0, i1, sel;
// wire inverting selector bit, and the output of two and gate
logic invSel, nand1, nand2;
// out logic
not #DELAY_NS nselect(invSel, sel);
nand #DELAY_NS u1(nand1, i1, sel);
nand #DELAY_NS u2(nand2, i0, invSel);
nand #DELAY_NS res(out, nand1, nand2);
endmodule

16
src/hdl/mux32.sv Normal file
View File

@ -0,0 +1,16 @@
// create a 32:1 mux from two 16:1 mux which by a 2:1 mux
`timescale 1ns/10ps
module mux32(out, in, sel);
input logic [31:0] in;
input logic [4:0] sel;
output logic out;
// internal wire to connect the muxes input/output
logic w1, w2, w3;
// two mux 16:1 which output connects to a 2:1 mux
mux16 m1 (.out(w1), .in(in[15:0]), .sel(sel[3:0]));
mux16 m2 (.out(w2), .in(in[31:16]), .sel(sel[3:0]));
mux2_1 m3 (.out, .i0(w1), .i1(w2), .sel(sel[4]));
endmodule

27
src/hdl/mux32_64.sv Normal file
View File

@ -0,0 +1,27 @@
// 64 bits 32:1 mux from 64 31:1 mux
`timescale 1ns/10ps
module mux32_64 #(parameter WIDTH=64, ADDR=5) (readDat, datIn, readReg);
input logic [31:0][WIDTH - 1:0] datIn;
input logic [ADDR - 1:0] readReg;
output logic [WIDTH - 1:0] readDat;
// internal wire that transposed the width and depth of the module's data to 64 mux32:1's data
logic [WIDTH - 1 : 0][31:0] transposed;
integer j, k;
// wire 32 64-bit-DFF's buses to 64 32:1 mux's
always_comb begin
for (j = 0; j < WIDTH; j++) begin
for (k = 0; k < 32; k++) begin
transposed[j][k] = datIn[k][j];
end
end
end
// generate 64 of 32:1 mux
genvar i;
generate
for (i = 0; i < WIDTH; i ++) begin : genmux
mux32 muxes (.out(readDat[i]), .in(transposed[i]), .sel(readReg));
end
endgenerate
endmodule

18
src/hdl/mux4_1.sv Normal file
View File

@ -0,0 +1,18 @@
// create a 4:1 mux from two 2:1 mux with another 2:1 mux
`timescale 1ns/10ps
module mux4_1 (out, in, sel);
input logic [3:0] in;
input logic [1:0] sel;
output logic out;
// internal wire to connect the muxes input/output
logic w1, w2, w3;
// two mux 2:1 which output connects to a third 2:1 mux
mux2_1 m1 (.out(w1), .i0(in[0]), .i1(in[1]), .sel(sel[0]));
mux2_1 m2 (.out(w2), .i0(in[2]), .i1(in[3]), .sel(sel[0]));
mux2_1 m3 (.out, .i0(w1), .i1(w2), .sel(sel[1]));
endmodule

18
src/hdl/mux8.sv Normal file
View File

@ -0,0 +1,18 @@
// create a 8:1 mux from two 4:1 mux which by a 2:1 mux
`timescale 1ns/10ps
module mux8 (out, in, sel);
input logic [7:0] in;
input logic [2:0] sel;
output logic out;
// internal wire to connect the muxes input/output
logic w1, w2, w3;
// two mux 4:1 which output connects to a 2:1 mux
mux4_1 m1 (.out(w1), .in(in[3:0]), .sel(sel[1:0]));
mux4_1 m2 (.out(w2), .in(in[7:4]), .sel(sel[1:0]));
mux2_1 m3 (.out, .i0(w1), .i1(w2), .sel(sel[2]));
endmodule

15
src/hdl/reg16.sv Normal file
View File

@ -0,0 +1,15 @@
// a 16-bit register from four 4-bit registers
`timescale 1ns/10ps
module reg16 (in, out, en, clk, reset);
input logic [15:0] in;
input logic en, clk, reset;
output logic [15:0] out;
// 4 DFF_E, each represents 1 bit in the register
reg4 r0 (in[3:0], out[3:0], en, clk, reset);
reg4 r1 (in[7:4], out[7:4], en, clk, reset);
reg4 r2 (in[11:8], out[11:8], en, clk, reset);
reg4 r3 (in[15:12], out[15:12], en, clk, reset);
endmodule

15
src/hdl/reg4.sv Normal file
View File

@ -0,0 +1,15 @@
// four bits register from four enabled register
`timescale 1ns/10ps
module reg4 (in, out, en, clk, reset);
input logic [3:0] in;
input logic en, clk, reset;
output logic [3:0] out;
// 4 DFF_E, each represents 1 bit in the register
DFF_with_enable d0 (in[0], reset, clk, en, out[0]);
DFF_with_enable d1 (in[1], reset, clk, en, out[1]);
DFF_with_enable d2 (in[2], reset, clk, en, out[2]);
DFF_with_enable d3 (in[3], reset, clk, en, out[3]);
endmodule

15
src/hdl/reg64.sv Normal file
View File

@ -0,0 +1,15 @@
// a 64-bit enabled register from four 16-bit registers
`timescale 1ns/10ps
module reg64 (in, out, en, clk, reset);
input logic [63:0] in;
input logic en, clk, reset;
output logic [63:0] out;
// 4 DFF_Enabled, each represents 1 bit in the register
reg16 r0 (in[15:0], out[15:0], en, clk, reset);
reg16 r1 (in[31:16], out[31:16], en, clk, reset);
reg16 r2 (in[47:32], out[47:32], en, clk, reset);
reg16 r3 (in[63:48], out[63:48], en, clk, reset);
endmodule

20
src/hdl/reg64x32.sv Normal file
View File

@ -0,0 +1,20 @@
// 32 64-bits dff connected in parallel
`timescale 1ns/10ps
module reg64x32 (in, out, en, clk, reset);
input logic [63:0] in;
input logic [31:0] en;
input logic clk, reset;
output logic [31:0][63:0] out;
genvar i;
// use for loop to generate an array of 31 64-bit registers
generate
for (i = 0; i < 31; i++) begin : manyDFFs
reg64 bigReg (.in(in), .out(out[i]), .en(en[i]), .clk, .reset);
end
endgenerate
// the 32nd register is the zero register, always write zero to it.
reg64 reg0 (.in(64'd0), .out(out[31]), .en(1'b1), .clk, .reset);
endmodule

32
src/hdl/regfile.sv Normal file
View File

@ -0,0 +1,32 @@
// toplevel for register file, with two 5-bit read selector input and one 5-bit write inputs, and takes in 64-bit data and returns two 63-bit data depends on the output, with write enebled option
`timescale 1ns/10ps
module regfile(RegWrite, clk, ReadRegister1, ReadRegister2, WriteData, WriteRegister, ReadData1, ReadData2);
input logic RegWrite;
input logic clk;
input logic [4:0] ReadRegister1;
input logic [4:0] ReadRegister2;
input logic [63:0] WriteData;
input logic [4:0] WriteRegister;
output logic [63:0] ReadData1;
output logic [63:0] ReadData2;
// generate wires to connect decodes to DFF's enable, and from DFF data to two muxes
logic [31:0] en;
logic [31:0][63:0] dataBus;
// call the array of 32 64-bit registers
reg64x32 regs(.clk(clk), .reset(1'b0), .en, .in(WriteData), .out(dataBus));
// create two 64-bit 31:1 muxes to allow select different register output
mux32_64 mux1(.datIn(dataBus), .readReg(ReadRegister1), .readDat(ReadData1));
// defined the mux's selector bits and inputs bit
defparam mux1.ADDR = 5;
defparam mux1.WIDTH = 64;
mux32_64 mux2( .datIn(dataBus), .readReg(ReadRegister2), .readDat(ReadData2));
defparam mux2.ADDR = 5;
defparam mux2.WIDTH = 64;
// connect the 5x32 decoder to the 64bit registers to allow at most only one register to be able to get write value each time
decoder_5x32 decoder(.en(RegWrite), .in(WriteRegister), .out(en));
endmodule

View File

@ -0,0 +1,26 @@
module DFF_with_enable_testbench();
logic d, q, reset, clk, en;
DFF_with_enable dut (.d, .reset, .clk, .en, .q);
// Set up a simulated clock.
parameter CLOCK_PERIOD=10;
initial begin
clk <= 0;
forever #(CLOCK_PERIOD/2) clk <= ~clk; // Forever toggle the clock
end
// Set up the inputs to the design. Each line is a clock cycle.
initial begin
reset <= 1; @(posedge clk); // Always reset FSMs at start
// check if enable works properly by writing data when turn on enable
reset <= 0; d <= 1; q <= 0; en <= 0; @(posedge clk);
en <= 1; @(posedge clk);
d <= 0; @(posedge clk);
// check if data output would stay when enable is off
en <= 0; @(posedge clk);
repeat(2) @(posedge clk);
$stop; // End the simulation.
end
endmodule

20
src/tb/decoder_2x4_tb.sv Normal file
View File

@ -0,0 +1,20 @@
module decoder_2x4_testbench();
logic [1:0] in;
logic en;
logic [3:0] out;
decoder_2x4 dut (.in, .en, .out);
integer i, j;
initial begin // Test all input variations
for(i=0; i<4; i++) begin
en = 1;
in[1:0] = i; #1;
end
for(j=0; j<4; j++) begin
en = 0;
in[1:0] = j; #1;
end
end
endmodule

21
src/tb/decoder_3x8_tb.sv Normal file
View File

@ -0,0 +1,21 @@
module decoder_3x8_testbench();
logic [2:0] in;
logic [7:0] out;
logic en;
logic [2:0] not_in;
decoder_3x8 dut (.in, .en, .out);
integer i, j;
initial begin // Test all input variations
for(i=0; i<8; i++) begin
en = 1;
in[2:0] = i; #1;
end
for(j=0; j<8; j++) begin
en = 0;
in[2:0] = j; #1;
end
end
endmodule

22
src/tb/decoder_5x32_tb.sv Normal file
View File

@ -0,0 +1,22 @@
module decoder_5x32_testbench();
logic [4:0] in;
logic en;
logic [31:0] out;
logic [3:0] decoder_2x4_out;
decoder_5x32 dut (.in, .en, .out);
integer i, j;
initial begin // Test all input variations
for(i=0; i<32; i++) begin
en = 1;
in[4:0] = i; #1;
end
for(j=0; j<32; j++) begin
en = 0;
in[4:0] = j; #1;
end
end
endmodule

13
src/tb/mux16_tb.sv Normal file
View File

@ -0,0 +1,13 @@
module mux16_testbench();
logic [15:0] in;
logic [3:0] sel;
logic out;
mux16 dut (.*);
integer i;
initial begin // Test all input variations
for (i = 0; i < 2**20; i++) begin
{in, sel} = i; #1;
end
end
endmodule

12
src/tb/mux2_1_tb.sv Normal file
View File

@ -0,0 +1,12 @@
module mux2_1_testbench();
logic i0, i1, sel;
logic out;
mux2_1 dut (.out, .i0, .i1, .sel);
integer i;
initial begin // Test all input variations
for (i = 0; i < 2**3; i++) begin
{i0, i1, sel} = i; #1;
end
end
endmodule

17
src/tb/mux32_64_tb.sv Normal file
View File

@ -0,0 +1,17 @@
module mux32_64_testbench();
logic [31:0][63:0] datIn;
logic [4:0] readReg;
logic [63:0] readDat;
mux32_64 dut (.*);
integer i;
initial begin
for (i=0; i<32; i=i+1) begin
datIn[i] = i * 64'h00000000000000A0; // addr # multiplies a fixed hex seed
end
for (i = 0; i < 2**5; i++) begin
readReg = i; #10; // select an addr to output
end
end
endmodule

13
src/tb/mux32_tb.sv Normal file
View File

@ -0,0 +1,13 @@
module mux32_testbench();
logic [31:0] in;
logic [4:0] sel;
logic out;
mux32 dut (.*);
integer i;
initial begin // Test all input variations
for (i = 0; i < 2**10; i++) begin
{in, sel} = i; #1;
end
end
endmodule

13
src/tb/mux4_1_tb.sv Normal file
View File

@ -0,0 +1,13 @@
module mux4_1_testbench();
logic [3:0] in;
logic [1:0] sel;
logic out;
mux4_1 dut (.*);
integer i;
initial begin // Test all input variations
for (i = 0; i < 2**6; i++) begin
{in, sel} = i; #1;
end
end
endmodule

13
src/tb/mux8_tb.sv Normal file
View File

@ -0,0 +1,13 @@
module mux8_testbench();
logic [7:0] in;
logic [2:0] sel;
logic out;
mux8 dut (.*);
integer i;
initial begin // Test all input variations
for (i = 0; i < 2**11; i++) begin
{in, sel} = i; #1;
end
end
endmodule

27
src/tb/reg16_tb.sv Normal file
View File

@ -0,0 +1,27 @@
module reg16_testbench();
logic [15:0] in, out;
logic reset, clk, en;
reg16 dut (.in, .out, .en, .clk, .reset);
// Set up a simulated clock.
parameter CLOCK_PERIOD=10;
initial begin
clk <= 0;
forever #(CLOCK_PERIOD/2) clk <= ~clk; // Forever toggle the clock
end
initial begin
reset <= 1; @(posedge clk); // Always reset FSMs at start
// write in some values and check if register values stays when enable is low, or if is writes in if enable is high.
reset <= 0; en <= 0; in <= 4'd65536; @(posedge clk);
en <= 1; in <= 16'd11451; @(posedge clk);
en <= 1; in <= 16'd19198; @(posedge clk);
en <= 0; in <= 16'd19198; @(posedge clk);
en <= 0; in <= 16'd14; @(posedge clk);
en <= 1; in <= 16'd32; @(posedge clk);
repeat(2) @(posedge clk);
$stop;
end
endmodule

27
src/tb/reg4_tb.sv Normal file
View File

@ -0,0 +1,27 @@
module reg4_testbench();
logic [3:0] in, out;
logic reset, clk, en;
reg4 dut (.in, .out, .en, .clk, .reset);
// Set up a simulated clock.
parameter CLOCK_PERIOD=10;
initial begin
clk <= 0;
forever #(CLOCK_PERIOD/2) clk <= ~clk; // Forever toggle the clock
end
initial begin
reset <= 1; @(posedge clk); // Always reset FSMs at start
// write in some values and check if register values stays when enable is low, or if is writes in if enable is high.
reset <= 0; en <= 0; in <= 4'b1111; @(posedge clk);
en <= 1; in <= 4'b1111; @(posedge clk);
en <= 1; in <= 4'b1001; @(posedge clk);
en <= 0; in <= 4'b1001; @(posedge clk);
en <= 0; in <= 4'b1111; @(posedge clk);
en <= 1; in <= 4'b0000; @(posedge clk);
repeat(2) @(posedge clk);
$stop;
end
endmodule

27
src/tb/reg64_tb.sv Normal file
View File

@ -0,0 +1,27 @@
module reg64_testbench();
logic [63:0] in, out;
logic reset, clk, en;
reg64 dut (.in, .out, .en, .clk, .reset);
// Set up a simulated clock.
parameter CLOCK_PERIOD=10;
initial begin
clk <= 0;
forever #(CLOCK_PERIOD/2) clk <= ~clk; // Forever toggle the clock
end
initial begin
reset <= 1; @(posedge clk); // Always reset FSMs at start
// write in some values and check if register values stays when enable is low, or if is writes in if enable is high.
reset <= 0; en <= 0; in <= 64'd4254663563463457; @(posedge clk);
en <= 1; in <= 64'd1145141919810; @(posedge clk);
en <= 1; in <= 64'd8689689680; @(posedge clk);
en <= 0; in <= 64'd0; @(posedge clk);
en <= 0; in <= 64'd8689689680; @(posedge clk);
en <= 1; in <= 64'd1145141919810; @(posedge clk);
repeat(2) @(posedge clk);
$stop;
end
endmodule

48
src/tb/reg64x32_tb.sv Normal file
View File

@ -0,0 +1,48 @@
module reg64x32_testbench();
logic [63:0] in;
logic [31:0] en;
logic clk, reset;
logic [31:0][63:0] out; // output
integer i;
assign reset = 1'b0;
reg64x32 dut (.*);
initial $timeformat(-9, 2, " ns", 10);
initial begin // Set up the clock
clk <= 0;
forever #(5000/2) clk <= ~clk; // clk delay is 5000
end
initial begin
// Try to write the value 0xA0 into register 31.
// Register 31 should always be at the value of 0.
$display("%t Attempting overwrite of register 31, which should always be 0", $time);
en <= 31'b1 << 31;
in <= 64'h00000000000000A0;
@(posedge clk);
// $display("%t Writing pattern to all registers.", $time);
for (i=0; i<31; i=i+1) begin
en <= 0;
@(posedge clk);
$display("%t Writing pattern to %i", $time, i);
en <= 31'b1 << i;
in <= i*64'h0000010204080001;
@(posedge clk);
end
// Go back and verify that the registers
// retained the data.
$display("%t Checking pattern.", $time);
en <= 31'b0;
for (i=0; i<32; i=i+1) begin
// WriteRegister <= i;
in <= i*64'h0000000000000100+i;
@(posedge clk);
end
$stop;
end
endmodule

79
src/tb/regstim.sv Normal file
View File

@ -0,0 +1,79 @@
// Test bench for Register file
`timescale 1ns/10ps
module regstim();
parameter ClockDelay = 5000;
logic [4:0] ReadRegister1, ReadRegister2, WriteRegister;
logic [63:0] WriteData;
logic RegWrite, clk;
logic [63:0] ReadData1, ReadData2;
integer i;
// Your register file MUST be named "regfile".
// Also you must make sure that the port declarations
// match up with the module instance in this stimulus file.
regfile dut (.ReadData1, .ReadData2, .WriteData,
.ReadRegister1, .ReadRegister2, .WriteRegister,
.RegWrite, .clk);
// Force %t's to print in a nice format.
initial $timeformat(-9, 2, " ns", 10);
initial begin // Set up the clock
clk <= 0;
forever #(ClockDelay/2) clk <= ~clk;
end
initial begin
// Try to write the value 0xA0 into register 31.
// Register 31 should always be at the value of 0.
RegWrite <= 5'd0;
ReadRegister1 <= 5'd0;
ReadRegister2 <= 5'd0;
WriteRegister <= 5'd31;
WriteData <= 64'h00000000000000A0;
@(posedge clk);
$display("%t Attempting overwrite of register 31, which should always be 0", $time);
RegWrite <= 1;
@(posedge clk);
// Write a value into each register.
$display("%t Writing pattern to all registers.", $time);
for (i=0; i<31; i=i+1) begin
RegWrite <= 0;
ReadRegister1 <= i-1;
ReadRegister2 <= i;
WriteRegister <= i;
WriteData <= i*64'h0000010204080001;
@(posedge clk);
RegWrite <= 1;
@(posedge clk);
end
// Go back and verify that the registers
// retained the data.
$display("%t Checking pattern.", $time);
for (i=0; i<32; i=i+1) begin
RegWrite <= 0;
ReadRegister1 <= i-1;
ReadRegister2 <= i;
WriteRegister <= i;
WriteData <= i*64'h0000000000000100+i;
@(posedge clk);
if (ReadData1 !== (i-1)*64'h0000010204080001 && i-1 >= 0) begin
$error("%t ReadData1 mismatch at register %d: \n\tExpected %h, got %h", $time, i, (i-1)*64'h0000010204080001, ReadData1);
end
if (ReadData2 !== i*64'h0000010204080001 && i != 31) begin
$error("%t ReadData2 mismatch at register %d: \n\tExpected %h, got %h", $time, i, i*64'h0000010204080001, ReadData2);
end
end
$finish;
end
endmodule

8
tools/sim/run.do Normal file
View File

@ -0,0 +1,8 @@
vlib work
vlog ../../src/hdl/*
vlog ../../src/tb/*
vsim work.regstim
log * -r
vcd file waveform.vcd
vcd add -r /*
run -all