//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
//// ////
|
//// ////
|
//// Versatile memory controller ////
|
//// Versatile memory controller ////
|
//// ////
|
//// ////
|
//// Description ////
|
//// Description ////
|
//// A modular wishbone compatible memory controller with support////
|
//// A modular wishbone compatible memory controller with support////
|
//// for various types of memory configurations ////
|
//// for various types of memory configurations ////
|
//// ////
|
//// ////
|
//// To Do: ////
|
//// To Do: ////
|
//// - add support for additional SDRAM variants ////
|
//// - add support for additional SDRAM variants ////
|
//// ////
|
//// ////
|
//// Author(s): ////
|
//// Author(s): ////
|
//// - Michael Unneback, unneback@opencores.org ////
|
//// - Michael Unneback, unneback@opencores.org ////
|
//// ORSoC AB ////
|
//// ORSoC AB ////
|
//// ////
|
//// ////
|
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
//// ////
|
//// ////
|
//// Copyright (C) 2009 Authors and OPENCORES.ORG ////
|
//// Copyright (C) 2009 Authors and OPENCORES.ORG ////
|
//// ////
|
//// ////
|
//// This source file may be used and distributed without ////
|
//// This source file may be used and distributed without ////
|
//// restriction provided that this copyright statement is not ////
|
//// restriction provided that this copyright statement is not ////
|
//// removed from the file and that any derivative work contains ////
|
//// removed from the file and that any derivative work contains ////
|
//// the original copyright notice and the associated disclaimer. ////
|
//// the original copyright notice and the associated disclaimer. ////
|
//// ////
|
//// ////
|
//// This source file is free software; you can redistribute it ////
|
//// This source file is free software; you can redistribute it ////
|
//// and/or modify it under the terms of the GNU Lesser General ////
|
//// and/or modify it under the terms of the GNU Lesser General ////
|
//// Public License as published by the Free Software Foundation; ////
|
//// Public License as published by the Free Software Foundation; ////
|
//// either version 2.1 of the License, or (at your option) any ////
|
//// either version 2.1 of the License, or (at your option) any ////
|
//// later version. ////
|
//// later version. ////
|
//// ////
|
//// ////
|
//// This source is distributed in the hope that it will be ////
|
//// This source is distributed in the hope that it will be ////
|
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
//// details. ////
|
//// details. ////
|
//// ////
|
//// ////
|
//// You should have received a copy of the GNU Lesser General ////
|
//// You should have received a copy of the GNU Lesser General ////
|
//// Public License along with this source; if not, download it ////
|
//// Public License along with this source; if not, download it ////
|
//// from http://www.opencores.org/lgpl.shtml ////
|
//// from http://www.opencores.org/lgpl.shtml ////
|
//// ////
|
//// ////
|
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
//// ////
|
//// ////
|
//// Versatile counter ////
|
//// Versatile counter ////
|
//// ////
|
//// ////
|
//// Description ////
|
//// Description ////
|
//// Versatile counter, a reconfigurable binary, gray or LFSR ////
|
//// Versatile counter, a reconfigurable binary, gray or LFSR ////
|
//// counter ////
|
//// counter ////
|
//// ////
|
//// ////
|
//// To Do: ////
|
//// To Do: ////
|
//// - add LFSR with more taps ////
|
//// - add LFSR with more taps ////
|
//// ////
|
//// ////
|
//// Author(s): ////
|
//// Author(s): ////
|
//// - Michael Unneback, unneback@opencores.org ////
|
//// - Michael Unneback, unneback@opencores.org ////
|
//// ORSoC AB ////
|
//// ORSoC AB ////
|
//// ////
|
//// ////
|
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
//// ////
|
//// ////
|
//// Copyright (C) 2009 Authors and OPENCORES.ORG ////
|
//// Copyright (C) 2009 Authors and OPENCORES.ORG ////
|
//// ////
|
//// ////
|
//// This source file may be used and distributed without ////
|
//// This source file may be used and distributed without ////
|
//// restriction provided that this copyright statement is not ////
|
//// restriction provided that this copyright statement is not ////
|
//// removed from the file and that any derivative work contains ////
|
//// removed from the file and that any derivative work contains ////
|
//// the original copyright notice and the associated disclaimer. ////
|
//// the original copyright notice and the associated disclaimer. ////
|
//// ////
|
//// ////
|
//// This source file is free software; you can redistribute it ////
|
//// This source file is free software; you can redistribute it ////
|
//// and/or modify it under the terms of the GNU Lesser General ////
|
//// and/or modify it under the terms of the GNU Lesser General ////
|
//// Public License as published by the Free Software Foundation; ////
|
//// Public License as published by the Free Software Foundation; ////
|
//// either version 2.1 of the License, or (at your option) any ////
|
//// either version 2.1 of the License, or (at your option) any ////
|
//// later version. ////
|
//// later version. ////
|
//// ////
|
//// ////
|
//// This source is distributed in the hope that it will be ////
|
//// This source is distributed in the hope that it will be ////
|
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
//// details. ////
|
//// details. ////
|
//// ////
|
//// ////
|
//// You should have received a copy of the GNU Lesser General ////
|
//// You should have received a copy of the GNU Lesser General ////
|
//// Public License along with this source; if not, download it ////
|
//// Public License along with this source; if not, download it ////
|
//// from http://www.opencores.org/lgpl.shtml ////
|
//// from http://www.opencores.org/lgpl.shtml ////
|
//// ////
|
//// ////
|
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
|
|
module versatile_fifo_async_cmp ( wptr, rptr, fifo_empty, fifo_full, wclk, rclk, rst );
|
module versatile_fifo_async_cmp ( wptr, rptr, fifo_empty, fifo_full, wclk, rclk, rst );
|
|
|
parameter ADDR_WIDTH = 4;
|
parameter ADDR_WIDTH = 4;
|
parameter N = ADDR_WIDTH-1;
|
parameter N = ADDR_WIDTH-1;
|
|
|
parameter Q1 = 2'b00;
|
parameter Q1 = 2'b00;
|
parameter Q2 = 2'b01;
|
parameter Q2 = 2'b01;
|
parameter Q3 = 2'b11;
|
parameter Q3 = 2'b11;
|
parameter Q4 = 2'b10;
|
parameter Q4 = 2'b10;
|
|
|
parameter going_empty = 1'b0;
|
parameter going_empty = 1'b0;
|
parameter going_full = 1'b1;
|
parameter going_full = 1'b1;
|
|
|
input [N:0] wptr, rptr;
|
input [N:0] wptr, rptr;
|
output reg fifo_empty;
|
output reg fifo_empty;
|
output fifo_full;
|
output fifo_full;
|
input wclk, rclk, rst;
|
input wclk, rclk, rst;
|
|
|
|
`ifndef GENERATE_DIRECTION_AS_LATCH
|
wire direction;
|
wire direction;
|
|
`endif
|
|
`ifdef GENERATE_DIRECTION_AS_LATCH
|
|
reg direction;
|
|
`endif
|
reg direction_set, direction_clr;
|
reg direction_set, direction_clr;
|
|
|
wire async_empty, async_full;
|
wire async_empty, async_full;
|
wire fifo_full2;
|
wire fifo_full2;
|
reg fifo_empty2;
|
reg fifo_empty2;
|
|
|
// direction_set
|
// direction_set
|
always @ (wptr[N:N-1] or rptr[N:N-1])
|
always @ (wptr[N:N-1] or rptr[N:N-1])
|
case ({wptr[N:N-1],rptr[N:N-1]})
|
case ({wptr[N:N-1],rptr[N:N-1]})
|
{Q1,Q2} : direction_set <= 1'b1;
|
{Q1,Q2} : direction_set <= 1'b1;
|
{Q2,Q3} : direction_set <= 1'b1;
|
{Q2,Q3} : direction_set <= 1'b1;
|
{Q3,Q4} : direction_set <= 1'b1;
|
{Q3,Q4} : direction_set <= 1'b1;
|
{Q4,Q1} : direction_set <= 1'b1;
|
{Q4,Q1} : direction_set <= 1'b1;
|
default : direction_set <= 1'b0;
|
default : direction_set <= 1'b0;
|
endcase
|
endcase
|
|
|
// direction_clear
|
// direction_clear
|
always @ (wptr[N:N-1] or rptr[N:N-1] or rst)
|
always @ (wptr[N:N-1] or rptr[N:N-1] or rst)
|
if (rst)
|
if (rst)
|
direction_clr <= 1'b1;
|
direction_clr <= 1'b1;
|
else
|
else
|
case ({wptr[N:N-1],rptr[N:N-1]})
|
case ({wptr[N:N-1],rptr[N:N-1]})
|
{Q2,Q1} : direction_clr <= 1'b1;
|
{Q2,Q1} : direction_clr <= 1'b1;
|
{Q3,Q2} : direction_clr <= 1'b1;
|
{Q3,Q2} : direction_clr <= 1'b1;
|
{Q4,Q3} : direction_clr <= 1'b1;
|
{Q4,Q3} : direction_clr <= 1'b1;
|
{Q1,Q4} : direction_clr <= 1'b1;
|
{Q1,Q4} : direction_clr <= 1'b1;
|
default : direction_clr <= 1'b0;
|
default : direction_clr <= 1'b0;
|
endcase
|
endcase
|
|
|
`ifndef GENERATE_DIRECTION_AS_LATCH
|
`ifndef GENERATE_DIRECTION_AS_LATCH
|
dff_sr dff_sr_dir( .aclr(direction_clr), .aset(direction_set), .clock(1'b1), .data(1'b1), .q(direction));
|
dff_sr dff_sr_dir( .aclr(direction_clr), .aset(direction_set), .clock(1'b1), .data(1'b1), .q(direction));
|
`endif
|
`endif
|
|
|
`ifdef GENERATE_DIRECTION_AS_LATCH
|
`ifdef GENERATE_DIRECTION_AS_LATCH
|
always @ (posedge direction_set or posedge direction_clr)
|
always @ (posedge direction_set or posedge direction_clr)
|
if (direction_clr)
|
if (direction_clr)
|
direction <= going_empty;
|
direction <= going_empty;
|
else
|
else
|
direction <= going_full;
|
direction <= going_full;
|
`endif
|
`endif
|
|
|
assign async_empty = (wptr == rptr) && (direction==going_empty);
|
assign async_empty = (wptr == rptr) && (direction==going_empty);
|
assign async_full = (wptr == rptr) && (direction==going_full);
|
assign async_full = (wptr == rptr) && (direction==going_full);
|
|
|
dff_sr dff_sr_empty0( .aclr(rst), .aset(async_full), .clock(wclk), .data(async_full), .q(fifo_full2));
|
dff_sr dff_sr_empty0( .aclr(rst), .aset(async_full), .clock(wclk), .data(async_full), .q(fifo_full2));
|
dff_sr dff_sr_empty1( .aclr(rst), .aset(async_full), .clock(wclk), .data(fifo_full2), .q(fifo_full));
|
dff_sr dff_sr_empty1( .aclr(rst), .aset(async_full), .clock(wclk), .data(fifo_full2), .q(fifo_full));
|
|
|
/*
|
/*
|
always @ (posedge wclk or posedge rst or posedge async_full)
|
always @ (posedge wclk or posedge rst or posedge async_full)
|
if (rst)
|
if (rst)
|
{fifo_full, fifo_full2} <= 2'b00;
|
{fifo_full, fifo_full2} <= 2'b00;
|
else if (async_full)
|
else if (async_full)
|
{fifo_full, fifo_full2} <= 2'b11;
|
{fifo_full, fifo_full2} <= 2'b11;
|
else
|
else
|
{fifo_full, fifo_full2} <= {fifo_full2, async_full};
|
{fifo_full, fifo_full2} <= {fifo_full2, async_full};
|
*/
|
*/
|
always @ (posedge rclk or posedge async_empty)
|
always @ (posedge rclk or posedge async_empty)
|
if (async_empty)
|
if (async_empty)
|
{fifo_empty, fifo_empty2} <= 2'b11;
|
{fifo_empty, fifo_empty2} <= 2'b11;
|
else
|
else
|
{fifo_empty,fifo_empty2} <= {fifo_empty2,async_empty};
|
{fifo_empty,fifo_empty2} <= {fifo_empty2,async_empty};
|
|
|
endmodule // async_comp
|
endmodule // async_comp
|
// async FIFO with multiple queues
|
// async FIFO with multiple queues
|
|
|
module async_fifo_mq (
|
module async_fifo_mq (
|
d, fifo_full, write, write_enable, clk1, rst1,
|
d, fifo_full, write, write_enable, clk1, rst1,
|
q, fifo_empty, read, read_enable, clk2, rst2
|
q, fifo_empty, read, read_enable, clk2, rst2
|
);
|
);
|
|
|
parameter a_hi_size = 4;
|
parameter a_hi_size = 4;
|
parameter a_lo_size = 4;
|
parameter a_lo_size = 4;
|
parameter nr_of_queues = 16;
|
parameter nr_of_queues = 16;
|
parameter data_width = 36;
|
parameter data_width = 36;
|
|
|
input [data_width-1:0] d;
|
input [data_width-1:0] d;
|
output [0:nr_of_queues-1] fifo_full;
|
output [0:nr_of_queues-1] fifo_full;
|
input write;
|
input write;
|
input [0:nr_of_queues-1] write_enable;
|
input [0:nr_of_queues-1] write_enable;
|
input clk1;
|
input clk1;
|
input rst1;
|
input rst1;
|
|
|
output [data_width-1:0] q;
|
output [data_width-1:0] q;
|
output [0:nr_of_queues-1] fifo_empty;
|
output [0:nr_of_queues-1] fifo_empty;
|
input read;
|
input read;
|
input [0:nr_of_queues-1] read_enable;
|
input [0:nr_of_queues-1] read_enable;
|
input clk2;
|
input clk2;
|
input rst2;
|
input rst2;
|
|
|
wire [a_lo_size-1:0] fifo_wadr_bin[0:nr_of_queues-1];
|
wire [a_lo_size-1:0] fifo_wadr_bin[0:nr_of_queues-1];
|
wire [a_lo_size-1:0] fifo_wadr_gray[0:nr_of_queues-1];
|
wire [a_lo_size-1:0] fifo_wadr_gray[0:nr_of_queues-1];
|
wire [a_lo_size-1:0] fifo_radr_bin[0:nr_of_queues-1];
|
wire [a_lo_size-1:0] fifo_radr_bin[0:nr_of_queues-1];
|
wire [a_lo_size-1:0] fifo_radr_gray[0:nr_of_queues-1];
|
wire [a_lo_size-1:0] fifo_radr_gray[0:nr_of_queues-1];
|
reg [a_lo_size-1:0] wadr;
|
reg [a_lo_size-1:0] wadr;
|
reg [a_lo_size-1:0] radr;
|
reg [a_lo_size-1:0] radr;
|
reg [data_width-1:0] wdata;
|
reg [data_width-1:0] wdata;
|
wire [data_width-1:0] wdataa[0:nr_of_queues-1];
|
wire [data_width-1:0] wdataa[0:nr_of_queues-1];
|
|
|
genvar i;
|
genvar i;
|
integer j,k,l;
|
integer j,k,l;
|
|
|
function [a_lo_size-1:0] onehot2bin;
|
function [a_lo_size-1:0] onehot2bin;
|
input [0:nr_of_queues-1] a;
|
input [0:nr_of_queues-1] a;
|
integer i;
|
integer i;
|
begin
|
begin
|
onehot2bin = {a_lo_size{1'b0}};
|
onehot2bin = {a_lo_size{1'b0}};
|
for (i=1;i<nr_of_queues;i=i+1) begin
|
for (i=1;i<nr_of_queues;i=i+1) begin
|
if (a[i])
|
if (a[i])
|
onehot2bin = i;
|
onehot2bin = i;
|
end
|
end
|
end
|
end
|
endfunction
|
endfunction
|
|
|
generate
|
generate
|
for (i=0;i<nr_of_queues;i=i+1) begin : fifo_adr
|
for (i=0;i<nr_of_queues;i=i+1) begin : fifo_adr
|
|
|
gray_counter wadrcnt (
|
gray_counter wadrcnt (
|
.cke(write & write_enable[i]),
|
.cke(write & write_enable[i]),
|
.q(fifo_wadr_gray[i]),
|
.q(fifo_wadr_gray[i]),
|
.q_bin(fifo_wadr_bin[i]),
|
.q_bin(fifo_wadr_bin[i]),
|
.rst(rst1),
|
.rst(rst1),
|
.clk(clk1));
|
.clk(clk1));
|
|
|
gray_counter radrcnt (
|
gray_counter radrcnt (
|
.cke(read & read_enable[i]),
|
.cke(read & read_enable[i]),
|
.q(fifo_radr_gray[i]),
|
.q(fifo_radr_gray[i]),
|
.q_bin(fifo_radr_bin[i]),
|
.q_bin(fifo_radr_bin[i]),
|
.rst(rst2),
|
.rst(rst2),
|
.clk(clk2));
|
.clk(clk2));
|
|
|
versatile_fifo_async_cmp
|
versatile_fifo_async_cmp
|
#(.ADDR_WIDTH(a_lo_size))
|
#(.ADDR_WIDTH(a_lo_size))
|
egresscmp (
|
egresscmp (
|
.wptr(fifo_wadr_gray[i]),
|
.wptr(fifo_wadr_gray[i]),
|
.rptr(fifo_radr_gray[i]),
|
.rptr(fifo_radr_gray[i]),
|
.fifo_empty(fifo_empty[i]),
|
.fifo_empty(fifo_empty[i]),
|
.fifo_full(fifo_full[i]),
|
.fifo_full(fifo_full[i]),
|
.wclk(clk1),
|
.wclk(clk1),
|
.rclk(clk2),
|
.rclk(clk2),
|
.rst(rst1));
|
.rst(rst1));
|
|
|
end
|
end
|
endgenerate
|
endgenerate
|
|
|
// and-or mux write address
|
// and-or mux write address
|
always @*
|
always @*
|
begin
|
begin
|
wadr = {a_lo_size{1'b0}};
|
wadr = {a_lo_size{1'b0}};
|
for (j=0;j<nr_of_queues;j=j+1) begin
|
for (j=0;j<nr_of_queues;j=j+1) begin
|
wadr = (fifo_wadr_bin[j] & {a_lo_size{write_enable[j]}}) | wadr;
|
wadr = (fifo_wadr_bin[j] & {a_lo_size{write_enable[j]}}) | wadr;
|
end
|
end
|
end
|
end
|
|
|
// and-or mux read address
|
// and-or mux read address
|
always @*
|
always @*
|
begin
|
begin
|
radr = {a_lo_size{1'b0}};
|
radr = {a_lo_size{1'b0}};
|
for (k=0;k<nr_of_queues;k=k+1) begin
|
for (k=0;k<nr_of_queues;k=k+1) begin
|
radr = (fifo_radr_bin[k] & {a_lo_size{read_enable[k]}}) | radr;
|
radr = (fifo_radr_bin[k] & {a_lo_size{read_enable[k]}}) | radr;
|
end
|
end
|
end
|
end
|
|
|
vfifo_dual_port_ram_dc_sw # ( .DATA_WIDTH(data_width), .ADDR_WIDTH(a_hi_size+a_lo_size))
|
vfifo_dual_port_ram_dc_sw # ( .DATA_WIDTH(data_width), .ADDR_WIDTH(a_hi_size+a_lo_size))
|
dpram (
|
dpram (
|
.d_a(d),
|
.d_a(d),
|
.adr_a({onehot2bin(write_enable),wadr}),
|
.adr_a({onehot2bin(write_enable),wadr}),
|
.we_a(write),
|
.we_a(write),
|
.clk_a(clk1),
|
.clk_a(clk1),
|
.q_b(q),
|
.q_b(q),
|
.adr_b({onehot2bin(read_enable),radr}),
|
.adr_b({onehot2bin(read_enable),radr}),
|
.clk_b(clk2) );
|
.clk_b(clk2) );
|
|
|
endmodule
|
endmodule
|
module vfifo_dual_port_ram_dc_dw
|
module vfifo_dual_port_ram_dc_dw
|
(
|
(
|
d_a,
|
d_a,
|
q_a,
|
q_a,
|
adr_a,
|
adr_a,
|
we_a,
|
we_a,
|
clk_a,
|
clk_a,
|
q_b,
|
q_b,
|
adr_b,
|
adr_b,
|
d_b,
|
d_b,
|
we_b,
|
we_b,
|
clk_b
|
clk_b
|
);
|
);
|
parameter DATA_WIDTH = 32;
|
parameter DATA_WIDTH = 32;
|
parameter ADDR_WIDTH = 8;
|
parameter ADDR_WIDTH = 8;
|
input [(DATA_WIDTH-1):0] d_a;
|
input [(DATA_WIDTH-1):0] d_a;
|
input [(ADDR_WIDTH-1):0] adr_a;
|
input [(ADDR_WIDTH-1):0] adr_a;
|
input [(ADDR_WIDTH-1):0] adr_b;
|
input [(ADDR_WIDTH-1):0] adr_b;
|
input we_a;
|
input we_a;
|
output [(DATA_WIDTH-1):0] q_b;
|
output [(DATA_WIDTH-1):0] q_b;
|
input [(DATA_WIDTH-1):0] d_b;
|
input [(DATA_WIDTH-1):0] d_b;
|
output reg [(DATA_WIDTH-1):0] q_a;
|
output reg [(DATA_WIDTH-1):0] q_a;
|
input we_b;
|
input we_b;
|
input clk_a, clk_b;
|
input clk_a, clk_b;
|
reg [(DATA_WIDTH-1):0] q_b;
|
reg [(DATA_WIDTH-1):0] q_b;
|
reg [DATA_WIDTH-1:0] ram [(1<<ADDR_WIDTH)-1:0] `SYN;
|
reg [DATA_WIDTH-1:0] ram [(1<<ADDR_WIDTH)-1:0] /*synthesis syn_ramstyle = "no_rw_check"*/;
|
always @ (posedge clk_a)
|
always @ (posedge clk_a)
|
begin
|
begin
|
q_a <= ram[adr_a];
|
q_a <= ram[adr_a];
|
if (we_a)
|
if (we_a)
|
ram[adr_a] <= d_a;
|
ram[adr_a] <= d_a;
|
end
|
end
|
always @ (posedge clk_b)
|
always @ (posedge clk_b)
|
begin
|
begin
|
q_b <= ram[adr_b];
|
q_b <= ram[adr_b];
|
if (we_b)
|
if (we_b)
|
ram[adr_b] <= d_b;
|
ram[adr_b] <= d_b;
|
end
|
end
|
endmodule
|
endmodule
|
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
//// ////
|
//// ////
|
//// Versatile counter ////
|
//// Versatile counter ////
|
//// ////
|
//// ////
|
//// Description ////
|
//// Description ////
|
//// Versatile counter, a reconfigurable binary, gray or LFSR ////
|
//// Versatile counter, a reconfigurable binary, gray or LFSR ////
|
//// counter ////
|
//// counter ////
|
//// ////
|
//// ////
|
//// To Do: ////
|
//// To Do: ////
|
//// - add LFSR with more taps ////
|
//// - add LFSR with more taps ////
|
//// ////
|
//// ////
|
//// Author(s): ////
|
//// Author(s): ////
|
//// - Michael Unneback, unneback@opencores.org ////
|
//// - Michael Unneback, unneback@opencores.org ////
|
//// ORSoC AB ////
|
//// ORSoC AB ////
|
//// ////
|
//// ////
|
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
//// ////
|
//// ////
|
//// Copyright (C) 2009 Authors and OPENCORES.ORG ////
|
//// Copyright (C) 2009 Authors and OPENCORES.ORG ////
|
//// ////
|
//// ////
|
//// This source file may be used and distributed without ////
|
//// This source file may be used and distributed without ////
|
//// restriction provided that this copyright statement is not ////
|
//// restriction provided that this copyright statement is not ////
|
//// removed from the file and that any derivative work contains ////
|
//// removed from the file and that any derivative work contains ////
|
//// the original copyright notice and the associated disclaimer. ////
|
//// the original copyright notice and the associated disclaimer. ////
|
//// ////
|
//// ////
|
//// This source file is free software; you can redistribute it ////
|
//// This source file is free software; you can redistribute it ////
|
//// and/or modify it under the terms of the GNU Lesser General ////
|
//// and/or modify it under the terms of the GNU Lesser General ////
|
//// Public License as published by the Free Software Foundation; ////
|
//// Public License as published by the Free Software Foundation; ////
|
//// either version 2.1 of the License, or (at your option) any ////
|
//// either version 2.1 of the License, or (at your option) any ////
|
//// later version. ////
|
//// later version. ////
|
//// ////
|
//// ////
|
//// This source is distributed in the hope that it will be ////
|
//// This source is distributed in the hope that it will be ////
|
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
//// details. ////
|
//// details. ////
|
//// ////
|
//// ////
|
//// You should have received a copy of the GNU Lesser General ////
|
//// You should have received a copy of the GNU Lesser General ////
|
//// Public License along with this source; if not, download it ////
|
//// Public License along with this source; if not, download it ////
|
//// from http://www.opencores.org/lgpl.shtml ////
|
//// from http://www.opencores.org/lgpl.shtml ////
|
//// ////
|
//// ////
|
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
|
|
// LFSR counter
|
// LFSR counter
|
module ctrl_counter ( clear, cke, zq, rst, clk);
|
module ctrl_counter ( clear, cke, zq, rst, clk);
|
|
|
parameter length = 5;
|
parameter length = 5;
|
input clear;
|
input clear;
|
input cke;
|
input cke;
|
output reg zq;
|
output reg zq;
|
input rst;
|
input rst;
|
input clk;
|
input clk;
|
|
|
parameter clear_value = 0;
|
parameter clear_value = 0;
|
parameter set_value = 0;
|
parameter set_value = 0;
|
parameter wrap_value = 31;
|
parameter wrap_value = 31;
|
|
|
reg [length:1] qi;
|
reg [length:1] qi;
|
reg lfsr_fb;
|
reg lfsr_fb;
|
wire [length:1] q_next;
|
wire [length:1] q_next;
|
reg [32:1] polynom;
|
reg [32:1] polynom;
|
integer i;
|
integer i;
|
|
|
always @ (qi)
|
always @ (qi)
|
begin
|
begin
|
case (length)
|
case (length)
|
2: polynom = 32'b11; // 0x3
|
2: polynom = 32'b11; // 0x3
|
3: polynom = 32'b110; // 0x6
|
3: polynom = 32'b110; // 0x6
|
4: polynom = 32'b1100; // 0xC
|
4: polynom = 32'b1100; // 0xC
|
5: polynom = 32'b10100; // 0x14
|
5: polynom = 32'b10100; // 0x14
|
6: polynom = 32'b110000; // 0x30
|
6: polynom = 32'b110000; // 0x30
|
7: polynom = 32'b1100000; // 0x60
|
7: polynom = 32'b1100000; // 0x60
|
8: polynom = 32'b10111000; // 0xb8
|
8: polynom = 32'b10111000; // 0xb8
|
9: polynom = 32'b100010000; // 0x110
|
9: polynom = 32'b100010000; // 0x110
|
10: polynom = 32'b1001000000; // 0x240
|
10: polynom = 32'b1001000000; // 0x240
|
11: polynom = 32'b10100000000; // 0x500
|
11: polynom = 32'b10100000000; // 0x500
|
12: polynom = 32'b100000101001; // 0x829
|
12: polynom = 32'b100000101001; // 0x829
|
13: polynom = 32'b1000000001100; // 0x100C
|
13: polynom = 32'b1000000001100; // 0x100C
|
14: polynom = 32'b10000000010101; // 0x2015
|
14: polynom = 32'b10000000010101; // 0x2015
|
15: polynom = 32'b110000000000000; // 0x6000
|
15: polynom = 32'b110000000000000; // 0x6000
|
16: polynom = 32'b1101000000001000; // 0xD008
|
16: polynom = 32'b1101000000001000; // 0xD008
|
17: polynom = 32'b10010000000000000; // 0x12000
|
17: polynom = 32'b10010000000000000; // 0x12000
|
18: polynom = 32'b100000010000000000; // 0x20400
|
18: polynom = 32'b100000010000000000; // 0x20400
|
19: polynom = 32'b1000000000000100011; // 0x40023
|
19: polynom = 32'b1000000000000100011; // 0x40023
|
20: polynom = 32'b10000010000000000000; // 0x82000
|
20: polynom = 32'b10000010000000000000; // 0x82000
|
21: polynom = 32'b101000000000000000000; // 0x140000
|
21: polynom = 32'b101000000000000000000; // 0x140000
|
22: polynom = 32'b1100000000000000000000; // 0x300000
|
22: polynom = 32'b1100000000000000000000; // 0x300000
|
23: polynom = 32'b10000100000000000000000; // 0x420000
|
23: polynom = 32'b10000100000000000000000; // 0x420000
|
24: polynom = 32'b111000010000000000000000; // 0xE10000
|
24: polynom = 32'b111000010000000000000000; // 0xE10000
|
25: polynom = 32'b1001000000000000000000000; // 0x1200000
|
25: polynom = 32'b1001000000000000000000000; // 0x1200000
|
26: polynom = 32'b10000000000000000000100011; // 0x2000023
|
26: polynom = 32'b10000000000000000000100011; // 0x2000023
|
27: polynom = 32'b100000000000000000000010011; // 0x4000013
|
27: polynom = 32'b100000000000000000000010011; // 0x4000013
|
28: polynom = 32'b1100100000000000000000000000; // 0xC800000
|
28: polynom = 32'b1100100000000000000000000000; // 0xC800000
|
29: polynom = 32'b10100000000000000000000000000; // 0x14000000
|
29: polynom = 32'b10100000000000000000000000000; // 0x14000000
|
30: polynom = 32'b100000000000000000000000101001; // 0x20000029
|
30: polynom = 32'b100000000000000000000000101001; // 0x20000029
|
31: polynom = 32'b1001000000000000000000000000000; // 0x48000000
|
31: polynom = 32'b1001000000000000000000000000000; // 0x48000000
|
32: polynom = 32'b10000000001000000000000000000011; // 0x80200003
|
32: polynom = 32'b10000000001000000000000000000011; // 0x80200003
|
default: polynom = 32'b0;
|
default: polynom = 32'b0;
|
endcase
|
endcase
|
lfsr_fb = qi[length];
|
lfsr_fb = qi[length];
|
for (i=length-1; i>=1; i=i-1) begin
|
for (i=length-1; i>=1; i=i-1) begin
|
if (polynom[i])
|
if (polynom[i])
|
lfsr_fb = lfsr_fb ~^ qi[i];
|
lfsr_fb = lfsr_fb ~^ qi[i];
|
end
|
end
|
end
|
end
|
assign q_next = clear ? {length{1'b0}} :{qi[length-1:1],lfsr_fb};
|
assign q_next = clear ? {length{1'b0}} :{qi[length-1:1],lfsr_fb};
|
|
|
always @ (posedge clk or posedge rst)
|
always @ (posedge clk or posedge rst)
|
if (rst)
|
if (rst)
|
qi <= {length{1'b0}};
|
qi <= {length{1'b0}};
|
else
|
else
|
if (cke)
|
if (cke)
|
qi <= q_next;
|
qi <= q_next;
|
|
|
|
|
|
|
always @ (posedge clk or posedge rst)
|
always @ (posedge clk or posedge rst)
|
if (rst)
|
if (rst)
|
zq <= 1'b1;
|
zq <= 1'b1;
|
else
|
else
|
if (cke)
|
if (cke)
|
zq <= q_next == {length{1'b0}};
|
zq <= q_next == {length{1'b0}};
|
endmodule
|
endmodule
|
`include "versatile_mem_ctrl_defines.v"
|
`include "versatile_mem_ctrl_defines.v"
|
|
|
module fifo
|
module fifo
|
(
|
(
|
// A side
|
// A side
|
input [35:0] a_dat_i,
|
input [35:0] a_dat_i,
|
input a_we_i,
|
input a_we_i,
|
input [2:0] a_fifo_sel_i,
|
input [2:0] a_fifo_sel_i,
|
output [7:0] a_fifo_full_o,
|
output [7:0] a_fifo_full_o,
|
input a_clk,
|
input a_clk,
|
// B side
|
// B side
|
output [35:0] b_dat_o,
|
output [35:0] b_dat_o,
|
input b_re_i,
|
input b_re_i,
|
input [2:0] b_fifo_sel_i,
|
input [2:0] b_fifo_sel_i,
|
output [7:0] b_fifo_empty_o,
|
output [7:0] b_fifo_empty_o,
|
input b_clk,
|
input b_clk,
|
// Common
|
// Common
|
input rst
|
input rst
|
);
|
);
|
|
|
wire [4:0] wadr0, radr0;
|
wire [4:0] wadr0, radr0;
|
wire [4:0] wadr1, radr1;
|
wire [4:0] wadr1, radr1;
|
wire [4:0] wadr2, radr2;
|
wire [4:0] wadr2, radr2;
|
wire [4:0] wadr3, radr3;
|
wire [4:0] wadr3, radr3;
|
wire [4:0] wadr4, radr4;
|
wire [4:0] wadr4, radr4;
|
wire [4:0] wadr5, radr5;
|
wire [4:0] wadr5, radr5;
|
wire [4:0] wadr6, radr6;
|
wire [4:0] wadr6, radr6;
|
wire [4:0] wadr7, radr7;
|
wire [4:0] wadr7, radr7;
|
|
|
`ifdef PORT0
|
`ifdef PORT0
|
wire [4:0] wptr0, rptr0;
|
wire [4:0] wptr0, rptr0;
|
`endif
|
`endif
|
`ifdef PORT1
|
`ifdef PORT1
|
wire [4:0] wptr1, rptr1;
|
wire [4:0] wptr1, rptr1;
|
`endif
|
`endif
|
`ifdef PORT2
|
`ifdef PORT2
|
wire [4:0] wptr2, rptr2;
|
wire [4:0] wptr2, rptr2;
|
`endif
|
`endif
|
`ifdef PORT3
|
`ifdef PORT3
|
wire [4:0] wptr3, rptr3;
|
wire [4:0] wptr3, rptr3;
|
`endif
|
`endif
|
`ifdef PORT4
|
`ifdef PORT4
|
wire [4:0] wptr4, rptr4;
|
wire [4:0] wptr4, rptr4;
|
`endif
|
`endif
|
`ifdef PORT5
|
`ifdef PORT5
|
wire [4:0] wptr5, rptr5;
|
wire [4:0] wptr5, rptr5;
|
`endif
|
`endif
|
`ifdef PORT6
|
`ifdef PORT6
|
wire [4:0] wptr6, rptr6;
|
wire [4:0] wptr6, rptr6;
|
`endif
|
`endif
|
`ifdef PORT7
|
`ifdef PORT7
|
wire [4:0] wptr7, rptr7;
|
wire [4:0] wptr7, rptr7;
|
`endif
|
`endif
|
|
|
wire [7:0] dpram_a_a, dpram_a_b;
|
wire [7:0] dpram_a_a, dpram_a_b;
|
|
|
// WB#0
|
// WB#0
|
`ifdef PORT0
|
`ifdef PORT0
|
fifo_adr_counter wptr0_cnt
|
fifo_adr_counter wptr0_cnt
|
(
|
(
|
.q(wptr0),
|
.q(wptr0),
|
.q_bin(wadr0),
|
.q_bin(wadr0),
|
.cke(a_we_i & (a_fifo_sel_i==3'h0)),
|
.cke(a_we_i & (a_fifo_sel_i==3'h0)),
|
.clk(a_clk),
|
.clk(a_clk),
|
.rst(rst)
|
.rst(rst)
|
);
|
);
|
|
|
fifo_adr_counter rptr0_cnt
|
fifo_adr_counter rptr0_cnt
|
(
|
(
|
.q(rptr0),
|
.q(rptr0),
|
.q_bin(radr0),
|
.q_bin(radr0),
|
.cke(b_re_i & (b_fifo_sel_i==3'h0)),
|
.cke(b_re_i & (b_fifo_sel_i==3'h0)),
|
.clk(b_clk),
|
.clk(b_clk),
|
.rst(rst)
|
.rst(rst)
|
);
|
);
|
|
|
versatile_fifo_async_cmp
|
versatile_fifo_async_cmp
|
#
|
#
|
(
|
(
|
.ADDR_WIDTH(5)
|
.ADDR_WIDTH(5)
|
)
|
)
|
cmp0
|
cmp0
|
(
|
(
|
.wptr(wptr0),
|
.wptr(wptr0),
|
.rptr(rptr0),
|
.rptr(rptr0),
|
.fifo_empty(b_fifo_empty_o[0]),
|
.fifo_empty(b_fifo_empty_o[0]),
|
.fifo_full(a_fifo_full_o[0]),
|
.fifo_full(a_fifo_full_o[0]),
|
.wclk(a_clk),
|
.wclk(a_clk),
|
.rclk(b_clk),
|
.rclk(b_clk),
|
.rst(rst)
|
.rst(rst)
|
);
|
);
|
`else // !`ifdef PORT0
|
`else // !`ifdef PORT0
|
assign wptr0 = 5'h0;
|
assign wptr0 = 5'h0;
|
assign wadr0 = 5'h0;
|
assign wadr0 = 5'h0;
|
assign rptr0 = 5'h0;
|
assign rptr0 = 5'h0;
|
assign radr0 = 5'h0;
|
assign radr0 = 5'h0;
|
assign a_fifo_full_o[0] = 1'b0;
|
assign a_fifo_full_o[0] = 1'b0;
|
assign b_fifo_empty_o[0] = 1'b1;
|
assign b_fifo_empty_o[0] = 1'b1;
|
`endif // !`ifdef PORT0
|
`endif // !`ifdef PORT0
|
|
|
// WB#1
|
// WB#1
|
`ifdef PORT1
|
`ifdef PORT1
|
fifo_adr_counter wptr1_cnt
|
fifo_adr_counter wptr1_cnt
|
(
|
(
|
.q(wptr1),
|
.q(wptr1),
|
.q_bin(wadr1),
|
.q_bin(wadr1),
|
.cke(a_we_i & (a_fifo_sel_i==3'h1)),
|
.cke(a_we_i & (a_fifo_sel_i==3'h1)),
|
.clk(a_clk),
|
.clk(a_clk),
|
.rst(rst)
|
.rst(rst)
|
);
|
);
|
|
|
fifo_adr_counter rptr1_cnt
|
fifo_adr_counter rptr1_cnt
|
(
|
(
|
.q(rptr1),
|
.q(rptr1),
|
.q_bin(radr1),
|
.q_bin(radr1),
|
.cke(b_re_i & (b_fifo_sel_i==3'h1)),
|
.cke(b_re_i & (b_fifo_sel_i==3'h1)),
|
.clk(b_clk),
|
.clk(b_clk),
|
.rst(rst)
|
.rst(rst)
|
);
|
);
|
|
|
versatile_fifo_async_cmp
|
versatile_fifo_async_cmp
|
#
|
#
|
(
|
(
|
.ADDR_WIDTH(5)
|
.ADDR_WIDTH(5)
|
)
|
)
|
cmp1
|
cmp1
|
(
|
(
|
.wptr(wptr1),
|
.wptr(wptr1),
|
.rptr(rptr1),
|
.rptr(rptr1),
|
.fifo_empty(b_fifo_empty_o[1]),
|
.fifo_empty(b_fifo_empty_o[1]),
|
.fifo_full(a_fifo_full_o[1]),
|
.fifo_full(a_fifo_full_o[1]),
|
.wclk(a_clk),
|
.wclk(a_clk),
|
.rclk(b_clk),
|
.rclk(b_clk),
|
.rst(rst)
|
.rst(rst)
|
);
|
);
|
`else // !`ifdef PORT1
|
`else // !`ifdef PORT1
|
assign wptr1 = 5'h0;
|
assign wptr1 = 5'h0;
|
assign wadr1 = 5'h0;
|
assign wadr1 = 5'h0;
|
assign rptr1 = 5'h0;
|
assign rptr1 = 5'h0;
|
assign radr1 = 5'h0;
|
assign radr1 = 5'h0;
|
assign a_fifo_full_o[1] = 1'b0;
|
assign a_fifo_full_o[1] = 1'b0;
|
assign b_fifo_empty_o[1] = 1'b1;
|
assign b_fifo_empty_o[1] = 1'b1;
|
`endif // !`ifdef PORT1
|
`endif // !`ifdef PORT1
|
|
|
// WB#2
|
// WB#2
|
`ifdef PORT2
|
`ifdef PORT2
|
fifo_adr_counter wptr2_cnt
|
fifo_adr_counter wptr2_cnt
|
(
|
(
|
.q(wptr2),
|
.q(wptr2),
|
.q_bin(wadr2),
|
.q_bin(wadr2),
|
.cke(a_we_i & (a_fifo_sel_i==3'h2)),
|
.cke(a_we_i & (a_fifo_sel_i==3'h2)),
|
.clk(a_clk),
|
.clk(a_clk),
|
.rst(rst)
|
.rst(rst)
|
);
|
);
|
|
|
fifo_adr_counter rptr2_cnt
|
fifo_adr_counter rptr2_cnt
|
(
|
(
|
.q(rptr2),
|
.q(rptr2),
|
.q_bin(radr2),
|
.q_bin(radr2),
|
.cke(b_re_i & (b_fifo_sel_i==3'h2)),
|
.cke(b_re_i & (b_fifo_sel_i==3'h2)),
|
.clk(b_clk),
|
.clk(b_clk),
|
.rst(rst)
|
.rst(rst)
|
);
|
);
|
|
|
versatile_fifo_async_cmp
|
versatile_fifo_async_cmp
|
#
|
#
|
(
|
(
|
.ADDR_WIDTH(5)
|
.ADDR_WIDTH(5)
|
)
|
)
|
cmp2
|
cmp2
|
(
|
(
|
.wptr(wptr2),
|
.wptr(wptr2),
|
.rptr(rptr2),
|
.rptr(rptr2),
|
.fifo_empty(b_fifo_empty_o[2]),
|
.fifo_empty(b_fifo_empty_o[2]),
|
.fifo_full(a_fifo_full_o[2]),
|
.fifo_full(a_fifo_full_o[2]),
|
.wclk(a_clk),
|
.wclk(a_clk),
|
.rclk(b_clk),
|
.rclk(b_clk),
|
.rst(rst)
|
.rst(rst)
|
);
|
);
|
`else // !`ifdef PORT2
|
`else // !`ifdef PORT2
|
assign wptr2 = 5'h0;
|
assign wptr2 = 5'h0;
|
assign wadr2 = 5'h0;
|
assign wadr2 = 5'h0;
|
assign rptr2 = 5'h0;
|
assign rptr2 = 5'h0;
|
assign radr2 = 5'h0;
|
assign radr2 = 5'h0;
|
assign a_fifo_full_o[2] = 1'b0;
|
assign a_fifo_full_o[2] = 1'b0;
|
assign b_fifo_empty_o[2] = 1'b1;
|
assign b_fifo_empty_o[2] = 1'b1;
|
`endif // !`ifdef PORT2
|
`endif // !`ifdef PORT2
|
|
|
// WB#3
|
// WB#3
|
`ifdef PORT3
|
`ifdef PORT3
|
fifo_adr_counter wptr3_cnt
|
fifo_adr_counter wptr3_cnt
|
(
|
(
|
.q(wptr3),
|
.q(wptr3),
|
.q_bin(wadr3),
|
.q_bin(wadr3),
|
.cke(a_we_i & (a_fifo_sel_i==3'h3)),
|
.cke(a_we_i & (a_fifo_sel_i==3'h3)),
|
.clk(a_clk),
|
.clk(a_clk),
|
.rst(rst)
|
.rst(rst)
|
);
|
);
|
|
|
fifo_adr_counter rptr3_cnt
|
fifo_adr_counter rptr3_cnt
|
(
|
(
|
.q(rptr3),
|
.q(rptr3),
|
.q_bin(radr3),
|
.q_bin(radr3),
|
.cke(b_re_i & (b_fifo_sel_i==3'h3)),
|
.cke(b_re_i & (b_fifo_sel_i==3'h3)),
|
.clk(b_clk),
|
.clk(b_clk),
|
.rst(rst)
|
.rst(rst)
|
);
|
);
|
|
|
versatile_fifo_async_cmp
|
versatile_fifo_async_cmp
|
#
|
#
|
(
|
(
|
.ADDR_WIDTH(5)
|
.ADDR_WIDTH(5)
|
)
|
)
|
cmp3
|
cmp3
|
(
|
(
|
.wptr(wptr3),
|
.wptr(wptr3),
|
.rptr(rptr3),
|
.rptr(rptr3),
|
.fifo_empty(b_fifo_empty_o[3]),
|
.fifo_empty(b_fifo_empty_o[3]),
|
.fifo_full(a_fifo_full_o[3]),
|
.fifo_full(a_fifo_full_o[3]),
|
.wclk(a_clk),
|
.wclk(a_clk),
|
.rclk(b_clk),
|
.rclk(b_clk),
|
.rst(rst)
|
.rst(rst)
|
);
|
);
|
`else // !`ifdef PORT3
|
`else // !`ifdef PORT3
|
assign wptr3 = 5'h0;
|
assign wptr3 = 5'h0;
|
assign wadr3 = 5'h0;
|
assign wadr3 = 5'h0;
|
assign rptr3 = 5'h0;
|
assign rptr3 = 5'h0;
|
assign radr3 = 5'h0;
|
assign radr3 = 5'h0;
|
assign a_fifo_full_o[3] = 1'b0;
|
assign a_fifo_full_o[3] = 1'b0;
|
assign b_fifo_empty_o[3] = 1'b1;
|
assign b_fifo_empty_o[3] = 1'b1;
|
`endif // !`ifdef PORT3
|
`endif // !`ifdef PORT3
|
|
|
// WB#4
|
// WB#4
|
`ifdef PORT4
|
`ifdef PORT4
|
fifo_adr_counter wptr4_cnt
|
fifo_adr_counter wptr4_cnt
|
(
|
(
|
.q(wptr4),
|
.q(wptr4),
|
.q_bin(wadr4),
|
.q_bin(wadr4),
|
.cke(a_we_i & (a_fifo_sel_i==3'h4)),
|
.cke(a_we_i & (a_fifo_sel_i==3'h4)),
|
.clk(a_clk),
|
.clk(a_clk),
|
.rst(rst)
|
.rst(rst)
|
);
|
);
|
|
|
fifo_adr_counter rptr4_cnt
|
fifo_adr_counter rptr4_cnt
|
(
|
(
|
.q(rptr4),
|
.q(rptr4),
|
.q_bin(radr4),
|
.q_bin(radr4),
|
.cke(b_re_i & (b_fifo_sel_i==3'h4)),
|
.cke(b_re_i & (b_fifo_sel_i==3'h4)),
|
.clk(b_clk),
|
.clk(b_clk),
|
.rst(rst)
|
.rst(rst)
|
);
|
);
|
|
|
versatile_fifo_async_cmp
|
versatile_fifo_async_cmp
|
#
|
#
|
(
|
(
|
.ADDR_WIDTH(5)
|
.ADDR_WIDTH(5)
|
)
|
)
|
cmp4
|
cmp4
|
(
|
(
|
.wptr(wptr4),
|
.wptr(wptr4),
|
.rptr(rptr4),
|
.rptr(rptr4),
|
.fifo_empty(b_fifo_empty_o[4]),
|
.fifo_empty(b_fifo_empty_o[4]),
|
.fifo_full(a_fifo_full_o[4]),
|
.fifo_full(a_fifo_full_o[4]),
|
.wclk(a_clk),
|
.wclk(a_clk),
|
.rclk(b_clk),
|
.rclk(b_clk),
|
.rst(rst)
|
.rst(rst)
|
);
|
);
|
`else // !`ifdef PORT4
|
`else // !`ifdef PORT4
|
assign wptr4 = 5'h0;
|
assign wptr4 = 5'h0;
|
assign wadr4 = 5'h0;
|
assign wadr4 = 5'h0;
|
assign rptr4 = 5'h0;
|
assign rptr4 = 5'h0;
|
assign radr4 = 5'h0;
|
assign radr4 = 5'h0;
|
assign a_fifo_full_o[4] = 1'b0;
|
assign a_fifo_full_o[4] = 1'b0;
|
assign b_fifo_empty_o[4] = 1'b1;
|
assign b_fifo_empty_o[4] = 1'b1;
|
`endif // !`ifdef PORT4
|
`endif // !`ifdef PORT4
|
|
|
// WB#5
|
// WB#5
|
`ifdef PORT5
|
`ifdef PORT5
|
fifo_adr_counter wptr5_cnt
|
fifo_adr_counter wptr5_cnt
|
(
|
(
|
.q(wptr5),
|
.q(wptr5),
|
.q_bin(wadr5),
|
.q_bin(wadr5),
|
.cke(a_we_i & (a_fifo_sel_i==3'h5)),
|
.cke(a_we_i & (a_fifo_sel_i==3'h5)),
|
.clk(a_clk),
|
.clk(a_clk),
|
.rst(rst)
|
.rst(rst)
|
);
|
);
|
|
|
fifo_adr_counter rptr5_cnt
|
fifo_adr_counter rptr5_cnt
|
(
|
(
|
.q(rptr5),
|
.q(rptr5),
|
.q_bin(radr5),
|
.q_bin(radr5),
|
.cke(b_re_i & (b_fifo_sel_i==3'h5)),
|
.cke(b_re_i & (b_fifo_sel_i==3'h5)),
|
.clk(b_clk),
|
.clk(b_clk),
|
.rst(rst)
|
.rst(rst)
|
);
|
);
|
|
|
versatile_fifo_async_cmp
|
versatile_fifo_async_cmp
|
#
|
#
|
(
|
(
|
.ADDR_WIDTH(5)
|
.ADDR_WIDTH(5)
|
)
|
)
|
cmp5
|
cmp5
|
(
|
(
|
.wptr(wptr5),
|
.wptr(wptr5),
|
.rptr(rptr5),
|
.rptr(rptr5),
|
.fifo_empty(b_fifo_empty_o[5]),
|
.fifo_empty(b_fifo_empty_o[5]),
|
.fifo_full(a_fifo_full_o[5]),
|
.fifo_full(a_fifo_full_o[5]),
|
.wclk(a_clk),
|
.wclk(a_clk),
|
.rclk(b_clk),
|
.rclk(b_clk),
|
.rst(rst)
|
.rst(rst)
|
);
|
);
|
`else // !`ifdef PORT5
|
`else // !`ifdef PORT5
|
assign wptr5 = 5'h0;
|
assign wptr5 = 5'h0;
|
assign wadr5 = 5'h0;
|
assign wadr5 = 5'h0;
|
assign rptr5 = 5'h0;
|
assign rptr5 = 5'h0;
|
assign radr5 = 5'h0;
|
assign radr5 = 5'h0;
|
assign a_fifo_full_o[5] = 1'b0;
|
assign a_fifo_full_o[5] = 1'b0;
|
assign b_fifo_empty_o[5] = 1'b1;
|
assign b_fifo_empty_o[5] = 1'b1;
|
`endif // !`ifdef PORT5
|
`endif // !`ifdef PORT5
|
|
|
// WB#6
|
// WB#6
|
`ifdef PORT6
|
`ifdef PORT6
|
fifo_adr_counter wptr6_cnt
|
fifo_adr_counter wptr6_cnt
|
(
|
(
|
.q(wptr6),
|
.q(wptr6),
|
.q_bin(wadr6),
|
.q_bin(wadr6),
|
.cke(a_we_i & (a_fifo_sel_i==3'h6)),
|
.cke(a_we_i & (a_fifo_sel_i==3'h6)),
|
.clk(a_clk),
|
.clk(a_clk),
|
.rst(rst)
|
.rst(rst)
|
);
|
);
|
|
|
fifo_adr_counter rptr6_cnt
|
fifo_adr_counter rptr6_cnt
|
(
|
(
|
.q(rptr6),
|
.q(rptr6),
|
.q_bin(radr6),
|
.q_bin(radr6),
|
.cke(b_re_i & (b_fifo_sel_i==3'h6)),
|
.cke(b_re_i & (b_fifo_sel_i==3'h6)),
|
.clk(b_clk),
|
.clk(b_clk),
|
.rst(rst)
|
.rst(rst)
|
);
|
);
|
|
|
versatile_fifo_async_cmp
|
versatile_fifo_async_cmp
|
#
|
#
|
(
|
(
|
.ADDR_WIDTH(5)
|
.ADDR_WIDTH(5)
|
)
|
)
|
cmp6
|
cmp6
|
(
|
(
|
.wptr(wptr6),
|
.wptr(wptr6),
|
.rptr(rptr6),
|
.rptr(rptr6),
|
.fifo_empty(b_fifo_empty_o[6]),
|
.fifo_empty(b_fifo_empty_o[6]),
|
.fifo_full(a_fifo_full_o[6]),
|
.fifo_full(a_fifo_full_o[6]),
|
.wclk(a_clk),
|
.wclk(a_clk),
|
.rclk(b_clk),
|
.rclk(b_clk),
|
.rst(rst)
|
.rst(rst)
|
);
|
);
|
`else // !`ifdef PORT6
|
`else // !`ifdef PORT6
|
assign wptr6 = 5'h0;
|
assign wptr6 = 5'h0;
|
assign wadr6 = 5'h0;
|
assign wadr6 = 5'h0;
|
assign rptr6 = 5'h0;
|
assign rptr6 = 5'h0;
|
assign radr6 = 5'h0;
|
assign radr6 = 5'h0;
|
assign a_fifo_full_o[6] = 1'b0;
|
assign a_fifo_full_o[6] = 1'b0;
|
assign b_fifo_empty_o[6] = 1'b1;
|
assign b_fifo_empty_o[6] = 1'b1;
|
`endif // !`ifdef PORT6
|
`endif // !`ifdef PORT6
|
|
|
// WB#7
|
// WB#7
|
`ifdef PORT7
|
`ifdef PORT7
|
fifo_adr_counter wptr7_cnt
|
fifo_adr_counter wptr7_cnt
|
(
|
(
|
.q(wptr7),
|
.q(wptr7),
|
.q_bin(wadr7),
|
.q_bin(wadr7),
|
.cke(a_we_i & (a_fifo_sel_i==3'h7)),
|
.cke(a_we_i & (a_fifo_sel_i==3'h7)),
|
.clk(a_clk),
|
.clk(a_clk),
|
.rst(rst)
|
.rst(rst)
|
);
|
);
|
|
|
fifo_adr_counter rptr7_cnt
|
fifo_adr_counter rptr7_cnt
|
(
|
(
|
.q(rptr7),
|
.q(rptr7),
|
.q_bin(radr7),
|
.q_bin(radr7),
|
.cke(b_re_i & (b_fifo_sel_i==3'h7)),
|
.cke(b_re_i & (b_fifo_sel_i==3'h7)),
|
.clk(b_clk),
|
.clk(b_clk),
|
.rst(rst)
|
.rst(rst)
|
);
|
);
|
|
|
versatile_fifo_async_cmp
|
versatile_fifo_async_cmp
|
#
|
#
|
(
|
(
|
.ADDR_WIDTH(5)
|
.ADDR_WIDTH(5)
|
)
|
)
|
cmp7
|
cmp7
|
(
|
(
|
.wptr(wptr7),
|
.wptr(wptr7),
|
.rptr(rptr7),
|
.rptr(rptr7),
|
.fifo_empty(b_fifo_empty_o[7]),
|
.fifo_empty(b_fifo_empty_o[7]),
|
.fifo_full(a_fifo_full_o[7]),
|
.fifo_full(a_fifo_full_o[7]),
|
.wclk(a_clk),
|
.wclk(a_clk),
|
.rclk(b_clk),
|
.rclk(b_clk),
|
.rst(rst)
|
.rst(rst)
|
);
|
);
|
`else // !`ifdef PORT7
|
`else // !`ifdef PORT7
|
assign wptr7 = 5'h0;
|
assign wptr7 = 5'h0;
|
assign wadr7 = 5'h0;
|
assign wadr7 = 5'h0;
|
assign rptr7 = 5'h0;
|
assign rptr7 = 5'h0;
|
assign radr7 = 5'h0;
|
assign radr7 = 5'h0;
|
assign a_fifo_full_o[7] = 1'b0;
|
assign a_fifo_full_o[7] = 1'b0;
|
assign b_fifo_empty_o[7] = 1'b1;
|
assign b_fifo_empty_o[7] = 1'b1;
|
`endif // !`ifdef PORT7
|
`endif // !`ifdef PORT7
|
|
|
assign dpram_a_a = (a_fifo_sel_i==3'd0) ? {a_fifo_sel_i,wadr0} :
|
assign dpram_a_a = (a_fifo_sel_i==3'd0) ? {a_fifo_sel_i,wadr0} :
|
(a_fifo_sel_i==3'd1) ? {a_fifo_sel_i,wadr1} :
|
(a_fifo_sel_i==3'd1) ? {a_fifo_sel_i,wadr1} :
|
(a_fifo_sel_i==3'd2) ? {a_fifo_sel_i,wadr2} :
|
(a_fifo_sel_i==3'd2) ? {a_fifo_sel_i,wadr2} :
|
(a_fifo_sel_i==3'd3) ? {a_fifo_sel_i,wadr3} :
|
(a_fifo_sel_i==3'd3) ? {a_fifo_sel_i,wadr3} :
|
(a_fifo_sel_i==3'd4) ? {a_fifo_sel_i,wadr4} :
|
(a_fifo_sel_i==3'd4) ? {a_fifo_sel_i,wadr4} :
|
(a_fifo_sel_i==3'd5) ? {a_fifo_sel_i,wadr5} :
|
(a_fifo_sel_i==3'd5) ? {a_fifo_sel_i,wadr5} :
|
(a_fifo_sel_i==3'd6) ? {a_fifo_sel_i,wadr6} :
|
(a_fifo_sel_i==3'd6) ? {a_fifo_sel_i,wadr6} :
|
{a_fifo_sel_i,wadr7} ;
|
{a_fifo_sel_i,wadr7} ;
|
|
|
assign dpram_a_b = (b_fifo_sel_i==3'd0) ? {b_fifo_sel_i,radr0} :
|
assign dpram_a_b = (b_fifo_sel_i==3'd0) ? {b_fifo_sel_i,radr0} :
|
(b_fifo_sel_i==3'd1) ? {b_fifo_sel_i,radr1} :
|
(b_fifo_sel_i==3'd1) ? {b_fifo_sel_i,radr1} :
|
(b_fifo_sel_i==3'd2) ? {b_fifo_sel_i,radr2} :
|
(b_fifo_sel_i==3'd2) ? {b_fifo_sel_i,radr2} :
|
(b_fifo_sel_i==3'd3) ? {b_fifo_sel_i,radr3} :
|
(b_fifo_sel_i==3'd3) ? {b_fifo_sel_i,radr3} :
|
(b_fifo_sel_i==3'd4) ? {b_fifo_sel_i,radr4} :
|
(b_fifo_sel_i==3'd4) ? {b_fifo_sel_i,radr4} :
|
(b_fifo_sel_i==3'd5) ? {b_fifo_sel_i,radr5} :
|
(b_fifo_sel_i==3'd5) ? {b_fifo_sel_i,radr5} :
|
(b_fifo_sel_i==3'd6) ? {b_fifo_sel_i,radr6} :
|
(b_fifo_sel_i==3'd6) ? {b_fifo_sel_i,radr6} :
|
{b_fifo_sel_i,radr7} ;
|
{b_fifo_sel_i,radr7} ;
|
|
|
|
|
`ifdef ACTEL
|
`ifdef ACTEL
|
TwoPortRAM_256x36 dpram
|
TwoPortRAM_256x36 dpram
|
(
|
(
|
.WD(a_dat_i),
|
.WD(a_dat_i),
|
.RD(b_dat_o),
|
.RD(b_dat_o),
|
.WEN(a_we_i),
|
.WEN(a_we_i),
|
//.REN(b_re_i),
|
//.REN(b_re_i),
|
.REN(1'b1),
|
.REN(1'b1),
|
.WADDR(dpram_a_a),
|
.WADDR(dpram_a_a),
|
.RADDR(dpram_a_b),
|
.RADDR(dpram_a_b),
|
.WCLK(a_clk),
|
.WCLK(a_clk),
|
.RCLK(b_clk)
|
.RCLK(b_clk)
|
);
|
);
|
`else
|
`else
|
vfifo_dual_port_ram_dc_dw
|
vfifo_dual_port_ram_dc_dw
|
/* #
|
/* #
|
(
|
(
|
.ADDR_WIDTH(8),
|
.ADDR_WIDTH(8),
|
.DATA_WIDTH(36)
|
.DATA_WIDTH(36)
|
)*/
|
)*/
|
dpram
|
dpram
|
(
|
(
|
.d_a(a_dat_i),
|
.d_a(a_dat_i),
|
.q_a(),
|
.q_a(),
|
.adr_a(dpram_a_a),
|
.adr_a(dpram_a_a),
|
.we_a(a_we_i),
|
.we_a(a_we_i),
|
.clk_a(a_clk),
|
.clk_a(a_clk),
|
.q_b(b_dat_o),
|
.q_b(b_dat_o),
|
.adr_b(dpram_a_b),
|
.adr_b(dpram_a_b),
|
.d_b(36'h0),
|
.d_b(36'h0),
|
.we_b(1'b0),
|
.we_b(1'b0),
|
.clk_b(b_clk)
|
.clk_b(b_clk)
|
);
|
);
|
`endif
|
`endif
|
endmodule // sd_fifo
|
endmodule // sd_fifo
|
`define EOB (!(|cti) | &cti)
|
`define EOB (!(|cti) | &cti)
|
module fifo_fill (
|
module fifo_fill (
|
output reg wbs_flag,
|
output reg wbs_flag,
|
output reg we_req,
|
output reg we_req,
|
input wire ack,
|
input wire ack,
|
input wire [1:0] bte,
|
input wire [1:0] bte,
|
input wire clk,
|
input wire clk,
|
input wire [2:0] cti,
|
input wire [2:0] cti,
|
input wire cyc,
|
input wire cyc,
|
input wire rst,
|
input wire rst,
|
input wire stb,
|
input wire stb,
|
input wire we,
|
input wire we,
|
input wire we_ack
|
input wire we_ack
|
);
|
);
|
|
|
|
|
// state bits
|
// state bits
|
parameter
|
parameter
|
idle = 0,
|
idle = 0,
|
state1 = 1,
|
state1 = 1,
|
state10 = 2,
|
state10 = 2,
|
state11 = 3,
|
state11 = 3,
|
state12 = 4,
|
state12 = 4,
|
state13 = 5,
|
state13 = 5,
|
state14 = 6,
|
state14 = 6,
|
state15 = 7,
|
state15 = 7,
|
state16 = 8,
|
state16 = 8,
|
state2 = 9,
|
state2 = 9,
|
state3 = 10,
|
state3 = 10,
|
state4 = 11,
|
state4 = 11,
|
state5 = 12,
|
state5 = 12,
|
state6 = 13,
|
state6 = 13,
|
state7 = 14,
|
state7 = 14,
|
state8 = 15,
|
state8 = 15,
|
state9 = 16;
|
state9 = 16;
|
|
|
reg [16:0] state;
|
reg [16:0] state;
|
reg [16:0] nextstate;
|
reg [16:0] nextstate;
|
|
|
// comb always block
|
// comb always block
|
always @* begin
|
always @* begin
|
nextstate = 17'b00000000000000000;
|
nextstate = 17'b00000000000000000;
|
wbs_flag = 1'b0; // default
|
wbs_flag = 1'b0; // default
|
we_req = we & stb; // default
|
we_req = we & stb; // default
|
case (1'b1) // synopsys parallel_case full_case
|
case (1'b1) // synopsys parallel_case full_case
|
state[idle] : begin
|
state[idle] : begin
|
wbs_flag = 1'b1;
|
wbs_flag = 1'b1;
|
we_req = cyc & stb;
|
we_req = cyc & stb;
|
if (cyc & stb & we_ack) begin
|
if (cyc & stb & we_ack) begin
|
nextstate[state1] = 1'b1;
|
nextstate[state1] = 1'b1;
|
end
|
end
|
else begin
|
else begin
|
nextstate[idle] = 1'b1; // Added because implied_loopback is true
|
nextstate[idle] = 1'b1; // Added because implied_loopback is true
|
end
|
end
|
end
|
end
|
state[state1] : begin
|
state[state1] : begin
|
if (`EOB & ack) begin
|
if (`EOB & ack) begin
|
nextstate[idle] = 1'b1;
|
nextstate[idle] = 1'b1;
|
end
|
end
|
else if (ack) begin
|
else if (ack) begin
|
nextstate[state2] = 1'b1;
|
nextstate[state2] = 1'b1;
|
end
|
end
|
else begin
|
else begin
|
nextstate[state1] = 1'b1; // Added because implied_loopback is true
|
nextstate[state1] = 1'b1; // Added because implied_loopback is true
|
end
|
end
|
end
|
end
|
state[state10]: begin
|
state[state10]: begin
|
if (`EOB & ack) begin
|
if (`EOB & ack) begin
|
nextstate[idle] = 1'b1;
|
nextstate[idle] = 1'b1;
|
end
|
end
|
else if (ack) begin
|
else if (ack) begin
|
nextstate[state11] = 1'b1;
|
nextstate[state11] = 1'b1;
|
end
|
end
|
else begin
|
else begin
|
nextstate[state10] = 1'b1; // Added because implied_loopback is true
|
nextstate[state10] = 1'b1; // Added because implied_loopback is true
|
end
|
end
|
end
|
end
|
state[state11]: begin
|
state[state11]: begin
|
if (`EOB & ack) begin
|
if (`EOB & ack) begin
|
nextstate[idle] = 1'b1;
|
nextstate[idle] = 1'b1;
|
end
|
end
|
else if (ack) begin
|
else if (ack) begin
|
nextstate[state12] = 1'b1;
|
nextstate[state12] = 1'b1;
|
end
|
end
|
else begin
|
else begin
|
nextstate[state11] = 1'b1; // Added because implied_loopback is true
|
nextstate[state11] = 1'b1; // Added because implied_loopback is true
|
end
|
end
|
end
|
end
|
state[state12]: begin
|
state[state12]: begin
|
if (`EOB & ack) begin
|
if (`EOB & ack) begin
|
nextstate[idle] = 1'b1;
|
nextstate[idle] = 1'b1;
|
end
|
end
|
else if (ack) begin
|
else if (ack) begin
|
nextstate[state13] = 1'b1;
|
nextstate[state13] = 1'b1;
|
end
|
end
|
else begin
|
else begin
|
nextstate[state12] = 1'b1; // Added because implied_loopback is true
|
nextstate[state12] = 1'b1; // Added because implied_loopback is true
|
end
|
end
|
end
|
end
|
state[state13]: begin
|
state[state13]: begin
|
if (`EOB & ack) begin
|
if (`EOB & ack) begin
|
nextstate[idle] = 1'b1;
|
nextstate[idle] = 1'b1;
|
end
|
end
|
else if (ack) begin
|
else if (ack) begin
|
nextstate[state14] = 1'b1;
|
nextstate[state14] = 1'b1;
|
end
|
end
|
else begin
|
else begin
|
nextstate[state13] = 1'b1; // Added because implied_loopback is true
|
nextstate[state13] = 1'b1; // Added because implied_loopback is true
|
end
|
end
|
end
|
end
|
state[state14]: begin
|
state[state14]: begin
|
if (`EOB & ack) begin
|
if (`EOB & ack) begin
|
nextstate[idle] = 1'b1;
|
nextstate[idle] = 1'b1;
|
end
|
end
|
else if (ack) begin
|
else if (ack) begin
|
nextstate[state15] = 1'b1;
|
nextstate[state15] = 1'b1;
|
end
|
end
|
else begin
|
else begin
|
nextstate[state14] = 1'b1; // Added because implied_loopback is true
|
nextstate[state14] = 1'b1; // Added because implied_loopback is true
|
end
|
end
|
end
|
end
|
state[state15]: begin
|
state[state15]: begin
|
if (`EOB & ack) begin
|
if (`EOB & ack) begin
|
nextstate[idle] = 1'b1;
|
nextstate[idle] = 1'b1;
|
end
|
end
|
else if (ack) begin
|
else if (ack) begin
|
nextstate[state16] = 1'b1;
|
nextstate[state16] = 1'b1;
|
end
|
end
|
else begin
|
else begin
|
nextstate[state15] = 1'b1; // Added because implied_loopback is true
|
nextstate[state15] = 1'b1; // Added because implied_loopback is true
|
end
|
end
|
end
|
end
|
state[state16]: begin
|
state[state16]: begin
|
if (ack) begin
|
if (ack) begin
|
nextstate[idle] = 1'b1;
|
nextstate[idle] = 1'b1;
|
end
|
end
|
else begin
|
else begin
|
nextstate[state16] = 1'b1; // Added because implied_loopback is true
|
nextstate[state16] = 1'b1; // Added because implied_loopback is true
|
end
|
end
|
end
|
end
|
state[state2] : begin
|
state[state2] : begin
|
if (`EOB & ack) begin
|
if (`EOB & ack) begin
|
nextstate[idle] = 1'b1;
|
nextstate[idle] = 1'b1;
|
end
|
end
|
else if (ack) begin
|
else if (ack) begin
|
nextstate[state3] = 1'b1;
|
nextstate[state3] = 1'b1;
|
end
|
end
|
else begin
|
else begin
|
nextstate[state2] = 1'b1; // Added because implied_loopback is true
|
nextstate[state2] = 1'b1; // Added because implied_loopback is true
|
end
|
end
|
end
|
end
|
state[state3] : begin
|
state[state3] : begin
|
if (`EOB & ack) begin
|
if (`EOB & ack) begin
|
nextstate[idle] = 1'b1;
|
nextstate[idle] = 1'b1;
|
end
|
end
|
else if (ack) begin
|
else if (ack) begin
|
nextstate[state4] = 1'b1;
|
nextstate[state4] = 1'b1;
|
end
|
end
|
else begin
|
else begin
|
nextstate[state3] = 1'b1; // Added because implied_loopback is true
|
nextstate[state3] = 1'b1; // Added because implied_loopback is true
|
end
|
end
|
end
|
end
|
state[state4] : begin
|
state[state4] : begin
|
if (`EOB & ack) begin
|
if (`EOB & ack) begin
|
nextstate[idle] = 1'b1;
|
nextstate[idle] = 1'b1;
|
end
|
end
|
else if ((bte==2'b01) & ack) begin
|
else if ((bte==2'b01) & ack) begin
|
nextstate[idle] = 1'b1;
|
nextstate[idle] = 1'b1;
|
end
|
end
|
else if (ack) begin
|
else if (ack) begin
|
nextstate[state5] = 1'b1;
|
nextstate[state5] = 1'b1;
|
end
|
end
|
else begin
|
else begin
|
nextstate[state4] = 1'b1; // Added because implied_loopback is true
|
nextstate[state4] = 1'b1; // Added because implied_loopback is true
|
end
|
end
|
end
|
end
|
state[state5] : begin
|
state[state5] : begin
|
if (`EOB & ack) begin
|
if (`EOB & ack) begin
|
nextstate[idle] = 1'b1;
|
nextstate[idle] = 1'b1;
|
end
|
end
|
else if (ack) begin
|
else if (ack) begin
|
nextstate[state6] = 1'b1;
|
nextstate[state6] = 1'b1;
|
end
|
end
|
else begin
|
else begin
|
nextstate[state5] = 1'b1; // Added because implied_loopback is true
|
nextstate[state5] = 1'b1; // Added because implied_loopback is true
|
end
|
end
|
end
|
end
|
state[state6] : begin
|
state[state6] : begin
|
if (`EOB & ack) begin
|
if (`EOB & ack) begin
|
nextstate[idle] = 1'b1;
|
nextstate[idle] = 1'b1;
|
end
|
end
|
else if (ack) begin
|
else if (ack) begin
|
nextstate[state7] = 1'b1;
|
nextstate[state7] = 1'b1;
|
end
|
end
|
else begin
|
else begin
|
nextstate[state6] = 1'b1; // Added because implied_loopback is true
|
nextstate[state6] = 1'b1; // Added because implied_loopback is true
|
end
|
end
|
end
|
end
|
state[state7] : begin
|
state[state7] : begin
|
if (`EOB & ack) begin
|
if (`EOB & ack) begin
|
nextstate[idle] = 1'b1;
|
nextstate[idle] = 1'b1;
|
end
|
end
|
else if (ack) begin
|
else if (ack) begin
|
nextstate[state8] = 1'b1;
|
nextstate[state8] = 1'b1;
|
end
|
end
|
else begin
|
else begin
|
nextstate[state7] = 1'b1; // Added because implied_loopback is true
|
nextstate[state7] = 1'b1; // Added because implied_loopback is true
|
end
|
end
|
end
|
end
|
state[state8] : begin
|
state[state8] : begin
|
if (`EOB & ack) begin
|
if (`EOB & ack) begin
|
nextstate[idle] = 1'b1;
|
nextstate[idle] = 1'b1;
|
end
|
end
|
else if ((bte==2'b10) & ack) begin
|
else if ((bte==2'b10) & ack) begin
|
nextstate[idle] = 1'b1;
|
nextstate[idle] = 1'b1;
|
end
|
end
|
else if (ack) begin
|
else if (ack) begin
|
nextstate[state9] = 1'b1;
|
nextstate[state9] = 1'b1;
|
end
|
end
|
else begin
|
else begin
|
nextstate[state8] = 1'b1; // Added because implied_loopback is true
|
nextstate[state8] = 1'b1; // Added because implied_loopback is true
|
end
|
end
|
end
|
end
|
state[state9] : begin
|
state[state9] : begin
|
if (`EOB & ack) begin
|
if (`EOB & ack) begin
|
nextstate[idle] = 1'b1;
|
nextstate[idle] = 1'b1;
|
end
|
end
|
else if (ack) begin
|
else if (ack) begin
|
nextstate[state10] = 1'b1;
|
nextstate[state10] = 1'b1;
|
end
|
end
|
else begin
|
else begin
|
nextstate[state9] = 1'b1; // Added because implied_loopback is true
|
nextstate[state9] = 1'b1; // Added because implied_loopback is true
|
end
|
end
|
end
|
end
|
endcase
|
endcase
|
end
|
end
|
|
|
// sequential always block
|
// sequential always block
|
always @(posedge clk or posedge rst) begin
|
always @(posedge clk or posedge rst) begin
|
if (rst)
|
if (rst)
|
state <= 17'b00000000000000001 << idle;
|
state <= 17'b00000000000000001 << idle;
|
else
|
else
|
state <= nextstate;
|
state <= nextstate;
|
end
|
end
|
|
|
// This code allows you to see state names in simulation
|
// This code allows you to see state names in simulation
|
`ifndef SYNTHESIS
|
`ifndef SYNTHESIS
|
reg [55:0] statename;
|
reg [55:0] statename;
|
always @* begin
|
always @* begin
|
case (1'b1)
|
case (1'b1)
|
state[idle] :
|
state[idle] :
|
statename = "idle";
|
statename = "idle";
|
state[state1] :
|
state[state1] :
|
statename = "state1";
|
statename = "state1";
|
state[state10]:
|
state[state10]:
|
statename = "state10";
|
statename = "state10";
|
state[state11]:
|
state[state11]:
|
statename = "state11";
|
statename = "state11";
|
state[state12]:
|
state[state12]:
|
statename = "state12";
|
statename = "state12";
|
state[state13]:
|
state[state13]:
|
statename = "state13";
|
statename = "state13";
|
state[state14]:
|
state[state14]:
|
statename = "state14";
|
statename = "state14";
|
state[state15]:
|
state[state15]:
|
statename = "state15";
|
statename = "state15";
|
state[state16]:
|
state[state16]:
|
statename = "state16";
|
statename = "state16";
|
state[state2] :
|
state[state2] :
|
statename = "state2";
|
statename = "state2";
|
state[state3] :
|
state[state3] :
|
statename = "state3";
|
statename = "state3";
|
state[state4] :
|
state[state4] :
|
statename = "state4";
|
statename = "state4";
|
state[state5] :
|
state[state5] :
|
statename = "state5";
|
statename = "state5";
|
state[state6] :
|
state[state6] :
|
statename = "state6";
|
statename = "state6";
|
state[state7] :
|
state[state7] :
|
statename = "state7";
|
statename = "state7";
|
state[state8] :
|
state[state8] :
|
statename = "state8";
|
statename = "state8";
|
state[state9] :
|
state[state9] :
|
statename = "state9";
|
statename = "state9";
|
default:
|
default:
|
statename = "XXXXXXX";
|
statename = "XXXXXXX";
|
endcase
|
endcase
|
end
|
end
|
`endif
|
`endif
|
|
|
|
|
endmodule
|
endmodule
|
|
|
module inc_adr
|
module inc_adr
|
(
|
(
|
input [3:0] adr_i,
|
input [3:0] adr_i,
|
input [2:0] cti_i,
|
input [2:0] cti_i,
|
input [1:0] bte_i,
|
input [1:0] bte_i,
|
input init,
|
input init,
|
input inc,
|
input inc,
|
output reg [3:0] adr_o,
|
output reg [3:0] adr_o,
|
output reg done,
|
output reg done,
|
input clk,
|
input clk,
|
input rst
|
input rst
|
);
|
);
|
|
|
reg init_i;
|
reg init_i;
|
|
|
reg [1:0] bte;
|
reg [1:0] bte;
|
reg [3:0] cnt;
|
reg [3:0] cnt;
|
|
|
// delay init one clock cycle to be able to read from mem
|
// delay init one clock cycle to be able to read from mem
|
always @ (posedge clk or posedge rst)
|
always @ (posedge clk or posedge rst)
|
if (rst)
|
if (rst)
|
init_i <= 1'b0;
|
init_i <= 1'b0;
|
else
|
else
|
init_i <= init;
|
init_i <= init;
|
|
|
// bte
|
// bte
|
always @ (posedge clk or posedge rst)
|
always @ (posedge clk or posedge rst)
|
if (rst)
|
if (rst)
|
bte <= 2'b00;
|
bte <= 2'b00;
|
else
|
else
|
if (init_i)
|
if (init_i)
|
bte <= bte_i;
|
bte <= bte_i;
|
|
|
// adr_o
|
// adr_o
|
always @ (posedge clk or posedge rst)
|
always @ (posedge clk or posedge rst)
|
if (rst)
|
if (rst)
|
adr_o <= 4'd0;
|
adr_o <= 4'd0;
|
else
|
else
|
if (init_i)
|
if (init_i)
|
adr_o <= adr_i;
|
adr_o <= adr_i;
|
else
|
else
|
if (inc)
|
if (inc)
|
case (bte)
|
case (bte)
|
2'b01: adr_o <= {adr_o[3:2], adr_o[1:0] + 2'd1};
|
2'b01: adr_o <= {adr_o[3:2], adr_o[1:0] + 2'd1};
|
2'b10: adr_o <= {adr_o[3], adr_o[2:0] + 3'd1};
|
2'b10: adr_o <= {adr_o[3], adr_o[2:0] + 3'd1};
|
default: adr_o <= adr_o + 4'd1;
|
default: adr_o <= adr_o + 4'd1;
|
endcase // case (bte)
|
endcase // case (bte)
|
|
|
// done
|
// done
|
always @ (posedge clk or posedge rst)
|
always @ (posedge clk or posedge rst)
|
if (rst)
|
if (rst)
|
{done,cnt} <= {1'b0,4'd0};
|
{done,cnt} <= {1'b0,4'd0};
|
else
|
else
|
if (init_i)
|
if (init_i)
|
begin
|
begin
|
done <= ({bte_i,cti_i} == {2'b00,3'b000});
|
done <= ({bte_i,cti_i} == {2'b00,3'b000});
|
case (bte_i)
|
case (bte_i)
|
2'b01: cnt <= 4'd12;
|
2'b01: cnt <= 4'd12;
|
2'b10: cnt <= 4'd8;
|
2'b10: cnt <= 4'd8;
|
2'b11: cnt <= 4'd0;
|
2'b11: cnt <= 4'd0;
|
default: cnt <= adr_i;
|
default: cnt <= adr_i;
|
endcase
|
endcase
|
end
|
end
|
else
|
else
|
if (inc)
|
if (inc)
|
{done,cnt} <= cnt + 4'd1;
|
{done,cnt} <= cnt + 4'd1;
|
|
|
endmodule // inc_adr
|
endmodule // inc_adr
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
//// ////
|
//// ////
|
//// Versatile counter ////
|
//// Versatile counter ////
|
//// ////
|
//// ////
|
//// Description ////
|
//// Description ////
|
//// Versatile counter, a reconfigurable binary, gray or LFSR ////
|
//// Versatile counter, a reconfigurable binary, gray or LFSR ////
|
//// counter ////
|
//// counter ////
|
//// ////
|
//// ////
|
//// To Do: ////
|
//// To Do: ////
|
//// - add LFSR with more taps ////
|
//// - add LFSR with more taps ////
|
//// ////
|
//// ////
|
//// Author(s): ////
|
//// Author(s): ////
|
//// - Michael Unneback, unneback@opencores.org ////
|
//// - Michael Unneback, unneback@opencores.org ////
|
//// ORSoC AB ////
|
//// ORSoC AB ////
|
//// ////
|
//// ////
|
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
//// ////
|
//// ////
|
//// Copyright (C) 2009 Authors and OPENCORES.ORG ////
|
//// Copyright (C) 2009 Authors and OPENCORES.ORG ////
|
//// ////
|
//// ////
|
//// This source file may be used and distributed without ////
|
//// This source file may be used and distributed without ////
|
//// restriction provided that this copyright statement is not ////
|
//// restriction provided that this copyright statement is not ////
|
//// removed from the file and that any derivative work contains ////
|
//// removed from the file and that any derivative work contains ////
|
//// the original copyright notice and the associated disclaimer. ////
|
//// the original copyright notice and the associated disclaimer. ////
|
//// ////
|
//// ////
|
//// This source file is free software; you can redistribute it ////
|
//// This source file is free software; you can redistribute it ////
|
//// and/or modify it under the terms of the GNU Lesser General ////
|
//// and/or modify it under the terms of the GNU Lesser General ////
|
//// Public License as published by the Free Software Foundation; ////
|
//// Public License as published by the Free Software Foundation; ////
|
//// either version 2.1 of the License, or (at your option) any ////
|
//// either version 2.1 of the License, or (at your option) any ////
|
//// later version. ////
|
//// later version. ////
|
//// ////
|
//// ////
|
//// This source is distributed in the hope that it will be ////
|
//// This source is distributed in the hope that it will be ////
|
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
//// details. ////
|
//// details. ////
|
//// ////
|
//// ////
|
//// You should have received a copy of the GNU Lesser General ////
|
//// You should have received a copy of the GNU Lesser General ////
|
//// Public License along with this source; if not, download it ////
|
//// Public License along with this source; if not, download it ////
|
//// from http://www.opencores.org/lgpl.shtml ////
|
//// from http://www.opencores.org/lgpl.shtml ////
|
//// ////
|
//// ////
|
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
|
|
// LFSR counter
|
// LFSR counter
|
module ref_counter ( zq, rst, clk);
|
module ref_counter ( zq, rst, clk);
|
|
|
parameter length = 10;
|
parameter length = 10;
|
output reg zq;
|
output reg zq;
|
input rst;
|
input rst;
|
input clk;
|
input clk;
|
|
|
parameter clear_value = 0;
|
parameter clear_value = 0;
|
parameter set_value = 0;
|
parameter set_value = 0;
|
parameter wrap_value = 417;
|
parameter wrap_value = 417;
|
|
|
reg [length:1] qi;
|
reg [length:1] qi;
|
reg lfsr_fb;
|
reg lfsr_fb;
|
wire [length:1] q_next;
|
wire [length:1] q_next;
|
reg [32:1] polynom;
|
reg [32:1] polynom;
|
integer i;
|
integer i;
|
|
|
always @ (qi)
|
always @ (qi)
|
begin
|
begin
|
case (length)
|
case (length)
|
2: polynom = 32'b11; // 0x3
|
2: polynom = 32'b11; // 0x3
|
3: polynom = 32'b110; // 0x6
|
3: polynom = 32'b110; // 0x6
|
4: polynom = 32'b1100; // 0xC
|
4: polynom = 32'b1100; // 0xC
|
5: polynom = 32'b10100; // 0x14
|
5: polynom = 32'b10100; // 0x14
|
6: polynom = 32'b110000; // 0x30
|
6: polynom = 32'b110000; // 0x30
|
7: polynom = 32'b1100000; // 0x60
|
7: polynom = 32'b1100000; // 0x60
|
8: polynom = 32'b10111000; // 0xb8
|
8: polynom = 32'b10111000; // 0xb8
|
9: polynom = 32'b100010000; // 0x110
|
9: polynom = 32'b100010000; // 0x110
|
10: polynom = 32'b1001000000; // 0x240
|
10: polynom = 32'b1001000000; // 0x240
|
11: polynom = 32'b10100000000; // 0x500
|
11: polynom = 32'b10100000000; // 0x500
|
12: polynom = 32'b100000101001; // 0x829
|
12: polynom = 32'b100000101001; // 0x829
|
13: polynom = 32'b1000000001100; // 0x100C
|
13: polynom = 32'b1000000001100; // 0x100C
|
14: polynom = 32'b10000000010101; // 0x2015
|
14: polynom = 32'b10000000010101; // 0x2015
|
15: polynom = 32'b110000000000000; // 0x6000
|
15: polynom = 32'b110000000000000; // 0x6000
|
16: polynom = 32'b1101000000001000; // 0xD008
|
16: polynom = 32'b1101000000001000; // 0xD008
|
17: polynom = 32'b10010000000000000; // 0x12000
|
17: polynom = 32'b10010000000000000; // 0x12000
|
18: polynom = 32'b100000010000000000; // 0x20400
|
18: polynom = 32'b100000010000000000; // 0x20400
|
19: polynom = 32'b1000000000000100011; // 0x40023
|
19: polynom = 32'b1000000000000100011; // 0x40023
|
20: polynom = 32'b10000010000000000000; // 0x82000
|
20: polynom = 32'b10000010000000000000; // 0x82000
|
21: polynom = 32'b101000000000000000000; // 0x140000
|
21: polynom = 32'b101000000000000000000; // 0x140000
|
22: polynom = 32'b1100000000000000000000; // 0x300000
|
22: polynom = 32'b1100000000000000000000; // 0x300000
|
23: polynom = 32'b10000100000000000000000; // 0x420000
|
23: polynom = 32'b10000100000000000000000; // 0x420000
|
24: polynom = 32'b111000010000000000000000; // 0xE10000
|
24: polynom = 32'b111000010000000000000000; // 0xE10000
|
25: polynom = 32'b1001000000000000000000000; // 0x1200000
|
25: polynom = 32'b1001000000000000000000000; // 0x1200000
|
26: polynom = 32'b10000000000000000000100011; // 0x2000023
|
26: polynom = 32'b10000000000000000000100011; // 0x2000023
|
27: polynom = 32'b100000000000000000000010011; // 0x4000013
|
27: polynom = 32'b100000000000000000000010011; // 0x4000013
|
28: polynom = 32'b1100100000000000000000000000; // 0xC800000
|
28: polynom = 32'b1100100000000000000000000000; // 0xC800000
|
29: polynom = 32'b10100000000000000000000000000; // 0x14000000
|
29: polynom = 32'b10100000000000000000000000000; // 0x14000000
|
30: polynom = 32'b100000000000000000000000101001; // 0x20000029
|
30: polynom = 32'b100000000000000000000000101001; // 0x20000029
|
31: polynom = 32'b1001000000000000000000000000000; // 0x48000000
|
31: polynom = 32'b1001000000000000000000000000000; // 0x48000000
|
32: polynom = 32'b10000000001000000000000000000011; // 0x80200003
|
32: polynom = 32'b10000000001000000000000000000011; // 0x80200003
|
default: polynom = 32'b0;
|
default: polynom = 32'b0;
|
endcase
|
endcase
|
lfsr_fb = qi[length];
|
lfsr_fb = qi[length];
|
for (i=length-1; i>=1; i=i-1) begin
|
for (i=length-1; i>=1; i=i-1) begin
|
if (polynom[i])
|
if (polynom[i])
|
lfsr_fb = lfsr_fb ~^ qi[i];
|
lfsr_fb = lfsr_fb ~^ qi[i];
|
end
|
end
|
end
|
end
|
assign q_next = (qi == wrap_value) ? {length{1'b0}} :{qi[length-1:1],lfsr_fb};
|
assign q_next = (qi == wrap_value) ? {length{1'b0}} :{qi[length-1:1],lfsr_fb};
|
|
|
always @ (posedge clk or posedge rst)
|
always @ (posedge clk or posedge rst)
|
if (rst)
|
if (rst)
|
qi <= {length{1'b0}};
|
qi <= {length{1'b0}};
|
else
|
else
|
qi <= q_next;
|
qi <= q_next;
|
|
|
|
|
|
|
always @ (posedge clk or posedge rst)
|
always @ (posedge clk or posedge rst)
|
if (rst)
|
if (rst)
|
zq <= 1'b1;
|
zq <= 1'b1;
|
else
|
else
|
zq <= q_next == {length{1'b0}};
|
zq <= q_next == {length{1'b0}};
|
endmodule
|
endmodule
|
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
//// ////
|
//// ////
|
//// Versatile counter ////
|
//// Versatile counter ////
|
//// ////
|
//// ////
|
//// Description ////
|
//// Description ////
|
//// Versatile counter, a reconfigurable binary, gray or LFSR ////
|
//// Versatile counter, a reconfigurable binary, gray or LFSR ////
|
//// counter ////
|
//// counter ////
|
//// ////
|
//// ////
|
//// To Do: ////
|
//// To Do: ////
|
//// - add LFSR with more taps ////
|
//// - add LFSR with more taps ////
|
//// ////
|
//// ////
|
//// Author(s): ////
|
//// Author(s): ////
|
//// - Michael Unneback, unneback@opencores.org ////
|
//// - Michael Unneback, unneback@opencores.org ////
|
//// ORSoC AB ////
|
//// ORSoC AB ////
|
//// ////
|
//// ////
|
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
//// ////
|
//// ////
|
//// Copyright (C) 2009 Authors and OPENCORES.ORG ////
|
//// Copyright (C) 2009 Authors and OPENCORES.ORG ////
|
//// ////
|
//// ////
|
//// This source file may be used and distributed without ////
|
//// This source file may be used and distributed without ////
|
//// restriction provided that this copyright statement is not ////
|
//// restriction provided that this copyright statement is not ////
|
//// removed from the file and that any derivative work contains ////
|
//// removed from the file and that any derivative work contains ////
|
//// the original copyright notice and the associated disclaimer. ////
|
//// the original copyright notice and the associated disclaimer. ////
|
//// ////
|
//// ////
|
//// This source file is free software; you can redistribute it ////
|
//// This source file is free software; you can redistribute it ////
|
//// and/or modify it under the terms of the GNU Lesser General ////
|
//// and/or modify it under the terms of the GNU Lesser General ////
|
//// Public License as published by the Free Software Foundation; ////
|
//// Public License as published by the Free Software Foundation; ////
|
//// either version 2.1 of the License, or (at your option) any ////
|
//// either version 2.1 of the License, or (at your option) any ////
|
//// later version. ////
|
//// later version. ////
|
//// ////
|
//// ////
|
//// This source is distributed in the hope that it will be ////
|
//// This source is distributed in the hope that it will be ////
|
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
//// details. ////
|
//// details. ////
|
//// ////
|
//// ////
|
//// You should have received a copy of the GNU Lesser General ////
|
//// You should have received a copy of the GNU Lesser General ////
|
//// Public License along with this source; if not, download it ////
|
//// Public License along with this source; if not, download it ////
|
//// from http://www.opencores.org/lgpl.shtml ////
|
//// from http://www.opencores.org/lgpl.shtml ////
|
//// ////
|
//// ////
|
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
|
|
// BINARY counter
|
// BINARY counter
|
module ref_delay_counter ( cke, zq, rst, clk);
|
module ref_delay_counter ( cke, zq, rst, clk);
|
|
|
parameter length = 6;
|
parameter length = 6;
|
input cke;
|
input cke;
|
output reg zq;
|
output reg zq;
|
input rst;
|
input rst;
|
input clk;
|
input clk;
|
|
|
parameter clear_value = 0;
|
parameter clear_value = 0;
|
parameter set_value = 0;
|
parameter set_value = 0;
|
parameter wrap_value = 12;
|
parameter wrap_value = 12;
|
|
|
reg [length:1] qi;
|
reg [length:1] qi;
|
wire [length:1] q_next;
|
wire [length:1] q_next;
|
assign q_next = qi + {{length-1{1'b0}},1'b1};
|
assign q_next = qi + {{length-1{1'b0}},1'b1};
|
|
|
always @ (posedge clk or posedge rst)
|
always @ (posedge clk or posedge rst)
|
if (rst)
|
if (rst)
|
qi <= {length{1'b0}};
|
qi <= {length{1'b0}};
|
else
|
else
|
if (cke)
|
if (cke)
|
qi <= q_next;
|
qi <= q_next;
|
|
|
|
|
|
|
always @ (posedge clk or posedge rst)
|
always @ (posedge clk or posedge rst)
|
if (rst)
|
if (rst)
|
zq <= 1'b1;
|
zq <= 1'b1;
|
else
|
else
|
if (cke)
|
if (cke)
|
zq <= q_next == {length{1'b0}};
|
zq <= q_next == {length{1'b0}};
|
endmodule
|
endmodule
|
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
//// ////
|
//// ////
|
//// Versatile counter ////
|
//// Versatile counter ////
|
//// ////
|
//// ////
|
//// Description ////
|
//// Description ////
|
//// Versatile counter, a reconfigurable binary, gray or LFSR ////
|
//// Versatile counter, a reconfigurable binary, gray or LFSR ////
|
//// counter ////
|
//// counter ////
|
//// ////
|
//// ////
|
//// To Do: ////
|
//// To Do: ////
|
//// - add LFSR with more taps ////
|
//// - add LFSR with more taps ////
|
//// ////
|
//// ////
|
//// Author(s): ////
|
//// Author(s): ////
|
//// - Michael Unneback, unneback@opencores.org ////
|
//// - Michael Unneback, unneback@opencores.org ////
|
//// ORSoC AB ////
|
//// ORSoC AB ////
|
//// ////
|
//// ////
|
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
//// ////
|
//// ////
|
//// Copyright (C) 2009 Authors and OPENCORES.ORG ////
|
//// Copyright (C) 2009 Authors and OPENCORES.ORG ////
|
//// ////
|
//// ////
|
//// This source file may be used and distributed without ////
|
//// This source file may be used and distributed without ////
|
//// restriction provided that this copyright statement is not ////
|
//// restriction provided that this copyright statement is not ////
|
//// removed from the file and that any derivative work contains ////
|
//// removed from the file and that any derivative work contains ////
|
//// the original copyright notice and the associated disclaimer. ////
|
//// the original copyright notice and the associated disclaimer. ////
|
//// ////
|
//// ////
|
//// This source file is free software; you can redistribute it ////
|
//// This source file is free software; you can redistribute it ////
|
//// and/or modify it under the terms of the GNU Lesser General ////
|
//// and/or modify it under the terms of the GNU Lesser General ////
|
//// Public License as published by the Free Software Foundation; ////
|
//// Public License as published by the Free Software Foundation; ////
|
//// either version 2.1 of the License, or (at your option) any ////
|
//// either version 2.1 of the License, or (at your option) any ////
|
//// later version. ////
|
//// later version. ////
|
//// ////
|
//// ////
|
//// This source is distributed in the hope that it will be ////
|
//// This source is distributed in the hope that it will be ////
|
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
//// details. ////
|
//// details. ////
|
//// ////
|
//// ////
|
//// You should have received a copy of the GNU Lesser General ////
|
//// You should have received a copy of the GNU Lesser General ////
|
//// Public License along with this source; if not, download it ////
|
//// Public License along with this source; if not, download it ////
|
//// from http://www.opencores.org/lgpl.shtml ////
|
//// from http://www.opencores.org/lgpl.shtml ////
|
//// ////
|
//// ////
|
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
|
|
// BINARY counter
|
// BINARY counter
|
module pre_delay_counter ( cke, zq, rst, clk);
|
module pre_delay_counter ( cke, zq, rst, clk);
|
|
|
parameter length = 2;
|
parameter length = 2;
|
input cke;
|
input cke;
|
output reg zq;
|
output reg zq;
|
input rst;
|
input rst;
|
input clk;
|
input clk;
|
|
|
parameter clear_value = 0;
|
parameter clear_value = 0;
|
parameter set_value = 0;
|
parameter set_value = 0;
|
parameter wrap_value = 2;
|
parameter wrap_value = 2;
|
|
|
reg [length:1] qi;
|
reg [length:1] qi;
|
wire [length:1] q_next;
|
wire [length:1] q_next;
|
assign q_next = qi + {{length-1{1'b0}},1'b1};
|
assign q_next = qi + {{length-1{1'b0}},1'b1};
|
|
|
always @ (posedge clk or posedge rst)
|
always @ (posedge clk or posedge rst)
|
if (rst)
|
if (rst)
|
qi <= {length{1'b0}};
|
qi <= {length{1'b0}};
|
else
|
else
|
if (cke)
|
if (cke)
|
qi <= q_next;
|
qi <= q_next;
|
|
|
|
|
|
|
always @ (posedge clk or posedge rst)
|
always @ (posedge clk or posedge rst)
|
if (rst)
|
if (rst)
|
zq <= 1'b1;
|
zq <= 1'b1;
|
else
|
else
|
if (cke)
|
if (cke)
|
zq <= q_next == {length{1'b0}};
|
zq <= q_next == {length{1'b0}};
|
endmodule
|
endmodule
|
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
//// ////
|
//// ////
|
//// Versatile counter ////
|
//// Versatile counter ////
|
//// ////
|
//// ////
|
//// Description ////
|
//// Description ////
|
//// Versatile counter, a reconfigurable binary, gray or LFSR ////
|
//// Versatile counter, a reconfigurable binary, gray or LFSR ////
|
//// counter ////
|
//// counter ////
|
//// ////
|
//// ////
|
//// To Do: ////
|
//// To Do: ////
|
//// - add LFSR with more taps ////
|
//// - add LFSR with more taps ////
|
//// ////
|
//// ////
|
//// Author(s): ////
|
//// Author(s): ////
|
//// - Michael Unneback, unneback@opencores.org ////
|
//// - Michael Unneback, unneback@opencores.org ////
|
//// ORSoC AB ////
|
//// ORSoC AB ////
|
//// ////
|
//// ////
|
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
//// ////
|
//// ////
|
//// Copyright (C) 2009 Authors and OPENCORES.ORG ////
|
//// Copyright (C) 2009 Authors and OPENCORES.ORG ////
|
//// ////
|
//// ////
|
//// This source file may be used and distributed without ////
|
//// This source file may be used and distributed without ////
|
//// restriction provided that this copyright statement is not ////
|
//// restriction provided that this copyright statement is not ////
|
//// removed from the file and that any derivative work contains ////
|
//// removed from the file and that any derivative work contains ////
|
//// the original copyright notice and the associated disclaimer. ////
|
//// the original copyright notice and the associated disclaimer. ////
|
//// ////
|
//// ////
|
//// This source file is free software; you can redistribute it ////
|
//// This source file is free software; you can redistribute it ////
|
//// and/or modify it under the terms of the GNU Lesser General ////
|
//// and/or modify it under the terms of the GNU Lesser General ////
|
//// Public License as published by the Free Software Foundation; ////
|
//// Public License as published by the Free Software Foundation; ////
|
//// either version 2.1 of the License, or (at your option) any ////
|
//// either version 2.1 of the License, or (at your option) any ////
|
//// later version. ////
|
//// later version. ////
|
//// ////
|
//// ////
|
//// This source is distributed in the hope that it will be ////
|
//// This source is distributed in the hope that it will be ////
|
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
//// details. ////
|
//// details. ////
|
//// ////
|
//// ////
|
//// You should have received a copy of the GNU Lesser General ////
|
//// You should have received a copy of the GNU Lesser General ////
|
//// Public License along with this source; if not, download it ////
|
//// Public License along with this source; if not, download it ////
|
//// from http://www.opencores.org/lgpl.shtml ////
|
//// from http://www.opencores.org/lgpl.shtml ////
|
//// ////
|
//// ////
|
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
|
|
// BINARY counter
|
// BINARY counter
|
module burst_length_counter ( cke, zq, rst, clk);
|
module burst_length_counter ( cke, zq, rst, clk);
|
|
|
parameter length = 2;
|
parameter length = 2;
|
input cke;
|
input cke;
|
output reg zq;
|
output reg zq;
|
input rst;
|
input rst;
|
input clk;
|
input clk;
|
|
|
parameter clear_value = 0;
|
parameter clear_value = 0;
|
parameter set_value = 0;
|
parameter set_value = 0;
|
parameter wrap_value = 3;
|
parameter wrap_value = 3;
|
|
|
reg [length:1] qi;
|
reg [length:1] qi;
|
wire [length:1] q_next;
|
wire [length:1] q_next;
|
assign q_next = (qi == wrap_value) ? {length{1'b0}} :qi + {{length-1{1'b0}},1'b1};
|
assign q_next = (qi == wrap_value) ? {length{1'b0}} :qi + {{length-1{1'b0}},1'b1};
|
|
|
always @ (posedge clk or posedge rst)
|
always @ (posedge clk or posedge rst)
|
if (rst)
|
if (rst)
|
qi <= {length{1'b0}};
|
qi <= {length{1'b0}};
|
else
|
else
|
if (cke)
|
if (cke)
|
qi <= q_next;
|
qi <= q_next;
|
|
|
|
|
|
|
always @ (posedge clk or posedge rst)
|
always @ (posedge clk or posedge rst)
|
if (rst)
|
if (rst)
|
zq <= 1'b1;
|
zq <= 1'b1;
|
else
|
else
|
if (cke)
|
if (cke)
|
zq <= q_next == {length{1'b0}};
|
zq <= q_next == {length{1'b0}};
|
endmodule
|
endmodule
|
`timescale 1ns/1ns
|
`timescale 1ns/1ns
|
module ddr_16 (
|
module ddr_16 (
|
output reg [14:0] a,
|
output reg [14:0] a,
|
output reg adr_init,
|
output reg adr_init,
|
output reg bl_en,
|
output reg bl_en,
|
output reg [2:0] cmd,
|
output reg [2:0] cmd,
|
output reg cs_n,
|
output reg cs_n,
|
output reg [12:0] cur_row,
|
output reg [12:0] cur_row,
|
output reg fifo_re,
|
output reg fifo_re,
|
output reg read,
|
output reg read,
|
output reg ref_ack,
|
output reg ref_ack,
|
output reg ref_delay,
|
output reg ref_delay,
|
output reg state_idle,
|
output reg state_idle,
|
output reg write,
|
output reg write,
|
input wire bl_ack,
|
input wire bl_ack,
|
input wire [3:0] burst_adr,
|
input wire [3:0] burst_adr,
|
input wire clk,
|
input wire clk,
|
input wire fifo_empty,
|
input wire fifo_empty,
|
input wire fifo_re_d,
|
input wire fifo_re_d,
|
input wire [2:0] fifo_sel,
|
input wire [2:0] fifo_sel,
|
input wire ref_delay_ack,
|
input wire ref_delay_ack,
|
input wire ref_req,
|
input wire ref_req,
|
input wire rst,
|
input wire rst,
|
input wire [35:0] tx_fifo_dat_o
|
input wire [35:0] tx_fifo_dat_o
|
);
|
);
|
parameter
|
parameter
|
IDLE = 0,
|
IDLE = 0,
|
ACT_ROW = 1,
|
ACT_ROW = 1,
|
AREF = 2,
|
AREF = 2,
|
AREF_0 = 3,
|
AREF_0 = 3,
|
AREF_1 = 4,
|
AREF_1 = 4,
|
AWAIT_CMD = 5,
|
AWAIT_CMD = 5,
|
LEMR2 = 6,
|
LEMR2 = 6,
|
LEMR3 = 7,
|
LEMR3 = 7,
|
LEMR_0 = 8,
|
LEMR_0 = 8,
|
LEMR_1 = 9,
|
LEMR_1 = 9,
|
LEMR_2 = 10,
|
LEMR_2 = 10,
|
LMR_0 = 11,
|
LMR_0 = 11,
|
LMR_1 = 12,
|
LMR_1 = 12,
|
NOP0 = 13,
|
NOP0 = 13,
|
NOP1 = 14,
|
NOP1 = 14,
|
NOP10 = 15,
|
NOP10 = 15,
|
NOP11 = 16,
|
NOP11 = 16,
|
NOP12 = 17,
|
NOP12 = 17,
|
NOP14 = 18,
|
NOP14 = 18,
|
NOP15 = 19,
|
NOP15 = 19,
|
NOP2 = 20,
|
NOP2 = 20,
|
NOP20 = 21,
|
NOP20 = 21,
|
NOP21 = 22,
|
NOP21 = 22,
|
NOP22 = 23,
|
NOP22 = 23,
|
NOP3 = 24,
|
NOP3 = 24,
|
NOP30 = 25,
|
NOP30 = 25,
|
NOP31 = 26,
|
NOP31 = 26,
|
NOP32 = 27,
|
NOP32 = 27,
|
NOP4 = 28,
|
NOP4 = 28,
|
NOP5 = 29,
|
NOP5 = 29,
|
NOP6 = 30,
|
NOP6 = 30,
|
NOP7 = 31,
|
NOP7 = 31,
|
NOP8 = 32,
|
NOP8 = 32,
|
NOP9 = 33,
|
NOP9 = 33,
|
NOP_tRFC = 34,
|
NOP_tRFC = 34,
|
NOP_tWR = 35,
|
NOP_tWR = 35,
|
PRECHARGE = 36,
|
PRECHARGE = 36,
|
PRE_0 = 37,
|
PRE_0 = 37,
|
PRE_1 = 38,
|
PRE_1 = 38,
|
READ_ADDR = 39,
|
READ_ADDR = 39,
|
READ_BURST = 40,
|
READ_BURST = 40,
|
WRITE_ADDR = 41,
|
WRITE_ADDR = 41,
|
WRITE_BURST = 42;
|
WRITE_BURST = 42;
|
reg [42:0] state;
|
reg [42:0] state;
|
reg [42:0] nextstate;
|
reg [42:0] nextstate;
|
always @* begin
|
always @* begin
|
nextstate = 43'b0000000000000000000000000000000000000000000;
|
nextstate = 43'b0000000000000000000000000000000000000000000;
|
adr_init = 1'b0;
|
adr_init = 1'b0;
|
bl_en = 1'b0;
|
bl_en = 1'b0;
|
fifo_re = 1'b0;
|
fifo_re = 1'b0;
|
read = 1'b0;
|
read = 1'b0;
|
ref_ack = 1'b0;
|
ref_ack = 1'b0;
|
ref_delay = 1'b0;
|
ref_delay = 1'b0;
|
state_idle = 1'b0;
|
state_idle = 1'b0;
|
write = 1'b0;
|
write = 1'b0;
|
case (1'b1)
|
case (1'b1)
|
state[IDLE] : begin
|
state[IDLE] : begin
|
begin
|
begin
|
nextstate[NOP0] = 1'b1;
|
nextstate[NOP0] = 1'b1;
|
end
|
end
|
end
|
end
|
state[ACT_ROW] : begin
|
state[ACT_ROW] : begin
|
if (tx_fifo_dat_o[5]) begin
|
if (tx_fifo_dat_o[5]) begin
|
nextstate[NOP14] = 1'b1;
|
nextstate[NOP14] = 1'b1;
|
end
|
end
|
else begin
|
else begin
|
nextstate[NOP15] = 1'b1;
|
nextstate[NOP15] = 1'b1;
|
end
|
end
|
end
|
end
|
state[AREF] : begin
|
state[AREF] : begin
|
ref_ack = 1'b1;
|
ref_ack = 1'b1;
|
ref_delay = 1'b1;
|
ref_delay = 1'b1;
|
begin
|
begin
|
nextstate[NOP_tRFC] = 1'b1;
|
nextstate[NOP_tRFC] = 1'b1;
|
end
|
end
|
end
|
end
|
state[AREF_0] : begin
|
state[AREF_0] : begin
|
ref_ack = 1'b1;
|
ref_ack = 1'b1;
|
begin
|
begin
|
nextstate[NOP7] = 1'b1;
|
nextstate[NOP7] = 1'b1;
|
end
|
end
|
end
|
end
|
state[AREF_1] : begin
|
state[AREF_1] : begin
|
ref_ack = 1'b1;
|
ref_ack = 1'b1;
|
begin
|
begin
|
nextstate[NOP8] = 1'b1;
|
nextstate[NOP8] = 1'b1;
|
end
|
end
|
end
|
end
|
state[AWAIT_CMD] : begin
|
state[AWAIT_CMD] : begin
|
adr_init = !fifo_empty;
|
adr_init = !fifo_empty;
|
state_idle = 1'b1;
|
state_idle = 1'b1;
|
if (ref_req) begin
|
if (ref_req) begin
|
nextstate[AREF] = 1'b1;
|
nextstate[AREF] = 1'b1;
|
end
|
end
|
else if (!fifo_empty) begin
|
else if (!fifo_empty) begin
|
nextstate[NOP12] = 1'b1;
|
nextstate[NOP12] = 1'b1;
|
end
|
end
|
else begin
|
else begin
|
nextstate[AWAIT_CMD] = 1'b1;
|
nextstate[AWAIT_CMD] = 1'b1;
|
end
|
end
|
end
|
end
|
state[LEMR2] : begin
|
state[LEMR2] : begin
|
ref_ack = 1'b1;
|
ref_ack = 1'b1;
|
begin
|
begin
|
nextstate[NOP2] = 1'b1;
|
nextstate[NOP2] = 1'b1;
|
end
|
end
|
end
|
end
|
state[LEMR3] : begin
|
state[LEMR3] : begin
|
ref_ack = 1'b1;
|
ref_ack = 1'b1;
|
begin
|
begin
|
nextstate[NOP3] = 1'b1;
|
nextstate[NOP3] = 1'b1;
|
end
|
end
|
end
|
end
|
state[LEMR_0] : begin
|
state[LEMR_0] : begin
|
ref_ack = 1'b1;
|
ref_ack = 1'b1;
|
begin
|
begin
|
nextstate[NOP4] = 1'b1;
|
nextstate[NOP4] = 1'b1;
|
end
|
end
|
end
|
end
|
state[LEMR_1] : begin
|
state[LEMR_1] : begin
|
ref_ack = 1'b1;
|
ref_ack = 1'b1;
|
begin
|
begin
|
nextstate[NOP10] = 1'b1;
|
nextstate[NOP10] = 1'b1;
|
end
|
end
|
end
|
end
|
state[LEMR_2] : begin
|
state[LEMR_2] : begin
|
ref_ack = 1'b1;
|
ref_ack = 1'b1;
|
begin
|
begin
|
nextstate[NOP11] = 1'b1;
|
nextstate[NOP11] = 1'b1;
|
end
|
end
|
end
|
end
|
state[LMR_0] : begin
|
state[LMR_0] : begin
|
ref_ack = 1'b1;
|
ref_ack = 1'b1;
|
begin
|
begin
|
nextstate[NOP5] = 1'b1;
|
nextstate[NOP5] = 1'b1;
|
end
|
end
|
end
|
end
|
state[LMR_1] : begin
|
state[LMR_1] : begin
|
ref_ack = 1'b1;
|
ref_ack = 1'b1;
|
begin
|
begin
|
nextstate[NOP9] = 1'b1;
|
nextstate[NOP9] = 1'b1;
|
end
|
end
|
end
|
end
|
state[NOP0] : begin
|
state[NOP0] : begin
|
begin
|
begin
|
nextstate[PRE_0] = 1'b1;
|
nextstate[PRE_0] = 1'b1;
|
end
|
end
|
end
|
end
|
state[NOP1] : begin
|
state[NOP1] : begin
|
if (ref_req) begin
|
if (ref_req) begin
|
nextstate[LEMR2] = 1'b1;
|
nextstate[LEMR2] = 1'b1;
|
end
|
end
|
else begin
|
else begin
|
nextstate[NOP1] = 1'b1;
|
nextstate[NOP1] = 1'b1;
|
end
|
end
|
end
|
end
|
state[NOP10] : begin
|
state[NOP10] : begin
|
if (ref_req) begin
|
if (ref_req) begin
|
nextstate[LEMR_2] = 1'b1;
|
nextstate[LEMR_2] = 1'b1;
|
end
|
end
|
else begin
|
else begin
|
nextstate[NOP10] = 1'b1;
|
nextstate[NOP10] = 1'b1;
|
end
|
end
|
end
|
end
|
state[NOP11] : begin
|
state[NOP11] : begin
|
if (ref_req) begin
|
if (ref_req) begin
|
nextstate[AWAIT_CMD] = 1'b1;
|
nextstate[AWAIT_CMD] = 1'b1;
|
end
|
end
|
else begin
|
else begin
|
nextstate[NOP11] = 1'b1;
|
nextstate[NOP11] = 1'b1;
|
end
|
end
|
end
|
end
|
state[NOP12] : begin
|
state[NOP12] : begin
|
begin
|
begin
|
nextstate[ACT_ROW] = 1'b1;
|
nextstate[ACT_ROW] = 1'b1;
|
end
|
end
|
end
|
end
|
state[NOP14] : begin
|
state[NOP14] : begin
|
begin
|
begin
|
nextstate[WRITE_ADDR] = 1'b1;
|
nextstate[WRITE_ADDR] = 1'b1;
|
end
|
end
|
end
|
end
|
state[NOP15] : begin
|
state[NOP15] : begin
|
begin
|
begin
|
nextstate[READ_ADDR] = 1'b1;
|
nextstate[READ_ADDR] = 1'b1;
|
end
|
end
|
end
|
end
|
state[NOP2] : begin
|
state[NOP2] : begin
|
if (ref_req) begin
|
if (ref_req) begin
|
nextstate[LEMR3] = 1'b1;
|
nextstate[LEMR3] = 1'b1;
|
end
|
end
|
else begin
|
else begin
|
nextstate[NOP2] = 1'b1;
|
nextstate[NOP2] = 1'b1;
|
end
|
end
|
end
|
end
|
state[NOP20] : begin
|
state[NOP20] : begin
|
begin
|
begin
|
nextstate[NOP21] = 1'b1;
|
nextstate[NOP21] = 1'b1;
|
end
|
end
|
end
|
end
|
state[NOP21] : begin
|
state[NOP21] : begin
|
adr_init = 1'b1;
|
adr_init = 1'b1;
|
fifo_re = 1'b1;
|
fifo_re = 1'b1;
|
begin
|
begin
|
nextstate[NOP22] = 1'b1;
|
nextstate[NOP22] = 1'b1;
|
end
|
end
|
end
|
end
|
state[NOP22] : begin
|
state[NOP22] : begin
|
begin
|
begin
|
nextstate[NOP_tWR] = 1'b1;
|
nextstate[NOP_tWR] = 1'b1;
|
end
|
end
|
end
|
end
|
state[NOP3] : begin
|
state[NOP3] : begin
|
if (ref_req) begin
|
if (ref_req) begin
|
nextstate[LEMR_0] = 1'b1;
|
nextstate[LEMR_0] = 1'b1;
|
end
|
end
|
else begin
|
else begin
|
nextstate[NOP3] = 1'b1;
|
nextstate[NOP3] = 1'b1;
|
end
|
end
|
end
|
end
|
state[NOP30] : begin
|
state[NOP30] : begin
|
begin
|
begin
|
nextstate[NOP31] = 1'b1;
|
nextstate[NOP31] = 1'b1;
|
end
|
end
|
end
|
end
|
state[NOP31] : begin
|
state[NOP31] : begin
|
adr_init = 1'b1;
|
adr_init = 1'b1;
|
fifo_re = 1'b1;
|
fifo_re = 1'b1;
|
begin
|
begin
|
nextstate[NOP32] = 1'b1;
|
nextstate[NOP32] = 1'b1;
|
end
|
end
|
end
|
end
|
state[NOP32] : begin
|
state[NOP32] : begin
|
begin
|
begin
|
nextstate[NOP_tWR] = 1'b1;
|
nextstate[NOP_tWR] = 1'b1;
|
end
|
end
|
end
|
end
|
state[NOP4] : begin
|
state[NOP4] : begin
|
if (ref_req) begin
|
if (ref_req) begin
|
nextstate[LMR_0] = 1'b1;
|
nextstate[LMR_0] = 1'b1;
|
end
|
end
|
else begin
|
else begin
|
nextstate[NOP4] = 1'b1;
|
nextstate[NOP4] = 1'b1;
|
end
|
end
|
end
|
end
|
state[NOP5] : begin
|
state[NOP5] : begin
|
if (ref_req) begin
|
if (ref_req) begin
|
nextstate[PRE_1] = 1'b1;
|
nextstate[PRE_1] = 1'b1;
|
end
|
end
|
else begin
|
else begin
|
nextstate[NOP5] = 1'b1;
|
nextstate[NOP5] = 1'b1;
|
end
|
end
|
end
|
end
|
state[NOP6] : begin
|
state[NOP6] : begin
|
if (ref_req) begin
|
if (ref_req) begin
|
nextstate[AREF_0] = 1'b1;
|
nextstate[AREF_0] = 1'b1;
|
end
|
end
|
else begin
|
else begin
|
nextstate[NOP6] = 1'b1;
|
nextstate[NOP6] = 1'b1;
|
end
|
end
|
end
|
end
|
state[NOP7] : begin
|
state[NOP7] : begin
|
if (ref_req) begin
|
if (ref_req) begin
|
nextstate[AREF_1] = 1'b1;
|
nextstate[AREF_1] = 1'b1;
|
end
|
end
|
else begin
|
else begin
|
nextstate[NOP7] = 1'b1;
|
nextstate[NOP7] = 1'b1;
|
end
|
end
|
end
|
end
|
state[NOP8] : begin
|
state[NOP8] : begin
|
if (ref_req) begin
|
if (ref_req) begin
|
nextstate[LMR_1] = 1'b1;
|
nextstate[LMR_1] = 1'b1;
|
end
|
end
|
else begin
|
else begin
|
nextstate[NOP8] = 1'b1;
|
nextstate[NOP8] = 1'b1;
|
end
|
end
|
end
|
end
|
state[NOP9] : begin
|
state[NOP9] : begin
|
if (ref_req) begin
|
if (ref_req) begin
|
nextstate[LEMR_1] = 1'b1;
|
nextstate[LEMR_1] = 1'b1;
|
end
|
end
|
else begin
|
else begin
|
nextstate[NOP9] = 1'b1;
|
nextstate[NOP9] = 1'b1;
|
end
|
end
|
end
|
end
|
state[NOP_tRFC] : begin
|
state[NOP_tRFC] : begin
|
ref_delay = !ref_delay_ack;
|
ref_delay = !ref_delay_ack;
|
if (ref_delay_ack) begin
|
if (ref_delay_ack) begin
|
nextstate[AWAIT_CMD] = 1'b1;
|
nextstate[AWAIT_CMD] = 1'b1;
|
end
|
end
|
else begin
|
else begin
|
nextstate[NOP_tRFC] = 1'b1;
|
nextstate[NOP_tRFC] = 1'b1;
|
end
|
end
|
end
|
end
|
state[NOP_tWR] : begin
|
state[NOP_tWR] : begin
|
begin
|
begin
|
nextstate[PRECHARGE] = 1'b1;
|
nextstate[PRECHARGE] = 1'b1;
|
end
|
end
|
end
|
end
|
state[PRECHARGE] : begin
|
state[PRECHARGE] : begin
|
begin
|
begin
|
nextstate[AWAIT_CMD] = 1'b1;
|
nextstate[AWAIT_CMD] = 1'b1;
|
end
|
end
|
end
|
end
|
state[PRE_0] : begin
|
state[PRE_0] : begin
|
ref_ack = 1'b1;
|
ref_ack = 1'b1;
|
begin
|
begin
|
nextstate[NOP1] = 1'b1;
|
nextstate[NOP1] = 1'b1;
|
end
|
end
|
end
|
end
|
state[PRE_1] : begin
|
state[PRE_1] : begin
|
ref_ack = 1'b1;
|
ref_ack = 1'b1;
|
begin
|
begin
|
nextstate[NOP6] = 1'b1;
|
nextstate[NOP6] = 1'b1;
|
end
|
end
|
end
|
end
|
state[READ_ADDR] : begin
|
state[READ_ADDR] : begin
|
bl_en = 1'b1;
|
bl_en = 1'b1;
|
read = 1'b1;
|
read = 1'b1;
|
begin
|
begin
|
nextstate[READ_BURST] = 1'b1;
|
nextstate[READ_BURST] = 1'b1;
|
end
|
end
|
end
|
end
|
state[READ_BURST] : begin
|
state[READ_BURST] : begin
|
bl_en = !bl_ack;
|
bl_en = !bl_ack;
|
read = !bl_ack;
|
read = !bl_ack;
|
if (bl_ack) begin
|
if (bl_ack) begin
|
nextstate[NOP30] = 1'b1;
|
nextstate[NOP30] = 1'b1;
|
end
|
end
|
else begin
|
else begin
|
nextstate[READ_BURST] = 1'b1;
|
nextstate[READ_BURST] = 1'b1;
|
end
|
end
|
end
|
end
|
state[WRITE_ADDR] : begin
|
state[WRITE_ADDR] : begin
|
bl_en = 1'b1;
|
bl_en = 1'b1;
|
write = 1'b1;
|
write = 1'b1;
|
begin
|
begin
|
nextstate[WRITE_BURST] = 1'b1;
|
nextstate[WRITE_BURST] = 1'b1;
|
end
|
end
|
end
|
end
|
state[WRITE_BURST]: begin
|
state[WRITE_BURST]: begin
|
bl_en = !bl_ack;
|
bl_en = !bl_ack;
|
fifo_re = 1'b1;
|
fifo_re = 1'b1;
|
write = 1'b1;
|
write = 1'b1;
|
if (bl_ack) begin
|
if (bl_ack) begin
|
nextstate[NOP20] = 1'b1;
|
nextstate[NOP20] = 1'b1;
|
end
|
end
|
else begin
|
else begin
|
nextstate[WRITE_BURST] = 1'b1;
|
nextstate[WRITE_BURST] = 1'b1;
|
end
|
end
|
end
|
end
|
endcase
|
endcase
|
end
|
end
|
always @(posedge clk or posedge rst) begin
|
always @(posedge clk or posedge rst) begin
|
if (rst)
|
if (rst)
|
state <= 43'b0000000000000000000000000000000000000000001 << IDLE;
|
state <= 43'b0000000000000000000000000000000000000000001 << IDLE;
|
else
|
else
|
state <= nextstate;
|
state <= nextstate;
|
end
|
end
|
always @(posedge clk or posedge rst) begin
|
always @(posedge clk or posedge rst) begin
|
if (rst) begin
|
if (rst) begin
|
a[14:0] <= 15'd0;
|
a[14:0] <= 15'd0;
|
cmd[2:0] <= 3'b111;
|
cmd[2:0] <= 3'b111;
|
cs_n <= 1'b1;
|
cs_n <= 1'b1;
|
cur_row[12:0] <= cur_row;
|
cur_row[12:0] <= cur_row;
|
end
|
end
|
else begin
|
else begin
|
a[14:0] <= 15'd0;
|
a[14:0] <= 15'd0;
|
cmd[2:0] <= 3'b111;
|
cmd[2:0] <= 3'b111;
|
cs_n <= 1'b0;
|
cs_n <= 1'b0;
|
cur_row[12:0] <= cur_row;
|
cur_row[12:0] <= cur_row;
|
case (1'b1)
|
case (1'b1)
|
nextstate[IDLE] : begin
|
nextstate[IDLE] : begin
|
cs_n <= 1'b1;
|
cs_n <= 1'b1;
|
end
|
end
|
nextstate[ACT_ROW] : begin
|
nextstate[ACT_ROW] : begin
|
a[14:0] <= {tx_fifo_dat_o[28:27],tx_fifo_dat_o[26:14]};
|
a[14:0] <= {tx_fifo_dat_o[28:27],tx_fifo_dat_o[26:14]};
|
cmd[2:0] <= 3'b011;
|
cmd[2:0] <= 3'b011;
|
cur_row[12:0] <= tx_fifo_dat_o[26:14];
|
cur_row[12:0] <= tx_fifo_dat_o[26:14];
|
end
|
end
|
nextstate[AREF] : begin
|
nextstate[AREF] : begin
|
a[14:0] <= a;
|
a[14:0] <= a;
|
cmd[2:0] <= 3'b001;
|
cmd[2:0] <= 3'b001;
|
end
|
end
|
nextstate[AREF_0] : begin
|
nextstate[AREF_0] : begin
|
a[14:0] <= a;
|
a[14:0] <= a;
|
cmd[2:0] <= 3'b001;
|
cmd[2:0] <= 3'b001;
|
end
|
end
|
nextstate[AREF_1] : begin
|
nextstate[AREF_1] : begin
|
a[14:0] <= a;
|
a[14:0] <= a;
|
cmd[2:0] <= 3'b001;
|
cmd[2:0] <= 3'b001;
|
end
|
end
|
nextstate[AWAIT_CMD] : begin
|
nextstate[AWAIT_CMD] : begin
|
a[14:0] <= a;
|
a[14:0] <= a;
|
cs_n <= 1'b1;
|
cs_n <= 1'b1;
|
end
|
end
|
nextstate[LEMR2] : begin
|
nextstate[LEMR2] : begin
|
a[14:0] <= {2'b10,5'b00000,1'b0,7'b0000000};
|
a[14:0] <= {2'b10,5'b00000,1'b0,7'b0000000};
|
cmd[2:0] <= 3'b000;
|
cmd[2:0] <= 3'b000;
|
end
|
end
|
nextstate[LEMR3] : begin
|
nextstate[LEMR3] : begin
|
a[14:0] <= {2'b11,13'b0000000000000};
|
a[14:0] <= {2'b11,13'b0000000000000};
|
cmd[2:0] <= 3'b000;
|
cmd[2:0] <= 3'b000;
|
end
|
end
|
nextstate[LEMR_0] : begin
|
nextstate[LEMR_0] : begin
|
a[14:0] <= {2'b01,1'b0,1'b0,1'b0,3'b000,1'b0,3'b000,1'b0,1'b0,1'b0};
|
a[14:0] <= {2'b01,1'b0,1'b0,1'b0,3'b000,1'b0,3'b000,1'b0,1'b0,1'b0};
|
cmd[2:0] <= 3'b000;
|
cmd[2:0] <= 3'b000;
|
end
|
end
|
nextstate[LEMR_1] : begin
|
nextstate[LEMR_1] : begin
|
a[14:0] <= {2'b01,1'b0,1'b0,1'b0,3'b111,1'b0,3'b000,1'b0,1'b0,1'b0};
|
a[14:0] <= {2'b01,1'b0,1'b0,1'b0,3'b111,1'b0,3'b000,1'b0,1'b0,1'b0};
|
cmd[2:0] <= 3'b000;
|
cmd[2:0] <= 3'b000;
|
end
|
end
|
nextstate[LEMR_2] : begin
|
nextstate[LEMR_2] : begin
|
a[14:0] <= {2'b01,1'b0,1'b0,1'b0,3'b000,1'b0,3'b000,1'b0,1'b0,1'b0};
|
a[14:0] <= {2'b01,1'b0,1'b0,1'b0,3'b000,1'b0,3'b000,1'b0,1'b0,1'b0};
|
cmd[2:0] <= 3'b000;
|
cmd[2:0] <= 3'b000;
|
end
|
end
|
nextstate[LMR_0] : begin
|
nextstate[LMR_0] : begin
|
a[14:0] <= {2'b00,1'b0,3'b001,1'b1,1'b0,3'b100,1'b0,3'b011};
|
a[14:0] <= {2'b00,1'b0,3'b001,1'b1,1'b0,3'b100,1'b0,3'b011};
|
cmd[2:0] <= 3'b000;
|
cmd[2:0] <= 3'b000;
|
end
|
end
|
nextstate[LMR_1] : begin
|
nextstate[LMR_1] : begin
|
a[14:0] <= {2'b00,1'b0,3'b001,1'b0,1'b0,3'b100,1'b0,3'b011};
|
a[14:0] <= {2'b00,1'b0,3'b001,1'b0,1'b0,3'b100,1'b0,3'b011};
|
cmd[2:0] <= 3'b000;
|
cmd[2:0] <= 3'b000;
|
end
|
end
|
nextstate[NOP0] : begin
|
nextstate[NOP0] : begin
|
a[14:0] <= a;
|
a[14:0] <= a;
|
end
|
end
|
nextstate[NOP1] : begin
|
nextstate[NOP1] : begin
|
a[14:0] <= a;
|
a[14:0] <= a;
|
end
|
end
|
nextstate[NOP10] : begin
|
nextstate[NOP10] : begin
|
a[14:0] <= a;
|
a[14:0] <= a;
|
end
|
end
|
nextstate[NOP11] : begin
|
nextstate[NOP11] : begin
|
a[14:0] <= a;
|
a[14:0] <= a;
|
end
|
end
|
nextstate[NOP14] : begin
|
nextstate[NOP14] : begin
|
a[14:0] <= a;
|
a[14:0] <= a;
|
end
|
end
|
nextstate[NOP15] : begin
|
nextstate[NOP15] : begin
|
a[14:0] <= a;
|
a[14:0] <= a;
|
end
|
end
|
nextstate[NOP2] : begin
|
nextstate[NOP2] : begin
|
a[14:0] <= a;
|
a[14:0] <= a;
|
end
|
end
|
nextstate[NOP20] : begin
|
nextstate[NOP20] : begin
|
a[14:0] <= a;
|
a[14:0] <= a;
|
end
|
end
|
nextstate[NOP21] : begin
|
nextstate[NOP21] : begin
|
a[14:0] <= a;
|
a[14:0] <= a;
|
end
|
end
|
nextstate[NOP22] : begin
|
nextstate[NOP22] : begin
|
a[14:0] <= a;
|
a[14:0] <= a;
|
end
|
end
|
nextstate[NOP3] : begin
|
nextstate[NOP3] : begin
|
a[14:0] <= a;
|
a[14:0] <= a;
|
end
|
end
|
nextstate[NOP30] : begin
|
nextstate[NOP30] : begin
|
a[14:0] <= a;
|
a[14:0] <= a;
|
end
|
end
|
nextstate[NOP31] : begin
|
nextstate[NOP31] : begin
|
a[14:0] <= a;
|
a[14:0] <= a;
|
end
|
end
|
nextstate[NOP32] : begin
|
nextstate[NOP32] : begin
|
a[14:0] <= a;
|
a[14:0] <= a;
|
end
|
end
|
nextstate[NOP4] : begin
|
nextstate[NOP4] : begin
|
a[14:0] <= a;
|
a[14:0] <= a;
|
end
|
end
|
nextstate[NOP5] : begin
|
nextstate[NOP5] : begin
|
a[14:0] <= a;
|
a[14:0] <= a;
|
end
|
end
|
nextstate[NOP6] : begin
|
nextstate[NOP6] : begin
|
a[14:0] <= a;
|
a[14:0] <= a;
|
end
|
end
|
nextstate[NOP7] : begin
|
nextstate[NOP7] : begin
|
a[14:0] <= a;
|
a[14:0] <= a;
|
end
|
end
|
nextstate[NOP8] : begin
|
nextstate[NOP8] : begin
|
a[14:0] <= a;
|
a[14:0] <= a;
|
end
|
end
|
nextstate[NOP9] : begin
|
nextstate[NOP9] : begin
|
a[14:0] <= a;
|
a[14:0] <= a;
|
end
|
end
|
nextstate[NOP_tRFC] : begin
|
nextstate[NOP_tRFC] : begin
|
a[14:0] <= a;
|
a[14:0] <= a;
|
end
|
end
|
nextstate[NOP_tWR] : begin
|
nextstate[NOP_tWR] : begin
|
a[14:0] <= a;
|
a[14:0] <= a;
|
end
|
end
|
nextstate[PRECHARGE] : begin
|
nextstate[PRECHARGE] : begin
|
a[14:0] <= {2'b00,13'b0010000000000};
|
a[14:0] <= {2'b00,13'b0010000000000};
|
cmd[2:0] <= 3'b010;
|
cmd[2:0] <= 3'b010;
|
end
|
end
|
nextstate[PRE_0] : begin
|
nextstate[PRE_0] : begin
|
a[14:0] <= {2'b00,13'b0010000000000};
|
a[14:0] <= {2'b00,13'b0010000000000};
|
cmd[2:0] <= 3'b010;
|
cmd[2:0] <= 3'b010;
|
end
|
end
|
nextstate[PRE_1] : begin
|
nextstate[PRE_1] : begin
|
a[14:0] <= {2'b00,13'b0010000000000};
|
a[14:0] <= {2'b00,13'b0010000000000};
|
cmd[2:0] <= 3'b010;
|
cmd[2:0] <= 3'b010;
|
end
|
end
|
nextstate[READ_ADDR] : begin
|
nextstate[READ_ADDR] : begin
|
a[14:0] <= {tx_fifo_dat_o[28:27],{4'b0000,tx_fifo_dat_o[13:10],burst_adr,1'b0}};
|
a[14:0] <= {tx_fifo_dat_o[28:27],{4'b0000,tx_fifo_dat_o[13:10],burst_adr,1'b0}};
|
cmd[2:0] <= 3'b101;
|
cmd[2:0] <= 3'b101;
|
end
|
end
|
nextstate[READ_BURST] : begin
|
nextstate[READ_BURST] : begin
|
a[14:0] <= a;
|
a[14:0] <= a;
|
end
|
end
|
nextstate[WRITE_ADDR] : begin
|
nextstate[WRITE_ADDR] : begin
|
a[14:0] <= {tx_fifo_dat_o[28:27],{4'b0000,tx_fifo_dat_o[13:10],burst_adr,1'b0}};
|
a[14:0] <= {tx_fifo_dat_o[28:27],{4'b0000,tx_fifo_dat_o[13:10],burst_adr,1'b0}};
|
cmd[2:0] <= 3'b100;
|
cmd[2:0] <= 3'b100;
|
end
|
end
|
nextstate[WRITE_BURST]: begin
|
nextstate[WRITE_BURST]: begin
|
a[14:0] <= a;
|
a[14:0] <= a;
|
end
|
end
|
endcase
|
endcase
|
end
|
end
|
end
|
end
|
reg [87:0] statename;
|
reg [87:0] statename;
|
always @* begin
|
always @* begin
|
case (1'b1)
|
case (1'b1)
|
state[IDLE] :
|
state[IDLE] :
|
statename = "IDLE";
|
statename = "IDLE";
|
state[ACT_ROW] :
|
state[ACT_ROW] :
|
statename = "ACT_ROW";
|
statename = "ACT_ROW";
|
state[AREF] :
|
state[AREF] :
|
statename = "AREF";
|
statename = "AREF";
|
state[AREF_0] :
|
state[AREF_0] :
|
statename = "AREF_0";
|
statename = "AREF_0";
|
state[AREF_1] :
|
state[AREF_1] :
|
statename = "AREF_1";
|
statename = "AREF_1";
|
state[AWAIT_CMD] :
|
state[AWAIT_CMD] :
|
statename = "AWAIT_CMD";
|
statename = "AWAIT_CMD";
|
state[LEMR2] :
|
state[LEMR2] :
|
statename = "LEMR2";
|
statename = "LEMR2";
|
state[LEMR3] :
|
state[LEMR3] :
|
statename = "LEMR3";
|
statename = "LEMR3";
|
state[LEMR_0] :
|
state[LEMR_0] :
|
statename = "LEMR_0";
|
statename = "LEMR_0";
|
state[LEMR_1] :
|
state[LEMR_1] :
|
statename = "LEMR_1";
|
statename = "LEMR_1";
|
state[LEMR_2] :
|
state[LEMR_2] :
|
statename = "LEMR_2";
|
statename = "LEMR_2";
|
state[LMR_0] :
|
state[LMR_0] :
|
statename = "LMR_0";
|
statename = "LMR_0";
|
state[LMR_1] :
|
state[LMR_1] :
|
statename = "LMR_1";
|
statename = "LMR_1";
|
state[NOP0] :
|
state[NOP0] :
|
statename = "NOP0";
|
statename = "NOP0";
|
state[NOP1] :
|
state[NOP1] :
|
statename = "NOP1";
|
statename = "NOP1";
|
state[NOP10] :
|
state[NOP10] :
|
statename = "NOP10";
|
statename = "NOP10";
|
state[NOP11] :
|
state[NOP11] :
|
statename = "NOP11";
|
statename = "NOP11";
|
state[NOP12] :
|
state[NOP12] :
|
statename = "NOP12";
|
statename = "NOP12";
|
state[NOP14] :
|
state[NOP14] :
|
statename = "NOP14";
|
statename = "NOP14";
|
state[NOP15] :
|
state[NOP15] :
|
statename = "NOP15";
|
statename = "NOP15";
|
state[NOP2] :
|
state[NOP2] :
|
statename = "NOP2";
|
statename = "NOP2";
|
state[NOP20] :
|
state[NOP20] :
|
statename = "NOP20";
|
statename = "NOP20";
|
state[NOP21] :
|
state[NOP21] :
|
statename = "NOP21";
|
statename = "NOP21";
|
state[NOP22] :
|
state[NOP22] :
|
statename = "NOP22";
|
statename = "NOP22";
|
state[NOP3] :
|
state[NOP3] :
|
statename = "NOP3";
|
statename = "NOP3";
|
state[NOP30] :
|
state[NOP30] :
|
statename = "NOP30";
|
statename = "NOP30";
|
state[NOP31] :
|
state[NOP31] :
|
statename = "NOP31";
|
statename = "NOP31";
|
state[NOP32] :
|
state[NOP32] :
|
statename = "NOP32";
|
statename = "NOP32";
|
state[NOP4] :
|
state[NOP4] :
|
statename = "NOP4";
|
statename = "NOP4";
|
state[NOP5] :
|
state[NOP5] :
|
statename = "NOP5";
|
statename = "NOP5";
|
state[NOP6] :
|
state[NOP6] :
|
statename = "NOP6";
|
statename = "NOP6";
|
state[NOP7] :
|
state[NOP7] :
|
statename = "NOP7";
|
statename = "NOP7";
|
state[NOP8] :
|
state[NOP8] :
|
statename = "NOP8";
|
statename = "NOP8";
|
state[NOP9] :
|
state[NOP9] :
|
statename = "NOP9";
|
statename = "NOP9";
|
state[NOP_tRFC] :
|
state[NOP_tRFC] :
|
statename = "NOP_tRFC";
|
statename = "NOP_tRFC";
|
state[NOP_tWR] :
|
state[NOP_tWR] :
|
statename = "NOP_tWR";
|
statename = "NOP_tWR";
|
state[PRECHARGE] :
|
state[PRECHARGE] :
|
statename = "PRECHARGE";
|
statename = "PRECHARGE";
|
state[PRE_0] :
|
state[PRE_0] :
|
statename = "PRE_0";
|
statename = "PRE_0";
|
state[PRE_1] :
|
state[PRE_1] :
|
statename = "PRE_1";
|
statename = "PRE_1";
|
state[READ_ADDR] :
|
state[READ_ADDR] :
|
statename = "READ_ADDR";
|
statename = "READ_ADDR";
|
state[READ_BURST] :
|
state[READ_BURST] :
|
statename = "READ_BURST";
|
statename = "READ_BURST";
|
state[WRITE_ADDR] :
|
state[WRITE_ADDR] :
|
statename = "WRITE_ADDR";
|
statename = "WRITE_ADDR";
|
state[WRITE_BURST]:
|
state[WRITE_BURST]:
|
statename = "WRITE_BURST";
|
statename = "WRITE_BURST";
|
default :
|
default :
|
statename = "XXXXXXXXXXX";
|
statename = "XXXXXXXXXXX";
|
endcase
|
endcase
|
end
|
end
|
endmodule
|
endmodule
|
module fsm_wb (
|
module fsm_wb (
|
stall_i, stall_o,
|
stall_i, stall_o,
|
we_i, cti_i, bte_i, stb_i, cyc_i, ack_o,
|
we_i, cti_i, bte_i, stb_i, cyc_i, ack_o,
|
egress_fifo_we, egress_fifo_full,
|
egress_fifo_we, egress_fifo_full,
|
ingress_fifo_re, ingress_fifo_empty,
|
ingress_fifo_re, ingress_fifo_empty,
|
state_idle,
|
state_idle,
|
sdram_burst_reading,
|
sdram_burst_reading,
|
debug_state,
|
debug_state,
|
wb_clk, wb_rst
|
wb_clk, wb_rst
|
);
|
);
|
|
|
input stall_i;
|
input stall_i;
|
output stall_o;
|
output stall_o;
|
|
|
input [2:0] cti_i;
|
input [2:0] cti_i;
|
input [1:0] bte_i;
|
input [1:0] bte_i;
|
input we_i, stb_i, cyc_i;
|
input we_i, stb_i, cyc_i;
|
output ack_o;
|
output ack_o;
|
output egress_fifo_we, ingress_fifo_re;
|
output egress_fifo_we, ingress_fifo_re;
|
input egress_fifo_full, ingress_fifo_empty;
|
input egress_fifo_full, ingress_fifo_empty;
|
input sdram_burst_reading;
|
input sdram_burst_reading;
|
output state_idle;
|
output state_idle;
|
input wb_clk, wb_rst;
|
input wb_clk, wb_rst;
|
output [1:0] debug_state;
|
output [1:0] debug_state;
|
|
|
|
|
|
|
reg ingress_fifo_read_reg;
|
reg ingress_fifo_read_reg;
|
|
|
// bte
|
// bte
|
parameter linear = 2'b00;
|
parameter linear = 2'b00;
|
parameter wrap4 = 2'b01;
|
parameter wrap4 = 2'b01;
|
parameter wrap8 = 2'b10;
|
parameter wrap8 = 2'b10;
|
parameter wrap16 = 2'b11;
|
parameter wrap16 = 2'b11;
|
// cti
|
// cti
|
parameter classic = 3'b000;
|
parameter classic = 3'b000;
|
parameter endofburst = 3'b111;
|
parameter endofburst = 3'b111;
|
|
|
parameter idle = 2'b00;
|
parameter idle = 2'b00;
|
parameter rd = 2'b01;
|
parameter rd = 2'b01;
|
parameter wr = 2'b10;
|
parameter wr = 2'b10;
|
parameter fe = 2'b11;
|
parameter fe = 2'b11;
|
reg [1:0] state;
|
reg [1:0] state;
|
|
|
assign debug_state = state;
|
assign debug_state = state;
|
|
|
|
|
reg sdram_burst_reading_1, sdram_burst_reading_2;
|
reg sdram_burst_reading_1, sdram_burst_reading_2;
|
wire sdram_burst_reading_wb_clk;
|
wire sdram_burst_reading_wb_clk;
|
|
|
|
|
always @ (posedge wb_clk or posedge wb_rst)
|
always @ (posedge wb_clk or posedge wb_rst)
|
if (wb_rst)
|
if (wb_rst)
|
state <= idle;
|
state <= idle;
|
else
|
else
|
case (state)
|
case (state)
|
idle:
|
idle:
|
if (we_i & stb_i & cyc_i & !egress_fifo_full & !stall_i)
|
if (we_i & stb_i & cyc_i & !egress_fifo_full & !stall_i)
|
state <= wr;
|
state <= wr;
|
else if (!we_i & stb_i & cyc_i & !egress_fifo_full & !stall_i)
|
else if (!we_i & stb_i & cyc_i & !egress_fifo_full & !stall_i)
|
state <= rd;
|
state <= rd;
|
wr:
|
wr:
|
if ((cti_i==classic | cti_i==endofburst | bte_i==linear) &
|
if ((cti_i==classic | cti_i==endofburst | bte_i==linear) &
|
stb_i & cyc_i & !egress_fifo_full & !stall_i)
|
stb_i & cyc_i & !egress_fifo_full & !stall_i)
|
state <= idle;
|
state <= idle;
|
rd:
|
rd:
|
if ((cti_i==classic | cti_i==endofburst | bte_i==linear) &
|
if ((cti_i==classic | cti_i==endofburst | bte_i==linear) &
|
stb_i & cyc_i & ack_o)
|
stb_i & cyc_i & ack_o)
|
state <= fe;
|
state <= fe;
|
fe:
|
fe:
|
if (ingress_fifo_empty & !sdram_burst_reading_wb_clk)
|
if (ingress_fifo_empty & !sdram_burst_reading_wb_clk)
|
state <= idle;
|
state <= idle;
|
default: ;
|
default: ;
|
endcase
|
endcase
|
|
|
assign state_idle = (state==idle);
|
assign state_idle = (state==idle);
|
|
|
assign stall_o = (stall_i) ? 1'b1 :
|
assign stall_o = (stall_i) ? 1'b1 :
|
(state==idle & stb_i & cyc_i & !egress_fifo_full) ? 1'b1 :
|
(state==idle & stb_i & cyc_i & !egress_fifo_full) ? 1'b1 :
|
(state==wr & stb_i & cyc_i & !egress_fifo_full) ? 1'b1 :
|
(state==wr & stb_i & cyc_i & !egress_fifo_full) ? 1'b1 :
|
(state==rd & stb_i & cyc_i & !ingress_fifo_empty) ? 1'b1 :
|
(state==rd & stb_i & cyc_i & !ingress_fifo_empty) ? 1'b1 :
|
(state==fe & !ingress_fifo_empty) ? 1'b1 :
|
(state==fe & !ingress_fifo_empty) ? 1'b1 :
|
1'b0;
|
1'b0;
|
|
|
assign egress_fifo_we = (state==idle & stb_i & cyc_i & !egress_fifo_full & !stall_i) ? 1'b1 :
|
assign egress_fifo_we = (state==idle & stb_i & cyc_i & !egress_fifo_full & !stall_i) ? 1'b1 :
|
(state==wr & stb_i & cyc_i & !egress_fifo_full & !stall_i) ? 1'b1 :
|
(state==wr & stb_i & cyc_i & !egress_fifo_full & !stall_i) ? 1'b1 :
|
1'b0;
|
1'b0;
|
|
|
assign ingress_fifo_re = (state==rd & stb_i & cyc_i & !ingress_fifo_empty & !stall_i) ? 1'b1 :
|
assign ingress_fifo_re = (state==rd & stb_i & cyc_i & !ingress_fifo_empty & !stall_i) ? 1'b1 :
|
(state==fe & !ingress_fifo_empty & !stall_i) ? 1'b1:
|
(state==fe & !ingress_fifo_empty & !stall_i) ? 1'b1:
|
1'b0;
|
1'b0;
|
|
|
always @ (posedge wb_clk or posedge wb_rst)
|
always @ (posedge wb_clk or posedge wb_rst)
|
if (wb_rst)
|
if (wb_rst)
|
ingress_fifo_read_reg <= 1'b0;
|
ingress_fifo_read_reg <= 1'b0;
|
else
|
else
|
ingress_fifo_read_reg <= ingress_fifo_re;
|
ingress_fifo_read_reg <= ingress_fifo_re;
|
|
|
/*assign ack_o = (ingress_fifo_read_reg & stb_i) ? 1'b1 :
|
/*assign ack_o = (ingress_fifo_read_reg & stb_i) ? 1'b1 :
|
(state==fe) ? 1'b0 :
|
(state==fe) ? 1'b0 :
|
(state==wr & stb_i & cyc_i & !egress_fifo_full & !stall_i) ? 1'b1 :
|
(state==wr & stb_i & cyc_i & !egress_fifo_full & !stall_i) ? 1'b1 :
|
1'b0;*/
|
1'b0;*/
|
|
|
assign ack_o = !(state==fe) & ((ingress_fifo_read_reg & stb_i) | (state==wr & stb_i & cyc_i & !egress_fifo_full & !stall_i));
|
assign ack_o = !(state==fe) & ((ingress_fifo_read_reg & stb_i) | (state==wr & stb_i & cyc_i & !egress_fifo_full & !stall_i));
|
|
|
|
|
// Sample the SDRAM burst reading signal in WB domain
|
// Sample the SDRAM burst reading signal in WB domain
|
always @(posedge wb_clk)
|
always @(posedge wb_clk)
|
sdram_burst_reading_1 <= sdram_burst_reading;
|
sdram_burst_reading_1 <= sdram_burst_reading;
|
|
|
always @(posedge wb_clk)
|
always @(posedge wb_clk)
|
sdram_burst_reading_2 <= sdram_burst_reading_1;
|
sdram_burst_reading_2 <= sdram_burst_reading_1;
|
|
|
assign sdram_burst_reading_wb_clk = sdram_burst_reading_2;
|
assign sdram_burst_reading_wb_clk = sdram_burst_reading_2;
|
|
|
endmodule`timescale 1ns/1ns
|
endmodule`timescale 1ns/1ns
|
module delay (d, q, clk, rst);
|
module delay (d, q, clk, rst);
|
|
|
parameter width = 4;
|
parameter width = 4;
|
parameter depth = 3;
|
parameter depth = 3;
|
|
|
input [width-1:0] d;
|
input [width-1:0] d;
|
output [width-1:0] q;
|
output [width-1:0] q;
|
input clk;
|
input clk;
|
input rst;
|
input rst;
|
|
|
reg [width-1:0] dffs [1:depth];
|
reg [width-1:0] dffs [1:depth];
|
|
|
integer i;
|
integer i;
|
|
|
always @ (posedge clk or posedge rst)
|
always @ (posedge clk or posedge rst)
|
if (rst)
|
if (rst)
|
for ( i=1; i <= depth; i=i+1)
|
for ( i=1; i <= depth; i=i+1)
|
dffs[i] <= {width{1'b0}};
|
dffs[i] <= {width{1'b0}};
|
else
|
else
|
begin
|
begin
|
dffs[1] <= d;
|
dffs[1] <= d;
|
for ( i=2; i <= depth; i=i+1 )
|
for ( i=2; i <= depth; i=i+1 )
|
dffs[i] <= dffs[i-1];
|
dffs[i] <= dffs[i-1];
|
end
|
end
|
|
|
assign q = dffs[depth];
|
assign q = dffs[depth];
|
|
|
endmodule //delay
|
endmodule //delay
|
|
|
|
|
`include "versatile_mem_ctrl_defines.v"
|
`include "versatile_mem_ctrl_defines.v"
|
|
|
module ddr_ff_in
|
module ddr_ff_in
|
(
|
(
|
input C0, // clock
|
input C0, // clock
|
input C1, // clock
|
input C1, // clock
|
input D, // data input
|
input D, // data input
|
input CE, // clock enable
|
input CE, // clock enable
|
output Q0, // data output
|
output Q0, // data output
|
output Q1, // data output
|
output Q1, // data output
|
input R, // reset
|
input R, // reset
|
input S // set
|
input S // set
|
);
|
);
|
|
|
`ifdef XILINX
|
`ifdef XILINX
|
IDDR2 #(
|
IDDR2 #(
|
.DDR_ALIGNMENT("NONE"),
|
.DDR_ALIGNMENT("NONE"),
|
.INIT_Q0(1'b0),
|
.INIT_Q0(1'b0),
|
.INIT_Q1(1'b0),
|
.INIT_Q1(1'b0),
|
.SRTYPE("SYNC"))
|
.SRTYPE("SYNC"))
|
IDDR2_inst (
|
IDDR2_inst (
|
.Q0(Q0),
|
.Q0(Q0),
|
.Q1(Q1),
|
.Q1(Q1),
|
.C0(C0),
|
.C0(C0),
|
.C1(C1),
|
.C1(C1),
|
.CE(CE),
|
.CE(CE),
|
.D(D),
|
.D(D),
|
.R(R),
|
.R(R),
|
.S(S)
|
.S(S)
|
);
|
);
|
`endif // XILINX
|
`endif // XILINX
|
|
|
`ifdef ALTERA
|
`ifdef ALTERA
|
altddio_in #(
|
altddio_in #(
|
.WIDTH(1),
|
.WIDTH(1),
|
.POWER_UP_HIGH("OFF"),
|
.POWER_UP_HIGH("OFF"),
|
.INTENDED_DEVICE_FAMILY("Stratix III"))
|
.INTENDED_DEVICE_FAMILY("Stratix III"))
|
altddio_in_inst (
|
altddio_in_inst (
|
.aset(),
|
.aset(),
|
.datain(D),
|
.datain(D),
|
.inclocken(CE),
|
.inclocken(CE),
|
.inclock(C0),
|
.inclock(C0),
|
.aclr(R),
|
.aclr(R),
|
.dataout_h(Q0),
|
.dataout_h(Q0),
|
.dataout_l(Q1)
|
.dataout_l(Q1)
|
);
|
);
|
`endif // ALTERA
|
`endif // ALTERA
|
|
|
`ifdef GENERIC_PRIMITIVES
|
`ifdef GENERIC_PRIMITIVES
|
reg Q0_i, Q1_i;
|
reg Q0_i, Q1_i;
|
always @ (posedge R or posedge C0)
|
always @ (posedge R or posedge C0)
|
if (R)
|
if (R)
|
Q0_i <= 1'b0;
|
Q0_i <= 1'b0;
|
else
|
else
|
Q0_i <= D;
|
Q0_i <= D;
|
|
|
assign Q0 = Q0_i;
|
assign Q0 = Q0_i;
|
|
|
always @ (posedge R or posedge C1)
|
always @ (posedge R or posedge C1)
|
if (R)
|
if (R)
|
Q1_i <= 1'b0;
|
Q1_i <= 1'b0;
|
else
|
else
|
Q1_i <= D;
|
Q1_i <= D;
|
|
|
assign Q1 = Q1_i;
|
assign Q1 = Q1_i;
|
`endif // GENERIC_PRIMITIVES
|
`endif // GENERIC_PRIMITIVES
|
|
|
endmodule // ddr_ff_in
|
endmodule // ddr_ff_in
|
|
|
|
|
module ddr_ff_out
|
module ddr_ff_out
|
(
|
(
|
input C0, // clock
|
input C0, // clock
|
input C1, // clock
|
input C1, // clock
|
input D0, // data input
|
input D0, // data input
|
input D1, // data input
|
input D1, // data input
|
input CE, // clock enable
|
input CE, // clock enable
|
output Q, // data output
|
output Q, // data output
|
input R, // reset
|
input R, // reset
|
input S // set
|
input S // set
|
);
|
);
|
|
|
`ifdef XILINX
|
`ifdef XILINX
|
ODDR2 #(
|
ODDR2 #(
|
.DDR_ALIGNMENT("NONE"),
|
.DDR_ALIGNMENT("NONE"),
|
.INIT(1'b0),
|
.INIT(1'b0),
|
.SRTYPE("SYNC"))
|
.SRTYPE("SYNC"))
|
ODDR2_inst (
|
ODDR2_inst (
|
.Q(Q),
|
.Q(Q),
|
.C0(C0),
|
.C0(C0),
|
.C1(C1),
|
.C1(C1),
|
.CE(CE),
|
.CE(CE),
|
.D0(D0),
|
.D0(D0),
|
.D1(D1),
|
.D1(D1),
|
.R(R),
|
.R(R),
|
.S(S)
|
.S(S)
|
);
|
);
|
`endif // XILINX
|
`endif // XILINX
|
|
|
`ifdef ALTERA
|
`ifdef ALTERA
|
altddio_out #(
|
altddio_out #(
|
.WIDTH(1),
|
.WIDTH(1),
|
.POWER_UP_HIGH("OFF"),
|
.POWER_UP_HIGH("OFF"),
|
.INTENDED_DEVICE_FAMILY("Stratix III"),
|
.INTENDED_DEVICE_FAMILY("Stratix III"),
|
.OE_REG("UNUSED"))
|
.OE_REG("UNUSED"))
|
altddio_out_inst (
|
altddio_out_inst (
|
.aset(),
|
.aset(),
|
.datain_h(D0),
|
.datain_h(D0),
|
.datain_l(D1),
|
.datain_l(D1),
|
.outclocken(CE),
|
.outclocken(CE),
|
.outclock(C0),
|
.outclock(C0),
|
.aclr(R),
|
.aclr(R),
|
.dataout(Q)
|
.dataout(Q)
|
);
|
);
|
`endif // ALTERA
|
`endif // ALTERA
|
|
|
`ifdef GENERIC_PRIMITIVES
|
`ifdef GENERIC_PRIMITIVES
|
reg Q0, Q1;
|
reg Q0, Q1;
|
always @ (posedge R or posedge C0)
|
always @ (posedge R or posedge C0)
|
if (R)
|
if (R)
|
Q0 <= 1'b0;
|
Q0 <= 1'b0;
|
else
|
else
|
Q0 <= D0;
|
Q0 <= D0;
|
|
|
always @ (posedge R or posedge C1)
|
always @ (posedge R or posedge C1)
|
if (R)
|
if (R)
|
Q1 <= 1'b0;
|
Q1 <= 1'b0;
|
else
|
else
|
Q1 <= D1;
|
Q1 <= D1;
|
|
|
assign Q = C0 ? Q0 : Q1;
|
assign Q = C0 ? Q0 : Q1;
|
`endif // GENERIC_PRIMITIVES
|
`endif // GENERIC_PRIMITIVES
|
|
|
endmodule // ddr_ff_out
|
endmodule // ddr_ff_out
|
|
|
`include "versatile_mem_ctrl_defines.v"
|
`include "versatile_mem_ctrl_defines.v"
|
|
|
module dcm_pll
|
module dcm_pll
|
(
|
(
|
input rst, // reset
|
input rst, // reset
|
input clk_in, // clock in
|
input clk_in, // clock in
|
input clkfb_in, // feedback clock in
|
input clkfb_in, // feedback clock in
|
output clk0_out, // clock out
|
output clk0_out, // clock out
|
output clk90_out, // clock out, 90 degree phase shift
|
output clk90_out, // clock out, 90 degree phase shift
|
output clk180_out, // clock out, 180 degree phase shift
|
output clk180_out, // clock out, 180 degree phase shift
|
output clk270_out, // clock out, 270 degree phase shift
|
output clk270_out, // clock out, 270 degree phase shift
|
output clkfb_out // feedback clock out
|
output clkfb_out // feedback clock out
|
);
|
);
|
|
|
`ifdef XILINX
|
`ifdef XILINX
|
wire clk_in_ibufg;
|
wire clk_in_ibufg;
|
wire clk0_bufg, clk90_bufg, clk180_bufg, clk270_bufg;
|
wire clk0_bufg, clk90_bufg, clk180_bufg, clk270_bufg;
|
// DCM with internal feedback
|
// DCM with internal feedback
|
DCM #(
|
DCM #(
|
.CLKDV_DIVIDE(2.0),
|
.CLKDV_DIVIDE(2.0),
|
.CLKFX_DIVIDE(1),
|
.CLKFX_DIVIDE(1),
|
.CLKFX_MULTIPLY(4),
|
.CLKFX_MULTIPLY(4),
|
.CLKIN_DIVIDE_BY_2("FALSE"),
|
.CLKIN_DIVIDE_BY_2("FALSE"),
|
.CLKIN_PERIOD(8.0),
|
.CLKIN_PERIOD(8.0),
|
.CLKOUT_PHASE_SHIFT("NONE"),
|
.CLKOUT_PHASE_SHIFT("NONE"),
|
.CLK_FEEDBACK("1X"),
|
.CLK_FEEDBACK("1X"),
|
.DESKEW_ADJUST("SYSTEM_SYNCHRONOUS"),
|
.DESKEW_ADJUST("SYSTEM_SYNCHRONOUS"),
|
.DLL_FREQUENCY_MODE("LOW"),
|
.DLL_FREQUENCY_MODE("LOW"),
|
.DUTY_CYCLE_CORRECTION("TRUE"),
|
.DUTY_CYCLE_CORRECTION("TRUE"),
|
.PHASE_SHIFT(0),
|
.PHASE_SHIFT(0),
|
.STARTUP_WAIT("FALSE"))
|
.STARTUP_WAIT("FALSE"))
|
DCM_internal (
|
DCM_internal (
|
.CLK0(clk0_bufg),
|
.CLK0(clk0_bufg),
|
.CLK180(clk180_bufg),
|
.CLK180(clk180_bufg),
|
.CLK270(clk270_bufg),
|
.CLK270(clk270_bufg),
|
.CLK2X(),
|
.CLK2X(),
|
.CLK2X180(),
|
.CLK2X180(),
|
.CLK90(clk90_bufg),
|
.CLK90(clk90_bufg),
|
.CLKDV(),
|
.CLKDV(),
|
.CLKFX(),
|
.CLKFX(),
|
.CLKFX180(),
|
.CLKFX180(),
|
.LOCKED(),
|
.LOCKED(),
|
.PSDONE(),
|
.PSDONE(),
|
.STATUS(),
|
.STATUS(),
|
.CLKFB(clk0_out),
|
.CLKFB(clk0_out),
|
.CLKIN(clk_in_ibufg),
|
.CLKIN(clk_in_ibufg),
|
.DSSEN(),
|
.DSSEN(),
|
.PSCLK(),
|
.PSCLK(),
|
.PSEN(),
|
.PSEN(),
|
.PSINCDEC(),
|
.PSINCDEC(),
|
.RST(rst)
|
.RST(rst)
|
);
|
);
|
// DCM with external feedback
|
// DCM with external feedback
|
DCM #(
|
DCM #(
|
.CLKDV_DIVIDE(2.0),
|
.CLKDV_DIVIDE(2.0),
|
.CLKFX_DIVIDE(1),
|
.CLKFX_DIVIDE(1),
|
.CLKFX_MULTIPLY(4),
|
.CLKFX_MULTIPLY(4),
|
.CLKIN_DIVIDE_BY_2("FALSE"),
|
.CLKIN_DIVIDE_BY_2("FALSE"),
|
.CLKIN_PERIOD(8.0),
|
.CLKIN_PERIOD(8.0),
|
.CLKOUT_PHASE_SHIFT("NONE"),
|
.CLKOUT_PHASE_SHIFT("NONE"),
|
.CLK_FEEDBACK("1X"),
|
.CLK_FEEDBACK("1X"),
|
.DESKEW_ADJUST("SYSTEM_SYNCHRONOUS"),
|
.DESKEW_ADJUST("SYSTEM_SYNCHRONOUS"),
|
.DLL_FREQUENCY_MODE("LOW"),
|
.DLL_FREQUENCY_MODE("LOW"),
|
.DUTY_CYCLE_CORRECTION("TRUE"),
|
.DUTY_CYCLE_CORRECTION("TRUE"),
|
.PHASE_SHIFT(0),
|
.PHASE_SHIFT(0),
|
.STARTUP_WAIT("FALSE"))
|
.STARTUP_WAIT("FALSE"))
|
DCM_external (
|
DCM_external (
|
.CLK0(clkfb_bufg),
|
.CLK0(clkfb_bufg),
|
.CLK180(),
|
.CLK180(),
|
.CLK270(),
|
.CLK270(),
|
.CLK2X(),
|
.CLK2X(),
|
.CLK2X180(),
|
.CLK2X180(),
|
.CLK90(),
|
.CLK90(),
|
.CLKDV(),
|
.CLKDV(),
|
.CLKFX(),
|
.CLKFX(),
|
.CLKFX180(),
|
.CLKFX180(),
|
.LOCKED(),
|
.LOCKED(),
|
.PSDONE(),
|
.PSDONE(),
|
.STATUS(),
|
.STATUS(),
|
.CLKFB(clkfb_ibufg),
|
.CLKFB(clkfb_ibufg),
|
.CLKIN(clk_in_ibufg),
|
.CLKIN(clk_in_ibufg),
|
.DSSEN(),
|
.DSSEN(),
|
.PSCLK(),
|
.PSCLK(),
|
.PSEN(),
|
.PSEN(),
|
.PSINCDEC(),
|
.PSINCDEC(),
|
.RST(rst)
|
.RST(rst)
|
);
|
);
|
|
|
// Input buffer on DCM clock source
|
// Input buffer on DCM clock source
|
IBUFG IBUFG_clk (
|
IBUFG IBUFG_clk (
|
.I(clk_in),
|
.I(clk_in),
|
.O(clk_in_ibufg));
|
.O(clk_in_ibufg));
|
|
|
// Global buffers on DCM generated clocks
|
// Global buffers on DCM generated clocks
|
BUFG BUFG_0 (
|
BUFG BUFG_0 (
|
.I(clk0_bufg),
|
.I(clk0_bufg),
|
.O(clk0_out));
|
.O(clk0_out));
|
BUFG BUFG_90 (
|
BUFG BUFG_90 (
|
.I(clk90_bufg),
|
.I(clk90_bufg),
|
.O(clk90_out));
|
.O(clk90_out));
|
BUFG BUFG_180 (
|
BUFG BUFG_180 (
|
.I(clk180_bufg),
|
.I(clk180_bufg),
|
.O(clk180_out));
|
.O(clk180_out));
|
BUFG BUFG_270 (
|
BUFG BUFG_270 (
|
.I(clk270_bufg),
|
.I(clk270_bufg),
|
.O(clk270_out));
|
.O(clk270_out));
|
|
|
// External feedback to DCM
|
// External feedback to DCM
|
IBUFG IBUFG_clkfb (
|
IBUFG IBUFG_clkfb (
|
.I(clkfb_in),
|
.I(clkfb_in),
|
.O(clkfb_ibufg));
|
.O(clkfb_ibufg));
|
OBUF OBUF_clkfb (
|
OBUF OBUF_clkfb (
|
.I(clkfb_bufg),
|
.I(clkfb_bufg),
|
.O(clkfb_out));
|
.O(clkfb_out));
|
`endif // XILINX
|
`endif // XILINX
|
|
|
|
|
`ifdef ALTERA
|
`ifdef ALTERA
|
wire [9:0] sub_wire0;
|
wire [9:0] sub_wire0;
|
wire [0:0] sub_wire8 = 1'h0;
|
wire [0:0] sub_wire8 = 1'h0;
|
wire [3:3] sub_wire4 = sub_wire0[3:3];
|
wire [3:3] sub_wire4 = sub_wire0[3:3];
|
wire [2:2] sub_wire3 = sub_wire0[2:2];
|
wire [2:2] sub_wire3 = sub_wire0[2:2];
|
wire [1:1] sub_wire2 = sub_wire0[1:1];
|
wire [1:1] sub_wire2 = sub_wire0[1:1];
|
wire [0:0] sub_wire1 = sub_wire0[0:0];
|
wire [0:0] sub_wire1 = sub_wire0[0:0];
|
wire sub_wire6 = clk_in;
|
wire sub_wire6 = clk_in;
|
wire [1:0] sub_wire7 = {sub_wire8, sub_wire6};
|
wire [1:0] sub_wire7 = {sub_wire8, sub_wire6};
|
|
|
assign clk0_out = sub_wire1;
|
assign clk0_out = sub_wire1;
|
assign clk90_out = sub_wire2;
|
assign clk90_out = sub_wire2;
|
assign clk180_out = sub_wire3;
|
assign clk180_out = sub_wire3;
|
assign clk270_out = sub_wire4;
|
assign clk270_out = sub_wire4;
|
|
|
// PLL with external feedback
|
// PLL with external feedback
|
altpll #(
|
altpll #(
|
.bandwidth_type("AUTO"),
|
.bandwidth_type("AUTO"),
|
.clk0_divide_by(1),
|
.clk0_divide_by(1),
|
.clk0_duty_cycle(50),
|
.clk0_duty_cycle(50),
|
.clk0_multiply_by(1),
|
.clk0_multiply_by(1),
|
.clk0_phase_shift("0"),
|
.clk0_phase_shift("0"),
|
.clk1_divide_by(1),
|
.clk1_divide_by(1),
|
.clk1_duty_cycle(50),
|
.clk1_duty_cycle(50),
|
.clk1_multiply_by(1),
|
.clk1_multiply_by(1),
|
.clk1_phase_shift("1250"),
|
.clk1_phase_shift("1250"),
|
.clk2_divide_by(1),
|
.clk2_divide_by(1),
|
.clk2_duty_cycle(50),
|
.clk2_duty_cycle(50),
|
.clk2_multiply_by(1),
|
.clk2_multiply_by(1),
|
.clk2_phase_shift("2500"),
|
.clk2_phase_shift("2500"),
|
.clk3_divide_by(1),
|
.clk3_divide_by(1),
|
.clk3_duty_cycle(50),
|
.clk3_duty_cycle(50),
|
.clk3_multiply_by(1),
|
.clk3_multiply_by(1),
|
.clk3_phase_shift("3750"),
|
.clk3_phase_shift("3750"),
|
.compensate_clock("CLK0"),
|
.compensate_clock("CLK0"),
|
.inclk0_input_frequency(5000),
|
.inclk0_input_frequency(5000),
|
.intended_device_family("Stratix III"),
|
.intended_device_family("Stratix III"),
|
.lpm_hint("UNUSED"),
|
.lpm_hint("UNUSED"),
|
.lpm_type("altpll"),
|
.lpm_type("altpll"),
|
.operation_mode("NORMAL"),
|
.operation_mode("NORMAL"),
|
// .operation_mode("SOURCE_SYNCHRONOUS"),
|
// .operation_mode("SOURCE_SYNCHRONOUS"),
|
.pll_type("AUTO"),
|
.pll_type("AUTO"),
|
.port_activeclock("PORT_UNUSED"),
|
.port_activeclock("PORT_UNUSED"),
|
.port_areset("PORT_USED"),
|
.port_areset("PORT_USED"),
|
.port_clkbad0("PORT_UNUSED"),
|
.port_clkbad0("PORT_UNUSED"),
|
.port_clkbad1("PORT_UNUSED"),
|
.port_clkbad1("PORT_UNUSED"),
|
.port_clkloss("PORT_UNUSED"),
|
.port_clkloss("PORT_UNUSED"),
|
.port_clkswitch("PORT_UNUSED"),
|
.port_clkswitch("PORT_UNUSED"),
|
.port_configupdate("PORT_UNUSED"),
|
.port_configupdate("PORT_UNUSED"),
|
.port_fbin("PORT_USED"),
|
.port_fbin("PORT_USED"),
|
.port_fbout("PORT_USED"),
|
.port_fbout("PORT_USED"),
|
.port_inclk0("PORT_USED"),
|
.port_inclk0("PORT_USED"),
|
.port_inclk1("PORT_UNUSED"),
|
.port_inclk1("PORT_UNUSED"),
|
.port_locked("PORT_UNUSED"),
|
.port_locked("PORT_UNUSED"),
|
.port_pfdena("PORT_UNUSED"),
|
.port_pfdena("PORT_UNUSED"),
|
.port_phasecounterselect("PORT_UNUSED"),
|
.port_phasecounterselect("PORT_UNUSED"),
|
.port_phasedone("PORT_UNUSED"),
|
.port_phasedone("PORT_UNUSED"),
|
.port_phasestep("PORT_UNUSED"),
|
.port_phasestep("PORT_UNUSED"),
|
.port_phaseupdown("PORT_UNUSED"),
|
.port_phaseupdown("PORT_UNUSED"),
|
.port_pllena("PORT_UNUSED"),
|
.port_pllena("PORT_UNUSED"),
|
.port_scanaclr("PORT_UNUSED"),
|
.port_scanaclr("PORT_UNUSED"),
|
.port_scanclk("PORT_UNUSED"),
|
.port_scanclk("PORT_UNUSED"),
|
.port_scanclkena("PORT_UNUSED"),
|
.port_scanclkena("PORT_UNUSED"),
|
.port_scandata("PORT_UNUSED"),
|
.port_scandata("PORT_UNUSED"),
|
.port_scandataout("PORT_UNUSED"),
|
.port_scandataout("PORT_UNUSED"),
|
.port_scandone("PORT_UNUSED"),
|
.port_scandone("PORT_UNUSED"),
|
.port_scanread("PORT_UNUSED"),
|
.port_scanread("PORT_UNUSED"),
|
.port_scanwrite("PORT_UNUSED"),
|
.port_scanwrite("PORT_UNUSED"),
|
.port_clk0("PORT_USED"),
|
.port_clk0("PORT_USED"),
|
.port_clk1("PORT_USED"),
|
.port_clk1("PORT_USED"),
|
.port_clk2("PORT_USED"),
|
.port_clk2("PORT_USED"),
|
.port_clk3("PORT_USED"),
|
.port_clk3("PORT_USED"),
|
.port_clk4("PORT_UNUSED"),
|
.port_clk4("PORT_UNUSED"),
|
.port_clk5("PORT_UNUSED"),
|
.port_clk5("PORT_UNUSED"),
|
.port_clk6("PORT_UNUSED"),
|
.port_clk6("PORT_UNUSED"),
|
.port_clk7("PORT_UNUSED"),
|
.port_clk7("PORT_UNUSED"),
|
.port_clk8("PORT_UNUSED"),
|
.port_clk8("PORT_UNUSED"),
|
.port_clk9("PORT_UNUSED"),
|
.port_clk9("PORT_UNUSED"),
|
.port_clkena0("PORT_UNUSED"),
|
.port_clkena0("PORT_UNUSED"),
|
.port_clkena1("PORT_UNUSED"),
|
.port_clkena1("PORT_UNUSED"),
|
.port_clkena2("PORT_UNUSED"),
|
.port_clkena2("PORT_UNUSED"),
|
.port_clkena3("PORT_UNUSED"),
|
.port_clkena3("PORT_UNUSED"),
|
.port_clkena4("PORT_UNUSED"),
|
.port_clkena4("PORT_UNUSED"),
|
.port_clkena5("PORT_UNUSED"),
|
.port_clkena5("PORT_UNUSED"),
|
.using_fbmimicbidir_port("OFF"),
|
.using_fbmimicbidir_port("OFF"),
|
.width_clock(10))
|
.width_clock(10))
|
altpll_internal (
|
altpll_internal (
|
.fbin (),//(clkfb_in),
|
.fbin (),//(clkfb_in),
|
.inclk (sub_wire7),
|
.inclk (sub_wire7),
|
.areset (rst),
|
.areset (rst),
|
.clk (sub_wire0),
|
.clk (sub_wire0),
|
.fbout (),//(clkfb_out),
|
.fbout (),//(clkfb_out),
|
.activeclock (),
|
.activeclock (),
|
.clkbad (),
|
.clkbad (),
|
.clkena ({6{1'b1}}),
|
.clkena ({6{1'b1}}),
|
.clkloss (),
|
.clkloss (),
|
.clkswitch (1'b0),
|
.clkswitch (1'b0),
|
.configupdate (1'b0),
|
.configupdate (1'b0),
|
.enable0 (),
|
.enable0 (),
|
.enable1 (),
|
.enable1 (),
|
.extclk (),
|
.extclk (),
|
.extclkena ({4{1'b1}}),
|
.extclkena ({4{1'b1}}),
|
.fbmimicbidir (),
|
.fbmimicbidir (),
|
.locked (),
|
.locked (),
|
.pfdena (1'b1),
|
.pfdena (1'b1),
|
.phasecounterselect ({4{1'b1}}),
|
.phasecounterselect ({4{1'b1}}),
|
.phasedone (),
|
.phasedone (),
|
.phasestep (1'b1),
|
.phasestep (1'b1),
|
.phaseupdown (1'b1),
|
.phaseupdown (1'b1),
|
.pllena (1'b1),
|
.pllena (1'b1),
|
.scanaclr (1'b0),
|
.scanaclr (1'b0),
|
.scanclk (1'b0),
|
.scanclk (1'b0),
|
.scanclkena (1'b1),
|
.scanclkena (1'b1),
|
.scandata (1'b0),
|
.scandata (1'b0),
|
.scandataout (),
|
.scandataout (),
|
.scandone (),
|
.scandone (),
|
.scanread (1'b0),
|
.scanread (1'b0),
|
.scanwrite (1'b0),
|
.scanwrite (1'b0),
|
.sclkout0 (),
|
.sclkout0 (),
|
.sclkout1 (),
|
.sclkout1 (),
|
.vcooverrange (),
|
.vcooverrange (),
|
.vcounderrange ()
|
.vcounderrange ()
|
);
|
);
|
`endif // ALTERA
|
`endif // ALTERA
|
|
|
//`ifdef GENERIC_PRIMITIVES
|
//`ifdef GENERIC_PRIMITIVES
|
//`endif // GENERIC_PRIMITIVES
|
//`endif // GENERIC_PRIMITIVES
|
|
|
|
|
endmodule // dcm_pll
|
endmodule // dcm_pll
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
//// ////
|
//// ////
|
//// Versatile counter ////
|
//// Versatile counter ////
|
//// ////
|
//// ////
|
//// Description ////
|
//// Description ////
|
//// Versatile counter, a reconfigurable binary, gray or LFSR ////
|
//// Versatile counter, a reconfigurable binary, gray or LFSR ////
|
//// counter ////
|
//// counter ////
|
//// ////
|
//// ////
|
//// To Do: ////
|
//// To Do: ////
|
//// - add LFSR with more taps ////
|
//// - add LFSR with more taps ////
|
//// ////
|
//// ////
|
//// Author(s): ////
|
//// Author(s): ////
|
//// - Michael Unneback, unneback@opencores.org ////
|
//// - Michael Unneback, unneback@opencores.org ////
|
//// ORSoC AB ////
|
//// ORSoC AB ////
|
//// ////
|
//// ////
|
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
//// ////
|
//// ////
|
//// Copyright (C) 2009 Authors and OPENCORES.ORG ////
|
//// Copyright (C) 2009 Authors and OPENCORES.ORG ////
|
//// ////
|
//// ////
|
//// This source file may be used and distributed without ////
|
//// This source file may be used and distributed without ////
|
//// restriction provided that this copyright statement is not ////
|
//// restriction provided that this copyright statement is not ////
|
//// removed from the file and that any derivative work contains ////
|
//// removed from the file and that any derivative work contains ////
|
//// the original copyright notice and the associated disclaimer. ////
|
//// the original copyright notice and the associated disclaimer. ////
|
//// ////
|
//// ////
|
//// This source file is free software; you can redistribute it ////
|
//// This source file is free software; you can redistribute it ////
|
//// and/or modify it under the terms of the GNU Lesser General ////
|
//// and/or modify it under the terms of the GNU Lesser General ////
|
//// Public License as published by the Free Software Foundation; ////
|
//// Public License as published by the Free Software Foundation; ////
|
//// either version 2.1 of the License, or (at your option) any ////
|
//// either version 2.1 of the License, or (at your option) any ////
|
//// later version. ////
|
//// later version. ////
|
//// ////
|
//// ////
|
//// This source is distributed in the hope that it will be ////
|
//// This source is distributed in the hope that it will be ////
|
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
//// details. ////
|
//// details. ////
|
//// ////
|
//// ////
|
//// You should have received a copy of the GNU Lesser General ////
|
//// You should have received a copy of the GNU Lesser General ////
|
//// Public License along with this source; if not, download it ////
|
//// Public License along with this source; if not, download it ////
|
//// from http://www.opencores.org/lgpl.shtml ////
|
//// from http://www.opencores.org/lgpl.shtml ////
|
//// ////
|
//// ////
|
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
|
|
module dff_sr ( aclr, aset, clock, data, q);
|
module dff_sr ( aclr, aset, clock, data, q);
|
|
|
input aclr;
|
input aclr;
|
input aset;
|
input aset;
|
input clock;
|
input clock;
|
input data;
|
input data;
|
output reg q;
|
output reg q;
|
|
|
always @ (posedge clock or posedge aclr or posedge aset)
|
always @ (posedge clock or posedge aclr or posedge aset)
|
if (aclr)
|
if (aclr)
|
q <= 1'b0;
|
q <= 1'b0;
|
else if (aset)
|
else if (aset)
|
q <= 1'b1;
|
q <= 1'b1;
|
else
|
else
|
q <= data;
|
q <= data;
|
|
|
endmodule
|
endmodule
|
module versatile_mem_ctrl_ddr (
|
module versatile_mem_ctrl_ddr (
|
// DDR2 SDRAM side
|
// DDR2 SDRAM side
|
ck_o, ck_n_o,
|
ck_o, ck_n_o,
|
dq_io, dqs_io, dqs_n_io,
|
dq_io, dqs_io, dqs_n_io,
|
dm_rdqs_io,
|
dm_rdqs_io,
|
//rdqs_n_i, odt_o,
|
//rdqs_n_i, odt_o,
|
// Memory controller side
|
// Memory controller side
|
tx_dat_i, rx_dat_o,
|
tx_dat_i, rx_dat_o,
|
dq_en, dqm_en,
|
dq_en, dqm_en,
|
rst, clk_0, clk_90, clk_180, clk_270
|
rst, clk_0, clk_90, clk_180, clk_270
|
);
|
);
|
|
|
output ck_o;
|
output ck_o;
|
output ck_n_o;
|
output ck_n_o;
|
inout [15:0] dq_io;
|
inout [15:0] dq_io;
|
inout [1:0] dqs_io;
|
inout [1:0] dqs_io;
|
inout [1:0] dqs_n_io;
|
inout [1:0] dqs_n_io;
|
inout [1:0] dm_rdqs_io;
|
inout [1:0] dm_rdqs_io;
|
//input [1:0] rdqs_n_i;
|
//input [1:0] rdqs_n_i;
|
//output odt_o;
|
//output odt_o;
|
input [35:0] tx_dat_i;
|
input [35:0] tx_dat_i;
|
output [31:0] rx_dat_o;
|
output [31:0] rx_dat_o;
|
input dq_en;
|
input dq_en;
|
input dqm_en;
|
input dqm_en;
|
input rst;
|
input rst;
|
input clk_0;
|
input clk_0;
|
input clk_90;
|
input clk_90;
|
input clk_180;
|
input clk_180;
|
input clk_270;
|
input clk_270;
|
|
|
reg [31:0] dq_rx_reg;
|
reg [31:0] dq_rx_reg;
|
wire [31:0] dq_rx;
|
wire [31:0] dq_rx;
|
wire [1:0] dqs_o, dqs_n_o, dqm_o;
|
wire [1:0] dqs_o, dqs_n_o, dqm_o;
|
wire [15:0] dq_o;
|
wire [15:0] dq_o;
|
wire [1:0] dqs_delayed, dqs_n_delayed;
|
wire [1:0] dqs_delayed, dqs_n_delayed;
|
|
|
wire [15:0] dq_iobuf;
|
wire [15:0] dq_iobuf;
|
wire [1:0] dqs_iobuf, dqs_n_iobuf;
|
wire [1:0] dqs_iobuf, dqs_n_iobuf;
|
|
|
genvar i;
|
genvar i;
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
// Common for both Xilinx and Altera
|
// Common for both Xilinx and Altera
|
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
// Generate clock with equal delay as data
|
// Generate clock with equal delay as data
|
ddr_ff_out ddr_ff_out_ck (
|
ddr_ff_out ddr_ff_out_ck (
|
.Q(ck_o),
|
.Q(ck_o),
|
.C0(clk_0),
|
.C0(clk_0),
|
.C1(clk_180),
|
.C1(clk_180),
|
.CE(1'b1),
|
.CE(1'b1),
|
.D0(1'b1),
|
.D0(1'b1),
|
.D1(1'b0),
|
.D1(1'b0),
|
.R(1'b0),
|
.R(1'b0),
|
.S(1'b0));
|
.S(1'b0));
|
|
|
ddr_ff_out ddr_ff_out_ck_n (
|
ddr_ff_out ddr_ff_out_ck_n (
|
.Q(ck_n_o),
|
.Q(ck_n_o),
|
.C0(clk_0),
|
.C0(clk_0),
|
.C1(clk_180),
|
.C1(clk_180),
|
.CE(1'b1),
|
.CE(1'b1),
|
.D0(1'b0),
|
.D0(1'b0),
|
.D1(1'b1),
|
.D1(1'b1),
|
.R(wb_rst),
|
.R(wb_rst),
|
.S(1'b0));
|
.S(1'b0));
|
|
|
// Generate strobe with equal delay as data
|
// Generate strobe with equal delay as data
|
generate
|
generate
|
for (i=0; i<2; i=i+1) begin:dqs_oddr
|
for (i=0; i<2; i=i+1) begin:dqs_oddr
|
ddr_ff_out ddr_ff_out_dqs (
|
ddr_ff_out ddr_ff_out_dqs (
|
.Q(dqs_o[i]),
|
.Q(dqs_o[i]),
|
.C0(clk_0),
|
.C0(clk_0),
|
.C1(clk_180),
|
.C1(clk_180),
|
.CE(1'b1),
|
.CE(1'b1),
|
.D0(1'b1),
|
.D0(1'b1),
|
.D1(1'b0),
|
.D1(1'b0),
|
.R(1'b0),
|
.R(1'b0),
|
.S(1'b0));
|
.S(1'b0));
|
end
|
end
|
endgenerate
|
endgenerate
|
|
|
generate
|
generate
|
for (i=0; i<2; i=i+1) begin:dqs_n_oddr
|
for (i=0; i<2; i=i+1) begin:dqs_n_oddr
|
ddr_ff_out ddr_ff_out_dqs_n (
|
ddr_ff_out ddr_ff_out_dqs_n (
|
.Q(dqs_n_o[i]),
|
.Q(dqs_n_o[i]),
|
.C0(clk_0),
|
.C0(clk_0),
|
.C1(clk_180),
|
.C1(clk_180),
|
.CE(1'b1),
|
.CE(1'b1),
|
.D0(1'b0),
|
.D0(1'b0),
|
.D1(1'b1),
|
.D1(1'b1),
|
.R(wb_rst),
|
.R(wb_rst),
|
.S(1'b0));
|
.S(1'b0));
|
end
|
end
|
endgenerate
|
endgenerate
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
// Xilinx
|
// Xilinx
|
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
`ifdef XILINX
|
`ifdef XILINX
|
|
|
reg [15:0] dq_tx_reg;
|
reg [15:0] dq_tx_reg;
|
wire [15:0] dq_tx;
|
wire [15:0] dq_tx;
|
reg [3:0] dqm_tx_reg;
|
reg [3:0] dqm_tx_reg;
|
wire [3:0] dqm_tx;
|
wire [3:0] dqm_tx;
|
|
|
// IO BUFFER
|
// IO BUFFER
|
// DDR data to/from DDR2 SDRAM
|
// DDR data to/from DDR2 SDRAM
|
generate
|
generate
|
for (i=0; i<16; i=i+1) begin:iobuf_dq
|
for (i=0; i<16; i=i+1) begin:iobuf_dq
|
IOBUF u_iobuf_dq (
|
IOBUF u_iobuf_dq (
|
.I(dq_o[i]),
|
.I(dq_o[i]),
|
.T(!dq_en),
|
.T(!dq_en),
|
.IO(dq_io[i]),
|
.IO(dq_io[i]),
|
.O(dq_iobuf[i]));
|
.O(dq_iobuf[i]));
|
end
|
end
|
endgenerate
|
endgenerate
|
|
|
// DQS strobe to/from DDR2 SDRAM
|
// DQS strobe to/from DDR2 SDRAM
|
generate
|
generate
|
for (i=0; i<2; i=i+1) begin:iobuf_dqs
|
for (i=0; i<2; i=i+1) begin:iobuf_dqs
|
IOBUF u_iobuf_dqs (
|
IOBUF u_iobuf_dqs (
|
.I(dqs_o[i]),
|
.I(dqs_o[i]),
|
.T(!dq_en),
|
.T(!dq_en),
|
.IO(dqs_io[i]),
|
.IO(dqs_io[i]),
|
.O(dqs_iobuf[i]));
|
.O(dqs_iobuf[i]));
|
end
|
end
|
endgenerate
|
endgenerate
|
|
|
// DQS strobe to/from DDR2 SDRAM
|
// DQS strobe to/from DDR2 SDRAM
|
generate
|
generate
|
for (i=0; i<2; i=i+1) begin:iobuf_dqs_n
|
for (i=0; i<2; i=i+1) begin:iobuf_dqs_n
|
IOBUF u_iobuf_dqs_n (
|
IOBUF u_iobuf_dqs_n (
|
.I(dqs_n_o[i]),
|
.I(dqs_n_o[i]),
|
.T(!dq_en),
|
.T(!dq_en),
|
.IO(dqs_n_io[i]),
|
.IO(dqs_n_io[i]),
|
.O(dqs_n_iobuf[i]));
|
.O(dqs_n_iobuf[i]));
|
end
|
end
|
endgenerate
|
endgenerate
|
|
|
|
|
// Data from Tx FIFO
|
// Data from Tx FIFO
|
always @ (posedge clk_270 or posedge wb_rst)
|
always @ (posedge clk_270 or posedge wb_rst)
|
if (wb_rst)
|
if (wb_rst)
|
dq_tx_reg[15:0] <= 16'h0;
|
dq_tx_reg[15:0] <= 16'h0;
|
else
|
else
|
if (dqm_en)
|
if (dqm_en)
|
dq_tx_reg[15:0] <= tx_dat_i[19:4];
|
dq_tx_reg[15:0] <= tx_dat_i[19:4];
|
else
|
else
|
dq_tx_reg[15:0] <= tx_dat_i[19:4];
|
dq_tx_reg[15:0] <= tx_dat_i[19:4];
|
|
|
assign dq_tx[15:0] = tx_dat_i[35:20];
|
assign dq_tx[15:0] = tx_dat_i[35:20];
|
|
|
// Output Data DDR flip-flops
|
// Output Data DDR flip-flops
|
generate
|
generate
|
for (i=0; i<16; i=i+1) begin:data_out_oddr
|
for (i=0; i<16; i=i+1) begin:data_out_oddr
|
ddr_ff_out ddr_ff_out_inst_0 (
|
ddr_ff_out ddr_ff_out_inst_0 (
|
.Q(dq_o[i]),
|
.Q(dq_o[i]),
|
.C0(clk_270),
|
.C0(clk_270),
|
.C1(clk_90),
|
.C1(clk_90),
|
.CE(dq_en),
|
.CE(dq_en),
|
.D0(dq_tx[i]),
|
.D0(dq_tx[i]),
|
.D1(dq_tx_reg[i]),
|
.D1(dq_tx_reg[i]),
|
.R(wb_rst),
|
.R(wb_rst),
|
.S(1'b0));
|
.S(1'b0));
|
end
|
end
|
endgenerate
|
endgenerate
|
|
|
// Data mask from Tx FIFO
|
// Data mask from Tx FIFO
|
always @ (posedge clk_270 or posedge wb_rst)
|
always @ (posedge clk_270 or posedge wb_rst)
|
if (wb_rst)
|
if (wb_rst)
|
dqm_tx_reg[1:0] <= 2'b00;
|
dqm_tx_reg[1:0] <= 2'b00;
|
else
|
else
|
if (dqm_en)
|
if (dqm_en)
|
dqm_tx_reg[1:0] <= 2'b00;
|
dqm_tx_reg[1:0] <= 2'b00;
|
else
|
else
|
dqm_tx_reg[1:0] <= tx_dat_i[1:0];
|
dqm_tx_reg[1:0] <= tx_dat_i[1:0];
|
|
|
always @ (posedge clk_180 or posedge wb_rst)
|
always @ (posedge clk_180 or posedge wb_rst)
|
if (wb_rst)
|
if (wb_rst)
|
dqm_tx_reg[3:2] <= 2'b00;
|
dqm_tx_reg[3:2] <= 2'b00;
|
else
|
else
|
if (dqm_en)
|
if (dqm_en)
|
dqm_tx_reg[3:2] <= 2'b00;
|
dqm_tx_reg[3:2] <= 2'b00;
|
else
|
else
|
dqm_tx_reg[3:2] <= tx_dat_i[3:2];
|
dqm_tx_reg[3:2] <= tx_dat_i[3:2];
|
|
|
assign dqm_tx[1:0] = (dqm_en) ? 2'b00 : tx_dat_i[3:2];
|
assign dqm_tx[1:0] = (dqm_en) ? 2'b00 : tx_dat_i[3:2];
|
|
|
// Mask output DDR flip-flops
|
// Mask output DDR flip-flops
|
generate
|
generate
|
for (i=0; i<2; i=i+1) begin:data_mask_oddr
|
for (i=0; i<2; i=i+1) begin:data_mask_oddr
|
ddr_ff_out ddr_ff_out_inst_1 (
|
ddr_ff_out ddr_ff_out_inst_1 (
|
.Q(dqm_o[i]),
|
.Q(dqm_o[i]),
|
.C0(clk_270),
|
.C0(clk_270),
|
.C1(clk_90),
|
.C1(clk_90),
|
.CE(dq_en),
|
.CE(dq_en),
|
.D0(!dqm_tx[i]),
|
.D0(!dqm_tx[i]),
|
.D1(!dqm_tx_reg[i]),
|
.D1(!dqm_tx_reg[i]),
|
.R(wb_rst),
|
.R(wb_rst),
|
.S(1'b0));
|
.S(1'b0));
|
end
|
end
|
endgenerate
|
endgenerate
|
|
|
// Data mask to DDR2 SDRAM
|
// Data mask to DDR2 SDRAM
|
generate
|
generate
|
for (i=0; i<2; i=i+1) begin:iobuf_dqm
|
for (i=0; i<2; i=i+1) begin:iobuf_dqm
|
IOBUF u_iobuf_dqm (
|
IOBUF u_iobuf_dqm (
|
.I(dqm_o[i]),
|
.I(dqm_o[i]),
|
.T(!dq_en),
|
.T(!dq_en),
|
.IO(dm_rdqs_io[i]),
|
.IO(dm_rdqs_io[i]),
|
.O());
|
.O());
|
end
|
end
|
endgenerate
|
endgenerate
|
|
|
|
|
`ifdef INT_CLOCKED_DATA_CAPTURE
|
`ifdef INT_CLOCKED_DATA_CAPTURE
|
// Data in
|
// Data in
|
// DDR flip-flops
|
// DDR flip-flops
|
generate
|
generate
|
for (i=0; i<16; i=i+1) begin:iddr2gen
|
for (i=0; i<16; i=i+1) begin:iddr2gen
|
ddr_ff_in ddr_ff_in_inst_0 (
|
ddr_ff_in ddr_ff_in_inst_0 (
|
.Q0(dq_rx[i]),
|
.Q0(dq_rx[i]),
|
.Q1(dq_rx[i+16]),
|
.Q1(dq_rx[i+16]),
|
.C0(clk_270),
|
.C0(clk_270),
|
.C1(clk_90),
|
.C1(clk_90),
|
.CE(1'b1),
|
.CE(1'b1),
|
.D(dq_io[i]),
|
.D(dq_io[i]),
|
.R(wb_rst),
|
.R(wb_rst),
|
.S(1'b0));
|
.S(1'b0));
|
end
|
end
|
endgenerate
|
endgenerate
|
|
|
// Data to Rx FIFO
|
// Data to Rx FIFO
|
always @ (posedge clk_0 or posedge wb_rst)
|
always @ (posedge clk_0 or posedge wb_rst)
|
if (wb_rst)
|
if (wb_rst)
|
dq_rx_reg[31:16] <= 16'h0;
|
dq_rx_reg[31:16] <= 16'h0;
|
else
|
else
|
dq_rx_reg[31:16] <= dq_rx[31:16];
|
dq_rx_reg[31:16] <= dq_rx[31:16];
|
|
|
always @ (posedge clk_180 or posedge wb_rst)
|
always @ (posedge clk_180 or posedge wb_rst)
|
if (wb_rst)
|
if (wb_rst)
|
dq_rx_reg[15:0] <= 16'h0;
|
dq_rx_reg[15:0] <= 16'h0;
|
else
|
else
|
dq_rx_reg[15:0] <= dq_rx[15:0];
|
dq_rx_reg[15:0] <= dq_rx[15:0];
|
|
|
assign rx_dat_o = dq_rx_reg;
|
assign rx_dat_o = dq_rx_reg;
|
`endif // INT_CLOCKED_DATA_CAPTURE
|
`endif // INT_CLOCKED_DATA_CAPTURE
|
|
|
|
|
`ifdef DEL_DQS_DATA_CAPTURE_1
|
`ifdef DEL_DQS_DATA_CAPTURE_1
|
|
|
wire [1:0] dqs_iodelay, dqs_n_iodelay;
|
wire [1:0] dqs_iodelay, dqs_n_iodelay;
|
|
|
// Delay DQS
|
// Delay DQS
|
assign # 2 dqs_iodelay = dqs_iobuf;
|
assign # 2 dqs_iodelay = dqs_iobuf;
|
assign # 2 dqs_n_iodelay = dqs_n_iobuf;
|
assign # 2 dqs_n_iodelay = dqs_n_iobuf;
|
|
|
// IDDR FF
|
// IDDR FF
|
generate
|
generate
|
for (i=0; i<16; i=i+1) begin:iddr_dq
|
for (i=0; i<16; i=i+1) begin:iddr_dq
|
ddr_ff_in ddr_ff_in_inst_0 (
|
ddr_ff_in ddr_ff_in_inst_0 (
|
.Q0(dq_rx[i]),
|
.Q0(dq_rx[i]),
|
.Q1(dq_rx[i+16]),
|
.Q1(dq_rx[i+16]),
|
.C0(dqs_iodelay[0]),
|
.C0(dqs_iodelay[0]),
|
.C1(dqs_n_iodelay[0]),
|
.C1(dqs_n_iodelay[0]),
|
.CE(1'b1),
|
.CE(1'b1),
|
.D(dq_iobuf[i]),
|
.D(dq_iobuf[i]),
|
.R(wb_rst),
|
.R(wb_rst),
|
.S(1'b0));
|
.S(1'b0));
|
end
|
end
|
endgenerate
|
endgenerate
|
|
|
// Data to Rx FIFO
|
// Data to Rx FIFO
|
always @ (posedge clk_0 or posedge wb_rst)
|
always @ (posedge clk_0 or posedge wb_rst)
|
if (wb_rst)
|
if (wb_rst)
|
dq_rx_reg[31:16] <= 16'h0;
|
dq_rx_reg[31:16] <= 16'h0;
|
else
|
else
|
dq_rx_reg[31:16] <= dq_rx[31:16];
|
dq_rx_reg[31:16] <= dq_rx[31:16];
|
|
|
always @ (posedge clk_0 or posedge wb_rst)
|
always @ (posedge clk_0 or posedge wb_rst)
|
if (wb_rst)
|
if (wb_rst)
|
dq_rx_reg[15:0] <= 16'h0;
|
dq_rx_reg[15:0] <= 16'h0;
|
else
|
else
|
dq_rx_reg[15:0] <= dq_rx[15:0];
|
dq_rx_reg[15:0] <= dq_rx[15:0];
|
|
|
assign rx_dat_o = dq_rx_reg;
|
assign rx_dat_o = dq_rx_reg;
|
|
|
`endif // DEL_DQS_DATA_CAPTURE_1
|
`endif // DEL_DQS_DATA_CAPTURE_1
|
|
|
|
|
`ifdef DEL_DQS_DATA_CAPTURE_2
|
`ifdef DEL_DQS_DATA_CAPTURE_2
|
|
|
wire [15:0] dq_iodelay;
|
wire [15:0] dq_iodelay;
|
wire [1:0] dqs_iodelay, dqs_n_iodelay;
|
wire [1:0] dqs_iodelay, dqs_n_iodelay;
|
wire [15:0] dq_iddr_fall, dq_iddr_rise;
|
wire [15:0] dq_iddr_fall, dq_iddr_rise;
|
reg [15:0] dq_fall_1, dq_rise_1;
|
reg [15:0] dq_fall_1, dq_rise_1;
|
reg [15:0] dq_fall_2, dq_rise_2;
|
reg [15:0] dq_fall_2, dq_rise_2;
|
reg [15:0] dq_fall_3, dq_rise_3;
|
reg [15:0] dq_fall_3, dq_rise_3;
|
|
|
|
|
// Delay data
|
// Delay data
|
// IODELAY is available in the Xilinx Virtex FPGAs
|
// IODELAY is available in the Xilinx Virtex FPGAs
|
/*IODELAY # (
|
/*IODELAY # (
|
.DELAY_SRC(),
|
.DELAY_SRC(),
|
.IDELAY_TYPE(),
|
.IDELAY_TYPE(),
|
.HIGH_PERFORMANCE_MODE(),
|
.HIGH_PERFORMANCE_MODE(),
|
.IDELAY_VALUE(),
|
.IDELAY_VALUE(),
|
.ODELAY_VALUE())
|
.ODELAY_VALUE())
|
u_idelay_dq (
|
u_idelay_dq (
|
.DATAOUT(),
|
.DATAOUT(),
|
.C(),
|
.C(),
|
.CE(),
|
.CE(),
|
.DATAIN(),
|
.DATAIN(),
|
.IDATAIN(),
|
.IDATAIN(),
|
.INC(),
|
.INC(),
|
.ODATAIN(),
|
.ODATAIN(),
|
.RST(),
|
.RST(),
|
.T());*/
|
.T());*/
|
// IODELAY is NOT available in the Xilinx Spartan FPGAs,
|
// IODELAY is NOT available in the Xilinx Spartan FPGAs,
|
// equivalent delay can be implemented using a chain of LUT
|
// equivalent delay can be implemented using a chain of LUT
|
/*lut_delay lut_delay_dq (
|
/*lut_delay lut_delay_dq (
|
.clk_i(),
|
.clk_i(),
|
.d_i(dq_iobuf),
|
.d_i(dq_iobuf),
|
.d_o(dq_iodelay));*/
|
.d_o(dq_iodelay));*/
|
|
|
// IDDR FF
|
// IDDR FF
|
generate
|
generate
|
for (i=0; i<16; i=i+1) begin:iddr_dq
|
for (i=0; i<16; i=i+1) begin:iddr_dq
|
ddr_ff_in ddr_ff_in_inst_0 (
|
ddr_ff_in ddr_ff_in_inst_0 (
|
.Q0(dq_iddr_fall[i]),
|
.Q0(dq_iddr_fall[i]),
|
.Q1(dq_iddr_rise[i]),
|
.Q1(dq_iddr_rise[i]),
|
.C0(dqs_iodelay[0]),
|
.C0(dqs_iodelay[0]),
|
.C1(dqs_n_iodelay[0]),
|
.C1(dqs_n_iodelay[0]),
|
.CE(1'b1),
|
.CE(1'b1),
|
.D(dq_iobuf[i]),
|
.D(dq_iobuf[i]),
|
.R(wb_rst),
|
.R(wb_rst),
|
.S(1'b0));
|
.S(1'b0));
|
end
|
end
|
endgenerate
|
endgenerate
|
|
|
// Rise & fall clocked FF
|
// Rise & fall clocked FF
|
always @ (posedge clk_0 or posedge wb_rst)
|
always @ (posedge clk_0 or posedge wb_rst)
|
if (wb_rst) begin
|
if (wb_rst) begin
|
dq_fall_1 <= 16'h0;
|
dq_fall_1 <= 16'h0;
|
dq_rise_1 <= 16'h0;
|
dq_rise_1 <= 16'h0;
|
end else begin
|
end else begin
|
dq_fall_1 <= dq_iddr_fall;
|
dq_fall_1 <= dq_iddr_fall;
|
dq_rise_1 <= dq_iddr_rise;
|
dq_rise_1 <= dq_iddr_rise;
|
end
|
end
|
|
|
always @ (posedge clk_180 or posedge wb_rst)
|
always @ (posedge clk_180 or posedge wb_rst)
|
if (wb_rst) begin
|
if (wb_rst) begin
|
dq_fall_2 <= 16'h0;
|
dq_fall_2 <= 16'h0;
|
dq_rise_2 <= 16'h0;
|
dq_rise_2 <= 16'h0;
|
end else begin
|
end else begin
|
dq_fall_2 <= dq_iddr_fall;
|
dq_fall_2 <= dq_iddr_fall;
|
dq_rise_2 <= dq_iddr_rise;
|
dq_rise_2 <= dq_iddr_rise;
|
end
|
end
|
|
|
// Fall sync FF
|
// Fall sync FF
|
always @ (posedge clk_0 or posedge wb_rst)
|
always @ (posedge clk_0 or posedge wb_rst)
|
if (wb_rst) begin
|
if (wb_rst) begin
|
dq_fall_3 <= 16'h0;
|
dq_fall_3 <= 16'h0;
|
dq_rise_3 <= 16'h0;
|
dq_rise_3 <= 16'h0;
|
end else begin
|
end else begin
|
dq_fall_3 <= dq_fall_2;
|
dq_fall_3 <= dq_fall_2;
|
dq_rise_3 <= dq_rise_2;
|
dq_rise_3 <= dq_rise_2;
|
end
|
end
|
|
|
// Mux
|
// Mux
|
assign rx_dat_o[31:16] = dq_fall_1;
|
assign rx_dat_o[31:16] = dq_fall_1;
|
assign rx_dat_o[15:0] = dq_rise_1;
|
assign rx_dat_o[15:0] = dq_rise_1;
|
|
|
// DDR DQS to IODUFDS
|
// DDR DQS to IODUFDS
|
// Delay DQS
|
// Delay DQS
|
// IODELAY is NOT available in the Xilinx Spartan FPGAs,
|
// IODELAY is NOT available in the Xilinx Spartan FPGAs,
|
// equivalent delay can be implemented using a chain of LUTs
|
// equivalent delay can be implemented using a chain of LUTs
|
/*
|
/*
|
generate
|
generate
|
for (i=0; i<2; i=i+1) begin:lut_delay_dqs
|
for (i=0; i<2; i=i+1) begin:lut_delay_dqs
|
lut_delay lut_delay_dqs (
|
lut_delay lut_delay_dqs (
|
.d_i(dqs_iobuf[i]),
|
.d_i(dqs_iobuf[i]),
|
.d_o(dqs_iodelay[i]));
|
.d_o(dqs_iodelay[i]));
|
end
|
end
|
endgenerate
|
endgenerate
|
generate
|
generate
|
for (i=0; i<2; i=i+1) begin:lut_delay_dqs_n
|
for (i=0; i<2; i=i+1) begin:lut_delay_dqs_n
|
lut_delay lut_delay_dqs_n (
|
lut_delay lut_delay_dqs_n (
|
.d_i(dqs_n_iobuf[i]),
|
.d_i(dqs_n_iobuf[i]),
|
.d_o(dqs_n_iodelay[i]));
|
.d_o(dqs_n_iodelay[i]));
|
end
|
end
|
endgenerate
|
endgenerate
|
*/
|
*/
|
|
|
assign # 2 dqs_iodelay = dqs_iobuf;
|
assign # 2 dqs_iodelay = dqs_iobuf;
|
assign # 2 dqs_n_iodelay = dqs_n_iobuf;
|
assign # 2 dqs_n_iodelay = dqs_n_iobuf;
|
|
|
|
|
// BUFIO (?)
|
// BUFIO (?)
|
`endif // DEL_DQS_DATA_CAPTURE_2
|
`endif // DEL_DQS_DATA_CAPTURE_2
|
|
|
`endif // XILINX
|
`endif // XILINX
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
// Altera
|
// Altera
|
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
`ifdef ALTERA
|
`ifdef ALTERA
|
|
|
wire [3:0] dqm_tx;
|
wire [3:0] dqm_tx;
|
|
|
// Data out
|
// Data out
|
// DDR flip-flops
|
// DDR flip-flops
|
generate
|
generate
|
for (i=0; i<16; i=i+1) begin:data_out_oddr
|
for (i=0; i<16; i=i+1) begin:data_out_oddr
|
ddr_ff_out ddr_ff_out_inst_0 (
|
ddr_ff_out ddr_ff_out_inst_0 (
|
.Q(dq_o[i]),
|
.Q(dq_o[i]),
|
.C0(clk_270),
|
.C0(clk_270),
|
.C1(clk_90),
|
.C1(clk_90),
|
.CE(dq_en),
|
.CE(dq_en),
|
.D0(tx_dat_i[i+16+4]),
|
.D0(tx_dat_i[i+16+4]),
|
.D1(tx_dat_i[i+4]),
|
.D1(tx_dat_i[i+4]),
|
.R(wb_rst),
|
.R(wb_rst),
|
.S(1'b0));
|
.S(1'b0));
|
end
|
end
|
endgenerate
|
endgenerate
|
|
|
// Assign outport
|
// Assign outport
|
assign dq_io = dq_en ? dq_o : {16{1'bz}};
|
assign dq_io = dq_en ? dq_o : {16{1'bz}};
|
|
|
// Data mask
|
// Data mask
|
// Data mask from Tx FIFO
|
// Data mask from Tx FIFO
|
assign dqm_tx = dqm_en ? {4{1'b0}} : tx_dat_i[3:0];
|
assign dqm_tx = dqm_en ? {4{1'b0}} : tx_dat_i[3:0];
|
|
|
// DDR flip-flops
|
// DDR flip-flops
|
generate
|
generate
|
for (i=0; i<2; i=i+1) begin:data_mask_oddr
|
for (i=0; i<2; i=i+1) begin:data_mask_oddr
|
ddr_ff_out ddr_ff_out_inst_1 (
|
ddr_ff_out ddr_ff_out_inst_1 (
|
.Q(dqm_o[i]),
|
.Q(dqm_o[i]),
|
.C0(clk_270),
|
.C0(clk_270),
|
.C1(clk_90),
|
.C1(clk_90),
|
.CE(dq_en),
|
.CE(dq_en),
|
.D0(!dqm_tx[i+2]),
|
.D0(!dqm_tx[i+2]),
|
.D1(!dqm_tx[i]),
|
.D1(!dqm_tx[i]),
|
.R(wb_rst),
|
.R(wb_rst),
|
.S(1'b0));
|
.S(1'b0));
|
end
|
end
|
endgenerate
|
endgenerate
|
|
|
// Assign outport
|
// Assign outport
|
assign dm_rdqs_io = dq_en ? dqm_o : 2'bzz;
|
assign dm_rdqs_io = dq_en ? dqm_o : 2'bzz;
|
|
|
|
|
// Data in
|
// Data in
|
`ifdef INT_CLOCKED_DATA_CAPTURE
|
`ifdef INT_CLOCKED_DATA_CAPTURE
|
// DDR flip-flops
|
// DDR flip-flops
|
generate
|
generate
|
for (i=0; i<16; i=i+1) begin:iddr2gen
|
for (i=0; i<16; i=i+1) begin:iddr2gen
|
ddr_ff_in ddr_ff_in_inst_0 (
|
ddr_ff_in ddr_ff_in_inst_0 (
|
.Q0(dq_rx[i]),
|
.Q0(dq_rx[i]),
|
.Q1(dq_rx[i+16]),
|
.Q1(dq_rx[i+16]),
|
.C0(clk_270),
|
.C0(clk_270),
|
.C1(clk_90),
|
.C1(clk_90),
|
.CE(1'b1),
|
.CE(1'b1),
|
.D(dq_io[i]),
|
.D(dq_io[i]),
|
.R(wb_rst),
|
.R(wb_rst),
|
.S(1'b0));
|
.S(1'b0));
|
end
|
end
|
endgenerate
|
endgenerate
|
|
|
// Data to Rx FIFO
|
// Data to Rx FIFO
|
always @ (posedge clk_180 or posedge wb_rst)
|
always @ (posedge clk_180 or posedge wb_rst)
|
if (wb_rst)
|
if (wb_rst)
|
dq_rx_reg <= 32'h0;
|
dq_rx_reg <= 32'h0;
|
else
|
else
|
dq_rx_reg <= dq_rx;
|
dq_rx_reg <= dq_rx;
|
|
|
assign rx_dat_o = dq_rx_reg;
|
assign rx_dat_o = dq_rx_reg;
|
`endif // INT_CLOCKED_DATA_CAPTURE
|
`endif // INT_CLOCKED_DATA_CAPTURE
|
|
|
`ifdef DEL_DQS_DATA_CAPTURE_1
|
`ifdef DEL_DQS_DATA_CAPTURE_1
|
// Delay DQS
|
// Delay DQS
|
// DDR FF
|
// DDR FF
|
`endif // DEL_DQS_DATA_CAPTURE_1
|
`endif // DEL_DQS_DATA_CAPTURE_1
|
|
|
`ifdef DEL_DQS_DATA_CAPTURE_2
|
`ifdef DEL_DQS_DATA_CAPTURE_2
|
// DDR data to IOBUFFER
|
// DDR data to IOBUFFER
|
// Delay data (?)
|
// Delay data (?)
|
// DDR FF
|
// DDR FF
|
// Rise & fall clocked FF
|
// Rise & fall clocked FF
|
// Fall sync FF
|
// Fall sync FF
|
// Mux
|
// Mux
|
// DDR DQS to IODUFDS
|
// DDR DQS to IODUFDS
|
// Delay DQS
|
// Delay DQS
|
// BUFIO (?)
|
// BUFIO (?)
|
`endif // DEL_DQS_DATA_CAPTURE_2
|
`endif // DEL_DQS_DATA_CAPTURE_2
|
|
|
`endif // ALTERA
|
`endif // ALTERA
|
|
|
|
|
endmodule // versatile_mem_ctrl_ddr
|
endmodule // versatile_mem_ctrl_ddr
|
|
|
|
|
`timescale 1ns/1ns
|
`timescale 1ns/1ns
|
|
|
|
|
//
|
//
|
// Specify either type of memory
|
// Specify either type of memory
|
// or
|
// or
|
// BA_SIZE, ROW_SIZE, COL_SIZE and SDRAM_DATA_WIDTH
|
// BA_SIZE, ROW_SIZE, COL_SIZE and SDRAM_DATA_WIDTH
|
//
|
//
|
// either in this file or as command line option; +define+MT48LC16M16
|
// either in this file or as command line option; +define+MT48LC16M16
|
//
|
//
|
|
|
// number of adr lines to use
|
// number of adr lines to use
|
// 2^2 = 4 32 bit word burst
|
// 2^2 = 4 32 bit word burst
|
//`define BURST_SIZE 2
|
//`define BURST_SIZE 2
|
|
|
|
|
// DDR2 SDRAM
|
// DDR2 SDRAM
|
// MT47H32M16 – 8 Meg x 16 x 4 banks
|
// MT47H32M16 – 8 Meg x 16 x 4 banks
|
`define MT47H32M16
|
`define MT47H32M16
|
`ifdef MT47H32M16
|
`ifdef MT47H32M16
|
// using 1 of MT47H32M16
|
// using 1 of MT47H32M16
|
// SDRAM data width is 16
|
// SDRAM data width is 16
|
`define BURST_SIZE 4
|
`define BURST_SIZE 4
|
`define SDRAM_DATA_WIDTH 16
|
`define SDRAM_DATA_WIDTH 16
|
`define COL_SIZE 10
|
`define COL_SIZE 10
|
`define ROW_SIZE 13
|
`define ROW_SIZE 13
|
`define BA_SIZE 2
|
`define BA_SIZE 2
|
|
|
`define SDRAM16
|
`define SDRAM16
|
`define BA tx_fifo_dat_o[28:27]
|
`define BA tx_fifo_dat_o[28:27]
|
`define ROW tx_fifo_dat_o[26:14]
|
`define ROW tx_fifo_dat_o[26:14]
|
`define COL {4'b0000,tx_fifo_dat_o[13:10],burst_adr,1'b0}
|
`define COL {4'b0000,tx_fifo_dat_o[13:10],burst_adr,1'b0}
|
`define WORD_SIZE 1
|
`define WORD_SIZE 1
|
`define WB_ADR_HI 24
|
`define WB_ADR_HI 24
|
`define WB_ADR_LO 2
|
`define WB_ADR_LO 2
|
|
|
// Mode Register (MR) Definition
|
// Mode Register (MR) Definition
|
// [16] (BA2) 1'b0
|
// [16] (BA2) 1'b0
|
// [15:14] (BA1-0) Mode Register Definition (MR): 2'b00 - Mode Register (MR)
|
// [15:14] (BA1-0) Mode Register Definition (MR): 2'b00 - Mode Register (MR)
|
// [13] (A13) 1'b0
|
// [13] (A13) 1'b0
|
// [12] (A12) PD Mode (PD): 1'b0 - Fast exit (normal), 1'b1 - Slow exit (low power)
|
// [12] (A12) PD Mode (PD): 1'b0 - Fast exit (normal), 1'b1 - Slow exit (low power)
|
// [11:9] (A11-9) Write Recovery (WR): 3'b000 - reserved, 3b'001 - 2, ... , 3b'111 - 8
|
// [11:9] (A11-9) Write Recovery (WR): 3'b000 - reserved, 3b'001 - 2, ... , 3b'111 - 8
|
// [8] (A8) DLL Reset (DLL): 1'b0 - No, 1'b1 - Yes
|
// [8] (A8) DLL Reset (DLL): 1'b0 - No, 1'b1 - Yes
|
// [7] (A7) Mode (TM): 1'b0 - Normal, 1'b1 - Test
|
// [7] (A7) Mode (TM): 1'b0 - Normal, 1'b1 - Test
|
// [6:4] (A5-4) CAS Latency (CL): 3'b011 - 3, ... , 3'b111 - 7
|
// [6:4] (A5-4) CAS Latency (CL): 3'b011 - 3, ... , 3'b111 - 7
|
// [3] (A3) Burst Type (BT): 1'b0 - Sequential, 1'b1 - Interleaved
|
// [3] (A3) Burst Type (BT): 1'b0 - Sequential, 1'b1 - Interleaved
|
// [2:0] (A2-0) Burst Length (BL): 3'b010 - 4, 3'b011 - 8
|
// [2:0] (A2-0) Burst Length (BL): 3'b010 - 4, 3'b011 - 8
|
`define MR 2'b00
|
`define MR 2'b00
|
`define PD 1'b0
|
`define PD 1'b0
|
`define WR 3'b001
|
`define WR 3'b001
|
`define DLL 1'b0
|
`define DLL 1'b0
|
`define DLL_RST 1'b1
|
`define DLL_RST 1'b1
|
`define TM 1'b0
|
`define TM 1'b0
|
`define CL 3'b100
|
`define CL 3'b100
|
`define BT 1'b0
|
`define BT 1'b0
|
`define BL 3'b011
|
`define BL 3'b011
|
|
|
// Extended Mode Register (EMR) Definition
|
// Extended Mode Register (EMR) Definition
|
// [16] (BA2) 1'b0
|
// [16] (BA2) 1'b0
|
// [15:14] (BA1-0) Mode Register Set (MRS): 2'b01 - Extended Mode Register (EMR)
|
// [15:14] (BA1-0) Mode Register Set (MRS): 2'b01 - Extended Mode Register (EMR)
|
// [13] (A13) 1'b0
|
// [13] (A13) 1'b0
|
// [12] (A12) Outputs (OUT): 1'b0 - Enabled, 1'b1 - Disabled
|
// [12] (A12) Outputs (OUT): 1'b0 - Enabled, 1'b1 - Disabled
|
// [11] (A11) RDQS Enable (RDQS): 1'b0 - Enabled, 1'b1 - Disabled
|
// [11] (A11) RDQS Enable (RDQS): 1'b0 - Enabled, 1'b1 - Disabled
|
// [10] (A10) DQS# Enable (DQS): 1'b0 - Enabled, 1'b1 - Disabled
|
// [10] (A10) DQS# Enable (DQS): 1'b0 - Enabled, 1'b1 - Disabled
|
// [9:7] (A9-7) OCD Opearation (OCD): 3'b000 - OCD exit, 3b'111 - Enable OCD defaults
|
// [9:7] (A9-7) OCD Opearation (OCD): 3'b000 - OCD exit, 3b'111 - Enable OCD defaults
|
// [6,2] (A6, A2) RTT Nominal (RTT6,2): 2'b00 - Disabled, 2'b01 - 75 ohm,
|
// [6,2] (A6, A2) RTT Nominal (RTT6,2): 2'b00 - Disabled, 2'b01 - 75 ohm,
|
// 2'b10 - 150 ohm, 2'b11 - 50 ohm,
|
// 2'b10 - 150 ohm, 2'b11 - 50 ohm,
|
// [5:3] (A5-3) Posted CAS# Additive Latenct (AL): 3'b000 - 0, ... , 3'b110 - 6
|
// [5:3] (A5-3) Posted CAS# Additive Latenct (AL): 3'b000 - 0, ... , 3'b110 - 6
|
// [1] (A1) Output Drive Strength (ODS): 1'b0 - Full, 1'b1 - Reduced
|
// [1] (A1) Output Drive Strength (ODS): 1'b0 - Full, 1'b1 - Reduced
|
// [0] (A0) DLL Enable (DLL_EN): 1'b0 - Enable (normal), 1'b1 - Disable (test/debug)
|
// [0] (A0) DLL Enable (DLL_EN): 1'b0 - Enable (normal), 1'b1 - Disable (test/debug)
|
`define MRS 2'b01
|
`define MRS 2'b01
|
`define OUT 1'b0
|
`define OUT 1'b0
|
`define RDQS 1'b0
|
`define RDQS 1'b0
|
`define DQS 1'b0
|
`define DQS 1'b0
|
`define OCD 3'b000
|
`define OCD 3'b000
|
`define OCD_DEFAULT 3'b111
|
`define OCD_DEFAULT 3'b111
|
`define RTT6 1'b0
|
`define RTT6 1'b0
|
`define RTT2 1'b0
|
`define RTT2 1'b0
|
`define AL 3'b000
|
`define AL 3'b000
|
`define ODS 1'b0
|
`define ODS 1'b0
|
`define DLL_EN 1'b0
|
`define DLL_EN 1'b0
|
|
|
// Extended Mode Register 2 (EMR2) Definition
|
// Extended Mode Register 2 (EMR2) Definition
|
// [16] (BA2) 1'b0
|
// [16] (BA2) 1'b0
|
// [15:14] (BA1-0) Mode Register Set (MRS2): 2'b10 - Extended Mode Register 2 (EMR2)
|
// [15:14] (BA1-0) Mode Register Set (MRS2): 2'b10 - Extended Mode Register 2 (EMR2)
|
// [13:8] (A13-8) 6'b000000
|
// [13:8] (A13-8) 6'b000000
|
// [7] (A7) SRT Enable (SRT): 1'b0 - 1x refresh rate (0 - 85 C),
|
// [7] (A7) SRT Enable (SRT): 1'b0 - 1x refresh rate (0 - 85 C),
|
// 1'b1 - 2x refresh rate (> 85 C)
|
// 1'b1 - 2x refresh rate (> 85 C)
|
// [6:0] (A6-0) 7'b0000000
|
// [6:0] (A6-0) 7'b0000000
|
`define MRS2 2'b10
|
`define MRS2 2'b10
|
`define SRT 1'b0
|
`define SRT 1'b0
|
|
|
// Extended Mode Register 3 (EMR3) Definition
|
// Extended Mode Register 3 (EMR3) Definition
|
// [16] (BA2) 1'b0
|
// [16] (BA2) 1'b0
|
// [15:14] (BA1-0) Mode Register Set (MRS): 2'b11 - Extended Mode Register 2 (EMR2)
|
// [15:14] (BA1-0) Mode Register Set (MRS): 2'b11 - Extended Mode Register 2 (EMR2)
|
// [13:0] (A13-0) 14'b00000000000000
|
// [13:0] (A13-0) 14'b00000000000000
|
`define MRS3 2'b11
|
`define MRS3 2'b11
|
|
|
// Addr to SDRAM {ba[1:0],a[12:0]}
|
// Addr to SDRAM {ba[1:0],a[12:0]}
|
`define A_LMR {`MR,`PD,`WR,`DLL,`TM,`CL,`BT,`BL}
|
`define A_LMR {`MR,`PD,`WR,`DLL,`TM,`CL,`BT,`BL}
|
`define A_LMR_DLL_RST {`MR,`PD,`WR,`DLL_RST,`TM,`CL,`BT,`BL}
|
`define A_LMR_DLL_RST {`MR,`PD,`WR,`DLL_RST,`TM,`CL,`BT,`BL}
|
`define A_LEMR {`MRS,`OUT,`RDQS,`DQS,`OCD,`RTT6,`AL,`RTT2,`ODS,`DLL_EN}
|
`define A_LEMR {`MRS,`OUT,`RDQS,`DQS,`OCD,`RTT6,`AL,`RTT2,`ODS,`DLL_EN}
|
`define A_LEMR_OCD_DEFAULT {`MRS,`OUT,`RDQS,`DQS,`OCD_DEFAULT,`RTT6,`AL,`RTT2,`ODS,`DLL}
|
`define A_LEMR_OCD_DEFAULT {`MRS,`OUT,`RDQS,`DQS,`OCD_DEFAULT,`RTT6,`AL,`RTT2,`ODS,`DLL}
|
`define A_LEMR2 {`MRS2,5'b00000,`SRT,7'b0000000}
|
`define A_LEMR2 {`MRS2,5'b00000,`SRT,7'b0000000}
|
`define A_LEMR3 {`MRS3,13'b0000000000000}
|
`define A_LEMR3 {`MRS3,13'b0000000000000}
|
`define A_PRE {2'b00,13'b0010000000000}
|
`define A_PRE {2'b00,13'b0010000000000}
|
`define A_ACT {`BA,`ROW}
|
`define A_ACT {`BA,`ROW}
|
`define A_READ {`BA,`COL}
|
`define A_READ {`BA,`COL}
|
`define A_WRITE {`BA,`COL}
|
`define A_WRITE {`BA,`COL}
|
`define A_DEFAULT {2'b00,13'b0000000000000}
|
`define A_DEFAULT {2'b00,13'b0000000000000}
|
|
|
// Command
|
// Command
|
`define CMD {ras, cas, we}
|
`define CMD {ras, cas, we}
|
`define CMD_NOP 3'b111
|
`define CMD_NOP 3'b111
|
`define CMD_AREF 3'b001
|
`define CMD_AREF 3'b001
|
`define CMD_LMR 3'b000
|
`define CMD_LMR 3'b000
|
`define CMD_LEMR 3'b000
|
`define CMD_LEMR 3'b000
|
`define CMD_LEMR2 3'b000
|
`define CMD_LEMR2 3'b000
|
`define CMD_LEMR3 3'b000
|
`define CMD_LEMR3 3'b000
|
`define CMD_PRE 3'b010
|
`define CMD_PRE 3'b010
|
`define CMD_ACT 3'b011
|
`define CMD_ACT 3'b011
|
`define CMD_READ 3'b101
|
`define CMD_READ 3'b101
|
`define CMD_WRITE 3'b100
|
`define CMD_WRITE 3'b100
|
`define CMD_BT 3'b110
|
`define CMD_BT 3'b110
|
|
|
`endif // `ifdef MT47H32M16
|
`endif // `ifdef MT47H32M16
|
|
|
//
|
//
|
// Specify either type of memory
|
// Specify either type of memory
|
// or
|
// or
|
// BA_SIZE, ROW_SIZE, COL_SIZE and SDRAM_DATA_WIDTH
|
// BA_SIZE, ROW_SIZE, COL_SIZE and SDRAM_DATA_WIDTH
|
//
|
//
|
// either in this file or as command line option; +define+MT48LC16M16
|
// 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
|
// Most of these defines have an effect on things in fsm_sdr_16.v
|
|
|
|
|
//`define MT48LC32M16 // 64MB part
|
//`define MT48LC32M16 // 64MB part
|
`define MT48LC16M16 // 32MB part
|
`define MT48LC16M16 // 32MB part
|
//`define MT48LC4M16 // 8MB part
|
//`define MT48LC4M16 // 8MB part
|
|
|
// Define this to allow indication that a burst read is still going
|
// Define this to allow indication that a burst read is still going
|
// to the wishbone state machine, so it doesn't start emptying the
|
// to the wishbone state machine, so it doesn't start emptying the
|
// ingress fifo after a aborted burst before the burst read is
|
// ingress fifo after a aborted burst before the burst read is
|
// actually finished.
|
// actually finished.
|
`define SDRAM_WB_SAME_CLOCKS
|
`define SDRAM_WB_SAME_CLOCKS
|
|
|
// If intending to burst write, and the wishbone clock is about 1/4 the speed
|
// 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
|
// 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
|
// 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)
|
// burst reading (there's no almost_empty signal from the FIFO)
|
`define SLOW_WB_CLOCK
|
`define SLOW_WB_CLOCK
|
|
|
|
|
`ifdef MT48LC32M16
|
`ifdef MT48LC32M16
|
// using 1 of MT48LC16M16
|
// using 1 of MT48LC32M16
|
// SDRAM data width is 16
|
// SDRAM data width is 16
|
|
|
`define SDRAM_DATA_WIDTH 16
|
`define SDRAM_DATA_WIDTH 16
|
`define COL_SIZE 10
|
`define COL_SIZE 10
|
`define ROW_SIZE 13
|
`define ROW_SIZE 13
|
`define BA_SIZE 2
|
`define BA_SIZE 2
|
|
|
`endif // `ifdef MT48LC16M16
|
`endif // `ifdef MT48LC16M16
|
|
|
`ifdef MT48LC16M16
|
`ifdef MT48LC16M16
|
// using 1 of MT48LC16M16
|
// using 1 of MT48LC16M16
|
// SDRAM data width is 16
|
// SDRAM data width is 16
|
|
|
`define SDRAM_DATA_WIDTH 16
|
`define SDRAM_DATA_WIDTH 16
|
`define COL_SIZE 9
|
`define COL_SIZE 9
|
`define ROW_SIZE 13
|
`define ROW_SIZE 13
|
`define BA_SIZE 2
|
`define BA_SIZE 2
|
|
|
`endif // `ifdef MT48LC16M16
|
`endif // `ifdef MT48LC16M16
|
|
|
`ifdef MT48LC4M16
|
`ifdef MT48LC4M16
|
// using 1 of MT48LC4M16
|
// using 1 of MT48LC4M16
|
// SDRAM data width is 16
|
// SDRAM data width is 16
|
|
|
`define SDRAM_DATA_WIDTH 16
|
`define SDRAM_DATA_WIDTH 16
|
`define COL_SIZE 8
|
`define COL_SIZE 8
|
`define ROW_SIZE 12
|
`define ROW_SIZE 12
|
`define BA_SIZE 2
|
`define BA_SIZE 2
|
|
|
`endif // `ifdef MT48LC4M16
|
`endif // `ifdef MT48LC4M16
|
|
|
// LMR
|
// LMR
|
// [12:10] reserved
|
// [12:10] reserved
|
// [9] WB, write burst; 0 - programmed burst length, 1 - single location
|
// [9] WB, write burst; 0 - programmed burst length, 1 - single location
|
// [8:7] OP Mode, 2'b00
|
// [8:7] OP Mode, 2'b00
|
// [6:4] CAS Latency; 3'b010 - 2, 3'b011 - 3
|
// [6:4] CAS Latency; 3'b010 - 2, 3'b011 - 3
|
// [3] BT, Burst Type; 1'b0 - sequential, 1'b1 - interleaved
|
// [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
|
// [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_WB 1'b0
|
`define INIT_CL 3'b010
|
`define INIT_CL 3'b010
|
`define INIT_BT 1'b0
|
`define INIT_BT 1'b0
|
`define INIT_BL 3'b001
|
`define INIT_BL 3'b001
|
`timescale 1ns/1ns
|
`timescale 1ns/1ns
|
module encode (
|
module encode (
|
fifo_empty_0, fifo_empty_1, fifo_empty_2, fifo_empty_3,
|
fifo_empty_0, fifo_empty_1, fifo_empty_2, fifo_empty_3,
|
fifo_sel, fifo_sel_domain
|
fifo_sel, fifo_sel_domain
|
);
|
);
|
|
|
input [0:15] fifo_empty_0, fifo_empty_1, fifo_empty_2, fifo_empty_3;
|
input [0:15] fifo_empty_0, fifo_empty_1, fifo_empty_2, fifo_empty_3;
|
output [0:15] fifo_sel;
|
output [0:15] fifo_sel;
|
output [1:0] fifo_sel_domain;
|
output [1:0] fifo_sel_domain;
|
|
|
function [0:15] encode;
|
function [0:15] encode;
|
input [0:15] a;
|
input [0:15] a;
|
input [0:15] b;
|
input [0:15] b;
|
input [0:15] c;
|
input [0:15] c;
|
input [0:15] d;
|
input [0:15] d;
|
integer i;
|
integer i;
|
begin
|
begin
|
if (!(&d))
|
if (!(&d))
|
casex (d)
|
casex (d)
|
16'b0xxxxxxxxxxxxxxx: encode = 16'b1000000000000000;
|
16'b0xxxxxxxxxxxxxxx: encode = 16'b1000000000000000;
|
16'b10xxxxxxxxxxxxxx: encode = 16'b0100000000000000;
|
16'b10xxxxxxxxxxxxxx: encode = 16'b0100000000000000;
|
16'b110xxxxxxxxxxxxx: encode = 16'b0010000000000000;
|
16'b110xxxxxxxxxxxxx: encode = 16'b0010000000000000;
|
16'b1110xxxxxxxxxxxx: encode = 16'b0001000000000000;
|
16'b1110xxxxxxxxxxxx: encode = 16'b0001000000000000;
|
16'b11110xxxxxxxxxxx: encode = 16'b0000100000000000;
|
16'b11110xxxxxxxxxxx: encode = 16'b0000100000000000;
|
16'b111110xxxxxxxxxx: encode = 16'b0000010000000000;
|
16'b111110xxxxxxxxxx: encode = 16'b0000010000000000;
|
16'b1111110xxxxxxxxx: encode = 16'b0000001000000000;
|
16'b1111110xxxxxxxxx: encode = 16'b0000001000000000;
|
16'b11111110xxxxxxxx: encode = 16'b0000000100000000;
|
16'b11111110xxxxxxxx: encode = 16'b0000000100000000;
|
16'b111111110xxxxxxx: encode = 16'b0000000010000000;
|
16'b111111110xxxxxxx: encode = 16'b0000000010000000;
|
16'b1111111110xxxxxx: encode = 16'b0000000001000000;
|
16'b1111111110xxxxxx: encode = 16'b0000000001000000;
|
16'b11111111110xxxxx: encode = 16'b0000000000100000;
|
16'b11111111110xxxxx: encode = 16'b0000000000100000;
|
16'b111111111110xxxx: encode = 16'b0000000000010000;
|
16'b111111111110xxxx: encode = 16'b0000000000010000;
|
16'b1111111111110xxx: encode = 16'b0000000000001000;
|
16'b1111111111110xxx: encode = 16'b0000000000001000;
|
16'b11111111111110xx: encode = 16'b0000000000000100;
|
16'b11111111111110xx: encode = 16'b0000000000000100;
|
16'b111111111111110x: encode = 16'b0000000000000010;
|
16'b111111111111110x: encode = 16'b0000000000000010;
|
16'b1111111111111110: encode = 16'b0000000000000001;
|
16'b1111111111111110: encode = 16'b0000000000000001;
|
default: encode = 16'b0000000000000000;
|
default: encode = 16'b0000000000000000;
|
endcase
|
endcase
|
else if (!(&c))
|
else if (!(&c))
|
casex (c)
|
casex (c)
|
16'b0xxxxxxxxxxxxxxx: encode = 16'b1000000000000000;
|
16'b0xxxxxxxxxxxxxxx: encode = 16'b1000000000000000;
|
16'b10xxxxxxxxxxxxxx: encode = 16'b0100000000000000;
|
16'b10xxxxxxxxxxxxxx: encode = 16'b0100000000000000;
|
16'b110xxxxxxxxxxxxx: encode = 16'b0010000000000000;
|
16'b110xxxxxxxxxxxxx: encode = 16'b0010000000000000;
|
16'b1110xxxxxxxxxxxx: encode = 16'b0001000000000000;
|
16'b1110xxxxxxxxxxxx: encode = 16'b0001000000000000;
|
16'b11110xxxxxxxxxxx: encode = 16'b0000100000000000;
|
16'b11110xxxxxxxxxxx: encode = 16'b0000100000000000;
|
16'b111110xxxxxxxxxx: encode = 16'b0000010000000000;
|
16'b111110xxxxxxxxxx: encode = 16'b0000010000000000;
|
16'b1111110xxxxxxxxx: encode = 16'b0000001000000000;
|
16'b1111110xxxxxxxxx: encode = 16'b0000001000000000;
|
16'b11111110xxxxxxxx: encode = 16'b0000000100000000;
|
16'b11111110xxxxxxxx: encode = 16'b0000000100000000;
|
16'b111111110xxxxxxx: encode = 16'b0000000010000000;
|
16'b111111110xxxxxxx: encode = 16'b0000000010000000;
|
16'b1111111110xxxxxx: encode = 16'b0000000001000000;
|
16'b1111111110xxxxxx: encode = 16'b0000000001000000;
|
16'b11111111110xxxxx: encode = 16'b0000000000100000;
|
16'b11111111110xxxxx: encode = 16'b0000000000100000;
|
16'b111111111110xxxx: encode = 16'b0000000000010000;
|
16'b111111111110xxxx: encode = 16'b0000000000010000;
|
16'b1111111111110xxx: encode = 16'b0000000000001000;
|
16'b1111111111110xxx: encode = 16'b0000000000001000;
|
16'b11111111111110xx: encode = 16'b0000000000000100;
|
16'b11111111111110xx: encode = 16'b0000000000000100;
|
16'b111111111111110x: encode = 16'b0000000000000010;
|
16'b111111111111110x: encode = 16'b0000000000000010;
|
16'b1111111111111110: encode = 16'b0000000000000001;
|
16'b1111111111111110: encode = 16'b0000000000000001;
|
default: encode = 16'b0000000000000000;
|
default: encode = 16'b0000000000000000;
|
endcase
|
endcase
|
else if (!(&b))
|
else if (!(&b))
|
casex (b)
|
casex (b)
|
16'b0xxxxxxxxxxxxxxx: encode = 16'b1000000000000000;
|
16'b0xxxxxxxxxxxxxxx: encode = 16'b1000000000000000;
|
16'b10xxxxxxxxxxxxxx: encode = 16'b0100000000000000;
|
16'b10xxxxxxxxxxxxxx: encode = 16'b0100000000000000;
|
16'b110xxxxxxxxxxxxx: encode = 16'b0010000000000000;
|
16'b110xxxxxxxxxxxxx: encode = 16'b0010000000000000;
|
16'b1110xxxxxxxxxxxx: encode = 16'b0001000000000000;
|
16'b1110xxxxxxxxxxxx: encode = 16'b0001000000000000;
|
16'b11110xxxxxxxxxxx: encode = 16'b0000100000000000;
|
16'b11110xxxxxxxxxxx: encode = 16'b0000100000000000;
|
16'b111110xxxxxxxxxx: encode = 16'b0000010000000000;
|
16'b111110xxxxxxxxxx: encode = 16'b0000010000000000;
|
16'b1111110xxxxxxxxx: encode = 16'b0000001000000000;
|
16'b1111110xxxxxxxxx: encode = 16'b0000001000000000;
|
16'b11111110xxxxxxxx: encode = 16'b0000000100000000;
|
16'b11111110xxxxxxxx: encode = 16'b0000000100000000;
|
16'b111111110xxxxxxx: encode = 16'b0000000010000000;
|
16'b111111110xxxxxxx: encode = 16'b0000000010000000;
|
16'b1111111110xxxxxx: encode = 16'b0000000001000000;
|
16'b1111111110xxxxxx: encode = 16'b0000000001000000;
|
16'b11111111110xxxxx: encode = 16'b0000000000100000;
|
16'b11111111110xxxxx: encode = 16'b0000000000100000;
|
16'b111111111110xxxx: encode = 16'b0000000000010000;
|
16'b111111111110xxxx: encode = 16'b0000000000010000;
|
16'b1111111111110xxx: encode = 16'b0000000000001000;
|
16'b1111111111110xxx: encode = 16'b0000000000001000;
|
16'b11111111111110xx: encode = 16'b0000000000000100;
|
16'b11111111111110xx: encode = 16'b0000000000000100;
|
16'b111111111111110x: encode = 16'b0000000000000010;
|
16'b111111111111110x: encode = 16'b0000000000000010;
|
16'b1111111111111110: encode = 16'b0000000000000001;
|
16'b1111111111111110: encode = 16'b0000000000000001;
|
default: encode = 16'b0000000000000000;
|
default: encode = 16'b0000000000000000;
|
endcase
|
endcase
|
else
|
else
|
casex (a)
|
casex (a)
|
16'b0xxxxxxxxxxxxxxx: encode = 16'b1000000000000000;
|
16'b0xxxxxxxxxxxxxxx: encode = 16'b1000000000000000;
|
16'b10xxxxxxxxxxxxxx: encode = 16'b0100000000000000;
|
16'b10xxxxxxxxxxxxxx: encode = 16'b0100000000000000;
|
16'b110xxxxxxxxxxxxx: encode = 16'b0010000000000000;
|
16'b110xxxxxxxxxxxxx: encode = 16'b0010000000000000;
|
16'b1110xxxxxxxxxxxx: encode = 16'b0001000000000000;
|
16'b1110xxxxxxxxxxxx: encode = 16'b0001000000000000;
|
16'b11110xxxxxxxxxxx: encode = 16'b0000100000000000;
|
16'b11110xxxxxxxxxxx: encode = 16'b0000100000000000;
|
16'b111110xxxxxxxxxx: encode = 16'b0000010000000000;
|
16'b111110xxxxxxxxxx: encode = 16'b0000010000000000;
|
16'b1111110xxxxxxxxx: encode = 16'b0000001000000000;
|
16'b1111110xxxxxxxxx: encode = 16'b0000001000000000;
|
16'b11111110xxxxxxxx: encode = 16'b0000000100000000;
|
16'b11111110xxxxxxxx: encode = 16'b0000000100000000;
|
16'b111111110xxxxxxx: encode = 16'b0000000010000000;
|
16'b111111110xxxxxxx: encode = 16'b0000000010000000;
|
16'b1111111110xxxxxx: encode = 16'b0000000001000000;
|
16'b1111111110xxxxxx: encode = 16'b0000000001000000;
|
16'b11111111110xxxxx: encode = 16'b0000000000100000;
|
16'b11111111110xxxxx: encode = 16'b0000000000100000;
|
16'b111111111110xxxx: encode = 16'b0000000000010000;
|
16'b111111111110xxxx: encode = 16'b0000000000010000;
|
16'b1111111111110xxx: encode = 16'b0000000000001000;
|
16'b1111111111110xxx: encode = 16'b0000000000001000;
|
16'b11111111111110xx: encode = 16'b0000000000000100;
|
16'b11111111111110xx: encode = 16'b0000000000000100;
|
16'b111111111111110x: encode = 16'b0000000000000010;
|
16'b111111111111110x: encode = 16'b0000000000000010;
|
16'b1111111111111110: encode = 16'b0000000000000001;
|
16'b1111111111111110: encode = 16'b0000000000000001;
|
default: encode = 16'b0000000000000000;
|
default: encode = 16'b0000000000000000;
|
endcase
|
endcase
|
end
|
end
|
endfunction
|
endfunction
|
|
|
assign fifo_sel = encode( fifo_empty_0, fifo_empty_1, fifo_empty_2, fifo_empty_3);
|
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 :
|
assign fifo_sel_domain = (!(&fifo_empty_3)) ? 2'b11 :
|
(!(&fifo_empty_2)) ? 2'b10 :
|
(!(&fifo_empty_2)) ? 2'b10 :
|
(!(&fifo_empty_1)) ? 2'b01 :
|
(!(&fifo_empty_1)) ? 2'b01 :
|
2'b00;
|
2'b00;
|
|
|
endmodule
|
endmodule
|
|
|
`timescale 1ns/1ns
|
`timescale 1ns/1ns
|
module decode (
|
module decode (
|
fifo_sel, fifo_sel_domain,
|
fifo_sel, fifo_sel_domain,
|
fifo_we_0, fifo_we_1, fifo_we_2, fifo_we_3
|
fifo_we_0, fifo_we_1, fifo_we_2, fifo_we_3
|
);
|
);
|
|
|
input [0:15] fifo_sel;
|
input [0:15] fifo_sel;
|
input [1:0] fifo_sel_domain;
|
input [1:0] fifo_sel_domain;
|
output [0:15] fifo_we_0, fifo_we_1, fifo_we_2, fifo_we_3;
|
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_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_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_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}};
|
assign fifo_we_3 = (fifo_sel_domain == 2'b11) ? fifo_sel : {16{1'b0}};
|
|
|
endmodule
|
endmodule
|
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
//// ////
|
//// ////
|
//// Versatile counter ////
|
//// Versatile counter ////
|
//// ////
|
//// ////
|
//// Description ////
|
//// Description ////
|
//// Versatile counter, a reconfigurable binary, gray or LFSR ////
|
//// Versatile counter, a reconfigurable binary, gray or LFSR ////
|
//// counter ////
|
//// counter ////
|
//// ////
|
//// ////
|
//// To Do: ////
|
//// To Do: ////
|
//// - add LFSR with more taps ////
|
//// - add LFSR with more taps ////
|
//// ////
|
//// ////
|
//// Author(s): ////
|
//// Author(s): ////
|
//// - Michael Unneback, unneback@opencores.org ////
|
//// - Michael Unneback, unneback@opencores.org ////
|
//// ORSoC AB ////
|
//// ORSoC AB ////
|
//// ////
|
//// ////
|
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
//// ////
|
//// ////
|
//// Copyright (C) 2009 Authors and OPENCORES.ORG ////
|
//// Copyright (C) 2009 Authors and OPENCORES.ORG ////
|
//// ////
|
//// ////
|
//// This source file may be used and distributed without ////
|
//// This source file may be used and distributed without ////
|
//// restriction provided that this copyright statement is not ////
|
//// restriction provided that this copyright statement is not ////
|
//// removed from the file and that any derivative work contains ////
|
//// removed from the file and that any derivative work contains ////
|
//// the original copyright notice and the associated disclaimer. ////
|
//// the original copyright notice and the associated disclaimer. ////
|
//// ////
|
//// ////
|
//// This source file is free software; you can redistribute it ////
|
//// This source file is free software; you can redistribute it ////
|
//// and/or modify it under the terms of the GNU Lesser General ////
|
//// and/or modify it under the terms of the GNU Lesser General ////
|
//// Public License as published by the Free Software Foundation; ////
|
//// Public License as published by the Free Software Foundation; ////
|
//// either version 2.1 of the License, or (at your option) any ////
|
//// either version 2.1 of the License, or (at your option) any ////
|
//// later version. ////
|
//// later version. ////
|
//// ////
|
//// ////
|
//// This source is distributed in the hope that it will be ////
|
//// This source is distributed in the hope that it will be ////
|
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
//// details. ////
|
//// details. ////
|
//// ////
|
//// ////
|
//// You should have received a copy of the GNU Lesser General ////
|
//// You should have received a copy of the GNU Lesser General ////
|
//// Public License along with this source; if not, download it ////
|
//// Public License along with this source; if not, download it ////
|
//// from http://www.opencores.org/lgpl.shtml ////
|
//// from http://www.opencores.org/lgpl.shtml ////
|
//// ////
|
//// ////
|
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
|
|
// GRAY counter
|
// GRAY counter
|
module gray_counter ( cke, q, q_bin, rst, clk);
|
module gray_counter ( cke, q, q_bin, rst, clk);
|
|
|
parameter length = 4;
|
parameter length = 4;
|
input cke;
|
input cke;
|
output reg [length:1] q;
|
output reg [length:1] q;
|
output [length:1] q_bin;
|
output [length:1] q_bin;
|
input rst;
|
input rst;
|
input clk;
|
input clk;
|
|
|
parameter clear_value = 0;
|
parameter clear_value = 0;
|
|
|
reg [length:1] qi;
|
reg [length:1] qi;
|
wire [length:1] q_next;
|
wire [length:1] q_next;
|
assign q_next = qi + {{length-1{1'b0}},1'b1};
|
assign q_next = qi + {{length-1{1'b0}},1'b1};
|
|
|
always @ (posedge clk or posedge rst)
|
always @ (posedge clk or posedge rst)
|
if (rst)
|
if (rst)
|
qi <= {length{1'b0}};
|
qi <= {length{1'b0}};
|
else
|
else
|
if (cke)
|
if (cke)
|
qi <= q_next;
|
qi <= q_next;
|
|
|
always @ (posedge clk or posedge rst)
|
always @ (posedge clk or posedge rst)
|
if (rst)
|
if (rst)
|
q <= {length{1'b0}};
|
q <= {length{1'b0}};
|
else
|
else
|
if (cke)
|
if (cke)
|
q <= (q_next>>1) ^ q_next;
|
q <= (q_next>>1) ^ q_next;
|
|
|
assign q_bin = qi;
|
assign q_bin = qi;
|
|
|
endmodule
|
endmodule
|
// async FIFO with multiple queues, multiple data
|
// async FIFO with multiple queues, multiple data
|
`define ORIGINAL_EGRESS_FIFO
|
`define ORIGINAL_EGRESS_FIFO
|
`ifdef ORIGINAL_EGRESS_FIFO
|
`ifdef ORIGINAL_EGRESS_FIFO
|
module egress_fifo (
|
module egress_fifo (
|
d, fifo_full, write, write_enable, clk1, rst1,
|
d, fifo_full, write, write_enable, clk1, rst1,
|
q, fifo_empty, read_adr, read_data, read_enable, clk2, rst2
|
q, fifo_empty, read_adr, read_data, read_enable, clk2, rst2
|
);
|
);
|
|
|
parameter a_hi_size = 4;
|
parameter a_hi_size = 4;
|
parameter a_lo_size = 4;
|
parameter a_lo_size = 4;
|
parameter nr_of_queues = 16;
|
parameter nr_of_queues = 16;
|
parameter data_width = 36;
|
parameter data_width = 36;
|
|
|
input [data_width*nr_of_queues-1:0] d;
|
input [data_width*nr_of_queues-1:0] d;
|
output [0:nr_of_queues-1] fifo_full;
|
output [0:nr_of_queues-1] fifo_full;
|
input write;
|
input write;
|
input [0:nr_of_queues-1] write_enable;
|
input [0:nr_of_queues-1] write_enable;
|
input clk1;
|
input clk1;
|
input rst1;
|
input rst1;
|
|
|
output reg [data_width-1:0] q;
|
output reg [data_width-1:0] q;
|
output [0:nr_of_queues-1] fifo_empty;
|
output [0:nr_of_queues-1] fifo_empty;
|
input read_adr, read_data;
|
input read_adr, read_data;
|
input [0:nr_of_queues-1] read_enable;
|
input [0:nr_of_queues-1] read_enable;
|
input clk2;
|
input clk2;
|
input rst2;
|
input rst2;
|
|
|
wire [data_width-1:0] fifo_q;
|
wire [data_width-1:0] fifo_q;
|
|
|
wire [a_lo_size-1:0] fifo_wadr_bin[0:nr_of_queues-1];
|
wire [a_lo_size-1:0] fifo_wadr_bin[0:nr_of_queues-1];
|
wire [a_lo_size-1:0] fifo_wadr_gray[0:nr_of_queues-1];
|
wire [a_lo_size-1:0] fifo_wadr_gray[0:nr_of_queues-1];
|
wire [a_lo_size-1:0] fifo_radr_bin[0:nr_of_queues-1];
|
wire [a_lo_size-1:0] fifo_radr_bin[0:nr_of_queues-1];
|
wire [a_lo_size-1:0] fifo_radr_gray[0:nr_of_queues-1];
|
wire [a_lo_size-1:0] fifo_radr_gray[0:nr_of_queues-1];
|
reg [a_lo_size-1:0] wadr;
|
reg [a_lo_size-1:0] wadr;
|
reg [a_lo_size-1:0] radr;
|
reg [a_lo_size-1:0] radr;
|
reg [data_width-1:0] wdata;
|
reg [data_width-1:0] wdata;
|
wire [data_width-1:0] wdataa[0:nr_of_queues-1];
|
wire [data_width-1:0] wdataa[0:nr_of_queues-1];
|
|
|
reg read_adr_reg;
|
reg read_adr_reg;
|
reg [0:nr_of_queues-1] read_enable_reg;
|
reg [0:nr_of_queues-1] read_enable_reg;
|
|
|
genvar i;
|
genvar i;
|
integer j,k,l;
|
integer j,k,l;
|
|
|
function [a_lo_size-1:0] onehot2bin;
|
function [a_lo_size-1:0] onehot2bin;
|
input [0:nr_of_queues-1] a;
|
input [0:nr_of_queues-1] a;
|
integer i;
|
integer i;
|
begin
|
begin
|
onehot2bin = {a_lo_size{1'b0}};
|
onehot2bin = {a_lo_size{1'b0}};
|
for (i=1;i<nr_of_queues;i=i+1) begin
|
for (i=1;i<nr_of_queues;i=i+1) begin
|
if (a[i])
|
if (a[i])
|
onehot2bin = i;
|
onehot2bin = i;
|
end
|
end
|
end
|
end
|
endfunction
|
endfunction
|
|
|
// a pipeline stage for address read gives higher clock frequency but adds one
|
// a pipeline stage for address read gives higher clock frequency but adds one
|
// clock latency for adr read
|
// clock latency for adr read
|
always @ (posedge clk2 or posedge rst2)
|
always @ (posedge clk2 or posedge rst2)
|
if (rst2)
|
if (rst2)
|
read_adr_reg <= 1'b0;
|
read_adr_reg <= 1'b0;
|
else
|
else
|
read_adr_reg <= read_adr;
|
read_adr_reg <= read_adr;
|
|
|
always @ (posedge clk2 or posedge rst2)
|
always @ (posedge clk2 or posedge rst2)
|
if (rst2)
|
if (rst2)
|
read_enable_reg <= {nr_of_queues{1'b0}};
|
read_enable_reg <= {nr_of_queues{1'b0}};
|
else
|
else
|
if (read_adr)
|
if (read_adr)
|
read_enable_reg <= read_enable;
|
read_enable_reg <= read_enable;
|
|
|
|
|
generate
|
generate
|
for (i=0;i<nr_of_queues;i=i+1) begin : fifo_adr
|
for (i=0;i<nr_of_queues;i=i+1) begin : fifo_adr
|
|
|
gray_counter wadrcnt (
|
gray_counter wadrcnt (
|
.cke(write & write_enable[i]),
|
.cke(write & write_enable[i]),
|
.q(fifo_wadr_gray[i]),
|
.q(fifo_wadr_gray[i]),
|
.q_bin(fifo_wadr_bin[i]),
|
.q_bin(fifo_wadr_bin[i]),
|
.rst(rst1),
|
.rst(rst1),
|
.clk(clk1));
|
.clk(clk1));
|
|
|
gray_counter radrcnt (
|
gray_counter radrcnt (
|
.cke((read_adr_reg | read_data) & read_enable_reg[i]),
|
.cke((read_adr_reg | read_data) & read_enable_reg[i]),
|
.q(fifo_radr_gray[i]),
|
.q(fifo_radr_gray[i]),
|
.q_bin(fifo_radr_bin[i]),
|
.q_bin(fifo_radr_bin[i]),
|
.rst(rst2),
|
.rst(rst2),
|
.clk(clk2));
|
.clk(clk2));
|
|
|
versatile_fifo_async_cmp
|
versatile_fifo_async_cmp
|
#(.ADDR_WIDTH(a_lo_size))
|
#(.ADDR_WIDTH(a_lo_size))
|
egresscmp (
|
egresscmp (
|
.wptr(fifo_wadr_gray[i]),
|
.wptr(fifo_wadr_gray[i]),
|
.rptr(fifo_radr_gray[i]),
|
.rptr(fifo_radr_gray[i]),
|
.fifo_empty(fifo_empty[i]),
|
.fifo_empty(fifo_empty[i]),
|
.fifo_full(fifo_full[i]),
|
.fifo_full(fifo_full[i]),
|
.wclk(clk1),
|
.wclk(clk1),
|
.rclk(clk2),
|
.rclk(clk2),
|
.rst(rst1));
|
.rst(rst1));
|
|
|
end
|
end
|
endgenerate
|
endgenerate
|
|
|
// and-or mux write address
|
// and-or mux write address
|
always @*
|
always @*
|
begin
|
begin
|
wadr = {a_lo_size{1'b0}};
|
wadr = {a_lo_size{1'b0}};
|
for (j=0;j<nr_of_queues;j=j+1) begin
|
for (j=0;j<nr_of_queues;j=j+1) begin
|
wadr = (fifo_wadr_bin[j] & {a_lo_size{write_enable[j]}}) | wadr;
|
wadr = (fifo_wadr_bin[j] & {a_lo_size{write_enable[j]}}) | wadr;
|
end
|
end
|
end
|
end
|
|
|
// and-or mux read address
|
// and-or mux read address
|
always @*
|
always @*
|
begin
|
begin
|
radr = {a_lo_size{1'b0}};
|
radr = {a_lo_size{1'b0}};
|
for (k=0;k<nr_of_queues;k=k+1) begin
|
for (k=0;k<nr_of_queues;k=k+1) begin
|
radr = (fifo_radr_bin[k] & {a_lo_size{read_enable_reg[k]}}) | radr;
|
radr = (fifo_radr_bin[k] & {a_lo_size{read_enable_reg[k]}}) | radr;
|
end
|
end
|
end
|
end
|
|
|
// and-or mux write data
|
// and-or mux write data
|
generate
|
generate
|
for (i=0;i<nr_of_queues;i=i+1) begin : vector2array
|
for (i=0;i<nr_of_queues;i=i+1) begin : vector2array
|
assign wdataa[i] = d[(nr_of_queues-i)*data_width-1:(nr_of_queues-1-i)*data_width];
|
assign wdataa[i] = d[(nr_of_queues-i)*data_width-1:(nr_of_queues-1-i)*data_width];
|
end
|
end
|
endgenerate
|
endgenerate
|
|
|
always @*
|
always @*
|
begin
|
begin
|
wdata = {data_width{1'b0}};
|
wdata = {data_width{1'b0}};
|
for (l=0;l<nr_of_queues;l=l+1) begin
|
for (l=0;l<nr_of_queues;l=l+1) begin
|
wdata = (wdataa[l] & {data_width{write_enable[l]}}) | wdata;
|
wdata = (wdataa[l] & {data_width{write_enable[l]}}) | wdata;
|
end
|
end
|
end
|
end
|
|
|
|
|
|
|
vfifo_dual_port_ram_dc_sw
|
vfifo_dual_port_ram_dc_sw
|
# (
|
# (
|
.DATA_WIDTH(data_width),
|
.DATA_WIDTH(data_width),
|
.ADDR_WIDTH(a_hi_size+a_lo_size)
|
.ADDR_WIDTH(a_hi_size+a_lo_size)
|
)
|
)
|
dpram (
|
dpram (
|
.d_a(wdata),
|
.d_a(wdata),
|
.adr_a({onehot2bin(write_enable),wadr}),
|
.adr_a({onehot2bin(write_enable),wadr}),
|
.we_a(write),
|
.we_a(write),
|
.clk_a(clk1),
|
.clk_a(clk1),
|
.q_b(fifo_q),
|
.q_b(fifo_q),
|
.adr_b({onehot2bin(read_enable_reg),radr}),
|
.adr_b({onehot2bin(read_enable_reg),radr}),
|
.clk_b(clk2) );
|
.clk_b(clk2) );
|
|
|
// Added registering of FIFO output to break a timing path
|
// Added registering of FIFO output to break a timing path
|
always@(posedge clk2)
|
always@(posedge clk2)
|
q <= fifo_q;
|
q <= fifo_q;
|
|
|
|
|
endmodule
|
endmodule
|
`else // !`ifdef ORIGINAL_EGRESS_FIFO
|
`else // !`ifdef ORIGINAL_EGRESS_FIFO
|
module egress_fifo (
|
module egress_fifo (
|
d, fifo_full, write, write_enable, clk1, rst1,
|
d, fifo_full, write, write_enable, clk1, rst1,
|
q, fifo_empty, read_adr, read_data, read_enable, clk2, rst2
|
q, fifo_empty, read_adr, read_data, read_enable, clk2, rst2
|
);
|
);
|
|
|
parameter a_hi_size = 2;
|
parameter a_hi_size = 2;
|
parameter a_lo_size = 4;
|
parameter a_lo_size = 4;
|
parameter nr_of_queues = 16;
|
parameter nr_of_queues = 16;
|
parameter data_width = 36;
|
parameter data_width = 36;
|
|
|
input [data_width*nr_of_queues-1:0] d;
|
input [data_width*nr_of_queues-1:0] d;
|
output [0:nr_of_queues-1] fifo_full;
|
output [0:nr_of_queues-1] fifo_full;
|
input write;
|
input write;
|
input [0:nr_of_queues-1] write_enable;
|
input [0:nr_of_queues-1] write_enable;
|
input clk1;
|
input clk1;
|
input rst1;
|
input rst1;
|
|
|
output reg [data_width-1:0] q;
|
output reg [data_width-1:0] q;
|
output [0:nr_of_queues-1] fifo_empty;
|
output [0:nr_of_queues-1] fifo_empty;
|
input read_adr, read_data;
|
input read_adr, read_data;
|
input [0:nr_of_queues-1] read_enable;
|
input [0:nr_of_queues-1] read_enable;
|
input clk2;
|
input clk2;
|
input rst2;
|
input rst2;
|
|
|
wire [data_width-1:0] fifo_q;
|
wire [data_width-1:0] fifo_q;
|
|
|
wire [a_lo_size-1:0] fifo_wadr_bin[0:nr_of_queues-1];
|
wire [a_lo_size-1:0] fifo_wadr_bin[0:nr_of_queues-1];
|
wire [a_lo_size-1:0] fifo_wadr_gray[0:nr_of_queues-1];
|
wire [a_lo_size-1:0] fifo_wadr_gray[0:nr_of_queues-1];
|
wire [a_lo_size-1:0] fifo_radr_bin[0:nr_of_queues-1];
|
wire [a_lo_size-1:0] fifo_radr_bin[0:nr_of_queues-1];
|
wire [a_lo_size-1:0] fifo_radr_gray[0:nr_of_queues-1];
|
wire [a_lo_size-1:0] fifo_radr_gray[0:nr_of_queues-1];
|
wire [a_lo_size-1:0] wadr;
|
wire [a_lo_size-1:0] wadr;
|
wire [a_lo_size-1:0] radr;
|
wire [a_lo_size-1:0] radr;
|
wire [data_width-1:0] wdata;
|
wire [data_width-1:0] wdata;
|
wire [data_width-1:0] wdataa[0:nr_of_queues-1];
|
wire [data_width-1:0] wdataa[0:nr_of_queues-1];
|
|
|
reg read_adr_reg;
|
reg read_adr_reg;
|
reg [0:nr_of_queues-1] read_enable_reg;
|
reg [0:nr_of_queues-1] read_enable_reg;
|
|
|
genvar i;
|
genvar i;
|
integer j,k,l;
|
integer j,k,l;
|
|
|
// a pipeline stage for address read gives higher clock frequency but adds one
|
// a pipeline stage for address read gives higher clock frequency but adds one
|
// clock latency for adr read
|
// clock latency for adr read
|
always @ (posedge clk2 or posedge rst2)
|
always @ (posedge clk2 or posedge rst2)
|
if (rst2)
|
if (rst2)
|
read_adr_reg <= 1'b0;
|
read_adr_reg <= 1'b0;
|
else
|
else
|
read_adr_reg <= read_adr;
|
read_adr_reg <= read_adr;
|
|
|
always @ (posedge clk2 or posedge rst2)
|
always @ (posedge clk2 or posedge rst2)
|
if (rst2)
|
if (rst2)
|
read_enable_reg <= {nr_of_queues{1'b0}};
|
read_enable_reg <= {nr_of_queues{1'b0}};
|
else
|
else
|
if (read_adr)
|
if (read_adr)
|
read_enable_reg <= read_enable;
|
read_enable_reg <= read_enable;
|
|
|
// 0
|
// 0
|
gray_counter wadrcnt0
|
gray_counter wadrcnt0
|
(
|
(
|
.cke(write & write_enable[0]),
|
.cke(write & write_enable[0]),
|
.q(fifo_wadr_gray[0]),
|
.q(fifo_wadr_gray[0]),
|
.q_bin(fifo_wadr_bin[0]),
|
.q_bin(fifo_wadr_bin[0]),
|
.rst(rst1),
|
.rst(rst1),
|
.clk(clk1)
|
.clk(clk1)
|
);
|
);
|
|
|
gray_counter radrcnt0
|
gray_counter radrcnt0
|
(
|
(
|
.cke((read_adr_reg | read_data) & read_enable_reg[0]),
|
.cke((read_adr_reg | read_data) & read_enable_reg[0]),
|
.q(fifo_radr_gray[0]),
|
.q(fifo_radr_gray[0]),
|
.q_bin(fifo_radr_bin[0]),
|
.q_bin(fifo_radr_bin[0]),
|
.rst(rst2),
|
.rst(rst2),
|
.clk(clk2)
|
.clk(clk2)
|
);
|
);
|
|
|
versatile_fifo_async_cmp
|
versatile_fifo_async_cmp
|
#(
|
#(
|
.ADDR_WIDTH(a_lo_size)
|
.ADDR_WIDTH(a_lo_size)
|
)
|
)
|
egresscmp0
|
egresscmp0
|
(
|
(
|
.wptr(fifo_wadr_gray[0]),
|
.wptr(fifo_wadr_gray[0]),
|
.rptr(fifo_radr_gray[0]),
|
.rptr(fifo_radr_gray[0]),
|
.fifo_empty(fifo_empty[0]),
|
.fifo_empty(fifo_empty[0]),
|
.fifo_full(fifo_full[0]),
|
.fifo_full(fifo_full[0]),
|
.wclk(clk1),
|
.wclk(clk1),
|
.rclk(clk2),
|
.rclk(clk2),
|
.rst(rst1)
|
.rst(rst1)
|
);
|
);
|
|
|
// 1
|
// 1
|
gray_counter wadrcnt1
|
gray_counter wadrcnt1
|
(
|
(
|
.cke(write & write_enable[1]),
|
.cke(write & write_enable[1]),
|
.q(fifo_wadr_gray[1]),
|
.q(fifo_wadr_gray[1]),
|
.q_bin(fifo_wadr_bin[1]),
|
.q_bin(fifo_wadr_bin[1]),
|
.rst(rst1),
|
.rst(rst1),
|
.clk(clk1)
|
.clk(clk1)
|
);
|
);
|
|
|
gray_counter radrcnt1
|
gray_counter radrcnt1
|
(
|
(
|
.cke((read_adr_reg | read_data) & read_enable_reg[1]),
|
.cke((read_adr_reg | read_data) & read_enable_reg[1]),
|
.q(fifo_radr_gray[1]),
|
.q(fifo_radr_gray[1]),
|
.q_bin(fifo_radr_bin[1]),
|
.q_bin(fifo_radr_bin[1]),
|
.rst(rst2),
|
.rst(rst2),
|
.clk(clk2)
|
.clk(clk2)
|
);
|
);
|
|
|
versatile_fifo_async_cmp
|
versatile_fifo_async_cmp
|
#(
|
#(
|
.ADDR_WIDTH(a_lo_size)
|
.ADDR_WIDTH(a_lo_size)
|
)
|
)
|
egresscmp1
|
egresscmp1
|
(
|
(
|
.wptr(fifo_wadr_gray[1]),
|
.wptr(fifo_wadr_gray[1]),
|
.rptr(fifo_radr_gray[1]),
|
.rptr(fifo_radr_gray[1]),
|
.fifo_empty(fifo_empty[1]),
|
.fifo_empty(fifo_empty[1]),
|
.fifo_full(fifo_full[1]),
|
.fifo_full(fifo_full[1]),
|
.wclk(clk1),
|
.wclk(clk1),
|
.rclk(clk2),
|
.rclk(clk2),
|
.rst(rst1)
|
.rst(rst1)
|
);
|
);
|
|
|
// 2
|
// 2
|
gray_counter wadrcnt2
|
gray_counter wadrcnt2
|
(
|
(
|
.cke(write & write_enable[2]),
|
.cke(write & write_enable[2]),
|
.q(fifo_wadr_gray[2]),
|
.q(fifo_wadr_gray[2]),
|
.q_bin(fifo_wadr_bin[2]),
|
.q_bin(fifo_wadr_bin[2]),
|
.rst(rst1),
|
.rst(rst1),
|
.clk(clk1)
|
.clk(clk1)
|
);
|
);
|
|
|
gray_counter radrcnt2
|
gray_counter radrcnt2
|
(
|
(
|
.cke((read_adr_reg | read_data) & read_enable_reg[2]),
|
.cke((read_adr_reg | read_data) & read_enable_reg[2]),
|
.q(fifo_radr_gray[2]),
|
.q(fifo_radr_gray[2]),
|
.q_bin(fifo_radr_bin[2]),
|
.q_bin(fifo_radr_bin[2]),
|
.rst(rst2),
|
.rst(rst2),
|
.clk(clk2)
|
.clk(clk2)
|
);
|
);
|
|
|
versatile_fifo_async_cmp
|
versatile_fifo_async_cmp
|
#(
|
#(
|
.ADDR_WIDTH(a_lo_size)
|
.ADDR_WIDTH(a_lo_size)
|
)
|
)
|
egresscmp2
|
egresscmp2
|
(
|
(
|
.wptr(fifo_wadr_gray[2]),
|
.wptr(fifo_wadr_gray[2]),
|
.rptr(fifo_radr_gray[2]),
|
.rptr(fifo_radr_gray[2]),
|
.fifo_empty(fifo_empty[2]),
|
.fifo_empty(fifo_empty[2]),
|
.fifo_full(fifo_full[2]),
|
.fifo_full(fifo_full[2]),
|
.wclk(clk1),
|
.wclk(clk1),
|
.rclk(clk2),
|
.rclk(clk2),
|
.rst(rst1)
|
.rst(rst1)
|
);
|
);
|
|
|
|
|
assign wadr = (fifo_wadr_bin[0] & {a_lo_size{write_enable[0]}}) |
|
assign wadr = (fifo_wadr_bin[0] & {a_lo_size{write_enable[0]}}) |
|
(fifo_wadr_bin[1] & {a_lo_size{write_enable[1]}}) |
|
(fifo_wadr_bin[1] & {a_lo_size{write_enable[1]}}) |
|
(fifo_wadr_bin[2] & {a_lo_size{write_enable[2]}});
|
(fifo_wadr_bin[2] & {a_lo_size{write_enable[2]}});
|
|
|
assign radr = (fifo_radr_bin[0] & {a_lo_size{read_enable_reg[0]}}) |
|
assign radr = (fifo_radr_bin[0] & {a_lo_size{read_enable_reg[0]}}) |
|
(fifo_radr_bin[1] & {a_lo_size{read_enable_reg[1]}}) |
|
(fifo_radr_bin[1] & {a_lo_size{read_enable_reg[1]}}) |
|
(fifo_radr_bin[2] & {a_lo_size{read_enable_reg[2]}});
|
(fifo_radr_bin[2] & {a_lo_size{read_enable_reg[2]}});
|
|
|
|
|
assign wdataa[0] = d[108-1:72];
|
assign wdataa[0] = d[108-1:72];
|
assign wdataa[1] = d[72-1:36];
|
assign wdataa[1] = d[72-1:36];
|
assign wdataa[2] = d[36-1:0];
|
assign wdataa[2] = d[36-1:0];
|
|
|
assign wdata = ( d[108-1:72] & {data_width{write_enable[0]}}) |
|
assign wdata = ( d[108-1:72] & {data_width{write_enable[0]}}) |
|
( d[72-1:36] & {data_width{write_enable[1]}}) |
|
( d[72-1:36] & {data_width{write_enable[1]}}) |
|
( d[36-1:0] & {data_width{write_enable[2]}});
|
( d[36-1:0] & {data_width{write_enable[2]}});
|
|
|
wire [1:0] wadr_top;
|
wire [1:0] wadr_top;
|
assign wadr_top = write_enable[1] ? 2'b01 :
|
assign wadr_top = write_enable[1] ? 2'b01 :
|
write_enable[2] ? 2'b10 :
|
write_enable[2] ? 2'b10 :
|
2'b00;
|
2'b00;
|
wire [1:0] radr_top;
|
wire [1:0] radr_top;
|
assign radr_top = read_enable_reg[1] ? 2'b01 :
|
assign radr_top = read_enable_reg[1] ? 2'b01 :
|
read_enable_reg[2] ? 2'b10 :
|
read_enable_reg[2] ? 2'b10 :
|
2'b00;
|
2'b00;
|
|
|
vfifo_dual_port_ram_dc_sw
|
vfifo_dual_port_ram_dc_sw
|
# (
|
# (
|
.DATA_WIDTH(data_width),
|
.DATA_WIDTH(data_width),
|
.ADDR_WIDTH(2+a_lo_size)
|
.ADDR_WIDTH(2+a_lo_size)
|
)
|
)
|
dpram (
|
dpram (
|
.d_a(wdata),
|
.d_a(wdata),
|
.adr_a({wadr_top,wadr}),
|
.adr_a({wadr_top,wadr}),
|
.we_a(write),
|
.we_a(write),
|
.clk_a(clk1),
|
.clk_a(clk1),
|
.q_b(fifo_q),
|
.q_b(fifo_q),
|
.adr_b({radr_top,radr}),
|
.adr_b({radr_top,radr}),
|
.clk_b(clk2) );
|
.clk_b(clk2) );
|
|
|
// Added registering of FIFO output to break a timing path
|
// Added registering of FIFO output to break a timing path
|
always@(posedge clk2)
|
always@(posedge clk2)
|
q <= fifo_q;
|
q <= fifo_q;
|
|
|
|
|
endmodule
|
endmodule
|
`endif // !`ifdef ORIGINAL_EGRESS_FIFO
|
`endif // !`ifdef ORIGINAL_EGRESS_FIFO
|
|
// true dual port RAM, sync
|
|
|
|
`ifdef ACTEL
|
|
`define SYN
|
|
`endif
|
module vfifo_dual_port_ram_dc_sw
|
module vfifo_dual_port_ram_dc_sw
|
(
|
(
|
d_a,
|
d_a,
|
adr_a,
|
adr_a,
|
we_a,
|
we_a,
|
clk_a,
|
clk_a,
|
q_b,
|
q_b,
|
adr_b,
|
adr_b,
|
clk_b
|
clk_b
|
);
|
);
|
parameter DATA_WIDTH = 32;
|
parameter DATA_WIDTH = 32;
|
parameter ADDR_WIDTH = 8;
|
parameter ADDR_WIDTH = 8;
|
input [(DATA_WIDTH-1):0] d_a;
|
input [(DATA_WIDTH-1):0] d_a;
|
input [(ADDR_WIDTH-1):0] adr_a;
|
input [(ADDR_WIDTH-1):0] adr_a;
|
input [(ADDR_WIDTH-1):0] adr_b;
|
input [(ADDR_WIDTH-1):0] adr_b;
|
input we_a;
|
input we_a;
|
output [(DATA_WIDTH-1):0] q_b;
|
output [(DATA_WIDTH-1):0] q_b;
|
input clk_a, clk_b;
|
input clk_a, clk_b;
|
reg [(ADDR_WIDTH-1):0] adr_b_reg;
|
reg [(ADDR_WIDTH-1):0] adr_b_reg;
|
reg [DATA_WIDTH-1:0] ram [(1<<ADDR_WIDTH)-1:0]/*synthesis syn_ramstyle = "no_rw_check"*/ ;
|
reg [DATA_WIDTH-1:0] ram [(1<<ADDR_WIDTH)-1:0] /*synthesis syn_ramstyle = "no_rw_check"*/;
|
always @ (posedge clk_a)
|
always @ (posedge clk_a)
|
if (we_a)
|
if (we_a)
|
ram[adr_a] <= d_a;
|
ram[adr_a] <= d_a;
|
always @ (posedge clk_b)
|
always @ (posedge clk_b)
|
adr_b_reg <= adr_b;
|
adr_b_reg <= adr_b;
|
assign q_b = ram[adr_b_reg];
|
assign q_b = ram[adr_b_reg];
|
endmodule
|
endmodule
|
`timescale 1ns/1ns
|
`timescale 1ns/1ns
|
`include "sdr_16_defines.v"
|
`include "sdr_16_defines.v"
|
module fsm_sdr_16 (
|
module fsm_sdr_16 (
|
adr_i, we_i, bte_i, cti_i, sel_i,
|
adr_i, we_i, bte_i, cti_i, sel_i,
|
fifo_empty, fifo_rd_adr, fifo_rd_data, count0,
|
fifo_empty, fifo_rd_adr, fifo_rd_data, count0,
|
refresh_req, cmd_aref, cmd_read, state_idle,
|
refresh_req, cmd_aref, cmd_read, state_idle,
|
ba, a, cmd, dqm, dq_oe,
|
ba, a, cmd, dqm, dq_oe,
|
sdram_burst_reading,
|
sdram_burst_reading,
|
debug_state, debug_fifo_we_record,
|
debug_state, debug_fifo_we_record,
|
sdram_clk, sdram_fifo_wr, sdram_rst
|
sdram_clk, sdram_fifo_wr, sdram_rst
|
);
|
);
|
|
|
/* Now these are defined
|
/* Now these are defined
|
parameter ba_size = 2;
|
parameter ba_size = 2;
|
parameter row_size = 13;
|
parameter row_size = 13;
|
parameter col_size = 9;
|
parameter col_size = 9;
|
*/
|
*/
|
|
|
input [`BA_SIZE+`ROW_SIZE+`COL_SIZE-1:0] adr_i;
|
input [`BA_SIZE+`ROW_SIZE+`COL_SIZE-1:0] adr_i;
|
input we_i;
|
input we_i;
|
input [1:0] bte_i;
|
input [1:0] bte_i;
|
input [2:0] cti_i;
|
input [2:0] cti_i;
|
input [3:0] sel_i;
|
input [3:0] sel_i;
|
|
|
input fifo_empty;
|
input fifo_empty;
|
output fifo_rd_adr, fifo_rd_data;
|
output fifo_rd_adr, fifo_rd_data;
|
output reg count0;
|
output reg count0;
|
|
|
input refresh_req;
|
input refresh_req;
|
output reg cmd_aref; // used for rerfresh ack
|
output reg cmd_aref; // used for rerfresh ack
|
output reg cmd_read; // used for ingress fifo control
|
output reg cmd_read; // used for ingress fifo control
|
output state_idle; // state=idle
|
output state_idle; // state=idle
|
|
|
output reg [1:0] ba /*synthesis syn_useioff=1 syn_allow_retiming=0 */;
|
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 [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 [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 [1:0] dqm /*synthesis syn_useioff=1 syn_allow_retiming=0 */;
|
output reg dq_oe;
|
output reg dq_oe;
|
|
|
output sdram_burst_reading;
|
output sdram_burst_reading;
|
input sdram_clk, sdram_fifo_wr, sdram_rst;
|
input sdram_clk, sdram_fifo_wr, sdram_rst;
|
|
|
output [2:0] debug_state;
|
output [2:0] debug_state;
|
output [3:0] debug_fifo_we_record;
|
output [3:0] debug_fifo_we_record;
|
|
|
wire [`BA_SIZE-1:0] bank;
|
wire [`BA_SIZE-1:0] bank;
|
wire [`ROW_SIZE-1:0] row;
|
wire [`ROW_SIZE-1:0] row;
|
wire [`COL_SIZE-1:0] col;
|
wire [`COL_SIZE-1:0] col;
|
wire [12:0] col_reg_a10_fix;
|
wire [12:0] col_reg_a10_fix;
|
reg [0:31] shreg;
|
reg [0:31] shreg;
|
wire stall; // active if write burst need data
|
wire stall; // active if write burst need data
|
|
|
reg [0:15] fifo_sel_reg_int;
|
reg [0:15] fifo_sel_reg_int;
|
reg [1:0] fifo_sel_domain_reg_int;
|
reg [1:0] fifo_sel_domain_reg_int;
|
|
|
// adr_reg {ba,row,col,we}
|
// adr_reg {ba,row,col,we}
|
reg [1:0] ba_reg;
|
reg [1:0] ba_reg;
|
reg [`ROW_SIZE-1:0] row_reg;
|
reg [`ROW_SIZE-1:0] row_reg;
|
reg [`COL_SIZE-1:0] col_reg;
|
reg [`COL_SIZE-1:0] col_reg;
|
reg we_reg;
|
reg we_reg;
|
reg [1:0] bte_reg;
|
reg [1:0] bte_reg;
|
reg [2:0] cti_reg;
|
reg [2:0] cti_reg;
|
|
|
// to keep track of open rows per bank
|
// to keep track of open rows per bank
|
reg [`ROW_SIZE-1:0] open_row[0:3];
|
reg [`ROW_SIZE-1:0] open_row[0:3];
|
reg [0:3] open_ba;
|
reg [0:3] open_ba;
|
wire current_bank_closed, current_row_open;
|
wire current_bank_closed, current_row_open;
|
reg current_bank_closed_reg, current_row_open_reg;
|
reg current_bank_closed_reg, current_row_open_reg;
|
|
|
parameter [2:0] classic=3'b000,
|
parameter [2:0] classic=3'b000,
|
constant=3'b001,
|
constant=3'b001,
|
increment=3'b010,
|
increment=3'b010,
|
endburst=3'b111;
|
endburst=3'b111;
|
|
|
parameter [1:0] linear = 2'b00,
|
parameter [1:0] linear = 2'b00,
|
beat4 = 2'b01,
|
beat4 = 2'b01,
|
beat8 = 2'b10,
|
beat8 = 2'b10,
|
beat16 = 2'b11;
|
beat16 = 2'b11;
|
|
|
parameter [2:0] cmd_nop = 3'b111,
|
parameter [2:0] cmd_nop = 3'b111,
|
cmd_act = 3'b011,
|
cmd_act = 3'b011,
|
cmd_rd = 3'b101,
|
cmd_rd = 3'b101,
|
cmd_wr = 3'b100,
|
cmd_wr = 3'b100,
|
cmd_pch = 3'b010,
|
cmd_pch = 3'b010,
|
cmd_rfr = 3'b001,
|
cmd_rfr = 3'b001,
|
cmd_lmr = 3'b000;
|
cmd_lmr = 3'b000;
|
|
|
// ctrl FSM
|
// ctrl FSM
|
|
|
/* define instead of param, as synplify is doing weird things
|
/* define instead of param, as synplify is doing weird things
|
parameter [2:0] init = 3'b000,
|
parameter [2:0] init = 3'b000,
|
idle = 3'b001,
|
idle = 3'b001,
|
rfr = 3'b010,
|
rfr = 3'b010,
|
adr = 3'b011,
|
adr = 3'b011,
|
pch = 3'b100,
|
pch = 3'b100,
|
act = 3'b101,
|
act = 3'b101,
|
w4d = 3'b110,
|
w4d = 3'b110,
|
rw = 3'b111;
|
rw = 3'b111;
|
*/
|
*/
|
`define FSM_INIT 3'b000
|
`define FSM_INIT 3'b000
|
`define FSM_IDLE 3'b001
|
`define FSM_IDLE 3'b001
|
`define FSM_RFR 3'b010
|
`define FSM_RFR 3'b010
|
`define FSM_ADR 3'b011
|
`define FSM_ADR 3'b011
|
`define FSM_PCH 3'b100
|
`define FSM_PCH 3'b100
|
`define FSM_ACT 3'b101
|
`define FSM_ACT 3'b101
|
`define FSM_W4D 3'b110
|
`define FSM_W4D 3'b110
|
`define FSM_RW 3'b111
|
`define FSM_RW 3'b111
|
|
|
reg [2:0] state, next;
|
reg [2:0] state, next;
|
|
|
assign debug_state = state;
|
assign debug_state = state;
|
|
|
function [12:0] a10_fix;
|
function [12:0] a10_fix;
|
input [`COL_SIZE-1:0] a;
|
input [`COL_SIZE-1:0] a;
|
integer i;
|
integer i;
|
begin
|
begin
|
for (i=0;i<13;i=i+1) begin
|
for (i=0;i<13;i=i+1) begin
|
if (i<10)
|
if (i<10)
|
if (i<`COL_SIZE)
|
if (i<`COL_SIZE)
|
a10_fix[i] = a[i];
|
a10_fix[i] = a[i];
|
else
|
else
|
a10_fix[i] = 1'b0;
|
a10_fix[i] = 1'b0;
|
else if (i==10)
|
else if (i==10)
|
a10_fix[i] = 1'b0;
|
a10_fix[i] = 1'b0;
|
else
|
else
|
if (i<`COL_SIZE)
|
if (i<`COL_SIZE)
|
a10_fix[i] = a[i-1];
|
a10_fix[i] = a[i-1];
|
else
|
else
|
a10_fix[i] = 1'b0;
|
a10_fix[i] = 1'b0;
|
end
|
end
|
end
|
end
|
endfunction
|
endfunction
|
|
|
|
|
assign {bank,row,col} = adr_i;
|
assign {bank,row,col} = adr_i;
|
|
|
always @ (posedge sdram_clk or posedge sdram_rst)
|
always @ (posedge sdram_clk or posedge sdram_rst)
|
if (sdram_rst)
|
if (sdram_rst)
|
state <= `FSM_INIT;
|
state <= `FSM_INIT;
|
else
|
else
|
state <= next;
|
state <= next;
|
|
|
always @*
|
always @*
|
begin
|
begin
|
next = 3'bx;
|
next = 3'bx;
|
case (state)
|
case (state)
|
`FSM_INIT:
|
`FSM_INIT:
|
if (shreg[31])
|
if (shreg[31])
|
next = `FSM_IDLE;
|
next = `FSM_IDLE;
|
else
|
else
|
next = `FSM_INIT;
|
next = `FSM_INIT;
|
`FSM_IDLE:
|
`FSM_IDLE:
|
if (refresh_req)
|
if (refresh_req)
|
next = `FSM_RFR;
|
next = `FSM_RFR;
|
else if (!shreg[0] & !fifo_empty)
|
else if (!shreg[0] & !fifo_empty)
|
next = `FSM_ADR;
|
next = `FSM_ADR;
|
else
|
else
|
next = `FSM_IDLE;
|
next = `FSM_IDLE;
|
`FSM_RFR:
|
`FSM_RFR:
|
if (shreg[5])
|
if (shreg[5])
|
next = `FSM_IDLE;
|
next = `FSM_IDLE;
|
else
|
else
|
next = `FSM_RFR;
|
next = `FSM_RFR;
|
`FSM_ADR:
|
`FSM_ADR:
|
if (shreg[5])
|
if (shreg[5])
|
begin
|
begin
|
if (current_bank_closed_reg)
|
if (current_bank_closed_reg)
|
next = `FSM_ACT;
|
next = `FSM_ACT;
|
else if (current_row_open_reg)
|
else if (current_row_open_reg)
|
next = (we_reg) ? `FSM_W4D : `FSM_RW;
|
next = (we_reg) ? `FSM_W4D : `FSM_RW;
|
else
|
else
|
next = `FSM_PCH;
|
next = `FSM_PCH;
|
end
|
end
|
else
|
else
|
next = `FSM_ADR;
|
next = `FSM_ADR;
|
`FSM_PCH:
|
`FSM_PCH:
|
if (shreg[1])
|
if (shreg[1])
|
next = `FSM_ACT;
|
next = `FSM_ACT;
|
else
|
else
|
next = `FSM_PCH;
|
next = `FSM_PCH;
|
`FSM_ACT:
|
`FSM_ACT:
|
if (shreg[2])
|
if (shreg[2])
|
begin
|
begin
|
`ifdef SLOW_WB_CLOCK
|
`ifdef SLOW_WB_CLOCK
|
// Automatiacally go to wait for data if burst writing
|
// Automatiacally go to wait for data if burst writing
|
if ((|bte_reg) & we_reg & cti_reg==increment)
|
if ((|bte_reg) & we_reg & cti_reg==increment)
|
next = `FSM_W4D;
|
next = `FSM_W4D;
|
else if ((!fifo_empty | !we_reg))
|
else if ((!fifo_empty | !we_reg))
|
next = `FSM_RW;
|
next = `FSM_RW;
|
`else
|
`else
|
if ((!fifo_empty | !we_reg))
|
if ((!fifo_empty | !we_reg))
|
next = `FSM_RW;
|
next = `FSM_RW;
|
`endif
|
`endif
|
else if (fifo_empty)
|
else if (fifo_empty)
|
next = `FSM_W4D;
|
next = `FSM_W4D;
|
end
|
end
|
else
|
else
|
next = `FSM_ACT;
|
next = `FSM_ACT;
|
`ifdef SLOW_WB_CLOCK
|
`ifdef SLOW_WB_CLOCK
|
// Add some wait here if bursting and the wishbone clock is slow
|
// Add some wait here if bursting and the wishbone clock is slow
|
`FSM_W4D:
|
`FSM_W4D:
|
if (!fifo_empty & ((cti_reg!=increment)|(cti_reg==increment /*& bte_reg==beat4*/ & shreg[14])))
|
if (!fifo_empty & ((cti_reg!=increment)|(cti_reg==increment /*& bte_reg==beat4*/ & shreg[14])))
|
next = `FSM_RW;
|
next = `FSM_RW;
|
`else
|
`else
|
`FSM_W4D:
|
`FSM_W4D:
|
if (!fifo_empty)
|
if (!fifo_empty)
|
next = `FSM_RW;
|
next = `FSM_RW;
|
`endif
|
`endif
|
else
|
else
|
next = `FSM_W4D;
|
next = `FSM_W4D;
|
`FSM_RW:
|
`FSM_RW:
|
if ((bte_reg==linear | !(cti_reg==increment)) & shreg[1])
|
if ((bte_reg==linear | !(cti_reg==increment)) & shreg[1])
|
next = `FSM_IDLE;
|
next = `FSM_IDLE;
|
else if (bte_reg==beat4 & shreg[7])
|
else if (bte_reg==beat4 & shreg[7])
|
next = `FSM_IDLE;
|
next = `FSM_IDLE;
|
`ifdef BEAT8
|
`ifdef BEAT8
|
else if (bte_reg==beat8 & shreg[15])
|
else if (bte_reg==beat8 & shreg[15])
|
next = `FSM_IDLE;
|
next = `FSM_IDLE;
|
`endif
|
`endif
|
`ifdef BEAT16
|
`ifdef BEAT16
|
else if (bte_reg==beat16 & shreg[31])
|
else if (bte_reg==beat16 & shreg[31])
|
next = `FSM_IDLE;
|
next = `FSM_IDLE;
|
`endif
|
`endif
|
else
|
else
|
next = `FSM_RW;
|
next = `FSM_RW;
|
endcase
|
endcase
|
end // always @ *
|
end // always @ *
|
|
|
|
|
// active if write burst need data
|
// active if write burst need data
|
assign stall = state==`FSM_RW & next==`FSM_RW & fifo_empty & count0 & we_reg;
|
assign stall = state==`FSM_RW & next==`FSM_RW & fifo_empty & count0 & we_reg;
|
|
|
// counter
|
// counter
|
always @ (posedge sdram_clk or posedge sdram_rst)
|
always @ (posedge sdram_clk or posedge sdram_rst)
|
begin
|
begin
|
if (sdram_rst) begin
|
if (sdram_rst) begin
|
shreg <= {1'b1,{31{1'b0}}};
|
shreg <= {1'b1,{31{1'b0}}};
|
count0 <= 1'b0;
|
count0 <= 1'b0;
|
end else
|
end else
|
if (state!=next) begin
|
if (state!=next) begin
|
shreg <= {1'b1,{31{1'b0}}};
|
shreg <= {1'b1,{31{1'b0}}};
|
count0 <= 1'b0;
|
count0 <= 1'b0;
|
end else
|
end else
|
if (~stall) begin
|
if (~stall) begin
|
shreg <= shreg >> 1;
|
shreg <= shreg >> 1;
|
count0 <= ~count0;
|
count0 <= ~count0;
|
end
|
end
|
end
|
end
|
|
|
// ba, a, cmd
|
// ba, a, cmd
|
// col_reg_a10 has bit [10] set to zero to disable auto precharge
|
// col_reg_a10 has bit [10] set to zero to disable auto precharge
|
assign col_reg_a10_fix = a10_fix(col_reg);
|
assign col_reg_a10_fix = a10_fix(col_reg);
|
|
|
// outputs dependent on state vector
|
// outputs dependent on state vector
|
always @ (posedge sdram_clk or posedge sdram_rst)
|
always @ (posedge sdram_clk or posedge sdram_rst)
|
begin
|
begin
|
if (sdram_rst) begin
|
if (sdram_rst) begin
|
{ba,a,cmd} <= {2'b00,13'd0,cmd_nop};
|
{ba,a,cmd} <= {2'b00,13'd0,cmd_nop};
|
dqm <= 2'b11;
|
dqm <= 2'b11;
|
cmd_aref <= 1'b0;
|
cmd_aref <= 1'b0;
|
cmd_read <= 1'b0;
|
cmd_read <= 1'b0;
|
dq_oe <= 1'b0;
|
dq_oe <= 1'b0;
|
{open_ba,open_row[0],open_row[1],open_row[2],open_row[3]} <=
|
{open_ba,open_row[0],open_row[1],open_row[2],open_row[3]} <=
|
{4'b0000,{`ROW_SIZE*4{1'b0}}};
|
{4'b0000,{`ROW_SIZE*4{1'b0}}};
|
{ba_reg,row_reg,col_reg,we_reg,cti_reg,bte_reg} <=
|
{ba_reg,row_reg,col_reg,we_reg,cti_reg,bte_reg} <=
|
{2'b00, {`ROW_SIZE{1'b0}}, {`COL_SIZE{1'b0}}, 1'b0,3'b000, 2'b00 };
|
{2'b00, {`ROW_SIZE{1'b0}}, {`COL_SIZE{1'b0}}, 1'b0,3'b000, 2'b00 };
|
end else begin
|
end else begin
|
{ba,a,cmd} <= {2'b00,13'd0,cmd_nop};
|
{ba,a,cmd} <= {2'b00,13'd0,cmd_nop};
|
dqm <= 2'b11;
|
dqm <= 2'b11;
|
cmd_aref <= 1'b0;
|
cmd_aref <= 1'b0;
|
cmd_read <= 1'b0;
|
cmd_read <= 1'b0;
|
dq_oe <= 1'b0;
|
dq_oe <= 1'b0;
|
case (state)
|
case (state)
|
`FSM_INIT:
|
`FSM_INIT:
|
if (shreg[3]) begin
|
if (shreg[3]) begin
|
{ba,a,cmd} <= {2'b00, 13'b0010000000000, cmd_pch};
|
{ba,a,cmd} <= {2'b00, 13'b0010000000000, cmd_pch};
|
open_ba[ba_reg] <= 1'b0;
|
open_ba[ba_reg] <= 1'b0;
|
end else if (shreg[7] | shreg[19])
|
end else if (shreg[7] | shreg[19])
|
{ba,a,cmd,cmd_aref} <= {2'b00, 13'd0, cmd_rfr,1'b1};
|
{ba,a,cmd,cmd_aref} <= {2'b00, 13'd0, cmd_rfr,1'b1};
|
else if (shreg[31])
|
else if (shreg[31])
|
{ba,a,cmd} <=
|
{ba,a,cmd} <=
|
{2'b00,3'b000,`INIT_WB,2'b00,`INIT_CL,`INIT_BT,`INIT_BL, cmd_lmr};
|
{2'b00,3'b000,`INIT_WB,2'b00,`INIT_CL,`INIT_BT,`INIT_BL, cmd_lmr};
|
`FSM_RFR:
|
`FSM_RFR:
|
if (shreg[0]) begin
|
if (shreg[0]) begin
|
{ba,a,cmd} <= {2'b00, 13'b0010000000000, cmd_pch};
|
{ba,a,cmd} <= {2'b00, 13'b0010000000000, cmd_pch};
|
open_ba <= 4'b0000;
|
open_ba <= 4'b0000;
|
end else if (shreg[2])
|
end else if (shreg[2])
|
{ba,a,cmd,cmd_aref} <= {2'b00, 13'd0, cmd_rfr,1'b1};
|
{ba,a,cmd,cmd_aref} <= {2'b00, 13'd0, cmd_rfr,1'b1};
|
`FSM_ADR:
|
`FSM_ADR:
|
if (shreg[4])
|
if (shreg[4])
|
{ba_reg,row_reg,col_reg,we_reg,cti_reg,bte_reg} <=
|
{ba_reg,row_reg,col_reg,we_reg,cti_reg,bte_reg} <=
|
{bank,row,col,we_i,cti_i,bte_i};
|
{bank,row,col,we_i,cti_i,bte_i};
|
`FSM_PCH:
|
`FSM_PCH:
|
if (shreg[0]) begin
|
if (shreg[0]) begin
|
{ba,a,cmd} <= {ba_reg,13'd0,cmd_pch};
|
{ba,a,cmd} <= {ba_reg,13'd0,cmd_pch};
|
//open_ba <= 4'b0000;
|
//open_ba <= 4'b0000;
|
open_ba[ba_reg] <= 1'b0;
|
open_ba[ba_reg] <= 1'b0;
|
end
|
end
|
`FSM_ACT:
|
`FSM_ACT:
|
if (shreg[0]) begin
|
if (shreg[0]) begin
|
{ba,a,cmd} <= {ba_reg,(13'd0 | row_reg),cmd_act};
|
{ba,a,cmd} <= {ba_reg,(13'd0 | row_reg),cmd_act};
|
{open_ba[ba_reg],open_row[ba_reg]} <= {1'b1,row_reg};
|
{open_ba[ba_reg],open_row[ba_reg]} <= {1'b1,row_reg};
|
end
|
end
|
`FSM_RW:
|
`FSM_RW:
|
begin
|
begin
|
if (we_reg & !count0)
|
if (we_reg & !count0)
|
cmd <= cmd_wr;
|
cmd <= cmd_wr;
|
else if (!count0)
|
else if (!count0)
|
{cmd,cmd_read} <= {cmd_rd,1'b1};
|
{cmd,cmd_read} <= {cmd_rd,1'b1};
|
else
|
else
|
cmd <= cmd_nop;
|
cmd <= cmd_nop;
|
if (we_reg)
|
if (we_reg)
|
begin
|
begin
|
dqm <= count0 ? ~sel_i[1:0] : ~sel_i[3:2];
|
dqm <= count0 ? ~sel_i[1:0] : ~sel_i[3:2];
|
end
|
end
|
else
|
else
|
dqm <= 2'b00;
|
dqm <= 2'b00;
|
//if (we_reg)
|
//if (we_reg)
|
dq_oe <= we_reg;//1'b1;
|
dq_oe <= we_reg;//1'b1;
|
if (!stall)
|
if (!stall)
|
begin
|
begin
|
if (cti_reg==increment)
|
if (cti_reg==increment)
|
case (bte_reg)
|
case (bte_reg)
|
linear: {ba,a} <= {ba_reg,col_reg_a10_fix};
|
linear: {ba,a} <= {ba_reg,col_reg_a10_fix};
|
beat4: {ba,a,col_reg[2:0]} <=
|
beat4: {ba,a,col_reg[2:0]} <=
|
{ba_reg,col_reg_a10_fix, col_reg[2:0] + 3'd1};
|
{ba_reg,col_reg_a10_fix, col_reg[2:0] + 3'd1};
|
`ifdef BEAT8
|
`ifdef BEAT8
|
beat8: {ba,a,col_reg[3:0]} <=
|
beat8: {ba,a,col_reg[3:0]} <=
|
{ba_reg,col_reg_a10_fix, col_reg[3:0] + 4'd1};
|
{ba_reg,col_reg_a10_fix, col_reg[3:0] + 4'd1};
|
`endif
|
`endif
|
`ifdef BEAT16
|
`ifdef BEAT16
|
beat16: {ba,a,col_reg[4:0]} <=
|
beat16: {ba,a,col_reg[4:0]} <=
|
{ba_reg,col_reg_a10_fix, col_reg[4:0] + 5'd1};
|
{ba_reg,col_reg_a10_fix, col_reg[4:0] + 5'd1};
|
`endif
|
`endif
|
endcase // case (bte_reg)
|
endcase // case (bte_reg)
|
else
|
else
|
{ba,a} <= {ba_reg,col_reg_a10_fix};
|
{ba,a} <= {ba_reg,col_reg_a10_fix};
|
|
|
end // if (!stall)
|
end // if (!stall)
|
end
|
end
|
endcase
|
endcase
|
end
|
end
|
end
|
end
|
|
|
reg fifo_read_data_en;
|
reg fifo_read_data_en;
|
always @(posedge sdram_clk)
|
always @(posedge sdram_clk)
|
if (sdram_rst)
|
if (sdram_rst)
|
fifo_read_data_en <= 1;
|
fifo_read_data_en <= 1;
|
else if (next==`FSM_RW)
|
else if (next==`FSM_RW)
|
fifo_read_data_en <= ~fifo_read_data_en;
|
fifo_read_data_en <= ~fifo_read_data_en;
|
else
|
else
|
fifo_read_data_en <= 1;
|
fifo_read_data_en <= 1;
|
|
|
reg [3:0] beat4_data_read_limiter; // Use this to record how many times we've pulsed fifo_rd_data
|
reg [3:0] beat4_data_read_limiter; // Use this to record how many times we've pulsed fifo_rd_data
|
// Only 3 bits, becuase we're looking at when fifo_read_data_en goes low - should only happen 3
|
// Only 3 bits, becuase we're looking at when fifo_read_data_en goes low - should only happen 3
|
// times for a 4-beat burst
|
// times for a 4-beat burst
|
always @(posedge sdram_clk)
|
always @(posedge sdram_clk)
|
if (sdram_rst)
|
if (sdram_rst)
|
beat4_data_read_limiter <= 0;
|
beat4_data_read_limiter <= 0;
|
else if(state==`FSM_ADR)
|
else if(state==`FSM_ADR)
|
beat4_data_read_limiter <= 0;
|
beat4_data_read_limiter <= 0;
|
else if (!fifo_read_data_en)
|
else if (!fifo_read_data_en)
|
beat4_data_read_limiter <= {beat4_data_read_limiter[2:0],1'b1};
|
beat4_data_read_limiter <= {beat4_data_read_limiter[2:0],1'b1};
|
|
|
|
|
|
|
// rd_adr goes high when next adr is fetched from sync RAM and during write burst
|
// rd_adr goes high when next adr is fetched from sync RAM and during write burst
|
assign fifo_rd_adr = state==`FSM_ADR & shreg[1];
|
assign fifo_rd_adr = state==`FSM_ADR & shreg[1];
|
|
|
assign fifo_rd_data = (((state!=`FSM_RW & next==`FSM_RW)|(state==`FSM_RW & (cti_reg==increment && bte_reg==beat4 & fifo_read_data_en & !(&beat4_data_read_limiter)))) & we_reg & !fifo_empty);
|
assign fifo_rd_data = (((state!=`FSM_RW & next==`FSM_RW)|(state==`FSM_RW & (cti_reg==increment && bte_reg==beat4 & fifo_read_data_en & !(&beat4_data_read_limiter)))) & we_reg & !fifo_empty);
|
|
|
/*
|
/*
|
assign fifo_rd_data = ((state==`FSM_RW & next==`FSM_RW) &
|
assign fifo_rd_data = ((state==`FSM_RW & next==`FSM_RW) &
|
we_reg & !count0 & !fifo_empty);
|
we_reg & !count0 & !fifo_empty);
|
*/
|
*/
|
assign state_idle = (state==`FSM_IDLE);
|
assign state_idle = (state==`FSM_IDLE);
|
|
|
// bank and row open ?
|
// bank and row open ?
|
assign current_bank_closed = !(open_ba[bank]);
|
assign current_bank_closed = !(open_ba[bank]);
|
assign current_row_open = open_row[bank]==row;
|
assign current_row_open = open_row[bank]==row;
|
|
|
always @ (posedge sdram_clk or posedge sdram_rst)
|
always @ (posedge sdram_clk or posedge sdram_rst)
|
if (sdram_rst)
|
if (sdram_rst)
|
{current_bank_closed_reg, current_row_open_reg} <= {1'b1, 1'b0};
|
{current_bank_closed_reg, current_row_open_reg} <= {1'b1, 1'b0};
|
else
|
else
|
//if (state==adr & counter[1:0]==2'b10)
|
//if (state==adr & counter[1:0]==2'b10)
|
{current_bank_closed_reg, current_row_open_reg} <=
|
{current_bank_closed_reg, current_row_open_reg} <=
|
{current_bank_closed, current_row_open};
|
{current_bank_closed, current_row_open};
|
|
|
// Record the number of write enables going to INGRESS fifo (ie. that we
|
// Record the number of write enables going to INGRESS fifo (ie. that we
|
// generate when we're reading) - this makes sure we keep track of when a
|
// generate when we're reading) - this makes sure we keep track of when a
|
// burst read is in progress, and we can signal the wishbone bus to wait
|
// burst read is in progress, and we can signal the wishbone bus to wait
|
// for this data to be put into the FIFO before it'll empty it when it's
|
// for this data to be put into the FIFO before it'll empty it when it's
|
// had a terminated burst transfer.
|
// had a terminated burst transfer.
|
reg [3:0] fifo_we_record;
|
reg [3:0] fifo_we_record;
|
assign debug_fifo_we_record = fifo_we_record;
|
assign debug_fifo_we_record = fifo_we_record;
|
always @(posedge sdram_clk)
|
always @(posedge sdram_clk)
|
if (sdram_rst)
|
if (sdram_rst)
|
fifo_we_record <= 0;
|
fifo_we_record <= 0;
|
else if (next==`FSM_RW & ((state==`FSM_ADR)|(state==`FSM_ACT)) &
|
else if (next==`FSM_RW & ((state==`FSM_ADR)|(state==`FSM_ACT)) &
|
cti_reg==increment & (bte_reg==beat4) & !we_reg)
|
cti_reg==increment & (bte_reg==beat4) & !we_reg)
|
fifo_we_record <= 4'b0001;
|
fifo_we_record <= 4'b0001;
|
else if (sdram_fifo_wr)
|
else if (sdram_fifo_wr)
|
fifo_we_record <= {fifo_we_record[2:0],1'b0};
|
fifo_we_record <= {fifo_we_record[2:0],1'b0};
|
`ifdef SDRAM_WB_SAME_CLOCKS
|
`ifdef SDRAM_WB_SAME_CLOCKS
|
assign sdram_burst_reading = |fifo_we_record;
|
assign sdram_burst_reading = |fifo_we_record;
|
`else
|
`else
|
assign sdram_burst_reading = 0;
|
assign sdram_burst_reading = 0;
|
`endif
|
`endif
|
|
|
|
|
endmodule
|
endmodule
|
`timescale 1ns/1ns
|
`timescale 1ns/1ns
|
module versatile_mem_ctrl_wb
|
module versatile_mem_ctrl_wb
|
(
|
(
|
// wishbone side
|
// wishbone side
|
wb_adr_i_v, wb_dat_i_v, wb_dat_o_v,
|
wb_adr_i_v, wb_dat_i_v, wb_dat_o_v,
|
wb_stb_i, wb_cyc_i, wb_ack_o,
|
wb_stb_i, wb_cyc_i, wb_ack_o,
|
wb_clk, wb_rst,
|
wb_clk, wb_rst,
|
// SDRAM controller interface
|
// SDRAM controller interface
|
sdram_dat_o, sdram_fifo_empty, sdram_fifo_rd_adr, sdram_fifo_rd_data, sdram_fifo_re,
|
sdram_dat_o, sdram_fifo_empty, sdram_fifo_rd_adr, sdram_fifo_rd_data, sdram_fifo_re,
|
sdram_dat_i, sdram_fifo_wr, sdram_fifo_we, sdram_burst_reading,
|
sdram_dat_i, sdram_fifo_wr, sdram_fifo_we, sdram_burst_reading,
|
debug_wb_fsm_state, debug_ingress_fifo_empty, debug_egress_fifo_empty,
|
debug_wb_fsm_state, debug_ingress_fifo_empty, debug_egress_fifo_empty,
|
sdram_clk, sdram_rst
|
sdram_clk, sdram_rst
|
|
|
);
|
);
|
|
|
parameter nr_of_wb_ports = 3;
|
parameter nr_of_wb_ports = 3;
|
|
|
input [36*nr_of_wb_ports-1:0] wb_adr_i_v;
|
input [36*nr_of_wb_ports-1:0] wb_adr_i_v;
|
input [36*nr_of_wb_ports-1:0] wb_dat_i_v;
|
input [36*nr_of_wb_ports-1:0] wb_dat_i_v;
|
input [0:nr_of_wb_ports-1] wb_stb_i;
|
input [0:nr_of_wb_ports-1] wb_stb_i;
|
input [0:nr_of_wb_ports-1] wb_cyc_i;
|
input [0:nr_of_wb_ports-1] wb_cyc_i;
|
output [32*nr_of_wb_ports-1:0] wb_dat_o_v;
|
output [32*nr_of_wb_ports-1:0] wb_dat_o_v;
|
output [0:nr_of_wb_ports-1] wb_ack_o;
|
output [0:nr_of_wb_ports-1] wb_ack_o;
|
input wb_clk;
|
input wb_clk;
|
input wb_rst;
|
input wb_rst;
|
|
|
output [35:0] sdram_dat_o;
|
output [35:0] sdram_dat_o;
|
output [0:nr_of_wb_ports-1] sdram_fifo_empty;
|
output [0:nr_of_wb_ports-1] sdram_fifo_empty;
|
input sdram_fifo_rd_adr, sdram_fifo_rd_data;
|
input sdram_fifo_rd_adr, sdram_fifo_rd_data;
|
input [0:nr_of_wb_ports-1] sdram_fifo_re;
|
input [0:nr_of_wb_ports-1] sdram_fifo_re;
|
input [31:0] sdram_dat_i;
|
input [31:0] sdram_dat_i;
|
input sdram_fifo_wr;
|
input sdram_fifo_wr;
|
input [0:nr_of_wb_ports-1] sdram_fifo_we;
|
input [0:nr_of_wb_ports-1] sdram_fifo_we;
|
input sdram_burst_reading;
|
input sdram_burst_reading;
|
input sdram_clk;
|
input sdram_clk;
|
input sdram_rst;
|
input sdram_rst;
|
|
|
output [(2*nr_of_wb_ports)-1:0] debug_wb_fsm_state;
|
output [(2*nr_of_wb_ports)-1:0] debug_wb_fsm_state;
|
output [nr_of_wb_ports-1:0] debug_ingress_fifo_empty;
|
output [nr_of_wb_ports-1:0] debug_ingress_fifo_empty;
|
output [nr_of_wb_ports-1:0] debug_egress_fifo_empty;
|
output [nr_of_wb_ports-1:0] debug_egress_fifo_empty;
|
|
|
|
|
|
|
parameter linear = 2'b00;
|
parameter linear = 2'b00;
|
parameter wrap4 = 2'b01;
|
parameter wrap4 = 2'b01;
|
parameter wrap8 = 2'b10;
|
parameter wrap8 = 2'b10;
|
parameter wrap16 = 2'b11;
|
parameter wrap16 = 2'b11;
|
parameter classic = 3'b000;
|
parameter classic = 3'b000;
|
parameter endofburst = 3'b111;
|
parameter endofburst = 3'b111;
|
|
|
`define CTI_I 2:0
|
`define CTI_I 2:0
|
`define BTE_I 4:3
|
`define BTE_I 4:3
|
`define WE_I 5
|
`define WE_I 5
|
|
|
parameter idle = 2'b00;
|
parameter idle = 2'b00;
|
parameter rd = 2'b01;
|
parameter rd = 2'b01;
|
parameter wr = 2'b10;
|
parameter wr = 2'b10;
|
parameter fe = 2'b11;
|
parameter fe = 2'b11;
|
|
|
reg [1:0] wb_state[0:nr_of_wb_ports-1];
|
reg [1:0] wb_state[0:nr_of_wb_ports-1];
|
|
|
wire [35:0] wb_adr_i[0:nr_of_wb_ports-1];
|
wire [35:0] wb_adr_i[0:nr_of_wb_ports-1];
|
wire [35:0] wb_dat_i[0:nr_of_wb_ports-1];
|
wire [35:0] wb_dat_i[0:nr_of_wb_ports-1];
|
wire [36*nr_of_wb_ports-1:0] egress_fifo_di;
|
wire [36*nr_of_wb_ports-1:0] egress_fifo_di;
|
wire [31:0] wb_dat_o;
|
wire [31:0] wb_dat_o;
|
|
|
wire [0:nr_of_wb_ports] stall;
|
wire [0:nr_of_wb_ports] stall;
|
wire [0:nr_of_wb_ports-1] state_idle;
|
wire [0:nr_of_wb_ports-1] state_idle;
|
wire [0:nr_of_wb_ports-1] egress_fifo_we, egress_fifo_full;
|
wire [0:nr_of_wb_ports-1] egress_fifo_we, egress_fifo_full;
|
wire [0:nr_of_wb_ports-1] ingress_fifo_re, ingress_fifo_empty;
|
wire [0:nr_of_wb_ports-1] ingress_fifo_re, ingress_fifo_empty;
|
|
|
wire [1:0] debug_each_wb_fsm_state [0:nr_of_wb_ports-1];
|
wire [1:0] debug_each_wb_fsm_state [0:nr_of_wb_ports-1];
|
|
|
|
|
genvar i;
|
genvar i;
|
|
|
assign stall[0] = 1'b0;
|
assign stall[0] = 1'b0;
|
|
|
`define INDEX (nr_of_wb_ports-i)*36-1:(nr_of_wb_ports-1-i)*36
|
`define INDEX (nr_of_wb_ports-i)*36-1:(nr_of_wb_ports-1-i)*36
|
generate
|
generate
|
for (i=0;i<nr_of_wb_ports;i=i+1) begin : vector2array
|
for (i=0;i<nr_of_wb_ports;i=i+1) begin : vector2array
|
assign wb_adr_i[i] = wb_adr_i_v[`INDEX];
|
assign wb_adr_i[i] = wb_adr_i_v[`INDEX];
|
assign wb_dat_i[i] = wb_dat_i_v[`INDEX];
|
assign wb_dat_i[i] = wb_dat_i_v[`INDEX];
|
assign egress_fifo_di[`INDEX] = (state_idle[i]) ?
|
assign egress_fifo_di[`INDEX] = (state_idle[i]) ?
|
wb_adr_i[i] : wb_dat_i[i];
|
wb_adr_i[i] : wb_dat_i[i];
|
|
|
end
|
end
|
endgenerate
|
endgenerate
|
|
|
// Debug output assignments
|
// Debug output assignments
|
generate
|
generate
|
for (i=0;i<nr_of_wb_ports;i=i+1) begin : vector2debugarray
|
for (i=0;i<nr_of_wb_ports;i=i+1) begin : vector2debugarray
|
assign debug_wb_fsm_state[(nr_of_wb_ports-i)*2-1:(nr_of_wb_ports-1-i)*2] = debug_each_wb_fsm_state[i];
|
assign debug_wb_fsm_state[(nr_of_wb_ports-i)*2-1:(nr_of_wb_ports-1-i)*2] = debug_each_wb_fsm_state[i];
|
end
|
end
|
endgenerate
|
endgenerate
|
assign debug_ingress_fifo_empty = ingress_fifo_empty;
|
assign debug_ingress_fifo_empty = ingress_fifo_empty;
|
assign debug_egress_fifo_empty = egress_fifo_we;
|
assign debug_egress_fifo_empty = egress_fifo_we;
|
|
|
|
|
generate
|
generate
|
for (i=0;i<nr_of_wb_ports;i=i+1) begin : fsm
|
for (i=0;i<nr_of_wb_ports;i=i+1) begin : fsm
|
fsm_wb fsm_wb_i
|
fsm_wb fsm_wb_i
|
(
|
(
|
.stall_i(stall[i]),
|
.stall_i(stall[i]),
|
.stall_o(stall[i+1]),
|
.stall_o(stall[i+1]),
|
.we_i (wb_adr_i[i][`WE_I]),
|
.we_i (wb_adr_i[i][`WE_I]),
|
.cti_i(wb_adr_i[i][`CTI_I]),
|
.cti_i(wb_adr_i[i][`CTI_I]),
|
.bte_i(wb_adr_i[i][`BTE_I]),
|
.bte_i(wb_adr_i[i][`BTE_I]),
|
.stb_i(wb_stb_i[i]),
|
.stb_i(wb_stb_i[i]),
|
.cyc_i(wb_cyc_i[i]),
|
.cyc_i(wb_cyc_i[i]),
|
.ack_o(wb_ack_o[i]),
|
.ack_o(wb_ack_o[i]),
|
.egress_fifo_we(egress_fifo_we[i]),
|
.egress_fifo_we(egress_fifo_we[i]),
|
.egress_fifo_full(egress_fifo_full[i]),
|
.egress_fifo_full(egress_fifo_full[i]),
|
.ingress_fifo_re(ingress_fifo_re[i]),
|
.ingress_fifo_re(ingress_fifo_re[i]),
|
.ingress_fifo_empty(ingress_fifo_empty[i]),
|
.ingress_fifo_empty(ingress_fifo_empty[i]),
|
.state_idle(state_idle[i]),
|
.state_idle(state_idle[i]),
|
.sdram_burst_reading(sdram_burst_reading),
|
.sdram_burst_reading(sdram_burst_reading),
|
.debug_state(debug_each_wb_fsm_state[i]),
|
.debug_state(debug_each_wb_fsm_state[i]),
|
.wb_clk(wb_clk),
|
.wb_clk(wb_clk),
|
.wb_rst(wb_rst)
|
.wb_rst(wb_rst)
|
);
|
);
|
end
|
end
|
endgenerate
|
endgenerate
|
|
|
egress_fifo # (
|
egress_fifo # (
|
.a_hi_size(4),.a_lo_size(4),.nr_of_queues(nr_of_wb_ports),
|
.a_hi_size(4),.a_lo_size(4),.nr_of_queues(nr_of_wb_ports),
|
.data_width(36))
|
.data_width(36))
|
egress_FIFO(
|
egress_FIFO(
|
.d(egress_fifo_di),
|
.d(egress_fifo_di),
|
.fifo_full(egress_fifo_full),
|
.fifo_full(egress_fifo_full),
|
.write(|(egress_fifo_we)),
|
.write(|(egress_fifo_we)),
|
.write_enable(egress_fifo_we),
|
.write_enable(egress_fifo_we),
|
.q(sdram_dat_o),
|
.q(sdram_dat_o),
|
.fifo_empty(sdram_fifo_empty),
|
.fifo_empty(sdram_fifo_empty),
|
.read_adr(sdram_fifo_rd_adr),
|
.read_adr(sdram_fifo_rd_adr),
|
.read_data(sdram_fifo_rd_data),
|
.read_data(sdram_fifo_rd_data),
|
.read_enable(sdram_fifo_re),
|
.read_enable(sdram_fifo_re),
|
.clk1(wb_clk),
|
.clk1(wb_clk),
|
.rst1(wb_rst),
|
.rst1(wb_rst),
|
.clk2(sdram_clk),
|
.clk2(sdram_clk),
|
.rst2(sdram_rst)
|
.rst2(sdram_rst)
|
);
|
);
|
|
|
async_fifo_mq # (
|
async_fifo_mq # (
|
.a_hi_size(4),.a_lo_size(4),.nr_of_queues(nr_of_wb_ports),
|
.a_hi_size(4),.a_lo_size(4),.nr_of_queues(nr_of_wb_ports),
|
.data_width(32))
|
.data_width(32))
|
ingress_FIFO(
|
ingress_FIFO(
|
.d(sdram_dat_i), .fifo_full(), .write(sdram_fifo_wr),
|
.d(sdram_dat_i), .fifo_full(), .write(sdram_fifo_wr),
|
.write_enable(sdram_fifo_we), .q(wb_dat_o),
|
.write_enable(sdram_fifo_we), .q(wb_dat_o),
|
.fifo_empty(ingress_fifo_empty), .read(|(ingress_fifo_re)),
|
.fifo_empty(ingress_fifo_empty), .read(|(ingress_fifo_re)),
|
.read_enable(ingress_fifo_re), .clk1(sdram_clk),
|
.read_enable(ingress_fifo_re), .clk1(sdram_clk),
|
.rst1(sdram_rst), .clk2(wb_clk), .rst2(wb_rst)
|
.rst1(sdram_rst), .clk2(wb_clk), .rst2(wb_rst)
|
);
|
);
|
|
|
assign wb_dat_o_v = {nr_of_wb_ports{wb_dat_o}};
|
assign wb_dat_o_v = {nr_of_wb_ports{wb_dat_o}};
|
|
|
endmodule`timescale 1ns/1ns
|
endmodule`timescale 1ns/1ns
|
`ifdef DDR_16
|
`ifdef DDR_16
|
`include "ddr_16_defines.v"
|
`include "ddr_16_defines.v"
|
`endif
|
`endif
|
`ifdef SDR_16
|
`ifdef SDR_16
|
`include "sdr_16_defines.v"
|
`include "sdr_16_defines.v"
|
`endif
|
`endif
|
module versatile_mem_ctrl_top
|
module versatile_mem_ctrl_top
|
(
|
(
|
// wishbone side
|
// wishbone side
|
wb_adr_i_0, wb_dat_i_0, wb_dat_o_0,
|
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_stb_i_0, wb_cyc_i_0, wb_ack_o_0,
|
wb_adr_i_1, wb_dat_i_1, wb_dat_o_1,
|
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_stb_i_1, wb_cyc_i_1, wb_ack_o_1,
|
wb_adr_i_2, wb_dat_i_2, wb_dat_o_2,
|
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_stb_i_2, wb_cyc_i_2, wb_ack_o_2,
|
wb_adr_i_3, wb_dat_i_3, wb_dat_o_3,
|
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_stb_i_3, wb_cyc_i_3, wb_ack_o_3,
|
wb_clk, wb_rst,
|
wb_clk, wb_rst,
|
|
|
`ifdef SDR_16
|
`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
|
`endif
|
|
|
`ifdef DDR_16
|
`ifdef DDR_16
|
ck_pad_o, ck_n_pad_o, cke_pad_o, ck_fb_pad_o, ck_fb_pad_i,
|
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,
|
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,
|
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
|
`endif
|
// SDRAM signals
|
// SDRAM signals
|
sdram_clk, sdram_rst
|
sdram_clk, sdram_rst
|
);
|
);
|
|
|
// number of wb clock domains
|
// number of wb clock domains
|
parameter nr_of_wb_clk_domains = 1;
|
parameter nr_of_wb_clk_domains = 1;
|
// number of wb ports in each wb clock domain
|
// number of wb ports in each wb clock domain
|
parameter nr_of_wb_ports_clk0 = 3;
|
parameter nr_of_wb_ports_clk0 = 3;
|
parameter nr_of_wb_ports_clk1 = 0;
|
parameter nr_of_wb_ports_clk1 = 0;
|
parameter nr_of_wb_ports_clk2 = 0;
|
parameter nr_of_wb_ports_clk2 = 0;
|
parameter nr_of_wb_ports_clk3 = 0;
|
parameter nr_of_wb_ports_clk3 = 0;
|
|
|
input [36*nr_of_wb_ports_clk0-1:0] wb_adr_i_0;
|
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;
|
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;
|
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;
|
input [0:nr_of_wb_ports_clk0-1] wb_stb_i_0, wb_cyc_i_0;
|
output [0:nr_of_wb_ports_clk0-1] wb_ack_o_0;
|
output [0:nr_of_wb_ports_clk0-1] 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_adr_i_1;
|
input [36*nr_of_wb_ports_clk1-1:0] wb_dat_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;
|
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;
|
input [0:nr_of_wb_ports_clk1-1] wb_stb_i_1, wb_cyc_i_1;
|
output [0:nr_of_wb_ports_clk1-1] wb_ack_o_1;
|
output [0:nr_of_wb_ports_clk1-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_adr_i_2;
|
input [36*nr_of_wb_ports_clk2-1:0] wb_dat_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;
|
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;
|
input [0:nr_of_wb_ports_clk2-1] wb_stb_i_2, wb_cyc_i_2;
|
output [0:nr_of_wb_ports_clk2-1] wb_ack_o_2;
|
output [0:nr_of_wb_ports_clk2-1] 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_adr_i_3;
|
input [36*nr_of_wb_ports_clk3-1:0] wb_dat_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;
|
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;
|
input [0:nr_of_wb_ports_clk3-1] wb_stb_i_3, wb_cyc_i_3;
|
output [0:nr_of_wb_ports_clk3-1] wb_ack_o_3;
|
output [0:nr_of_wb_ports_clk3-1] wb_ack_o_3;
|
|
|
input [0:nr_of_wb_clk_domains-1] wb_clk;
|
input [0:nr_of_wb_clk_domains-1] wb_clk;
|
input [0:nr_of_wb_clk_domains-1] wb_rst;
|
input [0:nr_of_wb_clk_domains-1] wb_rst;
|
|
|
`ifdef SDR_16
|
`ifdef SDR_16
|
output [1:0] ba_pad_o;
|
output [1:0] ba_pad_o;
|
output [12:0] a_pad_o;
|
output [12:0] a_pad_o;
|
output cs_n_pad_o;
|
output cs_n_pad_o;
|
output ras_pad_o;
|
output ras_pad_o;
|
output cas_pad_o;
|
output cas_pad_o;
|
output we_pad_o;
|
output we_pad_o;
|
output reg [(`SDRAM_DATA_WIDTH)-1:0] dq_o /*synthesis syn_useioff=1 syn_allow_retiming=0 */;
|
output reg [(`SDRAM_DATA_WIDTH)-1:0] dq_o /*synthesis syn_useioff=1 syn_allow_retiming=0 */;
|
output [1:0] dqm_pad_o;
|
output [1:0] dqm_pad_o;
|
input [(`SDRAM_DATA_WIDTH)-1:0] dq_i ;
|
input [(`SDRAM_DATA_WIDTH)-1:0] dq_i ;
|
output dq_oe;
|
output dq_oe;
|
output cke_pad_o;
|
output cke_pad_o;
|
`endif
|
`endif
|
`ifdef DDR_16
|
`ifdef DDR_16
|
output ck_pad_o;
|
output ck_pad_o;
|
output ck_n_pad_o;
|
output ck_n_pad_o;
|
output cke_pad_o;
|
output cke_pad_o;
|
output ck_fb_pad_o;
|
output ck_fb_pad_o;
|
input ck_fb_pad_i;
|
input ck_fb_pad_i;
|
output cs_n_pad_o;
|
output cs_n_pad_o;
|
output ras_pad_o;
|
output ras_pad_o;
|
output cas_pad_o;
|
output cas_pad_o;
|
output we_pad_o;
|
output we_pad_o;
|
inout [1:0] dm_rdqs_pad_io;
|
inout [1:0] dm_rdqs_pad_io;
|
output [1:0] ba_pad_o;
|
output [1:0] ba_pad_o;
|
output [12:0] addr_pad_o;
|
output [12:0] addr_pad_o;
|
inout [15:0] dq_pad_io;
|
inout [15:0] dq_pad_io;
|
inout [1:0] dqs_pad_io;
|
inout [1:0] dqs_pad_io;
|
output dqs_oe;
|
output dqs_oe;
|
inout [1:0] dqs_n_pad_io;
|
inout [1:0] dqs_n_pad_io;
|
input [1:0] rdqs_n_pad_i;
|
input [1:0] rdqs_n_pad_i;
|
output odt_pad_o;
|
output odt_pad_o;
|
`endif
|
`endif
|
input sdram_clk, sdram_rst;
|
input sdram_clk, sdram_rst;
|
|
|
wire [0:15] fifo_empty[0:3];
|
wire [0:15] fifo_empty[0:3];
|
wire current_fifo_empty;
|
wire current_fifo_empty;
|
wire [0:15] fifo_re[0:3];
|
wire [0:15] fifo_re[0:3];
|
wire [35:0] fifo_dat_o[0:3];
|
wire [35:0] fifo_dat_o[0:3];
|
wire [31:0] fifo_dat_i;
|
wire [31:0] fifo_dat_i;
|
wire [0:15] fifo_we[0:3];
|
wire [0:15] fifo_we[0:3];
|
wire fifo_rd_adr, fifo_rd_data, fifo_wr, idle, count0;
|
wire fifo_rd_adr, fifo_rd_data, fifo_wr, idle, count0;
|
|
|
wire [0:15] fifo_sel_i, fifo_sel_dly;
|
wire [0:15] fifo_sel_i, fifo_sel_dly;
|
reg [0:15] fifo_sel_reg;
|
reg [0:15] fifo_sel_reg;
|
wire [1:0] fifo_sel_domain_i, fifo_sel_domain_dly;
|
wire [1:0] fifo_sel_domain_i, fifo_sel_domain_dly;
|
reg [1:0] fifo_sel_domain_reg;
|
reg [1:0] fifo_sel_domain_reg;
|
|
|
reg refresh_req;
|
reg refresh_req;
|
|
|
wire [35:0] tx_fifo_dat_o;
|
wire [35:0] tx_fifo_dat_o;
|
|
|
wire burst_reading;
|
wire burst_reading;
|
reg sdram_fifo_wr_r;
|
reg sdram_fifo_wr_r;
|
|
|
|
|
generate
|
generate
|
if (nr_of_wb_clk_domains > 0) begin
|
if (nr_of_wb_clk_domains > 0) begin
|
versatile_mem_ctrl_wb
|
versatile_mem_ctrl_wb
|
# (.nr_of_wb_ports(nr_of_wb_ports_clk0))
|
# (.nr_of_wb_ports(nr_of_wb_ports_clk0))
|
wb0
|
wb0
|
(
|
(
|
// wishbone side
|
// wishbone side
|
.wb_adr_i_v(wb_adr_i_0),
|
.wb_adr_i_v(wb_adr_i_0),
|
.wb_dat_i_v(wb_dat_i_0),
|
.wb_dat_i_v(wb_dat_i_0),
|
.wb_dat_o_v(wb_dat_o_0),
|
.wb_dat_o_v(wb_dat_o_0),
|
.wb_stb_i(wb_stb_i_0),
|
.wb_stb_i(wb_stb_i_0),
|
.wb_cyc_i(wb_cyc_i_0),
|
.wb_cyc_i(wb_cyc_i_0),
|
.wb_ack_o(wb_ack_o_0),
|
.wb_ack_o(wb_ack_o_0),
|
.wb_clk(wb_clk[0]),
|
.wb_clk(wb_clk[0]),
|
.wb_rst(wb_rst[0]),
|
.wb_rst(wb_rst[0]),
|
// SDRAM controller interface
|
// SDRAM controller interface
|
.sdram_dat_o(fifo_dat_o[0]),
|
.sdram_dat_o(fifo_dat_o[0]),
|
.sdram_fifo_empty(fifo_empty[0][0:nr_of_wb_ports_clk0-1]),
|
.sdram_fifo_empty(fifo_empty[0][0:nr_of_wb_ports_clk0-1]),
|
.sdram_fifo_rd_adr(fifo_rd_adr),
|
.sdram_fifo_rd_adr(fifo_rd_adr),
|
.sdram_fifo_rd_data(fifo_rd_data),
|
.sdram_fifo_rd_data(fifo_rd_data),
|
.sdram_fifo_re(fifo_re[0][0:nr_of_wb_ports_clk0-1]),
|
.sdram_fifo_re(fifo_re[0][0:nr_of_wb_ports_clk0-1]),
|
.sdram_dat_i(fifo_dat_i),
|
.sdram_dat_i(fifo_dat_i),
|
.sdram_fifo_wr(fifo_wr),
|
.sdram_fifo_wr(fifo_wr),
|
.sdram_fifo_we(fifo_we[0][0:nr_of_wb_ports_clk0-1]),
|
.sdram_fifo_we(fifo_we[0][0:nr_of_wb_ports_clk0-1]),
|
.sdram_burst_reading(burst_reading),
|
.sdram_burst_reading(burst_reading),
|
.debug_wb_fsm_state(),
|
.debug_wb_fsm_state(),
|
.debug_ingress_fifo_empty(),
|
.debug_ingress_fifo_empty(),
|
.debug_egress_fifo_empty(),
|
.debug_egress_fifo_empty(),
|
.sdram_clk(sdram_clk),
|
.sdram_clk(sdram_clk),
|
.sdram_rst(sdram_rst) );
|
.sdram_rst(sdram_rst) );
|
end
|
end
|
if (nr_of_wb_ports_clk0 < 16) begin
|
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}};
|
assign fifo_empty[0][nr_of_wb_ports_clk0:15] = {(16-nr_of_wb_ports_clk0){1'b1}};
|
end
|
end
|
endgenerate
|
endgenerate
|
|
|
generate
|
generate
|
if (nr_of_wb_clk_domains > 1) begin
|
if (nr_of_wb_clk_domains > 1) begin
|
versatile_mem_ctrl_wb
|
versatile_mem_ctrl_wb
|
# (.nr_of_wb_ports(nr_of_wb_ports_clk1))
|
# (.nr_of_wb_ports(nr_of_wb_ports_clk1))
|
wb1
|
wb1
|
(
|
(
|
// wishbone side
|
// wishbone side
|
.wb_adr_i_v(wb_adr_i_1),
|
.wb_adr_i_v(wb_adr_i_1),
|
.wb_dat_i_v(wb_dat_i_1),
|
.wb_dat_i_v(wb_dat_i_1),
|
.wb_dat_o_v(wb_dat_o_1),
|
.wb_dat_o_v(wb_dat_o_1),
|
.wb_stb_i(wb_stb_i_1),
|
.wb_stb_i(wb_stb_i_1),
|
.wb_cyc_i(wb_cyc_i_1),
|
.wb_cyc_i(wb_cyc_i_1),
|
.wb_ack_o(wb_ack_o_1),
|
.wb_ack_o(wb_ack_o_1),
|
.wb_clk(wb_clk[1]),
|
.wb_clk(wb_clk[1]),
|
.wb_rst(wb_rst[1]),
|
.wb_rst(wb_rst[1]),
|
// SDRAM controller interface
|
// SDRAM controller interface
|
.sdram_dat_o(fifo_dat_o[1]),
|
.sdram_dat_o(fifo_dat_o[1]),
|
.sdram_fifo_empty(fifo_empty[1][0:nr_of_wb_ports_clk1-1]),
|
.sdram_fifo_empty(fifo_empty[1][0:nr_of_wb_ports_clk1-1]),
|
.sdram_fifo_rd_adr(fifo_rd_adr),
|
.sdram_fifo_rd_adr(fifo_rd_adr),
|
.sdram_fifo_rd_data(fifo_rd_data),
|
.sdram_fifo_rd_data(fifo_rd_data),
|
.sdram_fifo_re(fifo_re[1][0:nr_of_wb_ports_clk1-1]),
|
.sdram_fifo_re(fifo_re[1][0:nr_of_wb_ports_clk1-1]),
|
.sdram_dat_i(fifo_dat_i),
|
.sdram_dat_i(fifo_dat_i),
|
.sdram_fifo_wr(fifo_wr),
|
.sdram_fifo_wr(fifo_wr),
|
.sdram_fifo_we(fifo_we[1][0:nr_of_wb_ports_clk1-1]),
|
.sdram_fifo_we(fifo_we[1][0:nr_of_wb_ports_clk1-1]),
|
.sdram_burst_reading(burst_reading),
|
.sdram_burst_reading(burst_reading),
|
.sdram_clk(sdram_clk),
|
.sdram_clk(sdram_clk),
|
.sdram_rst(sdram_rst) );
|
.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}};
|
assign fifo_empty[1][nr_of_wb_ports_clk1:15] = {(16-nr_of_wb_ports_clk1){1'b1}};
|
end
|
end
|
end else begin
|
end else begin
|
assign fifo_empty[1] = {16{1'b1}};
|
assign fifo_empty[1] = {16{1'b1}};
|
assign fifo_dat_o[1] = {36{1'b0}};
|
assign fifo_dat_o[1] = {36{1'b0}};
|
end
|
end
|
endgenerate
|
endgenerate
|
|
|
generate
|
generate
|
if (nr_of_wb_clk_domains > 2) begin
|
if (nr_of_wb_clk_domains > 2) begin
|
versatile_mem_ctrl_wb
|
versatile_mem_ctrl_wb
|
# (.nr_of_wb_ports(nr_of_wb_ports_clk1))
|
# (.nr_of_wb_ports(nr_of_wb_ports_clk1))
|
wb2
|
wb2
|
(
|
(
|
// wishbone side
|
// wishbone side
|
.wb_adr_i_v(wb_adr_i_2),
|
.wb_adr_i_v(wb_adr_i_2),
|
.wb_dat_i_v(wb_dat_i_2),
|
.wb_dat_i_v(wb_dat_i_2),
|
.wb_dat_o_v(wb_dat_o_2),
|
.wb_dat_o_v(wb_dat_o_2),
|
.wb_stb_i(wb_stb_i_2),
|
.wb_stb_i(wb_stb_i_2),
|
.wb_cyc_i(wb_cyc_i_2),
|
.wb_cyc_i(wb_cyc_i_2),
|
.wb_ack_o(wb_ack_o_2),
|
.wb_ack_o(wb_ack_o_2),
|
.wb_clk(wb_clk[2]),
|
.wb_clk(wb_clk[2]),
|
.wb_rst(wb_rst[2]),
|
.wb_rst(wb_rst[2]),
|
// SDRAM controller interface
|
// SDRAM controller interface
|
.sdram_dat_o(fifo_dat_o[2]),
|
.sdram_dat_o(fifo_dat_o[2]),
|
.sdram_fifo_empty(fifo_empty[2][0:nr_of_wb_ports_clk2-1]),
|
.sdram_fifo_empty(fifo_empty[2][0:nr_of_wb_ports_clk2-1]),
|
.sdram_fifo_rd_adr(fifo_rd_adr),
|
.sdram_fifo_rd_adr(fifo_rd_adr),
|
.sdram_fifo_rd_data(fifo_rd_data),
|
.sdram_fifo_rd_data(fifo_rd_data),
|
.sdram_fifo_re(fifo_re[2][0:nr_of_wb_ports_clk2-1]),
|
.sdram_fifo_re(fifo_re[2][0:nr_of_wb_ports_clk2-1]),
|
.sdram_dat_i(fifo_dat_i),
|
.sdram_dat_i(fifo_dat_i),
|
.sdram_fifo_wr(fifo_wr),
|
.sdram_fifo_wr(fifo_wr),
|
.sdram_fifo_we(fifo_we[2][0:nr_of_wb_ports_clk2-1]),
|
.sdram_fifo_we(fifo_we[2][0:nr_of_wb_ports_clk2-1]),
|
.sdram_burst_reading(burst_reading),
|
.sdram_burst_reading(burst_reading),
|
.sdram_clk(sdram_clk),
|
.sdram_clk(sdram_clk),
|
.sdram_rst(sdram_rst) );
|
.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}};
|
assign fifo_empty[2][nr_of_wb_ports_clk2:15] = {(16-nr_of_wb_ports_clk2){1'b1}};
|
end
|
end
|
end else begin
|
end else begin
|
assign fifo_empty[2] = {16{1'b1}};
|
assign fifo_empty[2] = {16{1'b1}};
|
assign fifo_dat_o[2] = {36{1'b0}};
|
assign fifo_dat_o[2] = {36{1'b0}};
|
end
|
end
|
endgenerate
|
endgenerate
|
|
|
generate
|
generate
|
if (nr_of_wb_clk_domains > 3) begin
|
if (nr_of_wb_clk_domains > 3) begin
|
versatile_mem_ctrl_wb
|
versatile_mem_ctrl_wb
|
# (.nr_of_wb_ports(nr_of_wb_ports_clk3))
|
# (.nr_of_wb_ports(nr_of_wb_ports_clk3))
|
wb3
|
wb3
|
(
|
(
|
// wishbone side
|
// wishbone side
|
.wb_adr_i_v(wb_adr_i_3),
|
.wb_adr_i_v(wb_adr_i_3),
|
.wb_dat_i_v(wb_dat_i_3),
|
.wb_dat_i_v(wb_dat_i_3),
|
.wb_dat_o_v(wb_dat_o_3),
|
.wb_dat_o_v(wb_dat_o_3),
|
.wb_stb_i(wb_stb_i_3),
|
.wb_stb_i(wb_stb_i_3),
|
.wb_cyc_i(wb_cyc_i_3),
|
.wb_cyc_i(wb_cyc_i_3),
|
.wb_ack_o(wb_ack_o_3),
|
.wb_ack_o(wb_ack_o_3),
|
.wb_clk(wb_clk[3]),
|
.wb_clk(wb_clk[3]),
|
.wb_rst(wb_rst[3]),
|
.wb_rst(wb_rst[3]),
|
// SDRAM controller interface
|
// SDRAM controller interface
|
.sdram_dat_o(fifo_dat_o[3]),
|
.sdram_dat_o(fifo_dat_o[3]),
|
.sdram_fifo_empty(fifo_empty[3][0:nr_of_wb_ports_clk3-1]),
|
.sdram_fifo_empty(fifo_empty[3][0:nr_of_wb_ports_clk3-1]),
|
.sdram_fifo_rd_adr(fifo_rd_adr),
|
.sdram_fifo_rd_adr(fifo_rd_adr),
|
.sdram_fifo_rd_data(fifo_rd_data),
|
.sdram_fifo_rd_data(fifo_rd_data),
|
.sdram_fifo_re(fifo_re[3][0:nr_of_wb_ports_clk3-1]),
|
.sdram_fifo_re(fifo_re[3][0:nr_of_wb_ports_clk3-1]),
|
.sdram_dat_i(fifo_dat_i),
|
.sdram_dat_i(fifo_dat_i),
|
.sdram_fifo_wr(fifo_wr),
|
.sdram_fifo_wr(fifo_wr),
|
.sdram_fifo_we(fifo_we[3][0:nr_of_wb_ports_clk3-1]),
|
.sdram_fifo_we(fifo_we[3][0:nr_of_wb_ports_clk3-1]),
|
.sdram_burst_reading(burst_reading),
|
.sdram_burst_reading(burst_reading),
|
.sdram_clk(sdram_clk),
|
.sdram_clk(sdram_clk),
|
.sdram_rst(sdram_rst) );
|
.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}};
|
assign fifo_empty[3][nr_of_wb_ports_clk3:15] = {(16-nr_of_wb_ports_clk3){1'b1}};
|
end
|
end
|
end else begin
|
end else begin
|
assign fifo_empty[3] = {16{1'b1}};
|
assign fifo_empty[3] = {16{1'b1}};
|
assign fifo_dat_o[3] = {36{1'b0}};
|
assign fifo_dat_o[3] = {36{1'b0}};
|
end
|
end
|
endgenerate
|
endgenerate
|
|
|
encode encode0
|
encode encode0
|
(
|
(
|
.fifo_empty_0(fifo_empty[0]), .fifo_empty_1(fifo_empty[1]),
|
.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_empty_2(fifo_empty[2]), .fifo_empty_3(fifo_empty[3]),
|
.fifo_sel(fifo_sel_i), .fifo_sel_domain(fifo_sel_domain_i)
|
.fifo_sel(fifo_sel_i), .fifo_sel_domain(fifo_sel_domain_i)
|
);
|
);
|
|
|
always @ (posedge sdram_clk or posedge sdram_rst)
|
always @ (posedge sdram_clk or posedge sdram_rst)
|
begin
|
begin
|
if (sdram_rst)
|
if (sdram_rst)
|
{fifo_sel_reg,fifo_sel_domain_reg} <= {16'h0,2'b00};
|
{fifo_sel_reg,fifo_sel_domain_reg} <= {16'h0,2'b00};
|
else
|
else
|
if (idle)
|
if (idle)
|
{fifo_sel_reg,fifo_sel_domain_reg}<={fifo_sel_i,fifo_sel_domain_i};
|
{fifo_sel_reg,fifo_sel_domain_reg}<={fifo_sel_i,fifo_sel_domain_i};
|
end
|
end
|
|
|
decode decode0
|
decode decode0
|
(
|
(
|
.fifo_sel(fifo_sel_reg), .fifo_sel_domain(fifo_sel_domain_reg),
|
.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_0(fifo_re[0]), .fifo_we_1(fifo_re[1]), .fifo_we_2(fifo_re[2]),
|
.fifo_we_3(fifo_re[3])
|
.fifo_we_3(fifo_re[3])
|
);
|
);
|
|
|
// fifo_re[0-3] is a one-hot read enable structure
|
// fifo_re[0-3] is a one-hot read enable structure
|
// fifo_empty should go active when chosen fifo queue is empty
|
// fifo_empty should go active when chosen fifo queue is empty
|
assign current_fifo_empty = (idle) ?
|
assign current_fifo_empty = (idle) ?
|
(!(|fifo_sel_i)) :
|
(!(|fifo_sel_i)) :
|
(|(fifo_empty[0] & fifo_re[0])) |
|
(|(fifo_empty[0] & fifo_re[0])) |
|
(|(fifo_empty[1] & fifo_re[1])) |
|
(|(fifo_empty[1] & fifo_re[1])) |
|
(|(fifo_empty[2] & fifo_re[2])) |
|
(|(fifo_empty[2] & fifo_re[2])) |
|
(|(fifo_empty[3] & fifo_re[3]));
|
(|(fifo_empty[3] & fifo_re[3]));
|
|
|
decode decode1
|
decode decode1
|
(
|
(
|
.fifo_sel(fifo_sel_dly), .fifo_sel_domain(fifo_sel_domain_dly),
|
.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_0(fifo_we[0]), .fifo_we_1(fifo_we[1]), .fifo_we_2(fifo_we[2]),
|
.fifo_we_3(fifo_we[3])
|
.fifo_we_3(fifo_we[3])
|
);
|
);
|
|
|
`ifdef SDR_16
|
`ifdef SDR_16
|
|
|
wire ref_cnt_zero;
|
wire ref_cnt_zero;
|
reg [(`SDRAM_DATA_WIDTH)-1:0] dq_i_reg /*synthesis syn_useioff=1 syn_allow_retiming=0 */;
|
reg [(`SDRAM_DATA_WIDTH)-1:0] dq_i_reg /*synthesis syn_useioff=1 syn_allow_retiming=0 */;
|
reg [(`SDRAM_DATA_WIDTH)-1:0] dq_i_tmp_reg;
|
reg [(`SDRAM_DATA_WIDTH)-1:0] dq_i_tmp_reg;
|
reg [17:0] dq_o_tmp_reg;
|
reg [17:0] dq_o_tmp_reg;
|
wire cmd_aref, cmd_read;
|
wire cmd_aref, cmd_read;
|
|
|
// refresch counter
|
// refresch counter
|
//ref_counter ref_counter0( .zq(ref_cnt_zero), .rst(sdram_rst), .clk(sdram_clk));
|
//ref_counter ref_counter0( .zq(ref_cnt_zero), .rst(sdram_rst), .clk(sdram_clk));
|
ref_counter
|
ref_counter
|
`ifdef MT48LC32M16
|
`ifdef MT48LC32M16
|
#(.length(9), .wrap_value(67))
|
#(.length(9), .wrap_value(67))
|
`endif
|
`endif
|
ref_counter0( .zq(ref_cnt_zero), .rst(sdram_rst), .clk(sdram_clk));
|
ref_counter0( .zq(ref_cnt_zero), .rst(sdram_rst), .clk(sdram_clk));
|
|
|
always @ (posedge sdram_clk or posedge sdram_rst)
|
always @ (posedge sdram_clk or posedge sdram_rst)
|
if (sdram_rst)
|
if (sdram_rst)
|
refresh_req <= 1'b0;
|
refresh_req <= 1'b0;
|
else
|
else
|
if (ref_cnt_zero)
|
if (ref_cnt_zero)
|
refresh_req <= 1'b1;
|
refresh_req <= 1'b1;
|
else if (cmd_aref)
|
else if (cmd_aref)
|
refresh_req <= 1'b0;
|
refresh_req <= 1'b0;
|
|
|
reg current_fifo_empty_r;
|
reg current_fifo_empty_r;
|
always @(posedge sdram_clk)
|
always @(posedge sdram_clk)
|
current_fifo_empty_r <= current_fifo_empty;
|
current_fifo_empty_r <= current_fifo_empty;
|
|
|
always @(posedge sdram_clk)
|
always @(posedge sdram_clk)
|
sdram_fifo_wr_r <= fifo_wr;
|
sdram_fifo_wr_r <= fifo_wr;
|
|
|
|
|
|
|
// SDR SDRAM 16 FSM
|
// SDR SDRAM 16 FSM
|
fsm_sdr_16 fsm_sdr_16_0
|
fsm_sdr_16 fsm_sdr_16_0
|
(
|
(
|
.adr_i({fifo_dat_o[0][`BA_SIZE+`ROW_SIZE+`COL_SIZE+6-2:6],1'b0}),
|
.adr_i({fifo_dat_o[0][`BA_SIZE+`ROW_SIZE+`COL_SIZE+6-2:6],1'b0}),
|
.we_i(fifo_dat_o[0][5]),
|
.we_i(fifo_dat_o[0][5]),
|
.bte_i(fifo_dat_o[0][4:3]),
|
.bte_i(fifo_dat_o[0][4:3]),
|
.cti_i(fifo_dat_o[0][2:0]),
|
.cti_i(fifo_dat_o[0][2:0]),
|
.sel_i({fifo_dat_o[0][3:2],dq_o_tmp_reg[1:0]}),
|
.sel_i({fifo_dat_o[0][3:2],dq_o_tmp_reg[1:0]}),
|
.fifo_empty(current_fifo_empty_r),
|
.fifo_empty(current_fifo_empty_r),
|
.fifo_rd_adr(fifo_rd_adr),
|
.fifo_rd_adr(fifo_rd_adr),
|
.fifo_rd_data(fifo_rd_data),
|
.fifo_rd_data(fifo_rd_data),
|
.state_idle(idle),
|
.state_idle(idle),
|
.count0(count0),
|
.count0(count0),
|
.refresh_req(refresh_req),
|
.refresh_req(refresh_req),
|
.cmd_aref(cmd_aref),
|
.cmd_aref(cmd_aref),
|
.cmd_read(cmd_read),
|
.cmd_read(cmd_read),
|
.ba(ba_pad_o), .a(a_pad_o),
|
.ba(ba_pad_o), .a(a_pad_o),
|
.cmd({ras_pad_o, cas_pad_o, we_pad_o}),
|
.cmd({ras_pad_o, cas_pad_o, we_pad_o}),
|
.dq_oe(dq_oe),
|
.dq_oe(dq_oe),
|
.dqm(dqm_pad_o),
|
.dqm(dqm_pad_o),
|
.sdram_fifo_wr(sdram_fifo_wr_r),
|
.sdram_fifo_wr(sdram_fifo_wr_r),
|
.sdram_burst_reading(burst_reading),
|
.sdram_burst_reading(burst_reading),
|
.debug_state(),
|
.debug_state(),
|
.debug_fifo_we_record(),
|
.debug_fifo_we_record(),
|
.sdram_clk(sdram_clk),
|
.sdram_clk(sdram_clk),
|
.sdram_rst(sdram_rst)
|
.sdram_rst(sdram_rst)
|
);
|
);
|
|
|
assign cs_pad_o = 1'b0;
|
assign cs_pad_o = 1'b0;
|
assign cke_pad_o = 1'b1;
|
assign cke_pad_o = 1'b1;
|
|
|
genvar i;
|
genvar i;
|
generate
|
generate
|
for (i=0; i < 16; i=i+1) begin : dly
|
for (i=0; i < 16; i=i+1) begin : dly
|
|
|
defparam delay0.depth=`INIT_CL+2;
|
defparam delay0.depth=`INIT_CL+2;
|
defparam delay0.width=1;
|
defparam delay0.width=1;
|
delay delay0 (
|
delay delay0 (
|
.d(fifo_sel_reg[i]),
|
.d(fifo_sel_reg[i]),
|
.q(fifo_sel_dly[i]),
|
.q(fifo_sel_dly[i]),
|
.clk(sdram_clk),
|
.clk(sdram_clk),
|
.rst(sdram_rst)
|
.rst(sdram_rst)
|
);
|
);
|
end
|
end
|
|
|
defparam delay1.depth=`INIT_CL+2;
|
defparam delay1.depth=`INIT_CL+2;
|
defparam delay1.width=2;
|
defparam delay1.width=2;
|
delay delay1 (
|
delay delay1 (
|
.d(fifo_sel_domain_reg),
|
.d(fifo_sel_domain_reg),
|
.q(fifo_sel_domain_dly),
|
.q(fifo_sel_domain_dly),
|
.clk(sdram_clk),
|
.clk(sdram_clk),
|
.rst(sdram_rst)
|
.rst(sdram_rst)
|
);
|
);
|
|
|
defparam delay2.depth=`INIT_CL+2;
|
defparam delay2.depth=`INIT_CL+2;
|
defparam delay2.width=1;
|
defparam delay2.width=1;
|
delay delay2 (
|
delay delay2 (
|
.d(cmd_read),
|
.d(cmd_read),
|
.q(fifo_wr),
|
.q(fifo_wr),
|
.clk(sdram_clk),
|
.clk(sdram_clk),
|
.rst(sdram_rst)
|
.rst(sdram_rst)
|
);
|
);
|
|
|
endgenerate
|
endgenerate
|
|
|
// output registers
|
// output registers
|
assign cs_n_pad_o = 1'b0;
|
assign cs_n_pad_o = 1'b0;
|
assign cke_pad_o = 1'b1;
|
assign cke_pad_o = 1'b1;
|
|
|
always @ (posedge sdram_clk)
|
always @ (posedge sdram_clk)
|
dq_i_reg <= dq_i;
|
dq_i_reg <= dq_i;
|
|
|
always @(posedge sdram_clk)
|
always @(posedge sdram_clk)
|
dq_i_tmp_reg <= dq_i_reg;
|
dq_i_tmp_reg <= 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)
|
always @ (posedge sdram_clk or posedge sdram_rst)
|
if (sdram_rst)
|
if (sdram_rst)
|
dq_o_tmp_reg <= 18'h0;
|
dq_o_tmp_reg <= 18'h0;
|
else
|
else
|
dq_o_tmp_reg <= {fifo_dat_o[0][19:4],fifo_dat_o[0][1:0]};
|
dq_o_tmp_reg <= {fifo_dat_o[0][19:4],fifo_dat_o[0][1:0]};
|
|
|
// output dq_o mux and dffs
|
// output dq_o mux and dffs
|
always @ (posedge sdram_clk or posedge sdram_rst)
|
always @ (posedge sdram_clk or posedge sdram_rst)
|
if (sdram_rst)
|
if (sdram_rst)
|
dq_o <= 16'h0000;
|
dq_o <= 16'h0000;
|
else
|
else
|
if (~count0)
|
if (~count0)
|
dq_o <= fifo_dat_o[0][35:20];
|
dq_o <= fifo_dat_o[0][35:20];
|
else
|
else
|
dq_o <= dq_o_tmp_reg[17:2];
|
dq_o <= dq_o_tmp_reg[17:2];
|
|
|
/*
|
/*
|
// data mask signals should be not(sel_i) for write and 2'b00 for read
|
// data mask signals should be not(sel_i) for write and 2'b00 for read
|
always @ (posedge sdram_clk or posedge sdram_rst)
|
always @ (posedge sdram_clk or posedge sdram_rst)
|
if (sdram_rst)
|
if (sdram_rst)
|
dqm_pad_o <= 2'b00;
|
dqm_pad_o <= 2'b00;
|
else
|
else
|
if (~count0)
|
if (~count0)
|
dqm_pad_o <= ~fifo_dat_o[fifo_sel_domain_reg][3:2];
|
dqm_pad_o <= ~fifo_dat_o[fifo_sel_domain_reg][3:2];
|
else
|
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)
|
always @ (posedge sdram_clk or posedge sdram_rst)
|
if (sdram_rst) begin
|
if (sdram_rst) begin
|
{dq_o, dqm_pad_o} <= {16'h0000,2'b00};
|
{dq_o, dqm_pad_o} <= {16'h0000,2'b00};
|
|
|
end else
|
end else
|
if (~count0) begin
|
if (~count0) begin
|
dq_o <= fifo_dat_o[fifo_sel_domain_reg][35:20];
|
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];
|
dq_o_tmp_reg[17:2] <= fifo_dat_o[fifo_sel_domain_reg][19:4];
|
if (cmd_read)
|
if (cmd_read)
|
dqm_pad_o <= 2'b00;
|
dqm_pad_o <= 2'b00;
|
else
|
else
|
dqm_pad_o <= ~fifo_dat_o[fifo_sel_domain_reg][3:2];
|
dqm_pad_o <= ~fifo_dat_o[fifo_sel_domain_reg][3:2];
|
if (cmd_read)
|
if (cmd_read)
|
dq_o_tmp_reg[1:0] <= 2'b00;
|
dq_o_tmp_reg[1:0] <= 2'b00;
|
else
|
else
|
dq_o_tmp_reg[1:0] <= ~fifo_dat_o[fifo_sel_domain_reg][1:0];
|
dq_o_tmp_reg[1:0] <= ~fifo_dat_o[fifo_sel_domain_reg][1:0];
|
end else
|
end else
|
{dq_o,dqm_pad_o} <= dq_o_tmp_reg;
|
{dq_o,dqm_pad_o} <= dq_o_tmp_reg;
|
*/
|
*/
|
|
|
|
|
`endif // `ifdef SDR_16
|
`endif // `ifdef SDR_16
|
|
|
|
|
`ifdef DDR_16
|
`ifdef DDR_16
|
wire read, write;
|
wire read, write;
|
wire sdram_clk_90, sdram_clk_180, sdram_clk_270;
|
wire sdram_clk_90, sdram_clk_180, sdram_clk_270;
|
wire ck_fb;
|
wire ck_fb;
|
reg cke, ras, cas, we, cs_n;
|
reg cke, ras, cas, we, cs_n;
|
wire cke_d, ras_d, cas_d, we_d, cs_n_d;
|
wire cke_d, ras_d, cas_d, we_d, cs_n_d;
|
wire ras_o, cas_o, we_o, cs_n_o;
|
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;
|
wire [12:0] addr_o;
|
reg [1:0] ba;
|
reg [1:0] ba;
|
wire [1:0] ba_d;
|
wire [1:0] ba_d;
|
reg [12:0] addr;
|
reg [12:0] addr;
|
wire [12:0] addr_d;
|
wire [12:0] addr_d;
|
wire dq_en, dqm_en;
|
wire dq_en, dqm_en;
|
reg [15:0] dq_tx_reg;
|
reg [15:0] dq_tx_reg;
|
wire [15:0] dq_tx;
|
wire [15:0] dq_tx;
|
reg [31:0] dq_rx_reg;
|
reg [31:0] dq_rx_reg;
|
wire [31:0] dq_rx;
|
wire [31:0] dq_rx;
|
wire [15:0] dq_o;
|
wire [15:0] dq_o;
|
reg [3:0] dqm_tx_reg;
|
reg [3:0] dqm_tx_reg;
|
wire [3:0] dqm_tx;
|
wire [3:0] dqm_tx;
|
wire [1:0] dqm_o, dqs_o, dqs_n_o;
|
wire [1:0] dqm_o, dqs_o, dqs_n_o;
|
wire ref_delay, ref_delay_ack;
|
wire ref_delay, ref_delay_ack;
|
wire bl_en, bl_ack;
|
wire bl_en, bl_ack;
|
wire tx_fifo_re, tx_fifo_re_i;
|
wire tx_fifo_re, tx_fifo_re_i;
|
//wire adr_init_delay;
|
//wire adr_init_delay;
|
//reg adr_init_delay_i;
|
//reg adr_init_delay_i;
|
reg [3:0] burst_cnt;
|
reg [3:0] burst_cnt;
|
wire [3:0] burst_next_cnt, burst_length;
|
wire [3:0] burst_next_cnt, burst_length;
|
//wire burst_mask;
|
//wire burst_mask;
|
reg burst_mask;
|
reg burst_mask;
|
wire [12:0] cur_row;
|
wire [12:0] cur_row;
|
wire [3:0] burst_adr;
|
wire [3:0] burst_adr;
|
//wire [2:0] tx_fifo_b_sel_i_cur;
|
//wire [2:0] tx_fifo_b_sel_i_cur;
|
wire [2:0] rx_fifo_a_sel_i;
|
wire [2:0] rx_fifo_a_sel_i;
|
//wire [7:0] tx_fifo_empty;
|
//wire [7:0] tx_fifo_empty;
|
wire rx_fifo_we;
|
wire rx_fifo_we;
|
|
|
wire ref_cnt_zero;
|
wire ref_cnt_zero;
|
wire cmd_aref;
|
wire cmd_aref;
|
|
|
// refresh counter
|
// refresh counter
|
ref_counter ref_counter0(
|
ref_counter ref_counter0(
|
.zq(ref_cnt_zero),
|
.zq(ref_cnt_zero),
|
.rst(sdram_rst),
|
.rst(sdram_rst),
|
.clk(sdram_clk));
|
.clk(sdram_clk));
|
always @ (posedge sdram_clk or posedge sdram_rst)
|
always @ (posedge sdram_clk or posedge sdram_rst)
|
if (sdram_rst)
|
if (sdram_rst)
|
refresh_req <= 1'b0;
|
refresh_req <= 1'b0;
|
else
|
else
|
if (ref_cnt_zero)
|
if (ref_cnt_zero)
|
refresh_req <= 1'b1;
|
refresh_req <= 1'b1;
|
else if (cmd_aref)
|
else if (cmd_aref)
|
refresh_req <= 1'b0;
|
refresh_req <= 1'b0;
|
|
|
// DDR SDRAM 16 FSM
|
// DDR SDRAM 16 FSM
|
ddr_16 ddr_16_0
|
ddr_16 ddr_16_0
|
(
|
(
|
.adr_init(adr_init),
|
.adr_init(adr_init),
|
.fifo_re(tx_fifo_re_i),
|
.fifo_re(tx_fifo_re_i),
|
.fifo_re_d(tx_fifo_re),
|
.fifo_re_d(tx_fifo_re),
|
.tx_fifo_dat_o(fifo_dat_o[fifo_sel_domain_reg]),
|
.tx_fifo_dat_o(fifo_dat_o[fifo_sel_domain_reg]),
|
.burst_adr(burst_adr),
|
.burst_adr(burst_adr),
|
.fifo_empty(current_fifo_empty),
|
.fifo_empty(current_fifo_empty),
|
.fifo_sel(),
|
.fifo_sel(),
|
.read(read),
|
.read(read),
|
.write(write),
|
.write(write),
|
.ref_req(refresh_req),
|
.ref_req(refresh_req),
|
.ref_ack(cmd_aref),
|
.ref_ack(cmd_aref),
|
.ref_delay(ref_delay),
|
.ref_delay(ref_delay),
|
.state_idle(idle),
|
.state_idle(idle),
|
.ref_delay_ack(ref_delay_ack),
|
.ref_delay_ack(ref_delay_ack),
|
.bl_en(bl_en),
|
.bl_en(bl_en),
|
.bl_ack(bl_ack),
|
.bl_ack(bl_ack),
|
.a({ba_o,addr_o}),
|
.a({ba_o,addr_o}),
|
.cmd({ras_o,cas_o,we_o}),
|
.cmd({ras_o,cas_o,we_o}),
|
.cs_n(cs_n_o),
|
.cs_n(cs_n_o),
|
.cur_row(cur_row),
|
.cur_row(cur_row),
|
.clk(sdram_clk_0),
|
.clk(sdram_clk_0),
|
.rst(sdram_rst)
|
.rst(sdram_rst)
|
);
|
);
|
|
|
inc_adr inc_adr0
|
inc_adr inc_adr0
|
(
|
(
|
.adr_i(fifo_dat_o[fifo_sel_domain_reg][9:6]),
|
.adr_i(fifo_dat_o[fifo_sel_domain_reg][9:6]),
|
.bte_i(fifo_dat_o[fifo_sel_domain_reg][4:3]),
|
.bte_i(fifo_dat_o[fifo_sel_domain_reg][4:3]),
|
.cti_i(fifo_dat_o[fifo_sel_domain_reg][2:0]),
|
.cti_i(fifo_dat_o[fifo_sel_domain_reg][2:0]),
|
.init(adr_init),
|
.init(adr_init),
|
.inc(),
|
.inc(),
|
.adr_o(burst_adr),
|
.adr_o(burst_adr),
|
.done(done),
|
.done(done),
|
.clk(sdram_clk_0),
|
.clk(sdram_clk_0),
|
.rst(sdram_rst)
|
.rst(sdram_rst)
|
);
|
);
|
|
|
// Delay, refresh to activate/refresh
|
// Delay, refresh to activate/refresh
|
ref_delay_counter ref_delay_counter0
|
ref_delay_counter ref_delay_counter0
|
(
|
(
|
.cke(ref_delay),
|
.cke(ref_delay),
|
.zq(ref_delay_ack),
|
.zq(ref_delay_ack),
|
.clk(sdram_clk_0),
|
.clk(sdram_clk_0),
|
.rst(sdram_rst)
|
.rst(sdram_rst)
|
);
|
);
|
|
|
// Burst length, DDR2 SDRAM
|
// Burst length, DDR2 SDRAM
|
burst_length_counter burst_length_counter0
|
burst_length_counter burst_length_counter0
|
(
|
(
|
.cke(bl_en),
|
.cke(bl_en),
|
.zq(bl_ack),
|
.zq(bl_ack),
|
.clk(sdram_clk_0),
|
.clk(sdram_clk_0),
|
.rst(sdram_rst)
|
.rst(sdram_rst)
|
);
|
);
|
|
|
// Wishbone burst length
|
// Wishbone burst length
|
assign burst_length = (adr_init && fifo_dat_o[fifo_sel_domain_reg][2:0] == 3'b000) ? 4'd1 : // classic cycle
|
assign burst_length = (adr_init && fifo_dat_o[fifo_sel_domain_reg][2:0] == 3'b000) ? 4'd1 : // classic cycle
|
(adr_init && fifo_dat_o[fifo_sel_domain_reg][2:0] == 3'b010) ? 4'd4 : // incremental burst cycle
|
(adr_init && fifo_dat_o[fifo_sel_domain_reg][2:0] == 3'b010) ? 4'd4 : // incremental burst cycle
|
burst_length;
|
burst_length;
|
|
|
// Burst mask
|
// Burst mask
|
// Burst length counter
|
// Burst length counter
|
assign burst_next_cnt = (burst_cnt == 3) ? 4'd0 : burst_cnt + 4'd1;
|
assign burst_next_cnt = (burst_cnt == 3) ? 4'd0 : burst_cnt + 4'd1;
|
always @ (posedge sdram_clk_0 or posedge sdram_rst)
|
always @ (posedge sdram_clk_0 or posedge sdram_rst)
|
if (sdram_rst)
|
if (sdram_rst)
|
burst_cnt <= 4'h0;
|
burst_cnt <= 4'h0;
|
else
|
else
|
if (bl_en)
|
if (bl_en)
|
burst_cnt <= burst_next_cnt;
|
burst_cnt <= burst_next_cnt;
|
// Burst Mask
|
// Burst Mask
|
//assign burst_mask = (burst_cnt >= burst_length) ? 1'b1 : 1'b0;
|
//assign burst_mask = (burst_cnt >= burst_length) ? 1'b1 : 1'b0;
|
|
|
// Burst Mask
|
// Burst Mask
|
always @ (posedge sdram_clk_0 or posedge sdram_rst)
|
always @ (posedge sdram_clk_0 or posedge sdram_rst)
|
if (sdram_rst)
|
if (sdram_rst)
|
burst_mask <= 1'b0;
|
burst_mask <= 1'b0;
|
else
|
else
|
burst_mask <= (burst_cnt >= burst_length) ? 1'b1 : 1'b0;
|
burst_mask <= (burst_cnt >= burst_length) ? 1'b1 : 1'b0;
|
|
|
// Delay address and control to compensate for delay in Tx FIOFs
|
// Delay address and control to compensate for delay in Tx FIOFs
|
defparam delay0.depth=3;
|
defparam delay0.depth=3;
|
defparam delay0.width=20;
|
defparam delay0.width=20;
|
delay delay0 (
|
delay delay0 (
|
.d({cs_n_o,1'b1,ras_o,cas_o,we_o,ba_o,addr_o}),
|
.d({cs_n_o,1'b1,ras_o,cas_o,we_o,ba_o,addr_o}),
|
.q({cs_n_d,cke_d,ras_d,cas_d,we_d,ba_d,addr_d}),
|
.q({cs_n_d,cke_d,ras_d,cas_d,we_d,ba_d,addr_d}),
|
.clk(sdram_clk_180),
|
.clk(sdram_clk_180),
|
.rst(sdram_rst));
|
.rst(sdram_rst));
|
|
|
// Assing outputs
|
// Assing outputs
|
// Non-DDR outputs
|
// Non-DDR outputs
|
assign cs_n_pad_o = cs_n_d;
|
assign cs_n_pad_o = cs_n_d;
|
assign cke_pad_o = cke_d;
|
assign cke_pad_o = cke_d;
|
assign ras_pad_o = ras_d;
|
assign ras_pad_o = ras_d;
|
assign cas_pad_o = cas_d;
|
assign cas_pad_o = cas_d;
|
assign we_pad_o = we_d;
|
assign we_pad_o = we_d;
|
assign ba_pad_o = ba_d;
|
assign ba_pad_o = ba_d;
|
assign addr_pad_o = addr_d;
|
assign addr_pad_o = addr_d;
|
assign ck_fb_pad_o = ck_fb;
|
assign ck_fb_pad_o = ck_fb;
|
assign dqs_oe = dq_en;
|
assign dqs_oe = dq_en;
|
|
|
// Read latency, delay the control signals to fit latency of the DDR2 SDRAM
|
// Read latency, delay the control signals to fit latency of the DDR2 SDRAM
|
defparam delay1.depth=`CL+`AL+4;
|
defparam delay1.depth=`CL+`AL+4;
|
defparam delay1.width=1;
|
defparam delay1.width=1;
|
delay delay1
|
delay delay1
|
(
|
(
|
.d(read && !burst_mask),
|
.d(read && !burst_mask),
|
.q(fifo_wr),
|
.q(fifo_wr),
|
.clk(sdram_clk_0),
|
.clk(sdram_clk_0),
|
.rst(sdram_rst)
|
.rst(sdram_rst)
|
);
|
);
|
|
|
// write latency, delay the control signals to fit latency of the DDR2 SDRAM
|
// write latency, delay the control signals to fit latency of the DDR2 SDRAM
|
defparam delay2.depth=`CL+`AL+1;
|
defparam delay2.depth=`CL+`AL+1;
|
defparam delay2.width=1;
|
defparam delay2.width=1;
|
delay delay2
|
delay delay2
|
(
|
(
|
.d(write),
|
.d(write),
|
.q(dq_en),
|
.q(dq_en),
|
.clk(sdram_clk_270),
|
.clk(sdram_clk_270),
|
.rst(sdram_rst)
|
.rst(sdram_rst)
|
);
|
);
|
|
|
// write latency, delay the control signals to fit latency of the DDR2 SDRAM
|
// write latency, delay the control signals to fit latency of the DDR2 SDRAM
|
defparam delay21.depth=`CL+`AL;
|
defparam delay21.depth=`CL+`AL;
|
defparam delay21.width=1;
|
defparam delay21.width=1;
|
delay delay21
|
delay delay21
|
(
|
(
|
.d(burst_mask),
|
.d(burst_mask),
|
.q(dqm_en),
|
.q(dqm_en),
|
.clk(sdram_clk_270),
|
.clk(sdram_clk_270),
|
.rst(sdram_rst)
|
.rst(sdram_rst)
|
);
|
);
|
|
|
/* // if CL>3 delay read from Tx FIFO
|
/* // if CL>3 delay read from Tx FIFO
|
defparam delay3.depth=`CL+`AL-3;
|
defparam delay3.depth=`CL+`AL-3;
|
defparam delay3.width=1;
|
defparam delay3.width=1;
|
delay delay3
|
delay delay3
|
(
|
(
|
.d(tx_fifo_re_i && !burst_mask),
|
.d(tx_fifo_re_i && !burst_mask),
|
.q(tx_fifo_re),
|
.q(tx_fifo_re),
|
.clk(sdram_clk_0),
|
.clk(sdram_clk_0),
|
.rst(sdram_rst)
|
.rst(sdram_rst)
|
);
|
);
|
*/
|
*/
|
|
|
// if CL=3, no delay
|
// if CL=3, no delay
|
assign tx_fifo_re = tx_fifo_re_i && !burst_mask;
|
assign tx_fifo_re = tx_fifo_re_i && !burst_mask;
|
assign fifo_rd_adr = tx_fifo_re;
|
assign fifo_rd_adr = tx_fifo_re;
|
|
|
//
|
//
|
genvar i;
|
genvar i;
|
generate
|
generate
|
for (i=0; i < 16; i=i+1) begin : dly
|
for (i=0; i < 16; i=i+1) begin : dly
|
|
|
defparam delay4.depth=`CL+2;
|
defparam delay4.depth=`CL+2;
|
defparam delay4.width=1;
|
defparam delay4.width=1;
|
delay delay4 (
|
delay delay4 (
|
.d(fifo_sel_reg[i]),
|
.d(fifo_sel_reg[i]),
|
.q(fifo_sel_dly[i]),
|
.q(fifo_sel_dly[i]),
|
.clk(sdram_clk),
|
.clk(sdram_clk),
|
.rst(sdram_rst)
|
.rst(sdram_rst)
|
);
|
);
|
end
|
end
|
|
|
defparam delay5.depth=`CL+2;
|
defparam delay5.depth=`CL+2;
|
defparam delay5.width=2;
|
defparam delay5.width=2;
|
delay delay5 (
|
delay delay5 (
|
.d(fifo_sel_domain_reg),
|
.d(fifo_sel_domain_reg),
|
.q(fifo_sel_domain_dly),
|
.q(fifo_sel_domain_dly),
|
.clk(sdram_clk),
|
.clk(sdram_clk),
|
.rst(sdram_rst)
|
.rst(sdram_rst)
|
);
|
);
|
endgenerate
|
endgenerate
|
|
|
|
|
// Increment address
|
// Increment address
|
defparam delay6.depth=`CL+`AL-1;
|
defparam delay6.depth=`CL+`AL-1;
|
defparam delay6.width=1;
|
defparam delay6.width=1;
|
delay delay6
|
delay delay6
|
(
|
(
|
.d({write|read}),
|
.d({write|read}),
|
.q({adr_inc}),
|
.q({adr_inc}),
|
.clk(sdram_clk_0),
|
.clk(sdram_clk_0),
|
.rst(sdram_rst)
|
.rst(sdram_rst)
|
);
|
);
|
|
|
// DCM/PLL with internal and external feedback
|
// DCM/PLL with internal and external feedback
|
// Remove skew from internal and external clock
|
// Remove skew from internal and external clock
|
// Parameters are set in dcm_pll.v
|
// Parameters are set in dcm_pll.v
|
dcm_pll dcm_pll_0
|
dcm_pll dcm_pll_0
|
(
|
(
|
.rst(sdram_rst),
|
.rst(sdram_rst),
|
.clk_in(sdram_clk),
|
.clk_in(sdram_clk),
|
.clkfb_in(ck_fb_pad_i),
|
.clkfb_in(ck_fb_pad_i),
|
.clk0_out(sdram_clk_0),
|
.clk0_out(sdram_clk_0),
|
.clk90_out(sdram_clk_90),
|
.clk90_out(sdram_clk_90),
|
.clk180_out(sdram_clk_180),
|
.clk180_out(sdram_clk_180),
|
.clk270_out(sdram_clk_270),
|
.clk270_out(sdram_clk_270),
|
.clkfb_out(ck_fb)
|
.clkfb_out(ck_fb)
|
);
|
);
|
|
|
// DDR2 IF
|
// DDR2 IF
|
versatile_mem_ctrl_ddr versatile_mem_ctrl_ddr_0
|
versatile_mem_ctrl_ddr versatile_mem_ctrl_ddr_0
|
(
|
(
|
// DDR2 SDRAM ports
|
// DDR2 SDRAM ports
|
.ck_o(ck_pad_o),
|
.ck_o(ck_pad_o),
|
.ck_n_o(ck_n_pad_o),
|
.ck_n_o(ck_n_pad_o),
|
.dq_io(dq_pad_io),
|
.dq_io(dq_pad_io),
|
.dqs_io(dqs_pad_io),
|
.dqs_io(dqs_pad_io),
|
.dqs_n_io(dqs_n_pad_io),
|
.dqs_n_io(dqs_n_pad_io),
|
.dm_rdqs_io(dm_rdqs_pad_io),
|
.dm_rdqs_io(dm_rdqs_pad_io),
|
// Memory controller side
|
// Memory controller side
|
.tx_dat_i(fifo_dat_o[fifo_sel_domain_reg]),
|
.tx_dat_i(fifo_dat_o[fifo_sel_domain_reg]),
|
.rx_dat_o(fifo_dat_i),
|
.rx_dat_o(fifo_dat_i),
|
.dq_en(dq_en),
|
.dq_en(dq_en),
|
.dqm_en(dqm_en),
|
.dqm_en(dqm_en),
|
.rst(sdram_rst),
|
.rst(sdram_rst),
|
.clk_0(sdram_clk_0),
|
.clk_0(sdram_clk_0),
|
.clk_90(sdram_clk_90),
|
.clk_90(sdram_clk_90),
|
.clk_180(sdram_clk_180),
|
.clk_180(sdram_clk_180),
|
.clk_270(sdram_clk_270));
|
.clk_270(sdram_clk_270));
|
|
|
`endif // `ifdef DDR_16
|
`endif // `ifdef DDR_16
|
|
|
endmodule // wb_sdram_ctrl_top
|
endmodule // wb_sdram_ctrl_top
|
|
|