女人自慰AV免费观看内涵网,日韩国产剧情在线观看网址,神马电影网特片网,最新一级电影欧美,在线观看亚洲欧美日韩,黄色视频在线播放免费观看,ABO涨奶期羡澄,第一导航fulione,美女主播操b

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

基于FPGA BRAM的多端口地址查找表與FPGA BRAM的資源分析

網(wǎng)絡(luò)交換FPGA ? 來源:網(wǎng)絡(luò)交換FPGA ? 2024-05-01 14:03 ? 次閱讀

一、背景

在多端口交換機(jī)的設(shè)計(jì)中,交換機(jī)的每個(gè)端口都會(huì)各自維護(hù)一張查找表,數(shù)據(jù)幀進(jìn)入到交換機(jī)后,需要進(jìn)行查表和轉(zhuǎn)發(fā)。但隨著端口數(shù)量和表項(xiàng)需求的增加,每個(gè)端口都單獨(dú)維護(hù)一張表使得FPGA的資源變得非常緊張。因此,需要一張查找表(本質(zhì)是可讀可寫的RAM),能夠滿足多讀多寫的功能。但在Xilinx FPGA上,Xilinx提供的BRAM IP最高只能實(shí)現(xiàn)真雙端口RAM。不能滿足多讀多寫的需求。

補(bǔ)充:這里不使用其他RAM類型如URAM的原因是,BRAM擁有更好的時(shí)序,更適合在高速交換中用于查找表。

二、手寫Multiport Ram

Multiport Ram,即多讀多寫存儲(chǔ)器,本工程實(shí)現(xiàn)的是1個(gè)口寫,同時(shí)滿足11個(gè)口讀的BRAM

為了讓vivado在綜合的時(shí)候把手寫ram例化為BRAM,我們需要按照官方手冊(cè)的要求編寫multiport ram。這時(shí)需要通過(*ram_style="block"*)對(duì)array進(jìn)行修飾。

查看Vivado的官方手冊(cè)u(píng)g901可知,對(duì)于Distributed RAM(LUTRAM)和Dedicated Block RAM(BRAM),二者都是寫同步的。主要區(qū)別在于讀數(shù)據(jù),前者為異步,后者為同步的。

1eb9cb74-0065-11ef-a297-92fbcf53809c.png

下面給出一種手寫多端口bram的方案并給出一種優(yōu)化FPGA bram資源利用的方法。

Multiport RAM 代碼方案

實(shí)現(xiàn)多端口bram最簡(jiǎn)單的方法就是把讀數(shù)據(jù)部分的邏輯復(fù)制11份,寫數(shù)據(jù)部分的邏輯保留1份。

部分代碼如下,實(shí)現(xiàn)位寬73bit,深度為16K的multiport ram:

(*ram_style="block"*)reg [DATA_WIDTH-1:0] bram [0:DEPTH-1];
/*-------------復(fù)制讀端口11份---------------*/
    always @(posedge clk)
    begin
        if(re1)
            rd_data1 <= bram[rd_addr1];
        else
            rd_data1 <= rd_data1;
????end
/*-----------------------------------------*/
    //write
    always @(posedge clk)
    begin
        if(we)
            bram[wr_addr]<=wr_data;
    end
endmodule

資源評(píng)估

利用vivado綜合實(shí)現(xiàn)后,消耗的資源如下

1ee47342-0065-11ef-a297-92fbcf53809c.png

MultiportRAM16K深度,73位寬的單口寫,11口讀的RAM消耗的BRAM數(shù)為192個(gè)。

普通真雙口RAM:利用vivado IP核生成的16K深度,73bit位寬的真雙口RAM消耗的BRAM數(shù)為32個(gè)。即如果11個(gè)端口各自維護(hù)一張地址查找表共使用352個(gè)RAM。

對(duì)比發(fā)現(xiàn),在滿足11個(gè)端口同時(shí)讀地址查找表的條件下,多端口RAM比普通RAM節(jié)約了45%左右的BRAM資源

三、Multiport RAM 資源利用的優(yōu)化

可能有的同學(xué)說,在某些大工程里面,192個(gè)BRAM還是有點(diǎn)多。下面我給出了一種降低BRAM資源消耗的方法。

首先我們把例化的ram array的位寬翻倍

//原本
(*ram_style="block"*)reg [DATA_WIDTH-1:0] bram [0:DEPTH-1];
//現(xiàn)在
(*ram_style="block"*)reg [DATA_WIDTH+DATA_WIDTH-1:0] bram [0:DEPTH-1];

(有同學(xué)會(huì)問了,這樣資源消耗不是翻倍了嗎?···別急!)

我們把需要寫入RAM的數(shù)據(jù),73位寫data復(fù)制成兩份,同時(shí)寫進(jìn)bram的高73位和低73位,地址不變,其中multi_wdata是我們要寫進(jìn)表中的73位表項(xiàng),代碼如下:

//bram例化模塊的寫使能、地址和數(shù)據(jù)
    .we       (   multi_wr),
    .wr_addr  (multi_waddr),
.wr_data({multi_wdata,multi_wdata})

在bram輸出中,每?jī)蓚€(gè)端口共用一個(gè)143位的bram行,并根據(jù)使能情況賦值:

   //read1
    assign rd_data1_wire = rd_data1[72:0]  ;
    assign rd_data2_wire = rd_data2[145:73];
    always @(posedge clk)
    begin
        if (re1 & re2) begin
            rd_data1 <=  bram[rd_addr1];
            rd_data2 <=  bram[rd_addr2];
        end
        else 
        if(re1) begin
             rd_data1 <=  bram [rd_addr1];
        end
        else if (re2) begin
            rd_data2 <= bram [rd_addr2];
        end 


    end

***補(bǔ)充:具體代碼在文章開頭鏈接

資源評(píng)估

利用vivado綜合實(shí)現(xiàn)后,消耗的資源如下

1efb0be8-0065-11ef-a297-92fbcf53809c.png

MultiportRAM:16K深度,146位寬的單口寫,11口讀的RAM消耗的BRAM數(shù)為112個(gè)。

普通真雙口RAM:利用vivado IP核生成的16K深度,73bit位寬的真雙口RAM消耗的BRAM數(shù)為32個(gè)。即如果11個(gè)端口各自維護(hù)一張表共使用352個(gè)RAM

對(duì)比發(fā)現(xiàn),在滿足11個(gè)端口同時(shí)讀地址查找表的條件下,多端口RAM比普通RAM節(jié)約了68%左右的BRAM資源

四、防止讀寫沖突的組合邏輯設(shè)計(jì)(寫優(yōu)先)

代碼原理,利用組合邏輯時(shí)序,當(dāng)寫入地址和讀地址相同時(shí),寫入地址、數(shù)據(jù)正常進(jìn)行但讀端口不對(duì)RAM進(jìn)行讀取,而是將寫入端的數(shù)據(jù)直接賦值給讀出端的數(shù)據(jù)。

下一拍,即讀寫沖突結(jié)束后的下一拍,再讀一拍RAM中的數(shù)據(jù),使得讀端口數(shù)據(jù)保持這一次讀的結(jié)果(因?yàn)榻M合邏輯在讀寫沖突時(shí)沒有真正讀RAM,所以RAM輸出data會(huì)保持上一次輸出的data),但這一步不是必要的,純粹為了好看。

部分代碼如下:

//防止讀寫沖突,且為寫優(yōu)先邏輯
assign multi_rdata0 =(multi_raddr0_f ==multi_waddr_f && multi_raddr0_f !='b0 )?multi_wdata_f:multi_rdata0_ram ;
assign multi_rdata1 =(multi_raddr1_f ==multi_waddr_f && multi_raddr1_f !='b0 )?multi_wdata_f:multi_rdata1_ram ;
assign multi_rdata2 =(multi_raddr2_f ==multi_waddr_f && multi_raddr2_f !='b0 )?multi_wdata_f:multi_rdata2_ram ;
assign multi_rdata3 =(multi_raddr3_f ==multi_waddr_f && multi_raddr3_f !='b0 )?multi_wdata_f:multi_rdata3_ram ;
assign multi_rdata4 =(multi_raddr4_f ==multi_waddr_f && multi_raddr4_f !='b0 )?multi_wdata_f:multi_rdata4_ram ;
assign multi_rdata5 =(multi_raddr5_f ==multi_waddr_f && multi_raddr5_f !='b0 )?multi_wdata_f:multi_rdata5_ram ;
assign multi_rdata6 =(multi_raddr6_f ==multi_waddr_f && multi_raddr6_f !='b0 )?multi_wdata_f:multi_rdata6_ram ;
assign multi_rdata7 =(multi_raddr7_f ==multi_waddr_f && multi_raddr7_f !='b0 )?multi_wdata_f:multi_rdata7_ram ;
assign multi_rdata8 =(multi_raddr8_f ==multi_waddr_f && multi_raddr8_f !='b0 )?multi_wdata_f:multi_rdata8_ram ;
assign multi_rdata9 =(multi_raddr9_f ==multi_waddr_f && multi_raddr9_f !='b0 )?multi_wdata_f:multi_rdata9_ram ;
assign multi_rdata10=(multi_raddr10_f==multi_waddr_f && multi_raddr10_f!='b0 )?multi_wdata_f:multi_rdata10_ram;


assign multi_raddr0_ram =(multi_raddr0_f ==multi_waddr_f && multi_raddr0_f !='b0 )?multi_waddr_f: multi_raddr0;
assign multi_raddr1_ram =(multi_raddr1_f ==multi_waddr_f && multi_raddr1_f !='b0 )?multi_waddr_f: multi_raddr1;
assign multi_raddr2_ram =(multi_raddr2_f ==multi_waddr_f && multi_raddr2_f !='b0 )?multi_waddr_f: multi_raddr2;
assign multi_raddr3_ram =(multi_raddr3_f ==multi_waddr_f && multi_raddr3_f !='b0 )?multi_waddr_f: multi_raddr3;
assign multi_raddr4_ram =(multi_raddr4_f ==multi_waddr_f && multi_raddr4_f !='b0 )?multi_waddr_f: multi_raddr4;
assign multi_raddr5_ram =(multi_raddr5_f ==multi_waddr_f && multi_raddr5_f !='b0 )?multi_waddr_f: multi_raddr5;
assign multi_raddr6_ram =(multi_raddr6_f ==multi_waddr_f && multi_raddr6_f !='b0 )?multi_waddr_f: multi_raddr6;
assign multi_raddr7_ram =(multi_raddr7_f ==multi_waddr_f && multi_raddr7_f !='b0 )?multi_waddr_f: multi_raddr7;
assign multi_raddr8_ram =(multi_raddr8_f ==multi_waddr_f && multi_raddr8_f !='b0 )?multi_waddr_f: multi_raddr8;
assign multi_raddr9_ram =(multi_raddr9_f ==multi_waddr_f && multi_raddr9_f !='b0 )?multi_waddr_f: multi_raddr9;
assign multi_raddr10_ram=(multi_raddr10_f==multi_waddr_f && multi_raddr10_f!='b0 )?multi_waddr_f: multi_raddr10;






assign multi_rd0_ram =(multi_raddr0 ==multi_waddr && multi_raddr0!='b0  )?  1'b0:((multi_raddr0_f ==multi_waddr_f && multi_raddr0_f !='b0  )?multi_rd0_f :multi_rd0 );
assign multi_rd1_ram =(multi_raddr1 ==multi_waddr && multi_raddr1!='b0  )?  1'b0:((multi_raddr1_f ==multi_waddr_f && multi_raddr1_f !='b0  )?multi_rd1_f :multi_rd1 );
assign multi_rd2_ram =(multi_raddr2 ==multi_waddr && multi_raddr2!='b0  )?  1'b0:((multi_raddr2_f ==multi_waddr_f && multi_raddr2_f !='b0  )?multi_rd2_f :multi_rd2 );
assign multi_rd3_ram =(multi_raddr3 ==multi_waddr && multi_raddr3!='b0  )?  1'b0:((multi_raddr3_f ==multi_waddr_f && multi_raddr3_f !='b0  )?multi_rd3_f :multi_rd3 );
assign multi_rd4_ram =(multi_raddr4 ==multi_waddr && multi_raddr4!='b0  )?  1'b0:((multi_raddr4_f ==multi_waddr_f && multi_raddr4_f !='b0  )?multi_rd4_f :multi_rd4 );
assign multi_rd5_ram =(multi_raddr5 ==multi_waddr && multi_raddr5!='b0  )?  1'b0:((multi_raddr5_f ==multi_waddr_f && multi_raddr5_f !='b0  )?multi_rd5_f :multi_rd5 );
assign multi_rd6_ram =(multi_raddr6 ==multi_waddr && multi_raddr6!='b0  )?  1'b0:((multi_raddr6_f ==multi_waddr_f && multi_raddr6_f !='b0  )?multi_rd6_f :multi_rd6 );
assign multi_rd7_ram =(multi_raddr7 ==multi_waddr && multi_raddr7!='b0  )?  1'b0:((multi_raddr7_f ==multi_waddr_f && multi_raddr7_f !='b0  )?multi_rd7_f :multi_rd7 );
assign multi_rd8_ram =(multi_raddr8 ==multi_waddr && multi_raddr8!='b0  )?  1'b0:((multi_raddr8_f ==multi_waddr_f && multi_raddr8_f !='b0  )?multi_rd8_f :multi_rd8 );
assign multi_rd9_ram =(multi_raddr9 ==multi_waddr && multi_raddr9!='b0  )?  1'b0:((multi_raddr9_f ==multi_waddr_f && multi_raddr9_f !='b0  )?multi_rd9_f :multi_rd9 );
assign multi_rd10_ram=(multi_raddr10==multi_waddr && multi_raddr1!='b0  )?  1'b0:((multi_raddr10_f==multi_waddr_f && multi_raddr10_f!='b0  )?multi_rd10_f:multi_rd10);

***補(bǔ)充:具體代碼在文章開頭鏈接

讀寫沖突的仿真結(jié)果如下:

1f15203c-0065-11ef-a297-92fbcf53809c.png

五、Multiport RAM仿真和時(shí)序

所有寫端口都是一拍寫入。讀端口是第一拍讀使能,讀地址,第二拍讀出數(shù)據(jù)。

1.單口寫數(shù)據(jù)

1f45b6b6-0065-11ef-a297-92fbcf53809c.png

2.單端口讀數(shù)據(jù)

1f601862-0065-11ef-a297-92fbcf53809c.png

3.多口讀相同數(shù)據(jù)

1f7fb438-0065-11ef-a297-92fbcf53809c.png

4.多口同時(shí)讀不同數(shù)據(jù)

1fb0918e-0065-11ef-a297-92fbcf53809c.png


審核編輯:劉清
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • FPGA
    +關(guān)注

    關(guān)注

    1643

    文章

    21957

    瀏覽量

    614038
  • 存儲(chǔ)器
    +關(guān)注

    關(guān)注

    38

    文章

    7634

    瀏覽量

    166399
  • 交換機(jī)
    +關(guān)注

    關(guān)注

    21

    文章

    2721

    瀏覽量

    101349
  • BRAM
    +關(guān)注

    關(guān)注

    0

    文章

    41

    瀏覽量

    11234
  • Vivado
    +關(guān)注

    關(guān)注

    19

    文章

    828

    瀏覽量

    68214

原文標(biāo)題:Multiport RAM,多讀多寫寄存器-——基于FPGA BRAM的多端口地址查找表與FPGA BRAM的資源分析

文章出處:【微信號(hào):gh_cb8502189068,微信公眾號(hào):網(wǎng)絡(luò)交換FPGA】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    FPGA ZYNQ Ultrascale+ MPSOC教程】33.BRAM實(shí)現(xiàn)PS與PL交互

    有時(shí)CPU需要與PL進(jìn)行小批量的數(shù)據(jù)交換,可以通過BRAM模塊,也就是Block RAM實(shí)現(xiàn)此要求。本章通過Zynq的GP Master接口讀寫PL端的BRAM,實(shí)現(xiàn)與PL的交互。在本實(shí)驗(yàn)中加入了自定義的FPGA程序,并利用AX
    的頭像 發(fā)表于 02-22 13:51 ?8766次閱讀
    【<b class='flag-5'>FPGA</b> ZYNQ Ultrascale+ MPSOC教程】33.<b class='flag-5'>BRAM</b>實(shí)現(xiàn)PS與PL交互

    FPGA設(shè)計(jì)中BRAM的知識(shí)科普

    FPGA設(shè)計(jì)中,BRAM是一項(xiàng)非常關(guān)鍵的內(nèi)置存儲(chǔ)資源FPGA開發(fā)需要熟練使用BRAM,今天再?gòu)?fù)習(xí)一下B
    發(fā)表于 08-15 15:44 ?6916次閱讀
    <b class='flag-5'>FPGA</b>設(shè)計(jì)中<b class='flag-5'>BRAM</b>的知識(shí)科普

    怎么從Virtex 6的FPGA中取出BRAM轉(zhuǎn)儲(chǔ)

    大家好請(qǐng)任何人告訴我。是否有任何方法可以從Virtex 6的FPGA中取出BRAM轉(zhuǎn)儲(chǔ)。提前致謝問候Vir_1602以上來自于谷歌翻譯以下為原文Hi all would anyone please
    發(fā)表于 03-20 15:37

    如何在不使用DDR內(nèi)存控制器的情況下設(shè)計(jì)FPGA BRAM大容量存儲(chǔ)單元?

    來修改我的設(shè)計(jì)。我刪除了mig_7series IP并將BRAM連接到AXI總線。我還將Microblaze M_AXI_IC和M_AXI_DC端口連接到BRAM,并檢查了MB緩存地址
    發(fā)表于 04-04 15:10

    無法正確寫入雙端口BRAM

    嗨,我正在嘗試使用自定義IP寫入vhdl中的雙端口BRAM,該IP生成地址并啟用所有信號(hào),但我無法正確寫入雙端口BRAM
    發(fā)表于 04-17 08:15

    URAM和BRAM的區(qū)別是什么

    。  工作模式  BRAM 可配置為單端口、簡(jiǎn)單雙端口和真雙端口,但對(duì)于 URAM,不能簡(jiǎn)單地將這三種模式映射過來,其工作行為如下圖所示。可以看到,A/B
    發(fā)表于 12-23 16:57

    8255端口地址如何確定_8255怎樣計(jì)算端口地址

    本文首先介紹了8255芯片特性及引腳功能,其次介紹了8255應(yīng)用電路圖,最后介紹了區(qū)分8255A端口地址方法及8255的端口地址的計(jì)算。
    的頭像 發(fā)表于 05-29 08:40 ?12.1w次閱讀
    8255<b class='flag-5'>端口地址</b>如何確定_8255怎樣計(jì)算<b class='flag-5'>端口地址</b>

    FPGA實(shí)現(xiàn)基于Vivado的BRAM IP核的使用

    的使用。 ? ? BRAMFPGA定制的RAM資源,有著較大的存儲(chǔ)空間,且在日常的工程中使用較為頻繁。BRAM以陣列的方式排布于FPGA
    的頭像 發(fā)表于 12-29 15:59 ?1.3w次閱讀

    使用FPGA調(diào)用RAM資源的詳細(xì)說明

    RAM),其中BRAM是block ram,是存在FPGA中的大容量的RAM,DRAM是FPGA中有LUT(look-up table 查找
    發(fā)表于 12-30 16:27 ?9次下載

    URAM和BRAM有哪些區(qū)別

    無論是7系列FPGA、UltraScale還是UltraScale Plus系列FPGA,都包含Block RAM(BRAM),但只有UltraScale Plus芯片有UltraRAM也就是我們所說的URAM。
    的頭像 發(fā)表于 07-25 17:54 ?6656次閱讀
    URAM和<b class='flag-5'>BRAM</b>有哪些區(qū)別

    URAM和BRAM有什么區(qū)別

    無論是7系列FPGA、UltraScale還是UltraScale Plus系列FPGA,都包含Block RAM(BRAM),但只有UltraScale Plus芯片有UltraRAM也就是我們所說的URAM。
    發(fā)表于 01-27 06:55 ?12次下載
    URAM和<b class='flag-5'>BRAM</b>有什么區(qū)別

    Vivado中BRAM IP的配置方式和使用技巧

    FPGA開發(fā)中使用頻率非常高的兩個(gè)IP就是FIFO和BRAM,上一篇文章中已經(jīng)詳細(xì)介紹了Vivado FIFO IP,今天我們來聊一聊BRAM IP。
    的頭像 發(fā)表于 08-29 16:41 ?8083次閱讀
    Vivado中<b class='flag-5'>BRAM</b> IP的配置方式和使用技巧

    FPGABRAM資源使用優(yōu)化策略

    FPGABRAM和LUT等資源都是有限的,在FPGA開發(fā)過程中,可能經(jīng)常遇到BRAM或者LUT資源
    的頭像 發(fā)表于 08-30 16:12 ?3906次閱讀
    <b class='flag-5'>FPGA</b>的<b class='flag-5'>BRAM</b><b class='flag-5'>資源</b>使用優(yōu)化策略

    FPGA實(shí)現(xiàn)基于Vivado的BRAM IP核的使用

    定制的RAM資源,有著較大的存儲(chǔ)空間,且在日常的工程中使用較為頻繁。BRAM以陣列的方式排布于FPGA的內(nèi)部,是FPGA實(shí)現(xiàn)各種存儲(chǔ)功能的主要部分,是真正的雙讀/寫
    的頭像 發(fā)表于 12-05 15:05 ?2266次閱讀

    基于FPGA設(shè)計(jì)的BRAM內(nèi)部結(jié)構(gòu)

    再看末級(jí)觸發(fā)器對(duì)BRAM時(shí)序性能的影響,下圖依次展示了7系列FPGA、UltraScale+和Versal芯片在未使用和使用末級(jí)觸發(fā)器兩種情形下時(shí)鐘到輸出的延遲。
    發(fā)表于 04-25 10:42 ?626次閱讀
    基于<b class='flag-5'>FPGA</b>設(shè)計(jì)的<b class='flag-5'>BRAM</b>內(nèi)部結(jié)構(gòu)