4348 lines
121 KiB
Verilog
4348 lines
121 KiB
Verilog
// =============================================================================
|
|
// Generated by efx_ipmgr
|
|
// Version: 2023.1.150
|
|
// IP Version: 5.0
|
|
// =============================================================================
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// Copyright (C) 2013-2023 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 _5c381f4179ce404bb3abce25f7e88ca9
|
|
`define IP_NAME_CONCAT(a,b) a``b
|
|
`define IP_MODULE_NAME(name) `IP_NAME_CONCAT(name,`IP_UUID)
|
|
module sdram_controller (
|
|
input i_aresetn,
|
|
input [23:0] i_AXI4_AWADDR,
|
|
input i_sysclk,
|
|
input i_sdrclk,
|
|
input i_tACclk,
|
|
input i_pll_locked,
|
|
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,
|
|
output o_pll_reset,
|
|
output o_AXI4_AWREADY,
|
|
input i_AXI4_AWVALID,
|
|
output o_AXI4_WREADY,
|
|
input [31:0] i_AXI4_WDATA,
|
|
input [3:0] i_AXI4_WSTRB,
|
|
input i_AXI4_WLAST,
|
|
input i_AXI4_WVALID,
|
|
output o_AXI4_BVALID,
|
|
input i_AXI4_BREADY,
|
|
output o_AXI4_ARREADY,
|
|
input [23:0] i_AXI4_ARADDR,
|
|
input i_AXI4_RREADY,
|
|
output [31:0] o_AXI4_RDATA,
|
|
output o_AXI4_RLAST,
|
|
output o_AXI4_RVALID,
|
|
input [3:0] i_AXI4_AWID,
|
|
input [2:0] i_AXI4_AWSIZE,
|
|
input i_AXI4_ARVALID,
|
|
input [3:0] i_AXI4_ARID,
|
|
input [7:0] i_AXI4_ARLEN,
|
|
input [2:0] i_AXI4_ARSIZE,
|
|
input [1:0] i_AXI4_ARBURST,
|
|
input [7:0] i_AXI4_AWLEN,
|
|
output [3:0] o_AXI4_RID,
|
|
output o_dbg_we,
|
|
output o_dbg_last,
|
|
output [23:0] o_dbg_addr,
|
|
output [31:0] o_dbg_din,
|
|
output [1:0] o_axi4_wrstate,
|
|
output o_fifo_wr,
|
|
output o_fifo_full,
|
|
output o_fifo_empty,
|
|
output [7:0] o_dbg_fifo_waddr,
|
|
output o_dbg_fifo_re,
|
|
output [7:0] o_dbg_fifo_raddr,
|
|
output o_dbg_fifo_we,
|
|
output o_dbg_axi4_wlast,
|
|
output [6:0] o_shift_cnt,
|
|
output o_re_lock,
|
|
output [1:0] o_axi4_rastate,
|
|
output o_axi4_nwr,
|
|
output [7:0] o_axi4_arlen,
|
|
output [1:0] o_axi4_rdstate,
|
|
output o_sdr_rd_valid,
|
|
output [36:0] o_sdr_dout,
|
|
output o_dbg_re,
|
|
output [3:0] o_AXI4_BID,
|
|
input [23:0] i_addr,
|
|
input [31:0] i_din,
|
|
input [3:0] i_dm,
|
|
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
|
|
);
|
|
`IP_MODULE_NAME(efx_sdram_controller) #(
|
|
.fSYS_MHz (100),
|
|
.fCK_MHz (200),
|
|
.tIORT_u (2),
|
|
.CL (3),
|
|
.BL (1),
|
|
.DDIO_TYPE ("SOFT"),
|
|
.DQ_WIDTH (8),
|
|
.DQ_GROUP (2),
|
|
.BA_WIDTH (2),
|
|
.ROW_WIDTH (13),
|
|
.COL_WIDTH (9),
|
|
.tPWRUP (200000),
|
|
.tRAS (44),
|
|
.tRAS_MAX (120000),
|
|
.tRC (66),
|
|
.tRCD (20),
|
|
.tREF (64000000),
|
|
.tRFC (66),
|
|
.tRP (20),
|
|
.tWR (2),
|
|
.tMRD (2),
|
|
.SDRAM_MODE ("AXI4"),
|
|
.DATA_RATE (2),
|
|
.AXI_AWADDR_WIDTH (24),
|
|
.AXI_WDATA_WIDTH (32),
|
|
.AXI_ARADDR_WIDTH (24),
|
|
.AXI_RDATA_WIDTH (32),
|
|
.AXI_AWID_WIDTH (4),
|
|
.AXI_AWUSER_WIDTH (2),
|
|
.AXI_WUSER_WIDTH (2),
|
|
.AXI_BID_WIDTH (4),
|
|
.AXI_BUSER_WIDTH (2),
|
|
.AXI_ARID_WIDTH (4),
|
|
.AXI_ARUSER_WIDTH (3),
|
|
.AXI_RUSER_WIDTH (3)
|
|
) u_efx_sdram_controller(
|
|
.i_aresetn ( i_aresetn ),
|
|
.i_AXI4_AWADDR ( i_AXI4_AWADDR ),
|
|
.i_sysclk ( i_sysclk ),
|
|
.i_sdrclk ( i_sdrclk ),
|
|
.i_tACclk ( i_tACclk ),
|
|
.i_pll_locked ( i_pll_locked ),
|
|
.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 ),
|
|
.o_pll_reset ( o_pll_reset ),
|
|
.o_AXI4_AWREADY ( o_AXI4_AWREADY ),
|
|
.i_AXI4_AWVALID ( i_AXI4_AWVALID ),
|
|
.o_AXI4_WREADY ( o_AXI4_WREADY ),
|
|
.i_AXI4_WDATA ( i_AXI4_WDATA ),
|
|
.i_AXI4_WSTRB ( i_AXI4_WSTRB ),
|
|
.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_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_AWSIZE ( i_AXI4_AWSIZE ),
|
|
.i_AXI4_ARVALID ( i_AXI4_ARVALID ),
|
|
.i_AXI4_ARID ( i_AXI4_ARID ),
|
|
.i_AXI4_ARLEN ( i_AXI4_ARLEN ),
|
|
.i_AXI4_ARSIZE ( i_AXI4_ARSIZE ),
|
|
.i_AXI4_ARBURST ( i_AXI4_ARBURST ),
|
|
.i_AXI4_AWLEN ( i_AXI4_AWLEN ),
|
|
.o_AXI4_RID ( o_AXI4_RID ),
|
|
.o_dbg_we ( o_dbg_we ),
|
|
.o_dbg_last ( o_dbg_last ),
|
|
.o_dbg_addr ( o_dbg_addr ),
|
|
.o_dbg_din ( o_dbg_din ),
|
|
.o_axi4_wrstate ( o_axi4_wrstate ),
|
|
.o_fifo_wr ( o_fifo_wr ),
|
|
.o_fifo_full ( o_fifo_full ),
|
|
.o_fifo_empty ( o_fifo_empty ),
|
|
.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_fifo_we ( o_dbg_fifo_we ),
|
|
.o_dbg_axi4_wlast ( o_dbg_axi4_wlast ),
|
|
.o_shift_cnt ( o_shift_cnt ),
|
|
.o_re_lock ( o_re_lock ),
|
|
.o_axi4_rastate ( o_axi4_rastate ),
|
|
.o_axi4_nwr ( o_axi4_nwr ),
|
|
.o_axi4_arlen ( o_axi4_arlen ),
|
|
.o_axi4_rdstate ( o_axi4_rdstate ),
|
|
.o_sdr_rd_valid ( o_sdr_rd_valid ),
|
|
.o_sdr_dout ( o_sdr_dout ),
|
|
.o_dbg_re ( o_dbg_re ),
|
|
.o_AXI4_BID ( o_AXI4_BID ),
|
|
.i_addr ( i_addr ),
|
|
.i_din ( i_din ),
|
|
.i_dm ( i_dm ),
|
|
.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 )
|
|
);
|
|
|
|
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/8-1:0]i_AXI4_WSTRB,
|
|
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_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 = 1; //(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 [DIN_WIDTH/8-1:0]r_dm_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 [8:0]arlen_cnt;
|
|
|
|
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 rd_last;
|
|
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]),
|
|
.i_dm (r_dm_1P[(SDR_BWIDTH/8)-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_dm_1P <= {DIN_WIDTH/8{1'b0}};
|
|
r_size_1P <= {7{1'b0}};
|
|
r_shift_cnt_1P <= {7{1'b0}};
|
|
arlen_cnt <= {9{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 <= {{(DATA_RATE-1){1'b0}},i_AXI4_AWADDR[BA_WIDTH+ROW_WIDTH+COL_WIDTH-1:DATA_RATE-1]};
|
|
// $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_dm_1P <= i_AXI4_WSTRB ^ {(AXI_WDATA_WIDTH/8){1'b1}}; //bitwise XOR to inver the bit
|
|
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)
|
|
begin
|
|
r_din_1P <= i_AXI4_WDATA;
|
|
r_dm_1P <= i_AXI4_WSTRB ^ {(AXI_WDATA_WIDTH/8){1'b1}}; //bitwise XOR to inver the bit;
|
|
end
|
|
|
|
if (~r_AXI4_WREADY_c & r_AXI4_WREADY_2P & i_AXI4_WLAST)
|
|
begin
|
|
r_din_1P <= i_AXI4_WDATA;
|
|
r_dm_1P <= i_AXI4_WSTRB ^ {(AXI_WDATA_WIDTH/8){1'b1}}; //bitwise XOR to inver the bit;
|
|
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 <= {{(DATA_RATE-1){1'b0}},i_AXI4_ARADDR[BA_WIDTH+ROW_WIDTH+COL_WIDTH-1:DATA_RATE-1]};
|
|
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 (arlen_cnt == r_AXI4_ARLEN_1P) begin
|
|
arlen_cnt <= {9{1'b0}};
|
|
end
|
|
else begin
|
|
arlen_cnt <= arlen_cnt+1'b1;
|
|
end
|
|
|
|
if (arlen_cnt == r_AXI4_ARLEN_1P)
|
|
r_dout_1P[DOUT_WIDTH+AXI_ARID_WIDTH] <= 1'b1;
|
|
else
|
|
r_dout_1P[DOUT_WIDTH+AXI_ARID_WIDTH] <= 1'b0;
|
|
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 (rd_last)
|
|
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 rd_last = r_AXI4_RVALID_1P ? w_fifo_dout[AXI_RDATA_WIDTH+AXI_ARID_WIDTH] : 1'b0;
|
|
|
|
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 = rd_last;
|
|
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,
|
|
i_dm,
|
|
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 = 25;
|
|
parameter AXI_WDATA_WIDTH = 64;
|
|
parameter AXI_ARADDR_WIDTH = 25;
|
|
parameter AXI_RDATA_WIDTH = 64;
|
|
|
|
parameter fSYS_MHz = 100;
|
|
parameter fCK_MHz = 200;
|
|
parameter DATA_RATE = 2;
|
|
parameter DDIO_TYPE = "SOFT";
|
|
parameter tPWRUP = 200000; // 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 = 64000000; // 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 = 13;
|
|
parameter COL_WIDTH = 10;
|
|
parameter DQ_WIDTH = 8; // x4; x8
|
|
parameter DQ_GROUP = 4;
|
|
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 = 3;
|
|
parameter AXI_RUSER_WIDTH = 3;
|
|
|
|
//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;
|
|
input [(DATA_RATE *DQ_GROUP *DQ_WIDTH)/8 -1:0] i_dm;
|
|
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),
|
|
.i_dm (i_dm),
|
|
.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,
|
|
input [(DATA_RATE *DQ_GROUP) -1:0] i_dm,
|
|
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),
|
|
.i_dm (i_dm),
|
|
.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,
|
|
input [(DATA_RATE *DQ_GROUP) -1:0] i_dm,
|
|
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 *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_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_dm_1P <= {DATA_RATE *DQ_GROUP {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_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_dm_1P <= i_dm;
|
|
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[1] || r_tRAS_MAX_done_1P[1] || (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
|
|
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[1] || r_tRAS_MAX_done_1P[1] || (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
|
|
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_DQM = r_sdr_dm_1P;
|
|
assign o_sdr_DATA_oe = r_sdr_dqoe_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
|