OpenCores
URL https://opencores.org/ocsvn/versatile_mem_ctrl/versatile_mem_ctrl/trunk

Subversion Repositories versatile_mem_ctrl

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 31 to Rev 32
    Reverse comparison

Rev 31 → Rev 32

/versatile_mem_ctrl/trunk/bench/tb.v
179,38 → 179,38
.wb_stb_i_0(wb_stb_i_v),
.wb_ack_o_0(wb_ack_o_v),
// wb clk1
/* .wb_dat_i_1(),
.wb_dat_i_1(),
.wb_dat_o_1(),
.wb_adr_i_1(),
.wb_sel_i_1(),
.wb_cti_i_1(),
.wb_bte_i_1(),
.wb_we_i_1(),
//.wb_sel_i_1(),
//.wb_cti_i_1(),
//.wb_bte_i_1(),
//.wb_we_i_1(),
.wb_cyc_i_1(),
.wb_stb_i_1(),
.wb_ack_o_1(), */
.wb_ack_o_1(),
// wb clk2
/* .wb_dat_i_2(),
.wb_dat_i_2(),
.wb_dat_o_2(),
.wb_adr_i_2(),
.wb_sel_i_2(),
.wb_cti_i_2(),
.wb_bte_i_2(),
.wb_we_i_2(),
//.wb_sel_i_2(),
//.wb_cti_i_2(),
//.wb_bte_i_2(),
//.wb_we_i_2(),
.wb_cyc_i_2(),
.wb_stb_i_2(),
.wb_ack_o_2(), */
.wb_ack_o_2(),
// wb clk3
/* .wb_dat_i_3(),
.wb_dat_i_3(),
.wb_dat_o_3(),
.wb_adr_i_3(),
.wb_sel_i_3(),
.wb_cti_i_3(),
.wb_bte_i_3(),
.wb_we_i_3(),
//.wb_sel_i_3(),
//.wb_cti_i_3(),
//.wb_bte_i_3(),
//.wb_we_i_3(),
.wb_cyc_i_3(),
.wb_stb_i_3(),
.wb_ack_o_3(), */
.wb_ack_o_3(),
// SDR SDRAM 16
`ifdef SDR_16
.ba_pad_o(ba),
/versatile_mem_ctrl/trunk/rtl/verilog/versatile_mem_ctrl_ip.v
100,7 → 100,9
input wclk, rclk, rst;
reg direction, direction_set, direction_clr;
wire tmp_direction; // MF
 
wire async_empty, async_full;
wire fifo_full2;
reg fifo_empty2;
129,7 → 131,10
endcase
 
`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));
dff_sr dff_sr_dir( .aclr(direction_clr), .aset(direction_set), .clock(1'b1), .data(1'b1), .q(tmp_direction));
always @ (tmp_direction)
direction <= tmp_direction;
`endif
 
`ifdef GENERATE_DIRECTION_AS_LATCH
162,17 → 167,20
{fifo_empty,fifo_empty2} <= {fifo_empty2,async_empty};
 
endmodule // async_comp
module vfifo_dual_port_ram_dc_sw
module vfifo_dual_port_ram_dc_dw
(
d_a,
q_a,
adr_a,
we_a,
clk_a,
q_b,
adr_b,
d_b,
we_b,
clk_b
);
parameter DATA_WIDTH = 32;
parameter DATA_WIDTH = 36;
parameter ADDR_WIDTH = 8;
input [(DATA_WIDTH-1):0] d_a;
input [(ADDR_WIDTH-1):0] adr_a;
179,15 → 187,24
input [(ADDR_WIDTH-1):0] adr_b;
input we_a;
output [(DATA_WIDTH-1):0] q_b;
input [(DATA_WIDTH-1):0] d_b;
output reg [(DATA_WIDTH-1):0] q_a;
input we_b;
input clk_a, clk_b;
reg [(ADDR_WIDTH-1):0] adr_b_reg;
reg [(DATA_WIDTH-1):0] q_b;
reg [DATA_WIDTH-1:0] ram [(1<<ADDR_WIDTH)-1:0] ;
always @ (posedge clk_a)
if (we_a)
ram[adr_a] <= d_a;
begin
q_a <= ram[adr_a];
if (we_a)
ram[adr_a] <= d_a;
end
always @ (posedge clk_b)
adr_b_reg <= adr_b;
assign q_b = ram[adr_b_reg];
begin
q_b <= ram[adr_b];
if (we_b)
ram[adr_b] <= d_b;
end
endmodule
//////////////////////////////////////////////////////////////////////
//// ////
234,7 → 251,7
// GRAY counter
module fifo_adr_counter ( cke, q, q_bin, rst, clk);
 
parameter length = 4;
parameter length = 5;
input cke;
output reg [length:1] q;
output [length:1] q_bin;
241,6 → 258,9
input rst;
input clk;
 
parameter clear_value = 0;
parameter set_value = 0;
parameter wrap_value = 9;
 
reg [length:1] qi;
wire [length:1] q_next;
306,7 → 326,7
//////////////////////////////////////////////////////////////////////
 
// LFSR counter
module fifo_adr_cnt ( clear, cke, zq, rst, clk);
module ctrl_counter ( clear, cke, zq, rst, clk);
 
parameter length = 5;
input clear;
2976,347 → 2996,370
endmodule // dcm_pll
 
 
// megafunction wizard: %LPM_FF%
// GENERATION: STANDARD
// VERSION: WM1.0
// MODULE: lpm_ff
module dff_sr (aclr, aset, clock, data, q);
 
// ============================================================
// File Name: dff_sr.v
// Megafunction Name(s):
// lpm_ff
//
// Simulation Library Files(s):
// lpm
// ============================================================
// ************************************************************
// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
//
// 9.1 Build 222 10/21/2009 SJ Full Version
// ************************************************************
input aclr;
input aset;
input clock;
input data;
output q;
 
wire data_in = data;
wire data_out;
wire q = data_out;
 
//Copyright (C) 1991-2009 Altera Corporation
//Your use of Altera Corporation's design tools, logic functions
//and other software and tools, and its AMPP partner logic
//functions, and any output files from any of the foregoing
//(including device programming or simulation files), and any
//associated documentation or information are expressly subject
//to the terms and conditions of the Altera Program License
//Subscription Agreement, Altera MegaCore Function License
//Agreement, or other applicable license agreement, including,
//without limitation, that your use is for the sole purpose of
//programming logic devices manufactured by Altera and sold by
//Altera or its authorized distributors. Please refer to the
//applicable agreement for further details.
`ifdef XILINX
FDCP FDCP_inst (
.Q(data_out),
.C(clock),
.CLR(aclr),
.D(data_in),
.PRE(aset));
defparam
FDCP_inst.INIT = 1'b0;
`endif // XILINX
 
`ifdef ALTERA
lpm_ff lpm_ff_inst (
.aclr(aclr),
.clock(clock),
.data(data_in),
.aset(aset),
.aload(),
.enable(),
.sclr(),
.sload(),
.sset(),
.q(data_out));
defparam
lpm_ff_inst.lpm_fftype = "DFF",
lpm_ff_inst.lpm_type = "LPM_FF",
lpm_ff_inst.lpm_width = 1;
`endif // ALTERA
 
// synopsys translate_off
`timescale 1 ps / 1 ps
// synopsys translate_on
module dff_sr (
aclr,
aset,
clock,
data,
q);
endmodule
 
input aclr;
input aset;
input clock;
input data;
output q;
module versatile_mem_ctrl_ddr (
// DDR2 SDRAM side
ck_o, ck_n_o,
dq_io, dqs_io, dqs_n_io,
dm_rdqs_io,
//rdqs_n_i, odt_o,
// Memory controller side
tx_dat_i, rx_dat_o,
dq_en, dqm_en,
wb_rst, sdram_clk_0, sdram_clk_90, sdram_clk_180, sdram_clk_270
);
 
wire [0:0] sub_wire0;
wire [0:0] sub_wire1 = sub_wire0[0:0];
wire q = sub_wire1;
wire sub_wire2 = data;
wire sub_wire3 = sub_wire2;
output ck_o;
output ck_n_o;
inout [15:0] dq_io;
inout [1:0] dqs_io;
inout [1:0] dqs_n_io;
inout [1:0] dm_rdqs_io;
//input [1:0] rdqs_n_i;
//output odt_o;
input [35:0] tx_dat_i;
output [35:0] rx_dat_o;
input dq_en;
input dqm_en;
input wb_rst;
input sdram_clk_0;
input sdram_clk_90;
input sdram_clk_180;
input sdram_clk_270;
 
lpm_ff lpm_ff_component (
.aclr (aclr),
.clock (clock),
.data (sub_wire3),
.aset (aset),
.q (sub_wire0)
// synopsys translate_off
,
.aload (),
.enable (),
.sclr (),
.sload (),
.sset ()
// synopsys translate_on
);
defparam
lpm_ff_component.lpm_fftype = "DFF",
lpm_ff_component.lpm_type = "LPM_FF",
lpm_ff_component.lpm_width = 1;
reg [31:0] dq_rx_reg;
wire [31:0] dq_rx;
wire [1:0] dqs_o, dqs_n_o, dqm_o;
wire [15:0] dq_o;
wire [1:0] dqs_delayed;
wire [1:0] dqs_n_delayed;
 
genvar i;
 
endmodule
// Generate clock with equal delay as data
ddr_ff_out ddr_ff_out_ck (
.Q(ck_o),
.C0(sdram_clk_0),
.C1(sdram_clk_180),
.CE(1'b1),
.D0(1'b1),
.D1(1'b0),
.R(1'b0),
.S(1'b0));
 
// ============================================================
// CNX file retrieval info
// ============================================================
// Retrieval info: PRIVATE: ACLR NUMERIC "1"
// Retrieval info: PRIVATE: ALOAD NUMERIC "0"
// Retrieval info: PRIVATE: ASET NUMERIC "1"
// Retrieval info: PRIVATE: ASET_ALL1 NUMERIC "1"
// Retrieval info: PRIVATE: CLK_EN NUMERIC "0"
// Retrieval info: PRIVATE: DFF NUMERIC "1"
// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Stratix"
// Retrieval info: PRIVATE: SCLR NUMERIC "0"
// Retrieval info: PRIVATE: SLOAD NUMERIC "0"
// Retrieval info: PRIVATE: SSET NUMERIC "0"
// Retrieval info: PRIVATE: SSET_ALL1 NUMERIC "1"
// Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
// Retrieval info: PRIVATE: UseTFFdataPort NUMERIC "0"
// Retrieval info: PRIVATE: nBit NUMERIC "1"
// Retrieval info: CONSTANT: LPM_FFTYPE STRING "DFF"
// Retrieval info: CONSTANT: LPM_TYPE STRING "LPM_FF"
// Retrieval info: CONSTANT: LPM_WIDTH NUMERIC "1"
// Retrieval info: USED_PORT: aclr 0 0 0 0 INPUT NODEFVAL aclr
// Retrieval info: USED_PORT: aset 0 0 0 0 INPUT NODEFVAL aset
// Retrieval info: USED_PORT: clock 0 0 0 0 INPUT NODEFVAL clock
// Retrieval info: USED_PORT: data 0 0 0 0 INPUT NODEFVAL data
// Retrieval info: USED_PORT: q 0 0 0 0 OUTPUT NODEFVAL q
// Retrieval info: CONNECT: @clock 0 0 0 0 clock 0 0 0 0
// Retrieval info: CONNECT: q 0 0 0 0 @q 0 0 1 0
// Retrieval info: CONNECT: @aclr 0 0 0 0 aclr 0 0 0 0
// Retrieval info: CONNECT: @aset 0 0 0 0 aset 0 0 0 0
// Retrieval info: CONNECT: @data 0 0 1 0 data 0 0 0 0
// Retrieval info: LIBRARY: lpm lpm.lpm_components.all
// Retrieval info: GEN_FILE: TYPE_NORMAL dff_sr.v TRUE
// Retrieval info: GEN_FILE: TYPE_NORMAL dff_sr.inc FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL dff_sr.cmp TRUE
// Retrieval info: GEN_FILE: TYPE_NORMAL dff_sr.bsf FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL dff_sr_inst.v TRUE
// Retrieval info: GEN_FILE: TYPE_NORMAL dff_sr_bb.v TRUE
// Retrieval info: LIB_FILE: lpm
module versatile_mem_ctrl_wb (
// wishbone side
wb_adr_i_v, wb_dat_i_v, wb_dat_o,
wb_stb_i, wb_cyc_i, wb_ack_o,
wb_clk, wb_rst,
// SDRAM controller interface
sdram_dat_o, sdram_fifo_empty, sdram_fifo_rd,
sdram_dat_i, sdram_fifo_wr,
sdram_clk, sdram_rst
ddr_ff_out ddr_ff_out_ck_n (
.Q(ck_n_o),
.C0(sdram_clk_0),
.C1(sdram_clk_180),
.CE(1'b1),
.D0(1'b0),
.D1(1'b1),
.R(wb_rst),
.S(1'b0));
 
);
// Generate strobe with equal delay as data
generate
for (i=0; i<2; i=i+1) begin:dqs_oddr
ddr_ff_out ddr_ff_out_dqs (
.Q(dqs_o[i]),
.C0(sdram_clk_0),
.C1(sdram_clk_180),
.CE(1'b1),
.D0(1'b1),
.D1(1'b0),
.R(1'b0),
.S(1'b0));
end
endgenerate
 
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_dat_i_v;
input [0:nr_of_wb_ports-1] wb_stb_i;
input [0:nr_of_wb_ports-1] wb_cyc_i;
output [31:0] wb_dat_o;
output reg [0:nr_of_wb_ports-1] wb_ack_o;
input wb_clk;
input wb_rst;
generate
for (i=0; i<2; i=i+1) begin:dqs_n_oddr
ddr_ff_out ddr_ff_out_dqs_n (
.Q(dqs_n_o[i]),
.C0(sdram_clk_0),
.C1(sdram_clk_180),
.CE(1'b1),
.D0(1'b0),
.D1(1'b1),
.R(wb_rst),
.S(1'b0));
end
endgenerate
 
output [35:0] sdram_dat_o;
output [0:nr_of_wb_ports-1] sdram_fifo_empty;
input [0:nr_of_wb_ports-1] sdram_fifo_rd;
input [31:0] sdram_dat_i;
input [0:nr_of_wb_ports-1] sdram_fifo_wr;
input sdram_clk;
input sdram_rst;
// Assign outports
assign dqs_io = dq_en ? dqs_o : 2'bz;
assign dqs_n_io = dq_en ? dqs_n_o : 2'bz;
 
parameter linear_burst = 2'b00;
parameter wrap4 = 2'b01;
parameter wrap8 = 2'b10;
parameter wrap16 = 2'b11;
parameter classic = 3'b000;
parameter endofburst = 3'b111;
 
`define CTI_I 2:0
`define BTE_I 4:3
`define WE_I 5
`ifdef XILINX
 
parameter idle = 2'b00;
parameter rd = 2'b01;
parameter wr = 2'b10;
reg [1:0] wb_state[0:nr_of_wb_ports-1];
reg [15:0] dq_tx_reg;
wire [15:0] dq_tx;
reg [3:0] dqm_tx_reg;
wire [3:0] dqm_tx;
 
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] egress_fifo_di[0:nr_of_wb_ports-1];
// Data out
// Data from Tx FIFO
always @ (posedge sdram_clk_270 or posedge wb_rst)
if (wb_rst)
dq_tx_reg[15:0] <= 16'h0;
else
if (dqm_en)
dq_tx_reg[15:0] <= tx_dat_i[19:4];
else
dq_tx_reg[15:0] <= tx_dat_i[19:4];
 
wire [0:nr_of_wb_ports-1] wb_wr_ack, wb_rd_ack;
assign dq_tx[15:0] = tx_dat_i[35:20];
 
wire [3:0] egress_fifo_wadr_bin[0:nr_of_wb_ports-1];
wire [3:0] egress_fifo_wadr_gray[0:nr_of_wb_ports-1];
wire [3:0] egress_fifo_radr_bin[0:nr_of_wb_ports-1];
wire [3:0] egress_fifo_radr_gray[0:nr_of_wb_ports-1];
wire [3:0] egress_fifo_full;
wire [3:0] ingress_fifo_wadr_bin[0:nr_of_wb_ports-1];
wire [3:0] ingress_fifo_wadr_gray[0:nr_of_wb_ports-1];
wire [3:0] ingress_fifo_radr_bin[0:nr_of_wb_ports-1];
wire [3:0] ingress_fifo_radr_gray[0:nr_of_wb_ports-1];
wire [3:0] ingress_fifo_empty;
 
function [3:0] onehot2bin;
input [0:nr_of_wb_ports-1] a;
integer i;
begin
onehot2bin = 0;
for (i=1;i<nr_of_wb_ports;i=i+1) begin
if (a[i])
onehot2bin = i;
// DDR flip-flops
generate
for (i=0; i<16; i=i+1) begin:data_out_oddr
ddr_ff_out ddr_ff_out_inst_0 (
.Q(dq_o[i]),
.C0(sdram_clk_270),
.C1(sdram_clk_90),
.CE(dq_en),
.D0(dq_tx[i]),
.D1(dq_tx_reg[i]),
.R(wb_rst),
.S(1'b0));
end
end
endfunction
endgenerate
 
genvar i;
// Assign outports
assign dq_io = dq_en ? dq_o : {16{1'bz}};
 
generate
for (i=0;i<nr_of_wb_ports;i=i+1) begin : vector2array
assign wb_adr_i[i] = wb_adr_i_v[(nr_of_wb_ports-i)*36-1:(nr_of_wb_ports-1-i)*36];
assign wb_dat_i[i] = wb_dat_i_v[(nr_of_wb_ports-i)*36-1:(nr_of_wb_ports-1-i)*36];
assign egress_fifo_di[i] = (wb_state[i]==idle) ? wb_adr_i[i] : wb_dat_i[i];
// Data mask
// Data mask from Tx FIFO
always @ (posedge sdram_clk_270 or posedge wb_rst)
if (wb_rst)
dqm_tx_reg[1:0] <= 2'b00;
else
if (dqm_en)
dqm_tx_reg[1:0] <= 2'b00;
else
dqm_tx_reg[1:0] <= tx_dat_i[1:0];
 
always @ (posedge sdram_clk_180 or posedge wb_rst)
if (wb_rst)
dqm_tx_reg[3:2] <= 2'b00;
else
if (dqm_en)
dqm_tx_reg[3:2] <= 2'b00;
else
dqm_tx_reg[3:2] <= tx_dat_i[3:2];
 
assign dqm_tx[1:0] = (dqm_en) ? 2'b00 : tx_dat_i[3:2];
 
// DDR flip-flops
generate
for (i=0; i<2; i=i+1) begin:data_mask_oddr
ddr_ff_out ddr_ff_out_inst_1 (
.Q(dqm_o[i]),
.C0(sdram_clk_270),
.C1(sdram_clk_90),
.CE(dq_en),
.D0(!dqm_tx[i]),
.D1(!dqm_tx_reg[i]),
.R(wb_rst),
.S(1'b0));
end
endgenerate
endgenerate
 
// wr_ack
generate
assign wb_wr_ack[0] = ((wb_state[0]==idle | wb_state[0]==wr) & wb_cyc_i[0] & wb_stb_i[0] & !egress_fifo_full[0]);
for (i=1;i<nr_of_wb_ports;i=i+1) begin : wr_ack
assign wb_wr_ack[i] = (|(wb_wr_ack[0:i-1])) ? 1'b0 : ((wb_state[i]==idle | wb_state[i]==wr) & wb_cyc_i[i] & wb_stb_i[i] & !egress_fifo_full[i]);
// Assign outport
assign dm_rdqs_io = dq_en ? dqm_o : 2'bzz;
// Data in
`ifdef INT_CLOCKED_DATA_CAPTURE
// DDR flip-flops
generate
for (i=0; i<16; i=i+1) begin:iddr2gen
ddr_ff_in ddr_ff_in_inst_0 (
.Q0(dq_rx[i]),
.Q1(dq_rx[i+16]),
.C0(sdram_clk_270),
.C1(sdram_clk_90),
.CE(1'b1),
.D(dq_io[i]),
.R(wb_rst),
.S(1'b0));
end
endgenerate
endgenerate
 
// rd_ack
generate
assign wb_rd_ack[0] = ((wb_state[0]==rd) & wb_cyc_i[0] & wb_stb_i[0] & !ingress_fifo_empty[0]);
for (i=1;i<nr_of_wb_ports;i=i+1) begin : rd_ack
assign wb_rd_ack[i] = (|(wb_rd_ack[0:i-1])) ? 1'b0 : ((wb_state[i]==rd) & wb_cyc_i[i] & wb_stb_i[i] & !ingress_fifo_empty[i]);
// Data to Rx FIFO
always @ (posedge sdram_clk_0 or posedge wb_rst)
if (wb_rst)
dq_rx_reg[31:16] <= 16'h0;
else
dq_rx_reg[31:16] <= dq_rx[31:16];
 
always @ (posedge sdram_clk_180 or posedge wb_rst)
if (wb_rst)
dq_rx_reg[15:0] <= 16'h0;
else
dq_rx_reg[15:0] <= dq_rx[15:0];
 
assign rx_dat_o = {dq_rx_reg, 4'h0};
`endif // INT_CLOCKED_DATA_CAPTURE
 
`ifdef DEL_DQS_DATA_CAPTURE_1
// Delay DQS
// DDR FF
`endif // DEL_DQS_DATA_CAPTURE_1
 
`ifdef DEL_DQS_DATA_CAPTURE_2
// DDR data to IOBUF
// Delay data (?)
// IDDR FF
// Rise & fall clocked FF
// Fall sync FF
// Mux
// DDR DQS to IODUFDS
// Delay DQS
// BUFIO (?)
`endif // DEL_DQS_DATA_CAPTURE_2
 
`endif // XILINX
 
`ifdef ALTERA
 
wire [3:0] dqm_tx;
 
// Data out
// DDR flip-flops
generate
for (i=0; i<16; i=i+1) begin:data_out_oddr
ddr_ff_out ddr_ff_out_inst_0 (
.Q(dq_o[i]),
.C0(sdram_clk_270),
.C1(sdram_clk_90),
.CE(dq_en),
.D0(tx_dat_i[i+16+4]),
.D1(tx_dat_i[i+4]),
.R(wb_rst),
.S(1'b0));
end
endgenerate
endgenerate
 
// trafic state machines
generate
for (i=0;i<nr_of_wb_ports;i=i+1) begin : fsm
always @ (posedge wb_clk or posedge wb_rst)
if (wb_rst)
wb_state[i] <= idle;
else
case (wb_state[i])
idle:
if (wb_wr_ack[i] & wb_adr_i[i][`WE_I])
wb_state[i] <= wr;
else if (wb_wr_ack[i])
wb_state[i] <= rd;
rd:
if ((wb_adr_i[i][`CTI_I]==classic | wb_adr_i[i][`CTI_I]==endofburst) & wb_ack_o[i])
wb_state[i] <= idle;
wr:
if ((wb_adr_i[i][`CTI_I]==classic | wb_adr_i[i][`CTI_I]==endofburst) & wb_ack_o[i])
wb_state[i] <= idle;
default: ;
endcase
// Assign outport
assign dq_io = dq_en ? dq_o : {16{1'bz}};
 
// Data mask
// Data mask from Tx FIFO
assign dqm_tx = dqm_en ? {4{1'b0}} : tx_dat_i[3:0];
 
// DDR flip-flops
generate
for (i=0; i<2; i=i+1) begin:data_mask_oddr
ddr_ff_out ddr_ff_out_inst_1 (
.Q(dqm_o[i]),
.C0(sdram_clk_270),
.C1(sdram_clk_90),
.CE(dq_en),
.D0(!dqm_tx[i+2]),
.D1(!dqm_tx[i]),
.R(wb_rst),
.S(1'b0));
end
endgenerate
endgenerate
 
generate
for (i=0;i<nr_of_wb_ports;i=i+1) begin : ack
always @ (posedge wb_clk or posedge wb_rst)
if (wb_rst)
wb_ack_o[i] <= 1'b0;
else
case (wb_state[i])
idle:
wb_ack_o[i] <= 1'b0;
wr:
wb_ack_o[i] <= wb_wr_ack[i];
rd:
wb_ack_o[i] <= wb_rd_ack[i];
default: ;
endcase
// Assign outport
assign dm_rdqs_io = dq_en ? dqm_o : 2'bzz;
 
 
// Data in
`ifdef INT_CLOCKED_DATA_CAPTURE
// DDR flip-flops
generate
for (i=0; i<16; i=i+1) begin:iddr2gen
ddr_ff_in ddr_ff_in_inst_0 (
.Q0(dq_rx[i]),
.Q1(dq_rx[i+16]),
.C0(sdram_clk_270),
.C1(sdram_clk_90),
.CE(1'b1),
.D(dq_io[i]),
.R(wb_rst),
.S(1'b0));
end
endgenerate
endgenerate
 
generate
for (i=0;i<nr_of_wb_ports;i=i+1) begin : fifo_adr
// egress queue
fifo_adr_counter egress_wadrcnt (
.cke(wb_wr_ack[i]),
.q(egress_fifo_wadr_gray[i]),
.q_bin(egress_fifo_wadr_bin[i]),
.rst(wb_rst),
.clk(wb_clk));
fifo_adr_counter egress_radrcnt (
.cke(sdram_fifo_rd[i]),
.q(egress_fifo_radr_gray[i]),
.q_bin(egress_fifo_radr_bin[i]),
.rst(sdram_rst),
.clk(sdram_clk));
versatile_fifo_async_cmp
#(.ADDR_WIDTH(4))
egresscmp (
.wptr(egress_fifo_wadr_gray[i]),
.rptr(egress_fifo_radr_gray[i]),
.fifo_empty(sdram_fifo_empty[i]),
.fifo_full(egress_fifo_full[i]),
.wclk(wb_clk),
.rclk(sdram_clk),
.rst(wb_rst));
// ingress queue
fifo_adr_counter ingress_wadrcnt (
.cke(sdram_fifo_wr[i]),
.q(ingress_fifo_wadr_gray[i]),
.q_bin(ingress_fifo_wadr_bin[i]),
.rst(wb_rst),
.clk(wb_clk));
fifo_adr_counter ingress_radrcnt (
.cke(wb_rd_ack[i]),
.q(ingress_fifo_radr_gray[i]),
.q_bin(ingress_fifo_radr_bin[i]),
.rst(wb_rst),
.clk(wb_clk));
versatile_fifo_async_cmp
#(.ADDR_WIDTH(4))
ingresscmp (
.wptr(ingress_fifo_wadr_gray[i]),
.rptr(ingress_fifo_radr_gray[i]),
.fifo_empty(ingress_fifo_empty[i]),
.fifo_full(),
.wclk(wb_clk),
.rclk(sdram_clk),
.rst(wb_rst));
end
endgenerate
vfifo_dual_port_ram_dc_sw # ( .DATA_WIDTH(36), .ADDR_WIDTH(8))
egress_dpram (
.d_a(egress_fifo_di[onehot2bin(wb_wr_ack)]),
.adr_a({onehot2bin(wb_wr_ack),egress_fifo_wadr_bin[onehot2bin(wb_wr_ack)]}),
.we_a(|(wb_wr_ack)),
.clk_a(wb_clk),
.q_b(sdram_dat_o),
.adr_b({onehot2bin(sdram_fifo_rd),egress_fifo_radr_bin[onehot2bin(sdram_fifo_rd)]}),
.clk_b(sdram_clk) );
// Data to Rx FIFO
always @ (posedge sdram_clk_180 or posedge wb_rst)
if (wb_rst)
dq_rx_reg <= 32'h0;
else
dq_rx_reg <= dq_rx;
 
vfifo_dual_port_ram_dc_sw # ( .DATA_WIDTH(32), .ADDR_WIDTH(8))
ingress_dpram (
.d_a(sdram_dat_i),
.adr_a({onehot2bin(sdram_fifo_wr),ingress_fifo_wadr_bin[onehot2bin(sdram_fifo_wr)]}),
.we_a(|(sdram_fifo_wr)),
.clk_a(sdram_clk),
.q_b(wb_dat_o),
.adr_b({onehot2bin(wb_rd_ack),ingress_fifo_radr_bin[onehot2bin(wb_rd_ack)]}),
.clk_b(wb_clk) );
assign rx_dat_o = {dq_rx_reg, 4'h0};
`endif // INT_CLOCKED_DATA_CAPTURE
 
endmodule`include "versatile_mem_ctrl_defines.v"
`ifdef DEL_DQS_DATA_CAPTURE_1
// Delay DQS
// DDR FF
`endif // DEL_DQS_DATA_CAPTURE_1
 
`ifdef DEL_DQS_DATA_CAPTURE_2
// DDR data to IOBUFFER
// Delay data (?)
// DDR FF
// Rise & fall clocked FF
// Fall sync FF
// Mux
// DDR DQS to IODUFDS
// Delay DQS
// BUFIO (?)
`endif // DEL_DQS_DATA_CAPTURE_2
 
`endif // ALTERA
 
 
endmodule // versatile_mem_ctrl_ddr
 
 
`include "versatile_mem_ctrl_defines.v"
`ifdef SDR_16
`include "sdr_16_defines.v"
`endif
3819,216 → 3862,36
.clkfb_out(ck_fb)
);
 
// Generate clock with equal delay as data
ddr_ff_out ddr_ff_out_inst_2 (
.Q(ck_pad_o),
.C0(sdram_clk_0),
.C1(sdram_clk_180),
.CE(1'b1),
.D0(1'b1),
.D1(1'b0),
.R(1'b0), // no reset for CK
.S(1'b0)
);
// DDR2 IF
versatile_mem_ctrl_ddr versatile_mem_ctrl_ddr_0 (
// DDR2 SDRAM ports
.ck_o(ck_pad_o),
.ck_n_o(ck_n_pad_o),
.dq_io(dq_pad_io),
.dqs_io(dqs_pad_io),
.dqs_n_io(dqs_n_pad_io),
.dm_rdqs_io(dm_rdqs_pad_io),
// Memory controller side
.tx_dat_i(tx_fifo_dat_o),
.rx_dat_o(rx_fifo_dat_i),
.dq_en(dq_en),
.dqm_en(dqm_en),
.wb_rst(wb_rst),
.sdram_clk_0(sdram_clk_0),
.sdram_clk_90(sdram_clk_90),
.sdram_clk_180(sdram_clk_180),
.sdram_clk_270(sdram_clk_270));
 
// Generate clock with equal delay as data
ddr_ff_out ddr_ff_out_inst_3
(
.Q(ck_n_pad_o),
.C0(sdram_clk_0),
.C1(sdram_clk_180),
.CE(1'b1),
.D0(1'b0),
.D1(1'b1),
.R(wb_rst),
.S(1'b0)
);
 
// Generate strobe with equal delay as data
generate
for (i=0; i<2; i=i+1) begin:dqs_oddr
ddr_ff_out ddr_ff_out_inst_4 (
.Q(dqs_o[i]),
.C0(sdram_clk_0),
.C1(sdram_clk_180),
.CE(1'b1),
.D0(1'b1),
.D1(1'b0),
.R(1'b0), // no reset for CK
.S(1'b0)
);
end
endgenerate
 
generate
for (i=0; i<2; i=i+1) begin:dqs_n_oddr
// Generate strobe with equal delay as data
ddr_ff_out ddr_ff_out_inst_5
(
.Q(dqs_n_o[i]),
.C0(sdram_clk_0),
.C1(sdram_clk_180),
.CE(1'b1),
.D0(1'b0),
.D1(1'b1),
.R(wb_rst),
.S(1'b0)
);
end
endgenerate
 
`ifdef XILINX
// Data and data mask from Tx FIFO
always @ (posedge sdram_clk_270 or posedge wb_rst)
if (wb_rst) begin
dq_tx_reg[15:0] <= 16'h0;
dqm_tx_reg[1:0] <= 2'b00;
end
else begin
if (dqm_en) begin
dq_tx_reg[15:0] <= tx_fifo_dat_o[19:4];
dqm_tx_reg[1:0] <= 2'b00;
end
else begin
dq_tx_reg[15:0] <= tx_fifo_dat_o[19:4];
dqm_tx_reg[1:0] <= tx_fifo_dat_o[1:0];
end
end
 
always @ (posedge sdram_clk_180 or posedge wb_rst)
if (wb_rst) begin
dqm_tx_reg[3:2] <= 2'b00;
end
else begin
if (dqm_en) begin
dqm_tx_reg[3:2] <= 2'b00;
end
else begin
dqm_tx_reg[3:2] <= tx_fifo_dat_o[3:2];
end
end
 
assign dq_tx[15:0] = tx_fifo_dat_o[35:20];
assign dqm_tx[1:0] = (dqm_en) ? 2'b00 : tx_fifo_dat_o[3:2];
 
// Data out
generate
for (i=0; i<16; i=i+1) begin:data_out_oddr
ddr_ff_out ddr_ff_out_inst_0 (
.Q(dq_o[i]),
.C0(sdram_clk_270),
.C1(sdram_clk_90),
.CE(dq_en),
.D0(dq_tx[i]),
.D1(dq_tx_reg[i]),
.R(wb_rst),
.S(1'b0)
);
end
endgenerate
 
assign dq_pad_io = dq_en ? dq_o : {16{1'bz}};
 
// Data mask
generate
for (i=0; i<2; i=i+1) begin:data_mask_oddr
ddr_ff_out ddr_ff_out_inst_1 (
.Q(dqm_o[i]),
.C0(sdram_clk_270),
.C1(sdram_clk_90),
.CE(dq_en),
.D0(!dqm_tx[i]),
.D1(!dqm_tx_reg[i]),
.R(wb_rst),
.S(1'b0)
);
end
endgenerate
 
assign dm_rdqs_pad_io = dq_en ? dqm_o : 2'bzz;
`endif // XILINX
 
`ifdef ALTERA
// Data out
generate
for (i=0; i<16; i=i+1) begin:data_out_oddr
ddr_ff_out ddr_ff_out_inst_0 (
.Q(dq_o[i]),
.C0(sdram_clk_270),
.C1(sdram_clk_90),
.CE(dq_en),
.D0(tx_fifo_dat_o[i+16+4]),
.D1(tx_fifo_dat_o[i+4]),
.R(wb_rst),
.S(1'b0)
);
end
endgenerate
 
assign dq_pad_io = dq_en ? dq_o : {16{1'bz}};
 
assign dqm_tx = dqm_en ? {4{1'b0}} : tx_fifo_dat_o[3:0];
 
// Data mask
generate
for (i=0; i<2; i=i+1) begin:data_mask_oddr
ddr_ff_out ddr_ff_out_inst_1 (
.Q(dqm_o[i]),
.C0(sdram_clk_270),
.C1(sdram_clk_90),
.CE(dq_en),
.D0(!dqm_tx[i+2]),
.D1(!dqm_tx[i]),
.R(wb_rst),
.S(1'b0)
);
end
endgenerate
 
assign dm_rdqs_pad_io = dq_en ? dqm_o : 2'bzz;
`endif // ALTERA
 
// DDR data in
generate
for (i=0; i<16; i=i+1) begin:iddr2gen
ddr_ff_in ddr_ff_in_inst_0
(
.Q0(dq_rx[i]),
.Q1(dq_rx[i+16]),
.C0(sdram_clk_270),
.C1(sdram_clk_90),
.CE(1'b1),
.D(dq_pad_io[i]),
.R(wb_rst),
.S(1'b0)
);
end
endgenerate
 
// Data to Rx FIFO
`ifdef XILINX
always @ (posedge sdram_clk_0 or posedge wb_rst)
`endif
`ifdef ALTERA
always @ (posedge sdram_clk_180 or posedge wb_rst)
`endif
if (wb_rst)
dq_rx_reg[31:16] <= 16'h0;
else
dq_rx_reg[31:16] <= dq_rx[31:16];
 
always @ (posedge sdram_clk_180 or posedge wb_rst)
if (wb_rst)
dq_rx_reg[15:0] <= 16'h0;
else
dq_rx_reg[15:0] <= dq_rx[15:0];
 
assign rx_fifo_dat_i = {dq_rx_reg, 4'h0};
 
// Assing outputs
assign dqs_pad_io = dq_en ? dqs_o : 2'bz;
assign dqs_n_pad_io = dq_en ? dqs_n_o : 2'bz;
// Non-DDR outputs
assign ba_pad_o = ba;
assign addr_pad_o = addr;
assign dqs_oe = dq_en;
assign cke_pad_o = cke;
assign ras_pad_o = ras;
assign cas_pad_o = cas;
assign we_pad_o = we;
assign cs_n_pad_o = cs_n;
assign ck_fb_pad_o = ck_fb;
 
`endif // `ifdef DDR_16

powered by: WebSVN 2.1.0

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