上文對BMG ip的基本情況進行了簡單的描述,本文通過例化仿真來實際使用功能一下這個IP。
首先使用簡單雙端口BRAM實現一個簡單的跨時鐘域操作:將16bit的a時鐘域的數據跨到b時鐘域,b時鐘頻率是a時鐘頻率的一半,為了操作方便,直接將b數據位寬擴展到32bit(這樣就不用增加控制信息,數據流是滿的)。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端口數據映射關系如下:
例化一個簡單的ip,設置如下。這里選擇簡單雙端口模式的本地接口,采用面積最小原則,端口A為16bit,深度為16,ram大小就是16*16bit,控制信號就使用ENA。對于端口B,將位寬設置為32bit,此時深度自動變換為8,使用寫優先模式,同樣使能ENB端口作為控制端口。
這里對續寫模式再做一個簡單的說明,支持WRITE_FIRST, READ_FIRST或NO_CHANGE三種模式,這三種模式的讀寫時序如下圖所示。
WRITE_FIRST模式下,寫優先級最高,同一地址,一旦寫入,數據直接會透傳到輸出端。READ_FIRST模式,數據輸出端口會鎖存輸出數據,有數據寫入時,輸出數據是上一次的數據。NO_CHANGE模式下,在寫使能拉高后,輸出將保持開始拉高時刻的數據,保持不變。注意這三種模式針對的是單端口,即端口A或者B。
編寫一個簡單的仿真測試代碼如下:
// ============================================================
// File Name: tb_blk_mem_gen_sdp
// VERSION : V1.0
// DATA : 2023/8/5
// Author : FPGA干貨分享
// ============================================================
// 功能:xilinx blk_mem_gen_sdp ip 代碼仿真
// 使用簡單雙端口實現一個簡單的跨時鐘域
// 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
仿真結果如下:clkb時鐘頻率是clka時鐘頻率的一半,dataa數據位寬16bit,datab數據位寬32bit,輸入輸出均為滿速率,同時在代碼中增加了防抖保護措施,防止跨時鐘域中因為出現時鐘抖動而產生的數據異常問題。
以上就是Xilinx Block Memory Generator(BMG) IP的仿真。
-
FPGA
+關注
關注
1630文章
21796瀏覽量
605999 -
Xilinx
+關注
關注
71文章
2171瀏覽量
122134 -
仿真
+關注
關注
50文章
4124瀏覽量
133991 -
時鐘
+關注
關注
11文章
1746瀏覽量
131799
發布評論請先 登錄
相關推薦
XILINX FPGA IP之Clocking Wizard詳解

XILINX FPGA IP之MMCM PLL DRP時鐘動態重配詳解

Xilinx FPGA IP之Block Memory Generator AXI接口說明

Distributed Memory Generator IP核簡介

XILINX FPGA IP之AXI Traffic Generator

評論