上文對BMG ip的基本情況進行了簡單的描述,本文通過例化仿真來實際使用功能一下這個IP。
首先使用簡單雙端口BRAM實現(xiàn)一個簡單的跨時鐘域操作:將16bit的a時鐘域的數(shù)據(jù)跨到b時鐘域,b時鐘頻率是a時鐘頻率的一半,為了操作方便,直接將b數(shù)據(jù)位寬擴展到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,輸入輸出均為滿速率,同時在代碼中增加了防抖保護措施,防止跨時鐘域中因為出現(xiàn)時鐘抖動而產(chǎn)生的數(shù)據(jù)異常問題。
以上就是Xilinx Block Memory Generator(BMG) IP的仿真。
-
FPGA
+關(guān)注
關(guān)注
1625文章
21620瀏覽量
601239 -
Xilinx
+關(guān)注
關(guān)注
71文章
2155瀏覽量
120853 -
仿真
+關(guān)注
關(guān)注
50文章
4023瀏覽量
133337 -
時鐘
+關(guān)注
關(guān)注
10文章
1714瀏覽量
131275
發(fā)布評論請先 登錄
相關(guān)推薦
評論