Files
super6502/hw/efinix_fpga/ip/sdram_controller/sdram_controller.v
2022-12-22 20:25:32 -05:00

4262 lines
119 KiB
Verilog

// =============================================================================
// Generated by efx_ipmgr
// Version: 2022.1.226
// IP Version: 1.6
// =============================================================================
////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2013-2022 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 _1a076fc510c34dc9a60c0ede33930d9f
`define IP_NAME_CONCAT(a,b) a``b
`define IP_MODULE_NAME(name) `IP_NAME_CONCAT(name,`IP_UUID)
module sdram_controller (
input i_we,
input i_sysclk,
input i_arst,
input i_sdrclk,
input i_tACclk,
input i_pll_locked,
input i_re,
input i_last,
output o_dbg_tRTW_done,
output o_dbg_ref_req,
output o_dbg_wr_ack,
output o_dbg_rd_ack,
output [1:0] o_dbg_n_CS,
output [1:0] o_dbg_n_RAS,
output [1:0] o_dbg_n_CAS,
output [1:0] o_dbg_n_WE,
output [3:0] o_dbg_BA,
output [25:0] o_dbg_ADDR,
output [31:0] o_dbg_DATA_out,
output [31:0] o_dbg_DATA_in,
input [23:0] i_addr,
input [31:0] i_din,
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,
output [5:0] o_dbg_dly_cnt_b,
output o_dbg_tRCD_done
);
`IP_MODULE_NAME(efx_sdram_controller) #(
.fSYS_MHz (100),
.fCK_MHz (200),
.tIORT_u (2),
.BL (1),
.DDIO_TYPE ("SOFT"),
.DQ_WIDTH (8),
.DQ_GROUP (2),
.BA_WIDTH (2),
.ROW_WIDTH (13),
.COL_WIDTH (9),
.tPWRUP (200000),
.tRAS (44),
.tRC (66),
.tRCD (20),
.tREF (64000000),
.tWR (2),
.tMRD (2),
.tRFC (66),
.tRAS_MAX (120000),
.DATA_RATE (2),
.AXI_ARADDR_WIDTH (24),
.SDRAM_MODE ("Native"),
.AXI_BUSER_WIDTH (2),
.AXI_BID_WIDTH (4),
.AXI_AWUSER_WIDTH (2),
.AXI_AWID_WIDTH (4),
.AXI_AWADDR_WIDTH (24),
.AXI_RDATA_WIDTH (32),
.AXI_WUSER_WIDTH (2),
.AXI_WDATA_WIDTH (32),
.AXI_RUSER_WIDTH (3),
.AXI_ARUSER_WIDTH (3),
.AXI_ARID_WIDTH (4),
.tRP (20),
.CL (3)
) u_efx_sdram_controller(
.i_we ( i_we ),
.i_sysclk ( i_sysclk ),
.i_arst ( i_arst ),
.i_sdrclk ( i_sdrclk ),
.i_tACclk ( i_tACclk ),
.i_pll_locked ( i_pll_locked ),
.i_re ( i_re ),
.i_last ( i_last ),
.o_dbg_tRTW_done ( o_dbg_tRTW_done ),
.o_dbg_ref_req ( o_dbg_ref_req ),
.o_dbg_wr_ack ( o_dbg_wr_ack ),
.o_dbg_rd_ack ( o_dbg_rd_ack ),
.o_dbg_n_CS ( o_dbg_n_CS ),
.o_dbg_n_RAS ( o_dbg_n_RAS ),
.o_dbg_n_CAS ( o_dbg_n_CAS ),
.o_dbg_n_WE ( o_dbg_n_WE ),
.o_dbg_BA ( o_dbg_BA ),
.o_dbg_ADDR ( o_dbg_ADDR ),
.o_dbg_DATA_out ( o_dbg_DATA_out ),
.o_dbg_DATA_in ( o_dbg_DATA_in ),
.i_addr ( i_addr ),
.i_din ( i_din ),
.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 )
);
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