blob: c845d023a142a83d281d2ac4e0df011fa2360f53 [file] [log] [blame]
//////////////////////////////////////////////////////////////////////////////
// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
//
/*********************************************************************
SDRAM Controller top File
This file is part of the sdram controller project
https://github.com/dineshannayya/yifive_r0.git
http://www.opencores.org/cores/yifive/
http://www.opencores.org/cores/sdr_ctrl/
Description: SDRAM Controller Top Module.
Support 81/6/32 Bit SDRAM.
Column Address is Programmable
Bank Bit are 2 Bit
Row Bits are 12 Bits
This block integrate following sub modules
sdrc_core
SDRAM Controller file
wb2sdrc
This module transalate the bus protocl from wishbone to custome
sdram controller
To Do:
nothing
Author(s): Dinesh Annayya, dinesha@opencores.org
Version : 0.0 - 8th Jan 2012
Initial version with 16/32 Bit SDRAM Support
: 0.1 - 24th Jan 2012
8 Bit SDRAM Support is added
0.2 - 31st Jan 2012
sdram_dq and sdram_pad_clk are internally generated
0.3 - 26th April 2013
Sdram Address witdh is increased from 12 to 13bits
0.3 - 25th June 2021
Move the Pad logic inside the sdram to avoid combo logic
at digital core level
0.4 - 27th June 2021
Unused port wb_cti_i removed
0.5 - 29th June 2021
Wishbone Stagging FF added to break timing path
0.6 - 6th July 2021, Dinesh A
32 bit debug port added
Copyright (C) 2000 Authors and OPENCORES.ORG
This source file may be used and distributed without
restriction provided that this copyright statement is not
removed from the file and that any derivative work contains
the original copyright notice and the associated disclaimer.
This source file is free software; you can redistribute it
and/or modify it under the terms of the GNU Lesser General
Public License as published by the Free Software Foundation;
either version 2.1 of the License, or (at your option) any
later version.
This source is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the GNU Lesser General Public License for more
details.
You should have received a copy of the GNU Lesser General
Public License along with this source; if not, download it
from http://www.opencores.org/lgpl.shtml
*******************************************************************/
`include "sdrc_define.v"
module sdrc_top
(
cfg_sdr_width ,
cfg_colbits ,
sdram_debug ,
// WB bus
wb_rst_n ,
wb_clk_i ,
wb_stb_i ,
wb_ack_o ,
wb_addr_i ,
wb_we_i ,
wb_dat_i ,
wb_sel_i ,
wb_dat_o ,
wb_cyc_i ,
/* Interface to SDRAMs */
sdram_clk ,
sdram_resetn ,
/** Pad Interface **/
io_in ,
io_oeb ,
io_out ,
/* Parameters */
sdr_init_done ,
cfg_req_depth , //how many req. buffer should hold
cfg_sdr_en ,
cfg_sdr_mode_reg ,
cfg_sdr_tras_d ,
cfg_sdr_trp_d ,
cfg_sdr_trcd_d ,
cfg_sdr_cas ,
cfg_sdr_trcar_d ,
cfg_sdr_twr_d ,
cfg_sdr_rfsh ,
cfg_sdr_rfmax
);
parameter APP_AW = 32; // Application Address Width
parameter APP_DW = 32; // Application Data Width
parameter APP_BW = 4; // Application Byte Width
parameter APP_RW = 9; // Application Request Width
parameter SDR_DW = 8; // SDR Data Width
parameter SDR_BW = 1; // SDR Byte Width
parameter tw = 8; // tag id width
parameter bl = 9; // burst_lenght_width
//-----------------------------------------------
// Global Variable
// ----------------------------------------------
input sdram_clk ; // SDRAM Clock
input sdram_resetn ; // Reset Signal
input [1:0] cfg_sdr_width ; // 2'b00 - 32 Bit SDR, 2'b01 - 16 Bit SDR, 2'b1x - 8 Bit
input [1:0] cfg_colbits ; // 2'b00 - 8 Bit column address,
// 2'b01 - 9 Bit, 10 - 10 bit, 11 - 11Bits
output [31:0] sdram_debug ; // SDRAM debug signals
//--------------------------------------
// Wish Bone Interface
// -------------------------------------
input wb_rst_n ;
input wb_clk_i ;
input wb_stb_i ;
output wb_ack_o ;
input [APP_AW-1:0] wb_addr_i ;
input wb_we_i ; // 1 - Write, 0 - Read
input [APP_DW-1:0] wb_dat_i ;
input [APP_DW/8-1:0] wb_sel_i ; // Byte enable
output [APP_DW-1:0] wb_dat_o ;
input wb_cyc_i ;
//--------------------------------------
// Pad Interface
// -------------------------------------
input [29:0] io_in ;
output [29:0] io_oeb ;
output [29:0] io_out ;
//------------------------------------------------
// Interface to SDRAMs
//------------------------------------------------
wire sdram_pad_clk ; // Sdram clock loop back from pad
wire sdr_cke ; // SDRAM CKE
wire sdr_cs_n ; // SDRAM Chip Select
wire sdr_ras_n ; // SDRAM ras
wire sdr_cas_n ; // SDRAM cas
wire sdr_we_n ; // SDRAM write enable
wire [SDR_BW-1:0] sdr_dqm ; // SDRAM Data Mask
wire [1:0] sdr_ba ; // SDRAM Bank Enable
wire [12:0] sdr_addr ; // SDRAM Address
wire [SDR_DW-1:0] pad_sdr_din ; // SDRA Data Input
wire [SDR_DW-1:0] sdr_dout ; // SDRAM Data Output
wire [SDR_BW-1:0] sdr_den_n ; // SDRAM Data Output enable
//------------------------------------------------
// Configuration Parameter
//------------------------------------------------
output sdr_init_done ; // Indicate SDRAM Initialisation Done
input [3:0] cfg_sdr_tras_d ; // Active to precharge delay
input [3:0] cfg_sdr_trp_d ; // Precharge to active delay
input [3:0] cfg_sdr_trcd_d ; // Active to R/W delay
input cfg_sdr_en ; // Enable SDRAM controller
input [1:0] cfg_req_depth ; // Maximum Request accepted by SDRAM controller
input [12:0] cfg_sdr_mode_reg ;
input [2:0] cfg_sdr_cas ; // SDRAM CAS Latency
input [3:0] cfg_sdr_trcar_d ; // Auto-refresh period
input [3:0] cfg_sdr_twr_d ; // Write recovery delay
input [`SDR_RFSH_TIMER_W-1 : 0] cfg_sdr_rfsh;
input [`SDR_RFSH_ROW_CNT_W -1 : 0] cfg_sdr_rfmax;
//--------------------------------------------
// SDRAM controller Interface
//--------------------------------------------
wire app_req ; // SDRAM request
wire [APP_AW-1:0] app_req_addr ; // SDRAM Request Address
wire [bl-1:0] app_req_len ;
wire app_req_wr_n ; // 0 - Write, 1 -> Read
wire app_req_ack ; // SDRAM request Accepted
wire app_busy_n ; // 0 -> sdr busy
wire [APP_DW/8-1:0] app_wr_en_n ; // Active low sdr byte-wise write data valid
wire app_wr_next_req ; // Ready to accept the next write
wire app_rd_valid ; // sdr read valid
wire app_last_rd ; // Indicate last Read of Burst Transfer
wire app_last_wr ; // Indicate last Write of Burst Transfer
wire [APP_DW-1:0] app_wr_data ; // sdr write data
wire [APP_DW-1:0] app_rd_data ; // sdr read data
//--------------------------------------------------
// WishBone Stagging FF
//--------------------------------------------------
wire wb_stag_stb_i ;
wire wb_stag_ack_o ;
wire [APP_AW-1:0] wb_stag_addr_i ;
wire wb_stag_we_i ; // 1 - Write, 0 - Read
wire [APP_DW-1:0] wb_stag_dat_i ;
wire [APP_DW/8-1:0] wb_stag_sel_i ; // Byte enable
wire [APP_DW-1:0] wb_stag_dat_o ;
wire wb_stag_cyc_i ;
//-----------------------------------------------------------------
// To avoid the logic at digital core, pad control are brought inside the
// block to support efabless/carvel soc enviornmental support
// -----------------------------------------------------------------
assign pad_sdr_din[7:0] = io_in[7:0] ;
assign io_out [7:0] = sdr_dout[7:0] ;
assign io_out [20:8] = sdr_addr[12:0] ;
assign io_out [22:21] = sdr_ba[1:0] ;
assign io_out [23] = sdr_dqm[0] ;
assign io_out [24] = sdr_we_n ;
assign io_out [25] = sdr_cas_n ;
assign io_out [26] = sdr_ras_n ;
assign io_out [27] = sdr_cs_n ;
assign io_out [28] = sdr_cke ;
assign io_out [29] = sdram_clk ;
assign sdram_pad_clk = io_in[29] ;
assign io_oeb [7:0] = sdr_den_n ;
assign io_oeb [20:8] = {(13) {1'b0}} ;
assign io_oeb [22:21] = {(2) {1'b0}} ;
assign io_oeb [23] = 1'b0 ;
assign io_oeb [24] = 1'b0 ;
assign io_oeb [25] = 1'b0 ;
assign io_oeb [26] = 1'b0 ;
assign io_oeb [27] = 1'b0 ;
assign io_oeb [28] = 1'b0 ;
assign io_oeb [29] = 1'b0 ;
//assign sdr_dq = (&sdr_den_n == 1'b0) ? sdr_dout : {SDR_DW{1'bz}};
//assign pad_sdr_din = sdr_dq;
// sdram pad clock is routed back through pad
// SDRAM Clock from Pad, used for registering Read Data
//wire #(1.0) sdram_pad_clk = sdram_clk;
//
wire [21:0] core_debug;
assign sdram_debug = {sdr_init_done,wb_stag_stb_i,wb_stag_we_i,wb_stag_ack_o,
app_req,app_req_wr_n,app_req_ack,app_busy_n,app_wr_next_req, app_rd_valid,
core_debug[21:0]};
/************** Ends Here **************************/
// Adding Wishbone stagging FF to break timing path
//
wb_stagging u_wb_stage (
.clk_i (wb_clk_i ),
.rst_n (wb_rst_n ),
// WishBone Input master I/P
.m_wbd_dat_i (wb_dat_i ),
.m_wbd_adr_i (wb_addr_i ),
.m_wbd_sel_i (wb_sel_i ),
.m_wbd_we_i (wb_we_i ),
.m_wbd_cyc_i (wb_cyc_i ),
.m_wbd_stb_i (wb_stb_i ),
.m_wbd_tid_i ('h0 ),
.m_wbd_dat_o (wb_dat_o ),
.m_wbd_ack_o (wb_ack_o ),
.m_wbd_err_o ( ),
// Slave Interface
.s_wbd_dat_i (wb_stag_dat_o ),
.s_wbd_ack_i (wb_stag_ack_o ),
.s_wbd_err_i (1'b0 ),
.s_wbd_dat_o (wb_stag_dat_i ),
.s_wbd_adr_o (wb_stag_addr_i ),
.s_wbd_sel_o (wb_stag_sel_i ),
.s_wbd_we_o (wb_stag_we_i ),
.s_wbd_cyc_o (wb_stag_cyc_i ),
.s_wbd_stb_o (wb_stag_stb_i ),
.s_wbd_tid_o ( )
);
wb2sdrc #(.dw(APP_DW),.tw(tw),.bl(bl),.APP_AW(APP_AW)) u_wb2sdrc (
// WB bus
.wb_rst_n (wb_rst_n ) ,
.wb_clk_i (wb_clk_i ) ,
.wb_stb_i (wb_stag_stb_i ) ,
.wb_ack_o (wb_stag_ack_o ) ,
.wb_addr_i (wb_stag_addr_i ) ,
.wb_we_i (wb_stag_we_i ) ,
.wb_dat_i (wb_stag_dat_i ) ,
.wb_sel_i (wb_stag_sel_i ) ,
.wb_dat_o (wb_stag_dat_o ) ,
.wb_cyc_i (wb_stag_cyc_i ) ,
//SDRAM Controller Hand-Shake Signal
.sdram_clk (sdram_clk ) ,
.sdram_resetn (sdram_resetn ) ,
.sdr_req (app_req ) ,
.sdr_req_addr (app_req_addr ) ,
.sdr_req_len (app_req_len ) ,
.sdr_req_wr_n (app_req_wr_n ) ,
.sdr_req_ack (app_req_ack ) ,
.sdr_busy_n (app_busy_n ) ,
.sdr_wr_en_n (app_wr_en_n ) ,
.sdr_wr_next (app_wr_next_req ) ,
.sdr_rd_valid (app_rd_valid ) ,
.sdr_last_rd (app_last_rd ) ,
.sdr_wr_data (app_wr_data ) ,
.sdr_rd_data (app_rd_data )
);
sdrc_core #(.SDR_DW(SDR_DW) , .SDR_BW(SDR_BW),.APP_AW(APP_AW)) u_sdrc_core (
.clk (sdram_clk ) ,
.pad_clk (sdram_pad_clk ) ,
.reset_n (sdram_resetn ) ,
.sdr_width (cfg_sdr_width ) ,
.cfg_colbits (cfg_colbits ) ,
.debug (core_debug ) ,
/* Request from app */
.app_req (app_req ) ,// Transfer Request
.app_req_addr (app_req_addr ) ,// SDRAM Address
.app_req_len (app_req_len ) ,// Burst Length (in 16 bit words)
.app_req_wrap (1'b0 ) ,// Wrap mode request
.app_req_wr_n (app_req_wr_n ) ,// 0 => Write request, 1 => read req
.app_req_ack (app_req_ack ) ,// Request has been accepted
.cfg_req_depth (cfg_req_depth ) ,//how many req. buffer should hold
.app_wr_data (app_wr_data ) ,
.app_wr_en_n (app_wr_en_n ) ,
.app_rd_data (app_rd_data ) ,
.app_rd_valid (app_rd_valid ) ,
.app_last_rd (app_last_rd ) ,
.app_last_wr (app_last_wr ) ,
.app_wr_next_req (app_wr_next_req ) ,
.sdr_init_done (sdr_init_done ) ,
.app_req_dma_last (app_req ) ,
/* Interface to SDRAMs */
.sdr_cs_n (sdr_cs_n ) ,
.sdr_cke (sdr_cke ) ,
.sdr_ras_n (sdr_ras_n ) ,
.sdr_cas_n (sdr_cas_n ) ,
.sdr_we_n (sdr_we_n ) ,
.sdr_dqm (sdr_dqm ) ,
.sdr_ba (sdr_ba ) ,
.sdr_addr (sdr_addr ) ,
.pad_sdr_din (pad_sdr_din ) ,
.sdr_dout (sdr_dout ) ,
.sdr_den_n (sdr_den_n ) ,
/* Parameters */
.cfg_sdr_en (cfg_sdr_en ) ,
.cfg_sdr_mode_reg (cfg_sdr_mode_reg ) ,
.cfg_sdr_tras_d (cfg_sdr_tras_d ) ,
.cfg_sdr_trp_d (cfg_sdr_trp_d ) ,
.cfg_sdr_trcd_d (cfg_sdr_trcd_d ) ,
.cfg_sdr_cas (cfg_sdr_cas ) ,
.cfg_sdr_trcar_d (cfg_sdr_trcar_d ) ,
.cfg_sdr_twr_d (cfg_sdr_twr_d ) ,
.cfg_sdr_rfsh (cfg_sdr_rfsh ) ,
.cfg_sdr_rfmax (cfg_sdr_rfmax )
);
endmodule // sdrc_core