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 51 to Rev 50
- ↔ Reverse comparison
Rev 51 → Rev 50
/core/sdrc_bank_fsm.v
96,9 → 96,7
|
parameter SDR_DW = 16; // SDR Data Width |
parameter SDR_BW = 2; // SDR Byte Width |
// 12 bit subtractor is not feasibile for FPGA, so changed to 8 bits |
parameter REQ_BW = (`TARGET_DESIGN == `FPGA) ? 8 : 12; // Request Width |
|
parameter REQ_BW = 12; // Request Width |
input clk, reset_n; |
|
/* Req from bank_ctl */ |
146,7 → 144,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_t; |
reg [1:0] b2x_cmd; |
reg bank_valid; |
reg [11:0] bank_row; |
reg [3:0] tras_cntr, timer0; |
159,47 → 157,10
|
wire tras_ok_internal, tras_ok, activate_bank; |
|
wire page_hit, timer0_tc_t, ld_trp, ld_trcd; |
wire page_hit, timer0_tc, 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; |
216,7 → 177,7
|
timer0 <= (ld_trp) ? trp_delay : |
(ld_trcd) ? trcd_delay : |
(timer0 != 'h0) ? timer0 - 4'b1 : timer0; |
(~timer0_tc) ? timer0 - 4'b1 : timer0; |
|
bank_st <= next_bank_st; |
|
254,24 → 215,23
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_t = ~|timer0; |
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_t = 2'bx; |
b2x_cmd = 2'bx; |
b2r_ack = 1'b0; |
b2x_addr = 12'bx; |
next_bank_st = bank_st; |
279,50 → 239,36
case (bank_st) |
|
`BANK_IDLE : begin |
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 |
|
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 & x2b_pre_ok_t; |
b2x_cmd_t = `OP_PRE; |
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; |
330,8 → 276,8
end // case: `BANK_PRE |
|
`BANK_ACT : begin |
b2x_req = timer0_tc & x2b_act_ok_t; |
b2x_cmd_t = `OP_ACT; |
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; |
339,9 → 285,9
end // case: `BANK_ACT |
|
`BANK_XFR : begin |
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; |
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; |
351,8 → 297,8
end // case: `BANK_XFR |
|
`BANK_DMA_LAST_PRE : begin |
b2x_req = tras_ok & x2b_pre_ok_t; |
b2x_cmd_t = `OP_PRE; |
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; |
/core/sdrc_req_gen.v
28,8 → 28,7
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, |
116,9 → 115,7
parameter SDR_DW = 16; // SDR Data Width |
parameter SDR_BW = 2; // SDR Byte Width |
|
// 12 bit subtractor is not feasibile for FPGA, so changed to 8 bits |
parameter REQ_BW = (`TARGET_DESIGN == `FPGA) ? 8 : 12; // Request Width |
|
parameter REQ_BW = 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 |
164,8 → 161,7
|
wire r2b_last, page_ovflw; |
wire [REQ_BW-1:0] r2b_len, next_req_len; |
wire [12:0] max_r2b_len; |
reg [12:0] max_r2b_len_r; |
wire [REQ_BW:0] max_r2b_len; |
|
reg [1:0] r2b_ba; |
reg [11:0] r2b_raddr; |
203,9 → 199,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 - {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]}); |
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); |
|
|
// If the wrap = 0 and current application burst length is crossing the page boundary, |
221,9 → 217,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_r) ? ~lcl_wrap : 1'b0; |
assign page_ovflw = ({1'b0, lcl_req_len} > max_r2b_len) ? ~lcl_wrap : 1'b0; |
|
assign r2b_len = (page_ovflw) ? max_r2b_len_r : lcl_req_len; |
assign r2b_len = (page_ovflw) ? max_r2b_len : lcl_req_len; |
|
assign next_req_len = lcl_req_len - r2b_len; |
|
238,7 → 234,6
// |
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,8 → 135,7
|
parameter SDR_DW = 16; // SDR Data Width |
parameter SDR_BW = 2; // SDR Byte Width |
// 12 bit subtractor is not feasibile for FPGA, so changed to 8 bits |
parameter REQ_BW = (`TARGET_DESIGN == `FPGA) ? 8 : 12; // Request Width |
parameter REQ_BW = 12; // Request Width |
|
|
input clk, reset_n; |
242,7 → 241,7
(sel_b2x) ? b2x_sdr_cmd : i_xfr_cmd; |
|
assign xfr_addr = (sel_mgmt) ? mgmt_addr : |
(sel_b2x) ? b2x_addr : xfr_caddr+1; |
(sel_b2x) ? b2x_addr : xfr_caddr; |
|
assign mgmt_ack = sel_mgmt; |
|
252,9 → 251,7
|
assign xfr_len = (ld_xfr) ? b2x_len : l_len; |
|
//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 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] : |
276,7 → 273,7
|
assign xfr_end = ~|xfr_len; |
|
assign l_xfr_end = ~|(l_len-1); |
assign l_xfr_end = ~|l_len; |
|
assign rd_start = ld_xfr & b2x_read & b2x_start; |
|
295,9 → 292,8
assign xfr_wrap = (ld_xfr) ? b2x_wrap : l_wrap; |
|
// assign burst_bdry = ~|xfr_caddr[2:0]; |
wire [1:0] xfr_caddr_lsb = (xfr_caddr[1:0]+1); |
assign burst_bdry = ~|(xfr_caddr_lsb[1:0]); |
|
assign burst_bdry = ~|xfr_caddr[1:0]; |
|
always @ (posedge clk) begin |
if (~reset_n) begin |
xfr_caddr <= 12'b0; |
316,8 → 312,9
end // if (~reset_n) |
|
else begin |
xfr_caddr <= (ld_xfr) ? b2x_addr : |
(rd_next | wr_next) ? xfr_caddr + 1 : xfr_caddr; |
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; |
361,8 → 358,7
l_xfr_end & ~mgmt_req & b2x_req & b2x_read; |
wr_next = 1'b0; |
rdok = l_xfr_end & ~mgmt_req; |
// Break the timing path for FPGA Based Design |
cb_pre_ok = (`TARGET_DESIGN == `FPGA) ? 1'b0 : l_xfr_end; |
cb_pre_ok = l_xfr_end; |
wrok = 1'b0; |
sel_mgmt = 1'b0; |
|
505,15 → 501,11
|
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,8 → 133,7
parameter SDR_DW = 16; // SDR Data Width |
parameter SDR_BW = 2; // SDR Byte Width |
|
// 12 bit subtractor is not feasibile for FPGA, so changed to 8 bits |
parameter REQ_BW = (`TARGET_DESIGN == `FPGA) ? 8 : 12; // Request Width |
parameter REQ_BW = 12; // Request Width |
|
//----------------------------------------------- |
// Global Variable |
/core/sdrc_bank_ctl.v
100,8 → 100,7
|
parameter SDR_DW = 16; // SDR Data Width |
parameter SDR_BW = 2; // SDR Byte Width |
// 12 bit subtractor is not feasibile for FPGA, so changed to 8 bits |
parameter REQ_BW = (`TARGET_DESIGN == `FPGA) ? 8 : 12; // Request Width |
parameter REQ_BW = 12; // Request Width |
input clk, reset_n; |
|
input [1:0] a2b_req_depth; |
173,9 → 172,8
|
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; |
183,15 → 181,10
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; |
|
205,11 → 198,8
// If the rank_fifo is empty, send the request from the bank addressed by |
// r2b_ba |
|
// 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 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]; |
|
assign rank_req[0] = i2x_req[xfr_ba]; // each rank generates requests |
|
360,21 → 350,17
rank_ba[7:6] <= (rank_wr_sel[3]) ? r2b_ba : |
(rank_fifo_rd) ? 2'b00 : rank_ba[7:6]; |
|
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_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]; |
end |
rank_ba_last[3] <= (rank_wr_sel[3]) ? sdr_req_norm_dma_last : |
(rank_fifo_rd) ? 1'b0 : rank_ba_last[3]; |
|
end // else: !if(~reset_n) |
|
/core/sdrc_define.v
23,7 → 23,5
`define SDR_REFRESH 4'b0001 |
`define SDR_MODE 4'b0000 |
|
`define ASIC 1'b1 |
`define FPGA 1'b0 |
`define TARGET_DESIGN `FPGA |
|
|