OpenCores
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
    from Rev 33 to Rev 34
    Reverse comparison

Rev 33 → Rev 34

/verilog/codec.v
0,0 → 1,124
`timescale 1ns/1ns
module encode (
fifo_empty_0, fifo_empty_1, fifo_empty_2, fifo_empty_3,
fifo_sel, fifo_sel_domain
);
 
input [0:15] fifo_empty_0, fifo_empty_1, fifo_empty_2, fifo_empty_3;
output [0:15] fifo_sel;
output [1:0] fifo_sel_domain;
 
function [0:15] encode;
input [0:15] a;
input [0:15] b;
input [0:15] c;
input [0:15] d;
integer i;
begin
if (!(&d))
casex (d)
16'b0xxxxxxxxxxxxxxx: encode = 16'b1000000000000000;
16'b10xxxxxxxxxxxxxx: encode = 16'b0100000000000000;
16'b110xxxxxxxxxxxxx: encode = 16'b0010000000000000;
16'b1110xxxxxxxxxxxx: encode = 16'b0001000000000000;
16'b11110xxxxxxxxxxx: encode = 16'b0000100000000000;
16'b111110xxxxxxxxxx: encode = 16'b0000010000000000;
16'b1111110xxxxxxxxx: encode = 16'b0000001000000000;
16'b11111110xxxxxxxx: encode = 16'b0000000100000000;
16'b111111110xxxxxxx: encode = 16'b0000000010000000;
16'b1111111110xxxxxx: encode = 16'b0000000001000000;
16'b11111111110xxxxx: encode = 16'b0000000000100000;
16'b111111111110xxxx: encode = 16'b0000000000010000;
16'b1111111111110xxx: encode = 16'b0000000000001000;
16'b11111111111110xx: encode = 16'b0000000000000100;
16'b111111111111110x: encode = 16'b0000000000000010;
16'b1111111111111110: encode = 16'b0000000000000001;
default: encode = 16'b0000000000000000;
endcase
else if (!(&c))
casex (c)
16'b0xxxxxxxxxxxxxxx: encode = 16'b1000000000000000;
16'b10xxxxxxxxxxxxxx: encode = 16'b0100000000000000;
16'b110xxxxxxxxxxxxx: encode = 16'b0010000000000000;
16'b1110xxxxxxxxxxxx: encode = 16'b0001000000000000;
16'b11110xxxxxxxxxxx: encode = 16'b0000100000000000;
16'b111110xxxxxxxxxx: encode = 16'b0000010000000000;
16'b1111110xxxxxxxxx: encode = 16'b0000001000000000;
16'b11111110xxxxxxxx: encode = 16'b0000000100000000;
16'b111111110xxxxxxx: encode = 16'b0000000010000000;
16'b1111111110xxxxxx: encode = 16'b0000000001000000;
16'b11111111110xxxxx: encode = 16'b0000000000100000;
16'b111111111110xxxx: encode = 16'b0000000000010000;
16'b1111111111110xxx: encode = 16'b0000000000001000;
16'b11111111111110xx: encode = 16'b0000000000000100;
16'b111111111111110x: encode = 16'b0000000000000010;
16'b1111111111111110: encode = 16'b0000000000000001;
default: encode = 16'b0000000000000000;
endcase
else if (!(&b))
casex (b)
16'b0xxxxxxxxxxxxxxx: encode = 16'b1000000000000000;
16'b10xxxxxxxxxxxxxx: encode = 16'b0100000000000000;
16'b110xxxxxxxxxxxxx: encode = 16'b0010000000000000;
16'b1110xxxxxxxxxxxx: encode = 16'b0001000000000000;
16'b11110xxxxxxxxxxx: encode = 16'b0000100000000000;
16'b111110xxxxxxxxxx: encode = 16'b0000010000000000;
16'b1111110xxxxxxxxx: encode = 16'b0000001000000000;
16'b11111110xxxxxxxx: encode = 16'b0000000100000000;
16'b111111110xxxxxxx: encode = 16'b0000000010000000;
16'b1111111110xxxxxx: encode = 16'b0000000001000000;
16'b11111111110xxxxx: encode = 16'b0000000000100000;
16'b111111111110xxxx: encode = 16'b0000000000010000;
16'b1111111111110xxx: encode = 16'b0000000000001000;
16'b11111111111110xx: encode = 16'b0000000000000100;
16'b111111111111110x: encode = 16'b0000000000000010;
16'b1111111111111110: encode = 16'b0000000000000001;
default: encode = 16'b0000000000000000;
endcase
else
casex (a)
16'b0xxxxxxxxxxxxxxx: encode = 16'b1000000000000000;
16'b10xxxxxxxxxxxxxx: encode = 16'b0100000000000000;
16'b110xxxxxxxxxxxxx: encode = 16'b0010000000000000;
16'b1110xxxxxxxxxxxx: encode = 16'b0001000000000000;
16'b11110xxxxxxxxxxx: encode = 16'b0000100000000000;
16'b111110xxxxxxxxxx: encode = 16'b0000010000000000;
16'b1111110xxxxxxxxx: encode = 16'b0000001000000000;
16'b11111110xxxxxxxx: encode = 16'b0000000100000000;
16'b111111110xxxxxxx: encode = 16'b0000000010000000;
16'b1111111110xxxxxx: encode = 16'b0000000001000000;
16'b11111111110xxxxx: encode = 16'b0000000000100000;
16'b111111111110xxxx: encode = 16'b0000000000010000;
16'b1111111111110xxx: encode = 16'b0000000000001000;
16'b11111111111110xx: encode = 16'b0000000000000100;
16'b111111111111110x: encode = 16'b0000000000000010;
16'b1111111111111110: encode = 16'b0000000000000001;
default: encode = 16'b0000000000000000;
endcase
end
endfunction
 
assign fifo_sel = encode( fifo_empty_0, fifo_empty_1, fifo_empty_2, fifo_empty_3);
assign fifo_sel_domain = (!(&fifo_empty_3)) ? 2'b11 :
(!(&fifo_empty_2)) ? 2'b10 :
(!(&fifo_empty_1)) ? 2'b01 :
2'b00;
endmodule
 
`timescale 1ns/1ns
module decode (
fifo_sel, fifo_sel_domain,
fifo_we_0, fifo_we_1, fifo_we_2, fifo_we_3
);
 
input [0:15] fifo_sel;
input [1:0] fifo_sel_domain;
output [0:15] fifo_we_0, fifo_we_1, fifo_we_2, fifo_we_3;
 
assign fifo_we_0 = (fifo_sel_domain == 2'b00) ? fifo_sel : {16{1'b0}};
assign fifo_we_1 = (fifo_sel_domain == 2'b01) ? fifo_sel : {16{1'b0}};
assign fifo_we_2 = (fifo_sel_domain == 2'b10) ? fifo_sel : {16{1'b0}};
assign fifo_we_3 = (fifo_sel_domain == 2'b11) ? fifo_sel : {16{1'b0}};
 
endmodule
/verilog/fsm_sdr_16.v
0,0 → 1,255
`timescale 1ns/1ns
module fsm_sdr_16 (
adr_i, we_i, bte_i,
fifo_sel_i, fifo_sel_domain_i,
fifo_sel_reg, fifo_sel_domain_reg,
fifo_empty, fifo_rd, count0,
refresh_req, cmd_aref, cmd_read,
ba, a, cmd, dq_oe,
sdram_clk, sdram_rst
);
 
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 [0:15] fifo_sel_i;
input [1:0] fifo_sel_domain_i;
output [0:15] fifo_sel_reg;
output [1:0] fifo_sel_domain_reg;
 
input fifo_empty;
output fifo_rd;
output count0;
 
input refresh_req;
output reg cmd_aref; // used for rerfresh ack
output reg cmd_read; // used for ingress fifo control
 
output reg [1:0] ba;
output reg [12:0] a;
output reg [2:0] cmd;
output reg dq_oe;
 
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 [4:0] counter;
 
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;
 
// to keep track of open rows per bank
reg [row_size-1:0] open_row[3:0];
reg [3:0] open_ba;
 
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
parameter [2:0] init = 3'b000,
idle = 3'b001,
rfr = 3'b010,
adr = 3'b011,
pch = 3'b100,
act = 3'b101,
nop = 3'b110,
rw = 3'b111;
reg [2:0] state, next;
 
function [3: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 sdram_clk or sdram_rst)
if (sdram_rst)
{ba_reg,row_reg,col_reg,we_reg,bte_reg} <= {2'b00,{row_size{1'b0}},{col_size{1'b0}}};
else
if (state==adr & !counter[0])
{ba_reg,row_reg,col_reg,we_reg,bte_reg} <= {bank,row,col,we_i,bte_i};
always @ (posedge sdram_clk or sdram_rst)
if (sdram_rst)
state <= init;
else
state <= next;
always @*
begin
next = 3'bx;
case (state)
init: if (counter==5'd31) next = idle;
else next = init;
idle: if (refresh_req) next = rfr;
else if (|fifo_sel_i) next = adr;
else next = idle;
rfr: if (counter==5'd5) next = idle;
else next = rfr;
adr: if (open_ba[ba_reg] & (open_row[ba_reg]==row_reg) & counter[0]) next = rw;
else if (!open_ba[ba_reg]& counter[0]) next = act;
else if (counter[0]) next = pch;
else next = adr;
pch: if (counter[0]) next = act;
else next = pch;
act: if (counter==5'd2) next = rw;
else next = act;
// nop: next = rw;
rw: case ({bte_reg,counter})
{linear,5'd1},{beat4,5'd7},{beat8,5'd15},{beat16,5'd31}: next = idle;
default: next = rw;
endcase
endcase
end
 
// counter
always @ (posedge sdram_clk or posedge sdram_rst)
begin
if (sdram_rst)
counter <= 5'd0;
else
if (state!=next)
counter <= 5'd0;
else
if (~(state==rw & fifo_empty & ~counter[0] & we_reg))
counter <= counter + 5'd1;
end
 
always @ (posedge sdram_clk or posedge sdram_rst)
begin
if (sdram_rst)
{fifo_sel_reg_int,fifo_sel_domain_reg_int} <= {16'h0,2'b00};
else
if (state==idle)
{fifo_sel_reg_int,fifo_sel_domain_reg_int} <= {fifo_sel_i,fifo_sel_domain_i};
end
 
assign {fifo_sel_reg,fifo_sel_domain_reg} = (state==idle) ? {fifo_sel_i,fifo_sel_domain_i} : {fifo_sel_reg_int,fifo_sel_domain_reg_int};
 
// 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);
 
always @ (posedge sdram_clk or posedge sdram_rst)
begin
if (sdram_rst)
{ba,a,cmd,cmd_aref,cmd_read} = {2'b00,13'd0,cmd_nop,1'b0,1'b0};
else begin
{ba,a,cmd,cmd_aref,cmd_read} = {2'b00,13'd0,cmd_nop,1'b0,1'b0};
casex ({state,counter})
{init,5'd3}, {rfr,5'd0}:
{ba,a,cmd} = {2'b00, 13'b0010000000000, cmd_pch};
{init,5'd7}, {init,5'd19}, {rfr,5'd2}:
{ba,a,cmd,cmd_aref} = {2'b00, 13'd0, cmd_rfr,1'b1};
{init,5'd31}:
{ba,a,cmd} = {2'b00,3'b000,init_wb,2'b00,init_cl,init_bt,init_bl, cmd_lmr};
{pch,5'bxxxx0}:
{ba,a,cmd} = {ba_reg,13'd0,cmd_pch};
{act,5'd0}:
{ba,a,cmd} = {ba_reg,(13'd0 | row_reg),cmd_act};
{rw,5'bxxxxx}:
begin
/*if (!counter[0] & !fifo_empty)
{cmd,cmd_read} = {{2'b10,!we_reg},~we_reg};
else
cmd = cmd_nop;*/
casex ({we_reg,counter[0],fifo_empty})
{1'b0,1'b0,1'bx}: {cmd,cmd_read} = {cmd_rd,1'b1};
{1'b1,1'b0,1'b0}: cmd = cmd_wr;
endcase
case (bte_reg)
linear: {ba,a} = {ba_reg,col_reg_a10_fix};
beat4: {ba,a} = {ba_reg,col_reg_a10_fix[12:2],col_reg_a10_fix[2:0] + counter[2:0]};
beat8: {ba,a} = {ba_reg,col_reg_a10_fix[12:3],col_reg_a10_fix[3:0] + counter[3:0]};
beat16: {ba,a} = {ba_reg,col_reg_a10_fix[12:4],col_reg_a10_fix[4:0] + counter[4:0]};
endcase
end
endcase
end
end
 
// rd_adr goes high when next adr is fetched from sync RAM and during write burst
assign fifo_rd = ((state==idle) & (next==adr)) ? 1'b1 :
((state==rw) & we_reg & !counter[0] & !fifo_empty) ? 1'b1 :
1'b0;
 
assign count0 = counter[0];
 
//assign dq_oe = (state==rw);
always @ (posedge sdram_clk or posedge sdram_rst)
if (sdram_rst)
dq_oe <= 1'b0;
else
dq_oe <= ((state==rw & we_reg & ~counter[0] & !fifo_empty) | (state==rw & we_reg & counter[0]));
always @ (posedge sdram_clk or posedge sdram_rst)
if (sdram_rst)
{open_ba,open_row[0],open_row[1],open_row[2],open_row[3]} <= {4'b0000,{row_size*4{1'b0}}};
else
casex ({ba,a[10],cmd})
{2'bxx,1'b1,cmd_pch}: open_ba <= 4'b0000;
{2'b00,1'b0,cmd_pch}: open_ba[0] <= 1'b0;
{2'b01,1'b0,cmd_pch}: open_ba[1] <= 1'b0;
{2'b10,1'b0,cmd_pch}: open_ba[2] <= 1'b0;
{2'b11,1'b0,cmd_pch}: open_ba[3] <= 1'b0;
{2'b00,1'bx,cmd_act}: {open_ba[0],open_row[0]} <= {1'b1,row_reg};
{2'b01,1'bx,cmd_act}: {open_ba[1],open_row[1]} <= {1'b1,row_reg};
{2'b10,1'bx,cmd_act}: {open_ba[2],open_row[2]} <= {1'b1,row_reg};
{2'b11,1'bx,cmd_act}: {open_ba[3],open_row[3]} <= {1'b1,row_reg};
endcase
 
endmodule

powered by: WebSVN 2.1.0

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