首先需要实现一个memory, reg[7:0]mem[15:0]。这样定义出来的是16个8bit位宽的寄存器
module dpram_16x8 (
input clk,
input [3:0] addr_a,
input [7:0] din_b,
input [3:0] addr_b,
input ce,
input we,
output reg[7:0] dout_a
);
parameter word_size=8;
parameter addr=16;
reg[word_size-1:0]mem[addr-1:0];
//synopsys_translate_off
integer i;
initial begin
dout_a=8'b0;
for(i=0; i<addr;i=i+1) begin
mem[i] = 8'h00;
end
end// synopsys_translate_on
always@(posedge clk)begin
if(ce==1&&we==1)begin
mem[addr_b]<=din_b;
end
else if(ce==1&&we==0)begin
dout_a<=mem[addr_a];
end
end
endmodule
下面为testbench 其中需要注意的是
1、@(negedge clk)指的是对clk的下降边沿敏感,但是这个操作只会执行一次。若是想多次执行的话可以用for语句。
2、for(i=0;i<16;i=i+1)中的i要注意其位宽,不然可能会产生溢出。因为这个是testbench,所以定义的位宽远大于所需要的位数也是可以的,在本次设计中我就使用了integer i 此时i为32位。
module sram_tb();
reg clk=0;
reg[3:0]addr_a=0;
reg[7:0]din_b=0;
reg[3:0]addr_b=0;
reg ce=1;
reg we=0;
integer i;
wire[7:0]dout_a;
always #5 clk=~clk;
initial begin
@(negedge clk)begin
we=0;
ce=1;
end
for(i=0;i<16;i=i+1)begin
@(negedge clk) addr_a=i;
end
@(negedge clk)begin
we=1;
ce=1;
end
for(i=0;i<16;i=i+1)begin
@(negedge clk)begin
addr_b=i;
din_b=din_b+1;
end
end
@(negedge clk)begin
we=0;
end
for(i=0;i<16;i=i+1)begin
@(negedge clk)begin
addr_a=i;
end
end
@(negedge clk)begin
ce=0;
end
#100 $stop;
end
dpram_16x8 u1(
.clk(clk),
.addr_a(addr_a),
.din_b(din_b),
.addr_b(addr_b),
.ce(ce),
.we(we),
.dout_a(dout_a)
);
endmodule
最后的仿真结果