Distributed Memory Generator IP 核采用 LUT RAM 资源创建各种不同的存储器结构。IP可用来创建只读存储器 (ROM)、单端口随机存取存储器 (RAM) 和简单双/双端口 RAM 以及基于 SRL16 的 RAM。该IP的灵活的特性配置方式,使用户能针对存储器类型、数据宽度、存储器大小、输入/输出选项和复位选项进行定制。
Distributed Memory Generator IP GUI界面如下:
该IP的主要特性为:
这个IP的端口如下图所示:
输入:
a:地址输入;
Dpra:双端口时的读地址;
d:数据输入;
Clk:时钟
Qdpo_clk:双端口模式下的第二个时钟
We:写使能
i_ce:输入时钟使能;
Qspo_ce:输出时钟使能;
Qdpo_ce:第二个端口的输出时钟使能;
输出:
Spo:非寄存器模式下第一个端口的输出数据
Dpo:非寄存器模式下第二个端口的输出数据
Qspo:寄存器模式下第一个端口的输出数据
Qdpo:寄存器模式下第二个端口的输出数据
复位:
qspo_rst :寄存器模式下第一个端口的异步复位
qdpo_rst :寄存器模式下第二个端口的异步复位
qspo_srst:寄存器模式下第一个端口的同步复位
qdpo_srst :寄存器模式下第二个端口的同步复位
Distributed Memory在不同工作模式下的内部情况如下图所示:
ROM模式:
单端口RAM模式:
双端口RAM模式:
简单双端口模式:
一般情况下常用简单双端口模式进行跨时钟域,简单缓存的操作。用简单双端口实现一个简单的跨时钟域代码如下:
// ============================================================
// File Name: tb_dist_mem_gen
// VERSION : V1.0
// DATA : 2023/8/18
// Author : FPGA干货分享
// ============================================================
// 功能:xilinx Distributed Memory Generator ip 代码仿真
// 使用简单双端口实现一个简单的跨时钟域
// delay :
// ============================================================
`timescale 1ns/100ps
module tb_dist_mem_gen ;
reg clka = 'd0 ;
reg ena = 'd1 ;
reg [0 : 0] wea = 'd1 ;
reg [5 : 0] addra = 'd0 ;
reg [15 : 0] dina = 'd0 ;
reg clkb = 'd1 ;
reg enb = 'd1 ;
reg [5 : 0] addrb = 'd0 ;
wire [15 : 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 #1 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 == 6'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;
dist_mem_gen_0 dist_mem_gen_0 (
.a (addra ), // input wire [5 : 0] a
.d (dina ), // input wire [15 : 0] d
.dpra (addrb ), // input wire [5 : 0] dpra
.clk (clka ), // input wire clk
.we (wea ), // input wire we
.qdpo_clk (clkb ), // input wire qdpo_clk
.qdpo (doutb ) // output wire [15 : 0] dpo
);
endmodule
全部0条评论
快来发表一下你的评论吧 !