那曲檬骨新材料有限公司

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

FPGA RAM簡介和使用案例

CHANBAEK ? 來源:工程實驗室 ? 作者:工程實驗室 ? 2023-08-22 16:12 ? 次閱讀

FPGA 邏輯設計中經常用到的數據存儲方式有ROMRAM和FIFO,根據不同的應用場景選擇不同的存儲方式。Xilinx 平臺三種存儲方式在使用過程中的區別如下:

1、ROM按照地址讀寫,使用初始化.ceo文件將地址和對應的數據內容存入,讀數據的時候給地址,輸出地址中存儲的數據。支持反復讀取,讀取過程中不會使數據減少;

2、RAM按照地址讀寫數據,按照指定的地址寫入數據,讀數據的時候給地址,輸出地址中存儲的數據,支持反復讀取,讀取過程中不會使數據減少;

3、FIFO沒有地址參與,先寫入的數據被先讀出,就是先進先出,讀取數據的過程中讀一個少一個,就像雞蛋放在籃子中取出一個少一個。

01 RAM簡介

RAM,random access memory,是隨機存取存儲器的縮寫,掉電后數據丟失。 這里使用簡單雙端口RAM舉例,即端口A寫數據,端口B讀數據。

圖片

端口A寫入數據的過程中WEA==1'b1 && ENA==1'b1,條件同時滿足的時候,DINA的數據被寫入到指定的內存地址中。

圖片

端口B讀出數據的時候,讀使能和讀地址同時有效,讀出數據需要延遲一個時鐘周期。

圖片

1.1、vivado中添加RAM-IP核

step1:在ip-catalog中搜索ram,找到 block memory generator

圖片

step2:在ip核配置

圖片

step3:端口A設置(寫入數據位寬和深度)

圖片

step4:端口B設置(注意細節)

圖片

step5:其他設置

圖片

02 RAM使用案例

2.1、簡單雙端口RAM使用案例

簡單雙端口RAM使用的案例有1、數據緩沖-實現位寬轉化;2、對應連續待處理的數據流使用乒乓RAM,實現數據流不間斷的輸入到處理模塊。本文主要對乒乓RAM做一個詳細介紹和測試應用。

圖片

2.2、乒乓RAM讀寫時序設計

乒乓RAM讀寫時序設計波形圖中讀寫時鐘使用了相同的時鐘信號,當讀寫數據的時鐘不同時,就是異步乒乓RAM。首先對RAMA寫入數據,按地址寫入數據結束以后讀取RAMA的數據給數據處理模塊,同時將外部輸入的數據緩存到RAMB中,保證同一時間內既有數據緩存又有數據輸出,實現的效果就是外部不間斷地輸入數據,經過RAM處理以后不間斷地輸出到下一級處理模塊。

圖片

圖2-2-1、乒乓RAM讀寫時序設計

2.3、代碼實現

根據時序設計波形圖2-2-1,編寫邏輯代碼,
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2022/01/08 19:19:47
// Design Name: 
// Module Name: pingpang_ram
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////
module pingpang_ram(
input      wire                sclk,
input      wire                async_rst_n,   
input      wire                wr_valid, 
input      wire [7:0]          data_in,
output     wire [7:0]          data_out
    );


//  信號定義 
localparam                  ADDR_MAX                  =              1024       -        1;  
// rama   
reg                        wr_en_a;
reg  [9  :  0]             wr_addr_a;           // 寫地址  
reg                        rd_en_a;
reg  [9  :  0]             rd_addr_a;           // 讀地址  
wire [7  :  0]             rd_data_a;      
reg                        wr_en_a_dly;
// ramb  
reg                        wr_en_b;
reg  [9  :  0]             wr_addr_b;           // 寫地址  
reg                        rd_en_b;
reg  [9  :  0]             rd_addr_b;           // 讀地址  
wire [7  :  0]             rd_data_b;     
//  
wire   sync_rst_n; 
reg    sync_rst_n1; 
reg    sync_rst_n2; 


assign      sync_rst_n           =              sync_rst_n2 ;
assign    data_out               =              (wr_en_a_dly   ==  1'b0 )  ?     rd_data_a    :    rd_data_b;         // 符合條件后---立即響應 


// 異步復位,同步釋放,異步復位信號,同步處理
always@(posedge sclk or negedge async_rst_n)   begin 
    if(!async_rst_n)   begin 
    sync_rst_n1    <=     1'b0;                             //  復位開始的時候 wr_en 就開始有效    
    sync_rst_n2    <=     1'b0;     
    end  
    else  begin 
    sync_rst_n1    <=       1'b1;   
    sync_rst_n2    <=       sync_rst_n1;  
     end 
end  
//  wr_en   
always@(posedge sclk or negedge sync_rst_n)   begin 
    if(!sync_rst_n)   begin 
    wr_en_a   <=     1'b0;                                
    end  
    else if (wr_valid  ==   1'b1   )  begin 
    wr_en_a     <=       1'b1;     
    end    
    else if(wr_addr_a   ==   ADDR_MAX)   begin  
    wr_en_a     <=      1'b0;
    end 
    else if(rd_addr_a   ==   ADDR_MAX)   begin  
    wr_en_a     <=      1'b1;
    end   
end 


//   寫地址信號  
always@(posedge sclk or negedge sync_rst_n)   begin 
     if(!sync_rst_n)   begin 
     wr_addr_a     <=      16'd0;                          
     end  
     else if(wr_addr_a   ==   ADDR_MAX) begin
     wr_addr_a     <=       16'd0;       
     end       
     else if(wr_en_a   ==  1'b1 )  begin                    
     wr_addr_a     <=    wr_addr_a      +     1'b1;
     end 
end 
//   讀使能信號  
always@(posedge sclk or negedge sync_rst_n)   begin 
     if(!sync_rst_n)   begin 
      rd_en_a          <=            1'b0;                          
     end  
     else if(wr_addr_a   ==   ADDR_MAX) begin                    
      rd_en_a          <=            1'b1;    
     end 
      else if (rd_addr_a    ==     ADDR_MAX) begin                  
      rd_en_a          <=            1'b0;     
     end 
end 
always@(posedge sclk or negedge sync_rst_n)   begin 
      wr_en_a_dly          <=            wr_en_a;                          
     end      
//   讀地址信號  
always@(posedge sclk  or  negedge sync_rst_n)   begin 
    if(!sync_rst_n)   begin 
      rd_addr_a          <=     10'd0;                             
    end  
    else if(rd_addr_a   ==  ADDR_MAX) begin
      rd_addr_a          <=         10'd0;  
    end      
    else if(rd_en_a    ==     1'b1)   begin                         
      rd_addr_a         <=     rd_addr_a          +        1'b1;
    end 
end 
// ---------RAMB   
always@(posedge sclk or negedge sync_rst_n)   begin 
    if(!sync_rst_n)   begin 
    wr_en_b   <=     1'b0;                                 
    end  
    else if(wr_addr_b   ==   ADDR_MAX)   begin  
    wr_en_b     <=      1'b0;
    end 
    else if(wr_addr_a   ==   ADDR_MAX)   begin                 //  寫完RAMA -開始寫RAMB    
    wr_en_b    <=      1'b1;
    end   
end 
//   寫地址信號  
always@(posedge sclk or negedge sync_rst_n)   begin 
     if(!sync_rst_n)   begin 
     wr_addr_b     <=      16'd0;                            
     end  
     else if(wr_addr_b   ==   ADDR_MAX) begin
     wr_addr_b     <=       16'd0;       
     end       
     else if(wr_en_b   ==  1'b1 )  begin                    
     wr_addr_b     <=    wr_addr_b      +     1'b1;
     end 
end 
//   讀使能信號  
always@(posedge sclk or negedge sync_rst_n)   begin 
     if(!sync_rst_n)   begin 
      rd_en_b          <=            1'b0;                          
     end  
     else if(wr_addr_b   ==   ADDR_MAX) begin                    
      rd_en_b          <=            1'b1;    
     end 
      else if (rd_addr_b    ==     ADDR_MAX) begin                  
      rd_en_b          <=            1'b0;     
     end 
end    
//   讀地址信號  
always@(posedge sclk  or  negedge sync_rst_n)   begin 
    if(!sync_rst_n)   begin 
      rd_addr_b          <=     10'd0;                              
    end  
    else if(rd_addr_b   ==  ADDR_MAX) begin
      rd_addr_b          <=         10'd0;  
    end      
    else if(rd_en_b    ==     1'b1)   begin                          
      rd_addr_b         <=     rd_addr_b          +         1'b1;
    end 
end 
//----------- Begin Cut here for INSTANTIATION Template ---// INST_TAG
ram_8x1024       a_instance_name (
  .clka(sclk),            // input wire clka
  .ena(wr_en_a),       // input wire ena
  .wea(wr_en_a),       // input wire [0 : 0] wea
  .addra(wr_addr_a),   // input wire [9 : 0] addra
  .dina(data_in),         // input wire [7 : 0] dina
  .clkb(sclk),            // input wire clkb
  .enb(rd_en_a),       // input wire enb
  .addrb(rd_addr_a),   // input wire [9 : 0] addrb
  .doutb(rd_data_a)       // output wire [7 : 0] doutb
);


//----------- Begin Cut here for INSTANTIATION Template ---// INST_TAG
ram_8x1024       b_instance_name (
  .clka(sclk),               // input wire clka
  .ena(wr_en_b),        // input wire ena
  .wea(wr_en_b),        // input wire [0 : 0] wea
  .addra(wr_addr_b),    // input wire [9 : 0] addra
  .dina(data_in),            // input wire [7 : 0] dina
  .clkb(sclk),               // input wire clkb
  .enb(rd_en_b),        // input wire enb
  .addrb(rd_addr_b),    // input wire [9 : 0] addrb
  .doutb(rd_data_b)          // output wire [7 : 0] doutb
);
endmodule

仿真激勵文件

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2022/01/08 20:24:11
// Design Name: 
// Module Name: tb_pingpang_ram
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////
module tb_pingpang_ram();
reg                       sclk;
reg                       async_rst_n;
reg                       wr_valid;
reg [7:0]                 data_in;
wire [7:0]                data_out;


initial  begin 
sclk    =        0;
forever          #5
sclk    =       ~sclk;
end  


initial  begin 
        async_rst_n          <=        0;
        wr_valid             <=        0;  
        #100  
        async_rst_n          <=        1;
        #10
        @(posedge    sclk)
        @(posedge    sclk)
        @(posedge    sclk)
        @(posedge    sclk)
        wr_valid                  <=             1;       
        #10
        wr_valid                  <=             0;
        gen_data(  );
end  
//@(posedge    wr_valid)
//gen_data(  );
//end 
task  gen_data;
integer     i;  
begin
    for(i= 0;      i   <   12288;      i =    i   +   1)  begin
        @(posedge   sclk)
           data_in     =       i[7:0];
        end  
    end 
endtask   
pingpang_ram     u_pingpang_ram(
    .sclk        ( sclk        ),
    .async_rst_n ( async_rst_n ),
    .wr_valid    ( wr_valid    ),
    .data_in     ( data_in     ),
    .data_out    ( data_out    )
);
endmodule

2.4、仿真驗證結果

圖片

圖2-2-1、乒乓RAM仿真結果-輸出數據連續

圖片

圖2-2-2、乒乓RAM仿真結果-輸入-輸出數據對應

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • FPGA
    +關注

    關注

    1630

    文章

    21796

    瀏覽量

    605987
  • ROM
    ROM
    +關注

    關注

    4

    文章

    575

    瀏覽量

    85987
  • RAM
    RAM
    +關注

    關注

    8

    文章

    1369

    瀏覽量

    114999
  • Xilinx
    +關注

    關注

    71

    文章

    2171

    瀏覽量

    122127
  • 邏輯設計
    +關注

    關注

    1

    文章

    41

    瀏覽量

    11609
收藏 人收藏

    評論

    相關推薦

    利用FPGA實現雙口RAM的設計及應用

    利用FPGA實現雙口RAM的設計及應用 概述:為了在高速采集時不丟失數據,在數據采集系統和
    發表于 04-16 14:08 ?1.2w次閱讀
    利用<b class='flag-5'>FPGA</b>實現雙口<b class='flag-5'>RAM</b>的設計及應用

    FPGA中塊RAM的分布和特性

    在選擇FPGA時,關注LUT(Look-Up Table)和BRAM(Block RAM)是非常重要的,因為它們是FPGA架構中的兩個核心資源,對于設計的性能和資源利用至關重要。
    的頭像 發表于 11-21 15:03 ?2731次閱讀
    <b class='flag-5'>FPGA</b>中塊<b class='flag-5'>RAM</b>的分布和特性

    如何實現ASIC RAM替換為FPGA RAM

    大家好, 我使用Ultrascale Virtex Devices和Vivado工具, 在ASIC RAM中,ther是一個單獨的奇偶校驗寫使能位,但在FPGA RAM中沒有單獨的Pariaty寫使能位。 如何實現ASIC
    發表于 04-24 09:37

    FPGA簡介

    (06)FPGA資源評估1.1 目錄1)目錄2)FPGA簡介3)Verilog HDL簡介4)FPGA資源評估5)結語1.2
    發表于 02-23 06:31

    基于Actel FPGA的雙端口RAM設計

    基于Actel FPGA 的雙端口RAM 設計雙端口RAM 芯片主要應用于高速率、高可靠性、對實時性要求高的場合,如實現DSP與PCI 總線芯片之間的數據交換接口電路等。但普通雙端口RAM
    發表于 11-15 17:44 ?82次下載

    Cyclone FPGA系列簡介

    Cyclone FPGA系列簡介
    發表于 12-26 22:02 ?0次下載

    _FPGA內部的RAM M9K

    FPGA內部的RAM M9K
    發表于 04-07 11:40 ?4次下載

    技術控:FPGARAM使用技巧探索

    FPGARAM的使用探索。以4bitX4為例,數據位寬為4,深度為4。
    的頭像 發表于 03-28 17:07 ?1w次閱讀
    技術控:<b class='flag-5'>FPGA</b>中<b class='flag-5'>RAM</b>使用技巧探索

    FPGARAM存儲資源詳細資料說明

    本文檔的主要內容詳細介紹的是FPGARAM存儲資源詳細資料說明包括了:1、 FPGA存儲資源簡介,2、 不同廠家的 Block RAM
    發表于 12-09 15:31 ?10次下載
    <b class='flag-5'>FPGA</b>的<b class='flag-5'>RAM</b>存儲資源詳細資料說明

    FPGA硬件基礎之FPGARAM存儲課件和工程文件

    本文檔的主要內容詳細介紹的是FPGA硬件基礎之FPGARAM存儲課件和工程文件。
    發表于 12-10 15:27 ?30次下載
    <b class='flag-5'>FPGA</b>硬件基礎之<b class='flag-5'>FPGA</b>的<b class='flag-5'>RAM</b>存儲課件和工程文件

    使用FPGA調用RAM資源的詳細說明

    FPGA可以調用分布式RAM和塊RAM兩種RAM,當我們編寫verilog代碼的時候如果合理的編寫就可以使我們想要的RAM被綜合成BRAM(
    發表于 12-30 16:27 ?9次下載

    如何使用FPGA內部的RAM以及程序對該RAM的數據讀寫操作

    RAMFPGA中常用的基礎模塊,可廣泛用于緩存數據的情況,同樣它也是ROM,FIFO的基礎。本實驗將為大家介紹如何使用FPGA內部的RAM以及程序對該
    的頭像 發表于 02-08 15:50 ?1.4w次閱讀
    如何使用<b class='flag-5'>FPGA</b>內部的<b class='flag-5'>RAM</b>以及程序對該<b class='flag-5'>RAM</b>的數據讀寫操作

    基于FPGA的ROM的實現簡介

    基于FPGA的ROM的實現簡介(嵌入式開發工程師培訓學校)-該文檔為基于FPGA的ROM的實現簡介資料,講解的還不錯,感興趣的可以下載看看…………………………
    發表于 07-30 09:08 ?5次下載
    基于<b class='flag-5'>FPGA</b>的ROM的實現<b class='flag-5'>簡介</b>

    FPGA電源簡介

    FPGA電源簡介
    發表于 11-04 09:51 ?0次下載
    <b class='flag-5'>FPGA</b>電源<b class='flag-5'>簡介</b>

    fpga雙口ram的使用

    FPGA雙口RAM的使用主要涉及配置和使用雙端口RAM模塊。雙端口RAM的特點是有兩組獨立的端口,可以對同一存儲塊進行讀寫操作,從而實現并行訪問。
    的頭像 發表于 03-15 13:58 ?1104次閱讀
    百家乐官网筹码| k7百家乐官网最小投注| 大发888娱乐官方网站| 百家乐荷| 百利宫百家乐的玩法技巧和规则| 豪享博百家乐官网的玩法技巧和规则 | 亚洲百家乐官网论坛| 百家乐官网自动算牌软件| 电子百家乐官网技巧| 百家乐官网侧牌器| 网上的百家乐官网怎么才能| 澳门百家乐官网牌规| 百家乐官网送錢平臺| 都坊百家乐官网的玩法技巧和规则 | 百家乐官网黄金城游戏大厅 | 澳门百家乐官网战法| 在线赌博平台| 黄大仙区| 百家乐官网平台出租家乐平台出租 | 澳门百家乐免费开户| 百家乐庄闲和各| 利来百家乐娱乐| 大发888 赌博网站大全| 澳客网比分直播| 百家乐官网视频游戏道具| 大发888官方6222.co| 百家乐怎样赢| 百家乐官网5式直缆投注法| 聚众玩百家乐官网的玩法技巧和规则| 百家乐官网纯技巧打| 百家乐打庄技巧| 豪华百家乐桌子| 百家乐娱乐求解答| 最新棋牌游戏| 澳门百家乐官网网上赌| 百家乐官网网站可信吗| 澳门百家乐官网论坛及玩法| 公海百家乐的玩法技巧和规则| 百家乐网上真钱娱乐| 中华德州扑克论坛| 澳门百家乐官网棋牌游戏|