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/rtl
    from Rev 50 to Rev 51
    Reverse comparison

Rev 50 → Rev 51

/core/sdrc_bank_fsm.v
96,7 → 96,9
 
parameter SDR_DW = 16; // SDR Data Width
parameter SDR_BW = 2; // SDR Byte Width
parameter REQ_BW = 12; // Request Width
// 12 bit subtractor is not feasibile for FPGA, so changed to 8 bits
parameter REQ_BW = (`TARGET_DESIGN == `FPGA) ? 8 : 12; // Request Width
 
input clk, reset_n;
 
/* Req from bank_ctl */
144,7 → 146,7
reg [11:0] b2x_addr;
reg [REQ_BW-1:0] l_len;
wire [REQ_BW-1:0] b2x_len;
reg [1:0] b2x_cmd;
reg [1:0] b2x_cmd_t;
reg bank_valid;
reg [11:0] bank_row;
reg [3:0] tras_cntr, timer0;
157,10 → 159,47
wire tras_ok_internal, tras_ok, activate_bank;
wire page_hit, timer0_tc, ld_trp, ld_trcd;
wire page_hit, timer0_tc_t, ld_trp, ld_trcd;
 
/*** Timing Break Logic Added for FPGA - Start ****/
reg x2b_wrok_r, xfr_ok_r , x2b_rdok_r;
reg [1:0] b2x_cmd_r,timer0_tc_r,tras_ok_r,x2b_pre_ok_r,x2b_act_ok_r;
always @ (posedge clk)
if (~reset_n) begin
x2b_wrok_r <= 1'b0;
xfr_ok_r <= 1'b0;
x2b_rdok_r <= 1'b0;
b2x_cmd_r <= 2'b0;
timer0_tc_r <= 1'b0;
tras_ok_r <= 1'b0;
x2b_pre_ok_r <= 1'b0;
x2b_act_ok_r <= 1'b0;
end
else begin
x2b_wrok_r <= x2b_wrok;
xfr_ok_r <= xfr_ok;
x2b_rdok_r <= x2b_rdok;
b2x_cmd_r <= b2x_cmd_t;
timer0_tc_r <= (ld_trp | ld_trcd) ? 1'b0 : timer0_tc_t;
tras_ok_r <= tras_ok_internal;
x2b_pre_ok_r <= x2b_pre_ok;
x2b_act_ok_r <= x2b_act_ok;
end
 
wire x2b_wrok_t = (`TARGET_DESIGN == `FPGA) ? x2b_wrok_r : x2b_wrok;
wire xfr_ok_t = (`TARGET_DESIGN == `FPGA) ? xfr_ok_r : xfr_ok;
wire x2b_rdok_t = (`TARGET_DESIGN == `FPGA) ? x2b_rdok_r : x2b_rdok;
wire [1:0] b2x_cmd = (`TARGET_DESIGN == `FPGA) ? b2x_cmd_r : b2x_cmd_t;
wire timer0_tc = (`TARGET_DESIGN == `FPGA) ? timer0_tc_r : timer0_tc_t;
assign tras_ok = (`TARGET_DESIGN == `FPGA) ? tras_ok_r : tras_ok_internal;
wire x2b_pre_ok_t = (`TARGET_DESIGN == `FPGA) ? x2b_pre_ok_r : x2b_pre_ok;
wire x2b_act_ok_t = (`TARGET_DESIGN == `FPGA) ? x2b_act_ok_r : x2b_act_ok;
 
/*** Timing Break Logic Added for FPGA - End****/
 
 
always @ (posedge clk)
if (~reset_n) begin
bank_valid <= 1'b0;
tras_cntr <= 4'b0;
timer0 <= 4'b0;
177,7 → 216,7
timer0 <= (ld_trp) ? trp_delay :
(ld_trcd) ? trcd_delay :
(~timer0_tc) ? timer0 - 4'b1 : timer0;
(timer0 != 'h0) ? timer0 - 4'b1 : timer0;
bank_st <= next_bank_st;
 
215,23 → 254,24
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 timer0_tc_t = ~|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;
b2x_cmd_t = 2'bx;
b2r_ack = 1'b0;
b2x_addr = 12'bx;
next_bank_st = bank_st;
239,36 → 279,50
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)
 
if(`TARGET_DESIGN == `FPGA) begin // To break the timing, b2x request are generated delayed
if (~r2b_req) begin
next_bank_st = `BANK_IDLE;
end // if (~r2b_req)
else if (page_hit) begin
b2r_ack = 1'b1;
b2x_cmd_t = (r2b_write) ? `OP_WR : `OP_RD;
next_bank_st = `BANK_XFR;
end // if (page_hit)
else begin // page_miss
b2r_ack = 1'b1;
b2x_cmd_t = `OP_PRE;
next_bank_st = `BANK_PRE; // bank was precharged on l_sdr_dma_last
end // else: !if(page_hit)
end else begin // ASIC
if (~r2b_req) begin
bank_prech_page_closed = 1'b0;
b2x_req = 1'b0;
b2x_cmd_t = 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_t & xfr_ok_t :
x2b_rdok_t & xfr_ok_t;
b2x_cmd_t = (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 & x2b_pre_ok_t;
b2x_cmd_t = `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
end // case: `BANK_IDLE
 
`BANK_PRE : begin
b2x_req = tras_ok_internal & x2b_pre_ok;
b2x_cmd = `OP_PRE;
b2x_req = tras_ok & x2b_pre_ok_t;
b2x_cmd_t = `OP_PRE;
b2r_ack = 1'b0;
b2x_addr = l_raddr & 12'hBFF; // Dont want to pre all banks!
bank_prech_page_closed = 1'b0;
276,8 → 330,8
end // case: `BANK_PRE
 
`BANK_ACT : begin
b2x_req = timer0_tc & x2b_act_ok;
b2x_cmd = `OP_ACT;
b2x_req = timer0_tc & x2b_act_ok_t;
b2x_cmd_t = `OP_ACT;
b2r_ack = 1'b0;
b2x_addr = l_raddr;
bank_prech_page_closed = 1'b0;
285,9 → 339,9
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;
b2x_req = (l_write) ? timer0_tc & x2b_wrok_t & xfr_ok_t :
timer0_tc & x2b_rdok_t & xfr_ok_t;
b2x_cmd_t = (l_write) ? `OP_WR : `OP_RD;
b2r_ack = 1'b0;
b2x_addr = l_caddr;
bank_prech_page_closed = 1'b0;
297,8 → 351,8
end // case: `BANK_XFR
 
`BANK_DMA_LAST_PRE : begin
b2x_req = tras_ok_internal & x2b_pre_ok;
b2x_cmd = `OP_PRE;
b2x_req = tras_ok & x2b_pre_ok_t;
b2x_cmd_t = `OP_PRE;
b2r_ack = 1'b0;
b2x_addr = l_raddr & 12'hBFF; // Dont want to pre all banks!
bank_prech_page_closed = 1'b1;
/core/sdrc_req_gen.v
28,7 → 28,8
The SDRAMs are operated in 4 beat burst mode.
 
If Wrap = 0;
If the current burst cross the page boundary, then this block split the request into two coressponding change in address and request length
If the current burst cross the page boundary, then this block split the request
into two coressponding change in address and request length
 
if the current burst cross the page boundar.
This module takes requests from the memory controller,
115,7 → 116,9
parameter SDR_DW = 16; // SDR Data Width
parameter SDR_BW = 2; // SDR Byte Width
 
parameter REQ_BW = 12; // Request Width
// 12 bit subtractor is not feasibile for FPGA, so changed to 8 bits
parameter REQ_BW = (`TARGET_DESIGN == `FPGA) ? 8 : 12; // Request Width
 
input clk ;
input reset_n ;
input [1:0] cfg_colbits ; // 2'b00 - 8 Bit column address, 2'b01 - 9 Bit, 10 - 10 bit, 11 - 11Bits
161,7 → 164,8
 
wire r2b_last, page_ovflw;
wire [REQ_BW-1:0] r2b_len, next_req_len;
wire [REQ_BW:0] max_r2b_len;
wire [12:0] max_r2b_len;
reg [12:0] max_r2b_len_r;
 
reg [1:0] r2b_ba;
reg [11:0] r2b_raddr;
199,9 → 203,9
// burst length, then we need to handle the bank cross over case and we
// need to split the reuest.
//
assign max_r2b_len = (cfg_colbits == 2'b00) ? (12'h100 - r2b_caddr) :
(cfg_colbits == 2'b01) ? (12'h200 - r2b_caddr) :
(cfg_colbits == 2'b10) ? (12'h400 - r2b_caddr) : (12'h800 - r2b_caddr);
assign max_r2b_len = (cfg_colbits == 2'b00) ? (12'h100 - {4'b0, req_addr_int[7:0]}) :
(cfg_colbits == 2'b01) ? (12'h200 - {3'b0, req_addr_int[8:0]}) :
(cfg_colbits == 2'b10) ? (12'h400 - {2'b0, req_addr_int[9:0]}) : (12'h800 - {1'b0, req_addr_int[10:0]});
 
 
// If the wrap = 0 and current application burst length is crossing the page boundary,
217,9 → 221,9
//
// Note: With Wrap = 0, each request from Application layer will be spilited into two request,
// if the current burst cross the page boundary.
assign page_ovflw = ({1'b0, lcl_req_len} > max_r2b_len) ? ~lcl_wrap : 1'b0;
assign page_ovflw = ({1'b0, lcl_req_len} > max_r2b_len_r) ? ~lcl_wrap : 1'b0;
 
assign r2b_len = (page_ovflw) ? max_r2b_len : lcl_req_len;
assign r2b_len = (page_ovflw) ? max_r2b_len_r : lcl_req_len;
 
assign next_req_len = lcl_req_len - r2b_len;
 
234,6 → 238,7
//
always @ (posedge clk) begin
 
max_r2b_len_r <= max_r2b_len;
r2b_start <= (req_ack) ? 1'b1 :
(b2r_ack) ? 1'b0 : r2b_start;
 
/core/sdrc_xfr_ctl.v
135,7 → 135,8
 
parameter SDR_DW = 16; // SDR Data Width
parameter SDR_BW = 2; // SDR Byte Width
parameter REQ_BW = 12; // Request Width
// 12 bit subtractor is not feasibile for FPGA, so changed to 8 bits
parameter REQ_BW = (`TARGET_DESIGN == `FPGA) ? 8 : 12; // Request Width
 
 
input clk, reset_n;
241,7 → 242,7
(sel_b2x) ? b2x_sdr_cmd : i_xfr_cmd;
 
assign xfr_addr = (sel_mgmt) ? mgmt_addr :
(sel_b2x) ? b2x_addr : xfr_caddr;
(sel_b2x) ? b2x_addr : xfr_caddr+1;
 
assign mgmt_ack = sel_mgmt;
 
251,7 → 252,9
assign xfr_len = (ld_xfr) ? b2x_len : l_len;
 
assign next_xfr_len = (xfr_end) ? xfr_len : xfr_len - 1;
//assign next_xfr_len = (l_xfr_end && !ld_xfr) ? l_len : xfr_len - 1;
assign next_xfr_len = (ld_xfr) ? b2x_len :
(l_xfr_end) ? l_len: l_len - 1;
 
assign d_rd_next = (cas_latency == 2'b01) ? l_rd_next[2] :
(cas_latency == 2'b10) ? l_rd_next[3] :
273,7 → 276,7
 
assign xfr_end = ~|xfr_len;
 
assign l_xfr_end = ~|l_len;
assign l_xfr_end = ~|(l_len-1);
 
assign rd_start = ld_xfr & b2x_read & b2x_start;
 
292,8 → 295,9
assign xfr_wrap = (ld_xfr) ? b2x_wrap : l_wrap;
// assign burst_bdry = ~|xfr_caddr[2:0];
assign burst_bdry = ~|xfr_caddr[1:0];
wire [1:0] xfr_caddr_lsb = (xfr_caddr[1:0]+1);
assign burst_bdry = ~|(xfr_caddr_lsb[1:0]);
always @ (posedge clk) begin
if (~reset_n) begin
xfr_caddr <= 12'b0;
312,9 → 316,8
end // if (~reset_n)
 
else begin
xfr_caddr <= (ld_xfr) ? b2x_addr + 12'h1 :
(rd_next | wr_next) ? xfr_caddr + 12'h1 :
xfr_caddr;
xfr_caddr <= (ld_xfr) ? b2x_addr :
(rd_next | wr_next) ? xfr_caddr + 1 : xfr_caddr;
l_start <= (dt_next) ? 1'b0 :
(ld_xfr) ? b2x_start : l_start;
l_last <= (ld_xfr) ? b2x_last : l_last;
358,7 → 361,8
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;
// Break the timing path for FPGA Based Design
cb_pre_ok = (`TARGET_DESIGN == `FPGA) ? 1'b0 : l_xfr_end;
wrok = 1'b0;
sel_mgmt = 1'b0;
 
501,11 → 505,15
 
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 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 x2b_pre_ok[0] = cb_pre_ok;
assign x2b_pre_ok[1] = cb_pre_ok;
assign x2b_pre_ok[2] = cb_pre_ok;
assign x2b_pre_ok[3] = cb_pre_ok;
assign last_burst = (ld_xfr) ? b2x_last : l_last;
/************************************************************************/
/core/sdrc_core.v
133,7 → 133,8
parameter SDR_DW = 16; // SDR Data Width
parameter SDR_BW = 2; // SDR Byte Width
parameter REQ_BW = 12; // Request Width
// 12 bit subtractor is not feasibile for FPGA, so changed to 8 bits
parameter REQ_BW = (`TARGET_DESIGN == `FPGA) ? 8 : 12; // Request Width
 
//-----------------------------------------------
// Global Variable
/core/sdrc_define.v
23,5 → 23,7
`define SDR_REFRESH 4'b0001
`define SDR_MODE 4'b0000
 
`define ASIC 1'b1
`define FPGA 1'b0
`define TARGET_DESIGN `FPGA
 
 
/core/sdrc_bank_ctl.v
100,7 → 100,8
 
parameter SDR_DW = 16; // SDR Data Width
parameter SDR_BW = 2; // SDR Byte Width
parameter REQ_BW = 12; // Request Width
// 12 bit subtractor is not feasibile for FPGA, so changed to 8 bits
parameter REQ_BW = (`TARGET_DESIGN == `FPGA) ? 8 : 12; // Request Width
input clk, reset_n;
 
input [1:0] a2b_req_depth;
172,8 → 173,9
wire [11:0] bank0_row, bank1_row, bank2_row, bank3_row;
 
assign b2x_tras_ok = &tras_ok;
assign b2x_tras_ok = &tras_ok;
 
 
// Distribute the request from req_gen
 
assign r2i_req[0] = (r2b_ba == 2'b00) ? r2b_req & ~rank_fifo_full : 1'b0;
181,10 → 183,15
assign r2i_req[2] = (r2b_ba == 2'b10) ? r2b_req & ~rank_fifo_full : 1'b0;
assign r2i_req[3] = (r2b_ba == 2'b11) ? r2b_req & ~rank_fifo_full : 1'b0;
 
/******************
Modified the Better FPGA Timing Purpose
assign b2r_ack = (r2b_ba == 2'b00) ? i2r_ack[0] :
(r2b_ba == 2'b01) ? i2r_ack[1] :
(r2b_ba == 2'b10) ? i2r_ack[2] :
(r2b_ba == 2'b11) ? i2r_ack[3] : 1'b0;
********************/
// Assumption: Only one Ack Will be asserted at a time.
assign b2r_ack =|i2r_ack;
 
assign b2r_arb_ok = ~rank_fifo_full;
198,8 → 205,11
// If the rank_fifo is empty, send the request from the bank addressed by
// r2b_ba
 
assign xfr_ba = (rank_fifo_mt) ? r2b_ba : rank_ba[1:0];
assign xfr_ba_last = (rank_fifo_mt) ? sdr_req_norm_dma_last : rank_ba_last[0];
// In FPGA Mode, to improve the timing, also send the rank_ba
assign xfr_ba = (`TARGET_DESIGN == `FPGA) ? rank_ba[1:0]:
((rank_fifo_mt) ? r2b_ba : rank_ba[1:0]);
assign xfr_ba_last = (`TARGET_DESIGN == `FPGA) ? rank_ba_last[0]:
((rank_fifo_mt) ? sdr_req_norm_dma_last : rank_ba_last[0]);
assign rank_req[0] = i2x_req[xfr_ba]; // each rank generates requests
350,17 → 360,21
rank_ba[7:6] <= (rank_wr_sel[3]) ? r2b_ba :
(rank_fifo_rd) ? 2'b00 : rank_ba[7:6];
 
rank_ba_last[0] <= (rank_wr_sel[0]) ? sdr_req_norm_dma_last :
if(`TARGET_DESIGN == `ASIC) begin // This Logic is implemented for ASIC Only
// Note: Currenly top-level does not generate the
// sdr_req_norm_dma_last signal and can be tied zero at top-level
rank_ba_last[0] <= (rank_wr_sel[0]) ? sdr_req_norm_dma_last :
(rank_fifo_rd) ? rank_ba_last[1] : rank_ba_last[0];
 
rank_ba_last[1] <= (rank_wr_sel[1]) ? sdr_req_norm_dma_last :
(rank_fifo_rd) ? rank_ba_last[2] : rank_ba_last[1];
rank_ba_last[1] <= (rank_wr_sel[1]) ? sdr_req_norm_dma_last :
(rank_fifo_rd) ? rank_ba_last[2] : rank_ba_last[1];
 
rank_ba_last[2] <= (rank_wr_sel[2]) ? sdr_req_norm_dma_last :
(rank_fifo_rd) ? rank_ba_last[3] : rank_ba_last[2];
rank_ba_last[2] <= (rank_wr_sel[2]) ? sdr_req_norm_dma_last :
(rank_fifo_rd) ? rank_ba_last[3] : rank_ba_last[2];
 
rank_ba_last[3] <= (rank_wr_sel[3]) ? sdr_req_norm_dma_last :
(rank_fifo_rd) ? 1'b0 : rank_ba_last[3];
rank_ba_last[3] <= (rank_wr_sel[3]) ? sdr_req_norm_dma_last :
(rank_fifo_rd) ? 1'b0 : rank_ba_last[3];
end
 
end // else: !if(~reset_n)

powered by: WebSVN 2.1.0

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