URL
https://opencores.org/ocsvn/versatile_mem_ctrl/versatile_mem_ctrl/trunk
Subversion Repositories versatile_mem_ctrl
Compare Revisions
- This comparison shows the changes necessary to convert path
/versatile_mem_ctrl/trunk/rtl/verilog
- from Rev 63 to Rev 64
- ↔ Reverse comparison
Rev 63 → Rev 64
/sdr_16_defines.v
5,13 → 5,13
// |
// either in this file or as command line option; +define+MT48LC16M16 |
// |
// This file appears unused - it should either begin to be used again or deleted to avoid the confusion I just endured figuring this out! jb |
|
// number of adr lines to use |
// 2^2 = 4 32 bit word burst |
`define BURST_SIZE 2 |
// Most of these defines have an effect on things in fsm_sdr_16.v |
|
//`define MT48LC16M16 |
//`define MT48LC16M16 // 32MB part |
`define MT48LC4M16 // 8MB part |
|
|
`ifdef MT48LC16M16 |
// using 1 of MT48LC16M16 |
// SDRAM data width is 16 |
21,16 → 21,8
`define ROW_SIZE 13 |
`define BA_SIZE 2 |
|
`define SDRAM16 |
`define BA tx_fifo_dat_o[28:27] |
`define ROW tx_fifo_dat_o[26:14] |
`define COL {4'b0000,tx_fifo_dat_o[13:10],burst_adr,1'b0} |
`define WORD_SIZE 1 |
`define WB_ADR_HI 24 |
`define WB_ADR_LO 2 |
`endif // `ifdef MT48LC16M16 |
|
`define MT48LC4M16 // 8MB part |
`ifdef MT48LC4M16 |
// using 1 of MT48LC4M16 |
// SDRAM data width is 16 |
40,21 → 32,8
`define ROW_SIZE 12 |
`define BA_SIZE 2 |
|
`define SDRAM16 |
`define COL {5'b0000,wb_adr_i[8:1]} |
`define ROW wb_adr_i[20:9] |
`define BA wb_adr_i[22:21] |
`define WORD_SIZE 1 |
`define END_OF_BURST burst_counter[0] |
`define WB_ADR_HI 22 |
`define WB_ADR_LO 1 |
`endif // `ifdef MT48LC4M16 |
|
|
// FIFO |
`define DLY_INIT 4095 |
`define AREF_INIT 390 |
|
// LMR |
// [12:10] reserved |
// [9] WB, write burst; 0 - programmed burst length, 1 - single location |
62,26 → 41,7
// [6:4] CAS Latency; 3'b010 - 2, 3'b011 - 3 |
// [3] BT, Burst Type; 1'b0 - sequential, 1'b1 - interleaved |
// [2:0] Burst length; 3'b000 - 1, 3'b001 - 2, 3'b010 - 4, 3'b011 - 8, 3'b111 - full page |
`define WB 1'b0 |
`define CL 2 |
`define BT 1'b0 |
`define BL 3'b001 |
|
// Adr to SDRAM {ba[1:0],a[12:0]} |
`define A_LMR {2'b00,3'b000,`WB,2'b00,3'd`CL,`BT,`BL} |
`define A_PRE {2'b00,13'b0010000000000} |
`define A_ACT {`BA,`ROW} |
`define A_READ {`BA,`COL} |
`define A_WRITE {`BA,`COL} |
`define A_DEFAULT {2'b00,13'b0000000000000} |
|
// command |
`define CMD {ras, cas, we} |
`define CMD_NOP 3'b111 |
`define CMD_AREF 3'b001 |
`define CMD_LMR 3'b000 |
`define CMD_PRE 3'b010 |
`define CMD_ACT 3'b011 |
`define CMD_READ 3'b101 |
`define CMD_WRITE 3'b100 |
`define CMD_BT 3'b110 |
`define INIT_WB 1'b0 |
`define INIT_CL 3'b010 |
`define INIT_BT 1'b0 |
`define INIT_BL 3'b001 |
/sdr_16.v
1,3 → 1,53
`line 1 "sdr_16_defines.v" 1 |
// |
// Specify either type of memory |
// or |
// BA_SIZE, ROW_SIZE, COL_SIZE and SDRAM_DATA_WIDTH |
// |
// either in this file or as command line option; +define+MT48LC16M16 |
// |
// This file appears unused - it should either begin to be used again or deleted to avoid the confusion I just endured figuring this out! jb |
|
//`define MT48LC16M16 // 32MB part |
// 8MB part |
|
|
|
|
|
|
|
|
|
|
|
|
`line 23 "sdr_16_defines.v" 0 |
// `ifdef MT48LC16M16 |
|
|
// using 1 of MT48LC4M16 |
// SDRAM data width is 16 |
|
|
|
|
|
|
// `ifdef MT48LC4M16 |
|
// LMR |
// [12:10] reserved |
// [9] WB, write burst; 0 - programmed burst length, 1 - single location |
// [8:7] OP Mode, 2'b00 |
// [6:4] CAS Latency; 3'b010 - 2, 3'b011 - 3 |
// [3] BT, Burst Type; 1'b0 - sequential, 1'b1 - interleaved |
// [2:0] Burst length; 3'b000 - 1, 3'b001 - 2, 3'b010 - 4, 3'b011 - 8, 3'b111 - full page |
|
|
|
|
`line 47 "sdr_16_defines.v" 2 |
`line 1 "versatile_fifo_async_cmp.v" 1 |
////////////////////////////////////////////////////////////////////// |
//// //// |
840,69 → 890,125
`line 119 "ref_counter.v" 2 |
`line 1 "fsm_sdr_16.v" 1 |
`timescale 1ns/1ns |
|
`line 2 "fsm_sdr_16.v" 0 |
`line 1 "sdr_16_defines.v" 1 |
// |
// Specify either type of memory |
// or |
// BA_SIZE, ROW_SIZE, COL_SIZE and SDRAM_DATA_WIDTH |
// |
// either in this file or as command line option; +define+MT48LC16M16 |
// |
// This file appears unused - it should either begin to be used again or deleted to avoid the confusion I just endured figuring this out! jb |
|
//`define MT48LC16M16 // 32MB part |
// 8MB part |
|
|
|
|
|
|
|
|
|
|
|
|
`line 23 "sdr_16_defines.v" 0 |
// `ifdef MT48LC16M16 |
|
|
// using 1 of MT48LC4M16 |
// SDRAM data width is 16 |
|
|
|
|
|
|
// `ifdef MT48LC4M16 |
|
// LMR |
// [12:10] reserved |
// [9] WB, write burst; 0 - programmed burst length, 1 - single location |
// [8:7] OP Mode, 2'b00 |
// [6:4] CAS Latency; 3'b010 - 2, 3'b011 - 3 |
// [3] BT, Burst Type; 1'b0 - sequential, 1'b1 - interleaved |
// [2:0] Burst length; 3'b000 - 1, 3'b001 - 2, 3'b010 - 4, 3'b011 - 8, 3'b111 - full page |
|
|
|
|
`line 47 "sdr_16_defines.v" 2 |
`line 2 "fsm_sdr_16.v" 0 |
|
module fsm_sdr_16 ( |
adr_i, we_i, bte_i, sel_i, |
fifo_empty, fifo_rd_adr, fifo_rd_data, count0, |
refresh_req, cmd_aref, cmd_read, state_idle, |
ba, a, cmd, dqm, dq_oe, |
sdram_clk, sdram_rst |
); |
adr_i, we_i, bte_i, sel_i, |
fifo_empty, fifo_rd_adr, fifo_rd_data, count0, |
refresh_req, cmd_aref, cmd_read, state_idle, |
ba, a, cmd, dqm, dq_oe, |
sdram_clk, sdram_rst |
); |
|
parameter ba_size = 2; |
parameter row_size = 13; |
parameter col_size = 9; |
/* Now these are defined |
parameter ba_size = 2; |
parameter row_size = 13; |
parameter col_size = 9; |
*/ |
|
input [2+12+8-1:0] adr_i; |
input we_i; |
input [1:0] bte_i; |
input [3:0] sel_i; |
|
input [ba_size+row_size+col_size-1:0] adr_i; |
input we_i; |
input [1:0] bte_i; |
input [3:0] sel_i; |
input fifo_empty; |
output fifo_rd_adr, fifo_rd_data; |
output reg count0; |
|
input fifo_empty; |
output fifo_rd_adr, fifo_rd_data; |
output reg count0; |
input refresh_req; |
output reg cmd_aref; // used for rerfresh ack |
output reg cmd_read; // used for ingress fifo control |
output state_idle; // state=idle |
|
input refresh_req; |
output reg cmd_aref; // used for rerfresh ack |
output reg cmd_read; // used for ingress fifo control |
output state_idle; // state=idle |
output reg [1:0] ba /*synthesis syn_useioff=1 syn_allow_retiming=0 */; |
output reg [12:0] a /*synthesis syn_useioff=1 syn_allow_retiming=0 */; |
output reg [2:0] cmd /*synthesis syn_useioff=1 syn_allow_retiming=0 */; |
output reg [1:0] dqm /*synthesis syn_useioff=1 syn_allow_retiming=0 */; |
output reg dq_oe; |
|
output reg [1:0] ba /*synthesis syn_useioff=1 syn_allow_retiming=0 */; |
output reg [12:0] a /*synthesis syn_useioff=1 syn_allow_retiming=0 */; |
output reg [2:0] cmd /*synthesis syn_useioff=1 syn_allow_retiming=0 */; |
output reg [1:0] dqm /*synthesis syn_useioff=1 syn_allow_retiming=0 */; |
output reg dq_oe; |
input sdram_clk, sdram_rst; |
|
input sdram_clk, sdram_rst; |
wire [2-1:0] bank; |
wire [12-1:0] row; |
wire [8-1:0] col; |
wire [12:0] col_reg_a10_fix; |
reg [0:31] shreg; |
wire stall; // active if write burst need data |
|
wire [ba_size-1:0] bank; |
wire [row_size-1:0] row; |
wire [col_size-1:0] col; |
wire [12:0] col_reg_a10_fix; |
reg [0:31] shreg; |
wire stall; // active if write burst need data |
reg [0:15] fifo_sel_reg_int; |
reg [1:0] fifo_sel_domain_reg_int; |
|
reg [0:15] fifo_sel_reg_int; |
reg [1:0] fifo_sel_domain_reg_int; |
// adr_reg {ba,row,col,we} |
reg [1:0] ba_reg; |
reg [12-1:0] row_reg; |
reg [8-1:0] col_reg; |
reg we_reg; |
reg [1:0] bte_reg; |
|
// adr_reg {ba,row,col,we} |
reg [1:0] ba_reg; |
reg [row_size-1:0] row_reg; |
reg [col_size-1:0] col_reg; |
reg we_reg; |
reg [1:0] bte_reg; |
// to keep track of open rows per bank |
reg [12-1:0] open_row[0:3]; |
reg [0:3] open_ba; |
wire current_bank_closed, current_row_open; |
reg current_bank_closed_reg, current_row_open_reg; |
|
// to keep track of open rows per bank |
reg [row_size-1:0] open_row[0:3]; |
reg [0:3] open_ba; |
wire current_bank_closed, current_row_open; |
reg current_bank_closed_reg, current_row_open_reg; |
|
parameter [1:0] linear = 2'b00, |
parameter [1:0] linear = 2'b00, |
beat4 = 2'b01, |
beat8 = 2'b10, |
beat16 = 2'b11; |
|
parameter [2:0] cmd_nop = 3'b111, |
parameter [2:0] cmd_nop = 3'b111, |
cmd_act = 3'b011, |
cmd_rd = 3'b101, |
cmd_wr = 3'b100, |
910,8 → 1016,10
cmd_rfr = 3'b001, |
cmd_lmr = 3'b000; |
|
// ctrl FSM |
parameter [2:0] init = 3'b000, |
// ctrl FSM |
|
/* define instead of param, as synplify is doing weird things |
parameter [2:0] init = 3'b000, |
idle = 3'b001, |
rfr = 3'b010, |
adr = 3'b011, |
919,204 → 1027,211
act = 3'b101, |
w4d = 3'b110, |
rw = 3'b111; |
reg [2:0] state, next; |
*/ |
|
|
|
|
|
|
|
|
|
reg [2:0] state, next; |
|
function [12:0] a10_fix; |
input [col_size-1:0] a; |
integer i; |
begin |
for (i=0;i<13;i=i+1) begin |
if (i<10) |
if (i<col_size) |
function [12:0] a10_fix; |
input [8-1:0] a; |
integer i; |
begin |
for (i=0;i<13;i=i+1) begin |
if (i<10) |
if (i<8) |
a10_fix[i] = a[i]; |
else |
a10_fix[i] = 1'b0; |
else if (i==10) |
a10_fix[i] = 1'b0; |
else |
a10_fix[i] = 1'b0; |
else if (i==10) |
a10_fix[i] = 1'b0; |
else |
if (i<col_size) |
if (i<8) |
a10_fix[i] = a[i-1]; |
else |
else |
a10_fix[i] = 1'b0; |
end |
end |
endfunction |
end |
end |
endfunction |
|
|
assign {bank,row,col} = adr_i; |
assign {bank,row,col} = adr_i; |
|
always @ (posedge sdram_clk or posedge sdram_rst) |
if (sdram_rst) |
state <= init; |
else |
state <= next; |
|
always @* |
begin |
next = 3'bx; |
case (state) |
init: if (shreg[31]) next = idle; |
else next = init; |
idle: if (refresh_req) next = rfr; |
else if (!fifo_empty) next = adr; |
else next = idle; |
rfr: if (shreg[5]) next = idle; |
else next = rfr; |
adr: if (current_row_open_reg & (shreg[4]) & we_reg) next = w4d; |
else if (current_row_open_reg & shreg[4]) next = rw; |
else if (current_bank_closed_reg & shreg[4]) next = act; |
else if (shreg[4]) next = pch; |
else next = adr; |
pch: if (shreg[1]) next = act; |
else next = pch; |
act: if (shreg[2] & (!fifo_empty | !we_reg)) next = rw; |
else if (shreg[2] & fifo_empty) next = w4d; |
else next = act; |
w4d: if (!fifo_empty) next = rw; |
else next = w4d; |
rw: if (bte_reg==linear & shreg[1]) |
next = idle; |
else if (bte_reg==beat4 & shreg[7]) |
next = idle; |
else if (bte_reg==beat8 & shreg[15]) |
next = idle; |
else if (bte_reg==beat16 & shreg[31]) |
next = idle; |
else |
next = rw; |
endcase |
end |
always @ (posedge sdram_clk or posedge sdram_rst) |
if (sdram_rst) |
state <= 3'b000; |
else |
state <= next; |
|
always @* |
begin |
next = 3'bx; |
case (state) |
3'b000: if (shreg[31]) next = 3'b001; |
else next = 3'b000; |
3'b001: if (refresh_req) next = 3'b010; |
else if (!fifo_empty) next = 3'b011; |
else next = 3'b001; |
3'b010: if (shreg[5]) next = 3'b001; |
else next = 3'b010; |
3'b011: if (current_row_open_reg & (shreg[4]) & we_reg) next = 3'b110; |
else if (current_row_open_reg & shreg[4]) next = 3'b111; |
else if (current_bank_closed_reg & shreg[4]) next = 3'b101; |
else if (shreg[4]) next = 3'b100; |
else next = 3'b011; |
3'b100: if (shreg[1]) next = 3'b101; |
else next = 3'b100; |
3'b101: if (shreg[2] & (!fifo_empty | !we_reg)) next = 3'b111; |
else if (shreg[2] & fifo_empty) next = 3'b110; |
else next = 3'b101; |
3'b110: if (!fifo_empty) next = 3'b111; |
else next = 3'b110; |
3'b111: if (bte_reg==linear & shreg[1]) |
next = 3'b001; |
else if (bte_reg==beat4 & shreg[7]) |
next = 3'b001; |
else if (bte_reg==beat8 & shreg[15]) |
next = 3'b001; |
else if (bte_reg==beat16 & shreg[31]) |
next = 3'b001; |
else |
next = 3'b111; |
endcase |
end |
|
// active if write burst need data |
assign stall = state==rw & next==rw & fifo_empty & count0 & we_reg; |
// active if write burst need data |
assign stall = state==3'b111 & next==3'b111 & fifo_empty & count0 & we_reg; |
|
// counter |
always @ (posedge sdram_clk or posedge sdram_rst) |
begin |
if (sdram_rst) begin |
shreg <= {1'b1,{31{1'b0}}}; |
count0 <= 1'b0; |
end else |
if (state!=next) begin |
shreg <= {1'b1,{31{1'b0}}}; |
count0 <= 1'b0; |
end else |
// counter |
always @ (posedge sdram_clk or posedge sdram_rst) |
begin |
if (sdram_rst) begin |
shreg <= {1'b1,{31{1'b0}}}; |
count0 <= 1'b0; |
end else |
if (state!=next) begin |
shreg <= {1'b1,{31{1'b0}}}; |
count0 <= 1'b0; |
end else |
if (~stall) begin |
shreg <= shreg >> 1; |
count0 <= ~count0; |
shreg <= shreg >> 1; |
count0 <= ~count0; |
end |
end |
end |
|
// LMR |
// [12:10] reserved |
// [9] WB, write burst; 0 - programmed burst length, 1 - single location |
// [8:7] OP Mode, 2'b00 |
// [6:4] CAS Latency; 3'b010 - 2, 3'b011 - 3 |
// [3] BT, Burst Type; 1'b0 - sequential, 1'b1 - interleaved |
// [2:0] Burst length; 3'b000 - 1, 3'b001 - 2, 3'b010 - 4, 3'b011 - 8, 3'b111 - full page |
parameter [0:0] init_wb = 1'b0; |
parameter [2:0] init_cl = 3'b010; |
parameter [0:0] init_bt = 1'b0; |
parameter [2:0] init_bl = 3'b001; |
// ba, a, cmd |
// col_reg_a10 has bit [10] set to zero to disable auto precharge |
assign col_reg_a10_fix = a10_fix(col_reg); |
|
// ba, a, cmd |
// col_reg_a10 has bit [10] set to zero to disable auto precharge |
assign col_reg_a10_fix = a10_fix(col_reg); |
|
// outputs dependent on state vector |
always @ (posedge sdram_clk or posedge sdram_rst) |
begin |
if (sdram_rst) begin |
{ba,a,cmd} <= {2'b00,13'd0,cmd_nop}; |
dqm <= 2'b11; |
cmd_aref <= 1'b0; |
cmd_read <= 1'b0; |
dq_oe <= 1'b0; |
{open_ba,open_row[0],open_row[1],open_row[2],open_row[3]} <= {4'b0000,{row_size*4{1'b0}}}; |
{ba_reg,row_reg,col_reg,we_reg,bte_reg} <= {2'b00, {row_size{1'b0}}, {col_size{1'b0}}, 1'b0, 2'b00 }; |
end else begin |
{ba,a,cmd} <= {2'b00,13'd0,cmd_nop}; |
dqm <= 2'b11; |
cmd_aref <= 1'b0; |
cmd_read <= 1'b0; |
dq_oe <= 1'b0; |
case (state) |
init: |
if (shreg[3]) begin |
{ba,a,cmd} <= {2'b00, 13'b0010000000000, cmd_pch}; |
open_ba[ba_reg] <= 1'b0; |
end else if (shreg[7] | shreg[19]) |
{ba,a,cmd,cmd_aref} <= {2'b00, 13'd0, cmd_rfr,1'b1}; |
else if (shreg[31]) |
{ba,a,cmd} <= {2'b00,3'b000,init_wb,2'b00,init_cl,init_bt,init_bl, cmd_lmr}; |
rfr: |
if (shreg[0]) begin |
{ba,a,cmd} <= {2'b00, 13'b0010000000000, cmd_pch}; |
open_ba <= 4'b0000; |
end else if (shreg[2]) |
{ba,a,cmd,cmd_aref} <= {2'b00, 13'd0, cmd_rfr,1'b1}; |
adr: |
if (shreg[3]) |
{ba_reg,row_reg,col_reg,we_reg,bte_reg} <= {bank,row,col,we_i,bte_i}; |
pch: |
if (shreg[0]) begin |
{ba,a,cmd} <= {ba_reg,13'd0,cmd_pch}; |
//open_ba <= 4'b0000; |
open_ba[ba_reg] <= 1'b0; |
end |
act: |
if (shreg[0]) begin |
{ba,a,cmd} <= {ba_reg,(13'd0 | row_reg),cmd_act}; |
{open_ba[ba_reg],open_row[ba_reg]} <= {1'b1,row_reg}; |
end |
rw: |
begin |
if (we_reg & !count0) |
// outputs dependent on state vector |
always @ (posedge sdram_clk or posedge sdram_rst) |
begin |
if (sdram_rst) begin |
{ba,a,cmd} <= {2'b00,13'd0,cmd_nop}; |
dqm <= 2'b11; |
cmd_aref <= 1'b0; |
cmd_read <= 1'b0; |
dq_oe <= 1'b0; |
{open_ba,open_row[0],open_row[1],open_row[2],open_row[3]} <= |
{4'b0000,{12*4{1'b0}}}; |
{ba_reg,row_reg,col_reg,we_reg,bte_reg} <= |
{2'b00, {12{1'b0}}, {8{1'b0}}, 1'b0, 2'b00 }; |
end else begin |
{ba,a,cmd} <= {2'b00,13'd0,cmd_nop}; |
dqm <= 2'b11; |
cmd_aref <= 1'b0; |
cmd_read <= 1'b0; |
dq_oe <= 1'b0; |
case (state) |
3'b000: |
if (shreg[3]) begin |
{ba,a,cmd} <= {2'b00, 13'b0010000000000, cmd_pch}; |
open_ba[ba_reg] <= 1'b0; |
end else if (shreg[7] | shreg[19]) |
{ba,a,cmd,cmd_aref} <= {2'b00, 13'd0, cmd_rfr,1'b1}; |
else if (shreg[31]) |
{ba,a,cmd} <= |
{2'b00,3'b000,1'b0,2'b00,3'b010,1'b0,3'b001, cmd_lmr}; |
3'b010: |
if (shreg[0]) begin |
{ba,a,cmd} <= {2'b00, 13'b0010000000000, cmd_pch}; |
open_ba <= 4'b0000; |
end else if (shreg[2]) |
{ba,a,cmd,cmd_aref} <= {2'b00, 13'd0, cmd_rfr,1'b1}; |
3'b011: |
if (shreg[3]) |
{ba_reg,row_reg,col_reg,we_reg,bte_reg} <= |
{bank,row,col,we_i,bte_i}; |
3'b100: |
if (shreg[0]) begin |
{ba,a,cmd} <= {ba_reg,13'd0,cmd_pch}; |
//open_ba <= 4'b0000; |
open_ba[ba_reg] <= 1'b0; |
end |
3'b101: |
if (shreg[0]) begin |
{ba,a,cmd} <= {ba_reg,(13'd0 | row_reg),cmd_act}; |
{open_ba[ba_reg],open_row[ba_reg]} <= {1'b1,row_reg}; |
end |
3'b111: |
begin |
if (we_reg & !count0) |
cmd <= cmd_wr; |
else if (!count0) |
else if (!count0) |
{cmd,cmd_read} <= {cmd_rd,1'b1}; |
else |
else |
cmd <= cmd_nop; |
if (we_reg & !count0) |
if (we_reg & !count0) |
dqm <= ~sel_i[3:2]; |
else if (we_reg & count0) |
else if (we_reg & count0) |
dqm <= ~sel_i[1:0]; |
else |
else |
dqm <= 2'b00; |
if (we_reg) |
if (we_reg) |
dq_oe <= 1'b1; |
if (~stall) |
if (~stall) |
case (bte_reg) |
linear: {ba,a} <= {ba_reg,col_reg_a10_fix}; |
beat4: {ba,a,col_reg[2:0]} <= {ba_reg,col_reg_a10_fix, col_reg[2:0] + 3'd1}; |
beat8: {ba,a,col_reg[3:0]} <= {ba_reg,col_reg_a10_fix, col_reg[3:0] + 4'd1}; |
beat16: {ba,a,col_reg[4:0]} <= {ba_reg,col_reg_a10_fix, col_reg[4:0] + 5'd1}; |
linear: {ba,a} <= {ba_reg,col_reg_a10_fix}; |
beat4: {ba,a,col_reg[2:0]} <= |
{ba_reg,col_reg_a10_fix, col_reg[2:0] + 3'd1}; |
beat8: {ba,a,col_reg[3:0]} <= |
{ba_reg,col_reg_a10_fix, col_reg[3:0] + 4'd1}; |
beat16: {ba,a,col_reg[4:0]} <= |
{ba_reg,col_reg_a10_fix, col_reg[4:0] + 5'd1}; |
endcase |
end |
endcase |
end |
end |
end |
endcase |
end |
end |
|
// rd_adr goes high when next adr is fetched from sync RAM and during write burst |
assign fifo_rd_adr = state==adr & shreg[0]; |
assign fifo_rd_data = ((state==rw & next==rw) & we_reg & !count0 & !fifo_empty); |
// rd_adr goes high when next adr is fetched from sync RAM and during write burst |
assign fifo_rd_adr = state==3'b011 & shreg[0]; |
assign fifo_rd_data = ((state==3'b111 & next==3'b111) & |
we_reg & !count0 & !fifo_empty); |
|
assign state_idle = (state==idle); |
assign state_idle = (state==3'b001); |
|
// bank and row open ? |
assign current_bank_closed = !(open_ba[bank]); |
assign current_row_open = open_ba[bank] & (open_row[bank]==row); |
// bank and row open ? |
assign current_bank_closed = !(open_ba[bank]); |
assign current_row_open = open_ba[bank] & (open_row[bank]==row); |
|
always @ (posedge sdram_clk or posedge sdram_rst) |
if (sdram_rst) |
{current_bank_closed_reg, current_row_open_reg} <= {1'b1, 1'b0}; |
else |
//if (state==adr & counter[1:0]==2'b10) |
{current_bank_closed_reg, current_row_open_reg} <= {current_bank_closed, current_row_open}; |
|
always @ (posedge sdram_clk or posedge sdram_rst) |
if (sdram_rst) |
{current_bank_closed_reg, current_row_open_reg} <= {1'b1, 1'b0}; |
else |
//if (state==adr & counter[1:0]==2'b10) |
{current_bank_closed_reg, current_row_open_reg} <= |
{current_bank_closed, current_row_open}; |
|
|
endmodule |
`line 278 "fsm_sdr_16.v" 2 |
`line 290 "fsm_sdr_16.v" 2 |
`line 1 "versatile_mem_ctrl_wb.v" 1 |
`timescale 1ns/1ns |
module versatile_mem_ctrl_wb ( |
1275,130 → 1390,189
|
`line 4 "versatile_mem_ctrl_top.v" 0 |
|
|
|
`line 6 "versatile_mem_ctrl_top.v" 0 |
`line 1 "sdr_16_defines.v" 1 |
// |
// Specify either type of memory |
// or |
// BA_SIZE, ROW_SIZE, COL_SIZE and SDRAM_DATA_WIDTH |
// |
// either in this file or as command line option; +define+MT48LC16M16 |
// |
// This file appears unused - it should either begin to be used again or deleted to avoid the confusion I just endured figuring this out! jb |
|
//`define MT48LC16M16 // 32MB part |
// 8MB part |
|
|
|
|
|
|
|
|
|
|
|
|
`line 23 "sdr_16_defines.v" 0 |
// `ifdef MT48LC16M16 |
|
|
// using 1 of MT48LC4M16 |
// SDRAM data width is 16 |
|
|
|
|
|
|
// `ifdef MT48LC4M16 |
|
// LMR |
// [12:10] reserved |
// [9] WB, write burst; 0 - programmed burst length, 1 - single location |
// [8:7] OP Mode, 2'b00 |
// [6:4] CAS Latency; 3'b010 - 2, 3'b011 - 3 |
// [3] BT, Burst Type; 1'b0 - sequential, 1'b1 - interleaved |
// [2:0] Burst length; 3'b000 - 1, 3'b001 - 2, 3'b010 - 4, 3'b011 - 8, 3'b111 - full page |
|
|
|
|
`line 47 "sdr_16_defines.v" 2 |
`line 6 "versatile_mem_ctrl_top.v" 0 |
|
|
module versatile_mem_ctrl_top |
( |
// wishbone side |
wb_adr_i_0, wb_dat_i_0, wb_dat_o_0, |
wb_stb_i_0, wb_cyc_i_0, wb_ack_o_0, |
wb_adr_i_1, wb_dat_i_1, wb_dat_o_1, |
wb_stb_i_1, wb_cyc_i_1, wb_ack_o_1, |
wb_adr_i_2, wb_dat_i_2, wb_dat_o_2, |
wb_stb_i_2, wb_cyc_i_2, wb_ack_o_2, |
wb_adr_i_3, wb_dat_i_3, wb_dat_o_3, |
wb_stb_i_3, wb_cyc_i_3, wb_ack_o_3, |
wb_clk, wb_rst, |
// wishbone side |
wb_adr_i_0, wb_dat_i_0, wb_dat_o_0, |
wb_stb_i_0, wb_cyc_i_0, wb_ack_o_0, |
wb_adr_i_1, wb_dat_i_1, wb_dat_o_1, |
wb_stb_i_1, wb_cyc_i_1, wb_ack_o_1, |
wb_adr_i_2, wb_dat_i_2, wb_dat_o_2, |
wb_stb_i_2, wb_cyc_i_2, wb_ack_o_2, |
wb_adr_i_3, wb_dat_i_3, wb_dat_o_3, |
wb_stb_i_3, wb_cyc_i_3, wb_ack_o_3, |
wb_clk, wb_rst, |
|
|
ba_pad_o, a_pad_o, cs_n_pad_o, ras_pad_o, cas_pad_o, we_pad_o, dq_o, dqm_pad_o, dq_i, dq_oe, cke_pad_o, |
ba_pad_o, a_pad_o, cs_n_pad_o, ras_pad_o, cas_pad_o, we_pad_o, dq_o, dqm_pad_o, dq_i, dq_oe, cke_pad_o, |
|
|
|
|
|
|
|
|
|
|
`line 27 "versatile_mem_ctrl_top.v" 0 |
`line 29 "versatile_mem_ctrl_top.v" 0 |
|
// SDRAM signals |
sdram_clk, sdram_rst |
); |
|
// number of wb clock domains |
parameter nr_of_wb_clk_domains = 1; |
// number of wb ports in each wb clock domain |
parameter nr_of_wb_ports_clk0 = 1; |
parameter nr_of_wb_ports_clk1 = 0; |
parameter nr_of_wb_ports_clk2 = 0; |
parameter nr_of_wb_ports_clk3 = 0; |
|
parameter ba_size = 2; |
parameter row_size = 13; |
parameter col_size = 9; |
parameter [2:0] cl = 3'b010; // valid options 010, 011 used for SDR LMR |
|
input [36*nr_of_wb_ports_clk0-1:0] wb_adr_i_0; |
input [36*nr_of_wb_ports_clk0-1:0] wb_dat_i_0; |
output [32*nr_of_wb_ports_clk0-1:0] wb_dat_o_0; |
input [0:nr_of_wb_ports_clk0-1] wb_stb_i_0, wb_cyc_i_0, wb_ack_o_0; |
|
input [36*nr_of_wb_ports_clk1-1:0] wb_adr_i_1; |
input [36*nr_of_wb_ports_clk1-1:0] wb_dat_i_1; |
output [32*nr_of_wb_ports_clk1-1:0] wb_dat_o_1; |
input [0:nr_of_wb_ports_clk1-1] wb_stb_i_1, wb_cyc_i_1, wb_ack_o_1; |
|
input [36*nr_of_wb_ports_clk2-1:0] wb_adr_i_2; |
input [36*nr_of_wb_ports_clk2-1:0] wb_dat_i_2; |
output [32*nr_of_wb_ports_clk2-1:0] wb_dat_o_2; |
input [0:nr_of_wb_ports_clk2-1] wb_stb_i_2, wb_cyc_i_2, wb_ack_o_2; |
|
input [36*nr_of_wb_ports_clk3-1:0] wb_adr_i_3; |
input [36*nr_of_wb_ports_clk3-1:0] wb_dat_i_3; |
output [32*nr_of_wb_ports_clk3-1:0] wb_dat_o_3; |
input [0:nr_of_wb_ports_clk3-1] wb_stb_i_3, wb_cyc_i_3, wb_ack_o_3; |
|
input [0:nr_of_wb_clk_domains-1] wb_clk; |
input [0:nr_of_wb_clk_domains-1] wb_rst; |
|
// number of wb clock domains |
parameter nr_of_wb_clk_domains = 1; |
// number of wb ports in each wb clock domain |
parameter nr_of_wb_ports_clk0 = 1; |
parameter nr_of_wb_ports_clk1 = 0; |
parameter nr_of_wb_ports_clk2 = 0; |
parameter nr_of_wb_ports_clk3 = 0; |
|
/* |
// Now these are defines, synthesis tool was doing strange things! jb |
parameter ba_size = 2; |
parameter row_size = 13; |
parameter col_size = 9; |
parameter [2:0] cl = 3'b010; // valid options 010, 011 used for SDR LMR |
*/ |
|
input [36*nr_of_wb_ports_clk0-1:0] wb_adr_i_0; |
input [36*nr_of_wb_ports_clk0-1:0] wb_dat_i_0; |
output [32*nr_of_wb_ports_clk0-1:0] wb_dat_o_0; |
input [0:nr_of_wb_ports_clk0-1] wb_stb_i_0, wb_cyc_i_0, wb_ack_o_0; |
|
input [36*nr_of_wb_ports_clk1-1:0] wb_adr_i_1; |
input [36*nr_of_wb_ports_clk1-1:0] wb_dat_i_1; |
output [32*nr_of_wb_ports_clk1-1:0] wb_dat_o_1; |
input [0:nr_of_wb_ports_clk1-1] wb_stb_i_1, wb_cyc_i_1, wb_ack_o_1; |
|
input [36*nr_of_wb_ports_clk2-1:0] wb_adr_i_2; |
input [36*nr_of_wb_ports_clk2-1:0] wb_dat_i_2; |
output [32*nr_of_wb_ports_clk2-1:0] wb_dat_o_2; |
input [0:nr_of_wb_ports_clk2-1] wb_stb_i_2, wb_cyc_i_2, wb_ack_o_2; |
|
input [36*nr_of_wb_ports_clk3-1:0] wb_adr_i_3; |
input [36*nr_of_wb_ports_clk3-1:0] wb_dat_i_3; |
output [32*nr_of_wb_ports_clk3-1:0] wb_dat_o_3; |
input [0:nr_of_wb_ports_clk3-1] wb_stb_i_3, wb_cyc_i_3, wb_ack_o_3; |
|
input [0:nr_of_wb_clk_domains-1] wb_clk; |
input [0:nr_of_wb_clk_domains-1] wb_rst; |
|
|
output [1:0] ba_pad_o; |
output [12:0] a_pad_o; |
output cs_n_pad_o; |
output ras_pad_o; |
output cas_pad_o; |
output we_pad_o; |
output reg [15:0] dq_o /*synthesis syn_useioff=1 syn_allow_retiming=0 */; |
output [1:0] dqm_pad_o; |
input [15:0] dq_i /*synthesis syn_useioff=1 syn_allow_retiming=0 */; |
output dq_oe; |
output cke_pad_o; |
output [1:0] ba_pad_o; |
output [12:0] a_pad_o; |
output cs_n_pad_o; |
output ras_pad_o; |
output cas_pad_o; |
output we_pad_o; |
output reg [(16)-1:0] dq_o /*synthesis syn_useioff=1 syn_allow_retiming=0 */; |
output [1:0] dqm_pad_o; |
input [(16)-1:0] dq_i /*synthesis syn_useioff=1 syn_allow_retiming=0 */; |
output dq_oe; |
output cke_pad_o; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
`line 100 "versatile_mem_ctrl_top.v" 0 |
`line 105 "versatile_mem_ctrl_top.v" 0 |
|
input sdram_clk, sdram_rst; |
input sdram_clk, sdram_rst; |
|
wire [0:15] fifo_empty[0:3]; |
wire current_fifo_empty; |
wire [0:15] fifo_re[0:3]; |
wire [35:0] fifo_dat_o[0:3]; |
wire [31:0] fifo_dat_i; |
wire [0:15] fifo_we[0:3]; |
wire fifo_rd_adr, fifo_rd_data, fifo_wr, idle, count0; |
|
wire [0:15] fifo_sel_i, fifo_sel_dly; |
reg [0:15] fifo_sel_reg; |
wire [1:0] fifo_sel_domain_i, fifo_sel_domain_dly; |
reg [1:0] fifo_sel_domain_reg; |
wire [0:15] fifo_empty[0:3]; |
wire current_fifo_empty; |
wire [0:15] fifo_re[0:3]; |
wire [35:0] fifo_dat_o[0:3]; |
wire [31:0] fifo_dat_i; |
wire [0:15] fifo_we[0:3]; |
wire fifo_rd_adr, fifo_rd_data, fifo_wr, idle, count0; |
|
wire [0:15] fifo_sel_i, fifo_sel_dly; |
reg [0:15] fifo_sel_reg; |
wire [1:0] fifo_sel_domain_i, fifo_sel_domain_dly; |
reg [1:0] fifo_sel_domain_reg; |
|
reg refresh_req; |
|
wire [35:0] tx_fifo_dat_o; // tmp added /MF |
reg refresh_req; |
|
wire [35:0] tx_fifo_dat_o; // tmp added /MF |
|
generate |
if (nr_of_wb_clk_domains > 0) begin |
versatile_mem_ctrl_wb |
# (.nr_of_wb_ports(nr_of_wb_ports_clk0)) |
wb0( |
generate |
if (nr_of_wb_clk_domains > 0) begin |
versatile_mem_ctrl_wb |
# (.nr_of_wb_ports(nr_of_wb_ports_clk0)) |
wb0 |
( |
// wishbone side |
.wb_adr_i_v(wb_adr_i_0), |
.wb_dat_i_v(wb_dat_i_0), |
1419,17 → 1593,18
.sdram_fifo_we(fifo_we[0][0:nr_of_wb_ports_clk0-1]), |
.sdram_clk(sdram_clk), |
.sdram_rst(sdram_rst) ); |
end |
if (nr_of_wb_ports_clk0 < 16) begin |
assign fifo_empty[0][nr_of_wb_ports_clk0:15] = {(16-nr_of_wb_ports_clk0){1'b1}}; |
end |
endgenerate |
end |
if (nr_of_wb_ports_clk0 < 16) begin |
assign fifo_empty[0][nr_of_wb_ports_clk0:15] = {(16-nr_of_wb_ports_clk0){1'b1}}; |
end |
endgenerate |
|
generate |
if (nr_of_wb_clk_domains > 1) begin |
versatile_mem_ctrl_wb |
# (.nr_of_wb_ports(nr_of_wb_ports_clk1)) |
wb1( |
generate |
if (nr_of_wb_clk_domains > 1) begin |
versatile_mem_ctrl_wb |
# (.nr_of_wb_ports(nr_of_wb_ports_clk1)) |
wb1 |
( |
// wishbone side |
.wb_adr_i_v(wb_adr_i_1), |
.wb_dat_i_v(wb_dat_i_1), |
1450,20 → 1625,21
.sdram_fifo_we(fifo_we[1][0:nr_of_wb_ports_clk1-1]), |
.sdram_clk(sdram_clk), |
.sdram_rst(sdram_rst) ); |
if (nr_of_wb_ports_clk1 < 16) begin |
if (nr_of_wb_ports_clk1 < 16) begin |
assign fifo_empty[1][nr_of_wb_ports_clk1:15] = {(16-nr_of_wb_ports_clk1){1'b1}}; |
end |
end else begin |
assign fifo_empty[1] = {16{1'b1}}; |
assign fifo_dat_o[1] = {36{1'b0}}; |
end |
endgenerate |
end |
end else begin |
assign fifo_empty[1] = {16{1'b1}}; |
assign fifo_dat_o[1] = {36{1'b0}}; |
end |
endgenerate |
|
generate |
if (nr_of_wb_clk_domains > 2) begin |
versatile_mem_ctrl_wb |
# (.nr_of_wb_ports(nr_of_wb_ports_clk1)) |
wb2( |
generate |
if (nr_of_wb_clk_domains > 2) begin |
versatile_mem_ctrl_wb |
# (.nr_of_wb_ports(nr_of_wb_ports_clk1)) |
wb2 |
( |
// wishbone side |
.wb_adr_i_v(wb_adr_i_2), |
.wb_dat_i_v(wb_dat_i_2), |
1484,20 → 1660,21
.sdram_fifo_we(fifo_we[2][0:nr_of_wb_ports_clk2-1]), |
.sdram_clk(sdram_clk), |
.sdram_rst(sdram_rst) ); |
if (nr_of_wb_ports_clk2 < 16) begin |
if (nr_of_wb_ports_clk2 < 16) begin |
assign fifo_empty[2][nr_of_wb_ports_clk2:15] = {(16-nr_of_wb_ports_clk2){1'b1}}; |
end |
end else begin |
assign fifo_empty[2] = {16{1'b1}}; |
assign fifo_dat_o[2] = {36{1'b0}}; |
end |
endgenerate |
end |
end else begin |
assign fifo_empty[2] = {16{1'b1}}; |
assign fifo_dat_o[2] = {36{1'b0}}; |
end |
endgenerate |
|
generate |
if (nr_of_wb_clk_domains > 3) begin |
versatile_mem_ctrl_wb |
# (.nr_of_wb_ports(nr_of_wb_ports_clk3)) |
wb3( |
generate |
if (nr_of_wb_clk_domains > 3) begin |
versatile_mem_ctrl_wb |
# (.nr_of_wb_ports(nr_of_wb_ports_clk3)) |
wb3 |
( |
// wishbone side |
.wb_adr_i_v(wb_adr_i_3), |
.wb_dat_i_v(wb_dat_i_3), |
1518,185 → 1695,188
.sdram_fifo_we(fifo_we[3][0:nr_of_wb_ports_clk3-1]), |
.sdram_clk(sdram_clk), |
.sdram_rst(sdram_rst) ); |
if (nr_of_wb_ports_clk3 < 16) begin |
if (nr_of_wb_ports_clk3 < 16) begin |
assign fifo_empty[3][nr_of_wb_ports_clk3:15] = {(16-nr_of_wb_ports_clk3){1'b1}}; |
end |
end else begin |
assign fifo_empty[3] = {16{1'b1}}; |
assign fifo_dat_o[3] = {36{1'b0}}; |
end |
endgenerate |
end |
end else begin |
assign fifo_empty[3] = {16{1'b1}}; |
assign fifo_dat_o[3] = {36{1'b0}}; |
end |
endgenerate |
|
encode encode0 ( |
.fifo_empty_0(fifo_empty[0]), .fifo_empty_1(fifo_empty[1]), .fifo_empty_2(fifo_empty[2]), .fifo_empty_3(fifo_empty[3]), |
.fifo_sel(fifo_sel_i), .fifo_sel_domain(fifo_sel_domain_i) |
); |
encode encode0 |
( |
.fifo_empty_0(fifo_empty[0]), .fifo_empty_1(fifo_empty[1]), .fifo_empty_2(fifo_empty[2]), .fifo_empty_3(fifo_empty[3]), |
.fifo_sel(fifo_sel_i), .fifo_sel_domain(fifo_sel_domain_i) |
); |
|
always @ (posedge sdram_clk or posedge sdram_rst) |
begin |
if (sdram_rst) |
{fifo_sel_reg,fifo_sel_domain_reg} <= {16'h0,2'b00}; |
else |
if (idle) |
always @ (posedge sdram_clk or posedge sdram_rst) |
begin |
if (sdram_rst) |
{fifo_sel_reg,fifo_sel_domain_reg} <= {16'h0,2'b00}; |
else |
if (idle) |
{fifo_sel_reg,fifo_sel_domain_reg} <= {fifo_sel_i,fifo_sel_domain_i}; |
end |
end |
|
decode decode0 ( |
.fifo_sel(fifo_sel_reg), .fifo_sel_domain(fifo_sel_domain_reg), |
.fifo_we_0(fifo_re[0]), .fifo_we_1(fifo_re[1]), .fifo_we_2(fifo_re[2]), .fifo_we_3(fifo_re[3]) |
); |
decode decode0 |
( |
.fifo_sel(fifo_sel_reg), .fifo_sel_domain(fifo_sel_domain_reg), |
.fifo_we_0(fifo_re[0]), .fifo_we_1(fifo_re[1]), .fifo_we_2(fifo_re[2]), .fifo_we_3(fifo_re[3]) |
); |
|
// fifo_re[0-3] is a one-hot read enable structure |
// fifo_empty should go active when chosen fifo queue is empty |
assign current_fifo_empty = (idle) ? (!(|fifo_sel_i)) : (|(fifo_empty[0] & fifo_re[0])) | (|(fifo_empty[1] & fifo_re[1])) | (|(fifo_empty[2] & fifo_re[2])) | (|(fifo_empty[3] & fifo_re[3])); |
// fifo_re[0-3] is a one-hot read enable structure |
// fifo_empty should go active when chosen fifo queue is empty |
assign current_fifo_empty = (idle) ? (!(|fifo_sel_i)) : (|(fifo_empty[0] & fifo_re[0])) | (|(fifo_empty[1] & fifo_re[1])) | (|(fifo_empty[2] & fifo_re[2])) | (|(fifo_empty[3] & fifo_re[3])); |
|
decode decode1 ( |
.fifo_sel(fifo_sel_dly), .fifo_sel_domain(fifo_sel_domain_dly), |
.fifo_we_0(fifo_we[0]), .fifo_we_1(fifo_we[1]), .fifo_we_2(fifo_we[2]), .fifo_we_3(fifo_we[3]) |
); |
decode decode1 |
( |
.fifo_sel(fifo_sel_dly), .fifo_sel_domain(fifo_sel_domain_dly), |
.fifo_we_0(fifo_we[0]), .fifo_we_1(fifo_we[1]), .fifo_we_2(fifo_we[2]), .fifo_we_3(fifo_we[3]) |
); |
|
|
|
wire ref_cnt_zero; |
reg [15:0] dq_i_reg, dq_i_tmp_reg; |
reg [17:0] dq_o_tmp_reg; |
wire cmd_aref, cmd_read; |
|
// refresch counter |
ref_counter ref_counter0( .zq(ref_cnt_zero), .rst(sdram_rst), .clk(sdram_clk)); |
always @ (posedge sdram_clk or posedge sdram_rst) |
if (sdram_rst) |
refresh_req <= 1'b0; |
else |
if (ref_cnt_zero) |
refresh_req <= 1'b1; |
else if (cmd_aref) |
refresh_req <= 1'b0; |
|
// SDR SDRAM 16 FSM |
fsm_sdr_16 # ( |
.ba_size(ba_size), |
.row_size(row_size), |
.col_size(col_size), |
.init_cl(cl) |
) |
fsm_sdr_16( |
.adr_i({fifo_dat_o[fifo_sel_domain_reg][ba_size+row_size+col_size+6-2:6],1'b0}), |
.we_i(fifo_dat_o[fifo_sel_domain_reg][5]), |
.bte_i(fifo_dat_o[fifo_sel_domain_reg][4:3]), |
.sel_i({fifo_dat_o[fifo_sel_domain_reg][3:2],dq_o_tmp_reg[1:0]}), |
.fifo_empty(current_fifo_empty), |
.fifo_rd_adr(fifo_rd_adr), |
.fifo_rd_data(fifo_rd_data), |
.state_idle(idle), |
.count0(count0), |
.refresh_req(refresh_req), |
.cmd_aref(cmd_aref), |
.cmd_read(cmd_read), |
.ba(ba_pad_o), .a(a_pad_o), |
.cmd({ras_pad_o, cas_pad_o, we_pad_o}), |
.dq_oe(dq_oe), |
.dqm(dqm_pad_o), |
.sdram_clk(sdram_clk), |
.sdram_rst(sdram_rst) |
); |
wire ref_cnt_zero; |
reg [(16)-1:0] dq_i_reg, dq_i_tmp_reg; |
reg [17:0] dq_o_tmp_reg; |
wire cmd_aref, cmd_read; |
|
assign cs_pad_o = 1'b0; |
assign cke_pad_o = 1'b1; |
// refresch counter |
ref_counter ref_counter0( .zq(ref_cnt_zero), .rst(sdram_rst), .clk(sdram_clk)); |
always @ (posedge sdram_clk or posedge sdram_rst) |
if (sdram_rst) |
refresh_req <= 1'b0; |
else |
if (ref_cnt_zero) |
refresh_req <= 1'b1; |
else if (cmd_aref) |
refresh_req <= 1'b0; |
|
// SDR SDRAM 16 FSM |
fsm_sdr_16 fsm_sdr_16_0 |
( |
.adr_i({fifo_dat_o[fifo_sel_domain_reg][2+12+8+6-2:6],1'b0}), |
.we_i(fifo_dat_o[fifo_sel_domain_reg][5]), |
.bte_i(fifo_dat_o[fifo_sel_domain_reg][4:3]), |
.sel_i({fifo_dat_o[fifo_sel_domain_reg][3:2],dq_o_tmp_reg[1:0]}), |
.fifo_empty(current_fifo_empty), |
.fifo_rd_adr(fifo_rd_adr), |
.fifo_rd_data(fifo_rd_data), |
.state_idle(idle), |
.count0(count0), |
.refresh_req(refresh_req), |
.cmd_aref(cmd_aref), |
.cmd_read(cmd_read), |
.ba(ba_pad_o), .a(a_pad_o), |
.cmd({ras_pad_o, cas_pad_o, we_pad_o}), |
.dq_oe(dq_oe), |
.dqm(dqm_pad_o), |
.sdram_clk(sdram_clk), |
.sdram_rst(sdram_rst) |
); |
/* |
defparam fsm_sdr_16_0.ba_size = ba_size; |
defparam fsm_sdr_16_0.row_size = row_size; |
defparam fsm_sdr_16_0.col_size = col_size; |
defparam fsm_sdr_16_0.init_cl = cl; |
*/ |
assign cs_pad_o = 1'b0; |
assign cke_pad_o = 1'b1; |
|
genvar i; |
generate |
for (i=0; i < 16; i=i+1) begin : dly |
genvar i; |
generate |
for (i=0; i < 16; i=i+1) begin : dly |
|
defparam delay0.depth=cl+2; |
defparam delay0.width=1; |
delay delay0 ( |
.d(fifo_sel_reg[i]), |
.q(fifo_sel_dly[i]), |
.clk(sdram_clk), |
.rst(sdram_rst) |
); |
end |
|
defparam delay1.depth=cl+2; |
defparam delay1.width=2; |
delay delay1 ( |
.d(fifo_sel_domain_reg), |
.q(fifo_sel_domain_dly), |
.clk(sdram_clk), |
.rst(sdram_rst) |
); |
|
defparam delay2.depth=cl+2; |
defparam delay2.width=1; |
delay delay2 ( |
.d(cmd_read), |
.q(fifo_wr), |
.clk(sdram_clk), |
.rst(sdram_rst) |
); |
|
endgenerate |
defparam delay0.depth=3'b010+2; |
defparam delay0.width=1; |
delay delay0 ( |
.d(fifo_sel_reg[i]), |
.q(fifo_sel_dly[i]), |
.clk(sdram_clk), |
.rst(sdram_rst) |
); |
end |
|
defparam delay1.depth=3'b010+2; |
defparam delay1.width=2; |
delay delay1 ( |
.d(fifo_sel_domain_reg), |
.q(fifo_sel_domain_dly), |
.clk(sdram_clk), |
.rst(sdram_rst) |
); |
|
defparam delay2.depth=3'b010+2; |
defparam delay2.width=1; |
delay delay2 ( |
.d(cmd_read), |
.q(fifo_wr), |
.clk(sdram_clk), |
.rst(sdram_rst) |
); |
|
endgenerate |
|
// output registers |
assign cs_n_pad_o = 1'b0; |
assign cke_pad_o = 1'b1; |
|
always @ (posedge sdram_clk or posedge sdram_rst) |
// output registers |
assign cs_n_pad_o = 1'b0; |
assign cke_pad_o = 1'b1; |
|
always @ (posedge sdram_clk or posedge sdram_rst) |
if (sdram_rst) |
{dq_i_reg, dq_i_tmp_reg} <= {16'h0000,16'h0000}; |
else |
{dq_i_reg, dq_i_tmp_reg} <= {dq_i, dq_i_reg}; |
|
assign fifo_dat_i = {dq_i_tmp_reg, dq_i_reg}; |
assign fifo_dat_i = {dq_i_tmp_reg, dq_i_reg}; |
|
always @ (posedge sdram_clk or posedge sdram_rst) |
if (sdram_rst) |
dq_o_tmp_reg <= 18'h0; |
else |
dq_o_tmp_reg <= {fifo_dat_o[fifo_sel_domain_reg][19:4],fifo_dat_o[fifo_sel_domain_reg][1:0]}; |
|
// output dq_o mux and dffs |
always @ (posedge sdram_clk or posedge sdram_rst) |
if (sdram_rst) |
dq_o <= 16'h0000; |
else |
if (~count0) |
dq_o <= fifo_dat_o[fifo_sel_domain_reg][35:20]; |
else |
dq_o <= dq_o_tmp_reg[17:2]; |
|
/* |
// data mask signals should be not(sel_i) for write and 2'b00 for read |
always @ (posedge sdram_clk or posedge sdram_rst) |
if (sdram_rst) |
dq_o_tmp_reg <= 18'h0; |
dqm_pad_o <= 2'b00; |
else |
dq_o_tmp_reg <= {fifo_dat_o[fifo_sel_domain_reg][19:4],fifo_dat_o[fifo_sel_domain_reg][1:0]}; |
|
// output dq_o mux and dffs |
always @ (posedge sdram_clk or posedge sdram_rst) |
if (sdram_rst) |
dq_o <= 16'h0000; |
if (~count0) |
dqm_pad_o <= ~fifo_dat_o[fifo_sel_domain_reg][3:2]; |
else |
if (~count0) |
dq_o <= fifo_dat_o[fifo_sel_domain_reg][35:20]; |
else |
dq_o <= dq_o_tmp_reg[17:2]; |
|
/* |
// data mask signals should be not(sel_i) for write and 2'b00 for read |
always @ (posedge sdram_clk or posedge sdram_rst) |
if (sdram_rst) |
dqm_pad_o <= 2'b00; |
else |
if (~count0) |
dqm_pad_o <= ~fifo_dat_o[fifo_sel_domain_reg][3:2]; |
else |
dqm_pad_o <= ~dq_o_tmp_reg[1:0]; |
dqm_pad_o <= ~dq_o_tmp_reg[1:0]; |
*/ |
/* |
/* |
always @ (posedge sdram_clk or posedge sdram_rst) |
if (sdram_rst) begin |
{dq_o, dqm_pad_o} <= {16'h0000,2'b00}; |
|
{dq_o, dqm_pad_o} <= {16'h0000,2'b00}; |
|
end else |
if (~count0) begin |
dq_o <= fifo_dat_o[fifo_sel_domain_reg][35:20]; |
dq_o_tmp_reg[17:2] <= fifo_dat_o[fifo_sel_domain_reg][19:4]; |
if (cmd_read) |
dqm_pad_o <= 2'b00; |
else |
dqm_pad_o <= ~fifo_dat_o[fifo_sel_domain_reg][3:2]; |
if (cmd_read) |
dq_o_tmp_reg[1:0] <= 2'b00; |
else |
dq_o_tmp_reg[1:0] <= ~fifo_dat_o[fifo_sel_domain_reg][1:0]; |
if (~count0) begin |
dq_o <= fifo_dat_o[fifo_sel_domain_reg][35:20]; |
dq_o_tmp_reg[17:2] <= fifo_dat_o[fifo_sel_domain_reg][19:4]; |
if (cmd_read) |
dqm_pad_o <= 2'b00; |
else |
dqm_pad_o <= ~fifo_dat_o[fifo_sel_domain_reg][3:2]; |
if (cmd_read) |
dq_o_tmp_reg[1:0] <= 2'b00; |
else |
dq_o_tmp_reg[1:0] <= ~fifo_dat_o[fifo_sel_domain_reg][1:0]; |
end else |
{dq_o,dqm_pad_o} <= dq_o_tmp_reg; |
*/ |
{dq_o,dqm_pad_o} <= dq_o_tmp_reg; |
*/ |
|
|
// `ifdef SDR_16 |
1791,7 → 1971,7
|
|
|
|
|
|
|
|
1808,22 → 1988,22
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1839,6 → 2019,7
|
|
|
|
|
|
|
1849,6 → 2030,7
|
|
|
|
|
|
|
1859,11 → 2041,12
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1872,6 → 2055,7
|
|
|
|
|
|
|
1882,6 → 2066,7
|
|
|
|
|
|
|
1894,6 → 2079,7
|
|
|
|
|
|
|
1925,8 → 2111,8
|
|
|
`line 650 "versatile_mem_ctrl_top.v" 0 |
`line 668 "versatile_mem_ctrl_top.v" 0 |
// `ifdef DDR_16 |
|
endmodule // wb_sdram_ctrl_top |
`line 653 "versatile_mem_ctrl_top.v" 2 |
`line 671 "versatile_mem_ctrl_top.v" 2 |
/versatile_mem_ctrl_top.v
2,126 → 2,132
`ifdef DDR_16 |
`include "ddr_16_defines.v" |
`endif |
|
`ifdef SDR_16 |
`include "sdr_16_defines.v" |
`endif |
module versatile_mem_ctrl_top |
( |
// wishbone side |
wb_adr_i_0, wb_dat_i_0, wb_dat_o_0, |
wb_stb_i_0, wb_cyc_i_0, wb_ack_o_0, |
wb_adr_i_1, wb_dat_i_1, wb_dat_o_1, |
wb_stb_i_1, wb_cyc_i_1, wb_ack_o_1, |
wb_adr_i_2, wb_dat_i_2, wb_dat_o_2, |
wb_stb_i_2, wb_cyc_i_2, wb_ack_o_2, |
wb_adr_i_3, wb_dat_i_3, wb_dat_o_3, |
wb_stb_i_3, wb_cyc_i_3, wb_ack_o_3, |
wb_clk, wb_rst, |
// wishbone side |
wb_adr_i_0, wb_dat_i_0, wb_dat_o_0, |
wb_stb_i_0, wb_cyc_i_0, wb_ack_o_0, |
wb_adr_i_1, wb_dat_i_1, wb_dat_o_1, |
wb_stb_i_1, wb_cyc_i_1, wb_ack_o_1, |
wb_adr_i_2, wb_dat_i_2, wb_dat_o_2, |
wb_stb_i_2, wb_cyc_i_2, wb_ack_o_2, |
wb_adr_i_3, wb_dat_i_3, wb_dat_o_3, |
wb_stb_i_3, wb_cyc_i_3, wb_ack_o_3, |
wb_clk, wb_rst, |
|
`ifdef SDR_16 |
ba_pad_o, a_pad_o, cs_n_pad_o, ras_pad_o, cas_pad_o, we_pad_o, dq_o, dqm_pad_o, dq_i, dq_oe, cke_pad_o, |
ba_pad_o, a_pad_o, cs_n_pad_o, ras_pad_o, cas_pad_o, we_pad_o, dq_o, dqm_pad_o, dq_i, dq_oe, cke_pad_o, |
`endif |
|
`ifdef DDR_16 |
ck_pad_o, ck_n_pad_o, cke_pad_o, ck_fb_pad_o, ck_fb_pad_i, |
cs_n_pad_o, ras_pad_o, cas_pad_o, we_pad_o, |
dm_rdqs_pad_io, ba_pad_o, addr_pad_o, dq_pad_io, dqs_pad_io, dqs_oe, dqs_n_pad_io, rdqs_n_pad_i, odt_pad_o, |
ck_pad_o, ck_n_pad_o, cke_pad_o, ck_fb_pad_o, ck_fb_pad_i, |
cs_n_pad_o, ras_pad_o, cas_pad_o, we_pad_o, |
dm_rdqs_pad_io, ba_pad_o, addr_pad_o, dq_pad_io, dqs_pad_io, dqs_oe, dqs_n_pad_io, rdqs_n_pad_i, odt_pad_o, |
`endif |
// SDRAM signals |
sdram_clk, sdram_rst |
); |
|
// number of wb clock domains |
parameter nr_of_wb_clk_domains = 1; |
// number of wb ports in each wb clock domain |
parameter nr_of_wb_ports_clk0 = 1; |
parameter nr_of_wb_ports_clk1 = 0; |
parameter nr_of_wb_ports_clk2 = 0; |
parameter nr_of_wb_ports_clk3 = 0; |
|
parameter ba_size = 2; |
parameter row_size = 13; |
parameter col_size = 9; |
parameter [2:0] cl = 3'b010; // valid options 010, 011 used for SDR LMR |
|
input [36*nr_of_wb_ports_clk0-1:0] wb_adr_i_0; |
input [36*nr_of_wb_ports_clk0-1:0] wb_dat_i_0; |
output [32*nr_of_wb_ports_clk0-1:0] wb_dat_o_0; |
input [0:nr_of_wb_ports_clk0-1] wb_stb_i_0, wb_cyc_i_0, wb_ack_o_0; |
|
input [36*nr_of_wb_ports_clk1-1:0] wb_adr_i_1; |
input [36*nr_of_wb_ports_clk1-1:0] wb_dat_i_1; |
output [32*nr_of_wb_ports_clk1-1:0] wb_dat_o_1; |
input [0:nr_of_wb_ports_clk1-1] wb_stb_i_1, wb_cyc_i_1, wb_ack_o_1; |
|
input [36*nr_of_wb_ports_clk2-1:0] wb_adr_i_2; |
input [36*nr_of_wb_ports_clk2-1:0] wb_dat_i_2; |
output [32*nr_of_wb_ports_clk2-1:0] wb_dat_o_2; |
input [0:nr_of_wb_ports_clk2-1] wb_stb_i_2, wb_cyc_i_2, wb_ack_o_2; |
|
input [36*nr_of_wb_ports_clk3-1:0] wb_adr_i_3; |
input [36*nr_of_wb_ports_clk3-1:0] wb_dat_i_3; |
output [32*nr_of_wb_ports_clk3-1:0] wb_dat_o_3; |
input [0:nr_of_wb_ports_clk3-1] wb_stb_i_3, wb_cyc_i_3, wb_ack_o_3; |
|
input [0:nr_of_wb_clk_domains-1] wb_clk; |
input [0:nr_of_wb_clk_domains-1] wb_rst; |
|
// number of wb clock domains |
parameter nr_of_wb_clk_domains = 1; |
// number of wb ports in each wb clock domain |
parameter nr_of_wb_ports_clk0 = 1; |
parameter nr_of_wb_ports_clk1 = 0; |
parameter nr_of_wb_ports_clk2 = 0; |
parameter nr_of_wb_ports_clk3 = 0; |
|
/* |
// Now these are defines, synthesis tool was doing strange things! jb |
parameter ba_size = 2; |
parameter row_size = 13; |
parameter col_size = 9; |
parameter [2:0] cl = 3'b010; // valid options 010, 011 used for SDR LMR |
*/ |
|
input [36*nr_of_wb_ports_clk0-1:0] wb_adr_i_0; |
input [36*nr_of_wb_ports_clk0-1:0] wb_dat_i_0; |
output [32*nr_of_wb_ports_clk0-1:0] wb_dat_o_0; |
input [0:nr_of_wb_ports_clk0-1] wb_stb_i_0, wb_cyc_i_0, wb_ack_o_0; |
|
input [36*nr_of_wb_ports_clk1-1:0] wb_adr_i_1; |
input [36*nr_of_wb_ports_clk1-1:0] wb_dat_i_1; |
output [32*nr_of_wb_ports_clk1-1:0] wb_dat_o_1; |
input [0:nr_of_wb_ports_clk1-1] wb_stb_i_1, wb_cyc_i_1, wb_ack_o_1; |
|
input [36*nr_of_wb_ports_clk2-1:0] wb_adr_i_2; |
input [36*nr_of_wb_ports_clk2-1:0] wb_dat_i_2; |
output [32*nr_of_wb_ports_clk2-1:0] wb_dat_o_2; |
input [0:nr_of_wb_ports_clk2-1] wb_stb_i_2, wb_cyc_i_2, wb_ack_o_2; |
|
input [36*nr_of_wb_ports_clk3-1:0] wb_adr_i_3; |
input [36*nr_of_wb_ports_clk3-1:0] wb_dat_i_3; |
output [32*nr_of_wb_ports_clk3-1:0] wb_dat_o_3; |
input [0:nr_of_wb_ports_clk3-1] wb_stb_i_3, wb_cyc_i_3, wb_ack_o_3; |
|
input [0:nr_of_wb_clk_domains-1] wb_clk; |
input [0:nr_of_wb_clk_domains-1] wb_rst; |
|
`ifdef SDR_16 |
output [1:0] ba_pad_o; |
output [12:0] a_pad_o; |
output cs_n_pad_o; |
output ras_pad_o; |
output cas_pad_o; |
output we_pad_o; |
output reg [15:0] dq_o /*synthesis syn_useioff=1 syn_allow_retiming=0 */; |
output [1:0] dqm_pad_o; |
input [15:0] dq_i /*synthesis syn_useioff=1 syn_allow_retiming=0 */; |
output dq_oe; |
output cke_pad_o; |
output [1:0] ba_pad_o; |
output [12:0] a_pad_o; |
output cs_n_pad_o; |
output ras_pad_o; |
output cas_pad_o; |
output we_pad_o; |
output reg [(`SDRAM_DATA_WIDTH)-1:0] dq_o /*synthesis syn_useioff=1 syn_allow_retiming=0 */; |
output [1:0] dqm_pad_o; |
input [(`SDRAM_DATA_WIDTH)-1:0] dq_i /*synthesis syn_useioff=1 syn_allow_retiming=0 */; |
output dq_oe; |
output cke_pad_o; |
`endif |
`ifdef DDR_16 |
output ck_pad_o; |
output ck_n_pad_o; |
output cke_pad_o; |
output ck_fb_pad_o; |
input ck_fb_pad_i; |
output cs_n_pad_o; |
output ras_pad_o; |
output cas_pad_o; |
output we_pad_o; |
inout [1:0] dm_rdqs_pad_io; |
output [1:0] ba_pad_o; |
output [12:0] addr_pad_o; |
inout [15:0] dq_pad_io; |
inout [1:0] dqs_pad_io; |
output dqs_oe; |
inout [1:0] dqs_n_pad_io; |
input [1:0] rdqs_n_pad_i; |
output odt_pad_o; |
output ck_pad_o; |
output ck_n_pad_o; |
output cke_pad_o; |
output ck_fb_pad_o; |
input ck_fb_pad_i; |
output cs_n_pad_o; |
output ras_pad_o; |
output cas_pad_o; |
output we_pad_o; |
inout [1:0] dm_rdqs_pad_io; |
output [1:0] ba_pad_o; |
output [12:0] addr_pad_o; |
inout [15:0] dq_pad_io; |
inout [1:0] dqs_pad_io; |
output dqs_oe; |
inout [1:0] dqs_n_pad_io; |
input [1:0] rdqs_n_pad_i; |
output odt_pad_o; |
`endif |
input sdram_clk, sdram_rst; |
input sdram_clk, sdram_rst; |
|
wire [0:15] fifo_empty[0:3]; |
wire current_fifo_empty; |
wire [0:15] fifo_re[0:3]; |
wire [35:0] fifo_dat_o[0:3]; |
wire [31:0] fifo_dat_i; |
wire [0:15] fifo_we[0:3]; |
wire fifo_rd_adr, fifo_rd_data, fifo_wr, idle, count0; |
|
wire [0:15] fifo_sel_i, fifo_sel_dly; |
reg [0:15] fifo_sel_reg; |
wire [1:0] fifo_sel_domain_i, fifo_sel_domain_dly; |
reg [1:0] fifo_sel_domain_reg; |
wire [0:15] fifo_empty[0:3]; |
wire current_fifo_empty; |
wire [0:15] fifo_re[0:3]; |
wire [35:0] fifo_dat_o[0:3]; |
wire [31:0] fifo_dat_i; |
wire [0:15] fifo_we[0:3]; |
wire fifo_rd_adr, fifo_rd_data, fifo_wr, idle, count0; |
|
wire [0:15] fifo_sel_i, fifo_sel_dly; |
reg [0:15] fifo_sel_reg; |
wire [1:0] fifo_sel_domain_i, fifo_sel_domain_dly; |
reg [1:0] fifo_sel_domain_reg; |
|
reg refresh_req; |
|
wire [35:0] tx_fifo_dat_o; // tmp added /MF |
reg refresh_req; |
|
wire [35:0] tx_fifo_dat_o; // tmp added /MF |
|
generate |
if (nr_of_wb_clk_domains > 0) begin |
versatile_mem_ctrl_wb |
# (.nr_of_wb_ports(nr_of_wb_ports_clk0)) |
wb0( |
generate |
if (nr_of_wb_clk_domains > 0) begin |
versatile_mem_ctrl_wb |
# (.nr_of_wb_ports(nr_of_wb_ports_clk0)) |
wb0 |
( |
// wishbone side |
.wb_adr_i_v(wb_adr_i_0), |
.wb_dat_i_v(wb_dat_i_0), |
142,17 → 148,18
.sdram_fifo_we(fifo_we[0][0:nr_of_wb_ports_clk0-1]), |
.sdram_clk(sdram_clk), |
.sdram_rst(sdram_rst) ); |
end |
if (nr_of_wb_ports_clk0 < 16) begin |
assign fifo_empty[0][nr_of_wb_ports_clk0:15] = {(16-nr_of_wb_ports_clk0){1'b1}}; |
end |
endgenerate |
end |
if (nr_of_wb_ports_clk0 < 16) begin |
assign fifo_empty[0][nr_of_wb_ports_clk0:15] = {(16-nr_of_wb_ports_clk0){1'b1}}; |
end |
endgenerate |
|
generate |
if (nr_of_wb_clk_domains > 1) begin |
versatile_mem_ctrl_wb |
# (.nr_of_wb_ports(nr_of_wb_ports_clk1)) |
wb1( |
generate |
if (nr_of_wb_clk_domains > 1) begin |
versatile_mem_ctrl_wb |
# (.nr_of_wb_ports(nr_of_wb_ports_clk1)) |
wb1 |
( |
// wishbone side |
.wb_adr_i_v(wb_adr_i_1), |
.wb_dat_i_v(wb_dat_i_1), |
173,20 → 180,21
.sdram_fifo_we(fifo_we[1][0:nr_of_wb_ports_clk1-1]), |
.sdram_clk(sdram_clk), |
.sdram_rst(sdram_rst) ); |
if (nr_of_wb_ports_clk1 < 16) begin |
if (nr_of_wb_ports_clk1 < 16) begin |
assign fifo_empty[1][nr_of_wb_ports_clk1:15] = {(16-nr_of_wb_ports_clk1){1'b1}}; |
end |
end else begin |
assign fifo_empty[1] = {16{1'b1}}; |
assign fifo_dat_o[1] = {36{1'b0}}; |
end |
endgenerate |
end |
end else begin |
assign fifo_empty[1] = {16{1'b1}}; |
assign fifo_dat_o[1] = {36{1'b0}}; |
end |
endgenerate |
|
generate |
if (nr_of_wb_clk_domains > 2) begin |
versatile_mem_ctrl_wb |
# (.nr_of_wb_ports(nr_of_wb_ports_clk1)) |
wb2( |
generate |
if (nr_of_wb_clk_domains > 2) begin |
versatile_mem_ctrl_wb |
# (.nr_of_wb_ports(nr_of_wb_ports_clk1)) |
wb2 |
( |
// wishbone side |
.wb_adr_i_v(wb_adr_i_2), |
.wb_dat_i_v(wb_dat_i_2), |
207,20 → 215,21
.sdram_fifo_we(fifo_we[2][0:nr_of_wb_ports_clk2-1]), |
.sdram_clk(sdram_clk), |
.sdram_rst(sdram_rst) ); |
if (nr_of_wb_ports_clk2 < 16) begin |
if (nr_of_wb_ports_clk2 < 16) begin |
assign fifo_empty[2][nr_of_wb_ports_clk2:15] = {(16-nr_of_wb_ports_clk2){1'b1}}; |
end |
end else begin |
assign fifo_empty[2] = {16{1'b1}}; |
assign fifo_dat_o[2] = {36{1'b0}}; |
end |
endgenerate |
end |
end else begin |
assign fifo_empty[2] = {16{1'b1}}; |
assign fifo_dat_o[2] = {36{1'b0}}; |
end |
endgenerate |
|
generate |
if (nr_of_wb_clk_domains > 3) begin |
versatile_mem_ctrl_wb |
# (.nr_of_wb_ports(nr_of_wb_ports_clk3)) |
wb3( |
generate |
if (nr_of_wb_clk_domains > 3) begin |
versatile_mem_ctrl_wb |
# (.nr_of_wb_ports(nr_of_wb_ports_clk3)) |
wb3 |
( |
// wishbone side |
.wb_adr_i_v(wb_adr_i_3), |
.wb_dat_i_v(wb_dat_i_3), |
241,185 → 250,188
.sdram_fifo_we(fifo_we[3][0:nr_of_wb_ports_clk3-1]), |
.sdram_clk(sdram_clk), |
.sdram_rst(sdram_rst) ); |
if (nr_of_wb_ports_clk3 < 16) begin |
if (nr_of_wb_ports_clk3 < 16) begin |
assign fifo_empty[3][nr_of_wb_ports_clk3:15] = {(16-nr_of_wb_ports_clk3){1'b1}}; |
end |
end else begin |
assign fifo_empty[3] = {16{1'b1}}; |
assign fifo_dat_o[3] = {36{1'b0}}; |
end |
endgenerate |
end |
end else begin |
assign fifo_empty[3] = {16{1'b1}}; |
assign fifo_dat_o[3] = {36{1'b0}}; |
end |
endgenerate |
|
encode encode0 ( |
.fifo_empty_0(fifo_empty[0]), .fifo_empty_1(fifo_empty[1]), .fifo_empty_2(fifo_empty[2]), .fifo_empty_3(fifo_empty[3]), |
.fifo_sel(fifo_sel_i), .fifo_sel_domain(fifo_sel_domain_i) |
); |
encode encode0 |
( |
.fifo_empty_0(fifo_empty[0]), .fifo_empty_1(fifo_empty[1]), .fifo_empty_2(fifo_empty[2]), .fifo_empty_3(fifo_empty[3]), |
.fifo_sel(fifo_sel_i), .fifo_sel_domain(fifo_sel_domain_i) |
); |
|
always @ (posedge sdram_clk or posedge sdram_rst) |
begin |
if (sdram_rst) |
{fifo_sel_reg,fifo_sel_domain_reg} <= {16'h0,2'b00}; |
else |
if (idle) |
always @ (posedge sdram_clk or posedge sdram_rst) |
begin |
if (sdram_rst) |
{fifo_sel_reg,fifo_sel_domain_reg} <= {16'h0,2'b00}; |
else |
if (idle) |
{fifo_sel_reg,fifo_sel_domain_reg} <= {fifo_sel_i,fifo_sel_domain_i}; |
end |
end |
|
decode decode0 ( |
.fifo_sel(fifo_sel_reg), .fifo_sel_domain(fifo_sel_domain_reg), |
.fifo_we_0(fifo_re[0]), .fifo_we_1(fifo_re[1]), .fifo_we_2(fifo_re[2]), .fifo_we_3(fifo_re[3]) |
); |
decode decode0 |
( |
.fifo_sel(fifo_sel_reg), .fifo_sel_domain(fifo_sel_domain_reg), |
.fifo_we_0(fifo_re[0]), .fifo_we_1(fifo_re[1]), .fifo_we_2(fifo_re[2]), .fifo_we_3(fifo_re[3]) |
); |
|
// fifo_re[0-3] is a one-hot read enable structure |
// fifo_empty should go active when chosen fifo queue is empty |
assign current_fifo_empty = (idle) ? (!(|fifo_sel_i)) : (|(fifo_empty[0] & fifo_re[0])) | (|(fifo_empty[1] & fifo_re[1])) | (|(fifo_empty[2] & fifo_re[2])) | (|(fifo_empty[3] & fifo_re[3])); |
// fifo_re[0-3] is a one-hot read enable structure |
// fifo_empty should go active when chosen fifo queue is empty |
assign current_fifo_empty = (idle) ? (!(|fifo_sel_i)) : (|(fifo_empty[0] & fifo_re[0])) | (|(fifo_empty[1] & fifo_re[1])) | (|(fifo_empty[2] & fifo_re[2])) | (|(fifo_empty[3] & fifo_re[3])); |
|
decode decode1 ( |
.fifo_sel(fifo_sel_dly), .fifo_sel_domain(fifo_sel_domain_dly), |
.fifo_we_0(fifo_we[0]), .fifo_we_1(fifo_we[1]), .fifo_we_2(fifo_we[2]), .fifo_we_3(fifo_we[3]) |
); |
decode decode1 |
( |
.fifo_sel(fifo_sel_dly), .fifo_sel_domain(fifo_sel_domain_dly), |
.fifo_we_0(fifo_we[0]), .fifo_we_1(fifo_we[1]), .fifo_we_2(fifo_we[2]), .fifo_we_3(fifo_we[3]) |
); |
|
`ifdef SDR_16 |
|
wire ref_cnt_zero; |
reg [15:0] dq_i_reg, dq_i_tmp_reg; |
reg [17:0] dq_o_tmp_reg; |
wire cmd_aref, cmd_read; |
|
// refresch counter |
ref_counter ref_counter0( .zq(ref_cnt_zero), .rst(sdram_rst), .clk(sdram_clk)); |
always @ (posedge sdram_clk or posedge sdram_rst) |
if (sdram_rst) |
refresh_req <= 1'b0; |
else |
if (ref_cnt_zero) |
refresh_req <= 1'b1; |
else if (cmd_aref) |
refresh_req <= 1'b0; |
|
// SDR SDRAM 16 FSM |
fsm_sdr_16 # ( |
.ba_size(ba_size), |
.row_size(row_size), |
.col_size(col_size), |
.init_cl(cl) |
) |
fsm_sdr_16( |
.adr_i({fifo_dat_o[fifo_sel_domain_reg][ba_size+row_size+col_size+6-2:6],1'b0}), |
.we_i(fifo_dat_o[fifo_sel_domain_reg][5]), |
.bte_i(fifo_dat_o[fifo_sel_domain_reg][4:3]), |
.sel_i({fifo_dat_o[fifo_sel_domain_reg][3:2],dq_o_tmp_reg[1:0]}), |
.fifo_empty(current_fifo_empty), |
.fifo_rd_adr(fifo_rd_adr), |
.fifo_rd_data(fifo_rd_data), |
.state_idle(idle), |
.count0(count0), |
.refresh_req(refresh_req), |
.cmd_aref(cmd_aref), |
.cmd_read(cmd_read), |
.ba(ba_pad_o), .a(a_pad_o), |
.cmd({ras_pad_o, cas_pad_o, we_pad_o}), |
.dq_oe(dq_oe), |
.dqm(dqm_pad_o), |
.sdram_clk(sdram_clk), |
.sdram_rst(sdram_rst) |
); |
wire ref_cnt_zero; |
reg [(`SDRAM_DATA_WIDTH)-1:0] dq_i_reg, dq_i_tmp_reg; |
reg [17:0] dq_o_tmp_reg; |
wire cmd_aref, cmd_read; |
|
assign cs_pad_o = 1'b0; |
assign cke_pad_o = 1'b1; |
// refresch counter |
ref_counter ref_counter0( .zq(ref_cnt_zero), .rst(sdram_rst), .clk(sdram_clk)); |
always @ (posedge sdram_clk or posedge sdram_rst) |
if (sdram_rst) |
refresh_req <= 1'b0; |
else |
if (ref_cnt_zero) |
refresh_req <= 1'b1; |
else if (cmd_aref) |
refresh_req <= 1'b0; |
|
// SDR SDRAM 16 FSM |
fsm_sdr_16 fsm_sdr_16_0 |
( |
.adr_i({fifo_dat_o[fifo_sel_domain_reg][`BA_SIZE+`ROW_SIZE+`COL_SIZE+6-2:6],1'b0}), |
.we_i(fifo_dat_o[fifo_sel_domain_reg][5]), |
.bte_i(fifo_dat_o[fifo_sel_domain_reg][4:3]), |
.sel_i({fifo_dat_o[fifo_sel_domain_reg][3:2],dq_o_tmp_reg[1:0]}), |
.fifo_empty(current_fifo_empty), |
.fifo_rd_adr(fifo_rd_adr), |
.fifo_rd_data(fifo_rd_data), |
.state_idle(idle), |
.count0(count0), |
.refresh_req(refresh_req), |
.cmd_aref(cmd_aref), |
.cmd_read(cmd_read), |
.ba(ba_pad_o), .a(a_pad_o), |
.cmd({ras_pad_o, cas_pad_o, we_pad_o}), |
.dq_oe(dq_oe), |
.dqm(dqm_pad_o), |
.sdram_clk(sdram_clk), |
.sdram_rst(sdram_rst) |
); |
/* |
defparam fsm_sdr_16_0.ba_size = ba_size; |
defparam fsm_sdr_16_0.row_size = row_size; |
defparam fsm_sdr_16_0.col_size = col_size; |
defparam fsm_sdr_16_0.init_cl = cl; |
*/ |
assign cs_pad_o = 1'b0; |
assign cke_pad_o = 1'b1; |
|
genvar i; |
generate |
for (i=0; i < 16; i=i+1) begin : dly |
genvar i; |
generate |
for (i=0; i < 16; i=i+1) begin : dly |
|
defparam delay0.depth=cl+2; |
defparam delay0.width=1; |
delay delay0 ( |
.d(fifo_sel_reg[i]), |
.q(fifo_sel_dly[i]), |
.clk(sdram_clk), |
.rst(sdram_rst) |
); |
end |
|
defparam delay1.depth=cl+2; |
defparam delay1.width=2; |
delay delay1 ( |
.d(fifo_sel_domain_reg), |
.q(fifo_sel_domain_dly), |
.clk(sdram_clk), |
.rst(sdram_rst) |
); |
|
defparam delay2.depth=cl+2; |
defparam delay2.width=1; |
delay delay2 ( |
.d(cmd_read), |
.q(fifo_wr), |
.clk(sdram_clk), |
.rst(sdram_rst) |
); |
|
endgenerate |
defparam delay0.depth=`INIT_CL+2; |
defparam delay0.width=1; |
delay delay0 ( |
.d(fifo_sel_reg[i]), |
.q(fifo_sel_dly[i]), |
.clk(sdram_clk), |
.rst(sdram_rst) |
); |
end |
|
defparam delay1.depth=`INIT_CL+2; |
defparam delay1.width=2; |
delay delay1 ( |
.d(fifo_sel_domain_reg), |
.q(fifo_sel_domain_dly), |
.clk(sdram_clk), |
.rst(sdram_rst) |
); |
|
defparam delay2.depth=`INIT_CL+2; |
defparam delay2.width=1; |
delay delay2 ( |
.d(cmd_read), |
.q(fifo_wr), |
.clk(sdram_clk), |
.rst(sdram_rst) |
); |
|
endgenerate |
|
// output registers |
assign cs_n_pad_o = 1'b0; |
assign cke_pad_o = 1'b1; |
|
always @ (posedge sdram_clk or posedge sdram_rst) |
// output registers |
assign cs_n_pad_o = 1'b0; |
assign cke_pad_o = 1'b1; |
|
always @ (posedge sdram_clk or posedge sdram_rst) |
if (sdram_rst) |
{dq_i_reg, dq_i_tmp_reg} <= {16'h0000,16'h0000}; |
else |
{dq_i_reg, dq_i_tmp_reg} <= {dq_i, dq_i_reg}; |
|
assign fifo_dat_i = {dq_i_tmp_reg, dq_i_reg}; |
assign fifo_dat_i = {dq_i_tmp_reg, dq_i_reg}; |
|
always @ (posedge sdram_clk or posedge sdram_rst) |
if (sdram_rst) |
dq_o_tmp_reg <= 18'h0; |
else |
dq_o_tmp_reg <= {fifo_dat_o[fifo_sel_domain_reg][19:4],fifo_dat_o[fifo_sel_domain_reg][1:0]}; |
|
// output dq_o mux and dffs |
always @ (posedge sdram_clk or posedge sdram_rst) |
if (sdram_rst) |
dq_o <= 16'h0000; |
else |
if (~count0) |
dq_o <= fifo_dat_o[fifo_sel_domain_reg][35:20]; |
else |
dq_o <= dq_o_tmp_reg[17:2]; |
|
/* |
// data mask signals should be not(sel_i) for write and 2'b00 for read |
always @ (posedge sdram_clk or posedge sdram_rst) |
if (sdram_rst) |
dq_o_tmp_reg <= 18'h0; |
dqm_pad_o <= 2'b00; |
else |
dq_o_tmp_reg <= {fifo_dat_o[fifo_sel_domain_reg][19:4],fifo_dat_o[fifo_sel_domain_reg][1:0]}; |
|
// output dq_o mux and dffs |
always @ (posedge sdram_clk or posedge sdram_rst) |
if (sdram_rst) |
dq_o <= 16'h0000; |
if (~count0) |
dqm_pad_o <= ~fifo_dat_o[fifo_sel_domain_reg][3:2]; |
else |
if (~count0) |
dq_o <= fifo_dat_o[fifo_sel_domain_reg][35:20]; |
else |
dq_o <= dq_o_tmp_reg[17:2]; |
|
/* |
// data mask signals should be not(sel_i) for write and 2'b00 for read |
always @ (posedge sdram_clk or posedge sdram_rst) |
if (sdram_rst) |
dqm_pad_o <= 2'b00; |
else |
if (~count0) |
dqm_pad_o <= ~fifo_dat_o[fifo_sel_domain_reg][3:2]; |
else |
dqm_pad_o <= ~dq_o_tmp_reg[1:0]; |
dqm_pad_o <= ~dq_o_tmp_reg[1:0]; |
*/ |
/* |
/* |
always @ (posedge sdram_clk or posedge sdram_rst) |
if (sdram_rst) begin |
{dq_o, dqm_pad_o} <= {16'h0000,2'b00}; |
|
{dq_o, dqm_pad_o} <= {16'h0000,2'b00}; |
|
end else |
if (~count0) begin |
dq_o <= fifo_dat_o[fifo_sel_domain_reg][35:20]; |
dq_o_tmp_reg[17:2] <= fifo_dat_o[fifo_sel_domain_reg][19:4]; |
if (cmd_read) |
dqm_pad_o <= 2'b00; |
else |
dqm_pad_o <= ~fifo_dat_o[fifo_sel_domain_reg][3:2]; |
if (cmd_read) |
dq_o_tmp_reg[1:0] <= 2'b00; |
else |
dq_o_tmp_reg[1:0] <= ~fifo_dat_o[fifo_sel_domain_reg][1:0]; |
if (~count0) begin |
dq_o <= fifo_dat_o[fifo_sel_domain_reg][35:20]; |
dq_o_tmp_reg[17:2] <= fifo_dat_o[fifo_sel_domain_reg][19:4]; |
if (cmd_read) |
dqm_pad_o <= 2'b00; |
else |
dqm_pad_o <= ~fifo_dat_o[fifo_sel_domain_reg][3:2]; |
if (cmd_read) |
dq_o_tmp_reg[1:0] <= 2'b00; |
else |
dq_o_tmp_reg[1:0] <= ~fifo_dat_o[fifo_sel_domain_reg][1:0]; |
end else |
{dq_o,dqm_pad_o} <= dq_o_tmp_reg; |
*/ |
{dq_o,dqm_pad_o} <= dq_o_tmp_reg; |
*/ |
|
|
`endif // `ifdef SDR_16 |
431,26 → 443,26
wire ck_fb; |
reg cke, ras, cas, we, cs_n; |
wire ras_o, cas_o, we_o, cs_n_o; |
wire [1:0] ba_o; |
wire [1:0] ba_o; |
wire [12:0] addr_o; |
reg [1:0] ba; |
reg [12:0] addr; |
reg [1:0] ba; |
reg [12:0] addr; |
wire dq_en, dqm_en; |
reg [15:0] dq_tx_reg; |
reg [15:0] dq_tx_reg; |
wire [15:0] dq_tx; |
reg [31:0] dq_rx_reg; |
reg [31:0] dq_rx_reg; |
wire [31:0] dq_rx; |
wire [15:0] dq_o; |
reg [3:0] dqm_tx_reg; |
wire [3:0] dqm_tx; |
wire [1:0] dqm_o, dqs_o, dqs_n_o; |
reg [3:0] dqm_tx_reg; |
wire [3:0] dqm_tx; |
wire [1:0] dqm_o, dqs_o, dqs_n_o; |
wire ref_delay, ref_delay_ack; |
wire bl_en, bl_ack; |
wire tx_fifo_re_i; |
wire adr_init_delay; |
reg adr_init_delay_i; |
reg [3:0] burst_cnt; |
wire [3:0] burst_next_cnt, burst_length; |
reg [3:0] burst_cnt; |
wire [3:0] burst_next_cnt, burst_length; |
wire burst_mask; |
wire [12:0] cur_row; |
|
514,7 → 526,7
// Wishbone burst length |
assign burst_length = (adr_init && tx_fifo_dat_o[2:0] == 3'b000) ? 4'd1 : // classic cycle |
(adr_init && tx_fifo_dat_o[2:0] == 3'b010) ? 4'd4 : // incremental burst cycle |
burst_length; |
burst_length; |
|
// Burst mask |
// Burst length counter |
531,22 → 543,22
// Control outports, DDR2 SDRAM |
always @ (posedge sdram_clk_180 or posedge wb_rst) |
if (wb_rst) begin |
cs_n <= 1'b0; |
cke <= 1'b0; |
ras <= 1'b0; |
cas <= 1'b0; |
we <= 1'b0; |
ba <= 2'b00; |
addr <= 13'b0000000000000; |
cs_n <= 1'b0; |
cke <= 1'b0; |
ras <= 1'b0; |
cas <= 1'b0; |
we <= 1'b0; |
ba <= 2'b00; |
addr <= 13'b0000000000000; |
end |
else begin |
cs_n <= cs_n_o; |
cke <= 1'b1; |
ras <= ras_o; |
cas <= cas_o; |
we <= we_o; |
ba <= ba_o; |
addr <= addr_o; |
cs_n <= cs_n_o; |
cke <= 1'b1; |
ras <= ras_o; |
cas <= cas_o; |
we <= we_o; |
ba <= ba_o; |
addr <= addr_o; |
end |
|
assign cke_pad_o = cke; |
559,9 → 571,10
|
|
// Read latency, delay the control signals to fit latency of the DDR2 SDRAM |
defparam delay0.depth=`CL+`AL+2; |
defparam delay0.depth=`INIT_CL+`AL+2; |
defparam delay0.width=4; |
delay delay0 ( |
delay delay0 |
( |
.d({read && !burst_mask,tx_fifo_b_sel_i_cur}), |
.q({rx_fifo_we,rx_fifo_a_sel_i}), |
.clk(sdram_clk_0), |
569,9 → 582,10
); |
|
// write latency, delay the control signals to fit latency of the DDR2 SDRAM |
defparam delay1.depth=`CL+`AL-1; |
defparam delay1.depth=`INIT_CL+`AL-1; |
defparam delay1.width=2; |
delay delay1 ( |
delay delay1 |
( |
.d({write, burst_mask}), |
.q({dq_en, dqm_en}), |
.clk(sdram_clk_270), |
579,22 → 593,24
); |
|
// if CL>3 delay read from Tx FIFO |
defparam delay2.depth=`CL+`AL-3; |
defparam delay2.depth=`INIT_CL+`AL-3; |
defparam delay2.width=1; |
delay delay2 ( |
.d(tx_fifo_re_i && !burst_mask), |
.q(tx_fifo_re), |
.clk(sdram_clk_0), |
.rst(wb_rst) |
); |
delay delay2 |
( |
.d(tx_fifo_re_i && !burst_mask), |
.q(tx_fifo_re), |
.clk(sdram_clk_0), |
.rst(wb_rst) |
); |
|
// if CL=3, no delay |
//assign tx_fifo_re = tx_fifo_re_i && !burst_mask; |
|
// Increment address |
defparam delay3.depth=`CL+`AL-1; |
defparam delay3.depth=`INIT_CL+`AL-1; |
defparam delay3.width=1; |
delay delay3 ( |
delay delay3 |
( |
.d({write|read}), |
.q({adr_inc}), |
.clk(sdram_clk_0), |
604,7 → 620,8
// DCM/PLL with internal and external feedback |
// Remove skew from internal and external clock |
// Parameters are set in dcm_pll.v |
dcm_pll dcm_pll_0 ( |
dcm_pll dcm_pll_0 |
( |
.rst(wb_rst), |
.clk_in(sdram_clk), |
.clkfb_in(ck_fb_pad_i), |
616,7 → 633,8
); |
|
// DDR2 IF |
versatile_mem_ctrl_ddr versatile_mem_ctrl_ddr_0 ( |
versatile_mem_ctrl_ddr versatile_mem_ctrl_ddr_0 |
( |
// DDR2 SDRAM ports |
.ck_o(ck_pad_o), |
.ck_n_o(ck_n_pad_o), |
/fsm_sdr_16.v
1,67 → 1,70
`timescale 1ns/1ns |
`include "sdr_16_defines.v" |
module fsm_sdr_16 ( |
adr_i, we_i, bte_i, sel_i, |
fifo_empty, fifo_rd_adr, fifo_rd_data, count0, |
refresh_req, cmd_aref, cmd_read, state_idle, |
ba, a, cmd, dqm, dq_oe, |
sdram_clk, sdram_rst |
); |
adr_i, we_i, bte_i, sel_i, |
fifo_empty, fifo_rd_adr, fifo_rd_data, count0, |
refresh_req, cmd_aref, cmd_read, state_idle, |
ba, a, cmd, dqm, dq_oe, |
sdram_clk, sdram_rst |
); |
|
parameter ba_size = 2; |
parameter row_size = 13; |
parameter col_size = 9; |
/* Now these are defined |
parameter ba_size = 2; |
parameter row_size = 13; |
parameter col_size = 9; |
*/ |
|
input [`BA_SIZE+`ROW_SIZE+`COL_SIZE-1:0] adr_i; |
input we_i; |
input [1:0] bte_i; |
input [3:0] sel_i; |
|
input [ba_size+row_size+col_size-1:0] adr_i; |
input we_i; |
input [1:0] bte_i; |
input [3:0] sel_i; |
input fifo_empty; |
output fifo_rd_adr, fifo_rd_data; |
output reg count0; |
|
input fifo_empty; |
output fifo_rd_adr, fifo_rd_data; |
output reg count0; |
input refresh_req; |
output reg cmd_aref; // used for rerfresh ack |
output reg cmd_read; // used for ingress fifo control |
output state_idle; // state=idle |
|
input refresh_req; |
output reg cmd_aref; // used for rerfresh ack |
output reg cmd_read; // used for ingress fifo control |
output state_idle; // state=idle |
output reg [1:0] ba /*synthesis syn_useioff=1 syn_allow_retiming=0 */; |
output reg [12:0] a /*synthesis syn_useioff=1 syn_allow_retiming=0 */; |
output reg [2:0] cmd /*synthesis syn_useioff=1 syn_allow_retiming=0 */; |
output reg [1:0] dqm /*synthesis syn_useioff=1 syn_allow_retiming=0 */; |
output reg dq_oe; |
|
output reg [1:0] ba /*synthesis syn_useioff=1 syn_allow_retiming=0 */; |
output reg [12:0] a /*synthesis syn_useioff=1 syn_allow_retiming=0 */; |
output reg [2:0] cmd /*synthesis syn_useioff=1 syn_allow_retiming=0 */; |
output reg [1:0] dqm /*synthesis syn_useioff=1 syn_allow_retiming=0 */; |
output reg dq_oe; |
input sdram_clk, sdram_rst; |
|
input sdram_clk, sdram_rst; |
wire [`BA_SIZE-1:0] bank; |
wire [`ROW_SIZE-1:0] row; |
wire [`COL_SIZE-1:0] col; |
wire [12:0] col_reg_a10_fix; |
reg [0:31] shreg; |
wire stall; // active if write burst need data |
|
wire [ba_size-1:0] bank; |
wire [row_size-1:0] row; |
wire [col_size-1:0] col; |
wire [12:0] col_reg_a10_fix; |
reg [0:31] shreg; |
wire stall; // active if write burst need data |
reg [0:15] fifo_sel_reg_int; |
reg [1:0] fifo_sel_domain_reg_int; |
|
reg [0:15] fifo_sel_reg_int; |
reg [1:0] fifo_sel_domain_reg_int; |
// adr_reg {ba,row,col,we} |
reg [1:0] ba_reg; |
reg [`ROW_SIZE-1:0] row_reg; |
reg [`COL_SIZE-1:0] col_reg; |
reg we_reg; |
reg [1:0] bte_reg; |
|
// adr_reg {ba,row,col,we} |
reg [1:0] ba_reg; |
reg [row_size-1:0] row_reg; |
reg [col_size-1:0] col_reg; |
reg we_reg; |
reg [1:0] bte_reg; |
// to keep track of open rows per bank |
reg [`ROW_SIZE-1:0] open_row[0:3]; |
reg [0:3] open_ba; |
wire current_bank_closed, current_row_open; |
reg current_bank_closed_reg, current_row_open_reg; |
|
// to keep track of open rows per bank |
reg [row_size-1:0] open_row[0:3]; |
reg [0:3] open_ba; |
wire current_bank_closed, current_row_open; |
reg current_bank_closed_reg, current_row_open_reg; |
|
parameter [1:0] linear = 2'b00, |
parameter [1:0] linear = 2'b00, |
beat4 = 2'b01, |
beat8 = 2'b10, |
beat16 = 2'b11; |
|
parameter [2:0] cmd_nop = 3'b111, |
parameter [2:0] cmd_nop = 3'b111, |
cmd_act = 3'b011, |
cmd_rd = 3'b101, |
cmd_wr = 3'b100, |
69,8 → 72,10
cmd_rfr = 3'b001, |
cmd_lmr = 3'b000; |
|
// ctrl FSM |
parameter [2:0] init = 3'b000, |
// ctrl FSM |
|
/* define instead of param, as synplify is doing weird things |
parameter [2:0] init = 3'b000, |
idle = 3'b001, |
rfr = 3'b010, |
adr = 3'b011, |
78,200 → 83,207
act = 3'b101, |
w4d = 3'b110, |
rw = 3'b111; |
reg [2:0] state, next; |
*/ |
`define FSM_INIT 3'b000 |
`define FSM_IDLE 3'b001 |
`define FSM_RFR 3'b010 |
`define FSM_ADR 3'b011 |
`define FSM_PCH 3'b100 |
`define FSM_ACT 3'b101 |
`define FSM_W4D 3'b110 |
`define FSM_RW 3'b111 |
|
reg [2:0] state, next; |
|
function [12:0] a10_fix; |
input [col_size-1:0] a; |
integer i; |
begin |
for (i=0;i<13;i=i+1) begin |
if (i<10) |
if (i<col_size) |
function [12:0] a10_fix; |
input [`COL_SIZE-1:0] a; |
integer i; |
begin |
for (i=0;i<13;i=i+1) begin |
if (i<10) |
if (i<`COL_SIZE) |
a10_fix[i] = a[i]; |
else |
a10_fix[i] = 1'b0; |
else if (i==10) |
a10_fix[i] = 1'b0; |
else |
a10_fix[i] = 1'b0; |
else if (i==10) |
a10_fix[i] = 1'b0; |
else |
if (i<col_size) |
if (i<`COL_SIZE) |
a10_fix[i] = a[i-1]; |
else |
else |
a10_fix[i] = 1'b0; |
end |
end |
endfunction |
end |
end |
endfunction |
|
|
assign {bank,row,col} = adr_i; |
assign {bank,row,col} = adr_i; |
|
always @ (posedge sdram_clk or posedge sdram_rst) |
if (sdram_rst) |
state <= init; |
else |
state <= next; |
|
always @* |
begin |
next = 3'bx; |
case (state) |
init: if (shreg[31]) next = idle; |
else next = init; |
idle: if (refresh_req) next = rfr; |
else if (!fifo_empty) next = adr; |
else next = idle; |
rfr: if (shreg[5]) next = idle; |
else next = rfr; |
adr: if (current_row_open_reg & (shreg[4]) & we_reg) next = w4d; |
else if (current_row_open_reg & shreg[4]) next = rw; |
else if (current_bank_closed_reg & shreg[4]) next = act; |
else if (shreg[4]) next = pch; |
else next = adr; |
pch: if (shreg[1]) next = act; |
else next = pch; |
act: if (shreg[2] & (!fifo_empty | !we_reg)) next = rw; |
else if (shreg[2] & fifo_empty) next = w4d; |
else next = act; |
w4d: if (!fifo_empty) next = rw; |
else next = w4d; |
rw: if (bte_reg==linear & shreg[1]) |
next = idle; |
else if (bte_reg==beat4 & shreg[7]) |
next = idle; |
else if (bte_reg==beat8 & shreg[15]) |
next = idle; |
else if (bte_reg==beat16 & shreg[31]) |
next = idle; |
else |
next = rw; |
endcase |
end |
always @ (posedge sdram_clk or posedge sdram_rst) |
if (sdram_rst) |
state <= `FSM_INIT; |
else |
state <= next; |
|
always @* |
begin |
next = 3'bx; |
case (state) |
`FSM_INIT: if (shreg[31]) next = `FSM_IDLE; |
else next = `FSM_INIT; |
`FSM_IDLE: if (refresh_req) next = `FSM_RFR; |
else if (!fifo_empty) next = `FSM_ADR; |
else next = `FSM_IDLE; |
`FSM_RFR: if (shreg[5]) next = `FSM_IDLE; |
else next = `FSM_RFR; |
`FSM_ADR: if (current_row_open_reg & (shreg[4]) & we_reg) next = `FSM_W4D; |
else if (current_row_open_reg & shreg[4]) next = `FSM_RW; |
else if (current_bank_closed_reg & shreg[4]) next = `FSM_ACT; |
else if (shreg[4]) next = `FSM_PCH; |
else next = `FSM_ADR; |
`FSM_PCH: if (shreg[1]) next = `FSM_ACT; |
else next = `FSM_PCH; |
`FSM_ACT: if (shreg[2] & (!fifo_empty | !we_reg)) next = `FSM_RW; |
else if (shreg[2] & fifo_empty) next = `FSM_W4D; |
else next = `FSM_ACT; |
`FSM_W4D: if (!fifo_empty) next = `FSM_RW; |
else next = `FSM_W4D; |
`FSM_RW: if (bte_reg==linear & shreg[1]) |
next = `FSM_IDLE; |
else if (bte_reg==beat4 & shreg[7]) |
next = `FSM_IDLE; |
else if (bte_reg==beat8 & shreg[15]) |
next = `FSM_IDLE; |
else if (bte_reg==beat16 & shreg[31]) |
next = `FSM_IDLE; |
else |
next = `FSM_RW; |
endcase |
end |
|
// active if write burst need data |
assign stall = state==rw & next==rw & fifo_empty & count0 & we_reg; |
// active if write burst need data |
assign stall = state==`FSM_RW & next==`FSM_RW & fifo_empty & count0 & we_reg; |
|
// counter |
always @ (posedge sdram_clk or posedge sdram_rst) |
begin |
if (sdram_rst) begin |
shreg <= {1'b1,{31{1'b0}}}; |
count0 <= 1'b0; |
end else |
if (state!=next) begin |
shreg <= {1'b1,{31{1'b0}}}; |
count0 <= 1'b0; |
end else |
// counter |
always @ (posedge sdram_clk or posedge sdram_rst) |
begin |
if (sdram_rst) begin |
shreg <= {1'b1,{31{1'b0}}}; |
count0 <= 1'b0; |
end else |
if (state!=next) begin |
shreg <= {1'b1,{31{1'b0}}}; |
count0 <= 1'b0; |
end else |
if (~stall) begin |
shreg <= shreg >> 1; |
count0 <= ~count0; |
shreg <= shreg >> 1; |
count0 <= ~count0; |
end |
end |
end |
|
// LMR |
// [12:10] reserved |
// [9] WB, write burst; 0 - programmed burst length, 1 - single location |
// [8:7] OP Mode, 2'b00 |
// [6:4] CAS Latency; 3'b010 - 2, 3'b011 - 3 |
// [3] BT, Burst Type; 1'b0 - sequential, 1'b1 - interleaved |
// [2:0] Burst length; 3'b000 - 1, 3'b001 - 2, 3'b010 - 4, 3'b011 - 8, 3'b111 - full page |
parameter [0:0] init_wb = 1'b0; |
parameter [2:0] init_cl = 3'b010; |
parameter [0:0] init_bt = 1'b0; |
parameter [2:0] init_bl = 3'b001; |
// ba, a, cmd |
// col_reg_a10 has bit [10] set to zero to disable auto precharge |
assign col_reg_a10_fix = a10_fix(col_reg); |
|
// ba, a, cmd |
// col_reg_a10 has bit [10] set to zero to disable auto precharge |
assign col_reg_a10_fix = a10_fix(col_reg); |
|
// outputs dependent on state vector |
always @ (posedge sdram_clk or posedge sdram_rst) |
begin |
if (sdram_rst) begin |
{ba,a,cmd} <= {2'b00,13'd0,cmd_nop}; |
dqm <= 2'b11; |
cmd_aref <= 1'b0; |
cmd_read <= 1'b0; |
dq_oe <= 1'b0; |
{open_ba,open_row[0],open_row[1],open_row[2],open_row[3]} <= {4'b0000,{row_size*4{1'b0}}}; |
{ba_reg,row_reg,col_reg,we_reg,bte_reg} <= {2'b00, {row_size{1'b0}}, {col_size{1'b0}}, 1'b0, 2'b00 }; |
end else begin |
{ba,a,cmd} <= {2'b00,13'd0,cmd_nop}; |
dqm <= 2'b11; |
cmd_aref <= 1'b0; |
cmd_read <= 1'b0; |
dq_oe <= 1'b0; |
case (state) |
init: |
if (shreg[3]) begin |
{ba,a,cmd} <= {2'b00, 13'b0010000000000, cmd_pch}; |
open_ba[ba_reg] <= 1'b0; |
end else if (shreg[7] | shreg[19]) |
{ba,a,cmd,cmd_aref} <= {2'b00, 13'd0, cmd_rfr,1'b1}; |
else if (shreg[31]) |
{ba,a,cmd} <= {2'b00,3'b000,init_wb,2'b00,init_cl,init_bt,init_bl, cmd_lmr}; |
rfr: |
if (shreg[0]) begin |
{ba,a,cmd} <= {2'b00, 13'b0010000000000, cmd_pch}; |
open_ba <= 4'b0000; |
end else if (shreg[2]) |
{ba,a,cmd,cmd_aref} <= {2'b00, 13'd0, cmd_rfr,1'b1}; |
adr: |
if (shreg[3]) |
{ba_reg,row_reg,col_reg,we_reg,bte_reg} <= {bank,row,col,we_i,bte_i}; |
pch: |
if (shreg[0]) begin |
{ba,a,cmd} <= {ba_reg,13'd0,cmd_pch}; |
//open_ba <= 4'b0000; |
open_ba[ba_reg] <= 1'b0; |
end |
act: |
if (shreg[0]) begin |
{ba,a,cmd} <= {ba_reg,(13'd0 | row_reg),cmd_act}; |
{open_ba[ba_reg],open_row[ba_reg]} <= {1'b1,row_reg}; |
end |
rw: |
begin |
if (we_reg & !count0) |
// outputs dependent on state vector |
always @ (posedge sdram_clk or posedge sdram_rst) |
begin |
if (sdram_rst) begin |
{ba,a,cmd} <= {2'b00,13'd0,cmd_nop}; |
dqm <= 2'b11; |
cmd_aref <= 1'b0; |
cmd_read <= 1'b0; |
dq_oe <= 1'b0; |
{open_ba,open_row[0],open_row[1],open_row[2],open_row[3]} <= |
{4'b0000,{`ROW_SIZE*4{1'b0}}}; |
{ba_reg,row_reg,col_reg,we_reg,bte_reg} <= |
{2'b00, {`ROW_SIZE{1'b0}}, {`COL_SIZE{1'b0}}, 1'b0, 2'b00 }; |
end else begin |
{ba,a,cmd} <= {2'b00,13'd0,cmd_nop}; |
dqm <= 2'b11; |
cmd_aref <= 1'b0; |
cmd_read <= 1'b0; |
dq_oe <= 1'b0; |
case (state) |
`FSM_INIT: |
if (shreg[3]) begin |
{ba,a,cmd} <= {2'b00, 13'b0010000000000, cmd_pch}; |
open_ba[ba_reg] <= 1'b0; |
end else if (shreg[7] | shreg[19]) |
{ba,a,cmd,cmd_aref} <= {2'b00, 13'd0, cmd_rfr,1'b1}; |
else if (shreg[31]) |
{ba,a,cmd} <= |
{2'b00,3'b000,`INIT_WB,2'b00,`INIT_CL,`INIT_BT,`INIT_BL, cmd_lmr}; |
`FSM_RFR: |
if (shreg[0]) begin |
{ba,a,cmd} <= {2'b00, 13'b0010000000000, cmd_pch}; |
open_ba <= 4'b0000; |
end else if (shreg[2]) |
{ba,a,cmd,cmd_aref} <= {2'b00, 13'd0, cmd_rfr,1'b1}; |
`FSM_ADR: |
if (shreg[3]) |
{ba_reg,row_reg,col_reg,we_reg,bte_reg} <= |
{bank,row,col,we_i,bte_i}; |
`FSM_PCH: |
if (shreg[0]) begin |
{ba,a,cmd} <= {ba_reg,13'd0,cmd_pch}; |
//open_ba <= 4'b0000; |
open_ba[ba_reg] <= 1'b0; |
end |
`FSM_ACT: |
if (shreg[0]) begin |
{ba,a,cmd} <= {ba_reg,(13'd0 | row_reg),cmd_act}; |
{open_ba[ba_reg],open_row[ba_reg]} <= {1'b1,row_reg}; |
end |
`FSM_RW: |
begin |
if (we_reg & !count0) |
cmd <= cmd_wr; |
else if (!count0) |
else if (!count0) |
{cmd,cmd_read} <= {cmd_rd,1'b1}; |
else |
else |
cmd <= cmd_nop; |
if (we_reg & !count0) |
if (we_reg & !count0) |
dqm <= ~sel_i[3:2]; |
else if (we_reg & count0) |
else if (we_reg & count0) |
dqm <= ~sel_i[1:0]; |
else |
else |
dqm <= 2'b00; |
if (we_reg) |
if (we_reg) |
dq_oe <= 1'b1; |
if (~stall) |
if (~stall) |
case (bte_reg) |
linear: {ba,a} <= {ba_reg,col_reg_a10_fix}; |
beat4: {ba,a,col_reg[2:0]} <= {ba_reg,col_reg_a10_fix, col_reg[2:0] + 3'd1}; |
beat8: {ba,a,col_reg[3:0]} <= {ba_reg,col_reg_a10_fix, col_reg[3:0] + 4'd1}; |
beat16: {ba,a,col_reg[4:0]} <= {ba_reg,col_reg_a10_fix, col_reg[4:0] + 5'd1}; |
linear: {ba,a} <= {ba_reg,col_reg_a10_fix}; |
beat4: {ba,a,col_reg[2:0]} <= |
{ba_reg,col_reg_a10_fix, col_reg[2:0] + 3'd1}; |
beat8: {ba,a,col_reg[3:0]} <= |
{ba_reg,col_reg_a10_fix, col_reg[3:0] + 4'd1}; |
beat16: {ba,a,col_reg[4:0]} <= |
{ba_reg,col_reg_a10_fix, col_reg[4:0] + 5'd1}; |
endcase |
end |
endcase |
end |
end |
end |
endcase |
end |
end |
|
// rd_adr goes high when next adr is fetched from sync RAM and during write burst |
assign fifo_rd_adr = state==adr & shreg[0]; |
assign fifo_rd_data = ((state==rw & next==rw) & we_reg & !count0 & !fifo_empty); |
// rd_adr goes high when next adr is fetched from sync RAM and during write burst |
assign fifo_rd_adr = state==`FSM_ADR & shreg[0]; |
assign fifo_rd_data = ((state==`FSM_RW & next==`FSM_RW) & |
we_reg & !count0 & !fifo_empty); |
|
assign state_idle = (state==idle); |
assign state_idle = (state==`FSM_IDLE); |
|
// bank and row open ? |
assign current_bank_closed = !(open_ba[bank]); |
assign current_row_open = open_ba[bank] & (open_row[bank]==row); |
// bank and row open ? |
assign current_bank_closed = !(open_ba[bank]); |
assign current_row_open = open_ba[bank] & (open_row[bank]==row); |
|
always @ (posedge sdram_clk or posedge sdram_rst) |
if (sdram_rst) |
{current_bank_closed_reg, current_row_open_reg} <= {1'b1, 1'b0}; |
else |
//if (state==adr & counter[1:0]==2'b10) |
{current_bank_closed_reg, current_row_open_reg} <= {current_bank_closed, current_row_open}; |
|
always @ (posedge sdram_clk or posedge sdram_rst) |
if (sdram_rst) |
{current_bank_closed_reg, current_row_open_reg} <= {1'b1, 1'b0}; |
else |
//if (state==adr & counter[1:0]==2'b10) |
{current_bank_closed_reg, current_row_open_reg} <= |
{current_bank_closed, current_row_open}; |
|
|
endmodule |
/Makefile
47,9 → 47,9
cat $^ | cat copyright.v - > $@ |
|
# SDRAM 16-bit wide databus dependency files - force a recompile |
SDR_16_FILES=versatile_fifo_async_cmp.v async_fifo_mq.v delay.v codec.v gray_counter.v egress_fifo.v versatile_fifo_dual_port_ram_dc_sw.v dff_sr.v versatile_fifo_async_cmp.v ref_counter.v fsm_sdr_16.v versatile_mem_ctrl_wb.v versatile_mem_ctrl_top.v |
SDR_16_FILES=sdr_16_defines.v versatile_fifo_async_cmp.v async_fifo_mq.v delay.v codec.v gray_counter.v egress_fifo.v versatile_fifo_dual_port_ram_dc_sw.v dff_sr.v versatile_fifo_async_cmp.v ref_counter.v fsm_sdr_16.v versatile_mem_ctrl_wb.v versatile_mem_ctrl_top.v |
sdr_16.v: $(SDR_16_FILES) |
vppreproc +define+SDR_16 $^ > $@ |
vppreproc +define+SDR_16 +incdir+. $^ > $@ |
|
# the single all rule |
all: versatile_fifo_dual_port_ram.v versatile_fifo_async_cmp.v versatile_fifo_dual_port_ram_dc_dw.v counter_csvs fifo_fill.v sdr_16.v ddr_16.v versatile_mem_ctrl_ip.v |