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 |