Verilog Register File和TestBench

时间:2015-04-08 17:35:46

标签: verilog system-verilog modelsim

所以我正在为它编写一个简单的寄存器文件和测试平台。在测试平台中,我想简单地在寄存器中写入一些for循环中的数字(如0到9)然后再读取这些数字。但我非常困惑,因为寄存器有两个DATA和ADDR端口,不像内存,它真的让我失望。具体来说,我在寄存器和测试台中使用什么来读写(寄存器的位置)?

这是我试过的:

Register_File

`include "prj_definition.v"
module REGISTER_FILE_32x32(DATA_R1, DATA_R2, ADDR_R1, ADDR_R2, 
                            DATA_W, ADDR_W, READ, WRITE, CLK, RST);

// input list
input READ, WRITE, CLK, RST;
input [`DATA_INDEX_LIMIT:0] DATA_W;
input [`REG_ADDR_INDEX_LIMIT:0] ADDR_R1, ADDR_R2, ADDR_W;

// output list
output [`DATA_INDEX_LIMIT:0] DATA_R1;
output [`DATA_INDEX_LIMIT:0] DATA_R2;

//reg [`DATA_INDEX_LIMIT:0] data_ret; // return data register 
integer i; // index for reset opeations

reg [`DATA_INDEX_LIMIT:0] DATA_R1;
reg [`DATA_INDEX_LIMIT:0] DATA_R2;
reg [`DATA_INDEX_LIMIT:0] sram_32x32m [0:`MEM_INDEX_LIMIT]; // memory storage

// Parameter for the memory initialization file name
//parameter mem_init_file = "mem_content_01.dat";

//what am I supposed to be assigning to?
assign DATA_W = ((READ===1'b1)&&(WRITE===1'b0))?ADDR_R1:{`DATA_WIDTH{1'bz} }; //drives the bus during read operation
assign DATA_W = ((READ===1'b1)&&(WRITE===1'b0))?ADDR_R2:{`DATA_WIDTH{1'bz} }; //drives the bus during read operation

initial 
begin
DATA_R1 = {`DATA_WIDTH{1'b0} }; //initializing content of all 32 registers as 0
DATA_R2 = {`DATA_WIDTH{1'b0} }; //initializing content of all 32 registers as 0
for(i = 0;i <= `MEM_INDEX_LIMIT; i = i + 1) //up to 32
    sram_32x32m[i] = {`DATA_WIDTH{1'b0}};

end

always @ (negedge RST or posedge CLK)
begin
// TBD: Code for the register file model
if (RST === 1'b0)
begin
for(i = 0;i <= `MEM_INDEX_LIMIT; i = i + 1) //up to 32
    sram_32x32m[i] = {`DATA_WIDTH{1'b0}};

//$readmemh(mem_init_file, sram_32x32m);

end
else
begin
 if ((READ===1'b1)&&(WRITE===1'b0))// for read operation
 begin 
    DATA_R1 =  sram_32x32m[ADDR_R1];
    DATA_R2 =  sram_32x32m[ADDR_R2];
 end
 else if ((READ===1'b0)&&(WRITE===1'b1)) // for write operation
    sram_32x32m[ADDR_W] = DATA_W;
end
end
endmodule

测试平台

`include "prj_definition.v"
module REGISTER_FILE_TB;

// Storage list
reg [`ADDRESS_INDEX_LIMIT:0] ADDR_R1;
reg [`ADDRESS_INDEX_LIMIT:0] ADDR_R2;
//reg [`ADDRESS_INDEX_LIMIT:0] DATA_W;
reg [`ADDRESS_INDEX_LIMIT:0] ADDR_W;

// reset
reg READ, WRITE, RST;

// data register
reg [`DATA_INDEX_LIMIT:0] DATA_REG;
integer i; // index for memory operation
integer no_of_test, no_of_pass;
integer load_data;

// wire lists
wire  CLK;
wire [`DATA_INDEX_LIMIT:0] DATA_W;
//wire [`DATA_INDEX_LIMIT:0] ADDR_W;


assign DATA_W = ((READ===1'b0)&&(WRITE===1'b1))?DATA_REG:{`DATA_WIDTH{1'bz} }; //drives the bus during write operation


// Clock generator instance
CLK_GENERATOR clk_gen_inst(.CLK(CLK));

// register instantiation
REGISTER_FILE reg_inst(.DATA_R1(DATA_R1), .DATA_R2(DATA_R2), .ADDR_R1(ADDR_R1), .ADDR_R2(ADDR_R2), 
    .DATA_W(DATA_W), .ADDR_W(ADDR_W), .READ(READ), .WRITE(WRITE), .CLK(CLK), .RST(RST));

initial
begin
RST=1'b1;
READ=1'b0;
WRITE=1'b0;
DATA_REG = {`DATA_WIDTH{1'b0} };
no_of_test = 0;
no_of_pass = 0;


// Start the operation
#10    RST=1'b0;
#10    RST=1'b1;
// Write cycle
for(i=1;i<10; i = i + 1)
begin
#10     DATA_REG=i; READ=1'b0; WRITE=1'b1; ADDR_W = i;
end

// Read Cycle
#10   READ=1'b0; WRITE=1'b0;
#5    no_of_test = no_of_test + 1;
      if (DATA_R1 !== {`DATA_WIDTH{1'bz}}) // if it's not read or write, then data should come out to highZ
        $write("[TEST] Read %1b, Write %1b, expecting 32'hzzzzzzzz, got %8h [FAILED]\n", READ, WRITE, DATA_REG);
      else 
    no_of_pass  = no_of_pass + 1;

// test of write data
for(i=0; i<10; i = i + 1)
begin
#5      READ=1'b1; WRITE=1'b0; ADDR_W = i;
#5      no_of_test = no_of_test + 1;
        if (DATA_R1 !== i)
        $write("[TEST] Read %1b, Write %1b, expecting %8h, got %8h [FAILED]\n", READ, WRITE, i, DATA_R1);
        else 
        no_of_pass  = no_of_pass + 1;

end

#10    READ=1'b0; WRITE=1'b0; // No op

#10 $write("\n");
    $write("\tTotal number of tests %d\n", no_of_test);
    $write("\tTotal number of pass  %d\n", no_of_pass);
    $write("\n");
    $stop;
end
endmodule

以下是我从TestBench获得的输出:

# [TEST] Read 0, Write 0, expecting 32'hzzzzzzzz, got 00000009 [FAILED]
# [TEST] Read 1, Write 0, expecting 00000000, got        x [FAILED]
# [TEST] Read 1, Write 0, expecting 00000001, got        x [FAILED]
# [TEST] Read 1, Write 0, expecting 00000002, got        x [FAILED]
# [TEST] Read 1, Write 0, expecting 00000003, got        x [FAILED]
# [TEST] Read 1, Write 0, expecting 00000004, got        x [FAILED]
# [TEST] Read 1, Write 0, expecting 00000005, got        x [FAILED]
# [TEST] Read 1, Write 0, expecting 00000006, got        x [FAILED]
# [TEST] Read 1, Write 0, expecting 00000007, got        x [FAILED]
# [TEST] Read 1, Write 0, expecting 00000008, got        x [FAILED]
# [TEST] Read 1, Write 0, expecting 00000009, got        x [FAILED]

对于这篇长篇文章感到抱歉,但如果有人能指出我正确的方向,或者至少给我一些可以帮我解决这个问题的事情,我将非常感激。感谢您仔细阅读!

0 个答案:

没有答案