数字IC设计——SRAM的Verilog语⾔实现(三)(双端⼝SRAM)
数字IC设计——SRAM的Verilog语⾔实现(三)(双端⼝SRAM)
在FPGA设计中,经常会⽤到RAM,这⾥的RAM⼀般指的是静态的RAM(SRAM)。⼀般FPGA(如xilinx)中就有所谓的block RAM,它就是现成的RAM资源,我们如果合理编写verilog代码,就可以使我们想要的RAM被综合成block RAM,从⽽节省逻辑资源,⽽且性能更优。
主要设计如下ram:
1)⽤Verilog实现⼀个同步双端⼝sram,深度16,位宽8bit。A⼝读出,B⼝写⼊。⽀持⽚选,读写请求,要求代码可综合。
2)⽤Verilog实现⼀个异步双端⼝sram,深度16,位宽8bit。A⼝读出,B⼝写⼊。⽀持⽚选,读写请求,要求代码可综合。
3)⽤Verilog实现⼀个同步双端⼝sram,深度16,位宽8bit。A⼝可读可写,B⼝可读可写。⽀持⽚选,读写请求,要求代码可综合。⼀、⽤Verilog实现⼀个同步双端⼝sram,深度16,位宽8bit
要求:A⼝读出,B⼝写⼊。
⽀持⽚选,读写请求,要求代码可综合。
1. Verilog 代码实现
module mini_sp_ram #(
parameter ADDR_WIDTH=4,
parameter DATA_WIDTH=8,沉默是金英文
parameter DATA_DEPTH=16
)(
input clk,
input rst_n,
input cn_n,//⽚选信号
//port A signal
英文歌下载
input [ ADDR_WIDTH-1:0] addr_a,//读地址
input rdena_n,//读信号
output reg [ DATA_WIDTH-1:0] data_a,
//port B signal
input [ ADDR_WIDTH-1:0] addr_b,//写地址
input wrenb_n,//写信号
input [ DATA_WIDTH-1:0] data_b
);
integer i;
reg [DATA_WIDTH-1:0] register [DATA_DEPTH-1:0];//定义⼀个深度为16,位宽为8的存储器
always @(podge clk or negedge rst_n) begin
if(rst_n ==1'b0) begin //初始化
for(i=0; i<DATA_DEPTH;i=i+1) begin
register[i]<=8'b0000_1111;
end
end
el if(wrenb_n ==1'b0 && cn_n == 1'b0) begin //写信号低有效
大量的register[addr_b]<= data_b;//写⼊
end
end
always @(podge clk or negedge rst_n) begin
if(rst_n ==1'b0) begin //输出初始化
data_a <=8'h0;
end
jedwardel if(rdena_n ==1'b0 && cn_n == 1'b0) begin //读信号低有效
data_a <= register[addr_a];//读出
end
el begin
任务英文data_a <= data_a;
end
end
endmodule邀请函英文
2. 通过两个分别独⽴的端⼝data_a和data_b,rdena_n和wrenb_n分别控制读写请求信号。
当置位信号置0时,对存储器register 进⾏初始化0000_1111
写信号有效时,给⼀个写进内存的地址addr_b以及要写进该地址的数data_b。wbt
读信号有效时,给⼀个写进内存的地址addr_a以及要读出该地址的数data_a。
register[addr_b] <= data_b; //写⼊
data_a <= register[addr_a]; //读出
3. 测试代码testbench:
module mem_tb(
);
reg clk,rst_n,cn_n;
reg rdena_n,wrenb_n;
reg [3:0] addr_a,addr_b;
reg [7:0] data_b;
wire [7:0] data_a;
integer i;
mini_sp_ram #(.ADDR_WIDTH(4),
.DATA_WIDTH(8),
.DATA_DEPTH(16)
)u_ram(
.clk(clk),
.rst_n(rst_n),
_n(cn_n),
.wrenb_n(wrenb_n),
.
rdena_n(rdena_n),
.addr_a(addr_a),
.addr_b(addr_b),
.data_a(data_a),
.data_b(data_b)
);
考研要带的东西//clk generate
always #5 clk =~clk;
initial begin
clk =1'b1;
rst_n =1'b0;
cn_n =1'b1;
wrenb_n =1'b1;
rdena_n =1'b1;
顾问英文
addr_a = 'b0;
#30
rst_n =1'b1;
cn_n =1'b0;
#5
@(podge clk)
wrenb_n =1'b0;//写信号有效
for(i=0;i<16;i=i+1)begin
@(podge clk) begin
addr_b = i;//存储器每⼀个地址号
data_b =8'b0000_0000+i;//每个循环向存储器中写⼊⼀个数据
end
end
#30
wrenb_n =1'b1;
@(podge clk)
rdena_n =1'b0;//读信号有效
for(i=0;i<16;i=i+1)begin
@(podge clk)begin
addr_a = i;//每个循环向外部data_a读出⼀个存储器地址内的数值 end
end
#30
cn_n =1'b1;
//200s stop
#100 $stop;
end
威廉婚礼
endmodule
其中测试过程中在连续的时钟周期内,产⽣⼀串读写地址:
4. 测试结果:
下图可以看到仿真过程中存储器 register 中数据值。
⼆、⽤Verilog实现⼀个异步双端⼝ram,深度16,位宽8bit
要求:
A⼝读出,B⼝写⼊。
⽀持⽚选,读写请求,要求代码可综合。