Skip to content

Commit

Permalink
RF verification + sizes fixes in RF (#73)
Browse files Browse the repository at this point in the history
  • Loading branch information
ahmednofal authored Jun 5, 2021
1 parent 59e6741 commit 618be36
Show file tree
Hide file tree
Showing 4 changed files with 272 additions and 21 deletions.
36 changes: 18 additions & 18 deletions platforms/sky130A/BB/rf/model.v
Original file line number Diff line number Diff line change
Expand Up @@ -87,14 +87,14 @@ module RFWORD #(parameter RWIDTH=32)

wire [RWIDTH-1:0] q_wire;
wire we_wire;
wire [3:0] SEL1_B, SEL2_B;
wire [3:0] GCLK;
wire [(RWIDTH/8)-1:0] SEL1_B, SEL2_B;
wire [(RWIDTH/8)-1:0] GCLK;

sky130_fd_sc_hd__inv_4 INV1[3:0] (.Y(SEL1_B), .A(SEL1));
sky130_fd_sc_hd__inv_4 INV2[3:0] (.Y(SEL2_B), .A(SEL2));
sky130_fd_sc_hd__inv_4 INV1[(RWIDTH/8)-1:0] (.Y(SEL1_B), .A(SEL1));
sky130_fd_sc_hd__inv_4 INV2[(RWIDTH/8)-1:0] (.Y(SEL2_B), .A(SEL2));

sky130_fd_sc_hd__and2_1 CGAND ( .A(SELW), .B(WE), .X(we_wire) );
sky130_fd_sc_hd__dlclkp_1 CG[3:0] ( .CLK(CLK), .GCLK(GCLK), .GATE(we_wire) );
sky130_fd_sc_hd__dlclkp_1 CG[(RWIDTH/8)-1:0] ( .CLK(CLK), .GCLK(GCLK), .GATE(we_wire) );

generate
genvar i;
Expand All @@ -118,12 +118,12 @@ module RFWORD0 #(parameter RWIDTH=32)

wire [RWIDTH-1:0] q_wire;
wire we_wire;
wire [3:0] SEL1_B, SEL2_B;
wire [3:0] GCLK;
wire [(RWIDTH/8)-1:0] SEL1_B, SEL2_B;
wire [(RWIDTH/8)-1:0] GCLK;
wire [7:0] lo;

sky130_fd_sc_hd__inv_4 INV1[3:0] (.Y(SEL1_B), .A(SEL1));
sky130_fd_sc_hd__inv_4 INV2[3:0] (.Y(SEL2_B), .A(SEL2));
sky130_fd_sc_hd__inv_4 INV1[(RWIDTH/8)-1:0] (.Y(SEL1_B), .A(SEL1));
sky130_fd_sc_hd__inv_4 INV2[(RWIDTH/8)-1:0] (.Y(SEL2_B), .A(SEL2));

sky130_fd_sc_hd__conb_1 TIE [7:0] (.LO(lo), .HI());

Expand All @@ -141,13 +141,13 @@ module DFFRF_2R1W #(parameter RWIDTH=32,
RCOUNT=32,
R0_ZERO=1 )
(
input wire [4:0] RA, RB, RW,
input wire [31:0] DW,
output wire [31:0] DA, DB,
input wire CLK,
input wire WE
input wire [4:0] RA, RB, RW,
input wire [RWIDTH-1:0] DW,
output wire [RWIDTH-1:0] DA, DB,
input wire CLK,
input wire WE
);
wire [RWIDTH-1:0] sel1, sel2, selw;
wire [RCOUNT-1:0] sel1, sel2, selw;

DEC5x32 DEC0 ( .A(RA), .SEL(sel1) );
DEC5x32 DEC1 ( .A(RB), .SEL(sel2) );
Expand All @@ -156,12 +156,12 @@ module DFFRF_2R1W #(parameter RWIDTH=32,
generate
genvar e;
if(R0_ZERO == 1)
RFWORD0 RFW0 ( .CLK(CLK), .SEL1(sel1[0]), .SEL2(sel2[0]), .SELW(selw[0]), .D1(DA), .D2(DB));
RFWORD0 #(.RWIDTH(RWIDTH)) RFW0 ( .CLK(CLK), .SEL1(sel1[0]), .SEL2(sel2[0]), .SELW(selw[0]), .D1(DA), .D2(DB));
else
RFWORD RFW0 ( .CLK(CLK), .WE(WE), .SEL1(sel1[0]), .SEL2(sel2[0]), .SELW(selw[0]), .D1(DA), .D2(DB), .DW(DW) );
RFWORD #(.RWIDTH(RWIDTH)) RFW0 ( .CLK(CLK), .WE(WE), .SEL1(sel1[0]), .SEL2(sel2[0]), .SELW(selw[0]), .D1(DA), .D2(DB), .DW(DW) );

for(e=1; e<RCOUNT; e=e+1) begin : REGF
RFWORD #(.RWIDTH(RWIDTH)) RFW ( .CLK(CLK), .WE(WE), .SEL1(sel1[e]), .SEL2(sel2[e]), .SELW(selw[e]), .D1(DA), .D2(DB), .DW(DW) );
end
endgenerate
endmodule
endmodule
11 changes: 11 additions & 0 deletions verification/Makefile
Original file line number Diff line number Diff line change
@@ -1,14 +1,25 @@
PATTERN = tb_RAM32x32
RCOUNT = 32
RWIDTH = 32

INCLUDE_PATHS=../platforms/sky130A/sky130_fd_sc_hd
RTL_PATH=../platforms/sky130A/BB/ram/model.v
RF_PATH=../platforms/sky130A/BB/rf/model.v

IVL_FLAGS= -DFUNCTIONAL $(addprefix -I ,$(INCLUDE_PATHS))
DFFRF_TB=tb_DFFRF$(RCOUNT)x$(RWIDTH)

.SUFFIXES:
.PRECIOUS: %.v %.vvp
all: ${PATTERN:=.vcd}

tb_dffrf:
$(eval RCOUNT=$(shell sh -c "echo "${PATTERN}" | grep -o -P '(?<=tb_DFFRF).*(?=x)'"))
$(eval RWIDTH=$(shell sh -c " echo "${PATTERN}" | grep -o -P '(?<=x).*(?=_2R1W)'"))
iverilog -o $(DFFRF_TB).vvp -DMODEL_FILEPATH=$(RF_PATH) -DRCOUNT=$(RCOUNT) -DRWIDTH=$(RWIDTH) \
$(IVL_FLAGS) dffrf_tb.v
vvp $(DFFRF_TB).vvp

%.vcd: %.vvp
vvp $<

Expand Down
240 changes: 240 additions & 0 deletions verification/dffrf_tb.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,240 @@
/*
An auto generated testbench to verify RAM{word_num}x{word_size}
Authors: Mohamed Shalan ([email protected])
Ahmed Nofal ([email protected])
*/
`define VERBOSE_1
`define VERBOSE_2

`define UNIT_DELAY #1

`define USE_LATCH 1

`define tb_DFFRF_module(count, width) tb_DFFRF``count``x``width``_2R1W
`define tb_DFFRF_module_vcd_file(count, width) `"tb_DFFRF``count``x``width``_2R1W.vcd`"


/* Those macros are passed on the command line */
/* `define RWIDTH */
/* `define RCOUNT */
/* `include `MODEL_FILEPATH */

`include "hd_primitives.v"
`include "hd_functional.v"

`include "../platforms/sky130A/BB/rf/model.v"


module `tb_DFFRF_module(`RCOUNT, `RWIDTH);

localparam RWIDTH = `RWIDTH;
localparam RCOUNT = `RCOUNT;
localparam SIZE = RWIDTH/8;
localparam A_W = $clog2(RWIDTH);

reg [4:0] RA, RB, RW;
reg [(RWIDTH-1):0] DW;
wire [(RWIDTH-1):0] DA, DB;
reg CLK;
reg [7:0] Phase;
reg [7:0] RANDOM_BYTE;
reg WE;
event done;

DFFRF_2R1W #(.RWIDTH(RWIDTH), .RCOUNT(RCOUNT), .R0_ZERO(1) ) RFILE
( .RA(RA),
.RB(RB),
.RW(RW),
.DW(DW),
.DA(DA),
.DB(DB),
.CLK(CLK),
.WE(WE)
);

initial begin
$dumpfile(`tb_DFFRF_module_vcd_file(`RCOUNT, `RWIDTH));
$dumpvars(0, `tb_DFFRF_module(`RCOUNT, `RWIDTH));
@(done) $finish;
end

/* Memory golden Model */
reg [(RWIDTH-1):0] DFFRF[(RCOUNT-1):0];
reg [(RWIDTH-1):0] DFFRF_DATA_READA;
reg [(RWIDTH-1):0] DFFRF_DATA_READB;

always @(posedge CLK) begin
DFFRF_DATA_READA <= DFFRF[RA];
DFFRF_DATA_READB <= DFFRF[RB];
if(WE) DFFRF[RW] <= DW;
end

always #10 CLK = !CLK;

integer i;

initial begin
CLK = 0;
WE = 0;

Phase = 0;
// Perform a 2 word write then read 2 words
mem_write_word({SIZE{8'h90}}, 4);
mem_write_word({SIZE{8'h33}}, 8);
mem_read_2words(4,8);

/***********************************************************
Write and read from different ports
************************************************************/

// Fill the memory with a known pattern
// Word Write then Read
Phase = 1;
`ifdef VERBOSE_1
$display("\n\tFinished Phase 0, starting Phase 1\n");
`endif
for(i=1; i<RCOUNT; i=i+1) begin
RANDOM_BYTE = $urandom;
mem_write_word({SIZE{RANDOM_BYTE}}, i);
mem_read_word_B(i);
end


/***********************************************************
Write and read from same port
************************************************************/
Phase = 2;
`ifdef VERBOSE_1
$display("\n\tFinished Phase 1, starting Phase 2\n");
`endif
for(i=1; i<RCOUNT; i=i+1) begin
RANDOM_BYTE = $urandom;
mem_write_word({SIZE{RANDOM_BYTE}}, i);
mem_read_word_A(i);
end

Phase = 3;
`ifdef VERBOSE_1
$display("\n\tFinished Phase 2, starting Phase 3\n");
`endif
for(i=1; i<RCOUNT; i=i+1) begin
RANDOM_BYTE = $urandom;
mem_read_2words_write_1($urandom % RCOUNT,
$urandom % RCOUNT,
$urandom % RCOUNT,
{SIZE{RANDOM_BYTE}});
end

$display ("\n>> Test Passed! <<\n");
-> done;
end

/***********************************************************
TASKS
************************************************************/
task mem_write_word(input [RWIDTH-1:0] word, input [A_W-1:0] addr);
begin
@(posedge CLK);
RW = addr;
WE = 1;
DW = word;
@(posedge CLK);
`ifdef VERBOSE_2
$display("WRITE WORD: 0x%X to %D", word, addr);
`endif
WE = 0;
end
endtask

task mem_read_word_A(input [A_W-1:0] addr);
begin
@(posedge CLK);
RA = addr;//[9:2];
@(posedge CLK);
#5;
`ifdef VERBOSE_2
$display("READ WORD A: 0x%X from %D", DA, RA);
`endif
checkA();
end
endtask

task checkA; begin
if(DFFRF_DATA_READA !== DA) begin
$display("\n>>Test Failed! CheckA <<\t(Phase: %0d, Iteration: %0d", Phase, i);
$display("Register: %D, READ: 0x%X - Should be: 0x%X", RA, DA, DFFRF[RA]);
$fatal(1);
end
end
endtask

task mem_read_word_B(input [A_W-1:0] addr);
begin
@(posedge CLK);
RB = addr;
@(posedge CLK);
#5;
`ifdef VERBOSE_2
$display("READ WORD B: 0x%X from %0D", DB, RB);
`endif
checkB();
end
endtask

task checkB; begin
if(DFFRF_DATA_READB !== DB) begin
$display("\n >>Test Failed! checkB << \t(Phase: %0d, Iteration: %0d", Phase, i);
$display("Register: %D, READ: 0x%X - Should be: 0x%X", RB, DB, DFFRF[RB]);
$fatal(1);
end
end
endtask

task mem_read_2words(input [A_W-1:0] addr0,
input [A_W-1:0] addr1);
begin
@(posedge CLK);
RA= addr0;
RB= addr1;
@(posedge CLK);
#5;
`ifdef VERBOSE_2
$display("READ WORDA: 0x%X from %D", DA, addr0);
$display("READ WORDB: 0x%X from %D", DB, addr1);
`endif
checkA();
checkB();
end
endtask
task mem_read_2words_write_1(input [A_W-1:0] addrA,

input [A_W-1:0] addrB,
input [A_W-1:0] addrW,
input [RWIDTH-1:0] dataW);
begin
@(posedge CLK);
RA= addrA;
RB= addrB;
RW= addrW;
DW= dataW;
WE= 1;
@(posedge CLK);
#5;
`ifdef VERBOSE_2
$display("READ WORDA: 0x%X from %D", DA, addrA);
$display("READ WORDB: 0x%X from %D", DB, addrB);
$display("WRITE WORD: 0x%X to %D", dataW, addrW);
`endif
checkA();
checkB();
WE= 0;
end
endtask

endmodule
6 changes: 3 additions & 3 deletions verification/tb_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,9 +131,9 @@
localparam M_SZ = 2**A_W;
reg CLK;
reg [(SIZE-1):0] WE0;
reg EN0;
reg ENR;
reg [(SIZE-1):0] WE0;
reg EN0;
reg ENR;
reg [(SIZE*8-1):0] Di0;
wire [(SIZE*8-1):0] Do0;
wire [(SIZE*8-1):0] Do1;
Expand Down

0 comments on commit 618be36

Please sign in to comment.