双口RAM(dual port RAM)在异构系统中应用广泛,通过双口RAM,不同硬件架构的芯片可以实现数据的交互,从而实现通信。例如,一般情况下,ARM与DSP之间的通信,可以利用双口RAM实现,ARM通过EBI总线连接到双口RAM的A口,DSP通过EMIF总线(也可以是uPP总线,取决于速度需求)连接到双口RAM的B口,两者对同一块存储区域进行操作,即可实现两者的数据交互。
但是,因为双口RAM的A口和B口都可以对相同的内存地址进行操作,这就引出了一个问题—假如通信双方在两个端口对同一地址同时读写,就会引发冲突。要解决这个问题,办法有二。
//产生RAM PORTB读地址
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
r_addr <= 9&#39;d0;
/*
这里是为了让读地址比写地址延迟一个周期
你可能会想,当w_addr=1不等于9&#39;d0的时候,r_addr不是也加1变成1了吗?
怎么就实现了延迟一个时钟周期了呢?
那是因为r_addr是寄存器类型的变量,只有在下一个时钟周期才能采集到此时的值。
*/
else if (|w_addr) //w_addr位或,不等于0
r_addr <= r_addr+1&#39;b1;
else
r_addr <= 9&#39;d0;
end
//产生RAM PORTA写使能信号
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
wea <= 1&#39;b0;
else
begin
if(&w_addr) //w_addr的bit位全为1,共写入512个数据,写入完成
wea <= 1&#39;b0;
else
wea <= 1&#39;b1; //ram写使能
end
end
//产生RAM PORTA写入的地址及数据
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
w_addr <= 9&#39;d0;
w_data <= 16&#39;d0;
end
else
begin
if(wea)//ram写使能有效
begin
//当写地址全为1的时候,说明已经写够512个数据,就可以不用写使能了。
if (&w_addr)
begin
w_addr <= w_addr ; //将地址和数据的值保持住,只写一次RAM
w_data <= w_data ;
end
else
begin
w_addr <= w_addr + 1&#39;b1;
w_data <= w_data + 1&#39;b1;
end
end
end
end