I think that previously, I had not actually commited any of this to git. This adds all of the new effinix stuff that I had been working on for months. The gist of all of this is that the intel fpga is expensive and does not exist, whereas the effinix ones are not as expensive and more existant. This redoes the project to use the dev board, as well as a custom board that I may or may not make.
4237 lines
118 KiB
Verilog
4237 lines
118 KiB
Verilog
// =============================================================================
|
|
// Generated by efx_ipmgr
|
|
// Version: 2021.2.323
|
|
// IP Version: 1.5
|
|
// =============================================================================
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// Copyright (C) 2013-2021 Efinix Inc. All rights reserved.
|
|
//
|
|
// This document contains proprietary information which is
|
|
// protected by copyright. All rights are reserved. This notice
|
|
// refers to original work by Efinix, Inc. which may be derivitive
|
|
// of other work distributed under license of the authors. In the
|
|
// case of derivative work, nothing in this notice overrides the
|
|
// original author's license agreement. Where applicable, the
|
|
// original license agreement is included in it's original
|
|
// unmodified form immediately below this header.
|
|
//
|
|
// WARRANTY DISCLAIMER.
|
|
// THE DESIGN, CODE, OR INFORMATION ARE PROVIDED “AS IS” AND
|
|
// EFINIX MAKES NO WARRANTIES, EXPRESS OR IMPLIED WITH
|
|
// RESPECT THERETO, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES,
|
|
// INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
|
// MERCHANTABILITY, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR
|
|
// PURPOSE. SOME STATES DO NOT ALLOW EXCLUSIONS OF AN IMPLIED
|
|
// WARRANTY, SO THIS DISCLAIMER MAY NOT APPLY TO LICENSEE.
|
|
//
|
|
// LIMITATION OF LIABILITY.
|
|
// NOTWITHSTANDING ANYTHING TO THE CONTRARY, EXCEPT FOR BODILY
|
|
// INJURY, EFINIX SHALL NOT BE LIABLE WITH RESPECT TO ANY SUBJECT
|
|
// MATTER OF THIS AGREEMENT UNDER TORT, CONTRACT, STRICT LIABILITY
|
|
// OR ANY OTHER LEGAL OR EQUITABLE THEORY (I) FOR ANY INDIRECT,
|
|
// SPECIAL, INCIDENTAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES OF ANY
|
|
// CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF
|
|
// GOODWILL, DATA OR PROFIT, WORK STOPPAGE, OR COMPUTER FAILURE OR
|
|
// MALFUNCTION, OR IN ANY EVENT (II) FOR ANY AMOUNT IN EXCESS, IN
|
|
// THE AGGREGATE, OF THE FEE PAID BY LICENSEE TO EFINIX HEREUNDER
|
|
// (OR, IF THE FEE HAS BEEN WAIVED, $100), EVEN IF EFINIX SHALL HAVE
|
|
// BEEN INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO
|
|
// NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR
|
|
// CONSEQUENTIAL DAMAGES, SO THIS LIMITATION AND EXCLUSION MAY NOT
|
|
// APPLY TO LICENSEE.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
`define IP_UUID _2fa8b2362acf42f5841c22a03034c8fb
|
|
`define IP_NAME_CONCAT(a,b) a``b
|
|
`define IP_MODULE_NAME(name) `IP_NAME_CONCAT(name,`IP_UUID)
|
|
module sdram (
|
|
input i_we,
|
|
input i_sysclk,
|
|
input i_arst,
|
|
input i_sdrclk,
|
|
input i_tACclk,
|
|
input i_pll_locked,
|
|
input i_re,
|
|
input i_last,
|
|
output o_dbg_tRTW_done,
|
|
output o_dbg_ref_req,
|
|
output o_dbg_wr_ack,
|
|
output o_dbg_rd_ack,
|
|
output [1:0] o_dbg_n_CS,
|
|
output [1:0] o_dbg_n_RAS,
|
|
output [1:0] o_dbg_n_CAS,
|
|
output [1:0] o_dbg_n_WE,
|
|
output [3:0] o_dbg_BA,
|
|
output [25:0] o_dbg_ADDR,
|
|
output [31:0] o_dbg_DATA_out,
|
|
output [31:0] o_dbg_DATA_in,
|
|
input [23:0] i_addr,
|
|
input [31:0] i_din,
|
|
output [31:0] o_dout,
|
|
output [3:0] o_sdr_state,
|
|
output o_sdr_init_done,
|
|
output o_wr_ack,
|
|
output o_rd_ack,
|
|
output o_ref_req,
|
|
output o_rd_valid,
|
|
output [1:0] o_sdr_CKE,
|
|
output [1:0] o_sdr_n_CS,
|
|
output [1:0] o_sdr_n_RAS,
|
|
output [1:0] o_sdr_n_CAS,
|
|
output [1:0] o_sdr_n_WE,
|
|
output [3:0] o_sdr_BA,
|
|
output [25:0] o_sdr_ADDR,
|
|
output [31:0] o_sdr_DATA,
|
|
output [31:0] o_sdr_DATA_oe,
|
|
input [31:0] i_sdr_DATA,
|
|
output [3:0] o_sdr_DQM,
|
|
output [5:0] o_dbg_dly_cnt_b,
|
|
output o_dbg_tRCD_done
|
|
);
|
|
`IP_MODULE_NAME(efx_sdram_controller) #(
|
|
.fSYS_MHz (100),
|
|
.fCK_MHz (200),
|
|
.tIORT_u (2),
|
|
.BL (1),
|
|
.DDIO_TYPE ("SOFT"),
|
|
.DQ_WIDTH (8),
|
|
.DQ_GROUP (2),
|
|
.BA_WIDTH (2),
|
|
.ROW_WIDTH (13),
|
|
.COL_WIDTH (9),
|
|
.tPWRUP (200000),
|
|
.tRAS (44),
|
|
.tRC (66),
|
|
.tRCD (20),
|
|
.tREF (64000000),
|
|
.tWR (2),
|
|
.tMRD (2),
|
|
.tRFC (66),
|
|
.tRAS_MAX (120000),
|
|
.DATA_RATE (2),
|
|
.AXI_ARADDR_WIDTH (24),
|
|
.SDRAM_MODE ("Native"),
|
|
.AXI_BUSER_WIDTH (2),
|
|
.AXI_BID_WIDTH (4),
|
|
.AXI_AWUSER_WIDTH (2),
|
|
.AXI_AWID_WIDTH (4),
|
|
.AXI_AWADDR_WIDTH (24),
|
|
.AXI_RDATA_WIDTH (32),
|
|
.AXI_WUSER_WIDTH (2),
|
|
.AXI_WDATA_WIDTH (32),
|
|
.AXI_RUSER_WIDTH (3),
|
|
.AXI_ARUSER_WIDTH (3),
|
|
.AXI_ARID_WIDTH (4),
|
|
.tRP (20),
|
|
.CL (3)
|
|
) u_efx_sdram_controller(
|
|
.i_we ( i_we ),
|
|
.i_sysclk ( i_sysclk ),
|
|
.i_arst ( i_arst ),
|
|
.i_sdrclk ( i_sdrclk ),
|
|
.i_tACclk ( i_tACclk ),
|
|
.i_pll_locked ( i_pll_locked ),
|
|
.i_re ( i_re ),
|
|
.i_last ( i_last ),
|
|
.o_dbg_tRTW_done ( o_dbg_tRTW_done ),
|
|
.o_dbg_ref_req ( o_dbg_ref_req ),
|
|
.o_dbg_wr_ack ( o_dbg_wr_ack ),
|
|
.o_dbg_rd_ack ( o_dbg_rd_ack ),
|
|
.o_dbg_n_CS ( o_dbg_n_CS ),
|
|
.o_dbg_n_RAS ( o_dbg_n_RAS ),
|
|
.o_dbg_n_CAS ( o_dbg_n_CAS ),
|
|
.o_dbg_n_WE ( o_dbg_n_WE ),
|
|
.o_dbg_BA ( o_dbg_BA ),
|
|
.o_dbg_ADDR ( o_dbg_ADDR ),
|
|
.o_dbg_DATA_out ( o_dbg_DATA_out ),
|
|
.o_dbg_DATA_in ( o_dbg_DATA_in ),
|
|
.i_addr ( i_addr ),
|
|
.i_din ( i_din ),
|
|
.o_dout ( o_dout ),
|
|
.o_sdr_state ( o_sdr_state ),
|
|
.o_sdr_init_done ( o_sdr_init_done ),
|
|
.o_wr_ack ( o_wr_ack ),
|
|
.o_rd_ack ( o_rd_ack ),
|
|
.o_ref_req ( o_ref_req ),
|
|
.o_rd_valid ( o_rd_valid ),
|
|
.o_sdr_CKE ( o_sdr_CKE ),
|
|
.o_sdr_n_CS ( o_sdr_n_CS ),
|
|
.o_sdr_n_RAS ( o_sdr_n_RAS ),
|
|
.o_sdr_n_CAS ( o_sdr_n_CAS ),
|
|
.o_sdr_n_WE ( o_sdr_n_WE ),
|
|
.o_sdr_BA ( o_sdr_BA ),
|
|
.o_sdr_ADDR ( o_sdr_ADDR ),
|
|
.o_sdr_DATA ( o_sdr_DATA ),
|
|
.o_sdr_DATA_oe ( o_sdr_DATA_oe ),
|
|
.i_sdr_DATA ( i_sdr_DATA ),
|
|
.o_sdr_DQM ( o_sdr_DQM ),
|
|
.o_dbg_dly_cnt_b ( o_dbg_dly_cnt_b ),
|
|
.o_dbg_tRCD_done ( o_dbg_tRCD_done )
|
|
);
|
|
|
|
endmodule
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// _____
|
|
// / _______ Copyright (C) 2013-2020 Efinix Inc. All rights reserved.
|
|
// / / \
|
|
// / / .. / `IP_MODULE_NAME(axi4_sdram_controller).v
|
|
// / / .' /
|
|
// __/ /.' / Description:
|
|
// __ \ / sdram contronller top with AXI4 interface
|
|
// /_/ /\ \_____/ /
|
|
// ____/ \_______/
|
|
//
|
|
// *******************************
|
|
// Revisions:
|
|
// 1.0 Initial rev
|
|
// Support ONLY AXI 32-bit data to SDRAM total DQ x16 half rate
|
|
//
|
|
// *******************************
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// AxSIZE
|
|
`define BYTES_TX_1 3'b000
|
|
`define BYTES_TX_2 3'b001
|
|
`define BYTES_TX_4 3'b010
|
|
`define BYTES_TX_8 3'b011
|
|
`define BYTES_TX_16 3'b100
|
|
`define BYTES_TX_32 3'b101
|
|
`define BYTES_TX_64 3'b110
|
|
`define BYTES_TX_128 3'b111
|
|
`define OKAY 2'b00
|
|
|
|
module `IP_MODULE_NAME(axi4_sdram_controller)
|
|
#(
|
|
parameter AXI_AWADDR_WIDTH = 32,
|
|
parameter AXI_WDATA_WIDTH = 32,
|
|
parameter AXI_ARADDR_WIDTH = 32,
|
|
parameter AXI_RDATA_WIDTH = 32,
|
|
|
|
parameter fSYS_MHz = 100,
|
|
parameter fCK_MHz = 100,
|
|
parameter DDIO_TYPE = "SOFT",
|
|
parameter tPWRUP = 100, // 100 us
|
|
parameter tRAS = 44, // 44 ns
|
|
parameter tRAS_MAX = 120, // 120 us
|
|
parameter tRC = 66, // 66 ns
|
|
parameter tRCD = 20, // 20 ns
|
|
parameter tREF = 64, // 64 ms
|
|
parameter tRFC = 66, // 66 ns
|
|
parameter tRP = 20, // 20 ns
|
|
parameter tWR = 2, // 1 CK+7.5 ns
|
|
parameter tMRD = 2, // 2 CK
|
|
parameter CL = 3, // 3 CK
|
|
parameter BL = 1,
|
|
parameter DATA_RATE = 1,
|
|
parameter tIORT_u = 2,
|
|
parameter BA_WIDTH = 2,
|
|
parameter ROW_WIDTH = 10,
|
|
parameter COL_WIDTH = 10,
|
|
parameter DQ_WIDTH = 8, // x4, x8
|
|
parameter DQ_GROUP = 8,
|
|
// x4 x8 x16 x32
|
|
// DQ_WIDTH 4 8 8 8
|
|
// DQ_GROUP 1 1 2 4
|
|
// AXI not support DQ_WIDTH = 4 DQ_GROUP = 1
|
|
|
|
//----- parameter not configurable by user----
|
|
parameter AXI_AWID_WIDTH = 4,
|
|
parameter AXI_AWUSER_WIDTH = 2,
|
|
parameter AXI_WUSER_WIDTH = 2,
|
|
parameter AXI_BID_WIDTH = 4,
|
|
parameter AXI_BUSER_WIDTH = 2,
|
|
parameter AXI_ARID_WIDTH = 4,
|
|
parameter AXI_ARUSER_WIDTH = 2,
|
|
parameter AXI_RUSER_WIDTH = 2
|
|
)
|
|
(
|
|
input i_aresetn,
|
|
input i_sysclk,
|
|
input i_sdrclk,
|
|
input i_tACclk,
|
|
input i_pll_locked,
|
|
output o_pll_reset,
|
|
|
|
// Compulsory
|
|
output o_AXI4_AWREADY,
|
|
input [AXI_AWADDR_WIDTH-1:0]i_AXI4_AWADDR,
|
|
input [2:0]i_AXI4_AWPROT, // Dummy
|
|
input i_AXI4_AWVALID,
|
|
|
|
output o_AXI4_WREADY,
|
|
input [AXI_WDATA_WIDTH-1:0]i_AXI4_WDATA,
|
|
input i_AXI4_WLAST,
|
|
input i_AXI4_WVALID,
|
|
|
|
output o_AXI4_BVALID,
|
|
input i_AXI4_BREADY,
|
|
|
|
output o_AXI4_ARREADY,
|
|
input [AXI_ARADDR_WIDTH-1:0]i_AXI4_ARADDR,
|
|
input [2:0]i_AXI4_ARPROT, // Dummy
|
|
input i_AXI4_ARVALID,
|
|
|
|
input i_AXI4_RREADY,
|
|
output [AXI_RDATA_WIDTH-1:0]o_AXI4_RDATA,
|
|
output o_AXI4_RLAST,
|
|
output o_AXI4_RVALID,
|
|
|
|
// Optional
|
|
input [AXI_AWID_WIDTH-1:0]i_AXI4_AWID,
|
|
input [3:0]i_AXI4_AWREGION, // Dummy
|
|
input [7:0]i_AXI4_AWLEN, // Dummy
|
|
input [2:0]i_AXI4_AWSIZE,
|
|
input [1:0]i_AXI4_AWBURST, // Dummy
|
|
input i_AXI4_AWLOCK, // Dummy
|
|
input [3:0]i_AXI4_AWCACHE, // Dummy
|
|
input [3:0]i_AXI4_AWQOS, // Dummy
|
|
input [AXI_AWUSER_WIDTH-1:0]i_AXI4_AWUSER, // Dummy
|
|
|
|
input [AXI_WDATA_WIDTH/8-1:0]i_AXI4_WSTRB, // Dummy
|
|
input [AXI_WUSER_WIDTH-1:0]i_AXI4_WUSER, // Dummy
|
|
|
|
output [AXI_BID_WIDTH-1:0]o_AXI4_BID,
|
|
output [1:0]o_AXI4_BRESP, // Dummy
|
|
output [AXI_BUSER_WIDTH-1:0]o_AXI4_BUSER, // Dummy
|
|
|
|
input [AXI_ARID_WIDTH-1:0]i_AXI4_ARID,
|
|
input [3:0]i_AXI4_ARREGION, // Dummy
|
|
input [7:0]i_AXI4_ARLEN,
|
|
input [2:0]i_AXI4_ARSIZE,
|
|
input [1:0]i_AXI4_ARBURST, // Dummy
|
|
input i_AXI4_ARLOCK, // Dummy
|
|
input [3:0]i_AXI4_ARCACHE, // Dummy
|
|
input [3:0]i_AXI4_ARQOS, // Dummy
|
|
input [AXI_ARUSER_WIDTH-1:0]i_AXI4_ARUSER, // Dummy
|
|
|
|
output [AXI_ARID_WIDTH-1:0]o_AXI4_RID,
|
|
output [1:0]o_AXI4_RRESP, // Dummy
|
|
output [AXI_RUSER_WIDTH-1:0]o_AXI4_RUSER, // Dummy
|
|
|
|
output [DATA_RATE -1:0] o_sdr_CKE,
|
|
output [DATA_RATE -1:0] o_sdr_n_CS,
|
|
output [DATA_RATE -1:0] o_sdr_n_RAS,
|
|
output [DATA_RATE -1:0] o_sdr_n_CAS,
|
|
output [DATA_RATE -1:0] o_sdr_n_WE,
|
|
output [DATA_RATE *BA_WIDTH -1:0] o_sdr_BA,
|
|
output [DATA_RATE *ROW_WIDTH -1:0] o_sdr_ADDR,
|
|
output [DATA_RATE *DQ_GROUP *DQ_WIDTH -1:0] o_sdr_DATA,
|
|
output [DATA_RATE *DQ_GROUP *DQ_WIDTH -1:0] o_sdr_DATA_oe,
|
|
input [DATA_RATE *DQ_GROUP *DQ_WIDTH -1:0] i_sdr_DATA,
|
|
output [DATA_RATE *DQ_GROUP -1:0] o_sdr_DQM,
|
|
|
|
// Debug port
|
|
output [3:0]o_sdr_state,
|
|
output o_dbg_we,
|
|
output o_dbg_re,
|
|
output o_dbg_last,
|
|
output [BA_WIDTH+ROW_WIDTH+COL_WIDTH-1:0]o_dbg_addr,
|
|
output [AXI_WDATA_WIDTH-1:0]o_dbg_din,
|
|
output o_dbg_wr_ack,
|
|
output o_dbg_rd_ack,
|
|
output o_sdr_rd_valid,
|
|
output o_dbg_ref_req,
|
|
output [DATA_RATE*DQ_GROUP*DQ_WIDTH+AXI_ARID_WIDTH:0]o_sdr_dout,
|
|
output [1:0]o_axi4_wrstate,
|
|
output o_dbg_axi4_wlast,
|
|
output [1:0]o_axi4_rastate,
|
|
output [1:0]o_axi4_rdstate,
|
|
output o_axi4_nwr,
|
|
output o_re_lock,
|
|
output [6:0]o_shift_cnt,
|
|
output [7:0]o_axi4_arlen,
|
|
output o_fifo_wr,
|
|
output o_fifo_full,
|
|
output o_fifo_empty,
|
|
output o_dbg_fifo_we,
|
|
output [7:0]o_dbg_fifo_waddr,
|
|
output o_dbg_fifo_re,
|
|
output [7:0]o_dbg_fifo_raddr,
|
|
|
|
output [DATA_RATE -1:0] o_dbg_n_CS,
|
|
output [DATA_RATE -1:0] o_dbg_n_RAS,
|
|
output [DATA_RATE -1:0] o_dbg_n_CAS,
|
|
output [DATA_RATE -1:0] o_dbg_n_WE,
|
|
output [DATA_RATE *BA_WIDTH -1:0] o_dbg_BA,
|
|
output [DATA_RATE *ROW_WIDTH -1:0] o_dbg_ADDR,
|
|
output [DATA_RATE *DQ_GROUP *DQ_WIDTH -1:0] o_dbg_DATA_out,
|
|
output [DATA_RATE *DQ_GROUP *DQ_WIDTH -1:0] o_dbg_DATA_in
|
|
);
|
|
|
|
function integer log2;
|
|
input integer val;
|
|
integer i;
|
|
begin
|
|
log2 = 0;
|
|
for (i=0; 2**i<val; i=i+1)
|
|
log2 = i+1;
|
|
end
|
|
endfunction
|
|
|
|
initial
|
|
begin
|
|
$display("DQ_GROUP: %d\n", DQ_GROUP);
|
|
$display("DQ_WIDTH: %d\n", DQ_WIDTH);
|
|
end
|
|
|
|
`ifdef RTL_SIM
|
|
localparam tIORT = (DATA_RATE == 2 && CL == 2) ? 1 : 0;
|
|
`else
|
|
localparam tIORT = tIORT_u;
|
|
`endif
|
|
|
|
localparam s_INIT = 2'b00;
|
|
localparam s_IDLE = 2'b01;
|
|
localparam s_WR_SHIFT = 2'b10;
|
|
localparam s_WR_RESP = 2'b11;
|
|
localparam s_RD_ADDR = 2'b10;
|
|
localparam s_RD_INIT = 2'b10;
|
|
localparam s_RD_SHIFT = 2'b11;
|
|
localparam SDR_DWIDTH = DQ_GROUP*DQ_WIDTH;
|
|
localparam SDR_BWIDTH = DATA_RATE*SDR_DWIDTH;
|
|
localparam DIN_WIDTH = AXI_WDATA_WIDTH;
|
|
localparam DOUT_WIDTH = AXI_RDATA_WIDTH;
|
|
|
|
wire r_AXI4_WREADY_c;
|
|
|
|
reg [1:0]r_axi4_wrstate_1P;
|
|
reg [1:0]r_axi4_rastate_1P;
|
|
reg [1:0]r_axi4_rdstate_1P;
|
|
reg r_axi4_nwr_1P;
|
|
reg r_AXI4_AWREADY_1P;
|
|
reg r_AXI4_AWLEN_1P;
|
|
//reg r_AXI4_WREADY_c;
|
|
reg r_AXI4_WLAST_1P;
|
|
reg r_AXI4_BVALID_1P;
|
|
reg r_AXI4_ARREADY_1P;
|
|
reg [7:0]r_AXI4_ARLEN_1P;
|
|
reg r_AXI4_RVALID_1P;
|
|
reg [AXI_BID_WIDTH-1:0]r_AXI4_BID_1P;
|
|
reg [AXI_ARID_WIDTH-1:0]r_AXI4_RID_1P;
|
|
|
|
reg r_we_1P;
|
|
reg r_re_1P;
|
|
reg r_last_1P;
|
|
reg [BA_WIDTH+ROW_WIDTH+COL_WIDTH-1:0]r_addr_1P;
|
|
reg [DIN_WIDTH-1:0]r_din_1P;
|
|
reg [6:0]r_size_1P;
|
|
reg [6:0]r_shift_cnt_1P;
|
|
reg [6:0]r_addr_cnt_1P;
|
|
reg [7:0]r_arlen_cnt_1P;
|
|
|
|
reg r_wr_ack_1P;
|
|
reg r_AXI4_WREADY_2P;
|
|
reg r_re_lock_1P;
|
|
|
|
reg [AXI_ARID_WIDTH-1:0]r_AXI4_RID[0:CL+tIORT+1];
|
|
reg [DOUT_WIDTH+AXI_ARID_WIDTH:0]r_dout_1P;
|
|
reg r_fifo_wr_1P;
|
|
reg r_fifo_rd_1P;
|
|
|
|
wire [SDR_BWIDTH-1:0]w_dout;
|
|
wire w_sdr_init_done;
|
|
wire w_wr_ack;
|
|
wire w_rd_ack;
|
|
wire w_ref_req;
|
|
wire w_rd_valid;
|
|
|
|
wire [AXI_RDATA_WIDTH+AXI_ARID_WIDTH:0]w_fifo_dout;
|
|
wire w_afull;
|
|
wire w_empty;
|
|
|
|
wire [1:0]c_addr_increment;
|
|
assign c_addr_increment = DATA_RATE;
|
|
assign o_pll_reset = i_aresetn;
|
|
|
|
`IP_MODULE_NAME(sdram_controller)
|
|
#(
|
|
.fSYS_MHz (fSYS_MHz),
|
|
.fCK_MHz (fCK_MHz),
|
|
.REF_LATENCY (4),
|
|
.tIORT_u (tIORT_u),
|
|
.DDIO_TYPE (DDIO_TYPE),
|
|
.tPWRUP (tPWRUP), // 100 us
|
|
.tRAS (tRAS), // 44 ns
|
|
.tRAS_MAX (tRAS_MAX), // 120 us
|
|
.tRC (tRC), // 66 ns
|
|
.tRCD (tRCD), // 20 ns
|
|
.tREF (tREF), // 64 ms
|
|
.tRFC (tRFC), // 66 ns
|
|
.tRP (tRP), // 20 ns
|
|
.tWR (tWR), // 1 CK+7.5 ns
|
|
.tMRD (tMRD), // 2 CK
|
|
.CL (CL), // 3 CK
|
|
.BL (BL),
|
|
.BA_WIDTH (BA_WIDTH),
|
|
.ROW_WIDTH (ROW_WIDTH),
|
|
.COL_WIDTH (COL_WIDTH),
|
|
.DATA_RATE (DATA_RATE),
|
|
.DQ_WIDTH (DQ_WIDTH), // x4, x8
|
|
.DQ_GROUP (DQ_GROUP)
|
|
// x4 x8 x16 x32
|
|
// DQ_WIDTH 4 8 8 8
|
|
// DQ_GROUP 1 1 2 4
|
|
)
|
|
inst_sdram_controller
|
|
(
|
|
.i_arst (~i_aresetn),
|
|
.i_sysclk (i_sysclk),
|
|
.i_sdrclk (i_sdrclk),
|
|
.i_tACclk (i_tACclk),
|
|
.i_pll_locked (i_pll_locked),
|
|
|
|
.i_we (r_we_1P),
|
|
.i_re (r_re_1P),
|
|
.i_last (r_last_1P),
|
|
.i_addr (r_addr_1P),
|
|
.i_din (r_din_1P[SDR_BWIDTH-1:0]),
|
|
.o_dout (w_dout),
|
|
.o_sdr_state (o_sdr_state), // debug use
|
|
.o_sdr_init_done(w_sdr_init_done),
|
|
.o_wr_ack (w_wr_ack),
|
|
.o_rd_ack (w_rd_ack),
|
|
.o_ref_req (w_ref_req),
|
|
.o_rd_valid (w_rd_valid),
|
|
|
|
.o_sdr_CKE (o_sdr_CKE),
|
|
.o_sdr_n_CS (o_sdr_n_CS),
|
|
.o_sdr_n_RAS (o_sdr_n_RAS),
|
|
.o_sdr_n_CAS (o_sdr_n_CAS),
|
|
.o_sdr_n_WE (o_sdr_n_WE),
|
|
.o_sdr_BA (o_sdr_BA),
|
|
.o_sdr_ADDR (o_sdr_ADDR),
|
|
.o_sdr_DATA (o_sdr_DATA),
|
|
.o_sdr_DATA_oe (o_sdr_DATA_oe),
|
|
.i_sdr_DATA (i_sdr_DATA),
|
|
.o_sdr_DQM (o_sdr_DQM),
|
|
|
|
.o_dbg_ref_req (o_dbg_ref_req),
|
|
.o_dbg_n_CS (o_dbg_n_CS),
|
|
.o_dbg_n_RAS (o_dbg_n_RAS),
|
|
.o_dbg_n_CAS (o_dbg_n_CAS),
|
|
.o_dbg_n_WE (o_dbg_n_WE),
|
|
.o_dbg_BA (o_dbg_BA),
|
|
.o_dbg_ADDR (o_dbg_ADDR),
|
|
.o_dbg_DATA_out (o_dbg_DATA_out),
|
|
.o_dbg_DATA_in (o_dbg_DATA_in),
|
|
.o_dbg_wr_ack (o_dbg_wr_ack),
|
|
.o_dbg_rd_ack (o_dbg_rd_ack)
|
|
);
|
|
|
|
`IP_MODULE_NAME(dual_clock_fifo_wrapper)
|
|
#(
|
|
.DATA_WIDTH(AXI_RDATA_WIDTH+AXI_ARID_WIDTH+1),
|
|
.ADDR_WIDTH(8),
|
|
.LATENCY(2),
|
|
.FIFO_MODE("STD_FIFO"),
|
|
.RAM_INIT_FILE(""),
|
|
.COMPATIBILITY("E"),
|
|
.OUTPUT_REG("FALSE"),
|
|
.CHECK_FULL("TRUE"),
|
|
.CHECK_EMPTY("TRUE"),
|
|
.AFULL_THRESHOLD(2**8-1),
|
|
.AEMPTY_THRESHOLD(1)
|
|
)
|
|
inst_dual_clock_fifo_wrapper
|
|
(
|
|
.i_arst(~i_aresetn),
|
|
|
|
.i_wclk(i_sysclk),
|
|
.i_we(r_fifo_wr_1P),
|
|
.i_wdata(r_dout_1P),
|
|
|
|
.i_rclk(i_sysclk),
|
|
.i_re(r_fifo_rd_1P || (r_AXI4_RVALID_1P && i_AXI4_RREADY)),
|
|
|
|
.o_full(w_afull),
|
|
.o_empty(w_empty),
|
|
.o_rdata(w_fifo_dout),
|
|
|
|
.o_afull(),
|
|
.o_wcnt(),
|
|
.o_aempty(),
|
|
.o_rcnt(),
|
|
|
|
.o_dbg_we(o_dbg_fifo_we),
|
|
.o_dbg_waddr(o_dbg_fifo_waddr),
|
|
.o_dbg_re(o_dbg_fifo_re),
|
|
.o_dbg_raddr(o_dbg_fifo_raddr)
|
|
);
|
|
|
|
always@(negedge i_aresetn or posedge i_sysclk)
|
|
begin
|
|
if (~i_aresetn)
|
|
begin
|
|
r_axi4_wrstate_1P <= s_INIT;
|
|
r_axi4_rastate_1P <= s_INIT;
|
|
r_axi4_rdstate_1P <= s_INIT;
|
|
r_axi4_nwr_1P <= 1'b0;
|
|
|
|
r_AXI4_AWREADY_1P <= 1'b0;
|
|
r_AXI4_AWLEN_1P <= 1'b0;
|
|
//r_AXI4_WREADY_c <= 1'b0;
|
|
r_AXI4_WLAST_1P <= 1'b0;
|
|
r_AXI4_BVALID_1P <= 1'b0;
|
|
r_AXI4_ARREADY_1P <= 1'b0;
|
|
r_AXI4_ARLEN_1P <= {8{1'b0}};
|
|
r_AXI4_RVALID_1P <= 1'b0;
|
|
r_AXI4_BID_1P <= {AXI_BID_WIDTH{1'b0}};
|
|
r_AXI4_RID_1P <= {AXI_ARID_WIDTH{1'b0}};
|
|
|
|
r_we_1P <= 1'b0;
|
|
r_re_1P <= 1'b0;
|
|
r_last_1P <= 1'b0;
|
|
r_addr_1P <= {BA_WIDTH+ROW_WIDTH+COL_WIDTH{1'b0}};
|
|
r_din_1P <= {DIN_WIDTH{1'b0}};
|
|
r_size_1P <= {7{1'b0}};
|
|
r_shift_cnt_1P <= {7{1'b0}};
|
|
r_addr_cnt_1P <= {7{1'b0}};
|
|
r_arlen_cnt_1P <= {8{1'b0}};
|
|
|
|
r_wr_ack_1P <= 1'b0;
|
|
r_AXI4_WREADY_2P <= 1'b0;
|
|
r_re_lock_1P <= 1'b0;
|
|
|
|
r_AXI4_RID[0] <= {AXI_ARID_WIDTH{1'b0}};
|
|
r_dout_1P <= {DOUT_WIDTH+AXI_ARID_WIDTH+1{1'b0}};
|
|
r_fifo_wr_1P <= 1'b0;
|
|
r_fifo_rd_1P <= 1'b0;
|
|
end
|
|
else if (i_pll_locked)
|
|
begin
|
|
r_axi4_nwr_1P <= ~r_axi4_nwr_1P;
|
|
r_AXI4_AWREADY_1P <= 1'b0;
|
|
//r_AXI4_WREADY_c <= 1'b0;
|
|
r_AXI4_ARREADY_1P <= 1'b0;
|
|
|
|
r_wr_ack_1P <= w_wr_ack;
|
|
r_AXI4_WREADY_2P <= r_AXI4_WREADY_c;
|
|
|
|
r_AXI4_RID[0] <= r_AXI4_RID_1P;
|
|
r_fifo_wr_1P <= 1'b0;
|
|
r_fifo_rd_1P <= 1'b0;
|
|
|
|
case (r_axi4_wrstate_1P)
|
|
s_INIT:
|
|
begin
|
|
if (w_sdr_init_done)
|
|
r_axi4_wrstate_1P <= s_IDLE;
|
|
end
|
|
|
|
s_IDLE:
|
|
begin
|
|
if (i_AXI4_AWVALID && i_AXI4_WVALID &&
|
|
~r_axi4_nwr_1P && ~r_re_lock_1P)
|
|
begin
|
|
r_axi4_wrstate_1P <= s_WR_SHIFT;
|
|
r_AXI4_AWREADY_1P <= 1'b1;
|
|
if (i_AXI4_AWLEN != {8{1'b0}})
|
|
r_AXI4_AWLEN_1P <= 1'b1;
|
|
else
|
|
r_AXI4_AWLEN_1P <= 1'b0;
|
|
r_AXI4_WLAST_1P <= i_AXI4_WLAST;
|
|
if (AXI_AWID_WIDTH >= AXI_BID_WIDTH)
|
|
r_AXI4_BID_1P <= i_AXI4_AWID[AXI_BID_WIDTH-1:0];
|
|
else
|
|
r_AXI4_BID_1P <= {{AXI_BID_WIDTH-AXI_AWID_WIDTH{1'b0}}, i_AXI4_AWID};
|
|
|
|
r_we_1P <= 1'b1;
|
|
// TODO AXI different width support
|
|
if (SDR_BWIDTH > AXI_WDATA_WIDTH)
|
|
begin
|
|
r_addr_1P[0+:BA_WIDTH+ROW_WIDTH+COL_WIDTH-(0-SDR_BWIDTH/AXI_WDATA_WIDTH+1)] <= i_AXI4_AWADDR[BA_WIDTH+ROW_WIDTH+COL_WIDTH-1:0-SDR_BWIDTH/AXI_WDATA_WIDTH+1];
|
|
$display("foo_gt\n");
|
|
end
|
|
else if (SDR_BWIDTH == AXI_WDATA_WIDTH)
|
|
begin
|
|
//r_addr_1P <= {i_AXI4_AWADDR[BA_WIDTH+ROW_WIDTH+COL_WIDTH-1:COL_WIDTH], {(DATA_RATE-1){1'b0}}, i_AXI4_AWADDR[COL_WIDTH-1:DATA_RATE-1]};
|
|
r_addr_1P <= i_AXI4_AWADDR;
|
|
$display("foo_eq\n");
|
|
end
|
|
|
|
if (SDR_BWIDTH > AXI_WDATA_WIDTH)
|
|
begin
|
|
//r_AXI4_WREADY_c <= 1'b1;
|
|
r_size_1P <= SDR_BWIDTH/AXI_WDATA_WIDTH-1'b1;
|
|
r_shift_cnt_1P <= SDR_BWIDTH/AXI_WDATA_WIDTH-1'b1;
|
|
$display("SDR_BWIDTH %d > AXI_WDATA_WIDTH %d\n", SDR_BWIDTH, AXI_WDATA_WIDTH);
|
|
end
|
|
else if (SDR_BWIDTH == AXI_WDATA_WIDTH)
|
|
begin
|
|
if (i_AXI4_WLAST)
|
|
begin
|
|
r_din_1P <= i_AXI4_WDATA;
|
|
r_last_1P <= 1'b1;
|
|
end
|
|
r_size_1P <= SDR_BWIDTH/AXI_WDATA_WIDTH-1'b1;
|
|
r_shift_cnt_1P <= {7{1'b0}};
|
|
$display("SDR_BWIDTH %d = AXI_WDATA_WIDTH %d\n", SDR_BWIDTH, AXI_WDATA_WIDTH);
|
|
end
|
|
else
|
|
begin
|
|
//r_AXI4_WREADY_c <= 1'b1;
|
|
r_size_1P <= AXI_WDATA_WIDTH/SDR_BWIDTH-1'b1;
|
|
r_shift_cnt_1P <= AXI_WDATA_WIDTH/SDR_BWIDTH-1'b1;
|
|
$display("SDR_BWIDTH %d < AXI_WDATA_WIDTH %d\n", SDR_BWIDTH, AXI_WDATA_WIDTH);
|
|
end
|
|
end
|
|
end
|
|
|
|
s_WR_SHIFT:
|
|
begin
|
|
if (SDR_BWIDTH > AXI_WDATA_WIDTH)
|
|
begin
|
|
if (r_shift_cnt_1P != 7'd0)
|
|
begin
|
|
if (r_AXI4_WREADY_c)
|
|
r_shift_cnt_1P <= r_shift_cnt_1P-1'b1;
|
|
end
|
|
else
|
|
begin
|
|
r_shift_cnt_1P <= r_size_1P;
|
|
end
|
|
end
|
|
else if (SDR_BWIDTH == AXI_WDATA_WIDTH)
|
|
begin
|
|
if (r_AXI4_WREADY_2P)
|
|
r_addr_1P <= r_addr_1P+c_addr_increment;
|
|
|
|
if (r_AXI4_WREADY_c)
|
|
r_din_1P <= i_AXI4_WDATA;
|
|
|
|
if (~r_AXI4_WREADY_c & r_AXI4_WREADY_2P & i_AXI4_WLAST)
|
|
begin
|
|
r_din_1P <= i_AXI4_WDATA;
|
|
end
|
|
end
|
|
|
|
if (w_wr_ack)
|
|
begin
|
|
/*if (SDR_BWIDTH < AXI_WDATA_WIDTH)
|
|
begin
|
|
if (r_size_1P != `BYTES_TX_1)
|
|
r_addr_1P <= r_addr_1P+c_addr_increment;
|
|
else if (~r_wr_ack_1P)
|
|
r_addr_1P <= r_addr_1P+c_addr_increment;
|
|
else if (r_AXI4_WREADY_2P)
|
|
r_addr_1P <= r_addr_1P+c_addr_increment;
|
|
|
|
r_shift_cnt_1P <= r_shift_cnt_1P-1'b1;
|
|
if (r_AXI4_WLAST_1P && r_shift_cnt_1P == 7'd1)
|
|
r_last_1P <= 1'b1;
|
|
end
|
|
else if (SDR_BWIDTH == AXI_WDATA_WIDTH)
|
|
begin
|
|
r_AXI4_WREADY_c <= 1'b1;
|
|
end
|
|
else
|
|
begin
|
|
r_AXI4_WREADY_c <= 1'b1;
|
|
|
|
if (r_AXI4_WREADY_c)
|
|
r_addr_1P <= r_addr_1P+1'b1;
|
|
|
|
if (r_shift_cnt_1P == 7'd1)
|
|
begin
|
|
if (i_AXI4_WLAST || r_AXI4_WLAST_1P)
|
|
begin
|
|
r_axi4_wrstate_1P <= s_WR_RESP;
|
|
r_AXI4_WREADY_c <= 1'b0;
|
|
r_AXI4_WLAST_1P <= 1'b0;
|
|
r_AXI4_BVALID_1P <= 1'b1;
|
|
|
|
r_last_1P <= 1'b1;
|
|
end
|
|
end
|
|
end*/
|
|
|
|
if (r_shift_cnt_1P == 7'd0)
|
|
begin
|
|
//r_AXI4_WREADY_c <= 1'b1;
|
|
|
|
r_AXI4_WLAST_1P <= i_AXI4_WLAST;
|
|
r_shift_cnt_1P <= r_size_1P;
|
|
|
|
if (i_AXI4_WLAST && r_size_1P == {7{1'b0}} && r_AXI4_AWLEN_1P)
|
|
begin
|
|
r_axi4_wrstate_1P <= s_WR_RESP;
|
|
//r_AXI4_WREADY_c <= ~r_AXI4_WREADY_c;
|
|
r_AXI4_WLAST_1P <= 1'b0;
|
|
r_AXI4_BVALID_1P <= 1'b1;
|
|
|
|
r_we_1P <= 1'b1;
|
|
r_last_1P <= 1'b1;
|
|
end
|
|
else if (r_AXI4_WLAST_1P)
|
|
begin
|
|
r_axi4_wrstate_1P <= s_WR_RESP;
|
|
//r_AXI4_WREADY_c <= ~r_AXI4_WREADY_c;
|
|
r_AXI4_WLAST_1P <= 1'b0;
|
|
r_AXI4_BVALID_1P <= 1'b1;
|
|
|
|
r_we_1P <= 1'b0;
|
|
r_last_1P <= 1'b0;
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
s_WR_RESP:
|
|
begin
|
|
r_we_1P <= 1'b0;
|
|
r_last_1P <= 1'b0;
|
|
|
|
if (i_AXI4_BREADY)
|
|
begin
|
|
r_axi4_wrstate_1P <= s_IDLE;
|
|
r_AXI4_BVALID_1P <= 1'b0;
|
|
end
|
|
end
|
|
endcase
|
|
|
|
case (r_axi4_rastate_1P)
|
|
s_INIT:
|
|
begin
|
|
if (w_sdr_init_done)
|
|
r_axi4_rastate_1P <= s_IDLE;
|
|
end
|
|
|
|
s_IDLE:
|
|
begin
|
|
if (i_AXI4_ARVALID && r_axi4_nwr_1P
|
|
&& ~r_we_1P && ~w_afull && ~r_AXI4_RVALID_1P)
|
|
begin
|
|
r_axi4_rastate_1P <= s_RD_ADDR;
|
|
r_AXI4_ARREADY_1P <= 1'b1;
|
|
r_AXI4_RID_1P <= i_AXI4_ARID;
|
|
|
|
r_re_1P <= 1'b1;
|
|
r_re_lock_1P <= 1'b1;
|
|
if (i_AXI4_ARLEN == 8'd0 && (SDR_BWIDTH == AXI_RDATA_WIDTH))
|
|
r_last_1P <= 1'b1;
|
|
|
|
// TODO AXI different width support
|
|
if (SDR_BWIDTH > AXI_RDATA_WIDTH)
|
|
begin
|
|
r_addr_1P[0+:BA_WIDTH+ROW_WIDTH+COL_WIDTH-(0-SDR_BWIDTH/AXI_RDATA_WIDTH+1)] <= i_AXI4_ARADDR[BA_WIDTH+ROW_WIDTH+COL_WIDTH-1:0-SDR_BWIDTH/AXI_RDATA_WIDTH+1];
|
|
end
|
|
else if (SDR_BWIDTH == AXI_RDATA_WIDTH)
|
|
begin
|
|
//r_addr_1P <= {i_AXI4_ARADDR[BA_WIDTH+ROW_WIDTH+COL_WIDTH-1:COL_WIDTH], {(DATA_RATE-1){1'b0}}, i_AXI4_ARADDR[COL_WIDTH-1:DATA_RATE-1]};
|
|
r_addr_1P <= i_AXI4_ARADDR;
|
|
end
|
|
|
|
if (SDR_BWIDTH > AXI_WDATA_WIDTH)
|
|
begin
|
|
r_size_1P <= SDR_BWIDTH/AXI_RDATA_WIDTH-1'b1;
|
|
r_shift_cnt_1P <= SDR_BWIDTH/AXI_RDATA_WIDTH-1'b1;
|
|
r_addr_cnt_1P <= SDR_BWIDTH/AXI_RDATA_WIDTH-1'b1;
|
|
end
|
|
else if (SDR_BWIDTH == AXI_WDATA_WIDTH)
|
|
begin
|
|
r_AXI4_ARLEN_1P <= i_AXI4_ARLEN;
|
|
r_size_1P <= 7'd0;
|
|
r_shift_cnt_1P <= 7'd0;
|
|
r_addr_cnt_1P <= 7'd0;
|
|
r_arlen_cnt_1P <= i_AXI4_ARLEN;
|
|
end
|
|
else
|
|
begin
|
|
r_AXI4_ARLEN_1P <= i_AXI4_ARLEN;
|
|
r_size_1P <= AXI_RDATA_WIDTH/SDR_BWIDTH-1'b1;
|
|
r_shift_cnt_1P <= AXI_RDATA_WIDTH/SDR_BWIDTH-1'b1;
|
|
r_addr_cnt_1P <= AXI_RDATA_WIDTH/SDR_BWIDTH-1'b1;
|
|
r_arlen_cnt_1P <= i_AXI4_ARLEN;
|
|
end
|
|
end
|
|
end
|
|
|
|
s_RD_ADDR:
|
|
begin
|
|
if (~w_afull)
|
|
r_re_1P <= 1'b1;
|
|
|
|
if (w_rd_ack)
|
|
begin
|
|
if (w_afull)
|
|
r_re_1P <= 1'b0;
|
|
if (SDR_BWIDTH < AXI_WDATA_WIDTH)
|
|
r_addr_1P <= r_addr_1P+c_addr_increment;
|
|
else if (SDR_BWIDTH == AXI_WDATA_WIDTH)
|
|
r_addr_1P <= r_addr_1P+c_addr_increment;
|
|
else
|
|
r_addr_1P <= r_addr_1P+1'b1;
|
|
|
|
r_addr_cnt_1P <= r_addr_cnt_1P-1'b1;
|
|
if (r_addr_cnt_1P == 7'd0)
|
|
begin
|
|
r_addr_cnt_1P <= r_size_1P;
|
|
r_arlen_cnt_1P <= r_arlen_cnt_1P-1'b1;
|
|
end
|
|
|
|
if (r_arlen_cnt_1P == 8'd1 && (SDR_BWIDTH == AXI_RDATA_WIDTH))
|
|
r_last_1P <= 1'b1;
|
|
|
|
if (r_arlen_cnt_1P == 8'd0)
|
|
begin
|
|
if (r_addr_cnt_1P == 8'd1)
|
|
r_last_1P <= 1'b1;
|
|
|
|
if (r_addr_cnt_1P == 8'd0)
|
|
begin
|
|
r_axi4_rastate_1P <= s_IDLE;
|
|
|
|
r_re_1P <= 1'b0;
|
|
r_last_1P <= 1'b0;
|
|
r_re_lock_1P <= 1'b0;
|
|
end
|
|
end
|
|
end
|
|
end
|
|
endcase
|
|
|
|
if (w_rd_valid)
|
|
begin
|
|
if (SDR_BWIDTH >= AXI_RDATA_WIDTH)
|
|
begin
|
|
r_dout_1P[DOUT_WIDTH-1:0] <= w_dout;
|
|
end
|
|
|
|
r_dout_1P[DOUT_WIDTH+AXI_ARID_WIDTH-1:DOUT_WIDTH] <= r_AXI4_RID[CL+tIORT+1];
|
|
|
|
r_shift_cnt_1P <= r_shift_cnt_1P-1'b1;
|
|
|
|
if (r_shift_cnt_1P == 7'd0)
|
|
begin
|
|
r_fifo_wr_1P <= 1'b1;
|
|
if (r_AXI4_ARLEN_1P == 7'd0)
|
|
r_dout_1P[DOUT_WIDTH+AXI_ARID_WIDTH] <= 1'b1;
|
|
else
|
|
r_AXI4_ARLEN_1P <= r_AXI4_ARLEN_1P-1'b1;
|
|
r_shift_cnt_1P <= r_size_1P;
|
|
end
|
|
end
|
|
|
|
case (r_axi4_rdstate_1P)
|
|
s_INIT:
|
|
begin
|
|
if (w_sdr_init_done)
|
|
r_axi4_rdstate_1P <= s_IDLE;
|
|
end
|
|
|
|
s_IDLE:
|
|
begin
|
|
if (~w_empty & r_dout_1P[DOUT_WIDTH+AXI_ARID_WIDTH])
|
|
begin
|
|
r_axi4_rdstate_1P <= s_RD_SHIFT;
|
|
r_fifo_rd_1P <= 1'b1;
|
|
r_dout_1P[DOUT_WIDTH+AXI_ARID_WIDTH] <= 1'b0;
|
|
end
|
|
end
|
|
|
|
s_RD_SHIFT:
|
|
begin
|
|
r_AXI4_RVALID_1P <= 1'b1;
|
|
|
|
if (i_AXI4_RREADY)
|
|
begin
|
|
if (w_empty)
|
|
begin
|
|
r_axi4_rdstate_1P <= s_IDLE;
|
|
r_AXI4_RVALID_1P <= 1'b0;
|
|
end
|
|
|
|
if (w_fifo_dout[AXI_RDATA_WIDTH+AXI_ARID_WIDTH])
|
|
begin
|
|
r_axi4_rdstate_1P <= s_IDLE;
|
|
r_AXI4_RVALID_1P <= 1'b0;
|
|
end
|
|
end
|
|
end
|
|
endcase
|
|
end
|
|
end
|
|
|
|
genvar i;
|
|
generate
|
|
for (i=0; i<CL+tIORT+1; i=i+1)
|
|
begin: pipe
|
|
always@(negedge i_aresetn or posedge i_sysclk)
|
|
begin
|
|
if (~i_aresetn)
|
|
r_AXI4_RID[i+1] <= {AXI_ARID_WIDTH{1'b0}};
|
|
else
|
|
r_AXI4_RID[i+1] <= r_AXI4_RID[i];
|
|
end
|
|
end
|
|
endgenerate
|
|
|
|
assign r_AXI4_WREADY_c = w_wr_ack;
|
|
|
|
assign o_AXI4_AWREADY = r_AXI4_AWREADY_1P;
|
|
assign o_AXI4_WREADY = r_AXI4_WREADY_c;
|
|
assign o_AXI4_BVALID = r_AXI4_BVALID_1P;
|
|
assign o_AXI4_ARREADY = r_AXI4_ARREADY_1P;
|
|
assign o_AXI4_RVALID = r_AXI4_RVALID_1P;
|
|
assign o_AXI4_RDATA = w_fifo_dout[AXI_RDATA_WIDTH-1:0];
|
|
assign o_AXI4_RLAST = w_fifo_dout[AXI_RDATA_WIDTH+AXI_ARID_WIDTH];
|
|
assign o_AXI4_BID = r_AXI4_BID_1P;
|
|
assign o_AXI4_RID = w_fifo_dout[AXI_RDATA_WIDTH+AXI_ARID_WIDTH-1:AXI_RDATA_WIDTH];
|
|
assign o_AXI4_BRESP = `OKAY;
|
|
assign o_AXI4_BUSER = {AXI_BUSER_WIDTH{1'b0}};
|
|
assign o_AXI4_RRESP = `OKAY;
|
|
assign o_AXI4_RUSER = {AXI_RUSER_WIDTH{1'b0}};
|
|
|
|
assign o_dbg_we = r_we_1P;
|
|
assign o_dbg_re = r_re_1P;
|
|
assign o_dbg_last = r_last_1P;
|
|
assign o_dbg_addr = r_addr_1P;
|
|
assign o_dbg_din = r_din_1P;
|
|
assign o_sdr_rd_valid = w_rd_valid;
|
|
assign o_sdr_dout = r_dout_1P;
|
|
assign o_axi4_wrstate = r_axi4_wrstate_1P;
|
|
assign o_dbg_axi4_wlast = r_AXI4_WLAST_1P;
|
|
assign o_axi4_rastate = r_axi4_rastate_1P;
|
|
assign o_axi4_rdstate = r_axi4_rdstate_1P;
|
|
assign o_axi4_nwr = r_axi4_nwr_1P;
|
|
assign o_re_lock = r_re_lock_1P;
|
|
assign o_shift_cnt = r_shift_cnt_1P;
|
|
assign o_axi4_arlen = r_AXI4_ARLEN_1P;
|
|
assign o_fifo_wr = r_fifo_wr_1P;
|
|
assign o_fifo_full = w_afull;
|
|
assign o_fifo_empty = w_empty;
|
|
|
|
endmodule
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
// Copyright (C) 2013-2019 Efinix Inc. All rights reserved.
|
|
//
|
|
// This document contains proprietary information which is
|
|
// protected by copyright. All rights are reserved. This notice
|
|
// refers to original work by Efinix, Inc. which may be derivitive
|
|
// of other work distributed under license of the authors. In the
|
|
// case of derivative work, nothing in this notice overrides the
|
|
// original author's license agreement. Where applicable, the
|
|
// original license agreement is included in it's original
|
|
// unmodified form immediately below this header.
|
|
//
|
|
// WARRANTY DISCLAIMER.
|
|
// THE DESIGN, CODE, OR INFORMATION ARE PROVIDED “AS IS” AND
|
|
// EFINIX MAKES NO WARRANTIES, EXPRESS OR IMPLIED WITH
|
|
// RESPECT THERETO, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES,
|
|
// INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
|
// MERCHANTABILITY, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR
|
|
// PURPOSE. SOME STATES DO NOT ALLOW EXCLUSIONS OF AN IMPLIED
|
|
// WARRANTY, SO THIS DISCLAIMER MAY NOT APPLY TO LICENSEE.
|
|
//
|
|
// LIMITATION OF LIABILITY.
|
|
// NOTWITHSTANDING ANYTHING TO THE CONTRARY, EXCEPT FOR BODILY
|
|
// INJURY, EFINIX SHALL NOT BE LIABLE WITH RESPECT TO ANY SUBJECT
|
|
// MATTER OF THIS AGREEMENT UNDER TORT, CONTRACT, STRICT LIABILITY
|
|
// OR ANY OTHER LEGAL OR EQUITABLE THEORY (I) FOR ANY INDIRECT,
|
|
// SPECIAL, INCIDENTAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES OF ANY
|
|
// CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF
|
|
// GOODWILL, DATA OR PROFIT, WORK STOPPAGE, OR COMPUTER FAILURE OR
|
|
// MALFUNCTION, OR IN ANY EVENT (II) FOR ANY AMOUNT IN EXCESS, IN
|
|
// THE AGGREGATE, OF THE FEE PAID BY LICENSEE TO EFINIX HEREUNDER
|
|
// (OR, IF THE FEE HAS BEEN WAIVED, $100), EVEN IF EFINIX SHALL HAVE
|
|
// BEEN INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO
|
|
// NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR
|
|
// CONSEQUENTIAL DAMAGES, SO THIS LIMITATION AND EXCLUSION MAY NOT
|
|
// APPLY TO LICENSEE.
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////projects/SWIP/hxlai/workplace/test/20201008_184659/testbench_random
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// _____
|
|
// / _______ Copyright (C) 2013-2020 Efinix Inc. All rights reserved.
|
|
// / / \
|
|
// / / .. / axi4.vh
|
|
// / / .' /
|
|
// __/ /.' / Description:
|
|
// __ \ / axi4 header file
|
|
// /_/ /\ \_____/ /
|
|
// ____/ \_______/
|
|
//
|
|
// *******************************
|
|
// Revisions:
|
|
// 1.0 Initial rev
|
|
//
|
|
// *******************************
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
// AxSIZE
|
|
`define BYTES_TX_1 3'b000
|
|
`define BYTES_TX_2 3'b001
|
|
`define BYTES_TX_4 3'b010
|
|
`define BYTES_TX_8 3'b011
|
|
`define BYTES_TX_16 3'b100
|
|
`define BYTES_TX_32 3'b101
|
|
`define BYTES_TX_64 3'b110
|
|
`define BYTES_TX_128 3'b111
|
|
|
|
// AxBURST
|
|
`define FIXED 2'b00
|
|
`define INCR 2'b01
|
|
`define WRAP 2'b10
|
|
`define RESERVED 2'b11
|
|
|
|
// xRESP
|
|
`define OKAY 2'b00
|
|
`define EXOKAY 2'b01
|
|
`define SLVERR 2'b10
|
|
`define DECERR 2'b11
|
|
|
|
// AxCACHE
|
|
`define B_BIT 0
|
|
`define M_BIT 1
|
|
`define OA_BIT 2
|
|
`define A_BIT 3
|
|
|
|
// AxPROT
|
|
`define PRIVILEGED 0
|
|
`define SECURE 1
|
|
`define DATA_INSTR 2
|
|
|
|
// AxLOCK
|
|
`define NORMAL 1'b0
|
|
`define EXCLUSIVE 1'b1
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// _____
|
|
// / _______ Copyright (C) 2013-2020 Efinix Inc. All rights reserved.
|
|
// / / \
|
|
// / / .. / `IP_MODULE_NAME(dual_clock_fifo_wrapper).v
|
|
// / / .' /
|
|
// __/ /.' / Description:
|
|
// __ \ / wraps around dual clock fifo
|
|
// /_/ /\ \_____/ /
|
|
// ____/ \_______/
|
|
//
|
|
// *******************************
|
|
// Revisions:
|
|
// 1.0 Initial rev
|
|
//
|
|
// *******************************
|
|
|
|
module `IP_MODULE_NAME(dual_clock_fifo_wrapper)
|
|
#(
|
|
parameter DATA_WIDTH = 8,
|
|
parameter ADDR_WIDTH = 8,
|
|
parameter LATENCY = 1,
|
|
parameter FIFO_MODE = "STD_FIFO",
|
|
parameter RAM_INIT_FILE = "",
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
// compatibility output_reg check_full_overflow check_empty_underflow
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
// E user configurable user configurable user configurable
|
|
// X user configurable always on always on
|
|
// A always off user configurable user configurable
|
|
parameter COMPATIBILITY = "E",
|
|
parameter OUTPUT_REG = "TRUE",
|
|
parameter CHECK_FULL = "TRUE",
|
|
parameter CHECK_EMPTY = "TRUE",
|
|
parameter AFULL_THRESHOLD = 2**ADDR_WIDTH-1,
|
|
parameter AEMPTY_THRESHOLD= 1
|
|
)
|
|
(
|
|
input i_arst,
|
|
|
|
input i_wclk,
|
|
input i_we,
|
|
input [DATA_WIDTH-1:0] i_wdata,
|
|
|
|
input i_rclk,
|
|
input i_re,
|
|
|
|
output o_full,
|
|
output o_empty,
|
|
output [DATA_WIDTH-1:0] o_rdata,
|
|
|
|
output o_afull,
|
|
output [ADDR_WIDTH-1:0] o_wcnt,
|
|
output o_aempty,
|
|
output [ADDR_WIDTH-1:0] o_rcnt,
|
|
|
|
output o_dbg_we,
|
|
output [ADDR_WIDTH-1:0] o_dbg_waddr,
|
|
output o_dbg_re,
|
|
output [ADDR_WIDTH-1:0] o_dbg_raddr
|
|
);
|
|
|
|
generate
|
|
if (COMPATIBILITY == "X")
|
|
begin
|
|
if (FIFO_MODE == "BYPASS")
|
|
begin
|
|
`IP_MODULE_NAME(dual_clock_fifo)
|
|
#(
|
|
.DATA_WIDTH (DATA_WIDTH),
|
|
.ADDR_WIDTH (ADDR_WIDTH),
|
|
.LATENCY (LATENCY+4),
|
|
.FIFO_MODE (FIFO_MODE),
|
|
.RAM_INIT_FILE (RAM_INIT_FILE),
|
|
.COMPATIBILITY (COMPATIBILITY),
|
|
.OUTPUT_REG ("FALSE"),
|
|
.CHECK_FULL ("TRUE"),
|
|
.CHECK_EMPTY ("TRUE"),
|
|
.AFULL_THRESHOLD (AFULL_THRESHOLD),
|
|
.AEMPTY_THRESHOLD (AEMPTY_THRESHOLD)
|
|
)
|
|
inst_dual_clock_fifo
|
|
(
|
|
.i_arst (i_arst),
|
|
.i_wclk (i_wclk),
|
|
.i_we (i_we),
|
|
.i_wdata (i_wdata),
|
|
.i_rclk (i_rclk),
|
|
.i_re (i_re),
|
|
.o_full (o_full),
|
|
.o_empty (o_empty),
|
|
.o_rdata (o_rdata),
|
|
|
|
.o_afull (o_afull),
|
|
.o_wcnt (o_wcnt),
|
|
.o_aempty (o_aempty),
|
|
.o_rcnt (o_rcnt),
|
|
|
|
.o_dbg_we (o_dbg_we),
|
|
.o_dbg_waddr(o_dbg_waddr),
|
|
.o_dbg_re (o_dbg_re),
|
|
.o_dbg_raddr(o_dbg_raddr)
|
|
);
|
|
end
|
|
else
|
|
begin
|
|
`IP_MODULE_NAME(dual_clock_fifo)
|
|
#(
|
|
.DATA_WIDTH (DATA_WIDTH),
|
|
.ADDR_WIDTH (ADDR_WIDTH),
|
|
.LATENCY (LATENCY+2),
|
|
.FIFO_MODE (FIFO_MODE),
|
|
.RAM_INIT_FILE (RAM_INIT_FILE),
|
|
.COMPATIBILITY (COMPATIBILITY),
|
|
.OUTPUT_REG (OUTPUT_REG),
|
|
.CHECK_FULL ("TRUE"),
|
|
.CHECK_EMPTY ("TRUE"),
|
|
.AFULL_THRESHOLD (AFULL_THRESHOLD),
|
|
.AEMPTY_THRESHOLD (AEMPTY_THRESHOLD)
|
|
)
|
|
inst_dual_clock_fifo
|
|
(
|
|
.i_arst (i_arst),
|
|
.i_wclk (i_wclk),
|
|
.i_we (i_we),
|
|
.i_wdata (i_wdata),
|
|
.i_rclk (i_rclk),
|
|
.i_re (i_re),
|
|
.o_full (o_full),
|
|
.o_empty (o_empty),
|
|
.o_rdata (o_rdata),
|
|
|
|
.o_afull (o_afull),
|
|
.o_wcnt (o_wcnt),
|
|
.o_aempty (o_aempty),
|
|
.o_rcnt (o_rcnt),
|
|
|
|
.o_dbg_we (o_dbg_we),
|
|
.o_dbg_waddr(o_dbg_waddr),
|
|
.o_dbg_re (o_dbg_re),
|
|
.o_dbg_raddr(o_dbg_raddr)
|
|
);
|
|
end
|
|
end
|
|
else if (COMPATIBILITY == "A")
|
|
begin
|
|
`IP_MODULE_NAME(dual_clock_fifo)
|
|
#(
|
|
.DATA_WIDTH (DATA_WIDTH),
|
|
.ADDR_WIDTH (ADDR_WIDTH),
|
|
.LATENCY (LATENCY),
|
|
.FIFO_MODE (FIFO_MODE),
|
|
.RAM_INIT_FILE (RAM_INIT_FILE),
|
|
.COMPATIBILITY (COMPATIBILITY),
|
|
.OUTPUT_REG ("FALSE"),
|
|
.CHECK_FULL (CHECK_FULL),
|
|
.CHECK_EMPTY (CHECK_EMPTY),
|
|
.AFULL_THRESHOLD (AFULL_THRESHOLD),
|
|
.AEMPTY_THRESHOLD (AEMPTY_THRESHOLD)
|
|
)
|
|
inst_dual_clock_fifo
|
|
(
|
|
.i_arst (i_arst),
|
|
.i_wclk (i_wclk),
|
|
.i_we (i_we),
|
|
.i_wdata (i_wdata),
|
|
.i_rclk (i_rclk),
|
|
.i_re (i_re),
|
|
.o_full (o_full),
|
|
.o_empty (o_empty),
|
|
.o_rdata (o_rdata),
|
|
|
|
.o_afull (o_afull),
|
|
.o_wcnt (o_wcnt),
|
|
.o_aempty (o_aempty),
|
|
.o_rcnt (o_rcnt),
|
|
|
|
.o_dbg_we (o_dbg_we),
|
|
.o_dbg_waddr(o_dbg_waddr),
|
|
.o_dbg_re (o_dbg_re),
|
|
.o_dbg_raddr(o_dbg_raddr)
|
|
);
|
|
end
|
|
else
|
|
begin
|
|
`IP_MODULE_NAME(dual_clock_fifo)
|
|
#(
|
|
.DATA_WIDTH (DATA_WIDTH),
|
|
.ADDR_WIDTH (ADDR_WIDTH),
|
|
.LATENCY (LATENCY),
|
|
.FIFO_MODE (FIFO_MODE),
|
|
.RAM_INIT_FILE (RAM_INIT_FILE),
|
|
.COMPATIBILITY (COMPATIBILITY),
|
|
.OUTPUT_REG (OUTPUT_REG),
|
|
.CHECK_FULL (CHECK_FULL),
|
|
.CHECK_EMPTY (CHECK_EMPTY),
|
|
.AFULL_THRESHOLD (AFULL_THRESHOLD),
|
|
.AEMPTY_THRESHOLD (AEMPTY_THRESHOLD)
|
|
)
|
|
inst_dual_clock_fifo
|
|
(
|
|
.i_arst (i_arst),
|
|
.i_wclk (i_wclk),
|
|
.i_we (i_we),
|
|
.i_wdata (i_wdata),
|
|
.i_rclk (i_rclk),
|
|
.i_re (i_re),
|
|
.o_full (o_full),
|
|
.o_empty (o_empty),
|
|
.o_rdata (o_rdata),
|
|
|
|
.o_afull (o_afull),
|
|
.o_wcnt (o_wcnt),
|
|
.o_aempty (o_aempty),
|
|
.o_rcnt (o_rcnt),
|
|
|
|
.o_dbg_we (o_dbg_we),
|
|
.o_dbg_waddr(o_dbg_waddr),
|
|
.o_dbg_re (o_dbg_re),
|
|
.o_dbg_raddr(o_dbg_raddr)
|
|
);
|
|
end
|
|
endgenerate
|
|
|
|
endmodule
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
// Copyright (C) 2013-2019 Efinix Inc. All rights reserved.
|
|
//
|
|
// This document contains proprietary information which is
|
|
// protected by copyright. All rights are reserved. This notice
|
|
// refers to original work by Efinix, Inc. which may be derivitive
|
|
// of other work distributed under license of the authors. In the
|
|
// case of derivative work, nothing in this notice overrides the
|
|
// original author's license agreement. Where applicable, the
|
|
// original license agreement is included in it's original
|
|
// unmodified form immediately below this header.
|
|
//
|
|
// WARRANTY DISCLAIMER.
|
|
// THE DESIGN, CODE, OR INFORMATION ARE PROVIDED “AS IS” AND
|
|
// EFINIX MAKES NO WARRANTIES, EXPRESS OR IMPLIED WITH
|
|
// RESPECT THERETO, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES,
|
|
// INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
|
// MERCHANTABILITY, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR
|
|
// PURPOSE. SOME STATES DO NOT ALLOW EXCLUSIONS OF AN IMPLIED
|
|
// WARRANTY, SO THIS DISCLAIMER MAY NOT APPLY TO LICENSEE.
|
|
//
|
|
// LIMITATION OF LIABILITY.
|
|
// NOTWITHSTANDING ANYTHING TO THE CONTRARY, EXCEPT FOR BODILY
|
|
// INJURY, EFINIX SHALL NOT BE LIABLE WITH RESPECT TO ANY SUBJECT
|
|
// MATTER OF THIS AGREEMENT UNDER TORT, CONTRACT, STRICT LIABILITY
|
|
// OR ANY OTHER LEGAL OR EQUITABLE THEORY (I) FOR ANY INDIRECT,
|
|
// SPECIAL, INCIDENTAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES OF ANY
|
|
// CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF
|
|
// GOODWILL, DATA OR PROFIT, WORK STOPPAGE, OR COMPUTER FAILURE OR
|
|
// MALFUNCTION, OR IN ANY EVENT (II) FOR ANY AMOUNT IN EXCESS, IN
|
|
// THE AGGREGATE, OF THE FEE PAID BY LICENSEE TO EFINIX HEREUNDER
|
|
// (OR, IF THE FEE HAS BEEN WAIVED, $100), EVEN IF EFINIX SHALL HAVE
|
|
// BEEN INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO
|
|
// NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR
|
|
// CONSEQUENTIAL DAMAGES, SO THIS LIMITATION AND EXCLUSION MAY NOT
|
|
// APPLY TO LICENSEE.
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// _____
|
|
// / _______ Copyright (C) 2013-2020 Efinix Inc. All rights reserved.
|
|
// / / \
|
|
// / / .. / `IP_MODULE_NAME(dual_clock_fifo).v
|
|
// / / .' /
|
|
// __/ /.' / Description:
|
|
// __ \ / dual clock fifo
|
|
// /_/ /\ \_____/ /
|
|
// ____/ \_______/
|
|
//
|
|
// *******************************
|
|
// Revisions:
|
|
// 1.0 Initial rev
|
|
//
|
|
// *******************************
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
module `IP_MODULE_NAME(dual_clock_fifo)
|
|
#(
|
|
parameter DATA_WIDTH = 8,
|
|
parameter ADDR_WIDTH = 8,
|
|
parameter LATENCY = 1,
|
|
parameter FIFO_MODE = "STD_FIFO",
|
|
parameter RAM_INIT_FILE = "",
|
|
parameter COMPATIBILITY = "E",
|
|
parameter OUTPUT_REG = "FALSE",
|
|
parameter CHECK_FULL = "TRUE",
|
|
parameter CHECK_EMPTY = "TRUE",
|
|
parameter AFULL_THRESHOLD = 2**ADDR_WIDTH-1,
|
|
parameter AEMPTY_THRESHOLD= 1
|
|
)
|
|
(
|
|
input i_arst,
|
|
|
|
input i_wclk,
|
|
input i_we,
|
|
input [DATA_WIDTH-1:0] i_wdata,
|
|
|
|
input i_rclk,
|
|
input i_re,
|
|
|
|
output o_full,
|
|
output o_empty,
|
|
output [DATA_WIDTH-1:0] o_rdata,
|
|
|
|
output o_afull,
|
|
output [ADDR_WIDTH-1:0] o_wcnt,
|
|
output o_aempty,
|
|
output [ADDR_WIDTH-1:0] o_rcnt,
|
|
|
|
output o_dbg_we,
|
|
output [ADDR_WIDTH-1:0] o_dbg_waddr,
|
|
output o_dbg_re,
|
|
output [ADDR_WIDTH-1:0] o_dbg_raddr
|
|
);
|
|
|
|
reg [ADDR_WIDTH:0] r_waddrb_1P;
|
|
reg r_wflag_1P;
|
|
reg [ADDR_WIDTH-1:0]r_waddrg_1P;
|
|
reg [ADDR_WIDTH-1:0]r_waddrg_2P;
|
|
|
|
reg [ADDR_WIDTH:0]r_raddrb_wclk_1P;
|
|
reg [ADDR_WIDTH:0]r_raddrb_wclk_neg;
|
|
reg [ADDR_WIDTH:0]wr_cnt;
|
|
|
|
reg [ADDR_WIDTH:0]r_waddrb_rclk_1P;
|
|
reg [ADDR_WIDTH:0]r_waddrb_rclk_neg;
|
|
reg [ADDR_WIDTH:0]rd_cnt;
|
|
|
|
reg r_we_1P;
|
|
reg r_re_1P;
|
|
reg [ADDR_WIDTH:0] r_raddrb_1P;
|
|
reg r_rflag_1P;
|
|
reg [ADDR_WIDTH-1:0]r_raddrg_1P;
|
|
reg r_rflag_2P;
|
|
reg [ADDR_WIDTH-1:0]r_raddrg_2P;
|
|
|
|
reg [LATENCY-1:0] r_empty;
|
|
reg [LATENCY:0] r_full;
|
|
|
|
wire [ADDR_WIDTH:0] w_waddrb_1P;
|
|
wire w_wflag_1P;
|
|
wire [ADDR_WIDTH-1:0]w_waddrg_1P;
|
|
|
|
wire [ADDR_WIDTH:0] w_raddrb_1P;
|
|
wire w_rflag_1P;
|
|
wire [ADDR_WIDTH-1:0]w_raddrg_1P;
|
|
|
|
wire w_empty;
|
|
wire w_full;
|
|
|
|
wire w_empty_P;
|
|
wire w_full_P;
|
|
|
|
wire w_we;
|
|
wire w_re;
|
|
wire [ADDR_WIDTH-1:0]w_raddr;
|
|
|
|
assign w_waddrb_1P = r_waddrb_1P + 1'b1;
|
|
assign w_wflag_1P = w_waddrb_1P[ADDR_WIDTH];
|
|
assign w_waddrg_1P[ADDR_WIDTH-1] = w_waddrb_1P[ADDR_WIDTH-1] ^ 1'b0;
|
|
assign w_waddrg_1P[ADDR_WIDTH-2:0] = w_waddrb_1P[ADDR_WIDTH-2:0] ^ w_waddrb_1P[ADDR_WIDTH-1:1];
|
|
|
|
assign w_full = ((r_waddrg_1P == r_raddrg_1P) &
|
|
(r_wflag_1P != r_rflag_1P))?
|
|
1'b1:
|
|
(i_we &
|
|
((w_waddrg_1P == r_raddrg_2P) &
|
|
(w_wflag_1P != r_rflag_2P)))?
|
|
1'b1:
|
|
1'b0;
|
|
|
|
always@(posedge i_arst or posedge i_wclk)
|
|
begin
|
|
if (i_arst) begin
|
|
r_raddrb_wclk_1P <= {ADDR_WIDTH+1{1'b0}};
|
|
end
|
|
else begin
|
|
r_raddrb_wclk_1P <= r_raddrb_1P;
|
|
end
|
|
end
|
|
|
|
always@(posedge i_arst or posedge i_wclk)
|
|
begin
|
|
if (i_arst) begin
|
|
r_raddrb_wclk_neg <= {ADDR_WIDTH+1{1'b0}};
|
|
end
|
|
else begin
|
|
r_raddrb_wclk_neg <= ~r_raddrb_wclk_1P + 1'b1;
|
|
end
|
|
end
|
|
|
|
always@(posedge i_arst or posedge i_wclk)
|
|
begin
|
|
if (i_arst) begin
|
|
wr_cnt <= {ADDR_WIDTH+1{1'b0}};
|
|
end
|
|
else begin
|
|
wr_cnt <= r_waddrb_1P + r_raddrb_wclk_neg;
|
|
end
|
|
end
|
|
|
|
always@(posedge i_arst or posedge i_rclk)
|
|
begin
|
|
if (i_arst) begin
|
|
r_waddrb_rclk_1P <= {ADDR_WIDTH+1{1'b0}};
|
|
end
|
|
else begin
|
|
r_waddrb_rclk_1P <= r_waddrb_1P;
|
|
end
|
|
end
|
|
|
|
always@(posedge i_arst or posedge i_rclk)
|
|
begin
|
|
if (i_arst) begin
|
|
r_waddrb_rclk_neg <= {ADDR_WIDTH+1{1'b0}};
|
|
end
|
|
else begin
|
|
r_waddrb_rclk_neg <= ~r_waddrb_rclk_1P;
|
|
end
|
|
end
|
|
|
|
always@(posedge i_arst or posedge i_rclk)
|
|
begin
|
|
if (i_arst) begin
|
|
rd_cnt <= {ADDR_WIDTH+1{1'b0}};
|
|
end
|
|
else begin
|
|
rd_cnt <= r_raddrb_1P + r_waddrb_rclk_neg;
|
|
end
|
|
end
|
|
|
|
always@(posedge i_arst or posedge i_wclk)
|
|
begin
|
|
if (i_arst)
|
|
begin
|
|
r_we_1P <= 1'b0;
|
|
r_waddrb_1P <= {ADDR_WIDTH{1'b0}};
|
|
r_wflag_1P <= 1'b0;
|
|
r_waddrg_1P <= {ADDR_WIDTH{1'b0}};
|
|
r_waddrg_2P <= {ADDR_WIDTH{1'b0}};
|
|
|
|
r_full[0] <= 1'b0;
|
|
end
|
|
else
|
|
begin
|
|
r_we_1P <= 1'b0;
|
|
|
|
if (CHECK_FULL == "TRUE")
|
|
begin
|
|
if (i_we & ~w_full_P)
|
|
begin
|
|
r_we_1P <= 1'b1;
|
|
r_waddrb_1P <= w_waddrb_1P;
|
|
r_wflag_1P <= w_wflag_1P;
|
|
r_waddrg_1P <= w_waddrg_1P;
|
|
end
|
|
end
|
|
else
|
|
begin
|
|
if (i_we)
|
|
begin
|
|
r_we_1P <= 1'b1;
|
|
r_waddrb_1P <= w_waddrb_1P;
|
|
r_wflag_1P <= w_wflag_1P;
|
|
r_waddrg_1P <= w_waddrg_1P;
|
|
end
|
|
end
|
|
|
|
if (r_we_1P)
|
|
r_waddrg_2P <= r_waddrg_1P;
|
|
|
|
r_full[0] <= w_full;
|
|
end
|
|
end
|
|
|
|
assign w_raddrb_1P = r_raddrb_1P + 1'b1;
|
|
assign w_rflag_1P = w_raddrb_1P[ADDR_WIDTH];
|
|
assign w_raddrg_1P[ADDR_WIDTH-1] = w_raddrb_1P[ADDR_WIDTH-1] ^ 1'b0;
|
|
assign w_raddrg_1P[ADDR_WIDTH-2:0] = w_raddrb_1P[ADDR_WIDTH-2:0] ^ w_raddrb_1P[ADDR_WIDTH-1:1];
|
|
|
|
assign w_empty = ((r_waddrg_2P == r_raddrg_1P) &
|
|
(r_wflag_1P == r_rflag_2P))?
|
|
1'b1:
|
|
(i_re &
|
|
((r_waddrg_1P == r_raddrg_1P) &
|
|
(r_wflag_1P == r_rflag_1P)))?
|
|
1'b1:
|
|
1'b0;
|
|
|
|
always@(posedge i_arst or posedge i_rclk)
|
|
begin
|
|
if (i_arst)
|
|
begin
|
|
r_re_1P <= 1'b0;
|
|
r_raddrb_1P <= {ADDR_WIDTH{1'b0}};
|
|
r_rflag_1P <= 1'b0;
|
|
r_raddrg_1P <= {ADDR_WIDTH{1'b0}};
|
|
r_rflag_2P <= 1'b0;
|
|
r_raddrg_2P <= {ADDR_WIDTH{1'b0}};
|
|
|
|
r_empty[0] <= 1'b1;
|
|
end
|
|
else
|
|
begin
|
|
r_re_1P <= 1'b0;
|
|
|
|
if (CHECK_FULL == "TRUE")
|
|
begin
|
|
if (i_re & ~w_empty_P)
|
|
begin
|
|
r_re_1P <= 1'b1;
|
|
r_raddrb_1P <= w_raddrb_1P;
|
|
r_rflag_1P <= w_rflag_1P;
|
|
r_raddrg_1P <= w_raddrg_1P;
|
|
end
|
|
end
|
|
else
|
|
begin
|
|
if (i_re)
|
|
begin
|
|
r_re_1P <= 1'b1;
|
|
r_raddrb_1P <= w_raddrb_1P;
|
|
r_rflag_1P <= w_rflag_1P;
|
|
r_raddrg_1P <= w_raddrg_1P;
|
|
end
|
|
end
|
|
|
|
if (r_re_1P)
|
|
begin
|
|
r_raddrg_2P <= r_raddrg_1P;
|
|
r_rflag_2P <= r_rflag_1P;
|
|
end
|
|
|
|
r_empty[0] <= w_empty;
|
|
end
|
|
end
|
|
|
|
genvar i, j;
|
|
generate
|
|
for (i=1; i<LATENCY; i=i+1)
|
|
begin: pipe_empty
|
|
always@(posedge i_arst or posedge i_rclk)
|
|
begin
|
|
if (i_arst)
|
|
r_empty[i] <= 1'b1;
|
|
else
|
|
r_empty[i] <= r_empty[i-1];
|
|
end
|
|
end
|
|
|
|
assign w_empty_P = w_empty | r_empty[LATENCY-1];
|
|
|
|
for (j=1; j<LATENCY+1; j=j+1)
|
|
begin: pipe_full
|
|
always@(posedge i_arst or posedge i_wclk)
|
|
begin
|
|
if (i_arst)
|
|
r_full[j] <= 1'b0;
|
|
else
|
|
r_full[j] <= r_full[j-1];
|
|
end
|
|
end
|
|
|
|
if (COMPATIBILITY == "X")
|
|
if (FIFO_MODE == "BYPASS")
|
|
assign w_full_P = r_full[0] | r_full[LATENCY-2];
|
|
else
|
|
assign w_full_P = r_full[0] | r_full[LATENCY];
|
|
else
|
|
assign w_full_P = r_full[0] | r_full[LATENCY-1];
|
|
|
|
if (CHECK_FULL == "TRUE")
|
|
assign w_we = i_we & ~w_full_P;
|
|
else
|
|
assign w_we = i_we;
|
|
|
|
if (FIFO_MODE == "BYPASS")
|
|
begin
|
|
assign w_re = 1'b1;
|
|
if (CHECK_EMPTY == "TRUE")
|
|
assign w_raddr = (i_re & ~w_empty_P)?
|
|
w_raddrg_1P[ADDR_WIDTH-1:0]:
|
|
r_raddrg_1P[ADDR_WIDTH-1:0];
|
|
else
|
|
assign w_raddr = (i_re)?
|
|
w_raddrg_1P[ADDR_WIDTH-1:0]:
|
|
r_raddrg_1P[ADDR_WIDTH-1:0];
|
|
end
|
|
else
|
|
begin
|
|
if (CHECK_EMPTY == "TRUE")
|
|
assign w_re = i_re & ~w_empty_P;
|
|
else
|
|
assign w_re = i_re;
|
|
assign w_raddr = r_raddrg_1P[ADDR_WIDTH-1:0];
|
|
end
|
|
|
|
`IP_MODULE_NAME(sdram_simple_dual_port_ram)
|
|
#(
|
|
.DATA_WIDTH(DATA_WIDTH),
|
|
.ADDR_WIDTH(ADDR_WIDTH),
|
|
.OUTPUT_REG(OUTPUT_REG),
|
|
.RAM_INIT_FILE(RAM_INIT_FILE)
|
|
)
|
|
inst_simple_dual_port_ram
|
|
(
|
|
.wdata(i_wdata),
|
|
.waddr(r_waddrg_1P[ADDR_WIDTH-1:0]),
|
|
.raddr(w_raddr),
|
|
.we(w_we),
|
|
.wclk(i_wclk),
|
|
.re(w_re),
|
|
.rclk(i_rclk),
|
|
.rdata(o_rdata)
|
|
);
|
|
endgenerate
|
|
|
|
assign o_empty = w_empty_P;
|
|
assign o_full = w_full_P;
|
|
|
|
assign o_aempty= w_empty_P | (rd_cnt[ADDR_WIDTH-1] & rd_cnt[ADDR_WIDTH-2] & rd_cnt[ADDR_WIDTH-3]);
|
|
assign o_wcnt = wr_cnt[ADDR_WIDTH] ? {ADDR_WIDTH{1'b1}} : wr_cnt[ADDR_WIDTH-1:0];
|
|
assign o_afull = w_full_P | wr_cnt[ADDR_WIDTH] | (wr_cnt[ADDR_WIDTH-1] & wr_cnt[ADDR_WIDTH-2] & wr_cnt[ADDR_WIDTH-3]);
|
|
assign o_rcnt = w_full_P ? {ADDR_WIDTH{1'b0}} : rd_cnt[ADDR_WIDTH-1:0];
|
|
|
|
assign o_dbg_we = w_we;
|
|
assign o_dbg_waddr = r_waddrg_1P[ADDR_WIDTH-1:0];
|
|
assign o_dbg_re = w_re;
|
|
assign o_dbg_raddr = w_raddr;
|
|
|
|
endmodule
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
// Copyright (C) 2013-2019 Efinix Inc. All rights reserved.
|
|
//
|
|
// This document contains proprietary information which is
|
|
// protected by copyright. All rights are reserved. This notice
|
|
// refers to original work by Efinix, Inc. which may be derivitive
|
|
// of other work distributed under license of the authors. In the
|
|
// case of derivative work, nothing in this notice overrides the
|
|
// original author's license agreement. Where applicable, the
|
|
// original license agreement is included in it's original
|
|
// unmodified form immediately below this header.
|
|
//
|
|
// WARRANTY DISCLAIMER.
|
|
// THE DESIGN, CODE, OR INFORMATION ARE PROVIDED “AS IS” AND
|
|
// EFINIX MAKES NO WARRANTIES, EXPRESS OR IMPLIED WITH
|
|
// RESPECT THERETO, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES,
|
|
// INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
|
// MERCHANTABILITY, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR
|
|
// PURPOSE. SOME STATES DO NOT ALLOW EXCLUSIONS OF AN IMPLIED
|
|
// WARRANTY, SO THIS DISCLAIMER MAY NOT APPLY TO LICENSEE.
|
|
//
|
|
// LIMITATION OF LIABILITY.
|
|
// NOTWITHSTANDING ANYTHING TO THE CONTRARY, EXCEPT FOR BODILY
|
|
// INJURY, EFINIX SHALL NOT BE LIABLE WITH RESPECT TO ANY SUBJECT
|
|
// MATTER OF THIS AGREEMENT UNDER TORT, CONTRACT, STRICT LIABILITY
|
|
// OR ANY OTHER LEGAL OR EQUITABLE THEORY (I) FOR ANY INDIRECT,
|
|
// SPECIAL, INCIDENTAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES OF ANY
|
|
// CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF
|
|
// GOODWILL, DATA OR PROFIT, WORK STOPPAGE, OR COMPUTER FAILURE OR
|
|
// MALFUNCTION, OR IN ANY EVENT (II) FOR ANY AMOUNT IN EXCESS, IN
|
|
// THE AGGREGATE, OF THE FEE PAID BY LICENSEE TO EFINIX HEREUNDER
|
|
// (OR, IF THE FEE HAS BEEN WAIVED, $100), EVEN IF EFINIX SHALL HAVE
|
|
// BEEN INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO
|
|
// NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR
|
|
// CONSEQUENTIAL DAMAGES, SO THIS LIMITATION AND EXCLUSION MAY NOT
|
|
// APPLY TO LICENSEE.
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// _____
|
|
// / _______ Copyright (C) 2013-2020 Efinix Inc. All rights reserved.
|
|
// / / \
|
|
// / / .. / `IP_MODULE_NAME(efx_sdram_controller).v
|
|
// / / .' /
|
|
// __/ /.' / Description:
|
|
// __ \ / SDRAM controller top module
|
|
// /_/ /\ \_____/ /
|
|
// ____/ \_______/
|
|
//
|
|
// *******************************
|
|
// Revisions:
|
|
// 1.0 Initial rev
|
|
//
|
|
// *******************************
|
|
|
|
module `IP_MODULE_NAME(efx_sdram_controller)
|
|
(
|
|
i_aresetn,
|
|
i_arst,
|
|
i_sysclk,
|
|
i_sdrclk,
|
|
i_tACclk,
|
|
i_pll_locked,
|
|
o_pll_reset,
|
|
i_we,
|
|
i_re,
|
|
i_last,
|
|
i_addr,
|
|
i_din,
|
|
o_dout,
|
|
o_sdr_init_done,
|
|
o_wr_ack,
|
|
o_rd_ack,
|
|
o_ref_req,
|
|
o_rd_valid,
|
|
o_AXI4_AWREADY,
|
|
i_AXI4_AWADDR,
|
|
i_AXI4_AWPROT,
|
|
i_AXI4_AWVALID,
|
|
o_AXI4_WREADY,
|
|
i_AXI4_WDATA,
|
|
i_AXI4_WLAST,
|
|
i_AXI4_WVALID,
|
|
o_AXI4_BVALID,
|
|
i_AXI4_BREADY,
|
|
o_AXI4_ARREADY,
|
|
i_AXI4_ARADDR,
|
|
i_AXI4_ARPROT,
|
|
i_AXI4_ARVALID,
|
|
i_AXI4_RREADY,
|
|
o_AXI4_RDATA,
|
|
o_AXI4_RLAST,
|
|
o_AXI4_RVALID,
|
|
i_AXI4_AWID,
|
|
i_AXI4_AWREGION,
|
|
i_AXI4_AWLEN,
|
|
i_AXI4_AWSIZE,
|
|
i_AXI4_AWBURST,
|
|
i_AXI4_AWLOCK,
|
|
i_AXI4_AWCACHE,
|
|
i_AXI4_AWQOS,
|
|
i_AXI4_AWUSER,
|
|
i_AXI4_WSTRB,
|
|
i_AXI4_WUSER,
|
|
o_AXI4_BID,
|
|
o_AXI4_BRESP,
|
|
o_AXI4_BUSER,
|
|
i_AXI4_ARID,
|
|
i_AXI4_ARREGION,
|
|
i_AXI4_ARLEN,
|
|
i_AXI4_ARSIZE,
|
|
i_AXI4_ARBURST,
|
|
i_AXI4_ARLOCK,
|
|
i_AXI4_ARCACHE,
|
|
i_AXI4_ARQOS,
|
|
i_AXI4_ARUSER,
|
|
o_AXI4_RID,
|
|
o_AXI4_RRESP,
|
|
o_AXI4_RUSER,
|
|
o_sdr_CKE,
|
|
o_sdr_n_CS,
|
|
o_sdr_n_RAS,
|
|
o_sdr_n_CAS,
|
|
o_sdr_n_WE,
|
|
o_sdr_BA,
|
|
o_sdr_ADDR,
|
|
o_sdr_DATA,
|
|
o_sdr_DATA_oe,
|
|
i_sdr_DATA,
|
|
o_sdr_DQM,
|
|
o_dbg_dly_cnt_b,
|
|
o_dbg_tRCD_done,
|
|
o_dbg_tRTW_done,
|
|
o_dbg_ref_req,
|
|
o_dbg_wr_ack,
|
|
o_dbg_rd_ack,
|
|
o_sdr_state,
|
|
o_dbg_we,
|
|
o_dbg_re,
|
|
o_dbg_last,
|
|
o_dbg_addr,
|
|
o_dbg_din,
|
|
o_sdr_rd_valid,
|
|
o_sdr_dout,
|
|
o_axi4_wrstate,
|
|
o_dbg_axi4_wlast,
|
|
o_axi4_rastate,
|
|
o_axi4_rdstate,
|
|
o_axi4_nwr,
|
|
o_re_lock,
|
|
o_shift_cnt,
|
|
o_axi4_arlen,
|
|
o_fifo_wr,
|
|
o_fifo_full,
|
|
o_fifo_empty,
|
|
o_dbg_fifo_we,
|
|
o_dbg_fifo_waddr,
|
|
o_dbg_fifo_re,
|
|
o_dbg_fifo_raddr,
|
|
o_dbg_n_CS,
|
|
o_dbg_n_RAS,
|
|
o_dbg_n_CAS,
|
|
o_dbg_n_WE,
|
|
o_dbg_BA,
|
|
o_dbg_ADDR,
|
|
o_dbg_DATA_out,
|
|
o_dbg_DATA_in
|
|
);
|
|
|
|
parameter AXI_AWADDR_WIDTH = 32;
|
|
parameter AXI_WDATA_WIDTH = 32;
|
|
parameter AXI_ARADDR_WIDTH = 32;
|
|
parameter AXI_RDATA_WIDTH = 32;
|
|
|
|
parameter fSYS_MHz = 100;
|
|
parameter fCK_MHz = 100;
|
|
parameter DATA_RATE = 1;
|
|
parameter DDIO_TYPE = "SOFT";
|
|
parameter tPWRUP = 100; // 100 us
|
|
parameter tRAS = 44; // 44 ns
|
|
parameter tRAS_MAX = 120; // 120 us
|
|
parameter tRC = 66; // 66 ns
|
|
parameter tRCD = 20; // 20 ns
|
|
parameter tREF = 64; // 64 ms
|
|
parameter tRFC = 66; // 66 ns
|
|
parameter tRP = 20; // 20 ns
|
|
parameter tWR = 2; // 1 CK+7.5 ns
|
|
parameter tMRD = 2; // 2 CK
|
|
parameter CL = 3; // 3 CK
|
|
parameter BL = 1;
|
|
parameter tIORT_u = 2;
|
|
parameter BA_WIDTH = 2;
|
|
parameter ROW_WIDTH = 10;
|
|
parameter COL_WIDTH = 10;
|
|
parameter DQ_WIDTH = 8; // x4; x8
|
|
parameter DQ_GROUP = 8;
|
|
parameter SDRAM_MODE = "AXI4";
|
|
|
|
//----- parameter not configurable by user----
|
|
parameter AXI_AWID_WIDTH = 4;
|
|
parameter AXI_AWUSER_WIDTH = 2;
|
|
parameter AXI_WUSER_WIDTH = 2;
|
|
parameter AXI_BID_WIDTH = 4;
|
|
parameter AXI_BUSER_WIDTH = 2;
|
|
parameter AXI_ARID_WIDTH = 4;
|
|
parameter AXI_ARUSER_WIDTH = 2;
|
|
parameter AXI_RUSER_WIDTH = 2;
|
|
|
|
//Common
|
|
input i_aresetn;
|
|
input i_arst;
|
|
input i_sysclk;
|
|
input i_sdrclk;
|
|
input i_tACclk;
|
|
input i_pll_locked;
|
|
output o_pll_reset;
|
|
|
|
//Native
|
|
input i_we;
|
|
input i_re;
|
|
input i_last;
|
|
input [(BA_WIDTH+ROW_WIDTH+COL_WIDTH) -1:0] i_addr;
|
|
input [DATA_RATE *DQ_GROUP *DQ_WIDTH -1:0] i_din;
|
|
output [DATA_RATE *DQ_GROUP *DQ_WIDTH -1:0] o_dout;
|
|
output o_sdr_init_done;
|
|
output o_wr_ack;
|
|
output o_rd_ack;
|
|
output o_ref_req;
|
|
output o_rd_valid;
|
|
|
|
//AXI4
|
|
output wire o_AXI4_AWREADY;
|
|
input [AXI_AWADDR_WIDTH-1:0] i_AXI4_AWADDR;
|
|
input [2:0] i_AXI4_AWPROT;
|
|
input i_AXI4_AWVALID;
|
|
|
|
output o_AXI4_WREADY;
|
|
input [AXI_WDATA_WIDTH-1:0] i_AXI4_WDATA;
|
|
input i_AXI4_WLAST;
|
|
input i_AXI4_WVALID;
|
|
|
|
output o_AXI4_BVALID;
|
|
input i_AXI4_BREADY;
|
|
|
|
output o_AXI4_ARREADY;
|
|
input [AXI_ARADDR_WIDTH-1:0] i_AXI4_ARADDR;
|
|
input [2:0] i_AXI4_ARPROT;
|
|
input i_AXI4_ARVALID;
|
|
|
|
input i_AXI4_RREADY;
|
|
output [AXI_RDATA_WIDTH-1:0] o_AXI4_RDATA;
|
|
output o_AXI4_RLAST;
|
|
output o_AXI4_RVALID;
|
|
|
|
input [AXI_AWID_WIDTH-1:0] i_AXI4_AWID;
|
|
input [3:0] i_AXI4_AWREGION;
|
|
input [7:0] i_AXI4_AWLEN;
|
|
input [2:0] i_AXI4_AWSIZE;
|
|
input [1:0] i_AXI4_AWBURST;
|
|
input i_AXI4_AWLOCK;
|
|
input [3:0] i_AXI4_AWCACHE;
|
|
input [3:0] i_AXI4_AWQOS;
|
|
input [AXI_AWUSER_WIDTH-1:0] i_AXI4_AWUSER;
|
|
input [AXI_WDATA_WIDTH/8-1:0] i_AXI4_WSTRB;
|
|
input [AXI_WUSER_WIDTH-1:0] i_AXI4_WUSER;
|
|
|
|
output [AXI_BID_WIDTH-1:0] o_AXI4_BID;
|
|
output [1:0] o_AXI4_BRESP;
|
|
output [AXI_BUSER_WIDTH-1:0] o_AXI4_BUSER;
|
|
|
|
input [AXI_ARID_WIDTH-1:0] i_AXI4_ARID;
|
|
input [3:0] i_AXI4_ARREGION;
|
|
input [7:0] i_AXI4_ARLEN;
|
|
input [2:0] i_AXI4_ARSIZE;
|
|
input [1:0] i_AXI4_ARBURST;
|
|
input i_AXI4_ARLOCK;
|
|
input [3:0] i_AXI4_ARCACHE;
|
|
input [3:0] i_AXI4_ARQOS;
|
|
input [AXI_ARUSER_WIDTH-1:0] i_AXI4_ARUSER;
|
|
|
|
output [AXI_ARID_WIDTH-1:0] o_AXI4_RID;
|
|
output [1:0] o_AXI4_RRESP;
|
|
output [AXI_RUSER_WIDTH-1:0] o_AXI4_RUSER;
|
|
|
|
output [DATA_RATE -1:0] o_sdr_CKE;
|
|
output [DATA_RATE -1:0] o_sdr_n_CS;
|
|
output [DATA_RATE -1:0] o_sdr_n_RAS;
|
|
output [DATA_RATE -1:0] o_sdr_n_CAS;
|
|
output [DATA_RATE -1:0] o_sdr_n_WE;
|
|
output [DATA_RATE *BA_WIDTH -1:0] o_sdr_BA;
|
|
output [DATA_RATE *ROW_WIDTH -1:0] o_sdr_ADDR;
|
|
output [DATA_RATE *DQ_GROUP *DQ_WIDTH -1:0] o_sdr_DATA;
|
|
output [DATA_RATE *DQ_GROUP *DQ_WIDTH -1:0] o_sdr_DATA_oe;
|
|
input [DATA_RATE *DQ_GROUP *DQ_WIDTH -1:0] i_sdr_DATA;
|
|
output [DATA_RATE *DQ_GROUP -1:0] o_sdr_DQM;
|
|
|
|
// Debug port
|
|
output [5:0] o_dbg_dly_cnt_b;
|
|
output o_dbg_tRCD_done;
|
|
output o_dbg_tRTW_done;
|
|
output o_dbg_ref_req;
|
|
output o_dbg_wr_ack;
|
|
output o_dbg_rd_ack;
|
|
output [3:0] o_sdr_state;
|
|
output o_dbg_we;
|
|
output o_dbg_re;
|
|
output o_dbg_last;
|
|
output [BA_WIDTH+ROW_WIDTH+COL_WIDTH-1:0] o_dbg_addr;
|
|
output [AXI_WDATA_WIDTH-1:0] o_dbg_din;
|
|
output o_sdr_rd_valid;
|
|
output [DATA_RATE*DQ_GROUP*DQ_WIDTH+AXI_ARID_WIDTH:0] o_sdr_dout;
|
|
output [1:0] o_axi4_wrstate;
|
|
output o_dbg_axi4_wlast;
|
|
output [1:0] o_axi4_rastate;
|
|
output [1:0] o_axi4_rdstate;
|
|
output o_axi4_nwr;
|
|
output o_re_lock;
|
|
output [6:0] o_shift_cnt;
|
|
output [7:0] o_axi4_arlen;
|
|
output o_fifo_wr;
|
|
output o_fifo_full;
|
|
output o_fifo_empty;
|
|
output o_dbg_fifo_we;
|
|
output [7:0] o_dbg_fifo_waddr;
|
|
output o_dbg_fifo_re;
|
|
output [7:0] o_dbg_fifo_raddr;
|
|
|
|
output [DATA_RATE -1:0] o_dbg_n_CS;
|
|
output [DATA_RATE -1:0] o_dbg_n_RAS;
|
|
output [DATA_RATE -1:0] o_dbg_n_CAS;
|
|
output [DATA_RATE -1:0] o_dbg_n_WE;
|
|
output [DATA_RATE *BA_WIDTH -1:0] o_dbg_BA;
|
|
output [DATA_RATE *ROW_WIDTH -1:0] o_dbg_ADDR;
|
|
output [DATA_RATE *DQ_GROUP *DQ_WIDTH -1:0] o_dbg_DATA_out;
|
|
output [DATA_RATE *DQ_GROUP *DQ_WIDTH -1:0] o_dbg_DATA_in;
|
|
|
|
generate
|
|
if (SDRAM_MODE == "AXI4") begin
|
|
`IP_MODULE_NAME(axi4_sdram_controller)
|
|
#(
|
|
.AXI_AWADDR_WIDTH (AXI_AWADDR_WIDTH),
|
|
.AXI_WDATA_WIDTH (AXI_WDATA_WIDTH),
|
|
.AXI_ARADDR_WIDTH (AXI_ARADDR_WIDTH),
|
|
.AXI_RDATA_WIDTH (AXI_RDATA_WIDTH),
|
|
.fSYS_MHz (fSYS_MHz),
|
|
.fCK_MHz (fCK_MHz),
|
|
.DDIO_TYPE (DDIO_TYPE),
|
|
.tPWRUP (tPWRUP),
|
|
.tRAS (tRAS),
|
|
.tRAS_MAX (tRAS_MAX),
|
|
.tRC (tRC),
|
|
.tRCD (tRCD),
|
|
.tREF (tREF),
|
|
.tRFC (tRFC),
|
|
.tRP (tRP),
|
|
.tWR (tWR),
|
|
.tMRD (tMRD),
|
|
.CL (CL),
|
|
.BL (BL),
|
|
.DATA_RATE (DATA_RATE),
|
|
.tIORT_u (tIORT_u),
|
|
.BA_WIDTH (BA_WIDTH),
|
|
.ROW_WIDTH (ROW_WIDTH),
|
|
.COL_WIDTH (COL_WIDTH),
|
|
.DQ_WIDTH (DQ_WIDTH),
|
|
.DQ_GROUP (DQ_GROUP),
|
|
.AXI_AWID_WIDTH (AXI_AWID_WIDTH ),
|
|
.AXI_AWUSER_WIDTH (AXI_AWUSER_WIDTH ),
|
|
.AXI_WUSER_WIDTH (AXI_WUSER_WIDTH ),
|
|
.AXI_BID_WIDTH (AXI_BID_WIDTH ),
|
|
.AXI_BUSER_WIDTH (AXI_BUSER_WIDTH ),
|
|
.AXI_ARID_WIDTH (AXI_ARID_WIDTH ),
|
|
.AXI_ARUSER_WIDTH (AXI_ARUSER_WIDTH ),
|
|
.AXI_RUSER_WIDTH (AXI_RUSER_WIDTH )
|
|
)
|
|
inst_axi4_sdram_controller
|
|
(
|
|
.i_aresetn (i_aresetn),
|
|
.i_sysclk (i_sysclk),
|
|
.i_sdrclk (i_sdrclk),
|
|
.i_tACclk (i_tACclk),
|
|
.i_pll_locked (i_pll_locked),
|
|
|
|
.o_AXI4_AWREADY (o_AXI4_AWREADY),
|
|
.i_AXI4_AWADDR (i_AXI4_AWADDR),
|
|
.i_AXI4_AWPROT (i_AXI4_AWPROT),
|
|
.i_AXI4_AWVALID (i_AXI4_AWVALID),
|
|
|
|
.o_AXI4_WREADY (o_AXI4_WREADY),
|
|
.i_AXI4_WDATA (i_AXI4_WDATA),
|
|
.i_AXI4_WLAST (i_AXI4_WLAST),
|
|
.i_AXI4_WVALID (i_AXI4_WVALID),
|
|
|
|
.o_AXI4_BVALID (o_AXI4_BVALID),
|
|
.i_AXI4_BREADY (i_AXI4_BREADY),
|
|
|
|
.o_AXI4_ARREADY (o_AXI4_ARREADY),
|
|
.i_AXI4_ARADDR (i_AXI4_ARADDR),
|
|
.i_AXI4_ARPROT (i_AXI4_ARPROT),
|
|
.i_AXI4_ARVALID (i_AXI4_ARVALID),
|
|
|
|
.i_AXI4_RREADY (i_AXI4_RREADY),
|
|
.o_AXI4_RDATA (o_AXI4_RDATA),
|
|
.o_AXI4_RLAST (o_AXI4_RLAST),
|
|
.o_AXI4_RVALID (o_AXI4_RVALID),
|
|
|
|
.i_AXI4_AWID (i_AXI4_AWID),
|
|
.i_AXI4_AWREGION (i_AXI4_AWREGION),
|
|
.i_AXI4_AWLEN (i_AXI4_AWLEN),
|
|
.i_AXI4_AWSIZE (i_AXI4_AWSIZE),
|
|
.i_AXI4_AWBURST (i_AXI4_AWBURST),
|
|
.i_AXI4_AWLOCK (i_AXI4_AWLOCK),
|
|
.i_AXI4_AWCACHE (i_AXI4_AWCACHE),
|
|
.i_AXI4_AWQOS (i_AXI4_AWQOS),
|
|
.i_AXI4_AWUSER (i_AXI4_AWUSER),
|
|
|
|
.i_AXI4_WSTRB (i_AXI4_WSTRB),
|
|
.i_AXI4_WUSER (i_AXI4_WUSER),
|
|
|
|
.o_AXI4_BID (o_AXI4_BID),
|
|
.o_AXI4_BRESP (o_AXI4_BRESP),
|
|
.o_AXI4_BUSER (o_AXI4_BUSER),
|
|
|
|
.i_AXI4_ARID (i_AXI4_ARID),
|
|
.i_AXI4_ARREGION (i_AXI4_ARREGION),
|
|
.i_AXI4_ARLEN (i_AXI4_ARLEN),
|
|
.i_AXI4_ARSIZE (i_AXI4_ARSIZE),
|
|
.i_AXI4_ARBURST (i_AXI4_ARBURST),
|
|
.i_AXI4_ARLOCK (i_AXI4_ARLOCK),
|
|
.i_AXI4_ARCACHE (i_AXI4_ARCACHE),
|
|
.i_AXI4_ARQOS (i_AXI4_ARQOS),
|
|
.i_AXI4_ARUSER (i_AXI4_ARUSER),
|
|
|
|
.o_AXI4_RID (o_AXI4_RID),
|
|
.o_AXI4_RRESP (o_AXI4_RRESP),
|
|
.o_AXI4_RUSER (o_AXI4_RUSER),
|
|
|
|
.o_sdr_CKE (o_sdr_CKE),
|
|
.o_sdr_n_CS (o_sdr_n_CS),
|
|
.o_sdr_n_RAS (o_sdr_n_RAS),
|
|
.o_sdr_n_CAS (o_sdr_n_CAS),
|
|
.o_sdr_n_WE (o_sdr_n_WE),
|
|
.o_sdr_BA (o_sdr_BA),
|
|
.o_sdr_ADDR (o_sdr_ADDR),
|
|
.o_sdr_DATA (o_sdr_DATA),
|
|
.o_sdr_DATA_oe (o_sdr_DATA_oe),
|
|
.i_sdr_DATA (i_sdr_DATA),
|
|
.o_sdr_DQM (o_sdr_DQM),
|
|
|
|
.o_sdr_state (o_sdr_state),
|
|
.o_dbg_we (o_dbg_we),
|
|
.o_dbg_re (o_dbg_re),
|
|
.o_dbg_last (o_dbg_last),
|
|
.o_dbg_addr (o_dbg_addr),
|
|
.o_dbg_din (o_dbg_din),
|
|
.o_dbg_wr_ack (o_dbg_wr_ack),
|
|
.o_dbg_rd_ack (o_dbg_rd_ack),
|
|
.o_sdr_rd_valid (o_sdr_rd_valid),
|
|
.o_dbg_ref_req (o_dbg_ref_req),
|
|
.o_sdr_dout (o_sdr_dout),
|
|
.o_axi4_wrstate (o_axi4_wrstate),
|
|
.o_dbg_axi4_wlast (o_dbg_axi4_wlast),
|
|
.o_axi4_rastate (o_axi4_rastate),
|
|
.o_axi4_rdstate (o_axi4_rdstate),
|
|
.o_axi4_nwr (o_axi4_nwr),
|
|
.o_re_lock (o_re_lock),
|
|
.o_shift_cnt (o_shift_cnt),
|
|
.o_axi4_arlen (o_axi4_arlen),
|
|
.o_fifo_wr (o_fifo_wr),
|
|
.o_fifo_full (o_fifo_full),
|
|
.o_fifo_empty (o_fifo_empty),
|
|
.o_dbg_fifo_we (o_dbg_fifo_we),
|
|
.o_dbg_fifo_waddr (o_dbg_fifo_waddr),
|
|
.o_dbg_fifo_re (o_dbg_fifo_re),
|
|
.o_dbg_fifo_raddr (o_dbg_fifo_raddr),
|
|
|
|
.o_dbg_n_CS (o_dbg_n_CS),
|
|
.o_dbg_n_RAS (o_dbg_n_RAS),
|
|
.o_dbg_n_CAS (o_dbg_n_CAS),
|
|
.o_dbg_n_WE (o_dbg_n_WE),
|
|
.o_dbg_BA (o_dbg_BA),
|
|
.o_dbg_ADDR (o_dbg_ADDR),
|
|
.o_dbg_DATA_out (o_dbg_DATA_out),
|
|
.o_dbg_DATA_in (o_dbg_DATA_in)
|
|
);
|
|
end
|
|
else begin
|
|
`IP_MODULE_NAME(sdram_controller)
|
|
#(
|
|
.fSYS_MHz (fSYS_MHz),
|
|
.fCK_MHz (fCK_MHz),
|
|
.REF_LATENCY (2),
|
|
.tIORT_u (tIORT_u),
|
|
.DDIO_TYPE (DDIO_TYPE),
|
|
.tPWRUP (tPWRUP),
|
|
.tRAS (tRAS),
|
|
.tRAS_MAX (tRAS_MAX),
|
|
.tRC (tRC),
|
|
.tRCD (tRCD),
|
|
.tREF (tREF),
|
|
.tRFC (tRFC),
|
|
.tRP (tRP),
|
|
.tWR (tWR),
|
|
.tMRD (tMRD),
|
|
.CL (CL),
|
|
.BL (BL),
|
|
.BA_WIDTH (BA_WIDTH),
|
|
.ROW_WIDTH (ROW_WIDTH),
|
|
.COL_WIDTH (COL_WIDTH),
|
|
.DATA_RATE (DATA_RATE),
|
|
.DQ_WIDTH (DQ_WIDTH),
|
|
.DQ_GROUP (DQ_GROUP)
|
|
)
|
|
inst_sdram_controller
|
|
(
|
|
.i_arst (i_arst),
|
|
.i_sysclk (i_sysclk),
|
|
.i_sdrclk (i_sdrclk),
|
|
.i_tACclk (i_tACclk),
|
|
.i_pll_locked (i_pll_locked),
|
|
|
|
.i_we (i_we),
|
|
.i_re (i_re),
|
|
.i_last (i_last),
|
|
.i_addr (i_addr),
|
|
.i_din (i_din),
|
|
.o_dout (o_dout),
|
|
.o_sdr_state (o_sdr_state),
|
|
.o_sdr_init_done (o_sdr_init_done),
|
|
.o_wr_ack (o_wr_ack),
|
|
.o_rd_ack (o_rd_ack),
|
|
.o_ref_req (o_ref_req),
|
|
.o_rd_valid (o_rd_valid),
|
|
|
|
.o_sdr_CKE (o_sdr_CKE),
|
|
.o_sdr_n_CS (o_sdr_n_CS),
|
|
.o_sdr_n_RAS (o_sdr_n_RAS),
|
|
.o_sdr_n_CAS (o_sdr_n_CAS),
|
|
.o_sdr_n_WE (o_sdr_n_WE),
|
|
.o_sdr_BA (o_sdr_BA),
|
|
.o_sdr_ADDR (o_sdr_ADDR),
|
|
.o_sdr_DATA (o_sdr_DATA),
|
|
.o_sdr_DATA_oe (o_sdr_DATA_oe),
|
|
.i_sdr_DATA (i_sdr_DATA),
|
|
.o_sdr_DQM (o_sdr_DQM),
|
|
|
|
.o_dbg_dly_cnt_b (o_dbg_dly_cnt_b),
|
|
.o_dbg_tRCD_done (o_dbg_tRCD_done),
|
|
.o_dbg_tRTW_done (o_dbg_tRTW_done),
|
|
.o_dbg_ref_req (o_dbg_ref_req),
|
|
.o_dbg_wr_ack (o_dbg_wr_ack),
|
|
.o_dbg_rd_ack (o_dbg_rd_ack),
|
|
.o_dbg_n_CS (o_dbg_n_CS),
|
|
.o_dbg_n_RAS (o_dbg_n_RAS),
|
|
.o_dbg_n_CAS (o_dbg_n_CAS),
|
|
.o_dbg_n_WE (o_dbg_n_WE),
|
|
.o_dbg_BA (o_dbg_BA),
|
|
.o_dbg_ADDR (o_dbg_ADDR),
|
|
.o_dbg_DATA_out (o_dbg_DATA_out),
|
|
.o_dbg_DATA_in (o_dbg_DATA_in)
|
|
);
|
|
end
|
|
endgenerate
|
|
|
|
endmodule
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// _____
|
|
// / _______ Copyright (C) 2013-2020 Efinix Inc. All rights reserved.
|
|
// / / \
|
|
// / / .. / `IP_MODULE_NAME(sdram_controller).v
|
|
// / / .' /
|
|
// __/ /.' / Description:
|
|
// __ \ / sdram controller top with native interface
|
|
// /_/ /\ \_____/ /
|
|
// ____/ \_______/
|
|
//
|
|
// *******************************
|
|
// Revisions:
|
|
//
|
|
// 1.0 Initial rev
|
|
// *******************************
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
module `IP_MODULE_NAME(sdram_controller)
|
|
#(
|
|
parameter fSYS_MHz = 100,
|
|
parameter fCK_MHz = 100,
|
|
parameter REF_LATENCY = 2, // 2 for Native interface, 4 for AXI interface
|
|
parameter DDIO_TYPE = "SOFT", // SOFT, RTL
|
|
// HARD, Interface Designer
|
|
//sdram parameters
|
|
parameter tPWRUP = 100, // 100 us
|
|
parameter tRAS = 44, // 44 ns
|
|
parameter tRAS_MAX = 120, // 120 us
|
|
parameter tRC = 66, // 66 ns
|
|
parameter tRCD = 20, // 20 ns
|
|
parameter tREF = 64, // 64 ms
|
|
parameter tRFC = 66, // 66 ns
|
|
parameter tRP = 20, // 20 ns
|
|
parameter tWR = 2, // 1 CK+7.5 ns
|
|
parameter tMRD = 2, // 2 CK
|
|
parameter CL = 3, // 3 CK
|
|
parameter BL = 1,
|
|
parameter BA_WIDTH = 2,
|
|
parameter ROW_WIDTH = 13,
|
|
parameter COL_WIDTH = 10,
|
|
parameter DATA_RATE = 1, // 1, 2
|
|
parameter tIORT_u = 2,
|
|
parameter DQ_WIDTH = 8, // x4, x8
|
|
parameter DQ_GROUP = 8
|
|
// x4 x8 x16 x32
|
|
// DQ_WIDTH 4 8 8 8
|
|
// DQ_GROUP 1 1 2 4
|
|
)
|
|
(
|
|
input i_arst,
|
|
input i_sysclk,
|
|
input i_sdrclk, // x2 i_sysclk
|
|
input i_tACclk, // x2 i_sysclk
|
|
input i_pll_locked,
|
|
|
|
input i_we,
|
|
input i_re,
|
|
input i_last,
|
|
input [ (BA_WIDTH+ROW_WIDTH+COL_WIDTH) -1:0] i_addr,
|
|
input [DATA_RATE *DQ_GROUP *DQ_WIDTH -1:0] i_din,
|
|
output [DATA_RATE *DQ_GROUP *DQ_WIDTH -1:0] o_dout,
|
|
output [3:0]o_sdr_state,
|
|
output o_sdr_init_done,
|
|
output o_wr_ack,
|
|
output o_rd_ack,
|
|
output o_ref_req,
|
|
output o_rd_valid,
|
|
|
|
output [DATA_RATE -1:0] o_sdr_CKE,
|
|
output [DATA_RATE -1:0] o_sdr_n_CS,
|
|
output [DATA_RATE -1:0] o_sdr_n_RAS,
|
|
output [DATA_RATE -1:0] o_sdr_n_CAS,
|
|
output [DATA_RATE -1:0] o_sdr_n_WE,
|
|
output [DATA_RATE *BA_WIDTH -1:0] o_sdr_BA,
|
|
output [DATA_RATE *ROW_WIDTH -1:0] o_sdr_ADDR,
|
|
output [DATA_RATE *DQ_GROUP *DQ_WIDTH -1:0] o_sdr_DATA,
|
|
output [DATA_RATE *DQ_GROUP *DQ_WIDTH -1:0] o_sdr_DATA_oe,
|
|
input [DATA_RATE *DQ_GROUP *DQ_WIDTH -1:0] i_sdr_DATA,
|
|
output [DATA_RATE *DQ_GROUP -1:0] o_sdr_DQM,
|
|
|
|
// Debug port
|
|
output [5:0]o_dbg_dly_cnt_b,
|
|
output o_dbg_tRCD_done,
|
|
output o_dbg_tRTW_done,
|
|
output o_dbg_ref_req,
|
|
output o_dbg_wr_ack,
|
|
output o_dbg_rd_ack,
|
|
output [DATA_RATE -1:0] o_dbg_n_CS,
|
|
output [DATA_RATE -1:0] o_dbg_n_RAS,
|
|
output [DATA_RATE -1:0] o_dbg_n_CAS,
|
|
output [DATA_RATE -1:0] o_dbg_n_WE,
|
|
output [DATA_RATE *BA_WIDTH -1:0] o_dbg_BA,
|
|
output [DATA_RATE *ROW_WIDTH -1:0] o_dbg_ADDR,
|
|
output [DATA_RATE *DQ_GROUP *DQ_WIDTH -1:0] o_dbg_DATA_out,
|
|
output [DATA_RATE *DQ_GROUP *DQ_WIDTH -1:0] o_dbg_DATA_in
|
|
);
|
|
`ifdef RTL_SIM
|
|
localparam tIORT = (DATA_RATE == 2 && CL == 2) ? 1 : 0;
|
|
`else
|
|
localparam tIORT = tIORT_u;
|
|
`endif
|
|
localparam PARTIAL_FEATURES = (fCK_MHz == 166 && fSYS_MHz == 166) ? 1 : 0; //partial features only applicable to 166Mhz fullrate
|
|
localparam DLY_CNT_A_WIDTH = (PARTIAL_FEATURES == 1) ? 4 : 6;
|
|
localparam DLY_CNT_B_WIDTH = (PARTIAL_FEATURES == 1) ? 4 : 6;
|
|
localparam CHECK_ACT_BA = (PARTIAL_FEATURES == 1) ? 1 : 4;
|
|
localparam BA_MSB = BA_WIDTH+ ROW_WIDTH+ COL_WIDTH- 1;
|
|
localparam BA_LSB = ROW_WIDTH+ COL_WIDTH;
|
|
localparam ROW_MSB = ROW_WIDTH+ COL_WIDTH- 1;
|
|
localparam ROW_LSB = COL_WIDTH;
|
|
localparam COL_MSB = COL_WIDTH- 1;
|
|
localparam COL_LSB = 0;
|
|
|
|
localparam CYC_A = 0;
|
|
localparam CYC_B = 1;
|
|
localparam CYC_C = 2;
|
|
localparam CYC_D = 3;
|
|
|
|
wire [DATA_RATE -1:0]w_sdr_CKE;
|
|
wire [DATA_RATE -1:0]w_sdr_n_CS;
|
|
wire [DATA_RATE -1:0]w_sdr_n_RAS;
|
|
wire [DATA_RATE -1:0]w_sdr_n_CAS;
|
|
wire [DATA_RATE -1:0]w_sdr_n_WE;
|
|
wire [DATA_RATE *BA_WIDTH -1:0]w_sdr_BA;
|
|
wire [DATA_RATE *ROW_WIDTH -1:0]w_sdr_ADDR;
|
|
wire [DATA_RATE *DQ_GROUP *DQ_WIDTH -1:0]w_sdr_DATA_out;
|
|
wire [DATA_RATE *DQ_GROUP *DQ_WIDTH -1:0]w_sdr_DATA_oe;
|
|
wire [DATA_RATE *DQ_GROUP *DQ_WIDTH -1:0]w_sdr_DATA_in;
|
|
wire [DATA_RATE *DQ_GROUP -1:0]w_sdr_DQM;
|
|
|
|
`IP_MODULE_NAME(sdram_fsm)
|
|
#(
|
|
.fSYS_MHz (fSYS_MHz),
|
|
.fCK_MHz (fCK_MHz),
|
|
.DLY_CNT_A_WIDTH (DLY_CNT_A_WIDTH),
|
|
.DLY_CNT_B_WIDTH (DLY_CNT_B_WIDTH),
|
|
.CHECK_ACT_BA (CHECK_ACT_BA),
|
|
.REF_LATENCY (REF_LATENCY),
|
|
.DATA_RATE (DATA_RATE),
|
|
.tPWRUP (tPWRUP),
|
|
.tRAS (tRAS),
|
|
.tRAS_MAX (tRAS_MAX),
|
|
.tRC (tRC),
|
|
.tRCD (tRCD),
|
|
.tREF (tREF),
|
|
.tRFC (tRFC),
|
|
.tRP (tRP),
|
|
.tWR (tWR),
|
|
.tMRD (tMRD),
|
|
.CL (CL),
|
|
.BL (BL),
|
|
.tIORT (tIORT),
|
|
.DDIO_TYPE (DDIO_TYPE),
|
|
.BA_WIDTH (BA_WIDTH),
|
|
.ROW_WIDTH (ROW_WIDTH),
|
|
.COL_WIDTH (COL_WIDTH),
|
|
.DQ_WIDTH (DQ_WIDTH),
|
|
.DQ_GROUP (DQ_GROUP)
|
|
)
|
|
inst_sdram_fsm
|
|
(
|
|
.i_arst (i_arst),
|
|
.i_sysclk (i_sysclk),
|
|
.i_pll_locked (i_pll_locked),
|
|
|
|
.i_we (i_we),
|
|
.i_re (i_re),
|
|
.i_last (i_last),
|
|
.i_addr (i_addr),
|
|
.i_din (i_din),
|
|
.o_dout (o_dout),
|
|
.o_sdr_state (o_sdr_state),
|
|
.o_sdr_init_done (o_sdr_init_done),
|
|
.o_wr_ack (o_wr_ack),
|
|
.o_rd_ack (o_rd_ack),
|
|
.o_ref_req (o_ref_req),
|
|
.o_rd_valid (o_rd_valid),
|
|
|
|
.o_sdr_CKE (w_sdr_CKE),
|
|
.o_sdr_n_CS (w_sdr_n_CS),
|
|
.o_sdr_n_RAS (w_sdr_n_RAS),
|
|
.o_sdr_n_CAS (w_sdr_n_CAS),
|
|
.o_sdr_n_WE (w_sdr_n_WE),
|
|
.o_sdr_BA (w_sdr_BA),
|
|
.o_sdr_ADDR (w_sdr_ADDR),
|
|
.o_sdr_DATA (w_sdr_DATA_out),
|
|
.o_sdr_DATA_oe (w_sdr_DATA_oe),
|
|
.i_sdr_DATA (w_sdr_DATA_in),
|
|
.o_sdr_DQM (w_sdr_DQM),
|
|
|
|
.o_dbg_dly_cnt_b (o_dbg_dly_cnt_b),
|
|
.o_dbg_tRCD_done (o_dbg_tRCD_done),
|
|
.o_dbg_tRTW_done (o_dbg_tRTW_done),
|
|
.o_dbg_ref_req (o_dbg_ref_req),
|
|
.o_dbg_wr_ack (o_dbg_wr_ack),
|
|
.o_dbg_rd_ack (o_dbg_rd_ack),
|
|
.o_dbg_n_CS (o_dbg_n_CS),
|
|
.o_dbg_n_RAS (o_dbg_n_RAS),
|
|
.o_dbg_n_CAS (o_dbg_n_CAS),
|
|
.o_dbg_n_WE (o_dbg_n_WE),
|
|
.o_dbg_BA (o_dbg_BA),
|
|
.o_dbg_ADDR (o_dbg_ADDR)
|
|
);
|
|
|
|
generate if (DDIO_TYPE == "SOFT" && DATA_RATE > 1) begin
|
|
`IP_MODULE_NAME(sdram_io_block)
|
|
#(
|
|
.DATA_RATE (DATA_RATE),
|
|
.BA_WIDTH (BA_WIDTH),
|
|
.ROW_WIDTH (ROW_WIDTH),
|
|
.COL_WIDTH (COL_WIDTH),
|
|
.DQ_WIDTH (DQ_WIDTH),
|
|
.DQ_GROUP (DQ_GROUP)
|
|
)
|
|
inst_sdram_io_block
|
|
(
|
|
.i_arst (i_arst),
|
|
.i_sysclk (i_sysclk),
|
|
.i_sdrclk (i_sdrclk),
|
|
.i_tACclk (i_tACclk),
|
|
.i_pll_locked (i_pll_locked),
|
|
|
|
.i_sdr_CKE_core (w_sdr_CKE),
|
|
.i_sdr_n_CS_core (w_sdr_n_CS),
|
|
.i_sdr_n_RAS_core (w_sdr_n_RAS),
|
|
.i_sdr_n_CAS_core (w_sdr_n_CAS),
|
|
.i_sdr_n_WE_core (w_sdr_n_WE),
|
|
.i_sdr_BA_core (w_sdr_BA),
|
|
.i_sdr_ADDR_core (w_sdr_ADDR),
|
|
.i_sdr_DATA_core (w_sdr_DATA_out),
|
|
.i_sdr_DATA_oe_core (w_sdr_DATA_oe),
|
|
.o_sdr_DATA_core (w_sdr_DATA_in),
|
|
.i_sdr_DQM_core (w_sdr_DQM),
|
|
|
|
.o_sdr_CKE_pad (o_sdr_CKE),
|
|
.o_sdr_n_CS_pad (o_sdr_n_CS),
|
|
.o_sdr_n_RAS_pad (o_sdr_n_RAS),
|
|
.o_sdr_n_CAS_pad (o_sdr_n_CAS),
|
|
.o_sdr_n_WE_pad (o_sdr_n_WE),
|
|
.o_sdr_BA_pad (o_sdr_BA),
|
|
.o_sdr_ADDR_pad (o_sdr_ADDR),
|
|
.o_sdr_DATA_pad (o_sdr_DATA),
|
|
.o_sdr_DATA_oe_pad (o_sdr_DATA_oe),
|
|
.i_sdr_DATA_pad (i_sdr_DATA),
|
|
.o_sdr_DQM_pad (o_sdr_DQM)
|
|
);
|
|
end
|
|
else begin
|
|
reg [DATA_RATE *DQ_GROUP *DQ_WIDTH -1:0]r_sdr_DATA_in_tACclk_1P;
|
|
|
|
always@(posedge i_arst or posedge i_tACclk)
|
|
begin
|
|
if (i_arst)
|
|
r_sdr_DATA_in_tACclk_1P <= {DATA_RATE*DQ_GROUP*DQ_WIDTH{1'b0}};
|
|
else
|
|
r_sdr_DATA_in_tACclk_1P <= i_sdr_DATA;
|
|
end
|
|
|
|
assign w_sdr_DATA_in = r_sdr_DATA_in_tACclk_1P;
|
|
assign o_sdr_CKE = w_sdr_CKE;
|
|
assign o_sdr_n_CS = w_sdr_n_CS;
|
|
assign o_sdr_n_RAS = w_sdr_n_RAS;
|
|
assign o_sdr_n_CAS = w_sdr_n_CAS;
|
|
assign o_sdr_n_WE = w_sdr_n_WE;
|
|
assign o_sdr_BA = w_sdr_BA;
|
|
assign o_sdr_ADDR = w_sdr_ADDR;
|
|
assign o_sdr_DATA = w_sdr_DATA_out;
|
|
assign o_sdr_DATA_oe = w_sdr_DATA_oe;
|
|
assign o_sdr_DQM = w_sdr_DQM;
|
|
end
|
|
endgenerate
|
|
|
|
assign o_dbg_DATA_out = w_sdr_DATA_out;
|
|
assign o_dbg_DATA_in = w_sdr_DATA_in;
|
|
|
|
endmodule
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
// Copyright (C) 2013-2019 Efinix Inc. All rights reserved.
|
|
//
|
|
// This document contains proprietary information which is
|
|
// protected by copyright. All rights are reserved. This notice
|
|
// refers to original work by Efinix, Inc. which may be derivitive
|
|
// of other work distributed under license of the authors. In the
|
|
// case of derivative work, nothing in this notice overrides the
|
|
// original author's license agreement. Where applicable, the
|
|
// original license agreement is included in it's original
|
|
// unmodified form immediately below this header.
|
|
//
|
|
// WARRANTY DISCLAIMER.
|
|
// THE DESIGN, CODE, OR INFORMATION ARE PROVIDED “AS IS” AND
|
|
// EFINIX MAKES NO WARRANTIES, EXPRESS OR IMPLIED WITH
|
|
// RESPECT THERETO, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES,
|
|
// INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
|
// MERCHANTABILITY, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR
|
|
// PURPOSE. SOME STATES DO NOT ALLOW EXCLUSIONS OF AN IMPLIED
|
|
// WARRANTY, SO THIS DISCLAIMER MAY NOT APPLY TO LICENSEE.
|
|
//
|
|
// LIMITATION OF LIABILITY.
|
|
// NOTWITHSTANDING ANYTHING TO THE CONTRARY, EXCEPT FOR BODILY
|
|
// INJURY, EFINIX SHALL NOT BE LIABLE WITH RESPECT TO ANY SUBJECT
|
|
// MATTER OF THIS AGREEMENT UNDER TORT, CONTRACT, STRICT LIABILITY
|
|
// OR ANY OTHER LEGAL OR EQUITABLE THEORY (I) FOR ANY INDIRECT,
|
|
// SPECIAL, INCIDENTAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES OF ANY
|
|
// CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF
|
|
// GOODWILL, DATA OR PROFIT, WORK STOPPAGE, OR COMPUTER FAILURE OR
|
|
// MALFUNCTION, OR IN ANY EVENT (II) FOR ANY AMOUNT IN EXCESS, IN
|
|
// THE AGGREGATE, OF THE FEE PAID BY LICENSEE TO EFINIX HEREUNDER
|
|
// (OR, IF THE FEE HAS BEEN WAIVED, $100), EVEN IF EFINIX SHALL HAVE
|
|
// BEEN INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO
|
|
// NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR
|
|
// CONSEQUENTIAL DAMAGES, SO THIS LIMITATION AND EXCLUSION MAY NOT
|
|
// APPLY TO LICENSEE.
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// _____
|
|
// / _______ Copyright (C) 2013-2020 Efinix Inc. All rights reserved.
|
|
// / / \
|
|
// / / .. / `IP_MODULE_NAME(sdram_fsm).v
|
|
// / / .' /
|
|
// __/ /.' / Description:
|
|
// __ \ / sdram controller state machine
|
|
// /_/ /\ \_____/ /
|
|
// ____/ \_______/
|
|
//
|
|
// *******************************
|
|
// Revisions:
|
|
// 1.0 Initial rev
|
|
//
|
|
// *******************************
|
|
|
|
module `IP_MODULE_NAME(sdram_fsm)
|
|
#(
|
|
parameter fSYS_MHz = 100,
|
|
parameter fCK_MHz = 200, // MHz
|
|
parameter DLY_CNT_A_WIDTH = 6,
|
|
parameter DLY_CNT_B_WIDTH = 6,
|
|
parameter CHECK_ACT_BA = 4,
|
|
parameter REF_LATENCY = 2, //
|
|
|
|
parameter tPWRUP = 200, // 100 us
|
|
parameter tRAS = 44, // 44 ns
|
|
parameter tRAS_MAX = 120000, // 120 us
|
|
parameter tRC = 66, // 66 ns
|
|
parameter tRCD = 20, // 20 ns
|
|
parameter tREF = 64, // 64 ms
|
|
parameter tRFC = 66, // 66 ns
|
|
parameter tRP = 20, // 20 ns
|
|
parameter tWR = 2, // 1 CK+7.5 ns
|
|
parameter tMRD = 2, // 2 CK
|
|
parameter CL = 3, // 3 CK
|
|
parameter BL = 1,
|
|
parameter tIORT = 2,
|
|
parameter DDIO_TYPE = "SOFT",
|
|
parameter DATA_RATE = 2,
|
|
parameter BA_WIDTH = 2,
|
|
parameter ROW_WIDTH = 13,
|
|
parameter COL_WIDTH = 10,
|
|
parameter DQ_WIDTH = 8, // x4, x8
|
|
parameter DQ_GROUP = 4
|
|
// x4 x8 x16 x32
|
|
// DQ_WIDTH 4 8 8 8
|
|
// DQ_GROUP 1 1 2 4
|
|
)
|
|
(
|
|
input i_arst,
|
|
input i_sysclk,
|
|
input i_pll_locked,
|
|
|
|
input i_we,
|
|
input i_re,
|
|
input i_last,
|
|
input [ (BA_WIDTH+ROW_WIDTH+COL_WIDTH) -1:0] i_addr,
|
|
input [DATA_RATE *DQ_GROUP *DQ_WIDTH -1:0] i_din,
|
|
output [DATA_RATE *DQ_GROUP *DQ_WIDTH -1:0] o_dout,
|
|
output [3:0]o_sdr_state,
|
|
output o_sdr_init_done,
|
|
output o_wr_ack,
|
|
output o_rd_ack,
|
|
output o_ref_req,
|
|
output o_rd_valid,
|
|
|
|
output [DATA_RATE -1:0] o_sdr_CKE,
|
|
output [DATA_RATE -1:0] o_sdr_n_CS,
|
|
output [DATA_RATE -1:0] o_sdr_n_RAS,
|
|
output [DATA_RATE -1:0] o_sdr_n_CAS,
|
|
output [DATA_RATE -1:0] o_sdr_n_WE,
|
|
output [DATA_RATE *BA_WIDTH -1:0] o_sdr_BA,
|
|
output [DATA_RATE *ROW_WIDTH -1:0] o_sdr_ADDR,
|
|
output [DATA_RATE *DQ_GROUP *DQ_WIDTH -1:0] o_sdr_DATA,
|
|
output [DATA_RATE *DQ_GROUP *DQ_WIDTH -1:0] o_sdr_DATA_oe,
|
|
input [DATA_RATE *DQ_GROUP *DQ_WIDTH -1:0] i_sdr_DATA,
|
|
output [DATA_RATE *DQ_GROUP -1:0] o_sdr_DQM,
|
|
|
|
output [5:0]o_dbg_dly_cnt_b,
|
|
output o_dbg_tRCD_done,
|
|
output o_dbg_tRTW_done,
|
|
output o_dbg_ref_req,
|
|
output o_dbg_wr_ack,
|
|
output o_dbg_rd_ack,
|
|
output [DATA_RATE -1:0] o_dbg_n_CS,
|
|
output [DATA_RATE -1:0] o_dbg_n_RAS,
|
|
output [DATA_RATE -1:0] o_dbg_n_CAS,
|
|
output [DATA_RATE -1:0] o_dbg_n_WE,
|
|
output [DATA_RATE *BA_WIDTH -1:0] o_dbg_BA,
|
|
output [DATA_RATE *ROW_WIDTH -1:0] o_dbg_ADDR
|
|
);
|
|
|
|
function integer log2;
|
|
input integer val;
|
|
integer i;
|
|
begin
|
|
log2 = 0;
|
|
for (i=0; 2**i<val; i=i+1)
|
|
log2 = i+1;
|
|
end
|
|
endfunction
|
|
|
|
localparam DLY_CNT_C_WIDTH = 16; // counter for tPWRUP & tRAS_MAX
|
|
localparam DLY_CNT_D_WIDTH = 17; // counter for tREF
|
|
|
|
//localparam tCK = (1000/fCK_MHz);
|
|
//+1 for parameter with minimum value, -1 for parameter wth maximum value
|
|
localparam nPWRUP = tPWRUP/(1000/fSYS_MHz) + 1;
|
|
localparam nRAS = tRAS/(1000/fSYS_MHz) + 1;
|
|
localparam nRAS_MAX= tRAS_MAX/(1000/fSYS_MHz);
|
|
localparam nRC = tRC/(1000/fSYS_MHz) + 1;
|
|
localparam nRCD = tRCD/(1000/fSYS_MHz) + 1;
|
|
localparam nREF = (tREF/(2**ROW_WIDTH)/100)/(1000/fSYS_MHz);
|
|
localparam nRFC = tRFC/(1000/fSYS_MHz) + 1;
|
|
localparam nRP = tRP/(1000/fSYS_MHz) + 1;
|
|
localparam nRTP = CL-1'b1;
|
|
localparam nRTW = CL+tIORT;
|
|
|
|
// CRCW
|
|
// AA
|
|
// SSSE
|
|
localparam c_NOP = 4'b1111;
|
|
localparam c_ACT = 4'b0011;
|
|
localparam c_RD = 4'b0101;
|
|
localparam c_WR = 4'b0100;
|
|
localparam c_BT = 4'b0110;
|
|
localparam c_PRE = 4'b0010;
|
|
localparam c_REF = 4'b0001;
|
|
localparam c_MRS = 4'b0000;
|
|
|
|
localparam BA_MSB = BA_WIDTH+ ROW_WIDTH+ COL_WIDTH- 1;
|
|
localparam BA_LSB = ROW_WIDTH+ COL_WIDTH;
|
|
localparam ROW_MSB = ROW_WIDTH+ COL_WIDTH- 1;
|
|
localparam ROW_LSB = COL_WIDTH;
|
|
localparam COL_MSB = COL_WIDTH- 1;
|
|
localparam COL_LSB = 0;
|
|
|
|
// M2-M0
|
|
localparam BL1 = 3'b000;
|
|
localparam BL2 = 3'b001;
|
|
localparam BL4 = 3'b010;
|
|
localparam BL8 = 3'b011;
|
|
localparam BLP = 3'b111;
|
|
// M3
|
|
localparam SEQ = 1'b0;
|
|
localparam INT = 1'b1;
|
|
// M6-M4
|
|
localparam CL1 = 3'b001;
|
|
localparam CL2 = 3'b010;
|
|
localparam CL3 = 3'b011;
|
|
// M8-M7
|
|
localparam STD = 2'b00;
|
|
// M9
|
|
localparam PBL = 1'b0;
|
|
localparam SLA = 1'b1;
|
|
|
|
localparam BURST_LENGTH = (BL == 1)? BL1 :
|
|
(BL == 2)? BL2 :
|
|
(BL == 4)? BL4 :
|
|
(BL == 8)? BL8 : BL1;
|
|
localparam BURST_TYPE = SEQ;
|
|
localparam CAS_LATENCY = CL;
|
|
localparam OP_MODE = PBL;
|
|
|
|
localparam s_POWER_UP = 4'b0000;
|
|
localparam s_INIT_CKE = 4'b0001;
|
|
localparam s_INIT_PRE = 4'b0010;
|
|
localparam s_INIT_REF0 = 4'b0011;
|
|
localparam s_INIT_REF1 = 4'b0100;
|
|
localparam s_INIT_MRS = 4'b0101;
|
|
localparam s_IDLE = 4'b0110;
|
|
localparam s_ACT = 4'b0111;
|
|
localparam s_PRE = 4'b1000;
|
|
localparam s_REF = 4'b1001;
|
|
reg [3:0]r_sdr_state_1P;
|
|
|
|
localparam PRE_ALL = 1'b1;
|
|
localparam PRE_SINGLE = 1'b0;
|
|
|
|
localparam CYC_A = 0;
|
|
localparam CYC_B = 1;
|
|
localparam CYC_C = 2;
|
|
localparam CYC_D = 3;
|
|
|
|
`ifdef RTL_SIM
|
|
localparam RD_PIPE = (DATA_RATE == 1 && DDIO_TYPE == "HARD") ? CL+tIORT+2 :
|
|
(DATA_RATE == 1 && DDIO_TYPE == "SOFT") ? CL+tIORT+2 : CL+tIORT+3;
|
|
`else
|
|
localparam RD_PIPE = (DATA_RATE == 1 && DDIO_TYPE == "HARD") ? CL+tIORT+2 :
|
|
CL+tIORT+3;
|
|
`endif
|
|
|
|
(* syn_preserve = "TRUE" *)reg [DLY_CNT_A_WIDTH-1:0]r_dly_cnt_a_1P;
|
|
(* syn_preserve = "TRUE" *)reg [DLY_CNT_B_WIDTH-1:0]r_dly_cnt_b_1P;
|
|
(* syn_preserve = "TRUE" *)reg [DLY_CNT_C_WIDTH-1:0]r_dly_cnt_c_1P;
|
|
(* syn_preserve = "TRUE" *)reg [DLY_CNT_D_WIDTH-1:0]r_dly_cnt_d_1P;
|
|
reg r_sdr_init_done_1P;
|
|
reg r_tRAS_done_1P;
|
|
reg [REF_LATENCY-1:0]r_tRAS_MAX_done_1P;
|
|
reg r_tRCD_done_1P;
|
|
reg r_tRTP_done_1P;
|
|
reg r_tRTW_done_1P;
|
|
reg r_tWR_done_1P;
|
|
reg r_tRC_done_1P;
|
|
|
|
reg r_wr_ack_1P;
|
|
reg [RD_PIPE:0]r_rd_ack_P;
|
|
|
|
reg [ROW_WIDTH:0]r_act_row_1P[0:3];
|
|
reg [BA_WIDTH+ROW_WIDTH-1:0]r_act_addr_1P;
|
|
|
|
reg r_tRAS_MAX_1P;
|
|
reg r_tRAS_MAX_2P;
|
|
|
|
reg r_pre_allbank;
|
|
|
|
reg r_oscclk_1P;
|
|
reg [REF_LATENCY-1:0]r_ref_req_1P;
|
|
reg [6:0] r_sysclk_cnt_100_1P;
|
|
reg [DATA_RATE -1:0] r_sdr_cke_1P;
|
|
reg [DATA_RATE *4 -1:0] r_sdr_cmd_1P;
|
|
reg [DATA_RATE *BA_WIDTH -1:0] r_sdr_ba_1P;
|
|
reg [DATA_RATE *ROW_WIDTH -1:0] r_sdr_addr_1P;
|
|
reg [DATA_RATE *DQ_GROUP *DQ_WIDTH -1:0] r_sdr_dq_1P;
|
|
reg [DATA_RATE *DQ_GROUP *DQ_WIDTH -1:0] r_sdr_dqoe_1P;
|
|
reg [DATA_RATE *DQ_GROUP -1:0] r_sdr_dm_1P;
|
|
|
|
reg [DATA_RATE *4 -1:0] r_sdr_cmd_2P;
|
|
reg [DATA_RATE *BA_WIDTH -1:0] r_sdr_ba_2P;
|
|
reg [DATA_RATE *ROW_WIDTH -1:0] r_sdr_addr_2P;
|
|
reg [DATA_RATE *DQ_GROUP *DQ_WIDTH -1:0] r_sdr_dqoe_2P;
|
|
reg [DATA_RATE *DQ_GROUP -1:0] r_sdr_dm_2P;
|
|
|
|
reg [DATA_RATE *DQ_GROUP *DQ_WIDTH -1:0] r_sdr_dqin_1P;
|
|
|
|
integer c, b;
|
|
|
|
wire w_oscclk;
|
|
wire w_tRAS_MAX;
|
|
wire [BA_WIDTH-1:0]w_BA;
|
|
wire [ROW_WIDTH-1:0]w_ROW;
|
|
wire w_AFLAG;
|
|
wire [ROW_WIDTH-1:0]w_AROW;
|
|
wire w_pre_req;
|
|
|
|
assign w_BA = i_addr[BA_MSB:BA_LSB];
|
|
assign w_ROW = i_addr[ROW_MSB:ROW_LSB];
|
|
assign w_AFLAG = r_act_row_1P[w_BA][ROW_WIDTH];
|
|
assign w_AROW = r_act_row_1P[w_BA][ROW_WIDTH-1:0];
|
|
|
|
initial
|
|
begin
|
|
$display("RD_PIPE = %d\n", RD_PIPE);
|
|
$display("nPWRUP = %d\n", nPWRUP);
|
|
$display("nRAS = %d\n", nRAS);
|
|
$display("nRC = %d\n", nRC);
|
|
$display("nREF = %d\n", nREF);
|
|
$display("nRCD = %d\n", nRCD);
|
|
$display("nRFC = %d\n", nRFC);
|
|
$display("nRP = %d\n", nRP);
|
|
end
|
|
|
|
genvar k;
|
|
generate
|
|
|
|
always@(posedge i_arst or posedge i_sysclk)
|
|
begin
|
|
if (i_arst)
|
|
r_sysclk_cnt_100_1P <= {7{1'b0}};
|
|
else
|
|
begin
|
|
if (r_sysclk_cnt_100_1P == 7'd98) begin
|
|
r_sysclk_cnt_100_1P <= {7{1'b0}};
|
|
end
|
|
else if (r_dly_cnt_d_1P == nREF-1) begin
|
|
r_sysclk_cnt_100_1P <= r_sysclk_cnt_100_1P+7'd1;
|
|
end
|
|
|
|
end
|
|
end
|
|
|
|
if (CHECK_ACT_BA == 4)
|
|
assign w_pre_req = (~w_AFLAG) || (w_AROW != w_ROW);
|
|
else
|
|
assign w_pre_req = r_act_addr_1P != {w_BA, w_ROW};
|
|
|
|
for (k=0; k<REF_LATENCY-1; k=k+1)
|
|
begin: REF_LATENCY_MAP
|
|
always@(posedge i_arst or posedge i_sysclk)
|
|
begin
|
|
if (i_arst)
|
|
begin
|
|
r_ref_req_1P[k+1] <= 1'b0;
|
|
end
|
|
else if (r_sdr_state_1P == s_REF && r_dly_cnt_a_1P == nRFC)
|
|
begin
|
|
r_ref_req_1P[k+1] <= 1'b0;
|
|
end
|
|
else
|
|
begin
|
|
r_ref_req_1P[k+1] <= r_ref_req_1P[k];
|
|
end
|
|
end
|
|
|
|
always@(posedge i_arst or posedge i_sysclk)
|
|
begin
|
|
if (i_arst)
|
|
begin
|
|
r_tRAS_MAX_done_1P[k+1] <= 1'b0;
|
|
end
|
|
else
|
|
begin
|
|
r_tRAS_MAX_done_1P[k+1] <= r_tRAS_MAX_done_1P[k];
|
|
end
|
|
end
|
|
end
|
|
endgenerate
|
|
|
|
always@(posedge i_arst or posedge i_sysclk)
|
|
begin
|
|
if (i_arst)
|
|
begin
|
|
r_sdr_state_1P <= s_POWER_UP;
|
|
|
|
r_sdr_cke_1P <= {DATA_RATE {1'b0}};
|
|
r_sdr_cmd_1P <= {DATA_RATE {c_NOP}};
|
|
r_sdr_ba_1P <= {DATA_RATE *BA_WIDTH {1'b0}};
|
|
r_sdr_addr_1P <= {DATA_RATE *ROW_WIDTH {1'b0}};
|
|
r_sdr_dq_1P <= {DATA_RATE *DQ_GROUP *DQ_WIDTH {1'b0}};
|
|
r_sdr_dqoe_1P <= {DATA_RATE *DQ_GROUP *DQ_WIDTH {1'b0}};
|
|
r_sdr_dm_1P <= {DATA_RATE *DQ_GROUP {1'b1}};
|
|
r_act_row_1P[0] <= {ROW_WIDTH+1{1'b0}};
|
|
r_act_row_1P[1] <= {ROW_WIDTH+1{1'b0}};
|
|
r_act_row_1P[2] <= {ROW_WIDTH+1{1'b0}};
|
|
r_act_row_1P[3] <= {ROW_WIDTH+1{1'b0}};
|
|
r_act_addr_1P <= {BA_WIDTH+ROW_WIDTH{1'b0}};
|
|
|
|
r_sdr_cmd_2P <= {DATA_RATE {c_NOP}};
|
|
r_sdr_ba_2P <= {DATA_RATE *BA_WIDTH {1'b0}};
|
|
r_sdr_addr_2P <= {DATA_RATE *ROW_WIDTH {1'b0}};
|
|
r_sdr_dqoe_2P <= {DATA_RATE *DQ_GROUP *DQ_WIDTH {1'b0}};
|
|
r_sdr_dm_2P <= {DATA_RATE *DQ_GROUP {1'b1}};
|
|
|
|
r_dly_cnt_a_1P <= {DLY_CNT_A_WIDTH{1'b0}};
|
|
r_dly_cnt_b_1P <= {DLY_CNT_B_WIDTH{1'b0}};
|
|
r_dly_cnt_c_1P <= {DLY_CNT_C_WIDTH{1'b0}};
|
|
r_dly_cnt_d_1P <= {DLY_CNT_D_WIDTH{1'b0}};
|
|
r_sdr_init_done_1P <= 1'b0;
|
|
r_wr_ack_1P <= 1'b0;
|
|
r_rd_ack_P[0] <= 1'b0;
|
|
|
|
r_oscclk_1P <= 1'b0;
|
|
r_ref_req_1P[0] <= 1'b0;
|
|
r_tRAS_done_1P <= 1'b0;
|
|
r_tRAS_MAX_done_1P[0] <= 1'b0;
|
|
r_tRCD_done_1P <= 1'b0;
|
|
r_tRTP_done_1P <= 1'b0;
|
|
r_tRTW_done_1P <= 1'b0;
|
|
r_tWR_done_1P <= 1'b0;
|
|
r_tRC_done_1P <= 1'b0;
|
|
|
|
r_sdr_dqin_1P <= {DQ_GROUP*DQ_WIDTH{1'b0}};
|
|
r_pre_allbank <= 1'b0;
|
|
end
|
|
else if (i_pll_locked)
|
|
begin
|
|
r_sdr_cmd_1P <= {DATA_RATE {c_NOP}};
|
|
r_sdr_ba_1P <= {DATA_RATE *BA_WIDTH {1'b0}};
|
|
r_sdr_addr_1P <= {DATA_RATE *ROW_WIDTH {1'b0}};
|
|
r_sdr_dq_1P <= {DATA_RATE *DQ_GROUP *DQ_WIDTH {1'b0}};
|
|
r_sdr_dqoe_1P <= {DATA_RATE *DQ_GROUP *DQ_WIDTH {1'b0}};
|
|
|
|
r_sdr_cmd_2P <= r_sdr_cmd_1P;
|
|
r_sdr_ba_2P <= r_sdr_ba_1P;
|
|
r_sdr_addr_2P <= r_sdr_addr_1P;
|
|
r_sdr_dqoe_2P <= r_sdr_dqoe_1P;
|
|
|
|
r_wr_ack_1P <= 1'b0;
|
|
r_rd_ack_P[0] <= 1'b0;
|
|
|
|
r_sdr_dqin_1P <= i_sdr_DATA;
|
|
|
|
r_dly_cnt_a_1P <= r_dly_cnt_a_1P+1'b1;
|
|
r_dly_cnt_b_1P <= r_dly_cnt_b_1P+1'b1;
|
|
r_dly_cnt_c_1P <= r_dly_cnt_c_1P+1'b1;
|
|
|
|
if (r_dly_cnt_d_1P == nREF-1)
|
|
r_dly_cnt_d_1P <= {DLY_CNT_D_WIDTH{1'b0}};
|
|
else if (r_sdr_state_1P != s_POWER_UP)
|
|
r_dly_cnt_d_1P <= r_dly_cnt_d_1P+1'b1;
|
|
|
|
if (r_dly_cnt_b_1P == nRAS-1'b1)
|
|
r_tRAS_done_1P <= 1'b1;
|
|
|
|
if (r_sysclk_cnt_100_1P == 7'd98)
|
|
r_ref_req_1P[0] <= 1'b1;
|
|
|
|
if (r_dly_cnt_b_1P == nRCD-1)
|
|
r_tRCD_done_1P <= 1'b1;
|
|
|
|
if (r_dly_cnt_b_1P == nRTP-1)
|
|
r_tRTP_done_1P <= 1'b1;
|
|
|
|
if (r_dly_cnt_b_1P == nRTW-1)
|
|
r_tRTW_done_1P <= 1'b1;
|
|
|
|
if (r_dly_cnt_b_1P == tWR-1)
|
|
r_tWR_done_1P <= 1'b1;
|
|
|
|
if (r_dly_cnt_b_1P == nRC-1)
|
|
r_tRC_done_1P <= 1'b1;
|
|
|
|
if (r_dly_cnt_c_1P == nRAS_MAX && r_sdr_state_1P != s_POWER_UP)
|
|
r_tRAS_MAX_done_1P[0] <= 1'b1;
|
|
|
|
case (r_sdr_state_1P)
|
|
s_POWER_UP:
|
|
begin
|
|
if (r_dly_cnt_c_1P == nPWRUP) // count power up sequence
|
|
begin
|
|
r_sdr_state_1P <= s_INIT_CKE;
|
|
|
|
r_sdr_cke_1P <= {DATA_RATE{1'b1}};
|
|
r_dly_cnt_c_1P <= {DLY_CNT_C_WIDTH{1'b0}};
|
|
end
|
|
end
|
|
|
|
s_INIT_CKE:
|
|
begin
|
|
r_sdr_state_1P <= s_INIT_PRE;
|
|
|
|
r_sdr_cmd_1P[CYC_A+:4] <= c_PRE;
|
|
r_sdr_addr_1P[CYC_A+10] <= PRE_ALL;
|
|
|
|
r_dly_cnt_a_1P <= {DLY_CNT_A_WIDTH{1'b0}};
|
|
end
|
|
|
|
s_INIT_PRE:
|
|
begin
|
|
if (r_dly_cnt_a_1P == nRP)
|
|
begin
|
|
r_sdr_state_1P <= s_INIT_REF0;
|
|
|
|
r_sdr_cmd_1P[CYC_A+:4] <= c_REF;
|
|
|
|
r_dly_cnt_a_1P <= {DLY_CNT_A_WIDTH{1'b0}};
|
|
end
|
|
end
|
|
|
|
s_INIT_REF0:
|
|
begin
|
|
if (r_dly_cnt_a_1P == nRFC)
|
|
begin
|
|
r_sdr_state_1P <= s_INIT_REF1;
|
|
|
|
r_sdr_cmd_1P[CYC_A+:4] <= c_REF;
|
|
|
|
r_dly_cnt_a_1P <= {DLY_CNT_A_WIDTH{1'b0}};
|
|
end
|
|
end
|
|
|
|
s_INIT_REF1:
|
|
begin
|
|
if (r_dly_cnt_a_1P == nRFC)
|
|
begin
|
|
r_sdr_state_1P <= s_INIT_MRS;
|
|
|
|
r_sdr_cmd_1P[CYC_A+:4] <= c_MRS;
|
|
r_sdr_addr_1P[CYC_A+:ROW_WIDTH] <= {{ROW_WIDTH-10{1'b0}},
|
|
OP_MODE, CAS_LATENCY,
|
|
BURST_TYPE, BURST_LENGTH};
|
|
|
|
r_dly_cnt_a_1P <= {DLY_CNT_A_WIDTH{1'b0}};
|
|
end
|
|
end
|
|
|
|
s_INIT_MRS:
|
|
begin
|
|
if (r_dly_cnt_a_1P == tMRD-1'b1)
|
|
begin
|
|
r_sdr_state_1P <= s_IDLE;
|
|
|
|
r_sdr_dm_1P <= {DATA_RATE*DQ_GROUP{1'b0}};
|
|
r_sdr_dm_2P <= {DATA_RATE*DQ_GROUP{1'b0}};
|
|
|
|
r_sdr_init_done_1P <= 1'b1;
|
|
r_tRCD_done_1P <= 1'b0;
|
|
r_tRTP_done_1P <= 1'b0;
|
|
r_tWR_done_1P <= 1'b0;
|
|
r_tRC_done_1P <= 1'b0;
|
|
end
|
|
end
|
|
|
|
s_IDLE:
|
|
begin
|
|
if (r_ref_req_1P[REF_LATENCY-1])
|
|
begin
|
|
if (CHECK_ACT_BA == 4 && (
|
|
r_act_row_1P[0][ROW_WIDTH] || r_act_row_1P[1][ROW_WIDTH] ||
|
|
r_act_row_1P[2][ROW_WIDTH] || r_act_row_1P[3][ROW_WIDTH ]))
|
|
begin
|
|
r_sdr_state_1P <= s_PRE;
|
|
|
|
r_sdr_cmd_1P[CYC_A+:4] <= c_PRE;
|
|
r_sdr_addr_1P[CYC_A+10] <= PRE_ALL;
|
|
r_act_row_1P[0][ROW_WIDTH] <= 1'b0;
|
|
r_act_row_1P[1][ROW_WIDTH] <= 1'b0;
|
|
r_act_row_1P[2][ROW_WIDTH] <= 1'b0;
|
|
r_act_row_1P[3][ROW_WIDTH] <= 1'b0;
|
|
|
|
r_dly_cnt_a_1P <= {DLY_CNT_A_WIDTH{1'b0}};
|
|
end
|
|
else
|
|
begin
|
|
r_sdr_state_1P <= s_REF;
|
|
|
|
r_sdr_cmd_1P[CYC_A+:4] <= c_REF;
|
|
|
|
r_dly_cnt_a_1P <= {DLY_CNT_A_WIDTH{1'b0}};
|
|
end
|
|
end
|
|
else if (i_we || i_re)
|
|
begin
|
|
r_sdr_state_1P <= s_ACT;
|
|
|
|
r_sdr_cmd_1P[CYC_A+:4] <= c_ACT;
|
|
r_sdr_ba_1P[CYC_A+:BA_WIDTH] <= i_addr[BA_MSB:BA_LSB];
|
|
r_sdr_addr_1P[CYC_A+:ROW_WIDTH] <= i_addr[ROW_MSB:ROW_LSB];
|
|
|
|
if (CHECK_ACT_BA == 4)
|
|
r_act_row_1P[w_BA] <= {1'b1, w_ROW};
|
|
r_act_addr_1P <= {w_BA, w_ROW};
|
|
|
|
r_dly_cnt_b_1P <= {DLY_CNT_B_WIDTH{1'b0}};
|
|
r_dly_cnt_c_1P <= {DLY_CNT_C_WIDTH{1'b0}};
|
|
r_tRAS_done_1P <= 1'b0;
|
|
r_tRCD_done_1P <= 1'b0;
|
|
r_tRC_done_1P <= 1'b0;
|
|
r_tRAS_MAX_done_1P[0] <= 1'b0;
|
|
end
|
|
end
|
|
|
|
s_ACT:
|
|
begin
|
|
if (r_ref_req_1P[REF_LATENCY-1] || r_tRAS_MAX_done_1P[REF_LATENCY-1])
|
|
begin
|
|
if (r_tRAS_done_1P && r_tWR_done_1P && r_tRTP_done_1P)
|
|
begin
|
|
r_sdr_state_1P <= s_PRE;
|
|
|
|
r_sdr_cmd_1P[CYC_A+:4] <= c_PRE;
|
|
r_sdr_addr_1P[CYC_A+10] <= PRE_ALL;
|
|
r_sdr_ba_2P <= r_sdr_ba_2P;
|
|
r_sdr_addr_2P <= r_sdr_addr_2P; // do not assign r_sdr_addr_1P to r_sdr_addr_2P because r_sdr_addr_1P was zero in previous clock
|
|
r_pre_allbank <= 1'b1;
|
|
if (CHECK_ACT_BA == 4)
|
|
begin
|
|
r_act_row_1P[0][ROW_WIDTH] <= 1'b0;
|
|
r_act_row_1P[1][ROW_WIDTH] <= 1'b0;
|
|
r_act_row_1P[2][ROW_WIDTH] <= 1'b0;
|
|
r_act_row_1P[3][ROW_WIDTH] <= 1'b0;
|
|
end
|
|
|
|
r_dly_cnt_a_1P <= {DLY_CNT_A_WIDTH{1'b0}};
|
|
end
|
|
end
|
|
else if (i_we || i_re)
|
|
begin
|
|
if (w_pre_req)
|
|
begin
|
|
if (r_tRC_done_1P && r_tRAS_done_1P &&
|
|
r_tWR_done_1P && r_tRTP_done_1P)
|
|
begin
|
|
r_sdr_state_1P <= s_PRE;
|
|
|
|
r_sdr_cmd_1P[CYC_A+:4] <= c_PRE;
|
|
r_sdr_ba_1P[CYC_A+:BA_WIDTH] <= i_addr[BA_MSB:BA_LSB];
|
|
r_sdr_addr_1P[CYC_A+10] <= PRE_SINGLE;
|
|
if (CHECK_ACT_BA == 4)
|
|
r_act_row_1P[w_BA][ROW_WIDTH] <= 1'b0;
|
|
|
|
r_dly_cnt_a_1P <= {DLY_CNT_A_WIDTH{1'b0}};
|
|
end
|
|
end
|
|
else if (r_tRCD_done_1P)
|
|
begin
|
|
if (i_we && r_tRTW_done_1P)
|
|
begin
|
|
if (DATA_RATE == 1)
|
|
begin
|
|
r_sdr_cmd_1P[CYC_A+:4] <= c_WR;
|
|
r_sdr_ba_2P[CYC_A+:BA_WIDTH] <= i_addr[BA_MSB:BA_LSB];
|
|
r_sdr_addr_2P[CYC_A+:COL_WIDTH] <= i_addr[COL_MSB:COL_LSB];
|
|
end
|
|
else
|
|
begin
|
|
for (c=0; c<DATA_RATE; c=c+1)
|
|
begin
|
|
r_sdr_cmd_1P[c*4+:4] <= c_WR;
|
|
r_sdr_ba_2P[c*BA_WIDTH+:BA_WIDTH] <= i_addr[BA_MSB:BA_LSB];
|
|
r_sdr_addr_2P[c*ROW_WIDTH+log2(DATA_RATE)+:COL_WIDTH-log2(DATA_RATE)] <= i_addr[COL_MSB:COL_LSB+log2(DATA_RATE)];
|
|
for (b=0; b<log2(DATA_RATE); b=b+1)
|
|
begin
|
|
r_sdr_addr_2P[c*ROW_WIDTH+b] <= (c & 32'hFFFFFFFF) >> b;
|
|
end
|
|
end
|
|
end
|
|
|
|
r_sdr_dq_1P <= i_din;
|
|
r_sdr_dqoe_1P <= {DATA_RATE*DQ_GROUP*DQ_WIDTH{1'b1}};
|
|
|
|
r_dly_cnt_b_1P <= {DLY_CNT_B_WIDTH{1'b0}};
|
|
r_tWR_done_1P <= 1'b0;
|
|
|
|
r_wr_ack_1P <= ~r_ref_req_1P[0];
|
|
|
|
if (REF_LATENCY > 2) begin
|
|
if (r_ref_req_1P[REF_LATENCY-2] || r_tRAS_MAX_done_1P[REF_LATENCY-2] || (i_last))
|
|
begin
|
|
r_sdr_cmd_1P <= {DATA_RATE{c_NOP}};
|
|
r_sdr_dqoe_1P <= {DATA_RATE*DQ_GROUP*DQ_WIDTH{1'b0}};
|
|
r_wr_ack_1P <= 1'b0;
|
|
end
|
|
end
|
|
else begin
|
|
if (r_ref_req_1P[REF_LATENCY-2] || r_tRAS_MAX_done_1P[REF_LATENCY-2] || (i_last & r_wr_ack_1P))
|
|
begin
|
|
r_sdr_cmd_1P <= {DATA_RATE{c_NOP}};
|
|
r_sdr_dqoe_1P <= {DATA_RATE*DQ_GROUP*DQ_WIDTH{1'b0}};
|
|
r_wr_ack_1P <= 1'b0;
|
|
end
|
|
end
|
|
|
|
end
|
|
else if (~i_we && i_re)
|
|
begin
|
|
if (DATA_RATE == 1)
|
|
begin
|
|
r_sdr_cmd_1P <= c_RD;
|
|
r_sdr_ba_2P <= i_addr[BA_MSB:BA_LSB];
|
|
r_sdr_addr_2P <= i_addr[COL_MSB:COL_LSB];
|
|
end
|
|
else
|
|
begin
|
|
for (c=0; c<DATA_RATE; c=c+1)
|
|
begin
|
|
r_sdr_cmd_1P[c*4+:4] <= c_RD;
|
|
r_sdr_ba_2P[c*BA_WIDTH+:BA_WIDTH] <= i_addr[BA_MSB:BA_LSB];
|
|
r_sdr_addr_2P[c*ROW_WIDTH+log2(DATA_RATE)+:COL_WIDTH-log2(DATA_RATE)] <= i_addr[COL_MSB:COL_LSB+log2(DATA_RATE)];
|
|
for (b=0; b<log2(DATA_RATE); b=b+1)
|
|
begin
|
|
r_sdr_addr_2P[c*ROW_WIDTH+b] <= (c & 32'hFFFFFFFF) >> b;
|
|
end
|
|
end
|
|
end
|
|
|
|
r_dly_cnt_b_1P <= {DLY_CNT_B_WIDTH{1'b0}};
|
|
r_tRTW_done_1P <= 1'b0;
|
|
r_tRC_done_1P <= 1'b0;
|
|
|
|
r_rd_ack_P[0] <= ~r_ref_req_1P[0];
|
|
|
|
if (REF_LATENCY > 2) begin
|
|
if (r_ref_req_1P[REF_LATENCY-2] || r_tRAS_MAX_done_1P[REF_LATENCY-2] || (i_last))
|
|
begin
|
|
if (r_rd_ack_P[0])
|
|
begin
|
|
r_sdr_cmd_1P <= {DATA_RATE{c_NOP}};
|
|
r_sdr_dqoe_1P <= {DATA_RATE*DQ_GROUP*DQ_WIDTH{1'b0}};
|
|
r_rd_ack_P[0] <= 1'b0;
|
|
end
|
|
end
|
|
end
|
|
else begin
|
|
if (r_ref_req_1P[REF_LATENCY-2] || r_tRAS_MAX_done_1P[REF_LATENCY-2] || (i_last & r_rd_ack_P[0]))
|
|
begin
|
|
if (r_rd_ack_P[0])
|
|
begin
|
|
r_sdr_cmd_1P <= {DATA_RATE{c_NOP}};
|
|
r_sdr_dqoe_1P <= {DATA_RATE*DQ_GROUP*DQ_WIDTH{1'b0}};
|
|
r_rd_ack_P[0] <= 1'b0;
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
s_PRE:
|
|
begin
|
|
if (r_dly_cnt_a_1P == nRP-1'b1)
|
|
begin
|
|
if (r_ref_req_1P[REF_LATENCY-1])
|
|
begin
|
|
if (r_pre_allbank) // check if the previous PRE is ALL_BANK or SINGLE_BANK
|
|
begin
|
|
r_sdr_state_1P <= s_REF;
|
|
r_sdr_cmd_1P[CYC_A+:4] <= c_REF;
|
|
r_pre_allbank <= 1'b0;
|
|
r_dly_cnt_a_1P <= {DLY_CNT_A_WIDTH{1'b0}};
|
|
end
|
|
else
|
|
begin // if the previous PRE is SINGLE_BANK, issue PRE to ALL_BANK before trigger AUTO-refresh
|
|
r_sdr_state_1P <= s_PRE;
|
|
r_sdr_cmd_1P[CYC_A+:4] <= c_PRE;
|
|
r_sdr_addr_1P[CYC_A+10] <= PRE_ALL;
|
|
r_pre_allbank <= 1'b1;
|
|
if (CHECK_ACT_BA == 4)
|
|
begin
|
|
r_act_row_1P[0][ROW_WIDTH] <= 1'b0;
|
|
r_act_row_1P[1][ROW_WIDTH] <= 1'b0;
|
|
r_act_row_1P[2][ROW_WIDTH] <= 1'b0;
|
|
r_act_row_1P[3][ROW_WIDTH] <= 1'b0;
|
|
end
|
|
r_dly_cnt_a_1P <= {DLY_CNT_A_WIDTH{1'b0}};
|
|
end
|
|
end
|
|
else
|
|
begin
|
|
r_sdr_state_1P <= s_IDLE;
|
|
end
|
|
end
|
|
end
|
|
|
|
s_REF:
|
|
begin
|
|
if (r_dly_cnt_a_1P == nRFC)
|
|
begin
|
|
r_sdr_state_1P <= s_IDLE;
|
|
r_ref_req_1P[0] <= 1'b0;
|
|
r_dly_cnt_d_1P <= {DLY_CNT_D_WIDTH{1'b0}};
|
|
end
|
|
end
|
|
endcase
|
|
end
|
|
end
|
|
|
|
assign o_sdr_state = r_sdr_state_1P;
|
|
assign o_sdr_init_done = r_sdr_init_done_1P;
|
|
assign o_wr_ack = r_wr_ack_1P;
|
|
genvar i;
|
|
generate
|
|
for (i=1; i<=RD_PIPE; i=i+1)
|
|
begin: readback
|
|
always@(posedge i_arst or posedge i_sysclk)
|
|
begin
|
|
if (i_arst)
|
|
r_rd_ack_P[i] <= 1'b0;
|
|
else
|
|
r_rd_ack_P[i] <= r_rd_ack_P[i-1];
|
|
end
|
|
end
|
|
endgenerate
|
|
assign o_rd_ack = r_rd_ack_P[0];
|
|
assign o_ref_req = r_ref_req_1P[0];
|
|
assign o_rd_valid = r_rd_ack_P[RD_PIPE];
|
|
assign o_dout = r_sdr_dqin_1P;
|
|
|
|
assign o_sdr_CKE = r_sdr_cke_1P;
|
|
genvar j;
|
|
generate
|
|
for (j=0; j<DATA_RATE; j=j+1)
|
|
begin: cycle_mapping
|
|
assign o_sdr_n_CS[j] = r_sdr_cmd_2P[j*4+3];
|
|
assign o_sdr_n_RAS[j] = r_sdr_cmd_2P[j*4+2];
|
|
assign o_sdr_n_CAS[j] = r_sdr_cmd_2P[j*4+1];
|
|
assign o_sdr_n_WE[j] = r_sdr_cmd_2P[j*4+0];
|
|
|
|
assign o_dbg_n_CS[j] = r_sdr_cmd_2P[j*4+3];
|
|
assign o_dbg_n_RAS[j] = r_sdr_cmd_2P[j*4+2];
|
|
assign o_dbg_n_CAS[j] = r_sdr_cmd_2P[j*4+1];
|
|
assign o_dbg_n_WE[j] = r_sdr_cmd_2P[j*4+0];
|
|
end
|
|
endgenerate
|
|
assign o_sdr_BA = r_sdr_ba_2P;
|
|
assign o_sdr_ADDR = r_sdr_addr_2P;
|
|
assign o_sdr_DATA = r_sdr_dq_1P;
|
|
assign o_sdr_DATA_oe = r_sdr_dqoe_2P;
|
|
assign o_sdr_DQM = r_sdr_dm_2P;
|
|
|
|
assign o_dbg_dly_cnt_b = (DLY_CNT_B_WIDTH == 4) ? {2'b00, r_dly_cnt_b_1P} : r_dly_cnt_b_1P;
|
|
assign o_dbg_tRCD_done = r_tRCD_done_1P;
|
|
assign o_dbg_tRTW_done = r_tRTW_done_1P;
|
|
assign o_dbg_ref_req = r_ref_req_1P[REF_LATENCY-2];
|
|
assign o_dbg_wr_ack = r_wr_ack_1P;
|
|
assign o_dbg_rd_ack = r_rd_ack_P[0];
|
|
|
|
assign o_dbg_BA = r_sdr_ba_2P;
|
|
assign o_dbg_ADDR = r_sdr_addr_2P;
|
|
|
|
endmodule
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
// Copyright (C) 2013-2019 Efinix Inc. All rights reserved.
|
|
//
|
|
// This document contains proprietary information which is
|
|
// protected by copyright. All rights are reserved. This notice
|
|
// refers to original work by Efinix, Inc. which may be derivitive
|
|
// of other work distributed under license of the authors. In the
|
|
// case of derivative work, nothing in this notice overrides the
|
|
// original author's license agreement. Where applicable, the
|
|
// original license agreement is included in it's original
|
|
// unmodified form immediately below this header.
|
|
//
|
|
// WARRANTY DISCLAIMER.
|
|
// THE DESIGN, CODE, OR INFORMATION ARE PROVIDED “AS IS” AND
|
|
// EFINIX MAKES NO WARRANTIES, EXPRESS OR IMPLIED WITH
|
|
// RESPECT THERETO, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES,
|
|
// INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
|
// MERCHANTABILITY, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR
|
|
// PURPOSE. SOME STATES DO NOT ALLOW EXCLUSIONS OF AN IMPLIED
|
|
// WARRANTY, SO THIS DISCLAIMER MAY NOT APPLY TO LICENSEE.
|
|
//
|
|
// LIMITATION OF LIABILITY.
|
|
// NOTWITHSTANDING ANYTHING TO THE CONTRARY, EXCEPT FOR BODILY
|
|
// INJURY, EFINIX SHALL NOT BE LIABLE WITH RESPECT TO ANY SUBJECT
|
|
// MATTER OF THIS AGREEMENT UNDER TORT, CONTRACT, STRICT LIABILITY
|
|
// OR ANY OTHER LEGAL OR EQUITABLE THEORY (I) FOR ANY INDIRECT,
|
|
// SPECIAL, INCIDENTAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES OF ANY
|
|
// CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF
|
|
// GOODWILL, DATA OR PROFIT, WORK STOPPAGE, OR COMPUTER FAILURE OR
|
|
// MALFUNCTION, OR IN ANY EVENT (II) FOR ANY AMOUNT IN EXCESS, IN
|
|
// THE AGGREGATE, OF THE FEE PAID BY LICENSEE TO EFINIX HEREUNDER
|
|
// (OR, IF THE FEE HAS BEEN WAIVED, $100), EVEN IF EFINIX SHALL HAVE
|
|
// BEEN INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO
|
|
// NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR
|
|
// CONSEQUENTIAL DAMAGES, SO THIS LIMITATION AND EXCLUSION MAY NOT
|
|
// APPLY TO LICENSEE.
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// _____
|
|
// / _______ Copyright (C) 2013-2020 Efinix Inc. All rights reserved.
|
|
// / / \
|
|
// / / .. / `IP_MODULE_NAME(sdram_io_block).v
|
|
// / / .' /
|
|
// __/ /.' / Description:
|
|
// __ \ / sdram controller I/O alignment
|
|
// /_/ /\ \_____/ /
|
|
// ____/ \_______/
|
|
//
|
|
// *******************************
|
|
// Revisions:
|
|
// 1.0 Initial rev
|
|
//
|
|
// *******************************
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
module `IP_MODULE_NAME(sdram_io_block)
|
|
#(
|
|
parameter DATA_RATE = 2, // Do not over write
|
|
parameter BA_WIDTH = 2,
|
|
parameter ROW_WIDTH = 13,
|
|
parameter COL_WIDTH = 10,
|
|
parameter DQ_WIDTH = 8, // x4, x8
|
|
parameter DQ_GROUP = 2
|
|
)
|
|
(
|
|
input i_arst,
|
|
input i_sysclk,
|
|
input i_sdrclk,
|
|
input i_tACclk,
|
|
input i_pll_locked,
|
|
|
|
input [DATA_RATE -1:0] i_sdr_CKE_core,
|
|
input [DATA_RATE -1:0] i_sdr_n_CS_core,
|
|
input [DATA_RATE -1:0] i_sdr_n_RAS_core,
|
|
input [DATA_RATE -1:0] i_sdr_n_CAS_core,
|
|
input [DATA_RATE -1:0] i_sdr_n_WE_core,
|
|
input [DATA_RATE *BA_WIDTH -1:0] i_sdr_BA_core,
|
|
input [DATA_RATE *ROW_WIDTH -1:0] i_sdr_ADDR_core,
|
|
input [DATA_RATE *DQ_GROUP *DQ_WIDTH -1:0] i_sdr_DATA_core,
|
|
input [DATA_RATE *DQ_GROUP *DQ_WIDTH -1:0] i_sdr_DATA_oe_core,
|
|
output [DATA_RATE *DQ_GROUP *DQ_WIDTH -1:0] o_sdr_DATA_core,
|
|
input [DATA_RATE *DQ_GROUP -1:0] i_sdr_DQM_core,
|
|
|
|
output [DATA_RATE -1:0] o_sdr_CKE_pad,
|
|
output [DATA_RATE -1:0] o_sdr_n_CS_pad,
|
|
output [DATA_RATE -1:0] o_sdr_n_RAS_pad,
|
|
output [DATA_RATE -1:0] o_sdr_n_CAS_pad,
|
|
output [DATA_RATE -1:0] o_sdr_n_WE_pad,
|
|
output [DATA_RATE *BA_WIDTH -1:0] o_sdr_BA_pad,
|
|
output [DATA_RATE *ROW_WIDTH -1:0] o_sdr_ADDR_pad,
|
|
output [DATA_RATE *DQ_GROUP *DQ_WIDTH -1:0] o_sdr_DATA_pad,
|
|
output [DATA_RATE *DQ_GROUP *DQ_WIDTH -1:0] o_sdr_DATA_oe_pad,
|
|
input [DATA_RATE *DQ_GROUP *DQ_WIDTH -1:0] i_sdr_DATA_pad,
|
|
output [DATA_RATE *DQ_GROUP -1:0] o_sdr_DQM_pad
|
|
);
|
|
|
|
localparam BA_MSB = BA_WIDTH+ ROW_WIDTH+ COL_WIDTH- 1;
|
|
localparam BA_LSB = ROW_WIDTH+ COL_WIDTH;
|
|
localparam ROW_MSB = ROW_WIDTH+ COL_WIDTH- 1;
|
|
localparam ROW_LSB = COL_WIDTH;
|
|
localparam COL_MSB = COL_WIDTH- 1;
|
|
localparam COL_LSB = 0;
|
|
|
|
localparam CYC_A = 0;
|
|
localparam CYC_B = 1;
|
|
localparam CYC_C = 2;
|
|
localparam CYC_D = 3;
|
|
|
|
wire [DATA_RATE*DQ_GROUP*DQ_WIDTH-1:0]w_sdr_DATA_core;
|
|
reg [DQ_GROUP*DQ_WIDTH-1:0]r_sdr_DATA_core_1P;
|
|
reg r_pll_locked_1P;
|
|
|
|
genvar rate;
|
|
|
|
initial
|
|
begin
|
|
$display("Data Rate = %d\n", DATA_RATE);
|
|
`ifdef RTL_SIM
|
|
$display("RTL_SIM\n");
|
|
`endif
|
|
end
|
|
|
|
always@(posedge i_arst or posedge i_sysclk)
|
|
begin
|
|
if (i_arst)
|
|
begin
|
|
r_pll_locked_1P <= 1'b0;
|
|
end
|
|
else
|
|
begin
|
|
r_pll_locked_1P <= i_pll_locked;
|
|
end
|
|
end
|
|
|
|
`IP_MODULE_NAME(sync_ddio_group_out)
|
|
#(
|
|
.DW(1),
|
|
.INIT(1'b0),
|
|
.SYNC("RISING")
|
|
)
|
|
inst_CKE
|
|
(
|
|
.arst(i_arst),
|
|
.d0(i_sdr_CKE_core[CYC_A]),
|
|
.d1(i_sdr_CKE_core[CYC_B]),
|
|
.c_x1(i_sysclk),
|
|
.c_x2(i_sdrclk),
|
|
.lock(r_pll_locked_1P),
|
|
.c(),
|
|
.q(o_sdr_CKE_pad[CYC_A])
|
|
);
|
|
|
|
`IP_MODULE_NAME(sync_ddio_group_out)
|
|
#(
|
|
.DW(1),
|
|
.INIT(1'b0),
|
|
.SYNC("RISING")
|
|
)
|
|
inst_CS
|
|
(
|
|
.arst(i_arst),
|
|
.d0(i_sdr_n_CS_core[CYC_A]),
|
|
.d1(i_sdr_n_CS_core[CYC_B]),
|
|
.c_x1(i_sysclk),
|
|
.c_x2(i_sdrclk),
|
|
.lock(r_pll_locked_1P),
|
|
.c(),
|
|
.q(o_sdr_n_CS_pad[CYC_A])
|
|
);
|
|
|
|
`IP_MODULE_NAME(sync_ddio_group_out)
|
|
#(
|
|
.DW(1),
|
|
.INIT(1'b0),
|
|
.SYNC("RISING")
|
|
)
|
|
inst_RAS
|
|
(
|
|
.arst(i_arst),
|
|
.d0(i_sdr_n_RAS_core[CYC_A]),
|
|
.d1(i_sdr_n_RAS_core[CYC_B]),
|
|
.c_x1(i_sysclk),
|
|
.c_x2(i_sdrclk),
|
|
.lock(r_pll_locked_1P),
|
|
.c(),
|
|
.q(o_sdr_n_RAS_pad[CYC_A])
|
|
);
|
|
|
|
`IP_MODULE_NAME(sync_ddio_group_out)
|
|
#(
|
|
.DW(1),
|
|
.INIT(1'b0),
|
|
.SYNC("RISING")
|
|
)
|
|
inst_CAS
|
|
(
|
|
.arst(i_arst),
|
|
.d0(i_sdr_n_CAS_core[CYC_A]),
|
|
.d1(i_sdr_n_CAS_core[CYC_B]),
|
|
.c_x1(i_sysclk),
|
|
.c_x2(i_sdrclk),
|
|
.lock(r_pll_locked_1P),
|
|
.c(),
|
|
.q(o_sdr_n_CAS_pad[CYC_A])
|
|
);
|
|
|
|
`IP_MODULE_NAME(sync_ddio_group_out)
|
|
#(
|
|
.DW(1),
|
|
.INIT(1'b0),
|
|
.SYNC("RISING")
|
|
)
|
|
inst_WE
|
|
(
|
|
.arst(i_arst),
|
|
.d0(i_sdr_n_WE_core[CYC_A]),
|
|
.d1(i_sdr_n_WE_core[CYC_B]),
|
|
.c_x1(i_sysclk),
|
|
.c_x2(i_sdrclk),
|
|
.lock(r_pll_locked_1P),
|
|
.c(),
|
|
.q(o_sdr_n_WE_pad[CYC_A])
|
|
);
|
|
|
|
`IP_MODULE_NAME(sync_ddio_group_out)
|
|
#(
|
|
.DW(BA_WIDTH),
|
|
.INIT(1'b0),
|
|
.SYNC("RISING")
|
|
)
|
|
inst_BA
|
|
(
|
|
.arst(i_arst),
|
|
.d0(i_sdr_BA_core[CYC_A*BA_WIDTH+:BA_WIDTH]),
|
|
.d1(i_sdr_BA_core[CYC_B*BA_WIDTH+:BA_WIDTH]),
|
|
.c_x1(i_sysclk),
|
|
.c_x2(i_sdrclk),
|
|
.lock(r_pll_locked_1P),
|
|
.c(),
|
|
.q(o_sdr_BA_pad[BA_WIDTH-1:0])
|
|
);
|
|
|
|
`IP_MODULE_NAME(sync_ddio_group_out)
|
|
#(
|
|
.DW(ROW_WIDTH),
|
|
.INIT(1'b0),
|
|
.SYNC("RISING")
|
|
)
|
|
inst_ADDR
|
|
(
|
|
.arst(i_arst),
|
|
.d0(i_sdr_ADDR_core[CYC_A*ROW_WIDTH+:ROW_WIDTH]),
|
|
.d1(i_sdr_ADDR_core[CYC_B*ROW_WIDTH+:ROW_WIDTH]),
|
|
.c_x1(i_sysclk),
|
|
.c_x2(i_sdrclk),
|
|
.lock(r_pll_locked_1P),
|
|
.c(),
|
|
.q(o_sdr_ADDR_pad[ROW_WIDTH-1:0])
|
|
);
|
|
|
|
`IP_MODULE_NAME(sync_ddio_group_out)
|
|
#(
|
|
.DW(DQ_GROUP*DQ_WIDTH),
|
|
.INIT(1'b0),
|
|
.SYNC("RISING")
|
|
)
|
|
inst_DQ_OUT
|
|
(
|
|
.arst(i_arst),
|
|
.d0(i_sdr_DATA_core[CYC_A*DQ_GROUP*DQ_WIDTH+:DQ_GROUP*DQ_WIDTH]),
|
|
.d1(i_sdr_DATA_core[CYC_B*DQ_GROUP*DQ_WIDTH+:DQ_GROUP*DQ_WIDTH]),
|
|
.c_x1(i_sysclk),
|
|
.c_x2(i_sdrclk),
|
|
.lock(r_pll_locked_1P),
|
|
.c(),
|
|
.q(o_sdr_DATA_pad[DQ_GROUP*DQ_WIDTH-1:0])
|
|
);
|
|
|
|
`IP_MODULE_NAME(sync_ddio_group_out)
|
|
#(
|
|
.DW(DQ_GROUP*DQ_WIDTH),
|
|
.INIT(1'b0),
|
|
.SYNC("RISING")
|
|
)
|
|
inst_DQ_oe
|
|
(
|
|
.arst(i_arst),
|
|
.d0(i_sdr_DATA_oe_core[CYC_A*DQ_GROUP*DQ_WIDTH+:DQ_GROUP*DQ_WIDTH]),
|
|
.d1(i_sdr_DATA_oe_core[CYC_B*DQ_GROUP*DQ_WIDTH+:DQ_GROUP*DQ_WIDTH]),
|
|
.c_x1(i_sysclk),
|
|
.c_x2(i_sdrclk),
|
|
.lock(r_pll_locked_1P),
|
|
.c(),
|
|
.q(o_sdr_DATA_oe_pad[DQ_GROUP*DQ_WIDTH-1:0])
|
|
);
|
|
|
|
`IP_MODULE_NAME(sync_ddio_group_in)
|
|
#(
|
|
.DW (DQ_GROUP*DQ_WIDTH),
|
|
.SYNC ("RISING")
|
|
)
|
|
inst_DQ_IN
|
|
(
|
|
.arst (i_arst),
|
|
.c_x1 (i_sysclk),
|
|
.c_x2 (i_tACclk),
|
|
.d (i_sdr_DATA_pad[DQ_GROUP*DQ_WIDTH-1:0]),
|
|
`ifdef RTL_SIM
|
|
.q0 (o_sdr_DATA_core[CYC_A*DQ_GROUP*DQ_WIDTH+:DQ_GROUP*DQ_WIDTH]), // simulation
|
|
.q1 (o_sdr_DATA_core[CYC_B*DQ_GROUP*DQ_WIDTH+:DQ_GROUP*DQ_WIDTH]) // simulation
|
|
`else
|
|
.q0 (w_sdr_DATA_core[CYC_A*DQ_GROUP*DQ_WIDTH+:DQ_GROUP*DQ_WIDTH]),
|
|
.q1 (w_sdr_DATA_core[CYC_B*DQ_GROUP*DQ_WIDTH+:DQ_GROUP*DQ_WIDTH])
|
|
`endif
|
|
);
|
|
|
|
`IP_MODULE_NAME(sync_ddio_group_out)
|
|
#(
|
|
.DW(DQ_GROUP),
|
|
.INIT(1'b0),
|
|
.SYNC("RISING")
|
|
)
|
|
inst_DQM
|
|
(
|
|
.arst(i_arst),
|
|
.d0(i_sdr_DQM_core[CYC_A*DQ_GROUP+:DQ_GROUP]),
|
|
.d1(i_sdr_DQM_core[CYC_B*DQ_GROUP+:DQ_GROUP]),
|
|
.c_x1(i_sysclk),
|
|
.c_x2(i_sdrclk),
|
|
.lock(r_pll_locked_1P),
|
|
.c(),
|
|
.q(o_sdr_DQM_pad[DQ_GROUP-1:0])
|
|
);
|
|
|
|
`ifndef RTL_SIM
|
|
// on board
|
|
always@(posedge i_arst or posedge i_sysclk)
|
|
begin
|
|
if (i_arst)
|
|
r_sdr_DATA_core_1P <= {DQ_GROUP*DQ_WIDTH{1'b0}};
|
|
else
|
|
r_sdr_DATA_core_1P <= w_sdr_DATA_core[CYC_B*DQ_GROUP*DQ_WIDTH+:DQ_GROUP*DQ_WIDTH];
|
|
end
|
|
assign o_sdr_DATA_core = { w_sdr_DATA_core[CYC_A*DQ_GROUP*DQ_WIDTH+:DQ_GROUP*DQ_WIDTH],
|
|
r_sdr_DATA_core_1P};
|
|
`endif
|
|
generate
|
|
for (rate=1; rate<DATA_RATE; rate=rate+1)
|
|
begin: cycle_mapping
|
|
assign o_sdr_CKE_pad[rate] = 1'b0;
|
|
assign o_sdr_n_CS_pad[rate] = 1'b0;
|
|
assign o_sdr_n_RAS_pad[rate] = 1'b0;
|
|
assign o_sdr_n_CAS_pad[rate] = 1'b0;
|
|
assign o_sdr_n_WE_pad[rate] = 1'b0;
|
|
assign o_sdr_BA_pad[rate*BA_WIDTH+:BA_WIDTH] = {BA_WIDTH{1'b0}};
|
|
assign o_sdr_ADDR_pad[rate*ROW_WIDTH+:ROW_WIDTH] = {ROW_WIDTH{1'b0}};
|
|
assign o_sdr_DATA_pad[rate*DQ_GROUP*DQ_WIDTH+:DQ_GROUP*DQ_WIDTH] = {DQ_GROUP*DQ_WIDTH{1'b0}};
|
|
assign o_sdr_DATA_oe_pad[rate*DQ_GROUP*DQ_WIDTH+:DQ_GROUP*DQ_WIDTH] = {DQ_GROUP*DQ_WIDTH{1'b0}};
|
|
assign o_sdr_DQM_pad[rate*DQ_GROUP+:DQ_GROUP] = {DQ_GROUP{1'b0}};
|
|
end
|
|
endgenerate
|
|
endmodule
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
// Copyright (C) 2013-2019 Efinix Inc. All rights reserved.
|
|
//
|
|
// This document contains proprietary information which is
|
|
// protected by copyright. All rights are reserved. This notice
|
|
// refers to original work by Efinix, Inc. which may be derivitive
|
|
// of other work distributed under license of the authors. In the
|
|
// case of derivative work, nothing in this notice overrides the
|
|
// original author's license agreement. Where applicable, the
|
|
// original license agreement is included in it's original
|
|
// unmodified form immediately below this header.
|
|
//
|
|
// WARRANTY DISCLAIMER.
|
|
// THE DESIGN, CODE, OR INFORMATION ARE PROVIDED “AS IS” AND
|
|
// EFINIX MAKES NO WARRANTIES, EXPRESS OR IMPLIED WITH
|
|
// RESPECT THERETO, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES,
|
|
// INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
|
// MERCHANTABILITY, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR
|
|
// PURPOSE. SOME STATES DO NOT ALLOW EXCLUSIONS OF AN IMPLIED
|
|
// WARRANTY, SO THIS DISCLAIMER MAY NOT APPLY TO LICENSEE.
|
|
//
|
|
// LIMITATION OF LIABILITY.
|
|
// NOTWITHSTANDING ANYTHING TO THE CONTRARY, EXCEPT FOR BODILY
|
|
// INJURY, EFINIX SHALL NOT BE LIABLE WITH RESPECT TO ANY SUBJECT
|
|
// MATTER OF THIS AGREEMENT UNDER TORT, CONTRACT, STRICT LIABILITY
|
|
// OR ANY OTHER LEGAL OR EQUITABLE THEORY (I) FOR ANY INDIRECT,
|
|
// SPECIAL, INCIDENTAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES OF ANY
|
|
// CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF
|
|
// GOODWILL, DATA OR PROFIT, WORK STOPPAGE, OR COMPUTER FAILURE OR
|
|
// MALFUNCTION, OR IN ANY EVENT (II) FOR ANY AMOUNT IN EXCESS, IN
|
|
// THE AGGREGATE, OF THE FEE PAID BY LICENSEE TO EFINIX HEREUNDER
|
|
// (OR, IF THE FEE HAS BEEN WAIVED, $100), EVEN IF EFINIX SHALL HAVE
|
|
// BEEN INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO
|
|
// NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR
|
|
// CONSEQUENTIAL DAMAGES, SO THIS LIMITATION AND EXCLUSION MAY NOT
|
|
// APPLY TO LICENSEE.
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
`define CLK_200
|
|
|
|
`define SYS_CLK_100
|
|
|
|
`define tPWRUP 200000
|
|
|
|
`define tRAS 44
|
|
|
|
`define tRAS_MAX 120000
|
|
|
|
`define tRC 66
|
|
|
|
`define tRCD 20
|
|
|
|
`define tREF 64000000
|
|
|
|
`define tRFC 66
|
|
|
|
`define tRP 20
|
|
|
|
`define tWR 2
|
|
|
|
`define tMRD 2
|
|
|
|
`define ba_width 2
|
|
|
|
`define row_width 13
|
|
|
|
`define col_width 10
|
|
|
|
`define dq_width 8
|
|
|
|
`define dq_group 2
|
|
|
|
`define fsys_mhz 100
|
|
|
|
`define fck_mhz 200
|
|
|
|
`define cl 3
|
|
|
|
`define bl 1
|
|
|
|
`define ddio_type "SOFT"
|
|
|
|
`define tIORT 2
|
|
|
|
`define SDRAM_MODE "AXI4" //"Native"
|
|
|
|
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// _____
|
|
// / _______ Copyright (C) 2013-2020 Efinix Inc. All rights reserved.
|
|
// / / \
|
|
// / / .. / simple_dual_port_ram.v
|
|
// / / .' /
|
|
// __/ /.' / Description:
|
|
// __ \ / simple dual port ram macro
|
|
// /_/ /\ \_____/ /
|
|
// ____/ \_______/
|
|
//
|
|
// *******************************
|
|
// Revisions:
|
|
// 1.0 Initial rev
|
|
//
|
|
// *******************************
|
|
|
|
module `IP_MODULE_NAME(sdram_simple_dual_port_ram)
|
|
#(
|
|
parameter DATA_WIDTH = 8,
|
|
parameter ADDR_WIDTH = 9,
|
|
parameter OUTPUT_REG = "TRUE",
|
|
parameter RAM_INIT_FILE = ""
|
|
)
|
|
(
|
|
input [(DATA_WIDTH-1):0] wdata,
|
|
input [(ADDR_WIDTH-1):0] waddr, raddr,
|
|
input we, wclk, re, rclk,
|
|
output [(DATA_WIDTH-1):0] rdata
|
|
);
|
|
|
|
localparam MEMORY_DEPTH = 2**ADDR_WIDTH;
|
|
localparam MAX_DATA = (1<<ADDR_WIDTH)-1;
|
|
|
|
reg [DATA_WIDTH-1:0] ram[MEMORY_DEPTH-1:0];
|
|
reg [DATA_WIDTH-1:0] r_rdata_1P;
|
|
reg [DATA_WIDTH-1:0] r_rdata_2P;
|
|
|
|
reg [DATA_WIDTH-1:0] i;
|
|
initial
|
|
begin
|
|
// By default the Efinix memory will initialize to 0
|
|
if (RAM_INIT_FILE != "")
|
|
begin
|
|
$readmemh(RAM_INIT_FILE, ram);
|
|
end
|
|
else
|
|
begin
|
|
for (i=0;i<=MEMORY_DEPTH-1;i=i+1)
|
|
ram[i] = i[DATA_WIDTH-1:0];
|
|
end
|
|
end
|
|
|
|
always @ (posedge wclk)
|
|
if (we)
|
|
ram[waddr] <= wdata;
|
|
|
|
always @ (posedge rclk)
|
|
begin
|
|
if (re)
|
|
r_rdata_1P <= ram[raddr];
|
|
r_rdata_2P <= r_rdata_1P;
|
|
end
|
|
|
|
generate
|
|
if (OUTPUT_REG == "TRUE")
|
|
assign rdata = r_rdata_2P;
|
|
else
|
|
assign rdata = r_rdata_1P;
|
|
endgenerate
|
|
|
|
endmodule
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
// Copyright (C) 2013-2019 Efinix Inc. All rights reserved.
|
|
//
|
|
// This document contains proprietary information which is
|
|
// protected by copyright. All rights are reserved. This notice
|
|
// refers to original work by Efinix, Inc. which may be derivitive
|
|
// of other work distributed under license of the authors. In the
|
|
// case of derivative work, nothing in this notice overrides the
|
|
// original author's license agreement. Where applicable, the
|
|
// original license agreement is included in it's original
|
|
// unmodified form immediately below this header.
|
|
//
|
|
// WARRANTY DISCLAIMER.
|
|
// THE DESIGN, CODE, OR INFORMATION ARE PROVIDED “AS IS” AND
|
|
// EFINIX MAKES NO WARRANTIES, EXPRESS OR IMPLIED WITH
|
|
// RESPECT THERETO, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES,
|
|
// INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
|
// MERCHANTABILITY, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR
|
|
// PURPOSE. SOME STATES DO NOT ALLOW EXCLUSIONS OF AN IMPLIED
|
|
// WARRANTY, SO THIS DISCLAIMER MAY NOT APPLY TO LICENSEE.
|
|
//
|
|
// LIMITATION OF LIABILITY.
|
|
// NOTWITHSTANDING ANYTHING TO THE CONTRARY, EXCEPT FOR BODILY
|
|
// INJURY, EFINIX SHALL NOT BE LIABLE WITH RESPECT TO ANY SUBJECT
|
|
// MATTER OF THIS AGREEMENT UNDER TORT, CONTRACT, STRICT LIABILITY
|
|
// OR ANY OTHER LEGAL OR EQUITABLE THEORY (I) FOR ANY INDIRECT,
|
|
// SPECIAL, INCIDENTAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES OF ANY
|
|
// CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF
|
|
// GOODWILL, DATA OR PROFIT, WORK STOPPAGE, OR COMPUTER FAILURE OR
|
|
// MALFUNCTION, OR IN ANY EVENT (II) FOR ANY AMOUNT IN EXCESS, IN
|
|
// THE AGGREGATE, OF THE FEE PAID BY LICENSEE TO EFINIX HEREUNDER
|
|
// (OR, IF THE FEE HAS BEEN WAIVED, $100), EVEN IF EFINIX SHALL HAVE
|
|
// BEEN INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO
|
|
// NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR
|
|
// CONSEQUENTIAL DAMAGES, SO THIS LIMITATION AND EXCLUSION MAY NOT
|
|
// APPLY TO LICENSEE.
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// _____
|
|
// / _______ Copyright (C) 2013-2020 Efinix Inc. All rights reserved.
|
|
// / / \
|
|
// / / .. / `IP_MODULE_NAME(sync_ddio_group_in).v
|
|
// / / .' /
|
|
// __/ /.' / Description:
|
|
// __ \ / soft DDIO input
|
|
// /_/ /\ \_____/ /
|
|
// ____/ \_______/
|
|
//
|
|
// *******************************
|
|
// Revisions:
|
|
// 1.0 Initial rev
|
|
//
|
|
// *******************************
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
module `IP_MODULE_NAME(sync_ddio_group_in)
|
|
#(
|
|
parameter DW = 1,
|
|
parameter SYNC = "RISING"
|
|
)
|
|
(
|
|
input arst,
|
|
input c_x1,
|
|
input c_x2,
|
|
input [DW-1:0]d,
|
|
output [DW-1:0]q0,
|
|
output [DW-1:0]q1
|
|
);
|
|
|
|
reg [DW-1:0]r_d_x2_1P;
|
|
reg [DW-1:0]r_d_x2_2P;
|
|
|
|
reg [DW-1:0]r_d0_x1_2P;
|
|
reg [DW-1:0]r_d1_x1_2P;
|
|
|
|
always@(posedge arst or posedge c_x2)
|
|
begin
|
|
if (arst)
|
|
begin
|
|
r_d_x2_1P <= {DW{1'b0}};
|
|
r_d_x2_2P <= {DW{1'b0}};
|
|
end
|
|
else
|
|
begin
|
|
r_d_x2_1P <= d;
|
|
r_d_x2_2P <= r_d_x2_1P;
|
|
end
|
|
end
|
|
|
|
always@(posedge arst or posedge c_x1)
|
|
begin
|
|
if (arst)
|
|
begin
|
|
r_d0_x1_2P <= {DW{1'b0}};
|
|
r_d1_x1_2P <= {DW{1'b0}};
|
|
end
|
|
else
|
|
begin
|
|
if (SYNC == "FALLING")
|
|
begin
|
|
r_d0_x1_2P <= r_d_x2_1P;
|
|
r_d1_x1_2P <= r_d_x2_2P;
|
|
end
|
|
else
|
|
begin
|
|
r_d0_x1_2P <= r_d_x2_2P;
|
|
r_d1_x1_2P <= r_d_x2_1P;
|
|
end
|
|
end
|
|
end
|
|
|
|
assign q0 = r_d0_x1_2P;
|
|
assign q1 = r_d1_x1_2P;
|
|
|
|
endmodule
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
// Copyright (C) 2013-2019 Efinix Inc. All rights reserved.
|
|
//
|
|
// This document contains proprietary information which is
|
|
// protected by copyright. All rights are reserved. This notice
|
|
// refers to original work by Efinix, Inc. which may be derivitive
|
|
// of other work distributed under license of the authors. In the
|
|
// case of derivative work, nothing in this notice overrides the
|
|
// original author's license agreement. Where applicable, the
|
|
// original license agreement is included in it's original
|
|
// unmodified form immediately below this header.
|
|
//
|
|
// WARRANTY DISCLAIMER.
|
|
// THE DESIGN, CODE, OR INFORMATION ARE PROVIDED “AS IS” AND
|
|
// EFINIX MAKES NO WARRANTIES, EXPRESS OR IMPLIED WITH
|
|
// RESPECT THERETO, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES,
|
|
// INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
|
// MERCHANTABILITY, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR
|
|
// PURPOSE. SOME STATES DO NOT ALLOW EXCLUSIONS OF AN IMPLIED
|
|
// WARRANTY, SO THIS DISCLAIMER MAY NOT APPLY TO LICENSEE.
|
|
//
|
|
// LIMITATION OF LIABILITY.
|
|
// NOTWITHSTANDING ANYTHING TO THE CONTRARY, EXCEPT FOR BODILY
|
|
// INJURY, EFINIX SHALL NOT BE LIABLE WITH RESPECT TO ANY SUBJECT
|
|
// MATTER OF THIS AGREEMENT UNDER TORT, CONTRACT, STRICT LIABILITY
|
|
// OR ANY OTHER LEGAL OR EQUITABLE THEORY (I) FOR ANY INDIRECT,
|
|
// SPECIAL, INCIDENTAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES OF ANY
|
|
// CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF
|
|
// GOODWILL, DATA OR PROFIT, WORK STOPPAGE, OR COMPUTER FAILURE OR
|
|
// MALFUNCTION, OR IN ANY EVENT (II) FOR ANY AMOUNT IN EXCESS, IN
|
|
// THE AGGREGATE, OF THE FEE PAID BY LICENSEE TO EFINIX HEREUNDER
|
|
// (OR, IF THE FEE HAS BEEN WAIVED, $100), EVEN IF EFINIX SHALL HAVE
|
|
// BEEN INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO
|
|
// NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR
|
|
// CONSEQUENTIAL DAMAGES, SO THIS LIMITATION AND EXCLUSION MAY NOT
|
|
// APPLY TO LICENSEE.
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// _____
|
|
// / _______ Copyright (C) 2013-2020 Efinix Inc. All rights reserved.
|
|
// / / \
|
|
// / / .. / `IP_MODULE_NAME(sync_ddio_group_out).v
|
|
// / / .' /
|
|
// __/ /.' / Description:
|
|
// __ \ / soft DDIO output
|
|
// /_/ /\ \_____/ /
|
|
// ____/ \_______/
|
|
//
|
|
// *******************************
|
|
// Revisions:
|
|
// 1.0 Initial rev
|
|
//
|
|
// *******************************
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
module `IP_MODULE_NAME(sync_ddio_group_out)
|
|
#(
|
|
parameter DW = 1,
|
|
parameter INIT = 1'b0,
|
|
parameter SYNC = "RISING"
|
|
)
|
|
(
|
|
input arst,
|
|
input [DW-1:0]d0,
|
|
input [DW-1:0]d1,
|
|
input c_x1,
|
|
input c_x2,
|
|
input lock,
|
|
output c,
|
|
output [DW-1:0]q
|
|
);
|
|
|
|
reg [DW-1:0]r_d0_x1_1P;
|
|
reg [DW-1:0]r_d1_x1_1P;
|
|
|
|
reg r_c_x2_1P;
|
|
reg r_s_x2_1P;
|
|
reg [DW-1:0]r_d_x2_2P;
|
|
|
|
wire w_c_rst;
|
|
|
|
generate
|
|
if (SYNC == "FALLING")
|
|
assign w_c_rst = 1'b1;
|
|
else
|
|
assign w_c_rst = 1'b0;
|
|
endgenerate
|
|
|
|
always@(posedge arst or posedge c_x1)
|
|
begin
|
|
if (arst)
|
|
begin
|
|
r_d0_x1_1P <= {DW{INIT}};
|
|
r_d1_x1_1P <= {DW{INIT}};
|
|
end
|
|
else if (lock)
|
|
begin
|
|
r_d0_x1_1P <= d0;
|
|
r_d1_x1_1P <= d1;
|
|
end
|
|
end
|
|
|
|
always@(posedge arst or posedge c_x2)
|
|
begin
|
|
if (arst)
|
|
begin
|
|
r_c_x2_1P <= w_c_rst;
|
|
r_s_x2_1P <= 1'b0;
|
|
r_d_x2_2P <= {DW{INIT}};
|
|
end
|
|
else if (lock)
|
|
begin
|
|
r_c_x2_1P <= ~r_c_x2_1P;
|
|
r_s_x2_1P <= ~r_s_x2_1P;
|
|
if (r_s_x2_1P)
|
|
r_d_x2_2P <= r_d1_x1_1P;
|
|
else
|
|
r_d_x2_2P <= r_d0_x1_1P;
|
|
end
|
|
end
|
|
|
|
assign c = r_c_x2_1P;
|
|
assign q = r_d_x2_2P;
|
|
|
|
endmodule
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
// Copyright (C) 2013-2019 Efinix Inc. All rights reserved.
|
|
//
|
|
// This document contains proprietary information which is
|
|
// protected by copyright. All rights are reserved. This notice
|
|
// refers to original work by Efinix, Inc. which may be derivitive
|
|
// of other work distributed under license of the authors. In the
|
|
// case of derivative work, nothing in this notice overrides the
|
|
// original author's license agreement. Where applicable, the
|
|
// original license agreement is included in it's original
|
|
// unmodified form immediately below this header.
|
|
//
|
|
// WARRANTY DISCLAIMER.
|
|
// THE DESIGN, CODE, OR INFORMATION ARE PROVIDED “AS IS” AND
|
|
// EFINIX MAKES NO WARRANTIES, EXPRESS OR IMPLIED WITH
|
|
// RESPECT THERETO, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES,
|
|
// INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
|
// MERCHANTABILITY, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR
|
|
// PURPOSE. SOME STATES DO NOT ALLOW EXCLUSIONS OF AN IMPLIED
|
|
// WARRANTY, SO THIS DISCLAIMER MAY NOT APPLY TO LICENSEE.
|
|
//
|
|
// LIMITATION OF LIABILITY.
|
|
// NOTWITHSTANDING ANYTHING TO THE CONTRARY, EXCEPT FOR BODILY
|
|
// INJURY, EFINIX SHALL NOT BE LIABLE WITH RESPECT TO ANY SUBJECT
|
|
// MATTER OF THIS AGREEMENT UNDER TORT, CONTRACT, STRICT LIABILITY
|
|
// OR ANY OTHER LEGAL OR EQUITABLE THEORY (I) FOR ANY INDIRECT,
|
|
// SPECIAL, INCIDENTAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES OF ANY
|
|
// CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF
|
|
// GOODWILL, DATA OR PROFIT, WORK STOPPAGE, OR COMPUTER FAILURE OR
|
|
// MALFUNCTION, OR IN ANY EVENT (II) FOR ANY AMOUNT IN EXCESS, IN
|
|
// THE AGGREGATE, OF THE FEE PAID BY LICENSEE TO EFINIX HEREUNDER
|
|
// (OR, IF THE FEE HAS BEEN WAIVED, $100), EVEN IF EFINIX SHALL HAVE
|
|
// BEEN INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO
|
|
// NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR
|
|
// CONSEQUENTIAL DAMAGES, SO THIS LIMITATION AND EXCLUSION MAY NOT
|
|
// APPLY TO LICENSEE.
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
`undef IP_UUID
|
|
`undef IP_NAME_CONCAT
|
|
`undef IP_MODULE_NAME
|