init
This commit is contained in:
parent
67b5b8d244
commit
f1a9cae544
|
@ -0,0 +1,4 @@
|
||||||
|
work/
|
||||||
|
transcript
|
||||||
|
vsim.wlf
|
||||||
|
waveform.vcd
|
|
@ -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
|
|
@ -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).
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
|
@ -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
|
||||||
|
|
|
@ -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
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
Loading…
Reference in New Issue