URL
https://opencores.org/ocsvn/sdr_ctrl/sdr_ctrl/trunk
Subversion Repositories sdr_ctrl
Compare Revisions
- This comparison shows the changes necessary to convert path
/sdr_ctrl/trunk
- from Rev 2 to Rev 3
- ↔ Reverse comparison
Rev 2 → Rev 3
/rtl/core/sdrc_req_gen.v
0,0 → 1,275
/********************************************************************* |
|
SDRAM Controller Request Generation |
|
This file is part of the sdram controller project |
http://www.opencores.org/cores/sdr_ctrl/ |
|
Description: SDRAM Controller Reguest Generation |
The 2Mx32 SDRAM is addressed by a 21 bit address, |
each loation is 32 bits wide. |
This 21 bit address is mapped as follows: |
ADDR [7:0] : Column Address (256 columns) |
ADDR [18:8] : Row Address (2K Rows) |
ADDR [20:19] : Bank Address (2 banks) |
|
The 4Mx16 SDRAM is addressed by a 22 bit address, |
each loation is 16 bits wide. |
This 22 bit address is mapped as follows: |
ADDR [7:0] : Column Address (256 columns) |
ADDR [21:10] : Row Address (4K Rows) |
ADDR [21:20] : Bank Address (4 banks) |
|
The 8Mx16 SDRAM is addressed by a 23 bit address, |
each loation is 16 bits wide. |
This 23 bit address is mapped as follows: |
ADDR [8:0] : Column Address (512 columns) |
ADDR [20:9] : Row Address (4K Rows) |
ADDR [22:21] : Bank Address (4 banks) |
|
The SDRAMs are operated in 4 beat burst mode. |
This module takes requests from the mc, |
chops them to page boundaries if wrap=0, |
and passes the request to bank_ctl |
|
To Do: |
nothing |
|
Author(s): |
- Dinesh Annayya, dinesha@opencores.org |
Version : 1.0 - 8th Jan 2012 |
|
|
|
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.def" |
|
module sdrc_req_gen (clk, |
reset_n, |
|
/* Request from app */ |
req, // Transfer Request |
req_id, // ID for this transfer |
req_addr, // SDRAM Address |
req_addr_mask, |
req_len, // Burst Length (in 32 bit words) |
req_wrap, // Wrap mode request (xfr_len = 4) |
req_wr_n, // 0 => Write request, 1 => read req |
req_ack, // Request has been accepted |
sdr_core_busy_n, // SDRAM Core Busy Indication |
sdr_dev_config, // sdram configuration |
|
/* Req to bank_ctl */ |
r2x_idle, |
r2b_req, // request |
r2b_req_id, // ID |
r2b_start, // First chunk of burst |
r2b_last, // Last chunk of burst |
r2b_wrap, // Wrap Mode |
r2b_ba, // bank address |
r2b_raddr, // row address |
r2b_caddr, // col address |
r2b_len, // length |
r2b_write, // write request |
b2r_ack, |
b2r_arb_ok, |
sdr_width, |
sdr_init_done); |
|
parameter APP_AW = 30; // 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 = 16; // SDR Data Width |
parameter SDR_BW = 2; // SDR Byte Width |
|
input clk, reset_n; |
|
/* Request from app */ |
input req; |
input [`SDR_REQ_ID_W-1:0] req_id; |
input [APP_AW:0] req_addr; |
input [APP_AW-2:0] req_addr_mask; |
input [APP_RW-1:0] req_len; |
input req_wr_n, req_wrap; |
output req_ack, sdr_core_busy_n; |
|
/* Req to bank_ctl */ |
output r2x_idle, r2b_req, r2b_start, r2b_last, |
r2b_write, r2b_wrap; |
output [`SDR_REQ_ID_W-1:0] r2b_req_id; |
output [1:0] r2b_ba; |
output [11:0] r2b_raddr; |
output [11:0] r2b_caddr; |
output [APP_RW-1:0] r2b_len; |
input b2r_ack, b2r_arb_ok, sdr_init_done; |
// |
input sdr_width; |
input [1:0] sdr_dev_config; |
|
/****************************************************************************/ |
// Internal Nets |
|
`define REQ_IDLE 1'b0 |
`define REQ_ACTIVE 1'b1 |
|
reg req_st, next_req_st; |
reg r2x_idle, req_ack, r2b_req, r2b_start, |
r2b_write, req_idle, req_ld, lcl_wrap; |
reg [`SDR_REQ_ID_W-1:0] r2b_req_id; |
reg [APP_RW-1:0] lcl_req_len; |
|
wire r2b_last, page_ovflw; |
wire [APP_RW-1:0] r2b_len, next_req_len; |
wire [APP_RW:0] max_r2b_len; |
|
wire [1:0] r2b_ba; |
wire [11:0] r2b_raddr; |
wire [11:0] r2b_caddr; |
|
reg [APP_AW-1:0] curr_sdr_addr, sdr_addrs_mask; |
wire [APP_AW-1:0] next_sdr_addr, next_sdr_addr1; |
|
// |
// The maximum length for no page overflow is 200h/100h - caddr. Split a request |
// into 2 or more requests if it crosses a page boundary. |
// For non-queue accesses req_addr_mask is set to all 1 and the accesses |
// proceed linearly. |
// All queues end on a 512 byte boundary (actually a 1K boundary). For Q |
// accesses req_addr_mask is set to LSB of 1 and MSB of 0 to constrain the |
// accesses within the space for a Q. When splitting and calculating the next |
// address only the LSBs are incremented, the MSBs remain = req_addr. |
// |
assign max_r2b_len = (sdr_width == 1'b0) ? ((sdr_dev_config == `SDR_CONFIG_IS_32M) ? (12'h200 - r2b_caddr) : (12'h100 - r2b_caddr)) : |
(sdr_dev_config == `SDR_CONFIG_IS_8M) ? (12'h100 - r2b_caddr) : (12'h200 - r2b_caddr); |
|
assign page_ovflw = ({1'b0, lcl_req_len} > max_r2b_len) ? ~lcl_wrap : 1'b0; |
|
assign r2b_len = (page_ovflw) ? max_r2b_len : lcl_req_len; |
|
assign next_req_len = lcl_req_len - r2b_len; |
|
assign next_sdr_addr1 = curr_sdr_addr + r2b_len; |
|
// Wrap back based on the mask |
assign next_sdr_addr = (sdr_addrs_mask & next_sdr_addr1) | |
(~sdr_addrs_mask & curr_sdr_addr); |
|
assign sdr_core_busy_n = req_idle & b2r_arb_ok & sdr_init_done; |
|
assign r2b_wrap = lcl_wrap; |
|
assign r2b_last = ~page_ovflw; |
// |
// |
// |
always @ (posedge clk) begin |
|
r2b_start <= (req_ack) ? 1'b1 : |
(b2r_ack) ? 1'b0 : r2b_start; |
|
r2b_write <= (req_ack) ? ~req_wr_n : r2b_write; |
|
r2b_req_id <= (req_ack) ? req_id : r2b_req_id; |
|
lcl_wrap <= (req_ack) ? req_wrap : lcl_wrap; |
|
lcl_req_len <= (req_ack) ? req_len : |
(req_ld) ? next_req_len : lcl_req_len; |
|
curr_sdr_addr <= (req_ack) ? req_addr : |
(req_ld) ? next_sdr_addr : curr_sdr_addr; |
|
sdr_addrs_mask <= (req_ack) ? (sdr_width ? {req_addr_mask,req_addr_mask[0]} : req_addr_mask) : sdr_addrs_mask; |
|
end // always @ (posedge clk) |
|
always @ (*) begin |
|
case (req_st) // synopsys full_case parallel_case |
|
`REQ_IDLE : begin |
r2x_idle = ~req; |
req_idle = 1'b1; |
req_ack = req & b2r_arb_ok; |
req_ld = 1'b0; |
r2b_req = 1'b0; |
next_req_st = (req & b2r_arb_ok) ? `REQ_ACTIVE : `REQ_IDLE; |
end // case: `REQ_IDLE |
|
`REQ_ACTIVE : begin |
r2x_idle = 1'b0; |
req_idle = 1'b0; |
req_ack = 1'b0; |
req_ld = b2r_ack; |
r2b_req = 1'b1; // req_gen to bank_req |
next_req_st = (b2r_ack & r2b_last) ? `REQ_IDLE : `REQ_ACTIVE; |
end // case: `REQ_ACTIVE |
|
endcase // case(req_st) |
|
end // always @ (req_st or ....) |
|
always @ (posedge clk) |
if (~reset_n) begin |
req_st <= `REQ_IDLE; |
end // if (~reset_n) |
else begin |
req_st <= next_req_st; |
end // else: !if(~reset_n) |
// |
// addrs bits for the bank, row and column |
// |
// SDR_CONFIG_IS_8M 2'b00 |
// SDR_CONFIG_IS_16M 2'b01 |
// SDR_CONFIG_IS_32M 2'b10 |
// SDR_CONFIG_IS_LGCY 2'b11 |
// |
assign r2b_ba = ({sdr_width,sdr_dev_config} == {1'b0,`SDR_CONFIG_IS_8M}) ? curr_sdr_addr[20:19] : |
({sdr_width,sdr_dev_config} == {1'b0,`SDR_CONFIG_IS_16M}) ? curr_sdr_addr[21:20] : |
({sdr_width,sdr_dev_config} == {1'b0,`SDR_CONFIG_IS_32M}) ? curr_sdr_addr[22:21] : |
({sdr_width,sdr_dev_config} == {1'b1,`SDR_CONFIG_IS_8M}) ? curr_sdr_addr[21:20] : |
({sdr_width,sdr_dev_config} == {1'b1,`SDR_CONFIG_IS_16M}) ? curr_sdr_addr[22:21]: |
({sdr_width,sdr_dev_config} == {1'b1,`SDR_CONFIG_IS_32M}) ? curr_sdr_addr[23:22] : curr_sdr_addr[9:8]; |
|
assign r2b_caddr = ({sdr_width,sdr_dev_config} == {1'b0,`SDR_CONFIG_IS_8M}) ? {4'b0, curr_sdr_addr[7:0]} : |
({sdr_width,sdr_dev_config} == {1'b0,`SDR_CONFIG_IS_16M}) ? {4'b0, curr_sdr_addr[7:0]} : |
({sdr_width,sdr_dev_config} == {1'b0,`SDR_CONFIG_IS_32M}) ? {3'b0, curr_sdr_addr[8:0]} : |
({sdr_width,sdr_dev_config} == {1'b1,`SDR_CONFIG_IS_8M}) ? {3'b0, curr_sdr_addr[7:0]} : |
({sdr_width,sdr_dev_config} == {1'b1,`SDR_CONFIG_IS_16M}) ? {3'b0, curr_sdr_addr[8:0]} : |
({sdr_width,sdr_dev_config} == {1'b1,`SDR_CONFIG_IS_32M}) ? {2'b0, curr_sdr_addr[8:0]} : {4'b0, curr_sdr_addr[7:0]}; |
|
assign r2b_raddr = ({sdr_width,sdr_dev_config} == {1'b0,`SDR_CONFIG_IS_8M}) ? {1'b0, curr_sdr_addr[18:8]} : |
({sdr_width,sdr_dev_config} == {1'b0,`SDR_CONFIG_IS_16M}) ? curr_sdr_addr[19:8] : |
({sdr_width,sdr_dev_config} == {1'b0,`SDR_CONFIG_IS_32M}) ? curr_sdr_addr[20:9] : |
({sdr_width,sdr_dev_config} == {1'b1,`SDR_CONFIG_IS_8M}) ? {1'b0,curr_sdr_addr[19:8]} : |
({sdr_width,sdr_dev_config} == {1'b1,`SDR_CONFIG_IS_16M}) ? curr_sdr_addr[20:9] : |
({sdr_width,sdr_dev_config} == {1'b1,`SDR_CONFIG_IS_32M}) ? curr_sdr_addr[21:9] : {1'b0, curr_sdr_addr[20:10]}; |
|
|
endmodule // sdr_req_gen |
rtl/core/sdrc_req_gen.v
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: rtl/core/sdrc_xfr_ctl.v
===================================================================
--- rtl/core/sdrc_xfr_ctl.v (nonexistent)
+++ rtl/core/sdrc_xfr_ctl.v (revision 3)
@@ -0,0 +1,762 @@
+/*********************************************************************
+
+ SDRAM Controller Transfer control
+
+ This file is part of the sdram controller project
+ http://www.opencores.org/cores/sdr_ctrl/
+
+ Description: SDRAM Controller Transfer control
+
+ This module takes requests from sdrc_bank_ctl and runs the
+ transfer. The input request is guaranteed to be in a bank that is
+ precharged and activated. This block runs the transfer until a
+ burst boundary is reached, then issues another read/write command
+ to sequentially step thru memory if wrap=0, until the transfer is
+ completed.
+
+ if a read transfer finishes and the caddr is not at a burst boundary
+ a burst terminate command is issued unless another read/write or
+ precharge to the same bank is pending.
+
+ if a write transfer finishes and the caddr is not at a burst boundary
+ a burst terminate command is issued unless a read/write is pending.
+
+ If a refresh request is made, the bank_ctl will be held off until
+ the number of refreshes requested are completed.
+
+ This block also handles SDRAM initialization.
+
+
+ To Do:
+ nothing
+
+ Author(s):
+ - Dinesh Annayya, dinesha@opencores.org
+ Version : 1.0 - 8th Jan 2012
+
+
+
+ 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.def"
+
+module sdrc_xfr_ctl (clk,
+ reset_n,
+
+ /* Transfer request from bank_ctl */
+ r2x_idle, // Req is idle
+ b2x_idle, // All banks are idle
+ b2x_req, // Req from bank_ctl
+ b2x_start, // first chunk of transfer
+ b2x_last, // last chunk of transfer
+ b2x_id, // Transfer ID
+ b2x_ba, // bank address
+ b2x_addr, // row/col address
+ b2x_len, // transfer length
+ b2x_cmd, // transfer command
+ b2x_wrap, // Wrap mode transfer
+ x2b_ack, // command accepted
+
+ /* Status to bank_ctl, req_gen */
+ b2x_tras_ok, // Tras for all banks expired
+ x2b_refresh, // We did a refresh
+ x2b_pre_ok, // OK to do a precharge (per bank)
+ x2b_act_ok, // OK to do an activate
+ x2b_rdok, // OK to do a read
+ x2b_wrok, // OK to do a write
+
+ /* SDRAM I/O */
+ sdr_cs_n,
+ sdr_cke,
+ sdr_ras_n,
+ sdr_cas_n,
+ sdr_we_n,
+ sdr_dqm,
+ sdr_ba,
+ sdr_addr,
+ sdr_din,
+ sdr_dout,
+ sdr_den_n,
+
+ /* Data Flow to the app */
+ x2a_rdstart,
+ x2a_wrstart,
+ x2a_rdlast,
+ x2a_wrlast,
+ x2a_id,
+ app_wrdt,
+ app_wren_n,
+ x2a_wrnext,
+ x2a_rddt,
+ x2a_rdok,
+ sdr_init_done,
+
+ /* SDRAM Parameters */
+ sdram_enable,
+ sdram_mode_reg,
+
+ /* output for generate row address of the transfer */
+ xfr_bank_sel,
+
+ /* SDRAM Timing */
+ cas_latency,
+ trp_delay, // Precharge to refresh delay
+ trcar_delay, // Auto-refresh period
+ twr_delay, // Write recovery delay
+ rfsh_time, // time per row (31.25 or 15.6125 uS)
+ rfsh_rmax); // Number of rows to rfsh at a time (<120uS)
+
+parameter APP_AW = 30; // 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 = 16; // SDR Data Width
+parameter SDR_BW = 2; // SDR Byte Width
+
+
+input clk, reset_n;
+
+ /* Req from bank_ctl */
+input b2x_req, b2x_start, b2x_last, b2x_tras_ok,
+ b2x_wrap, r2x_idle, b2x_idle;
+input [`SDR_REQ_ID_W-1:0] b2x_id;
+input [1:0] b2x_ba;
+input [11:0] b2x_addr;
+input [APP_RW-1:0] b2x_len;
+input [1:0] b2x_cmd;
+output x2b_ack;
+
+/* Status to bank_ctl */
+output [3:0] x2b_pre_ok;
+output x2b_refresh, x2b_act_ok, x2b_rdok,
+ x2b_wrok;
+/* Data Flow to the app */
+output x2a_rdstart, x2a_wrstart, x2a_rdlast, x2a_wrlast;
+output [`SDR_REQ_ID_W-1:0] x2a_id;
+
+input [SDR_DW-1:0] app_wrdt;
+input [SDR_BW-1:0] app_wren_n;
+output [SDR_DW-1:0] x2a_rddt;
+output x2a_wrnext, x2a_rdok, sdr_init_done;
+
+/* Interface to SDRAMs */
+output sdr_cs_n, sdr_cke, sdr_ras_n, sdr_cas_n,
+ sdr_we_n;
+output [SDR_BW-1:0] sdr_dqm;
+output [1:0] sdr_ba;
+output [11:0] sdr_addr;
+input [SDR_DW-1:0] sdr_din;
+output [SDR_DW-1:0] sdr_dout;
+output [SDR_BW-1:0] sdr_den_n;
+
+ output [1:0] xfr_bank_sel;
+
+ input sdram_enable;
+ input [11:0] sdram_mode_reg;
+ input [2:0] cas_latency;
+ input [3:0] trp_delay, trcar_delay, twr_delay;
+ input [`SDR_RFSH_TIMER_W-1 : 0] rfsh_time;
+ input [`SDR_RFSH_ROW_CNT_W-1:0] rfsh_rmax;
+
+
+ /************************************************************************/
+ // Internal Nets
+
+ `define XFR_IDLE 2'b00
+ `define XFR_WRITE 2'b01
+ `define XFR_READ 2'b10
+ `define XFR_RDWT 2'b11
+
+ reg [1:0] xfr_st, next_xfr_st;
+ reg [11:0] xfr_caddr;
+ wire last_burst;
+ wire x2a_rdstart, x2a_wrstart, x2a_rdlast, x2a_wrlast;
+ reg l_start, l_last, l_wrap;
+ wire [`SDR_REQ_ID_W-1:0] x2a_id;
+ reg [`SDR_REQ_ID_W-1:0] l_id;
+ wire [1:0] xfr_ba;
+ reg [1:0] l_ba;
+ wire [11:0] xfr_addr;
+ wire [APP_RW-1:0] xfr_len, next_xfr_len;
+ reg [APP_RW-1:0] l_len;
+
+ reg mgmt_idle, mgmt_req;
+ reg [3:0] mgmt_cmd;
+ reg [11:0] mgmt_addr;
+ reg [1:0] mgmt_ba;
+
+ reg sel_mgmt, sel_b2x;
+ reg cb_pre_ok, rdok, wrok, wr_next,
+ rd_next, sdr_init_done, act_cmd, d_act_cmd;
+ wire [3:0] b2x_sdr_cmd, xfr_cmd;
+ reg [3:0] i_xfr_cmd;
+ wire mgmt_ack, x2b_ack, b2x_read, b2x_write,
+ b2x_prechg, d_rd_next, dt_next, xfr_end,
+ rd_pipe_mt, ld_xfr, rd_last, d_rd_last,
+ wr_last, l_xfr_end, rd_start, d_rd_start,
+ wr_start, page_hit, burst_bdry, xfr_wrap,
+ b2x_prechg_hit;
+ reg [4:0] l_rd_next, l_rd_start, l_rd_last;
+
+ assign b2x_read = (b2x_cmd == `OP_RD) ? 1'b1 : 1'b0;
+
+ assign b2x_write = (b2x_cmd == `OP_WR) ? 1'b1 : 1'b0;
+
+ assign b2x_prechg = (b2x_cmd == `OP_PRE) ? 1'b1 : 1'b0;
+
+ assign b2x_sdr_cmd = (b2x_cmd == `OP_PRE) ? `SDR_PRECHARGE :
+ (b2x_cmd == `OP_ACT) ? `SDR_ACTIVATE :
+ (b2x_cmd == `OP_RD) ? `SDR_READ :
+ (b2x_cmd == `OP_WR) ? `SDR_WRITE : `SDR_DESEL;
+
+ assign page_hit = (b2x_ba == l_ba) ? 1'b1 : 1'b0;
+
+ assign b2x_prechg_hit = b2x_prechg & page_hit;
+
+ assign xfr_cmd = (sel_mgmt) ? mgmt_cmd :
+ (sel_b2x) ? b2x_sdr_cmd : i_xfr_cmd;
+
+ assign xfr_addr = (sel_mgmt) ? mgmt_addr :
+ (sel_b2x) ? b2x_addr : xfr_caddr;
+
+ assign mgmt_ack = sel_mgmt;
+
+ assign x2b_ack = sel_b2x;
+
+ assign ld_xfr = sel_b2x & (b2x_read | b2x_write);
+
+ assign xfr_len = (ld_xfr) ? b2x_len : l_len;
+
+ assign next_xfr_len = (xfr_end) ? xfr_len : xfr_len - 1;
+
+ assign d_rd_next = (cas_latency == 2'b01) ? l_rd_next[2] :
+ (cas_latency == 2'b10) ? l_rd_next[3] :
+ l_rd_next[4];
+
+ assign d_rd_last = (cas_latency == 2'b01) ? l_rd_last[2] :
+ (cas_latency == 2'b10) ? l_rd_last[3] :
+ l_rd_last[4];
+
+ assign d_rd_start = (cas_latency == 2'b01) ? l_rd_start[2] :
+ (cas_latency == 2'b10) ? l_rd_start[3] :
+ l_rd_start[4];
+
+ assign rd_pipe_mt = (cas_latency == 2'b01) ? ~|l_rd_next[1:0] :
+ (cas_latency == 2'b10) ? ~|l_rd_next[2:0] :
+ ~|l_rd_next[3:0];
+
+ assign dt_next = wr_next | d_rd_next;
+
+ assign xfr_end = ~|xfr_len;
+
+ assign l_xfr_end = ~|l_len;
+
+ assign rd_start = ld_xfr & b2x_read & b2x_start;
+
+ assign wr_start = ld_xfr & b2x_write & b2x_start;
+
+ assign rd_last = rd_next & last_burst & ~|xfr_len[APP_RW-1:1];
+
+ //assign wr_last = wr_next & last_burst & ~|xfr_len[APP_RW-1:1];
+
+ assign wr_last = last_burst & ~|xfr_len[APP_RW-1:1];
+
+ //assign xfr_ba = (ld_xfr) ? b2x_ba : l_ba;
+ assign xfr_ba = (sel_mgmt) ? mgmt_ba :
+ (sel_b2x) ? b2x_ba : l_ba;
+
+ assign xfr_wrap = (ld_xfr) ? b2x_wrap : l_wrap;
+
+// assign burst_bdry = ~|xfr_caddr[2:0];
+ assign burst_bdry = ~|xfr_caddr[1:0];
+
+ always @ (posedge clk) begin
+ if (~reset_n) begin
+ xfr_caddr <= 12'b0;
+ l_start <= 1'b0;
+ l_last <= 1'b0;
+ l_wrap <= 1'b0;
+ l_id <= 0;
+ l_ba <= 0;
+ l_len <= 0;
+ l_rd_next <= 5'b0;
+ l_rd_start <= 5'b0;
+ l_rd_last <= 5'b0;
+ act_cmd <= 1'b0;
+ d_act_cmd <= 1'b0;
+ xfr_st <= `XFR_IDLE;
+ end // if (~reset_n)
+
+ else begin
+ xfr_caddr <= (ld_xfr) ? b2x_addr + 12'h1 :
+ (rd_next | wr_next) ? xfr_caddr + 12'h1 :
+ xfr_caddr;
+ l_start <= (dt_next) ? 1'b0 :
+ (ld_xfr) ? b2x_start : l_start;
+ l_last <= (ld_xfr) ? b2x_last : l_last;
+ l_wrap <= (ld_xfr) ? b2x_wrap : l_wrap;
+ l_id <= (ld_xfr) ? b2x_id : l_id;
+ l_ba <= (ld_xfr) ? b2x_ba : l_ba;
+ l_len <= next_xfr_len;
+ l_rd_next <= {l_rd_next[3:0], rd_next};
+ l_rd_start <= {l_rd_start[3:0], rd_start};
+ l_rd_last <= {l_rd_last[3:0], rd_last};
+ act_cmd <= (xfr_cmd == `SDR_ACTIVATE) ? 1'b1 : 1'b0;
+ d_act_cmd <= act_cmd;
+ xfr_st <= next_xfr_st;
+ end // else: !if(~reset_n)
+
+ end // always @ (posedge clk)
+
+
+ always @ (*) begin
+ case (xfr_st)
+
+ `XFR_IDLE : begin
+
+ sel_mgmt = mgmt_req;
+ sel_b2x = ~mgmt_req & sdr_init_done & b2x_req;
+ i_xfr_cmd = `SDR_DESEL;
+ rd_next = ~mgmt_req & sdr_init_done & b2x_req & b2x_read;
+ wr_next = ~mgmt_req & sdr_init_done & b2x_req & b2x_write;
+ rdok = ~mgmt_req;
+ cb_pre_ok = 1'b1;
+ wrok = ~mgmt_req;
+ next_xfr_st = (mgmt_req | ~sdr_init_done) ? `XFR_IDLE :
+ (~b2x_req) ? `XFR_IDLE :
+ (b2x_read) ? `XFR_READ :
+ (b2x_write) ? `XFR_WRITE : `XFR_IDLE;
+
+ end // case: `XFR_IDLE
+
+ `XFR_READ : begin
+ rd_next = ~l_xfr_end |
+ l_xfr_end & ~mgmt_req & b2x_req & b2x_read;
+ wr_next = 1'b0;
+ rdok = l_xfr_end & ~mgmt_req;
+ cb_pre_ok = l_xfr_end;
+ wrok = 1'b0;
+ sel_mgmt = 1'b0;
+
+ if (l_xfr_end) begin // end of transfer
+
+ if (~l_wrap) begin
+ // Current transfer was not wrap mode, may need BT
+ // If next cmd is a R or W or PRE to same bank allow
+ // it else issue BT
+ // This is a little pessimistic since BT is issued
+ // for non-wrap mode transfers even if the transfer
+ // ends on a burst boundary, but is felt to be of
+ // minimal performance impact.
+
+ i_xfr_cmd = `SDR_BT;
+ sel_b2x = b2x_req & ~mgmt_req & (b2x_read | b2x_prechg_hit);
+
+ end // if (~l_wrap)
+
+ else begin
+ // Wrap mode transfer, by definition is end of burst
+ // boundary
+
+ i_xfr_cmd = `SDR_DESEL;
+ sel_b2x = b2x_req & ~mgmt_req & ~b2x_write;
+
+ end // else: !if(~l_wrap)
+
+ next_xfr_st = (sdr_init_done) ? ((b2x_req & ~mgmt_req & b2x_read) ? `XFR_READ : `XFR_RDWT) : `XFR_IDLE;
+
+ end // if (l_xfr_end)
+
+ else begin
+ // Not end of transfer
+ // If current transfer was not wrap mode and we are at
+ // the start of a burst boundary issue another R cmd to
+ // step sequemtially thru memory, ELSE,
+ // issue precharge/activate commands from the bank control
+
+ i_xfr_cmd = (burst_bdry & ~l_wrap) ? `SDR_READ : `SDR_DESEL;
+ sel_b2x = ~(burst_bdry & ~l_wrap) & b2x_req;
+ next_xfr_st = `XFR_READ;
+
+ end // else: !if(l_xfr_end)
+
+ end // case: `XFR_READ
+
+ `XFR_RDWT : begin
+ rd_next = ~mgmt_req & b2x_req & b2x_read;
+ wr_next = rd_pipe_mt & ~mgmt_req & b2x_req & b2x_write;
+ rdok = ~mgmt_req;
+ cb_pre_ok = 1'b1;
+ wrok = rd_pipe_mt & ~mgmt_req;
+
+ sel_mgmt = mgmt_req;
+
+ sel_b2x = ~mgmt_req & b2x_req;
+
+ i_xfr_cmd = `SDR_DESEL;
+
+ next_xfr_st = (~mgmt_req & b2x_req & b2x_read) ? `XFR_READ :
+ (~rd_pipe_mt) ? `XFR_RDWT :
+ (~mgmt_req & b2x_req & b2x_write) ? `XFR_WRITE :
+ `XFR_IDLE;
+
+ end // case: `XFR_RDWT
+
+ `XFR_WRITE : begin
+ rd_next = l_xfr_end & ~mgmt_req & b2x_req & b2x_read;
+ wr_next = ~l_xfr_end |
+ l_xfr_end & ~mgmt_req & b2x_req & b2x_write;
+ rdok = l_xfr_end & ~mgmt_req;
+ cb_pre_ok = 1'b0;
+ wrok = l_xfr_end & ~mgmt_req;
+ sel_mgmt = 1'b0;
+
+ if (l_xfr_end) begin // End of transfer
+
+ if (~l_wrap) begin
+ // Current transfer was not wrap mode, may need BT
+ // If next cmd is a R or W allow it else issue BT
+ // This is a little pessimistic since BT is issued
+ // for non-wrap mode transfers even if the transfer
+ // ends on a burst boundary, but is felt to be of
+ // minimal performance impact.
+
+
+ sel_b2x = b2x_req & ~mgmt_req & (b2x_read | b2x_write);
+ i_xfr_cmd = `SDR_BT;
+ end // if (~l_wrap)
+
+ else begin
+ // Wrap mode transfer, by definition is end of burst
+ // boundary
+
+ sel_b2x = b2x_req & ~mgmt_req & ~b2x_prechg_hit;
+ i_xfr_cmd = `SDR_DESEL;
+ end // else: !if(~l_wrap)
+
+ next_xfr_st = (~mgmt_req & b2x_req & b2x_read) ? `XFR_READ :
+ (~mgmt_req & b2x_req & b2x_write) ? `XFR_WRITE :
+ `XFR_IDLE;
+
+ end // if (l_xfr_end)
+
+ else begin
+ // Not end of transfer
+ // If current transfer was not wrap mode and we are at
+ // the start of a burst boundary issue another R cmd to
+ // step sequemtially thru memory, ELSE,
+ // issue precharge/activate commands from the bank control
+
+ if (burst_bdry & ~l_wrap) begin
+ sel_b2x = 1'b0;
+ i_xfr_cmd = `SDR_WRITE;
+ end // if (burst_bdry & ~l_wrap)
+
+ else begin
+ sel_b2x = b2x_req & ~mgmt_req;
+ i_xfr_cmd = `SDR_DESEL;
+ end // else: !if(burst_bdry & ~l_wrap)
+
+ next_xfr_st = `XFR_WRITE;
+ end // else: !if(l_xfr_end)
+
+ end // case: `XFR_WRITE
+
+ endcase // case(xfr_st)
+
+ end // always @ (xfr_st or ...)
+
+ // signals to bank_ctl (x2b_refresh, x2b_act_ok, x2b_rdok, x2b_wrok,
+ // x2b_pre_ok[3:0]
+
+ assign x2b_refresh = (xfr_cmd == `SDR_REFRESH) ? 1'b1 : 1'b0;
+
+ assign x2b_act_ok = ~act_cmd & ~d_act_cmd;
+
+ assign x2b_rdok = rdok;
+
+ assign x2b_wrok = wrok;
+
+ assign x2b_pre_ok[0] = (l_ba == 2'b00) ? cb_pre_ok : 1'b1;
+ assign x2b_pre_ok[1] = (l_ba == 2'b01) ? cb_pre_ok : 1'b1;
+ assign x2b_pre_ok[2] = (l_ba == 2'b10) ? cb_pre_ok : 1'b1;
+ assign x2b_pre_ok[3] = (l_ba == 2'b11) ? cb_pre_ok : 1'b1;
+
+ assign last_burst = (ld_xfr) ? b2x_last : l_last;
+
+ /************************************************************************/
+ // APP Data I/F
+
+ wire [SDR_DW-1:0] x2a_rddt;
+
+ //assign x2a_start = (ld_xfr) ? b2x_start : l_start;
+ assign x2a_rdstart = d_rd_start;
+ assign x2a_wrstart = wr_start;
+
+ assign x2a_rdlast = d_rd_last;
+ assign x2a_wrlast = wr_last;
+
+ assign x2a_id = (ld_xfr) ? b2x_id : l_id;
+
+ assign x2a_rddt = sdr_din;
+
+ assign x2a_wrnext = wr_next;
+
+ assign x2a_rdok = d_rd_next;
+
+ /************************************************************************/
+ // SDRAM I/F
+
+ reg sdr_cs_n, sdr_cke, sdr_ras_n, sdr_cas_n,
+ sdr_we_n;
+ reg [SDR_BW-1:0] sdr_dqm;
+ reg [1:0] sdr_ba;
+ reg [11:0] sdr_addr;
+ reg [SDR_DW-1:0] sdr_dout;
+ reg [SDR_BW-1:0] sdr_den_n;
+
+ always @ (posedge clk)
+ if (~reset_n) begin
+ sdr_cs_n <= 1'b1;
+ sdr_cke <= 1'b1;
+ sdr_ras_n <= 1'b1;
+ sdr_cas_n <= 1'b1;
+ sdr_we_n <= 1'b1;
+ sdr_dqm <= {SDR_DW{1'b1}};
+ sdr_den_n <= {SDR_DW{1'b1}};
+ end // if (~reset_n)
+ else begin
+ sdr_cs_n <= xfr_cmd[3];
+ sdr_ras_n <= xfr_cmd[2];
+ sdr_cas_n <= xfr_cmd[1];
+ sdr_we_n <= xfr_cmd[0];
+ sdr_cke <= (xfr_st != `XFR_IDLE) ? 1'b1 :
+ ~(mgmt_idle & b2x_idle & r2x_idle);
+ sdr_dqm <= (wr_next) ? app_wren_n : {SDR_BW{1'b0}};
+ sdr_den_n <= (wr_next) ? {SDR_BW{1'b0}} : {SDR_BW{1'b1}};
+ end // else: !if(~reset_n)
+
+ always @ (posedge clk) begin
+
+ if (~xfr_cmd[3]) begin
+ sdr_addr <= xfr_addr;
+ sdr_ba <= xfr_ba;
+ end // if (~xfr_cmd[3])
+
+ sdr_dout <= (wr_next) ? app_wrdt : sdr_dout;
+
+ end // always @ (posedge clk)
+
+ /************************************************************************/
+ // Refresh and Initialization
+
+ `define MGM_POWERUP 3'b000
+ `define MGM_PRECHARGE 3'b001
+ `define MGM_PCHWT 3'b010
+ `define MGM_REFRESH 3'b011
+ `define MGM_REFWT 3'b100
+ `define MGM_MODE_REG 3'b101
+ `define MGM_MODE_WT 3'b110
+ `define MGM_ACTIVE 3'b111
+
+ reg [2:0] mgmt_st, next_mgmt_st;
+ reg [3:0] tmr0, tmr0_d;
+ reg [3:0] cntr1, cntr1_d;
+ wire tmr0_tc, cntr1_tc, rfsh_timer_tc, ref_req, precharge_ok;
+ reg ld_tmr0, ld_cntr1, dec_cntr1, set_sdr_init_done;
+ reg [`SDR_RFSH_TIMER_W-1 : 0] rfsh_timer;
+ reg [`SDR_RFSH_ROW_CNT_W-1:0] rfsh_row_cnt;
+
+ always @ (posedge clk)
+ if (~reset_n) begin
+ mgmt_st <= `MGM_POWERUP;
+ tmr0 <= 4'b0;
+ cntr1 <= 4'h7;
+ rfsh_timer <= 0;
+ rfsh_row_cnt <= 0;
+ sdr_init_done <= 1'b0;
+ end // if (~reset_n)
+ else begin
+ mgmt_st <= next_mgmt_st;
+ tmr0 <= (ld_tmr0) ? tmr0_d :
+ (~tmr0_tc) ? tmr0 - 1 : tmr0;
+ cntr1 <= (ld_cntr1) ? cntr1_d :
+ (dec_cntr1) ? cntr1 - 1 : cntr1;
+ sdr_init_done <= (set_sdr_init_done | sdr_init_done) & sdram_enable;
+ rfsh_timer <= (rfsh_timer_tc) ? 0 : rfsh_timer + 1;
+ rfsh_row_cnt <= (~set_sdr_init_done) ? 0 :
+ (rfsh_timer_tc) ? rfsh_row_cnt + 1 : rfsh_row_cnt;
+ end // else: !if(~reset_n)
+
+ assign tmr0_tc = ~|tmr0;
+
+ assign cntr1_tc = ~|cntr1;
+
+ assign rfsh_timer_tc = (rfsh_timer == rfsh_time) ? 1'b1 : 1'b0;
+
+ assign ref_req = (rfsh_row_cnt >= rfsh_rmax) ? 1'b1 : 1'b0;
+
+ assign precharge_ok = cb_pre_ok & b2x_tras_ok;
+
+ assign xfr_bank_sel = l_ba;
+
+ always @ (mgmt_st or sdram_enable or mgmt_ack or trp_delay or tmr0_tc or
+ cntr1_tc or trcar_delay or rfsh_row_cnt or ref_req or sdr_init_done
+ or precharge_ok or sdram_mode_reg) begin
+
+ case (mgmt_st) // synopsys full_case parallel_case
+
+ `MGM_POWERUP : begin
+ mgmt_idle = 1'b0;
+ mgmt_req = 1'b0;
+ mgmt_cmd = `SDR_DESEL;
+ mgmt_ba = 2'b0;
+ mgmt_addr = 12'h400; // A10 = 1 => all banks
+ ld_tmr0 = 1'b0;
+ tmr0_d = 4'b0;
+ dec_cntr1 = 1'b0;
+ ld_cntr1 = 1'b1;
+ cntr1_d = 4'hf; // changed for sdrams with higher refresh cycles during initialization
+ set_sdr_init_done = 1'b0;
+ next_mgmt_st = (sdram_enable) ? `MGM_PRECHARGE : `MGM_POWERUP;
+ end // case: `MGM_POWERUP
+
+ `MGM_PRECHARGE : begin // Precharge all banks
+ mgmt_idle = 1'b0;
+ mgmt_req = 1'b1;
+ mgmt_cmd = (precharge_ok) ? `SDR_PRECHARGE : `SDR_DESEL;
+ mgmt_ba = 2'b0;
+ mgmt_addr = 12'h400; // A10 = 1 => all banks
+ ld_tmr0 = mgmt_ack;
+ tmr0_d = trp_delay;
+ ld_cntr1 = 1'b0;
+ cntr1_d = 4'h7;
+ dec_cntr1 = 1'b0;
+ set_sdr_init_done = 1'b0;
+ next_mgmt_st = (precharge_ok & mgmt_ack) ? `MGM_PCHWT : `MGM_PRECHARGE;
+ end // case: `MGM_PRECHARGE
+
+ `MGM_PCHWT : begin // Wait for Trp
+ mgmt_idle = 1'b0;
+ mgmt_req = 1'b1;
+ mgmt_cmd = `SDR_DESEL;
+ mgmt_ba = 2'b0;
+ mgmt_addr = 12'h400; // A10 = 1 => all banks
+ ld_tmr0 = 1'b0;
+ tmr0_d = trp_delay;
+ ld_cntr1 = 1'b0;
+ cntr1_d = 4'b0;
+ dec_cntr1 = 1'b0;
+ set_sdr_init_done = 1'b0;
+ next_mgmt_st = (tmr0_tc) ? `MGM_REFRESH : `MGM_PCHWT;
+ end // case: `MGM_PRECHARGE
+
+ `MGM_REFRESH : begin // Refresh
+ mgmt_idle = 1'b0;
+ mgmt_req = 1'b1;
+ mgmt_cmd = `SDR_REFRESH;
+ mgmt_ba = 2'b0;
+ mgmt_addr = 12'h400; // A10 = 1 => all banks
+ ld_tmr0 = mgmt_ack;
+ tmr0_d = trcar_delay;
+ dec_cntr1 = mgmt_ack;
+ ld_cntr1 = 1'b0;
+ cntr1_d = 4'h7;
+ set_sdr_init_done = 1'b0;
+ next_mgmt_st = (mgmt_ack) ? `MGM_REFWT : `MGM_REFRESH;
+ end // case: `MGM_REFRESH
+
+ `MGM_REFWT : begin // Wait for trcar
+ mgmt_idle = 1'b0;
+ mgmt_req = 1'b1;
+ mgmt_cmd = `SDR_DESEL;
+ mgmt_ba = 2'b0;
+ mgmt_addr = 12'h400; // A10 = 1 => all banks
+ ld_tmr0 = 1'b0;
+ tmr0_d = trcar_delay;
+ dec_cntr1 = 1'b0;
+ ld_cntr1 = 1'b0;
+ cntr1_d = 4'h7;
+ set_sdr_init_done = 1'b0;
+ next_mgmt_st = (~tmr0_tc) ? `MGM_REFWT :
+ (~cntr1_tc) ? `MGM_REFRESH :
+ (sdr_init_done) ? `MGM_ACTIVE : `MGM_MODE_REG;
+ end // case: `MGM_REFWT
+
+ `MGM_MODE_REG : begin // Program mode Register & wait for
+ mgmt_idle = 1'b0;
+ mgmt_req = 1'b1;
+ mgmt_cmd = `SDR_MODE;
+ mgmt_ba = {1'b0, sdram_mode_reg[11]};
+ mgmt_addr = sdram_mode_reg;
+ ld_tmr0 = mgmt_ack;
+ tmr0_d = 4'h7;
+ dec_cntr1 = 1'b0;
+ ld_cntr1 = 1'b0;
+ cntr1_d = 4'h7;
+ set_sdr_init_done = 1'b0;
+ next_mgmt_st = (mgmt_ack) ? `MGM_MODE_WT : `MGM_MODE_REG;
+ end // case: `MGM_MODE_REG
+
+ `MGM_MODE_WT : begin // Wait for tMRD
+ mgmt_idle = 1'b0;
+ mgmt_req = 1'b1;
+ mgmt_cmd = `SDR_DESEL;
+ mgmt_ba = 2'bx;
+ mgmt_addr = 12'bx;
+ ld_tmr0 = 1'b0;
+ tmr0_d = 4'h7;
+ dec_cntr1 = 1'b0;
+ ld_cntr1 = 1'b0;
+ cntr1_d = 4'h7;
+ set_sdr_init_done = 1'b0;
+ next_mgmt_st = (~tmr0_tc) ? `MGM_MODE_WT : `MGM_ACTIVE;
+ end // case: `MGM_MODE_WT
+
+ `MGM_ACTIVE : begin // Wait for ref_req
+ mgmt_idle = ~ref_req;
+ mgmt_req = 1'b0;
+ mgmt_cmd = `SDR_DESEL;
+ mgmt_ba = 2'bx;
+ mgmt_addr = 12'bx;
+ ld_tmr0 = 1'b0;
+ tmr0_d = 4'h7;
+ dec_cntr1 = 1'b0;
+ ld_cntr1 = ref_req;
+ cntr1_d = rfsh_row_cnt;
+ set_sdr_init_done = 1'b1;
+ next_mgmt_st = (~sdram_enable) ? `MGM_POWERUP :
+ (ref_req) ? `MGM_PRECHARGE : `MGM_ACTIVE;
+ end // case: `MGM_MODE_WT
+
+ endcase // case(mgmt_st)
+
+ end // always @ (mgmt_st or ....)
+
+
+
+endmodule // sdr_xfr_ctl
rtl/core/sdrc_xfr_ctl.v
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: rtl/core/sdrc_bs_convert.v
===================================================================
--- rtl/core/sdrc_bs_convert.v (nonexistent)
+++ rtl/core/sdrc_bs_convert.v (revision 3)
@@ -0,0 +1,335 @@
+/*********************************************************************
+
+ SDRAM Controller buswidth converter
+
+ This file is part of the sdram controller project
+ http://www.opencores.org/cores/sdr_ctrl/
+
+ Description: SDRAM Controller Buswidth converter
+
+ This module does write/read data transalation between
+ application data to SDRAM bus width
+
+ To Do:
+ nothing
+
+ Author(s):
+ - Dinesh Annayya, dinesha@opencores.org
+ Version : 1.0 - 8th Jan 2012
+
+
+
+ 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.def"
+module sdrc_bs_convert (
+ clk,
+ reset_n,
+ sdr_width,
+
+ app_req_addr,
+ app_req_addr_int,
+ app_req_len,
+ app_req_len_int,
+ app_req,
+ app_req_int,
+ app_req_dma_last,
+ app_req_dma_last_int,
+ app_req_wr_n,
+ app_req_ack,
+ app_req_ack_int,
+
+ app_wr_data,
+ app_wr_data_int,
+ app_wr_en_n,
+ app_wr_en_n_int,
+ app_wr_next_int,
+ app_wr_next,
+
+ app_rd_data_int,
+ app_rd_data,
+ app_rd_valid_int,
+ app_rd_valid
+ );
+parameter APP_AW = 30; // 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 = 16; // SDR Data Width
+parameter SDR_BW = 2; // SDR Byte Width
+
+input clk;
+input reset_n ;
+input sdr_width;
+
+input [APP_AW-1:0] app_req_addr;
+output [APP_AW:0] app_req_addr_int;
+input [APP_RW-1:0] app_req_len ;
+output [APP_RW-1:0] app_req_len_int;
+input app_req_wr_n;
+input app_req;
+output app_req_int;
+input app_req_dma_last;
+output app_req_dma_last_int;
+input app_req_ack_int;
+output app_req_ack;
+
+input [APP_DW-1:0] app_wr_data;
+output [SDR_DW-1:0] app_wr_data_int;
+input [APP_BW-1:0] app_wr_en_n;
+output [SDR_BW-1:0] app_wr_en_n_int;
+input app_wr_next_int;
+output app_wr_next;
+
+input [SDR_DW-1:0] app_rd_data_int;
+output [APP_DW-1:0] app_rd_data;
+input app_rd_valid_int;
+output app_rd_valid;
+
+reg [APP_AW:0] app_req_addr_int;
+reg [APP_RW-1:0] app_req_len_int;
+
+reg app_req_dma_last_int;
+reg app_req_int;
+reg app_req_ack;
+
+reg [APP_DW-1:0] app_rd_data;
+reg app_rd_valid;
+reg [SDR_DW-1:0] app_wr_data_int;
+reg [SDR_BW-1:0] app_wr_en_n_int;
+reg app_wr_next;
+
+reg lcl_rd_valid;
+reg lcl_wr_next;
+reg [15:0] saved_rd_data;
+reg save_lower;
+reg upper_word;
+reg write_upper;
+reg [7:0] rd_xfr_count;
+reg [7:0] wr_xfr_count;
+
+reg [3:0] rd_state,next_rd_state;
+reg [3:0] wr_state,next_wr_state;
+
+parameter SDR16_IDLE = 0,
+ SDR16_RD_LO = 1,
+ SDR16_RD_HI = 2,
+ SDR16_WR_LO = 3,
+ SDR16_WR_HI = 4;
+wire ok_to_req;
+
+assign ok_to_req = ((wr_state == SDR16_IDLE) && (rd_state == SDR16_IDLE));
+
+always @(*) begin
+ if(!sdr_width) // 32 Bit SDR Mode
+ begin
+ app_req_addr_int = {1'b0,app_req_addr};
+ app_req_len_int = app_req_len;
+ app_wr_data_int = app_wr_data;
+ app_wr_en_n_int = app_wr_en_n;
+ app_req_dma_last_int = app_req_dma_last;
+ app_req_int = app_req;
+ app_wr_next = app_wr_next_int;
+ app_rd_data = app_rd_data_int;
+ app_rd_valid = app_rd_valid_int;
+ app_req_ack = app_req_ack_int;
+ end
+ else // 16 Bit SDR Mode
+ begin
+ // Changed the address and length to match the 16 bit SDR Mode
+ app_req_addr_int = {app_req_addr,1'b0};
+ app_req_len_int = {app_req_len,1'b0};
+ app_req_dma_last_int = app_req_dma_last;
+ app_req_int = app_req && ok_to_req;
+ app_req_ack = app_req_ack_int;
+ app_wr_next = lcl_wr_next;
+ app_rd_valid = lcl_rd_valid;
+ if(write_upper)
+ begin
+ app_wr_en_n_int = app_wr_en_n[3:2];
+ app_wr_data_int = app_wr_data[31:16];
+ end
+ else
+ begin
+ app_wr_en_n_int = app_wr_en_n[1:0];
+ app_wr_data_int = app_wr_data[15:0];
+ end
+
+ app_rd_data = {app_rd_data_int[15:0],saved_rd_data};
+ end
+ end
+
+//
+// WRITES
+//
+always @(*) begin
+
+ lcl_wr_next = 1'b0;
+ upper_word = 1'b0;
+ next_wr_state = wr_state;
+
+ case(wr_state)
+ SDR16_IDLE:
+ begin
+ if(app_req_ack_int && sdr_width)
+ begin
+ if(~app_req_wr_n)
+ begin
+ next_wr_state = SDR16_WR_LO;
+ end
+ end
+ else
+ begin
+ next_wr_state = SDR16_IDLE;
+ end
+ end
+ SDR16_WR_LO:
+ begin
+ if(app_wr_next)
+ begin
+ upper_word = 1'b1;
+ next_wr_state = SDR16_WR_HI;
+ end
+ end
+ SDR16_WR_HI:
+ begin
+ if(app_wr_next_int)
+ if(~(|wr_xfr_count))
+ begin
+ lcl_wr_next = 1'b1;
+ next_wr_state = SDR16_IDLE;
+ end
+ else
+ begin
+ lcl_wr_next = 1'b1;
+ next_wr_state = SDR16_WR_LO;
+ end
+ end
+ default:
+ begin
+ next_wr_state = SDR16_IDLE;
+ end
+ endcase
+ end
+//
+// READS
+//
+always @(*) begin
+
+ lcl_rd_valid = 1'b0;
+ save_lower = 1'b0;
+ next_rd_state = rd_state;
+
+ case(rd_state)
+ SDR16_IDLE:
+ begin
+ if(app_req_ack_int && sdr_width)
+ begin
+ if(app_req_wr_n)
+ begin
+ next_rd_state = SDR16_RD_LO;
+ end
+ end
+ else
+ begin
+ next_rd_state = SDR16_IDLE;
+ end
+ end
+ SDR16_RD_LO:
+ begin
+ if(app_rd_valid_int)
+ begin
+ save_lower = 1'b1;
+ next_rd_state = SDR16_RD_HI;
+ end
+ end
+ SDR16_RD_HI:
+ begin
+ if(app_rd_valid_int)
+ if(~(|rd_xfr_count))
+ begin
+ lcl_rd_valid = 1'b1;
+ next_rd_state = SDR16_IDLE;
+ end
+ else
+ begin
+ lcl_rd_valid = 1'b1;
+ next_rd_state = SDR16_RD_LO;
+ end
+ end
+ default:
+ begin
+ next_rd_state = SDR16_IDLE;
+ end
+ endcase
+ end
+
+reg lcl_mc_req_wr_n;
+
+always @(posedge clk)
+ begin
+ if(!reset_n)
+ begin
+ rd_xfr_count <= 8'b0;
+ wr_xfr_count <= 8'b0;
+ lcl_mc_req_wr_n <= 1'b1;
+ end
+ else
+ begin
+ if(app_req_ack) begin
+ wr_xfr_count <= app_req_len - 1'b1;
+ rd_xfr_count <= app_req_len - 1'b1;
+ lcl_mc_req_wr_n <= app_req_wr_n;
+ end
+ else if((lcl_wr_next & !lcl_mc_req_wr_n) || (lcl_rd_valid & lcl_mc_req_wr_n)) begin
+ wr_xfr_count <= wr_xfr_count - 1'b1;
+ rd_xfr_count <= rd_xfr_count - 1'b1;
+ end
+ end
+ end
+//
+//
+always @(posedge clk)
+ begin
+ if(!reset_n)
+ begin
+ rd_state <= SDR16_IDLE;
+ wr_state <= SDR16_IDLE;
+ saved_rd_data <= 16'b0;
+ write_upper <= 1'b0;
+ end
+ else
+ begin
+ rd_state <= next_rd_state;
+ wr_state <= next_wr_state;
+ if(save_lower)
+ saved_rd_data <= app_rd_data_int[15:0];
+ write_upper <= upper_word;
+ end
+ end
+
+endmodule // sdr_bs_convert
rtl/core/sdrc_bs_convert.v
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: rtl/core/sdrc_core.v
===================================================================
--- rtl/core/sdrc_core.v (nonexistent)
+++ rtl/core/sdrc_core.v (revision 3)
@@ -0,0 +1,465 @@
+/*********************************************************************
+
+ SDRAM Controller Core File
+
+ This file is part of the sdram controller project
+ http://www.opencores.org/cores/sdr_ctrl/
+
+ Description: SDRAM Controller Core Module
+ 2 types of SDRAMs are supported, 1Mx16 2 bank, or 4Mx16 4 bank.
+ This block integrate following sub modules
+
+ sdrc_bs_convert
+ convert the system side 32 bit into equvailent 16/32 SDR format
+ sdrc_req_gen
+ This module takes requests from the app, chops them to burst booundaries
+ if wrap=0, decodes the bank and passe the request to bank_ctl
+ sdrc_xfr_ctl
+ This module takes requests from sdr_bank_ctl, runs the transfer and
+ controls data flow to/from the app. At the end of the transfer it issues a
+ burst terminate if not at the end of a burst and another command to this
+ bank is not available.
+
+ sdrc_bank_ctl
+ This module takes requests from sdr_req_gen, checks for page hit/miss and
+ issues precharge/activate commands and then passes the request to
+ sdr_xfr_ctl.
+
+
+ Assumption: SDRAM Pads should be placed near to this module. else
+ user should add a FF near the pads
+
+ To Do:
+ nothing
+
+ Author(s):
+ - Dinesh Annayya, dinesha@opencores.org
+ Version : 1.0 - 8th Jan 2012
+
+
+
+ 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.def"
+module sdrc_core
+ (
+ sdram_clk,
+ pad_sdram_clk,
+ reset_n,
+ sdr_width,
+
+ /* Request from app */
+ app_req, // Transfer Request
+ app_req_addr, // SDRAM Address
+ app_req_addr_mask, // Address mask for queue wrap
+ app_req_len, // Burst Length (in 16 bit words)
+ app_req_wrap, // Wrap mode request (xfr_len = 4)
+ app_req_wr_n, // 0 => Write request, 1 => read req
+ app_req_ack, // Request has been accepted
+ sdr_core_busy_n, // OK to arbitrate next request
+ cfg_req_depth, //how many req. buffer should hold
+
+ app_wr_data,
+ app_wr_en_n,
+ app_rd_data,
+ app_rd_valid,
+ app_wr_next_req,
+ sdr_init_done,
+ app_req_dma_last,
+
+ /* Interface to SDRAMs */
+ sdr_cs_n,
+ sdr_cke,
+ sdr_ras_n,
+ sdr_cas_n,
+ sdr_we_n,
+ sdr_dqm,
+ sdr_ba,
+ sdr_addr,
+ pad_sdr_din,
+ sdr_dout,
+ sdr_den_n,
+
+ /* Parameters */
+ cfg_sdr_en,
+ cfg_sdr_dev_config, // using 64M/4bank SDRAMs
+ 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 = 30; // 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 = 16; // SDR Data Width
+parameter SDR_BW = 2; // SDR Byte Width
+
+
+//-----------------------------------------------
+// Global Variable
+// ----------------------------------------------
+input sdram_clk ; // SDRAM Clock
+input pad_sdram_clk ; // SDRAM Clock from Pad, used for registering Read Data
+input reset_n ; // Reset Signal
+input sdr_width ; // 0 - 32 Bit SDR, 1 - 16 Bit SDR
+
+//------------------------------------------------
+// Request from app
+//------------------------------------------------
+input app_req ; // Application Request
+input [APP_AW-1:0] app_req_addr ; // Address
+input [APP_AW-2:0] app_req_addr_mask ; // Address Mask
+input app_req_wr_n ; // 0 - Write, 1 - Read
+input app_req_wrap ; // Address Wrap
+output app_req_ack ; // Application Request Ack
+output sdr_core_busy_n ; // 0 - busy, 1 - free
+
+input [APP_DW-1:0] app_wr_data ; // Write Data
+output app_wr_next_req ; // Next Write Data Request
+input [APP_BW-1:0] app_wr_en_n ; // Byte wise Write Enable
+output [APP_DW-1:0] app_rd_data ; // Read Data
+output app_rd_valid ; // Read Valid
+
+//------------------------------------------------
+// Interface to SDRAMs
+//------------------------------------------------
+output sdr_cke ; // SDRAM CKE
+output sdr_cs_n ; // SDRAM Chip Select
+output sdr_ras_n ; // SDRAM ras
+output sdr_cas_n ; // SDRAM cas
+output sdr_we_n ; // SDRAM write enable
+output [SDR_BW-1:0] sdr_dqm ; // SDRAM Data Mask
+output [1:0] sdr_ba ; // SDRAM Bank Enable
+output [11:0] sdr_addr ; // SDRAM Address
+input [SDR_DW-1:0] pad_sdr_din ; // SDRA Data Input
+output [SDR_DW-1:0] sdr_dout ; // SDRAM Data Output
+output [SDR_BW-1:0] sdr_den_n ; // SDRAM Data Output enable
+
+//------------------------------------------------
+// Configuration Parameter
+//------------------------------------------------
+output sdr_init_done ;
+input [3:0] cfg_sdr_tras_d ;
+input [3:0] cfg_sdr_trp_d ;
+input [3:0] cfg_sdr_trcd_d ;
+input cfg_sdr_en ;
+input [1:0] cfg_sdr_dev_config ; // 2'b00 - 8 MB, 01 - 16 MB, 10 - 32 MB , 11 - 64 MB
+input [1:0] cfg_req_depth ;
+input [APP_RW-1:0] app_req_len ;
+input [11:0] cfg_sdr_mode_reg ;
+input [2:0] cfg_sdr_cas ;
+input [3:0] cfg_sdr_trcar_d ;
+input [3:0] cfg_sdr_twr_d ;
+input [`SDR_RFSH_TIMER_W-1 : 0] cfg_sdr_rfsh;
+input [`SDR_RFSH_ROW_CNT_W -1 : 0] cfg_sdr_rfmax;
+input app_req_dma_last; // this signal should close the bank
+
+/****************************************************************************/
+// Internal Nets
+
+// SDR_REQ_GEN
+wire r2x_idle, app_req_ack,app_req_ack_int;
+wire app_req_dma_last_int;
+wire r2b_req, r2b_start, r2b_last, r2b_write;
+wire [`SDR_REQ_ID_W-1:0]r2b_req_id;
+wire [1:0] r2b_ba;
+wire [11:0] r2b_raddr;
+wire [11:0] r2b_caddr;
+wire [APP_RW-1:0] r2b_len;
+
+// SDR BANK CTL
+wire b2r_ack, b2x_idle;
+wire b2x_req, b2x_start, b2x_last, b2x_tras_ok;
+wire [`SDR_REQ_ID_W-1:0]b2x_id;
+wire [1:0] b2x_ba;
+wire b2x_ba_last;
+wire [11:0] b2x_addr;
+wire [APP_RW-1:0] b2x_len;
+wire [1:0] b2x_cmd;
+
+// SDR_XFR_CTL
+wire x2b_ack;
+wire [3:0] x2b_pre_ok;
+wire x2b_refresh, x2b_act_ok, x2b_rdok, x2b_wrok;
+wire xfr_rdstart, xfr_rdlast;
+wire xfr_wrstart, xfr_wrlast;
+wire [`SDR_REQ_ID_W-1:0]xfr_id;
+wire [13:0] xfr_addr_msb;
+wire [APP_DW-1:0] app_rd_data;
+wire app_wr_next_req, app_rd_valid;
+wire sdr_cs_n, sdr_cke, sdr_ras_n, sdr_cas_n, sdr_we_n;
+wire [SDR_BW-1:0] sdr_dqm;
+wire [1:0] sdr_ba;
+wire [11:0] sdr_addr;
+wire [SDR_DW-1:0] sdr_dout;
+wire [SDR_DW-1:0] sdr_dout_int;
+wire [SDR_BW-1:0] sdr_den_n;
+wire [SDR_BW-1:0] sdr_den_n_int;
+
+wire [1:0] xfr_bank_sel;
+wire [1:0] cfg_sdr_dev_config;
+
+wire [APP_AW:0] app_req_addr_int;
+wire [APP_AW-1:0] app_req_addr;
+wire [APP_RW-1:0] app_req_len_int;
+wire [APP_RW-1:0] app_req_len;
+
+wire [APP_DW-1:0] app_wr_data;
+wire [SDR_DW-1:0] add_wr_data_int;
+wire [APP_BW-1:0] app_wr_en_n;
+wire [SDR_BW-1:0] app_wr_en_n_int;
+
+//wire [31:0] app_rd_data;
+wire [SDR_DW-1:0] app_rd_data_int;
+
+//
+wire app_req_int;
+wire r2b_wrap;
+wire b2r_arb_ok;
+wire b2x_wrap;
+wire app_wr_next_int;
+wire app_rd_valid_int;
+
+// synopsys translate_off
+ wire [3:0] sdr_cmd;
+ assign sdr_cmd = {sdr_cs_n, sdr_ras_n, sdr_cas_n, sdr_we_n};
+// synopsys translate_on
+
+ assign sdr_den_n = sdr_width ? {2'b00,sdr_den_n_int[1:0]} : sdr_den_n_int;
+ assign sdr_dout = sdr_width ? {16'h0000,sdr_dout_int[15:0]} : sdr_dout_int;
+
+
+ /****************************************************************************/
+ // Instantiate sdr_req_gen
+ // This module takes requests from the app, chops them to burst booundaries
+ // if wrap=0, decodes the bank and passe the request to bank_ctl
+
+ sdrc_req_gen u_req_gen (
+ .clk (sdram_clk ),
+ .reset_n (reset_n ),
+ .sdr_dev_config (cfg_sdr_dev_config ),
+
+ /* Request from app */
+ .r2x_idle (r2x_idle ),
+ .req (app_req_int ),
+ .req_id (4'b0 ),
+ .req_addr (app_req_addr_int ),
+ .req_addr_mask (app_req_addr_mask ),
+ .req_len (app_req_len_int ),
+ .req_wrap (app_req_wrap ),
+ .req_wr_n (app_req_wr_n ),
+ .req_ack (app_req_ack_int ),
+ .sdr_core_busy_n (sdr_core_busy_n ),
+
+ /* Req to bank_ctl */
+ .r2b_req (r2b_req ),
+ .r2b_req_id (r2b_req_id ),
+ .r2b_start (r2b_start ),
+ .r2b_last (r2b_last ),
+ .r2b_wrap (r2b_wrap ),
+ .r2b_ba (r2b_ba ),
+ .r2b_raddr (r2b_raddr ),
+ .r2b_caddr (r2b_caddr ),
+ .r2b_len (r2b_len ),
+ .r2b_write (r2b_write ),
+ .b2r_ack (b2r_ack ),
+ .b2r_arb_ok (b2r_arb_ok ),
+ .sdr_width (sdr_width ),
+ .sdr_init_done (sdr_init_done )
+ );
+
+ /****************************************************************************/
+ // Instantiate sdr_bank_ctl
+ // This module takes requests from sdr_req_gen, checks for page hit/miss and
+ // issues precharge/activate commands and then passes the request to
+ // sdr_xfr_ctl.
+
+ sdrc_bank_ctl u_bank_ctl (
+ .clk (sdram_clk ),
+ .reset_n (reset_n ),
+ .a2b_req_depth (cfg_req_depth ),
+
+ /* Req from req_gen */
+ .r2b_req (r2b_req ),
+ .r2b_req_id (r2b_req_id ),
+ .r2b_start (r2b_start ),
+ .r2b_last (r2b_last ),
+ .r2b_wrap (r2b_wrap ),
+ .r2b_ba (r2b_ba ),
+ .r2b_raddr (r2b_raddr ),
+ .r2b_caddr (r2b_caddr ),
+ .r2b_len (r2b_len ),
+ .r2b_write (r2b_write ),
+ .b2r_arb_ok (b2r_arb_ok ),
+ .b2r_ack (b2r_ack ),
+
+ /* Transfer request to xfr_ctl */
+ .b2x_idle (b2x_idle ),
+ .b2x_req (b2x_req ),
+ .b2x_start (b2x_start ),
+ .b2x_last (b2x_last ),
+ .b2x_wrap (b2x_wrap ),
+ .b2x_id (b2x_id ),
+ .b2x_ba (b2x_ba ),
+ .b2x_addr (b2x_addr ),
+ .b2x_len (b2x_len ),
+ .b2x_cmd (b2x_cmd ),
+ .x2b_ack (x2b_ack ),
+
+ /* Status from xfr_ctl */
+ .b2x_tras_ok (b2x_tras_ok ),
+ .x2b_refresh (x2b_refresh ),
+ .x2b_pre_ok (x2b_pre_ok ),
+ .x2b_act_ok (x2b_act_ok ),
+ .x2b_rdok (x2b_rdok ),
+ .x2b_wrok (x2b_wrok ),
+
+ /* for generate cuurent xfr address msb */
+ .sdr_dev_config (cfg_sdr_dev_config ),
+ .sdr_req_norm_dma_last(app_req_dma_last_int),
+ .xfr_bank_sel (xfr_bank_sel ),
+ .xfr_addr_msb (xfr_addr_msb ),
+
+ /* SDRAM Timing */
+ .tras_delay (cfg_sdr_tras_d ),
+ .trp_delay (cfg_sdr_trp_d ),
+ .trcd_delay (cfg_sdr_trcd_d )
+ );
+
+ /****************************************************************************/
+ // Instantiate sdr_xfr_ctl
+ // This module takes requests from sdr_bank_ctl, runs the transfer and
+ // controls data flow to/from the app. At the end of the transfer it issues a
+ // burst terminate if not at the end of a burst and another command to this
+ // bank is not available.
+
+ sdrc_xfr_ctl u_xfr_ctl (
+ .clk (sdram_clk ),
+ .reset_n (reset_n ),
+
+ /* Transfer request from bank_ctl */
+ .r2x_idle (r2x_idle ),
+ .b2x_idle (b2x_idle ),
+ .b2x_req (b2x_req ),
+ .b2x_start (b2x_start ),
+ .b2x_last (b2x_last ),
+ .b2x_wrap (b2x_wrap ),
+ .b2x_id (b2x_id ),
+ .b2x_ba (b2x_ba ),
+ .b2x_addr (b2x_addr ),
+ .b2x_len (b2x_len ),
+ .b2x_cmd (b2x_cmd ),
+ .x2b_ack (x2b_ack ),
+
+ /* Status to bank_ctl, req_gen */
+ .b2x_tras_ok (b2x_tras_ok ),
+ .x2b_refresh (x2b_refresh ),
+ .x2b_pre_ok (x2b_pre_ok ),
+ .x2b_act_ok (x2b_act_ok ),
+ .x2b_rdok (x2b_rdok ),
+ .x2b_wrok (x2b_wrok ),
+
+ /* SDRAM I/O */
+ .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 ),
+ .sdr_din (pad_sdr_din ),
+ .sdr_dout (sdr_dout_int ),
+ .sdr_den_n (sdr_den_n_int ),
+
+ /* Data Flow to the app */
+ .x2a_rdstart (xfr_rdstart ),
+ .x2a_wrstart (xfr_wrstart ),
+ .x2a_id (xfr_id ),
+ .x2a_rdlast (xfr_rdlast ),
+ .x2a_wrlast (xfr_wrlast ),
+ .app_wrdt (add_wr_data_int ),
+ .app_wren_n (add_wr_en_n_int ),
+ .x2a_wrnext (app_wr_next_int ),
+ .x2a_rddt (app_rd_data_int ),
+ .x2a_rdok (app_rd_valid_int ),
+ .sdr_init_done (sdr_init_done ),
+
+ /* SDRAM Parameters */
+ .sdram_enable (cfg_sdr_en ),
+ .sdram_mode_reg (cfg_sdr_mode_reg ),
+
+ /* current xfr bank */
+ .xfr_bank_sel (xfr_bank_sel ),
+
+ /* SDRAM Timing */
+ .cas_latency (cfg_sdr_cas ),
+ .trp_delay (cfg_sdr_trp_d ),
+ .trcar_delay (cfg_sdr_trcar_d ),
+ .twr_delay (cfg_sdr_twr_d ),
+ .rfsh_time (cfg_sdr_rfsh ),
+ .rfsh_rmax (cfg_sdr_rfmax )
+ );
+
+sdrc_bs_convert u_bs_convert (
+ .clk (sdram_clk ),
+ .reset_n (reset_n ),
+ .sdr_width (sdr_width ),
+
+ .app_req_addr (app_req_addr ),
+ .app_req_addr_int (app_req_addr_int ),
+ .app_req_len (app_req_len ),
+ .app_req_len_int (app_req_len_int ),
+ .app_sdr_req (app_req ),
+ .app_sdr_req_int (app_req_int ),
+ .app_req_dma_last (app_req_dma_last ),
+ .app_req_dma_last_int(app_req_dma_last_int),
+ .app_req_wr_n (app_req_wr_n ),
+ .app_req_ack16 (app_req_ack_int ),
+ .app_req_ack (app_req_ack ),
+
+ .app_wr_data (app_wr_data ),
+ .app_wr_data_int (add_wr_data_int ),
+ .app_wr_en_n (app_wr_en_n ),
+ .app_wr_en_n_int (app_wr_en_n_int ),
+ .app_wr_next_int (app_wr_next_int ),
+ .app_wr_next (app_wr_next_req ),
+
+ .app_rd_data_int (app_rd_data_int ),
+ .app_rd_data (app_rd_data ),
+ .app_rd_valid_int (app_rd_valid_int ),
+ .app_rd_valid (app_rd_valid )
+ );
+
+endmodule // sdrc_core
rtl/core/sdrc_core.v
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: rtl/core/sdrc.def
===================================================================
--- rtl/core/sdrc.def (nonexistent)
+++ rtl/core/sdrc.def (revision 3)
@@ -0,0 +1,32 @@
+
+`define SDR_REQ_ID_W 4
+
+`define SDR_RFSH_TIMER_W 12
+`define SDR_RFSH_ROW_CNT_W 3
+
+// B2X Command
+
+`define OP_PRE 2'b00
+`define OP_ACT 2'b01
+`define OP_RD 2'b10
+`define OP_WR 2'b11
+
+// SDRAM Commands (CS_N, RAS_N, CAS_N, WE_N)
+
+`define SDR_DESEL 4'b1111
+`define SDR_NOOP 4'b0111
+`define SDR_ACTIVATE 4'b0011
+`define SDR_READ 4'b0101
+`define SDR_WRITE 4'b0100
+`define SDR_BT 4'b0110
+`define SDR_PRECHARGE 4'b0010
+`define SDR_REFRESH 4'b0001
+`define SDR_MODE 4'b0000
+
+// sdr configuration
+`define SDR_CONFIG_IS_8M 2'b00
+`define SDR_CONFIG_IS_16M 2'b01
+`define SDR_CONFIG_IS_32M 2'b10
+`define SDR_CONFIG_IS_LGCY 2'b11
+
+
rtl/core/sdrc.def
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: rtl/core/sdrc_bank_ctl.v
===================================================================
--- rtl/core/sdrc_bank_ctl.v (nonexistent)
+++ rtl/core/sdrc_bank_ctl.v (revision 3)
@@ -0,0 +1,323 @@
+/*********************************************************************
+
+ SDRAM Controller Bank Controller
+
+ This file is part of the sdram controller project
+ http://www.opencores.org/cores/sdr_ctrl/
+
+ Description:
+ This module takes requests from sdrc_req_gen, checks for page hit/miss and
+ issues precharge/activate commands and then passes the request to sdrc_xfr_ctl.
+
+ To Do:
+ nothing
+
+ Author(s):
+ - Dinesh Annayya, dinesha@opencores.org
+ Version : 1.0 - 8th Jan 2012
+
+
+
+ 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.def"
+
+module sdrc_bank_ctl (clk,
+ reset_n,
+
+ /* Req from req_gen */
+ r2b_req, // request
+ r2b_req_id, // ID
+ r2b_start, // First chunk of burst
+ r2b_last, // Last chunk of burst
+ r2b_wrap,
+ r2b_raddr, // row address
+ r2b_caddr, // col address
+ r2b_len, // length
+ r2b_write, // write request
+ b2r_ack,
+ sdr_dma_last,
+
+ /* Transfer request to xfr_ctl */
+ b2x_req, // Request to xfr_ctl
+ b2x_start, // first chunk of transfer
+ b2x_last, // last chunk of transfer
+ b2x_wrap,
+ b2x_id, // Transfer ID
+ b2x_addr, // row/col address
+ b2x_len, // transfer length
+ b2x_cmd, // transfer command
+ x2b_ack, // command accepted
+
+ /* Status to/from xfr_ctl */
+ tras_ok, // TRAS OK for this bank
+ xfr_ok,
+ x2b_refresh, // We did a refresh
+ x2b_pre_ok, // OK to do a precharge (per bank)
+ x2b_act_ok, // OK to do an activate
+ x2b_rdok, // OK to do a read
+ x2b_wrok, // OK to do a write
+
+ /* current xfr row address of the bank */
+ bank_row,
+
+ /* SDRAM Timing */
+ tras_delay, // Active to precharge delay
+ trp_delay, // Precharge to active delay
+ trcd_delay); // Active to R/W delay
+
+parameter APP_AW = 30; // 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 = 16; // SDR Data Width
+parameter SDR_BW = 2; // SDR Byte Width
+ input clk, reset_n;
+
+ /* Req from bank_ctl */
+ input r2b_req, r2b_start, r2b_last,
+ r2b_write, r2b_wrap;
+ input [`SDR_REQ_ID_W-1:0] r2b_req_id;
+ input [11:0] r2b_raddr;
+ input [11:0] r2b_caddr;
+ input [APP_RW-1:0] r2b_len;
+ output b2r_ack;
+ input sdr_dma_last;
+
+ /* Req to xfr_ctl */
+ output b2x_req, b2x_start, b2x_last,
+ tras_ok, b2x_wrap;
+ output [`SDR_REQ_ID_W-1:0] b2x_id;
+ output [11:0] b2x_addr;
+ output [APP_RW-1:0] b2x_len;
+ output [1:0] b2x_cmd;
+ input x2b_ack;
+
+ /* Status from xfr_ctl */
+ input x2b_refresh, x2b_act_ok, x2b_rdok,
+ x2b_wrok, x2b_pre_ok, xfr_ok;
+
+ input [3:0] tras_delay, trp_delay, trcd_delay;
+
+ output [11:0] bank_row;
+
+ /****************************************************************************/
+ // Internal Nets
+
+ `define BANK_IDLE 3'b000
+ `define BANK_PRE 3'b001
+ `define BANK_ACT 3'b010
+ `define BANK_XFR 3'b011
+ `define BANK_DMA_LAST_PRE 3'b100
+
+ reg [2:0] bank_st, next_bank_st;
+ wire b2x_start, b2x_last;
+ reg l_start, l_last;
+ reg b2x_req, b2r_ack;
+ wire [`SDR_REQ_ID_W-1:0] b2x_id;
+ reg [`SDR_REQ_ID_W-1:0] l_id;
+ reg [11:0] b2x_addr;
+ reg [APP_RW-1:0] l_len;
+ wire [APP_RW-1:0] b2x_len;
+ reg [1:0] b2x_cmd;
+ reg bank_valid;
+ reg [11:0] bank_row;
+ reg [3:0] tras_cntr, timer0;
+ reg l_wrap, l_write;
+ wire b2x_wrap;
+ reg [11:0] l_raddr;
+ reg [11:0] l_caddr;
+ reg l_sdr_dma_last;
+ reg bank_prech_page_closed;
+
+ wire tras_ok_internal, tras_ok, activate_bank;
+
+ wire page_hit, timer0_tc, ld_trp, ld_trcd;
+
+ always @ (posedge clk)
+ if (~reset_n) begin
+ bank_valid <= 1'b0;
+ tras_cntr <= 4'b0;
+ timer0 <= 4'b0;
+ bank_st <= `BANK_IDLE;
+ end // if (~reset_n)
+
+ else begin
+
+ bank_valid <= (x2b_refresh || bank_prech_page_closed) ? 1'b0 : // force the bank status to be invalid
+// bank_valid <= (x2b_refresh) ? 1'b0 :
+ (activate_bank) ? 1'b1 : bank_valid;
+
+ tras_cntr <= (activate_bank) ? tras_delay :
+ (~tras_ok_internal) ? tras_cntr - 4'b1 : 4'b0;
+
+ timer0 <= (ld_trp) ? trp_delay :
+ (ld_trcd) ? trcd_delay :
+ (~timer0_tc) ? timer0 - 4'b1 : timer0;
+
+ bank_st <= next_bank_st;
+
+ end // else: !if(~reset_n)
+
+ always @ (posedge clk) begin
+
+ bank_row <= (activate_bank) ? b2x_addr : bank_row;
+
+ if (~reset_n) begin
+ l_start <= 1'b0;
+ l_last <= 1'b0;
+ l_id <= 1'b0;
+ l_len <= 1'b0;
+ l_wrap <= 1'b0;
+ l_write <= 1'b0;
+ l_raddr <= 1'b0;
+ l_caddr <= 1'b0;
+ l_sdr_dma_last <= 1'b0;
+ end
+ else begin
+ if (b2r_ack) begin
+ l_start <= r2b_start;
+ l_last <= r2b_last;
+ l_id <= r2b_req_id;
+ l_len <= r2b_len;
+ l_wrap <= r2b_wrap;
+ l_write <= r2b_write;
+ l_raddr <= r2b_raddr;
+ l_caddr <= r2b_caddr;
+ l_sdr_dma_last <= sdr_dma_last;
+ end // if (b2r_ack)
+ end
+
+ end // always @ (posedge clk)
+
+ assign tras_ok_internal = ~|tras_cntr;
+ assign tras_ok = tras_ok_internal;
+
+ assign activate_bank = (b2x_cmd == `OP_ACT) & x2b_ack;
+
+ assign page_hit = (r2b_raddr == bank_row) ? bank_valid : 1'b0; // its a hit only if bank is valid
+
+ assign timer0_tc = ~|timer0;
+
+ assign ld_trp = (b2x_cmd == `OP_PRE) ? x2b_ack : 1'b0;
+
+ assign ld_trcd = (b2x_cmd == `OP_ACT) ? x2b_ack : 1'b0;
+
+ always @ (*) begin
+
+ bank_prech_page_closed = 1'b0;
+ b2x_req = 1'b0;
+ b2x_cmd = 2'bx;
+ b2r_ack = 1'b0;
+ b2x_addr = 12'bx;
+ next_bank_st = bank_st;
+
+ case (bank_st)
+
+ `BANK_IDLE : begin
+
+ if (~r2b_req) begin
+ bank_prech_page_closed = 1'b0;
+ b2x_req = 1'b0;
+ b2x_cmd = 2'bx;
+ b2r_ack = 1'b0;
+ b2x_addr = 12'bx;
+ next_bank_st = `BANK_IDLE;
+ end // if (~r2b_req)
+ else if (page_hit) begin
+ b2x_req = (r2b_write) ? x2b_wrok & xfr_ok :
+ x2b_rdok & xfr_ok;
+ b2x_cmd = (r2b_write) ? `OP_WR : `OP_RD;
+ b2r_ack = 1'b1;
+ b2x_addr = r2b_caddr;
+ next_bank_st = (x2b_ack) ? `BANK_IDLE : `BANK_XFR; // in case of hit, stay here till xfr sm acks
+ end // if (page_hit)
+ else begin // page_miss
+ b2x_req = tras_ok_internal & x2b_pre_ok;
+ b2x_cmd = `OP_PRE;
+ b2r_ack = 1'b1;
+ b2x_addr = r2b_raddr & 12'hBFF; // Dont want to pre all banks!
+ next_bank_st = (l_sdr_dma_last) ? `BANK_PRE : (x2b_ack) ? `BANK_ACT : `BANK_PRE; // bank was precharged on l_sdr_dma_last
+ end // else: !if(page_hit)
+
+ end // case: `BANK_IDLE
+
+ `BANK_PRE : begin
+ b2x_req = tras_ok_internal & x2b_pre_ok;
+ b2x_cmd = `OP_PRE;
+ b2r_ack = 1'b0;
+ b2x_addr = l_raddr & 12'hBFF; // Dont want to pre all banks!
+ bank_prech_page_closed = 1'b0;
+ next_bank_st = (x2b_ack) ? `BANK_ACT : `BANK_PRE;
+ end // case: `BANK_PRE
+
+ `BANK_ACT : begin
+ b2x_req = timer0_tc & x2b_act_ok;
+ b2x_cmd = `OP_ACT;
+ b2r_ack = 1'b0;
+ b2x_addr = l_raddr;
+ bank_prech_page_closed = 1'b0;
+ next_bank_st = (x2b_ack) ? `BANK_XFR : `BANK_ACT;
+ end // case: `BANK_ACT
+
+ `BANK_XFR : begin
+ b2x_req = (l_write) ? timer0_tc & x2b_wrok & xfr_ok :
+ timer0_tc & x2b_rdok & xfr_ok;
+ b2x_cmd = (l_write) ? `OP_WR : `OP_RD;
+ b2r_ack = 1'b0;
+ b2x_addr = l_caddr;
+ bank_prech_page_closed = 1'b0;
+ next_bank_st = (x2b_refresh) ? `BANK_ACT :
+ (x2b_ack & l_sdr_dma_last) ? `BANK_DMA_LAST_PRE :
+ (x2b_ack) ? `BANK_IDLE : `BANK_XFR;
+ end // case: `BANK_XFR
+
+ `BANK_DMA_LAST_PRE : begin
+ b2x_req = tras_ok_internal & x2b_pre_ok;
+ b2x_cmd = `OP_PRE;
+ b2r_ack = 1'b0;
+ b2x_addr = l_raddr & 12'hBFF; // Dont want to pre all banks!
+ bank_prech_page_closed = 1'b1;
+ next_bank_st = (x2b_ack) ? `BANK_IDLE : `BANK_DMA_LAST_PRE;
+ end // case: `BANK_DMA_LAST_PRE
+
+ endcase // case(bank_st)
+
+ end // always @ (bank_st or ...)
+
+ assign b2x_start = (bank_st == `BANK_IDLE) ? r2b_start : l_start;
+
+ assign b2x_last = (bank_st == `BANK_IDLE) ? r2b_last : l_last;
+
+ assign b2x_id = (bank_st == `BANK_IDLE) ? r2b_req_id : l_id;
+
+ assign b2x_len = (bank_st == `BANK_IDLE) ? r2b_len : l_len;
+
+ assign b2x_wrap = (bank_st == `BANK_IDLE) ? r2b_wrap : l_wrap;
+
+endmodule // sdr_bank_fsm
rtl/core/sdrc_bank_ctl.v
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property