Files
super6502/hw/efinix_fpga/ip/sdram/sdram.v
Byron Lathi fcae23785e Throw everything up
I think that previously, I had not actually commited any of this to git.
This adds all of the new effinix stuff that I had been working on for
months.

The gist of all of this is that the intel fpga is expensive and does not
exist, whereas the effinix ones are not as expensive and more existant.
This redoes the project to use the dev board, as well as a custom board
that I may or may not make.
2022-10-04 17:15:49 -05:00

4237 lines
118 KiB
Verilog

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