真双口RAM IP的使用

1 IP的例化

第一个配置界面:
Block Memory Gnerator一共可以产生5种不同类型的内存空间,
其中block RAM有三种:单口RAM、简化双口RAM和真双口RAM。
单口RAM只有一个端口(A端口),可以对A端口进行读写。
简化双口RAM有两个端口(A和B端口),但是A端口只能进行写入操作,不能进行读出操作,而B端口则只能进行读出操作,不能进行写入操作。
真双口RAM有两个端口(A和B端口),A和B端口都能进行读写操作。
在这里插入图片描述
第二个配置界面:
Operating Mode(操作模式)一共有三种:Write First,Read First,No Change。
在Write First模式中,在一个时钟周期里,写入内存单元的数据被同步输出到输出数据总线上;
在Read First模式中,在一个时钟周期里,写入到内存单元的数据是当前输入数据总线上的数据,
而输出到输出数据总线上的数据则是上一个时钟周期存储在内存单元中的数据。
细节可参考PG058的49到50页4。Enable Port Type设置为Always Enabled,一直使能端口A。

在这里插入图片描述

第三个配置界面:

在这里插入图片描述

其他窗口保持默认。

在这里插入图片描述

2 源代码

2.1 顶层文件


```cpp
`timescale 1ns / 1ps

/*
注意点:

(1)Block Memory Gnerator一共可以产生5种不同类型的内存空间,
其中block RAM有三种:单口RAM、简化双口RAM和真双口RAM[4]。
单口RAM只有一个端口(A端口),可以对A端口进行读写。
简化双口RAM有两个端口(A和B端口),但是A端口只能进行写入操作,不能进行读出操作,而B端口则只能进行读出操作,不能进行写入操作。
真双口RAM有两个端口(A和B端口),A和B端口都能进行读写操作


(2)Operating Mode(操作模式)一共有三种:Write First,Read First,No Change。
在Write First模式中,在一个时钟周期里,写入内存单元的数据被同步输出到输出数据总线上;
在Read First模式中,在一个时钟周期里,写入到内存单元的数据是当前输入数据总线上的数据,
而输出到输出数
##据总线上的数据则是上一个时钟周期存储在内存单元中的数据。
细节可参考PG058的49到50页4。Enable Port Type设置为Always Enabled,一直使能端口A。


*/

module True_TwoPort_RAM(
    input   clk,
    input   rst_n,
    input   trig  //RAM工作信号
);
 
 
 
 
/*模块功能:
    count=0到99,RAM不工作
    count=100到199,RAM写数据
    count=200到299,RAM不工作
    count=300到399,RAM读数据
    count=其他值,RAM不工作
*/    
reg            RAM_en      ;  // RAM 使能信号
reg            wea         ;  // wea=1,RAM写数据;  wea=0,RAM读数据。
reg [15:0]     addr        ;  // RAM的读写地址
reg [15:0]     Write_Data  ;  // RAM写入数据
reg [15:0]     count       ;  
always @ (posedge clk)  
begin
    if(!rst_n)
        begin
           RAM_en      <=1'b0;// RAM 使能信号
           wea         <=1'b0;
           addr        <=16'd0;
           Write_Data  <=16'd0;
           count       <=16'd0; 
        end
    else 
        if(trig==1'b1) 
            begin
                count <= count + 1'd1;  
                if( count<10'd100 )  //count=0到99,RAM不工作
                    begin  
                        RAM_en  <= 1'b0;  // RAM 使能信号
                        wea     <= 1'b0;   // wea=1,RAM写数据;  wea=0,RAM读数据。
                    end  
                else if( (count >=10'd100) && (count < 10'd200))//count=100到199,RAM写数据
                    begin  
                        RAM_en <= 1'b1;  // RAM 使能信号
                        wea    <= 1'b1;   // wea=1,RAM写数据;  wea=0,RAM读数据。
                        addr <= addr + 10'd1;  
                        Write_Data <= Write_Data + 1'd1;  
                    end  
                else if( (count >=10'd200) && (count < 10'd300) ) // count=200到299,RAM不工作
                    begin  
                        RAM_en <= 1'b0;     //RAM IP不工作
                        wea    <= 1'b0;   // wea=1,RAM写数据;  wea=0,RAM读数据。
                        addr <= 10'd0;      //地址清零
                        Write_Data <= 128'd0;    //数据清零
                    end  
                else if((count >=10'd300) && (count < 10'd400) )//count=300到399,RAM读数据
                    begin  
                        RAM_en <= 1'b1;  
                        wea    <= 1'b0;   // wea=1,RAM写数据;  wea=0,RAM读数据。
                        addr <= addr + 10'd1;  
                    end  
                else     //count=其他值,RAM不工作
                    begin  
                        RAM_en <= 1'b0;  //RAM IP不工作
                        count <= count;  //          
                    end
        end
        else
            begin
               RAM_en      <=RAM_en    ;// RAM 使能信号
               wea         <=wea       ;
               addr        <=addr      ;
               Write_Data  <=Write_Data;
               count       <=count     ; 
            end                     
end  
  
     
// ena:RAM IP 使能信号  ,ena=1,RAM IP工作 
// wea:wea=1,写数据;wea=0,读数据。
wire[15:0]     Read_Data   ;  // RAM读出数据    
True_TwoPort_RAM_ip Inst_True_TwoPort_RAM_ip (
   .clka    (clk        ),      // input wire clka
   .ena     (RAM_en     ),      // input wire ena   RAM IP 使能信号
   .wea     (wea        ),      // input [0 : 0]    wea=1,写数据;wea=0,读数据。
   .addra   (addr       ),      // input [15 : 0] addra  
   .dina    (Write_Data ),      // input [15 : 0] dina   
   .douta   (Read_Data  ),      // output [15 : 0] douta 
   
   .clkb(clk),    // input wire clkb
   .enb(),      // input wire enb
   .web(),      // input wire [0 : 0] web
   .addrb(),  // input wire [9 : 0] addrb
   .dinb(),    // input wire [127 : 0] dinb
   .doutb()  // output wire [127 : 0] doutb
); 
 
 
 
    
    
    
endmodule

2.2 testbench文件

`timescale 1ns / 1ps


module sim_top;


 //input
reg clk;
reg rst_n;
reg trig;

True_TwoPort_RAM Inst_True_TwoPort_RAM(
    .clk    (clk    ),
    .rst_n  (rst_n  ),
    .trig   (trig   )
);


// 初始化   
initial
begin
    //初始化输入
    clk<=1'b0;
    rst_n<=1'b0;
    trig<=1'b0;
    #20;
    rst_n<=1'b1;
    trig<=1'b1;
end

// create clock;
always #5 clk=~clk;//10ns一个周期,clk的频率为100M


endmodule


3 仿真结果

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值