我的verilog代码有什么问题?

时间:2015-02-27 17:34:14

标签: verilog

我想写verilog中的寄存器文件,即写入和读取数据寄存器。 这是我的代码:

module registerfile(writeaddr1,writedata1,readaddr2,readdata2,readaddr3,readdata3,write,clock);
input [4:0] writeaddr1, readaddr2, readaddr3;
input [31:0] writedata1;
output[31:0]readdata2,readdata3;
reg [31:0]readdata2,readdata3;
input write,clock;
reg [31:0] cells [0:31];
always @(posedge clock) 
begin
if (write == 1) cells[writeaddr1] =writedata1;
   readdata2 = cells[readaddr2];
    readdata3 = cells[readaddr3];
end
endmodule

这是我的测试台。

module testreg;
  reg [3:0]addr1,addr2,addr3;
  reg [31:0]data1;
  reg write;
    wire [31:0]data2,data3;
reg clock ; //Rising edge every 10 timesteps
registerfile regf(addr1,data1,addr2,data2,addr3,data3,write,clock);
initial begin
  addr1=1;
  addr2=2;
  addr3=3;
  write=0;
  data1=32'bx;
  clock=0;
  #10
  addr1=1;
  addr2=1;
  addr3=3;
  write=1;
  data1=30;
  clock=1;
  #10
  $finish;
end
endmodule

但我不知道为什么10到20之间的data2是xxx?我在那个地方写了30 :(

1 个答案:

答案 0 :(得分:3)

如果clk的周期为20ns,则在0ns和20ns之间应用第一次写入,但data2不是data1,因为读取和写入是同时的,并且当您在内存上写入值时,在下一个clk上升沿,您可以从内存中读取相同的值。然后介于20ns和40ns之间(在clk上升沿上)data2等于data1


testreg模块中addr1的大小应为[4:0]

 reg [4:0] addr1,addr2,addr3;

正如Greg在模块registerfile中所说,最好使用非阻塞分配(<=),例如以下代码:

always @(posedge clock) 
    if (write) begin
        cells[writeaddr1] <= writedata1;
        readdata2 <= cells[readaddr2];
        readdata3 <= cells[readaddr3];
    end

只需使用以下代码并继续运行模拟直到40ns:

initial begin
    addr1=1;
    data1=30;
    addr2=1;
    write=1;
end

initial begin
    clock = 0;
    forever #10 clock = ~clock;
end

我使用上述更改模拟了您的代码,可以得到正确的结果。