1. 程式人生 > >FPGA:雙口RAM

FPGA:雙口RAM

Xilinx IP核構建雙口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級標題。有助於使用語法後生成一個完美的目錄。