OpenCores
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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.