上文對BMG ip的基本情況進(jìn)行了簡單的描述,本文通過例化仿真來實際使用功能一下這個IP。
首先使用簡單雙端口BRAM實現(xiàn)一個簡單的跨時鐘域操作:將16bit的a時鐘域的數(shù)據(jù)跨到b時鐘域,b時鐘頻率是a時鐘頻率的一半,為了操作方便,直接將b數(shù)據(jù)位寬擴(kuò)展到32bit(這樣就不用增加控制信息,數(shù)據(jù)流是滿的)。BMG IP輸入輸出位寬比支持:1:32, 1:16, 1:8, 1:4, 1:2, 1:1, 2:1, 4:1, 8:1, 16:1, 32:1.位寬變換時BMG的AB端口數(shù)據(jù)映射關(guān)系如下:

例化一個簡單的ip,設(shè)置如下。這里選擇簡單雙端口模式的本地接口,采用面積最小原則,端口A為16bit,深度為16,ram大小就是16*16bit,控制信號就使用ENA。對于端口B,將位寬設(shè)置為32bit,此時深度自動變換為8,使用寫優(yōu)先模式,同樣使能ENB端口作為控制端口。



這里對續(xù)寫模式再做一個簡單的說明,支持WRITE_FIRST, READ_FIRST或NO_CHANGE三種模式,這三種模式的讀寫時序如下圖所示。



WRITE_FIRST模式下,寫優(yōu)先級最高,同一地址,一旦寫入,數(shù)據(jù)直接會透傳到輸出端。READ_FIRST模式,數(shù)據(jù)輸出端口會鎖存輸出數(shù)據(jù),有數(shù)據(jù)寫入時,輸出數(shù)據(jù)是上一次的數(shù)據(jù)。NO_CHANGE模式下,在寫使能拉高后,輸出將保持開始拉高時刻的數(shù)據(jù),保持不變。注意這三種模式針對的是單端口,即端口A或者B。
編寫一個簡單的仿真測試代碼如下:
// ============================================================
// File Name: tb_blk_mem_gen_sdp
// VERSION : V1.0
// DATA : 2023/8/5
// Author : FPGA干貨分享
// ============================================================
// 功能:xilinx blk_mem_gen_sdp ip 代碼仿真
// 使用簡單雙端口實現(xiàn)一個簡單的跨時鐘域
// delay :
// ============================================================
`timescale 1ns/100ps
module tb_blk_mem_gen_sdp ;
reg clka = 'd0 ;
reg ena = 'd1 ;
reg [0 : 0] wea = 'd1 ;
reg [3 : 0] addra = 'd0 ;
reg [15 : 0] dina = 'd0 ;
reg clkb = 'd0 ;
reg enb = 'd1 ;
reg [2 : 0] addrb = 'd0 ;
wire [31 : 0] doutb ;
reg [2:0] S_addr_a_flag ='d0 ;
reg S_a_flag ='d0 ;
reg [2:0] S_a_flag_2_b ='d0 ;
reg S_b_flag ='d0 ;
reg [2:0] S_clk_cnt8 ='d3 ;
always #1 clka = ~clka;
always #2 clkb = ~clkb;
//----------- clk_a ---//
always @(posedge clka)
if(ena && wea)
begin
addra <= addra + 'd1;
dina <= dina + 'd1;
end
always @(posedge clka)
S_addr_a_flag[0] <= (addra == 4'd10);
always @(posedge clka)
S_addr_a_flag[2:1] <= S_addr_a_flag[1:0] ;
always @(posedge clka)
S_a_flag <= |S_addr_a_flag ;
//----------- clk_b ---//
always @(posedge clkb)
S_a_flag_2_b <= {S_a_flag_2_b[1:0],S_a_flag} ;
always @(posedge clkb)
S_b_flag <= (!S_a_flag_2_b[2])&& S_a_flag_2_b[1] ;
always @(posedge clkb)
if((S_clk_cnt8 > 3'd2)&&S_b_flag)
S_clk_cnt8 <= 3'd2;
else
S_clk_cnt8 <= S_clk_cnt8 + 'd1;
always @(posedge clkb)
if(S_clk_cnt8 == 3'd1)
addrb <= 'd0;
else
addrb <= addrb + 'd1;
//----------- Begin Cut here for INSTANTIATION Template ---//
blk_mem_gen_sdp blk_mem_gen_sdp (
.clka (clka ), // input wire clka
.ena (ena ), // input wire ena
.wea (wea ), // input wire [0 : 0] wea
.addra (addra ), // input wire [3 : 0] addra
.dina (dina ), // input wire [15 : 0] dina
.clkb (clkb ), // input wire clkb
.enb (enb ), // input wire enb
.addrb (addrb ), // input wire [2 : 0] addrb
.doutb (doutb ) // output wire [31 : 0] doutb
);
endmodule
仿真結(jié)果如下:clkb時鐘頻率是clka時鐘頻率的一半,dataa數(shù)據(jù)位寬16bit,datab數(shù)據(jù)位寬32bit,輸入輸出均為滿速率,同時在代碼中增加了防抖保護(hù)措施,防止跨時鐘域中因為出現(xiàn)時鐘抖動而產(chǎn)生的數(shù)據(jù)異常問題。

以上就是Xilinx Block Memory Generator(BMG) IP的仿真。
-
FPGA
+關(guān)注
關(guān)注
1654文章
22273瀏覽量
629864 -
Xilinx
+關(guān)注
關(guān)注
73文章
2192瀏覽量
129821 -
仿真
+關(guān)注
關(guān)注
52文章
4400瀏覽量
137627 -
時鐘
+關(guān)注
關(guān)注
11文章
1950瀏覽量
134514
發(fā)布評論請先 登錄
XILINX FPGA IP之Clocking Wizard詳解
XILINX FPGA IP之MMCM PLL DRP時鐘動態(tài)重配詳解
Xilinx FPGA IP之Block Memory Generator功能概述
Xilinx FPGA IP之Block Memory Generator AXI接口說明
Distributed Memory Generator IP核簡介
XILINX FPGA IP之AXI Traffic Generator

Xilinx FPGA IP之Block Memory Generator仿真
評論