描述
怎么做 以Speedster®7t设备为目标时,我是否推断LRAM2K_SDP?什么过程?
回答
LRAM2K_SDP实现了一个具有一个写端口和一个读端口的2 KB单双端口(SDP)存储模块。请参阅 回忆 在这一章 Speedster7t IP组件用户指南(UG086) 有关LRAM2K_SDP的详细信息。 LRAM2K_SDP可以使用通常用于推断同步和组合RAM和ROM的RTL构造进行推断,并具有多种时钟使能和复位方案以及极性。
下面 是LRAM2K_SDP推理的一个示例。
LRAM2K_SDP推断
//---------------------------------------------------------------------------------
//
// Copyright (c) 2020 Achronix Semiconductor Corp.
// All Rights Reserved.
//
//
// This software constitutes an unpublished work and contains
// valuable proprietary information and trade secrets belonging
// to Achronix Semiconductor Corp.
//
// This software may not be used, copied, distributed or disclosed
// without specific prior written authorization from
// Achronix Semiconductor Corp.
//
// The copyright notice above does not evidence any actual or intended
// publication of such software.
//
//
//---------------------------------------------------------------------------------
// Design: LRAM2K_SDP推断
// An example to infer an LRAM2K_SDP in a Speedster7t design
//---------------------------------------------------------------------------------
`timescale 1ps / 1ps
module lram2k_sdp
#(
parameter ADDR_WIDTH = 5,
parameter DATA_WIDTH = 72,
parameter OUT_REG_EN = 0,
parameter INIT_FILE_NAME = ""
)
(
// Clocks and resets
input wire wr_clk,
input wire rd_clk,
// Enables
input wire we,
input wire rstreg,
// Address and data
input wire [ADDR_WIDTH-1:0] wr_addr,
input wire [ADDR_WIDTH-1:0] rd_addr,
input wire [DATA_WIDTH-1:0] wr_data,
// Output
output reg [DATA_WIDTH-1:0] rd_data
);
// Determine if size is small enough for an LRAM2K_SDP
localparam MEM_LRAM = ( ((DATA_WIDTH <= 36) && (ADDR_WIDTH <= 6)) ||
((DATA_WIDTH <= 72) && (ADDR_WIDTH <= 5)) ||
((DATA_WIDTH <= 144) && (ADDR_WIDTH <= 4)) ) ? 1 : 0;
// Define combinatorial and registered outputs from memory array
logic [DATA_WIDTH-1:0] rd_data_int;
logic [DATA_WIDTH-1:0] rd_data_reg;
logic read_collision;
always @(posedge rd_clk)
if (~rstreg)
rd_data_reg <= {DATA_WIDTH{1'b0}};
else
rd_data_reg <= rd_data_int;
// Need a generate block to apply the appropriate syn_ramstyle to the memory array
// Rest of the the code has to be within the generate block to access that variable
generate if ( MEM_LRAM == 1) begin : gb_lram
logic [DATA_WIDTH-1:0] mem [(2**ADDR_WIDTH)-1:0] /* synthesis syn_ramstyle = "logic" */;
// If an initialisation file exists, then initialise the memory
if ( INIT_FILE_NAME != "" ) begin : gb_init
initial
$readmemh( INIT_FILE_NAME, mem );
end
// Writing. Inference does not currently support byte enables
// Also generate the signals to detect if there is a memory collision
logic [ADDR_WIDTH-1:0] wr_addr_d;
always @(posedge wr_clk)
if( we ) begin
mem[wr_addr] <= wr_data;
wr_addr_d <= wr_addr;
end
// LRAM2K_SDP only supports the WRITE_FIRST mode. So if rd_addr = wr_addr then
// write takes priority and read value is invalid
// The value from the array is combinatorial, (this is different than for BRAM72K_SDP)
// Write address is effective on the cycle it is writing to the memory, (i.e. it is registered)
assign read_collision = (wr_addr_d == rd_addr);
assign rd_data_int = (read_collision) ? {DATA_WIDTH{1'bx}} : mem[rd_addr];
end
endgenerate
// Select output based on whether output register is enabled
assign rd_data = (OUT_REG_EN) ? rd_data_reg : rd_data_int;
endmodule : lram2k_sdp