FPGA:双口RAM

双口RAM

利用Xilinx提供的IP核构建真双口RAM,通过状态机实现从A口写数据,从B口读取数据。同样也可以在B口写入数据,A口读取数据。这样的双口RAM可以用在异构系统中。

IP核配置

IP核Block Memory Generator配置过程如下:

  1. Basic 类型选择Native,True Dual Port RAM;
    其他默认就好
    2.Port A
    3.
    3.Port B
    在这里插入图片描述
  2. Other options:在这里插入图片描述
  3. Summary:在这里插入图片描述

Verilog代码

top文件

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2018/12/18 16:28:04
// Design Name: 
// Module Name: ram_ftt
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module ram_ftt(
              input clk,
              input rst,
              input ena,
              input enb,
              input wea,
              input [9:0]addr,
              input [15:0]din,
              output [15:0]douta,
              output [15:0]dout               
    );
    
    reg rst_n;
//    reg ena;
//    reg enb;
//    reg wea;
    reg web;
    reg [9:0]addra;
    reg [9:0]addrb;
    reg [15:0]dina;
    reg [15:0]dinb;
//    reg [15:0]douta;
    reg [15:0]doutb;
    reg [15:0]din_reg;
//    reg [31:0]dout;
    reg [3:0] current_state,next_state;
    reg write_end;
    reg read_end;
     reg [15:0]ram [9:0];
    reg [15:0]read_ram [9:0];
   // integer i=0;
    parameter 
            idle=4'b0000,
            write=4'b0001,
            read=4'b0010;  
// assign din=dina;
// assign dout=doutb;
//第一个always块,时序逻辑,描述现态转移到次态
    always @ (posedge clk or negedge rst) begin
        if(!rst) begin
            current_state<=idle;
            end
        else
            current_state<=next_state;
    end
    
    //第二个always块,组合逻辑,描述状态转移的条件
    always @ (current_state or wea) begin                                                                                                                      
        case(current_state)
        idle:begin
            if(wea)        next_state <= write;//状态转移
            else           next_state <= idle;
            end
        write:begin
            if(!wea)       next_state <= read;//状态转移
            else                next_state <= write;
            end
         read:begin
             if(addr==10)     next_state <= idle;//状态转移
             else             next_state <= read;
             end
        default: begin
                next_state = idle;//状态转移
               end
        endcase
    end
    //第三个always块,时序逻辑,描述输出
    always @ (negedge clk or negedge rst) begin
    if(!rst)begin
            //addra<=0;
            //addra<=addr;
            //dina <= din;
           // dina<=0;
           // addrb<=0;
          end
    else
        case(current_state)
        idle: begin 
                   // addra<=0;
                    addra<=0;
                    dina<=0;
                   
                   // addrb<=0;
               end
        write: begin   
                    //i=i+1;
                    addra<=addr;                                                                                                                               
                    //addra<=i;   
                    dina<=din; 
                end
        read:begin
                  addrb=addr;                                         
               end
        default:begin
                 write_end<=0;
                 read_end<=0;
                end
        endcase
    end
 blk_mem_gen_0 sim(
            .clka(clk),
            .clkb(clk),
            .ena(ena),
            .enb(enb),
            .wea(wea),
            .web(),
            .addra(addra),
            .addrb(addrb),
            .dina(dina),
            .dinb(),
            .douta(douta),
            .doutb(dout)
            );  
endmodule

testbench

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2018/12/17 15:06:05
// Design Name: 
// Module Name: sim
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module simu;
    //module top(clka,clkb,ena,enb,wea,web,addra,addrb,dia,dib,doa,dob);  
    reg clk;
    reg rst;
    reg ena;
    reg enb;
    reg wea;
    reg [9:0]addr;
    reg [15:0]din;
wire [15:0]douta;
    wire [15:0]dout;
    reg[15:0] ram_a [9:0];
    integer i=0;
initial $readmemh("F:/date0.txt",ram_a);    

    initial begin 
             clk=0;
             rst=1;
             addr=0;
             ena=0;
             enb=0;
             wea=0;
             din=1;
        #50   rst= 0;
        #50   rst=1;
              ena= 1;
              wea=1;
              enb=1;
              addr=0;

    end
    always #10 clk =  ~clk;

always @(negedge clk or negedge rst)
    begin 
    if(!rst)begin
            addr<=1;
            end
    else begin       
             addr<=addr+1;     
             if(addr>=10)  begin
                          wea<=!wea;    
                          addr<=1; 
                          end 
             
            if(wea) din<= ram_a[addr];  
           end
 
     end
ram_ftt sim(.clk(clk),.rst(rst),.addr(addr),.din(din),.ena(ena),.enb(enb),.wea(wea),.douta(douta),.dout(dout));
endmodule

仿真图

直接输入1次#,并按下space后,将生成1级标题。输入2次#,并按下space后,将生成2级标题。以此类推,我们支持6级标题。有助于使用语法后生成一个完美的目录。

猜你喜欢

转载自blog.csdn.net/wb3jdw58/article/details/85208515
今日推荐