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
/
- from Rev 50 to Rev 51
- ↔ Reverse comparison
Rev 50 → Rev 51
/sdr_ctrl/trunk/rtl/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; |
/sdr_ctrl/trunk/rtl/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; |
|
/sdr_ctrl/trunk/rtl/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; |
|
/************************************************************************/ |
/sdr_ctrl/trunk/rtl/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 |
/sdr_ctrl/trunk/rtl/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 |
|
|
/sdr_ctrl/trunk/rtl/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) |
|