首先导入两个单口ram的IP核,我设置的是写优先模式,同时设置了一个写使能信号
首先设置状态机,第一个状态为闲置状态,第二个状态为写ram1,只把数据写进ram,不输出。第三个状态,写ram2读ram1,第四个状态为结束状态。自定义了一个信号为读使能信号,其实也不是读使能,就是决定输出是哪个ram的一个使能信号。读写的时候地址都要加1,所以定义了一个cnt信号作为状态转移。
接下来上代码:
module sing_ram2(
input clka,
input rst_n,
input [7:0] din,
output reg out_valid,
output reg [7:0] dout,
output wire [7:0] douta,
output wire [7:0] doutb,
output reg [1:0] state
);
reg [9:0] addra;
reg [9:0] addrb;
reg [9:0] cnt;
reg we_wr1,we_wr2,en_rd1,en_rd2;
parameter IDLE = 2'b00;
parameter RAM1_WR = 2'b01;
parameter RAM1_RD = 2'b10;
parameter RAM2_RD = 2'b11;
always @(posedge clka or negedge rst_n)
if(!rst_n)
cnt<=0;
else
cnt<=cnt+1;
always @(posedge clka or negedge rst_n)
if(!rst_n)
begin
state<=IDLE;
we_wr1<=1'b1;
en_rd1<=1'b0;
we_wr2<=1'b0;
en_rd2<=1'b0;
addra<=10'd0;
addrb<=10'd0;
end
else
begin
case(state)
IDLE : if(we_wr1)
state<=RAM1_WR;
else
state<=IDLE;
RAM1_WR: if (we_wr1)
begin
if(addra ==10'd1023)
begin
addra <= 10'd0;
state <= RAM1_RD;
end
else begin
addra <= addra + 10'd1;
state <= RAM1_WR;
we_wr1<=1'b1;
en_rd1<=1'b0;
we_wr2<=1'b0;
en_rd2<=1'b0;
end
end
RAM1_RD :
if(cnt ==10'd1023)
begin
// addrb <= 10'd0;
state <= RAM2_RD;
end
else begin
addrb <= addrb + 10'd1;
addra <= addra + 10'd1;
state <= RAM1_RD;
we_wr1<=1'b0;
en_rd1<=1'b1;
we_wr2<=1'b1;
en_rd2<=1'b0;
end
RAM2_RD : if(cnt==10'd1023)
begin
//addra <= 10'd0;
state <= RAM1_RD;
end
else begin
addra <= addra + 10'd1;
addrb <= addrb + 10'd1;
state <= RAM2_RD;
we_wr1<=1'b1;
en_rd1<=1'b0;
we_wr2<=1'b0;
en_rd2<=1'b1;
end
endcase
end
always @(posedge clka or negedge rst_n)
begin
if(!rst_n)
begin
dout<=0;
out_valid<=0;
end
else if(en_rd1)
begin
dout<=douta;
out_valid<=1;
end
else if(en_rd2)
begin
dout<=doutb;
out_valid<=1;
end
else
begin
dout<=8'b0;
out_valid<=0;
end
end
其实开始的时候也用一个双口ram试过,但是后来发现虽然双口ram的地址是a,b。但是它们是用同一个内存,所以写ram2的话就会把ram1的覆盖掉,不能进行同时读写的操作。