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 86 to Rev 95
- ↔ Reverse comparison
Rev 86 → Rev 95
/Makefile
1,60 → 1,22
VERSATILE_FIFO_PROJECT_FILES =versatile_fifo_dual_port_ram.v |
VERSATILE_FIFO_PROJECT_FILES +=versatile_fifo_async_cmp.v |
VERSATILE_FIFO_PROJECT_FILES +=dff_sr.v |
VERSATILE_FIFO_PROJECT_FILES +=async_fifo_mq.v |
VERSATILE_FIFO_PROJECT_FILES +=async_fifo_mq_md.v |
VERSATILE_FIFO_PROJECT_FILES +=versatile_fifo_dual_port_ram_dc_sw.v |
async_fifo_dw_simplex_actel.v: |
svn export http://opencores.org/ocsvn/versatile_fifo/versatile_fifo/trunk/rtl/verilog/async_fifo_dw_simplex_actel.v |
|
$(VERSATILE_FIFO_PROJECT_FILES): |
svn export http://opencores.org/ocsvn/versatile_fifo/versatile_fifo/trunk/rtl/verilog/$@ |
|
VERSATILE_COUNTER_PROJECT_FILES =versatile_counter_generator.php |
VERSATILE_COUNTER_PROJECT_FILES +=CSV.class.php |
|
$(VERSATILE_COUNTER_PROJECT_FILES): |
svn export http://opencores.org/ocsvn/versatile_counter/versatile_counter/trunk/rtl/verilog/$@ |
versatile_counter_generator.php: |
svn export http://opencores.org/ocsvn/versatile_counter/versatile_counter/trunk/rtl/verilog/ $(VERSATILE_COUNTER_PROJECT_FILES) |
|
versatile_fifo_dual_port_ram_dc_dw.v: versatile_fifo_dual_port_ram.v |
vppreproc +define+TYPE+"dc_dw" +define+DC +define+DW +define+DATA_WIDTH+36 +define+ADDR_WIDTH+8 --simple versatile_fifo_dual_port_ram.v > versatile_fifo_dual_port_ram_dc_dw.v |
ref_counter.v: versatile_counter_generator.php |
excel2csv ref_counter.xls -S , |
./versatile_counter_generator.php ref_counter.csv > ref_counter.v |
|
# These rules will generate counters as they're required, but some CSVs stil hang around (the ones we don't use, ironically.) |
counter_csvs:versatile_counter.xls versatile_counter_generator.php CSV.class.php |
excel2csv $< -S , |
sdr_sdram_16_ctrl_actel.v: sdr_sdram_16_ctrl.v ref_counter.v sdr_16_defines.v async_fifo_dw_simplex_actel.v |
vppreproc --noline --noblank +define+RFR_LENGTH+10 +define+RFR_WRAP_VALUE+1001 +define+ACTEL sdr_sdram_16_ctrl.v > sdr_sdram_16_ctrl_actel.v |
|
%.csv: |
$(MAKE) counter_csvs |
|
%.v: %.csv |
@if [ ! -e $< ]; then ls $<; fi |
./versatile_counter_generator.php $^ > $@ |
|
fifo_fill.v: fifo_fill.fzm |
perl fizzim.pl -encoding onehot < fifo_fill.fzm > fifo_fill.v |
|
ddr_16_generated.v: ddr_16.fzm ddr_16_defines.v |
perl fizzim.pl -encoding onehot < ddr_16.fzm > $@ |
|
ddr_16.v: ddr_16_generated.v |
vppreproc --simple $^ > $@ |
|
#fifo_adr_counter.v: |
# @echo;echo "\tThis file,"$@", doesn't exist, is it still needed?!. \n\tMake will now stop";echo |
# ls notexisting |
|
VERSATILE_MEM_CTRL_IP_FILES=versatile_fifo_async_cmp.v async_fifo_mq.v versatile_fifo_dual_port_ram_dc_dw.v ctrl_counter.v fifo.v fifo_fill.v inc_adr.v ref_counter.v ref_delay_counter.v pre_delay_counter.v burst_length_counter.v ddr_16.v fsm_wb.v delay.v ddr_ff.v dcm_pll.v dff_sr.v versatile_mem_ctrl_ddr.v ddr_16_defines.v sdr_16_defines.v codec.v gray_counter.v egress_fifo.v versatile_fifo_dual_port_ram_dc_sw.v fsm_sdr_16.v versatile_mem_ctrl_wb.v versatile_mem_ctrl_top.v |
|
versatile_mem_ctrl_ip.v: $(VERSATILE_MEM_CTRL_IP_FILES) |
cat $^ | cat copyright.v - > $@ |
|
# SDRAM 16-bit wide databus dependency files - force a recompile |
SDR_16_FILES=sdr_16_defines.v fsm_wb.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 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 +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 |
all: sdr_sdram_16_ctrl_actel.v |
|
|
clean: |
rm -rf $(VERSATILE_FIFO_PROJECT_FILES) $(VERSATILE_COUNTER_PROJECT_FILES) |
rm -rf fifo_fill.v sdr_16.v ddr_16.v |
62,4 → 24,4
rm -rf *_counter.v |
rm -rf *.csv |
rm -rf *~ |
|
rm -rf sdr_sdram_16_ctrl_actel.v |
/wbwb_bridge.v
0,0 → 1,150
module wbwb_bridge ( |
// wishbone slave side |
wbs_dat_i, wbs_adr_i, wbs_sel_i, wbs_bte_i, wbs_cti_i, wbs_we_i, wbs_cyc_i, wbs_stb_i, wbs_dat_o, wbs_ack_o, wbs_clk, wbs_rst, |
// wishbone master side |
wbm_dat_o, wbm_adr_o, wbm_sel_o, wbm_bte_o, wbm_cti_o, wbm_we_o, wbm_cyc_o, wbm_stb_o, wbm_dat_i, wbm_ack_i, wbm_clk, wbm_rst); |
|
input [31:0] wbs_dat_i; |
input [31:2] wbs_adr_i; |
input [3:0] wbs_sel_i; |
input [1:0] wbs_bte_i; |
input [2:0] wbs_cti_i; |
input wbs_we_i, wbs_cyc_i, wbs_stb_i; |
output [31:0] wbs_dat_o; |
output reg wbs_ack_o; |
input wbs_clk, wbs_rst; |
|
output [31:0] wbm_dat_o; |
output reg [31:2] wbm_adr_o; |
output [3:0] wbm_sel_o; |
output reg [1:0] wbm_bte_o; |
output reg [2:0] wbm_cti_o; |
output reg wbm_we_o, wbm_cyc_o; |
output wbm_stb_o; |
input [31:0] wbm_dat_i; |
input wbm_ack_i; |
input wbm_clk, wbm_rst; |
|
parameter addr_width = 4; |
|
// bte |
parameter linear = 2'b00; |
parameter wrap4 = 2'b01; |
parameter wrap8 = 2'b10; |
parameter wrap16 = 2'b11; |
// cti |
parameter classic = 3'b000; |
parameter incburst = 3'b010; |
parameter endofburst = 3'b111; |
|
parameter adr = 1'b0; |
parameter data = 1'b1; |
|
reg wbs_we_reg, wbs_bte_reg, wbs, wbm; |
reg wbs_ack_o_rd; |
wire wbs_ack_o_wr; |
|
wire [35:0] a_d, a_q, b_d, b_q; |
wire a_wr, a_rd, a_fifo_full, a_fifo_empty, b_wr, b_rd, b_fifo_full, b_fifo_empty; |
|
reg [1:16] count; |
reg count_zero; |
|
`define WBS_EOC (wbs_bte_i==linear | wbs_cti_i==endofburst) & wbs_cyc_i & wbs_stb_i |
always @ (posedge wbs_clk or posedge wbs_rst) |
if (wbs_rst) |
wbs <= adr; |
else |
if (wbs_cyc_i & wbs_stb_i & (wbs==adr) & !a_fifo_full) |
wbs <= data; |
else if ((`WBS_EOC & !a_fifo_full) & (a_rd | (wbs_stb_i & wbs_we_i))) |
wbs <= adr; |
|
// wbs FIFO |
assign a_d = (wbs==adr) ? {wbs_adr_i[31:2],wbs_we_i,wbs_bte_i,wbs_cti_i} : {wbs_dat_i,wbs_sel_i}; |
assign a_wr = ((wbs== adr) & wbs_cyc_i & wbs_stb_i & !a_fifo_full) ? 1'b1 : |
((wbs==data) & wbs_cyc_i & wbs_stb_i & !a_fifo_full & wbs_we_i) ? 1'b1 : |
1'b0; |
assign wbs_dat_o = a_q[35:4]; |
assign a_rd = !a_fifo_empty; |
always @ (posedge wbs_clk or posedge wbs_rst) |
if (wbs_rst) |
wbs_ack_o_rd <= 1'b0; |
else |
wbs_ack_o_rd <= a_rd; |
|
always @ (posedge wbs_clk or posedge wbs_rst) |
if (wbs_rst) |
{wbs_we_reg,wbs_bte_reg} <= 2'b00; |
else |
{wbs_we_reg,wbs_bte_reg} <= {wbs_we_i,|wbs_bte_i}; |
|
assign wbs_ack_o_wr = wbs==data & wbs_we_reg & wbs_stb_i; |
|
assign wbs_ack_o = wbs_ack_o_rd | wbs_ack_o_wr; |
|
// wbm FIFO |
always @ (posedge wbm_clk or posedge wbm_rst) |
if (wbm_rst) |
wbm <= adr; |
else |
if (!b_fifo_empty) |
wbm <= data; |
else if (wbm_ack_i & ((b_q[4:3]==wrap4 & count[3]) | (b_q[4:3]==wrap8 & count[7]) | (b_q[4:3]==wrap16 & count[15]))) |
wbm <= adr; |
assign b_d = {wbm_dat_i,4'b1111}; |
assign b_wr = !wbm_we_o & wbm_ack_i; |
assign b_rd = (wbm==adr & !b_fifo_empty) ? 1'b1 : |
(wbm==data & wbm_ack_i) ? 1'b1 : |
1'b0; |
always @ (posedge wbm_clk or posedge wbm_rst) |
if (wbm_rst) |
{count,count_zero} <= {16'h8000,1'b1}; |
else |
casex ({b_fifo_empty,wbm_bte_o,count,count_zero,wbm_ack_i}) |
{1'b0,linear,16'b1xxxxxxxxxxxxxxx,1'bx,1'b1}: {count, count_zero} <= {16'h8000,1'b1}; |
{1'b0,wrap4 ,16'bxxx1xxxxxxxxxxxx,1'bx,1'b1}: {count, count_zero} <= {16'h8000,1'b1}; |
{1'b0,wrap8 ,16'bxxxxxxx1xxxxxxxx,1'bx,1'b1}: {count, count_zero} <= {16'h8000,1'b1}; |
{1'b0,wrap16,16'bxxxxxxxxxxxxxxx1,1'bx,1'b1}: {count, count_zero} <= {16'h8000,1'b1}; |
{1'b0,2'bxx,{16{1'bx}},1'b0,1'b1} : {count, count_zero} <= {count >> 1,1'b0}; |
default : ; |
endcase |
assign wbm_cyc_o = wbm; |
assign wbm_stb_o = (wbm==adr) ? 1'b0 : |
(wbm==data & wbm_we_o) ? !b_fifo_empty : |
1'b1; |
always @ (posedge wbm_clk or posedge wbm_rst) |
if (wbm_rst) |
{wbm_adr_o,wbm_we_o,wbm_bte_o,wbm_cti_o} <= {32'h0,1'b0,linear,classic}; |
else begin |
if (wbm==adr & !b_fifo_empty) |
{wbm_adr_o,wbm_we_o,wbm_bte_o,wbm_cti_o} <= b_q; |
else if ((b_q[4:3]==wrap4 & count[3]) | (b_q[4:3]==wrap8 & count[7]) | (b_q[4:3]==wrap16 & count[15])) |
wbm_cti_o <= endofburst; |
end |
assign {wbm_dat_o,wbm_sel_o} = b_q; |
|
async_fifo_dw_simplex_top |
# ( .data_width(36), .addr_width(addr_width)) |
fifo ( |
// a side |
.a_d(a_d), |
.a_wr(a_wr), |
.a_fifo_full(a_fifo_full), |
.a_q(a_q), |
.a_rd(a_rd), |
.a_fifo_empty(a_fifo_empty), |
.a_clk(wbs_clk), |
.a_rst(wbs_rst), |
// b side |
.b_d(b_d), |
.b_wr(b_wr), |
.b_fifo_full(b_fifo_full), |
.b_q(b_q), |
.b_rd(b_rd), |
.b_fifo_empty(b_fifo_empty), |
.b_clk(wbm_clk), |
.b_rst(wbm_rst) |
); |
|
endmodule |
/sdr_16_defines.v
1,59 → 1,68
// |
// 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 |
// |
|
// Most of these defines have an effect on things in fsm_sdr_16.v |
|
`define MT48LC16M16 // 32MB part |
//`define MT48LC4M16 // 8MB part |
|
// Define this to allow indication that a burst read is still going |
// to the wishbone state machine, so it doesn't start emptying the |
// ingress fifo after a aborted burst before the burst read is |
// actually finished. |
//`define SDRAM_WB_SAME_CLOCKS |
|
// If intending to burst write, and the wishbone clock is about 1/4 the speed |
// of the SDRAM clock, then the data may come late, and this triggers a bug |
// during write. To avoid this we can just wait a little longer for data when |
// burst reading (there's no almost_empty signal from the FIFO) |
//`define SLOW_WB_CLOCK |
|
|
`ifdef MT48LC16M16 |
// using 1 of MT48LC16M16 |
// SDRAM data width is 16 |
|
`define SDRAM_DATA_WIDTH 16 |
`define COL_SIZE 9 |
`define ROW_SIZE 13 |
`define BA_SIZE 2 |
|
`endif // `ifdef MT48LC16M16 |
|
`ifdef MT48LC4M16 |
// using 1 of MT48LC4M16 |
// SDRAM data width is 16 |
|
`define SDRAM_DATA_WIDTH 16 |
`define COL_SIZE 8 |
`define ROW_SIZE 12 |
`define BA_SIZE 2 |
|
`endif // `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 |
`define INIT_WB 1'b0 |
`define INIT_CL 3'b010 |
`define INIT_BT 1'b0 |
`define INIT_BL 3'b001 |
// |
// 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 |
// |
|
// Most of these defines have an effect on things in fsm_sdr_16.v |
|
`define MT48LC16M16 // 32MB part |
//`define MT48LC4M16 // 8MB part |
|
|
// SDRAM clock frequency |
// set refresh counter timeout |
// all rows should be refreshed every 64 ms |
`define SDRAM_CLK_64 |
//`define SDRAM_CLK_125 |
//`define SDRAM_CLK_133 |
//`define SDRAM_CLK_154 |
|
// Define this to allow indication that a burst read is still going |
// to the wishbone state machine, so it doesn't start emptying the |
// ingress fifo after a aborted burst before the burst read is |
// actually finished. |
//`define SDRAM_WB_SAME_CLOCKS |
|
// If intending to burst write, and the wishbone clock is about 1/4 the speed |
// of the SDRAM clock, then the data may come late, and this triggers a bug |
// during write. To avoid this we can just wait a little longer for data when |
// burst reading (there's no almost_empty signal from the FIFO) |
//`define SLOW_WB_CLOCK |
|
|
`ifdef MT48LC16M16 |
// using 1 of MT48LC16M16 |
// SDRAM data width is 16 |
|
`define SDRAM_DATA_WIDTH 16 |
`define COL_SIZE 9 |
`define ROW_SIZE 13 |
`define BA_SIZE 2 |
|
`endif // `ifdef MT48LC16M16 |
|
`ifdef MT48LC4M16 |
// using 1 of MT48LC4M16 |
// SDRAM data width is 16 |
|
`define SDRAM_DATA_WIDTH 16 |
`define COL_SIZE 8 |
`define ROW_SIZE 12 |
`define BA_SIZE 2 |
|
`endif // `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 |
`define INIT_WB 1'b0 |
`define INIT_CL 3'b010 |
`define INIT_BT 1'b0 |
`define INIT_BL 3'b001 |
/sdr_sdram_16_ctrl.v
0,0 → 1,321
`timescale 1ns/1ns |
//`sinclude "type_definitions.struct" |
`include "sdr_16_defines.v" |
`ifdef ACTEL |
`define SYN /*synthesis syn_useioff=1 syn_allow_retiming=0 */ |
`else |
`define SYN |
`endif |
module sdr_sdram_16_ctrl ( |
// wisbone i/f |
dat_i, adr_i, sel_i, cti_i, bte_i, we_i, cyc_i, stb_i, dat_o, ack_o, |
// SDR SDRAM |
ba, a, cmd, cke, cs_n, dqm, dq_i, dq_o, dq_oe, |
// system |
clk, rst); |
|
/* Now these are defined |
parameter ba_size = 2; |
parameter row_size = 13; |
parameter col_size = 9; |
*/ |
|
input [31:0] dat_i; |
input [`BA_SIZE+`COL_SIZE+`ROW_SIZE-1:2] adr_i; |
input [3:0] sel_i; |
input [2:0] cti_i; |
input [1:0] bte_i; |
input we_i, cyc_i, stb_i; |
output reg [31:0] dat_o; |
output ack_o; |
|
output reg [1:0] ba `SYN; |
output reg [12:0] a `SYN; |
output reg [2:0] cmd `SYN; |
output cke, cs_n; |
output reg [1:0] dqm `SYN; |
output reg [15:0] dq_o `SYN; |
output reg dq_oe; |
input [15:0] dq_i; |
|
input clk, rst; |
|
wire [`BA_SIZE-1:0] bank; |
wire [`ROW_SIZE-1:0] row; |
wire [`COL_SIZE-1:0] col; |
wire [12:0] col_a10_fix; |
reg [4:0] col_reg; |
reg [0:31] shreg; |
reg count0; |
wire stall; // active if write burst need data |
reg refresh_req, cmd_aref; |
reg cmd_read; |
reg wb_flag; |
|
// to keep track of open rows per bank |
reg [`ROW_SIZE-1:0] open_row[0:3]; |
reg [0:3] open_ba; |
reg current_bank_closed, current_row_open; |
|
`ifndef RFR_WRAP_VALUE |
parameter rfr_length = 10; |
parameter rfr_wrap_value = 1010; |
`else |
parameter rfr_length = `RFR_LENGTH; |
parameter rfr_wrap_value = `RFR_WRAP_VALUE; |
`endif |
|
parameter [1:0] linear = 2'b00, |
beat4 = 2'b01, |
beat8 = 2'b10, |
beat16 = 2'b11; |
|
parameter [2:0] cmd_nop = 3'b111, |
cmd_act = 3'b011, |
cmd_rd = 3'b101, |
cmd_wr = 3'b100, |
cmd_pch = 3'b010, |
cmd_rfr = 3'b001, |
cmd_lmr = 3'b000; |
|
// ctrl FSM |
`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 |
|
assign cke = 1'b1; |
assign cs_n = 1'b0; |
|
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) |
a10_fix[i] = a[i]; |
else |
a10_fix[i] = 1'b0; |
else if (i==10) |
a10_fix[i] = 1'b0; |
else |
if (i<`COL_SIZE) |
a10_fix[i] = a[i-1]; |
else |
a10_fix[i] = 1'b0; |
end |
end |
endfunction |
|
|
assign {bank,row,col} = adr_i; |
|
always @ (posedge clk or posedge rst) begin |
if (rst) |
state <= `FSM_INIT; |
else |
state <= next; end |
|
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 (cyc_i & stb_i) next = `FSM_ADR; |
else next = `FSM_IDLE; |
`FSM_RFR: |
if (shreg[5]) next = `FSM_IDLE; |
else next = `FSM_RFR; |
`FSM_ADR: |
if (current_bank_closed) next = `FSM_ACT; |
else if (current_row_open) |
next = `FSM_RW; |
else next = `FSM_PCH; |
`FSM_PCH: |
if (shreg[1]) next = `FSM_ACT; |
else next = `FSM_PCH; |
`FSM_ACT: |
if (shreg[2]) next = `FSM_RW; |
else next = `FSM_ACT; |
// `FSM_W4D: |
// if (!fifo_empty) next = `FSM_RW; |
// else next = `FSM_W4D; |
`FSM_RW: |
if (bte_i==linear & shreg[1]) |
next = `FSM_IDLE; |
else if (bte_i==beat4 & shreg[7]) |
next = `FSM_IDLE; |
`ifdef BEAT8 |
else if (bte_i==beat8 & shreg[15]) |
next = `FSM_IDLE; |
`endif |
`ifdef BEAT16 |
else if (bte_i==beat16 & shreg[31]) |
next = `FSM_IDLE; |
`endif |
else |
next = `FSM_RW; |
endcase |
end |
|
// active if write burst need data |
assign stall = state==`FSM_RW & next==`FSM_RW & ~stb_i & count0 & we_i; |
|
// flag indicates active wb cycle |
always @ (posedge clk or posedge rst) |
if (rst) |
wb_flag <= 1'b0; |
else |
if (state==`FSM_ADR) |
wb_flag <= 1'b1; |
else if ((cti_i==3'b000 | cti_i==3'b111) & ack_o) |
wb_flag <= 1'b0; |
|
// counter |
always @ (posedge clk or posedge rst) |
if (rst) |
{shreg,count0} <= {32'h80000000,1'b0}; |
else |
if (!stall) |
if (state==next) |
{shreg,count0} <= {shreg >> 1,!count0}; |
else |
{shreg,count0} <= {32'h80000000,1'b0}; |
// else if (state!=next) |
// {shreg,count0} <= {1'b1,{31{1'b0}},1'b0}; |
// else if (~stall) |
// {shreg,count0} <= {shreg >> 1,!count0}; |
|
// ba, a, cmd |
// col_reg_a10 has bit [10] set to zero to disable auto precharge |
assign col_a10_fix = a10_fix({col[`COL_SIZE-1:5],col_reg}); |
|
// outputs dependent on state vector |
always @ (posedge clk or posedge rst) |
begin |
if (rst) begin |
{ba,a,cmd} <= {2'b00,13'd0,cmd_nop}; |
dqm <= 2'b11; |
cmd_aref <= 1'b0; |
dq_oe <= 1'b0; |
col_reg <= 5'b000; |
{open_ba,open_row[0],open_row[1],open_row[2],open_row[3]} <= |
{4'b0000,{`ROW_SIZE*4{1'b0}}}; |
end else begin |
{ba,a,cmd} <= {2'b00,13'd0,cmd_nop}; |
dqm <= 2'b11; |
cmd_aref <= 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[bank] <= 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_IDLE: |
col_reg <= col[4:0]; |
`FSM_PCH: |
if (shreg[0]) begin |
{ba,a,cmd} <= {ba,13'd0,cmd_pch}; |
//open_ba <= 4'b0000; |
open_ba[bank] <= 1'b0; |
end |
`FSM_ACT: |
if (shreg[0]) begin |
{ba,a,cmd} <= {bank,(13'd0 | row),cmd_act}; |
{open_ba[bank],open_row[bank]} <= {1'b1,row}; |
end |
`FSM_RW: |
begin |
if (we_i & !count0) |
cmd <= cmd_wr; |
else if (!count0) |
{cmd,cmd_read} <= {cmd_rd,1'b1}; |
else |
cmd <= cmd_nop; |
if (we_i & !count0) |
dqm <= ~sel_i[3:2]; |
else if (we_i & count0) |
dqm <= ~sel_i[1:0]; |
else |
dqm <= 2'b00; |
if (we_i) |
dq_oe <= 1'b1; |
if (~stall) |
case (bte_i) |
linear: {ba,a} <= {bank,col_a10_fix}; |
beat4: {ba,a,col_reg[2:0]} <= {bank,col_a10_fix, col_reg[2:0] + 3'd1}; |
`ifdef BEAT8 |
beat8: {ba,a,col_reg[3:0]} <= {bank,col_a10_fix, col_reg[3:0] + 4'd1}; |
`endif |
`ifdef BEAT16 |
beat16: {ba,a,col_reg[4:0]} <= {bank,col_a10_fix, col_reg[4:0] + 5'd1}; |
`endif |
endcase |
end |
endcase |
end |
end |
|
// bank and row open ? |
always @ (posedge clk or posedge rst) |
if (rst) |
{current_bank_closed, current_row_open} <= {1'b1, 1'b0}; |
else |
//if (state==adr & counter[1:0]==2'b10) |
{current_bank_closed, current_row_open} <= |
{!(open_ba[bank]), open_row[bank]==row}; |
|
// refresch counter |
ref_counter |
# ( .length(rfr_length), .wrap_value (rfr_wrap_value)) |
ref_counter0( .zq(ref_cnt_zero), .rst(sdram_rst), .clk(sdram_clk)); |
always @ (posedge clk or posedge rst) |
if (rst) |
refresh_req <= 1'b0; |
else |
if (ref_cnt_zero) |
refresh_req <= 1'b1; |
else if (cmd_aref) |
refresh_req <= 1'b0; |
|
// data to WB |
always @ (posedge clk or posedge rst) |
if (rst) |
dat_o <= 32'h00000000; |
else |
dat_o <= {dat_o[15:0],dq_i}; |
|
assign ack_o = (state==`FSM_RW & count0); |
|
// output dq_o mux and dffs |
always @ (posedge clk or posedge rst) |
if (rst) |
dq_o <= 16'h0000; |
else if (~count0) |
dq_o <= dat_i[31:16]; |
else |
dq_o <= dat_i[15:0]; |
|
endmodule |