对 (2^n) x m 单端口 RAM 建模
Modeling a (2^n) x m single port RAM
我正在使用 Verilog 对 (2^n) x m 单端口 ram 进行建模。这个 ram 有一个输入使能端口,输入读写端口 (rw),当它为 1 时,我们将写入 ram,当它为 0 时,我们将只读取,输入地址端口 (addr),inout 数据端口和一个输入 write_data 端口。
这里是设计代码:
module single_port_ram # ( parameter n=4,m=4) (rw,addr,data,enable);
input rw,enable;
inout [m-1:0]data;
input [n-1:0] addr;
reg [m-1:0] ram [(2**n)-1:0];
reg [m-1:0]data_reg;
assign data = (enable & !rw ) ? data_reg : {(m-1){1'bz}};
always @ (*) begin
if(enable) begin
if(rw)
ram[addr]<=data;// wrtite to the ram address
else
data_reg <= ram[addr] ; // read from ram address
end
end
endmodule
这是测试台代码:
module t_b # ( parameter n=4 , m=4);
reg rw,enable;
reg [n-1:0] addr;
// Variables needed for the read and write strategy to/from the bi-directional port
wire [m-1:0]data;
reg [m-1:0]write_data; // input data to be written
assign data = (enable & rw) ? write_data: {(m-1){1'bz}};
single_port_ram tb (.rw(rw),.enable(enable),.addr(addr),.data(data));
initial begin
$dumpfile("dump.vcd");
$dumpvars;
end
initial begin
// write
enable=1; rw=1 ; #20
addr=1; write_data='b 1 ; #20
// write again
enable=1; rw=1 ; #20
addr=2; write_data='b0 ; #20
// read
rw=0 ; addr=1; #10
$finish;
end
endmodule
问题是当我们写入时,ram 应该在其数据双向端口中输出 z 值,而当我们读取时,应该在数据双向端口中输出所需的值。我的代码不是这种情况。如果你模拟一下,你会发现数据端口会跟随我们写的时候write_data端口的值。这个问题的原因是什么?我认为它在tb代码中。
在您的测试台中,您目前总是设置 enable=1
,这永远不会让您在数据上看到 z
。如果您设置 enable=0
,您将在数据上看到 z
。例如:
// read
rw=0 ; addr=1; #10
// read
enable=0; rw=0 ; addr=1; #10
$finish;
此外,z
常量的位宽有误。变化:
{(m-1){1'bz}}
至:
{m{1'bz}}
我正在使用 Verilog 对 (2^n) x m 单端口 ram 进行建模。这个 ram 有一个输入使能端口,输入读写端口 (rw),当它为 1 时,我们将写入 ram,当它为 0 时,我们将只读取,输入地址端口 (addr),inout 数据端口和一个输入 write_data 端口。
这里是设计代码:
module single_port_ram # ( parameter n=4,m=4) (rw,addr,data,enable);
input rw,enable;
inout [m-1:0]data;
input [n-1:0] addr;
reg [m-1:0] ram [(2**n)-1:0];
reg [m-1:0]data_reg;
assign data = (enable & !rw ) ? data_reg : {(m-1){1'bz}};
always @ (*) begin
if(enable) begin
if(rw)
ram[addr]<=data;// wrtite to the ram address
else
data_reg <= ram[addr] ; // read from ram address
end
end
endmodule
这是测试台代码:
module t_b # ( parameter n=4 , m=4);
reg rw,enable;
reg [n-1:0] addr;
// Variables needed for the read and write strategy to/from the bi-directional port
wire [m-1:0]data;
reg [m-1:0]write_data; // input data to be written
assign data = (enable & rw) ? write_data: {(m-1){1'bz}};
single_port_ram tb (.rw(rw),.enable(enable),.addr(addr),.data(data));
initial begin
$dumpfile("dump.vcd");
$dumpvars;
end
initial begin
// write
enable=1; rw=1 ; #20
addr=1; write_data='b 1 ; #20
// write again
enable=1; rw=1 ; #20
addr=2; write_data='b0 ; #20
// read
rw=0 ; addr=1; #10
$finish;
end
endmodule
问题是当我们写入时,ram 应该在其数据双向端口中输出 z 值,而当我们读取时,应该在数据双向端口中输出所需的值。我的代码不是这种情况。如果你模拟一下,你会发现数据端口会跟随我们写的时候write_data端口的值。这个问题的原因是什么?我认为它在tb代码中。
在您的测试台中,您目前总是设置 enable=1
,这永远不会让您在数据上看到 z
。如果您设置 enable=0
,您将在数据上看到 z
。例如:
// read
rw=0 ; addr=1; #10
// read
enable=0; rw=0 ; addr=1; #10
$finish;
此外,z
常量的位宽有误。变化:
{(m-1){1'bz}}
至:
{m{1'bz}}