Commit c8904b67 authored by Andrey Filippov's avatar Andrey Filippov

added modules, simulating

parent 5034058e
// This file may be used to define same pre-processor macros to be included into each parsed file
// It can be used to check different `ifdef branches
`define XIL_TIMING //Simprim
//`define XIL_TIMING //Simprim
`define IVERILOG
\ No newline at end of file
......@@ -2,3 +2,4 @@ unisims
glbl.v
vivado_*
syntax_*
simulation/*
......@@ -51,7 +51,7 @@
<link>
<name>vivado_logs/VivadoOpt.log</name>
<type>1</type>
<location>/data/vdt/vdt-projects/eddr3/vivado_logs/VivadoOpt-20140515155524262.log</location>
<location>/data/vdt/vdt-projects/eddr3/vivado_logs/VivadoOpt-20140520232524498.log</location>
</link>
<link>
<name>vivado_logs/VivadoOptPhys.log</name>
......@@ -61,12 +61,12 @@
<link>
<name>vivado_logs/VivadoOptPower.log</name>
<type>1</type>
<location>/data/vdt/vdt-projects/eddr3/vivado_logs/VivadoOptPower-20140515155524262.log</location>
<location>/data/vdt/vdt-projects/eddr3/vivado_logs/VivadoOptPower-20140520232524498.log</location>
</link>
<link>
<name>vivado_logs/VivadoPlace.log</name>
<type>1</type>
<location>/data/vdt/vdt-projects/eddr3/vivado_logs/VivadoPlace-20140515155524262.log</location>
<location>/data/vdt/vdt-projects/eddr3/vivado_logs/VivadoPlace-20140520232524498.log</location>
</link>
<link>
<name>vivado_logs/VivadoRoute.log</name>
......@@ -76,7 +76,7 @@
<link>
<name>vivado_logs/VivadoSynthesis.log</name>
<type>1</type>
<location>/data/vdt/vdt-projects/eddr3/vivado_logs/VivadoSynthesis-20140515155524262.log</location>
<location>/data/vdt/vdt-projects/eddr3/vivado_logs/VivadoSynthesis-20140520232242973.log</location>
</link>
<link>
<name>vivado_logs/VivadoTimimgSummaryReportImplemented.log</name>
......@@ -86,7 +86,7 @@
<link>
<name>vivado_logs/VivadoTimimgSummaryReportSynthesis.log</name>
<type>1</type>
<location>/data/vdt/vdt-projects/eddr3/vivado_logs/VivadoTimimgSummaryReportSynthesis-20140515155524262.log</location>
<location>/data/vdt/vdt-projects/eddr3/vivado_logs/VivadoTimimgSummaryReportSynthesis-20140520232524498.log</location>
</link>
<link>
<name>vivado_logs/VivadoTimingReportImplemented.log</name>
......@@ -96,7 +96,7 @@
<link>
<name>vivado_logs/VivadoTimingReportSynthesis.log</name>
<type>1</type>
<location>/data/vdt/vdt-projects/eddr3/vivado_logs/VivadoTimingReportSynthesis-20140515155524262.log</location>
<location>/data/vdt/vdt-projects/eddr3/vivado_logs/VivadoTimingReportSynthesis-20140520232524498.log</location>
</link>
<link>
<name>vivado_state/eddr3-opt-phys.dcp</name>
......@@ -106,7 +106,7 @@
<link>
<name>vivado_state/eddr3-place.dcp</name>
<type>1</type>
<location>/data/vdt/vdt-projects/eddr3/vivado_state/eddr3-place-20140515155524262.dcp</location>
<location>/data/vdt/vdt-projects/eddr3/vivado_state/eddr3-place-20140520232524498.dcp</location>
</link>
<link>
<name>vivado_state/eddr3-route.dcp</name>
......@@ -116,7 +116,7 @@
<link>
<name>vivado_state/eddr3-synth.dcp</name>
<type>1</type>
<location>/data/vdt/vdt-projects/eddr3/vivado_state/eddr3-synth-20140515155524262.dcp</location>
<location>/data/vdt/vdt-projects/eddr3/vivado_state/eddr3-synth-20140520204515091.dcp</location>
</link>
</linkedResources>
</projectDescription>
FPGA_project_2_ImplementationTopFile=phy/test_phy_top_01.v
FPGA_project_0_SimulationTopFile=ddrc_test01_testbench.tf
FPGA_project_1_SimulationTopModule=ddrc_test01_testbench
FPGA_project_2_ImplementationTopFile=ddrc_test01.v
FPGA_project_4_part=xc7z030fbg484-2
com.elphel.store.context.FPGA_project=FPGA_project_2_ImplementationTopFile<-@\#\#@->FPGA_project_4_part<-@\#\#@->
com.elphel.store.context.FPGA_project=FPGA_project_2_ImplementationTopFile<-@\#\#@->FPGA_project_4_part<-@\#\#@->FPGA_project_0_SimulationTopFile<-@\#\#@->FPGA_project_1_SimulationTopModule<-@\#\#@->
eclipse.preferences.version=1
VivadoSynthesis_102_ConstraintsFiles=phy/test_phy_top_01.xdc<-@\#\#@->
com.elphel.store.context.VivadoSynthesis=VivadoSynthesis_102_ConstraintsFiles<-@\#\#@->
VivadoSynthesis_102_ConstraintsFiles=ddrc_test01.xdc<-@\#\#@->
VivadoSynthesis_95_ShowInfo=false
com.elphel.store.context.VivadoSynthesis=VivadoSynthesis_102_ConstraintsFiles<-@\#\#@->VivadoSynthesis_95_ShowInfo<-@\#\#@->
eclipse.preferences.version=1
......@@ -308,7 +308,7 @@ ram_1kx32_1kx32
.data_in(wdata_out[31:0]) // data out
);
fifo_reg_W_D #( .DATA_WIDTH(30),.DATA_DEPTH(4))
fifo_same_clock #( .DATA_WIDTH(30),.DATA_DEPTH(4))
raddr_i (
.rst(rst),
.clk(aclk),
......@@ -320,7 +320,7 @@ fifo_reg_W_D #( .DATA_WIDTH(30),.DATA_DEPTH(4))
.full(),
.half_full(ar_half_full)
);
fifo_reg_W_D #( .DATA_WIDTH(30),.DATA_DEPTH(4))
fifo_same_clock #( .DATA_WIDTH(30),.DATA_DEPTH(4))
waddr_i (
.rst(rst),
.clk(aclk),
......@@ -332,7 +332,7 @@ fifo_reg_W_D #( .DATA_WIDTH(30),.DATA_DEPTH(4))
.full(),
.half_full(aw_half_full)
);
fifo_reg_W_D #( .DATA_WIDTH(49),.DATA_DEPTH(4))
fifo_same_clock #( .DATA_WIDTH(49),.DATA_DEPTH(4))
wdata_i (
.rst(rst),
.clk(aclk),
......@@ -344,7 +344,7 @@ fifo_reg_W_D #( .DATA_WIDTH(49),.DATA_DEPTH(4))
.full(),
.half_full(w_half_full)
);
fifo_reg_W_D #( .DATA_WIDTH(14),.DATA_DEPTH(4))
fifo_same_clock #( .DATA_WIDTH(14),.DATA_DEPTH(4))
wresp_i (
.rst(rst),
.clk(aclk),
......
......@@ -223,7 +223,7 @@ module axibram_read #(
*/
// assign start_read_burst_w= ar_nempty && (rready?start_read_burst_1:start_read_burst_0);
fifo_reg_W_D #( .DATA_WIDTH(ADDRESS_BITS+20),.DATA_DEPTH(4))
fifo_same_clock #( .DATA_WIDTH(ADDRESS_BITS+20),.DATA_DEPTH(4))
raddr_i (
.rst(rst),
.clk(aclk),
......
......@@ -92,16 +92,25 @@ module axibram_write #(
wire bram_we_w; //,bram_we_nonmasked; // write BRAM memory non-masked - should be combined with
wire start_write_burst_w;
wire write_in_progress_w;
wire aw_nempty_ready; // aw_nempty and device ready
wire w_nempty_ready; // w_nempty and device ready
assign aw_nempty_ready=aw_nempty && dev_ready_r; // should it be dev_ready?
assign w_nempty_ready=w_nempty && dev_ready_r; // should it be dev_ready?
reg dev_ready_r; // device, selected at start burst
assign next_wr_address_w=
wburst[1]?
(wburst[0]? {ADDRESS_BITS{1'b0}}:((write_address[ADDRESS_BITS-1:0]+1) & {{(ADDRESS_BITS-4){1'b1}}, ~wlen[3:0]})):
(wburst[0]? (write_address[ADDRESS_BITS-1:0]+1):(write_address[ADDRESS_BITS-1:0]));
assign bram_we_w= w_nempty && write_in_progress && dev_ready_r;
assign bram_we_w= w_nempty_ready && write_in_progress;
// assign bram_we_nonmasked= w_nempty && write_in_progress;
assign start_write_burst_w=aw_nempty && (!write_in_progress || (w_nempty && (write_left[3:0]==4'b0)));
assign write_in_progress_w=aw_nempty || (write_in_progress && !(w_nempty && (write_left[3:0]==4'b0)));
// assign start_write_burst_w=aw_nempty && (!write_in_progress || (w_nempty && (write_left[3:0]==4'b0)));
// assign start_write_burst_w=aw_nempty_ready && (!write_in_progress || (w_nempty_ready && (write_left[3:0]==4'b0)));
assign start_write_burst_w=w_nempty_ready && aw_nempty_ready && (!write_in_progress || (w_nempty_ready && (write_left[3:0]==4'b0)));
// assign write_in_progress_w=aw_nempty || (write_in_progress && !(w_nempty && (write_left[3:0]==4'b0)));
assign write_in_progress_w=aw_nempty_ready || (write_in_progress && !(w_nempty_ready && (write_left[3:0]==4'b0)));
always @ (posedge aclk or posedge rst) begin
if (rst) wburst[1:0] <= 0;
......@@ -152,7 +161,7 @@ module axibram_write #(
assign bram_wstb = wstb_out[3:0];
assign bram_wdata = wdata_out[31:0];
fifo_reg_W_D #( .DATA_WIDTH(20+ADDRESS_BITS),.DATA_DEPTH(4))
fifo_same_clock #( .DATA_WIDTH(20+ADDRESS_BITS),.DATA_DEPTH(4))
waddr_i (
.rst(rst),
.clk(aclk),
......@@ -164,7 +173,7 @@ fifo_reg_W_D #( .DATA_WIDTH(20+ADDRESS_BITS),.DATA_DEPTH(4))
.full(),
.half_full(aw_half_full)
);
fifo_reg_W_D #( .DATA_WIDTH(49),.DATA_DEPTH(4))
fifo_same_clock #( .DATA_WIDTH(49),.DATA_DEPTH(4))
wdata_i (
.rst(rst),
.clk(aclk),
......@@ -176,7 +185,7 @@ fifo_reg_W_D #( .DATA_WIDTH(49),.DATA_DEPTH(4))
.full(),
.half_full(w_half_full)
);
fifo_reg_W_D #( .DATA_WIDTH(14),.DATA_DEPTH(4))
fifo_same_clock #( .DATA_WIDTH(14),.DATA_DEPTH(4))
wresp_i (
.rst(rst),
.clk(aclk),
......
......@@ -2,7 +2,7 @@
** -----------------------------------------------------------------------------**
** macros353.v
**
** I/O pads related circuitry
** temporary, modules to be moved
**
** Copyright (C) 2002 Elphel, Inc
**
......@@ -25,42 +25,8 @@
** -----------------------------------------------------------------------------**
**
*/
// just make more convenient A[3:0] instead of 4 one-bit inputs
// TODO: Replace direct instances of SRL16 to imporve portability
/*
module MSRL16 (Q, A, CLK, D);
output Q;
input [3:0] A;
input CLK, D;
SRL16 i_q(.Q(Q), .A0(A[0]), .A1(A[1]), .A2(A[2]), .A3(A[3]), .CLK(CLK), .D(D));
endmodule
module MSRL16_1 (Q, A, CLK, D);
output Q;
input [3:0] A;
input CLK, D;
SRL16_1 i_q(.Q(Q), .A0(A[0]), .A1(A[1]), .A2(A[2]), .A3(A[3]), .CLK(CLK), .D(D));
endmodule
*/
/*
module myRAM_WxD_D(D,WE,clk,AW,AR,QW,QR);
parameter DATA_WIDTH=16;
parameter DATA_DEPTH=4;
parameter DATA_2DEPTH=(1<<DATA_DEPTH)-1;
input [DATA_WIDTH-1:0] D;
input WE,clk;
input [DATA_DEPTH-1:0] AW;
input [DATA_DEPTH-1:0] AR;
output [DATA_WIDTH-1:0] QW;
output [DATA_WIDTH-1:0] QR;
reg [DATA_WIDTH-1:0] ram [0:DATA_2DEPTH];
always @ (posedge clk) if (WE) ram[AW] <= D;
assign QW= ram[AW];
assign QR= ram[AR];
endmodule
*/
module ram_WxD
#(
parameter integer DATA_WIDTH=16,
......@@ -82,75 +48,4 @@ module ram_WxD
assign QR= ram[AR];
endmodule
/*
FIFO with minimal latency 1, uses 1 register slice on the data input, output - 1 mux after register
*/
module fifo_reg_W_D
#(
parameter integer DATA_WIDTH=16,
parameter integer DATA_DEPTH=4,
parameter integer DATA_2DEPTH=(1<<DATA_DEPTH)-1
)
(
input rst, // reset, active high
input clk, // clock - positive edge
input we, // write enable
input re, // read enable
input [DATA_WIDTH-1:0] data_in, // input data
output [DATA_WIDTH-1:0] data_out, // output data
output reg nempty, // FIFO has some data
output reg full, // FIFO full
output reg half_full // FIFO half full
);
reg [DATA_DEPTH :0] fill=0;
reg just_one=0;
reg [DATA_WIDTH-1:0] inreg;
reg [DATA_WIDTH-1:0] outreg;
reg [DATA_DEPTH-1:0] ra;
reg [DATA_DEPTH-1:0] wa;
wire [DATA_DEPTH :0] next_fill;
reg wem;
wire rem;
reg [DATA_WIDTH-1:0] ram [0:DATA_2DEPTH];
// wire [DATA_DEPTH :0] pre_next_fill= ((we && ~re)?1:((~we && re)?-1:0));
assign next_fill = fill[4:0]+((we && ~re)?1:((~we && re)?5'b11111:5'b00000));
// assign next_fill = fill+((we && ~re)?1:((~we && re)?-1:0));
// assign next_fill[DATA_DEPTH :0] = fill[DATA_DEPTH :0]+pre_next_fill[DATA_DEPTH :0];
// assign next_fill[DATA_DEPTH :0] = fill[DATA_DEPTH :0]+1;
// assign next_fill[DATA_DEPTH :0] = fill[DATA_DEPTH :0]+((we && ~re)?5'b1:0);
// assign next_fill[4 :0] = fill[4 :0]+((we && ~re)?5'b1:0);
assign data_out = just_one?inreg:outreg;
assign rem = just_one? wem : re;
always @ (posedge clk or posedge rst) begin
if (rst) fill <= 0;
// else fill <= next_fill;
// else fill <= fill+1;
// else fill <= fill[4 :0]+((we && ~re)?1:((~we && re)?-1:0));
// else fill <= fill[4 :0]+((we && ~re)?5'b00001:((~we && re)?5'b11111:5'b00000));
else if (we && ~re) fill <= fill+1;
else if (~we && re) fill <= fill-1;
if (rst) wa <= 0;
else if (wem) wa <= wa+1;
if (rst) ra <= 1; // 0;
// else if (re) ra <= ra+1; //wrong?
// else if (rem) ra <= ra+1; //may be still wrong
else if (re) ra <= ra+1; //now ra is 1 ahead
else if (!nempty) ra <= wa+1; // Just recover from bit errors TODO: fix
if (rst) nempty <= 0;
else nempty <= (next_fill != 0);
end
always @ (posedge clk) begin
if (wem) ram[wa] <= inreg;
just_one <= (next_fill == 1);
// nempty <= (next_fill != 0);
half_full <=(fill & (1<<(DATA_DEPTH-1)))!=0;
full <= (fill & (1<< DATA_DEPTH ))!=0;
if (we) inreg <= data_in;
if (rem) outreg <= just_one?inreg:ram[ra];
wem <= we;
end
endmodule
// tri0 GSR = glbl.GSR;
......@@ -21,11 +21,48 @@
`timescale 1ns/1ps
module ddrc_control #(
parameter AXI_WR_ADDR_BITS= 12,
parameter SELECT_ADDR = 'h800, // address to select this module
parameter SELECT_ADDR_MASK = 'h800, // address mask to select this module
parameter BUSY_ADDR = 'hc00, // address to generate busy
parameter BUSY_ADDR_MASK = 'hc00 // address mask to generate busy
parameter AXI_WR_ADDR_BITS= 12,
// parameter SELECT_ADDR = 'h800, // address to select this module
// parameter SELECT_ADDR_MASK = 'h800, // address mask to select this module
// parameter BUSY_ADDR = 'hc00, // address to generate busy
// parameter BUSY_ADDR_MASK = 'hc00, // address mask to generate busy
parameter CONTROL_ADDR = 'h1000, // AXI write address of control write registers
parameter CONTROL_ADDR_MASK = 'h1400, // AXI write address of control registers
// parameter STATUS_ADDR = 'h1400, // AXI write address of status read registers
// parameter STATUS_ADDR_MASK = 'h1400, // AXI write address of status registers
parameter BUSY_WR_ADDR = 'h1800, // AXI write address to generate busy
parameter BUSY_WR_ADDR_MASK = 'h1c00, // AXI write address mask to generate busy
// parameter DLY_LD_ADDR = 'h880, // address to generate delay load
// parameter DLY_LD_ADDR_MASK = 'hb80, // address mask to generate delay load
// parameter DLY_SET_ADDR = 'h870, // address to generate delay set
// parameter DLY_SET_ADDR_MASK = 'hbff, // address mask to generate delay set
// parameter RUN_CHN_ADDR = 'h800, // address to set sequnecer channel and run (4 LSB-s - channel)
// parameter RUN_CHN_ADDR_MASK = 'hbf0, // address mask to generate sequencer channel/run
// parameter PATTERNS_ADDR = 'h820, // address to set DQM and DQS patterns (16'h0055)
// parameter PATTERNS_ADDR_MASK = 'hbff, // address mask to set DQM and DQS patterns
// parameter PAGES_ADDR = 'h821, // address to set buffer pages {port1_page[1:0],port1_int_page[1:0],port0_page[1:0],port0_int_page[1:0]}
// parameter PAGES_ADDR_MASK = 'hbff, // address mask to set DQM and DQS patterns
// parameter CMDA_EN_ADDR = 'h822, // address to enable('h823)/disable('h822) command/address outputs
// parameter CMDA_EN_ADDR_MASK = 'hbfe, // address mask for command/address outputs
// parameter EXTRA_ADDR = 'h824, // address to set extra parameters (currently just inv_clk_div)
// parameter EXTRA_ADDR_MASK = 'hbff // address mask for extra parameters
parameter DLY_LD_REL = 'h080, // address to generate delay load
parameter DLY_LD_REL_MASK = 'h380, // address mask to generate delay load
parameter DLY_SET_REL = 'h070, // address to generate delay set
parameter DLY_SET_REL_MASK = 'h3ff, // address mask to generate delay set
parameter RUN_CHN_REL = 'h000, // address to set sequnecer channel and run (4 LSB-s - channel)
parameter RUN_CHN_REL_MASK = 'h3f0, // address mask to generate sequencer channel/run
parameter PATTERNS_REL = 'h020, // address to set DQM and DQS patterns (16'h0055)
parameter PATTERNS_REL_MASK = 'h3ff, // address mask to set DQM and DQS patterns
parameter PAGES_REL = 'h021, // address to set buffer pages {port1_page[1:0],port1_int_page[1:0],port0_page[1:0],port0_int_page[1:0]}
parameter PAGES_REL_MASK = 'h3ff, // address mask to set DQM and DQS patterns
parameter CMDA_EN_REL = 'h022, // address to enable('h823)/disable('h822) command/address outputs
parameter CMDA_EN_REL_MASK = 'h3fe, // address mask for command/address outputs
parameter EXTRA_REL = 'h024, // address to set extra parameters (currently just inv_clk_div)
parameter EXTRA_REL_MASK = 'h3ff // address mask for extra parameters
)(
input clk,
input mclk,
......@@ -46,7 +83,7 @@ module ddrc_control #(
output [ 7:0] dly_data, // 8-bit IDELAY/ODELAY (fine) and MMCM phase shift
output [ 6:0] dly_addr, // address to select delay register
output ld_delay, // write dly_data to dly_address, one mclk active pulse
output set, // transfer (activate) all delays simultaneosly, 1 mclk pulse
output dly_set, // transfer (activate) all delays simultaneosly, 1 mclk pulse
// control: additional signals
output cmda_tri, // tri-state all command and address lines to DDR chip
output inv_clk_div, // invert clk_div to ISERDES
......@@ -59,11 +96,122 @@ module ddrc_control #(
output [ 1:0] port1_int_page // port 1 PHY-side buffer read page (to be controlled by arbiter later, set to 2'b0)
);
localparam DLY_LD_ADDR = CONTROL_ADDR | DLY_LD_REL; // address to generate delay load
localparam DLY_LD_ADDR_MASK = CONTROL_ADDR_MASK | DLY_LD_REL_MASK; // address mask to generate delay load
localparam DLY_SET_ADDR = CONTROL_ADDR | DLY_SET_REL; // address to generate delay set
localparam DLY_SET_ADDR_MASK = CONTROL_ADDR_MASK | DLY_SET_REL_MASK; // address mask to generate delay set
localparam RUN_CHN_ADDR = CONTROL_ADDR | RUN_CHN_REL; // address to set sequnecer channel and run (4 LSB-s - channel)
localparam RUN_CHN_ADDR_MASK = CONTROL_ADDR_MASK | RUN_CHN_REL_MASK; // address mask to generate sequencer channel/run
localparam PATTERNS_ADDR = CONTROL_ADDR | PATTERNS_REL; // address to set DQM and DQS patterns (16'h0055)
localparam PATTERNS_ADDR_MASK = CONTROL_ADDR_MASK | PATTERNS_REL_MASK;// address mask to set DQM and DQS patterns
localparam PAGES_ADDR = CONTROL_ADDR | PAGES_REL; // address to set buffer pages {port1_page[1:0],port1_int_page[1:0],port0_page[1:0],port0_int_page[1:0]}
localparam PAGES_ADDR_MASK = CONTROL_ADDR_MASK | PAGES_REL_MASK; // address mask to set DQM and DQS patterns
localparam CMDA_EN_ADDR = CONTROL_ADDR | CMDA_EN_REL; // address to enable('h823)/disable('h822) command/address outputs
localparam CMDA_EN_ADDR_MASK = CONTROL_ADDR_MASK | CMDA_EN_REL_MASK; // address mask for command/address outputs
localparam EXTRA_ADDR = CONTROL_ADDR | EXTRA_REL; // address to set extra parameters (currently just inv_clk_div)
localparam EXTRA_ADDR_MASK = CONTROL_ADDR_MASK | EXTRA_REL_MASK; // address mask for extra parameters
reg busy_r=0;
reg selected_r=0;
reg selected=0;
reg selected_busy=0;
(* keep = "true" *) wire fifo_half_empty; // just debugging with (* keep = "true" *)
wire [AXI_WR_ADDR_BITS-1:0] waddr_fifo_out;
wire [31:0] wdata_fifo_out;
// reg fifo_re; // wrong, need to have (fifo!=1) || !re
wire fifo_nempty;
wire fifo_re=fifo_nempty; // try simpler
reg [AXI_WR_ADDR_BITS-1:0] waddr_fifo_out_r;
reg [31:0] wdata_fifo_out_r;
reg dly_ld_r=0;
reg dly_set_r=0;
reg run_seq_r=0;
reg [ 7:0] dqs_pattern_r; // DQS pattern during write (normally 8'h55)
reg [ 7:0] dqm_pattern_r; // DQM pattern (just for testing, should be 8'h0)
reg [ 1:0] port0_page_r; // port 0 buffer read page (to be controlled by arbiter later, set to 2'b0)
reg [ 1:0] port0_int_page_r; // port 0 PHY-side write to buffer page (to be controlled by arbiter later, set to 2'b0)
reg [ 1:0] port1_page_r; // port 1 buffer write page (to be controlled by arbiter later, set to 2'b0)
reg [ 1:0] port1_int_page_r; // port 1 PHY-side buffer read page (to be controlled by arbiter later, set to 2'b0)
reg cmda_en_r; // enable (tri-state off) all command and address lines to DDR chip
reg inv_clk_div_r; // invert clk_div to ISERDES
assign ld_delay = dly_ld_r;
assign dly_set = dly_set_r;
assign dly_data = wdata_fifo_out_r[ 7:0]; // WARNING: [Synth 8-3936] Found unconnected internal register 'wdata_fifo_out_r_reg' and it is trimmed from '32' to '11' bits. [ddrc_control.v:100]
assign dly_addr = waddr_fifo_out_r[ 6:0]; //WARNING: [Synth 8-3936] Found unconnected internal register 'waddr_fifo_out_r_reg' and it is trimmed from '12' to '7' bits. [ddrc_control.v:101]
assign run_addr = wdata_fifo_out_r[10:0];
assign run_chn = waddr_fifo_out_r[3:0];
assign run_seq = run_seq_r;
assign busy=busy_r && (start_wburst?(((pre_waddr ^ BUSY_WR_ADDR) & BUSY_WR_ADDR_MASK)==0): selected_busy);
assign dqs_pattern = dqs_pattern_r[7:0];
assign dqm_pattern = dqm_pattern_r[7:0];
assign port0_page = port0_page_r[1:0];
assign port0_int_page = port0_int_page_r[1:0];
assign port1_page = port1_page_r[1:0];
assign port1_int_page = port1_int_page_r[1:0];
assign cmda_tri = ~cmda_en_r;
assign inv_clk_div = inv_clk_div_r;
always @ (posedge clk or posedge rst) begin
if (rst) selected <= 1'b0;
else if (start_wburst) selected <= ((pre_waddr ^ CONTROL_ADDR) & CONTROL_ADDR_MASK)==0;
if (rst) selected_busy <= 1'b0;
else if (start_wburst) selected_busy <= ((pre_waddr ^ BUSY_WR_ADDR) & BUSY_WR_ADDR_MASK)==0;
if (rst) busy_r <= 1'b0;
// else if (start_wburst) busy_r <= !fifo_half_empty;
else busy_r <= !fifo_half_empty;
end
/* FIFO to cross clock boundary */
fifo_cross_clocks #(
.DATA_WIDTH (AXI_WR_ADDR_BITS+32),
.DATA_DEPTH (4)
) fifo_cross_clocks_i (
.rst (rst), // input
.rclk (mclk), // input
.wclk (clk), // input
.we (wr_en && selected), // input
.re (fifo_re), // input
.data_in ({waddr[AXI_WR_ADDR_BITS-1:0],wdata[31:0]}), // input[15:0]
.data_out ({waddr_fifo_out[AXI_WR_ADDR_BITS-1:0],wdata_fifo_out[31:0]}), // output[15:0]
.nempty (fifo_nempty), // output
.half_empty (fifo_half_empty) // output
);
always @ (posedge rst or posedge mclk) begin
// if (rst) fifo_re <= 1'b0;
// else fifo_re <= fifo_nempty;
if (rst) dly_ld_r <= 1'b0;
else dly_ld_r <= fifo_re && (((waddr_fifo_out ^ DLY_LD_ADDR) & DLY_LD_ADDR_MASK)==0);
if (rst) dly_set_r <= 1'b0;
else dly_set_r <= fifo_re && (((waddr_fifo_out ^ DLY_SET_ADDR) & DLY_SET_ADDR_MASK)==0);
if (rst) run_seq_r <= 1'b0;
else run_seq_r <= fifo_re && (((waddr_fifo_out ^ RUN_CHN_ADDR) & RUN_CHN_ADDR_MASK)==0);
if (rst) {dqm_pattern_r,dqs_pattern_r} <= 16'h0055;
else if (fifo_re && (((waddr_fifo_out ^ PATTERNS_ADDR) & PATTERNS_ADDR_MASK)==0))
{dqm_pattern_r,dqs_pattern_r} <= wdata_fifo_out[15:0];
if (rst) {port1_page_r[1:0],port1_int_page_r[1:0],port0_page_r[1:0],port0_int_page_r[1:0]} <= 8'h00;
else if (fifo_re && (((waddr_fifo_out ^ PAGES_ADDR) & PAGES_ADDR_MASK)==0))
{port1_page_r[1:0],port1_int_page_r[1:0],port0_page_r[1:0],port0_int_page_r[1:0]} <= wdata_fifo_out[7:0];
if (rst) cmda_en_r <= 1'b0;
else if (fifo_re && (((waddr_fifo_out ^ CMDA_EN_ADDR) & CMDA_EN_ADDR_MASK)==0))
cmda_en_r <= waddr_fifo_out[0];
if (rst) inv_clk_div_r <= 1'b0;
else if (fifo_re && (((waddr_fifo_out ^ EXTRA_ADDR) & EXTRA_ADDR_MASK)==0))
inv_clk_div_r <= wdata_fifo_out[0];
end
always @ (posedge mclk) begin
waddr_fifo_out_r <= waddr_fifo_out;
wdata_fifo_out_r <= wdata_fifo_out;
end
// assign busy=busy_r && start_wburst?(((pre_addr ^ SELECT_ADDR) & SELECT_ADDR_MASK)==0): selected_r;
assign busy=busy_r && start_wburst?(((pre_waddr ^ BUSY_ADDR) & BUSY_ADDR_MASK)==0): selected_r;
endmodule
......@@ -20,31 +20,35 @@
*******************************************************************************/
`timescale 1ns/1ps
module ddrc_status#(
parameter AXI_RD_ADDR_BITS= 12,
parameter SELECT_ADDR = 'h800, // address to select this module
parameter SELECT_ADDR_MASK = 'h800, // address mask to select this module
parameter BUSY_ADDR = 'hc00, // address to generate busy
parameter BUSY_ADDR_MASK = 'hc00 // address mask to generate busy
)(
input clk,
input mclk,
input rst,
input [AXI_RD_ADDR_BITS-1:0] pre_raddr, // AXI reade address, before actual reads (to generate busy), valid@start_burst
input start_rburst, // burst start - should generate ~ready (should be AND-ed with !busy internally)
input [AXI_RD_ADDR_BITS-1:0] raddr, // read address, valid with rd_en
input rd_en, // read enable
module ddrc_status
//#(
// parameter AXI_RD_ADDR_BITS= 12
// parameter SELECT_ADDR = 'h800, // address to select this module
// parameter SELECT_ADDR_MASK = 'h800, // address mask to select this module
// parameter BUSY_ADDR = 'hc00, // address to generate busy
// parameter BUSY_ADDR_MASK = 'hc00 // address mask to generate busy
//)
(
// input clk,
// input mclk,
// input rst,
// input [AXI_RD_ADDR_BITS-1:0] pre_raddr, // AXI reade address, before actual reads (to generate busy), valid@start_burst
// input start_rburst, // burst start - should generate ~ready (should be AND-ed with !busy internally)
// input [AXI_RD_ADDR_BITS-1:0] raddr, // read address, valid with rd_en
// input rd_en, // read enable
output [31:0] rdata, // read data, should valid with raddr and rd_en
output busy, // interface busy (combinatorial delay from start_wburst and pre_addr
// status/readback signals
input run_done, // sequencer done (add busy?)
// input run_done, // sequencer done (add busy?)
input run_busy, // sequencer busy
input locked, // MMCM and PLL locked
input ps_rdy, // MMCM phase shift control ready
input [ 7:0] ps_out // MMCM phase shift value (in 1/56 of the Fvco period)
);
assign busy=0;
assign rdata={21'b0,run_busy,locked,ps_rdy,ps_out[7:0]};
endmodule
......@@ -25,7 +25,7 @@ module ddrc_test01 #(
parameter SLEW_DQ = "SLOW",
parameter SLEW_DQS = "SLOW",
parameter SLEW_CMDA = "SLOW",
parameter SLEW_CLK = "SLOW",
parameter SLEW_CLK = "SLOW",
parameter IBUF_LOW_PWR = "TRUE",
parameter real REFCLK_FREQUENCY = 300.0,
parameter HIGH_PERFORMANCE_MODE = "FALSE",
......@@ -45,16 +45,36 @@ module ddrc_test01 #(
parameter SS_MOD_PERIOD = 10000,
parameter CMD_PAUSE_BITS= 6,
parameter CMD_DONE_BIT= 6,
parameter AXI_WR_ADDR_BITS = 12,
parameter AXI_RD_ADDR_BITS = 12,
parameter SELECT_WR_ADDR = 'h800, // AXI write address to select this module
parameter SELECT_WR_ADDR_MASK = 'h800, // AXI write address mask to select this module
parameter BUSY_WR_ADDR = 'hc00, // AXI write address to generate busy
parameter BUSY_WR_ADDR_MASK = 'hc00, // AXI write address mask to generate busy
parameter SELECT_RD_ADDR = 'h800, // AXI read address to select this module
parameter SELECT_RD_ADDR_MASK = 'h800, // AXI read address mask to select this module
parameter BUSY_RD_ADDR = 'hc00, // AXI read address to generate busy
parameter BUSY_RD_ADDR_MASK = 'hc00 // AXI read address mask to generate busy
parameter AXI_WR_ADDR_BITS = 13,
parameter AXI_RD_ADDR_BITS = 13,
parameter CONTROL_ADDR = 'h1000, // AXI write address of control write registers
parameter CONTROL_ADDR_MASK = 'h1400, // AXI write address of control registers
parameter STATUS_ADDR = 'h1400, // AXI write address of status read registers
parameter STATUS_ADDR_MASK = 'h1400, // AXI write address of status registers
parameter BUSY_WR_ADDR = 'h1800, // AXI write address to generate busy
parameter BUSY_WR_ADDR_MASK = 'h1c00, // AXI write address mask to generate busy
parameter CMD0_ADDR = 'h0800, // AXI write to command sequence memory
parameter CMD0_ADDR_MASK = 'h1800, // AXI read address mask for the command sequence memory
parameter PORT0_RD_ADDR = 'h0000, // AXI read address to generate busy
parameter PORT0_RD_ADDR_MASK = 'h1c00, // AXI read address mask to generate busy
parameter PORT1_WR_ADDR = 'h0400, // AXI read address to generate busy
parameter PORT1_WR_ADDR_MASK = 'h1c00, // AXI read address mask to generate busy
// parameters below to be ORed with CONTROL_ADDR and CONTROL_ADDR_MASK respectively
parameter DLY_LD_REL = 'h080, // address to generate delay load
parameter DLY_LD_REL_MASK = 'h380, // address mask to generate delay load
parameter DLY_SET_REL = 'h070, // address to generate delay set
parameter DLY_SET_REL_MASK = 'h3ff, // address mask to generate delay set
parameter RUN_CHN_REL = 'h000, // address to set sequnecer channel and run (4 LSB-s - channel)
parameter RUN_CHN_REL_MASK = 'h3f0, // address mask to generate sequencer channel/run
parameter PATTERNS_REL = 'h020, // address to set DQM and DQS patterns (16'h0055)
parameter PATTERNS_REL_MASK = 'h3ff, // address mask to set DQM and DQS patterns
parameter PAGES_REL = 'h021, // address to set buffer pages {port1_page[1:0],port1_int_page[1:0],port0_page[1:0],port0_int_page[1:0]}
parameter PAGES_REL_MASK = 'h3ff, // address mask to set DQM and DQS patterns
parameter CMDA_EN_REL = 'h022, // address to enable('h823)/disable('h822) command/address outputs
parameter CMDA_EN_REL_MASK = 'h3fe, // address mask for command/address outputs
parameter EXTRA_REL = 'h024, // address to set extra parameters (currently just inv_clk_div)
parameter EXTRA_REL_MASK = 'h3ff // address mask for extra parameters
)(
// DDR3 interface
......@@ -155,6 +175,67 @@ module ddrc_test01 #(
wire axird_bram_ren; // .ren(bram_reg_re_w) , // read port enable
wire axird_bram_regen; // .regen(bram_reg_re_w), // output register enable
wire [31:0] axird_bram_rdata; // .data_out(rdata[31:0]), // data out
wire [31:0] port0_rdata; //
wire [31:0] status_rdata; //
wire mclk;
wire en_cmd0_wr;
wire [10:0] run_addr; // input[10:0]
wire [ 3:0] run_chn; // input[3:0]
wire run_seq; // input
// wire run_done; // output
wire run_busy; // TODO: add to ddrc_sequencer
wire [ 7:0] dly_data; // input[7:0]
wire [ 6:0] dly_addr; // input[6:0]
wire ld_delay; // input
wire set; // input
wire locked; // output
wire ps_rdy; // output
wire [ 7:0] ps_out; // output[7:0]
wire en_port0_rd;
wire en_port0_regen;
wire en_port1_wr;
wire [ 1:0] port0_page; // input[1:0]
wire [ 1:0] port0_int_page; // input[1:0]
wire [ 1:0] port1_page; // input[1:0]
wire [ 1:0] port1_int_page;// input[1:0]
// additional control signals
wire cmda_tri; // input
wire inv_clk_div; // input
wire [ 7:0] dqs_pattern; // input[7:0] 8'h55
wire [ 7:0] dqm_pattern; // input[7:0] 8'h00
reg select_port0;
reg select_status;
wire axiwr_dev_busy;
wire axird_dev_busy;
// assign en_cmd0_wr= axiwr_bram_wen && (axiwr_bram_waddr[11:10]==2'h1);
// assign en_port0_rd= axird_bram_ren && (axird_bram_raddr[11:10]==2'h0);
// assign en_port0_regen= axird_bram_regen && (axird_bram_raddr[11:10]==2'h0);
// assign en_port1_wr= axiwr_bram_wen && (axiwr_bram_waddr[11:10]==2'h0);
assign en_cmd0_wr= axiwr_bram_wen && (((axiwr_bram_waddr ^ CMD0_ADDR) & CMD0_ADDR_MASK)==0);
assign en_port0_rd= axird_bram_ren && (((axird_bram_raddr ^ PORT0_RD_ADDR) & PORT0_RD_ADDR_MASK)==0);
assign en_port0_regen= axird_bram_regen && (((axird_bram_raddr ^ PORT0_RD_ADDR) & PORT0_RD_ADDR_MASK)==0);
assign en_port1_wr= axiwr_bram_wen && (((axiwr_bram_waddr ^ PORT1_WR_ADDR) & PORT1_WR_ADDR_MASK)==0);
assign axiwr_dev_ready = ~axiwr_dev_busy; //may combine (AND) multiple sources if needed
assign axird_bram_rdata= select_port0? port0_rdata[31:0]:(select_status?status_rdata[31:0]:32'bx);
assign axird_dev_ready = ~axird_dev_busy; //may combine (AND) multiple sources if needed
always @ (posedge axi_rst or posedge axi_aclk) begin
if (axi_rst) select_port0 <= 1'b0;
else if (axird_start_burst) select_port0 <= (((axird_pre_araddr[11:10]^ PORT0_RD_ADDR) & PORT0_RD_ADDR_MASK)==0);
if (axi_rst) select_status <= 1'b0;
else if (axird_start_burst) select_status <= (((axird_pre_araddr[11:10]^ STATUS_ADDR) & STATUS_ADDR_MASK)==0);
end
// Clock and reset from PS
BUFG axi_rst_i (.O(axi_rst),.I(~frst[0]));
......@@ -219,58 +300,31 @@ BUFG axi_aclk_i (.O(axi_aclk),.I(~fclk[0]));
.bram_regen (axird_bram_regen), // output
.bram_rdata (axird_bram_rdata) // input[31:0]
);
wire mclk;
wire en_cmd0_wr;
wire [10:0] run_addr; // input[10:0]
wire [ 3:0] run_chn; // input[3:0]
wire run_seq; // input
wire run_done; // output
wire run_busy; // TODO: add to ddrc_sequencer
wire [ 7:0] dly_data; // input[7:0]
wire [ 6:0] dly_addr; // input[6:0]
wire ld_delay; // input
wire set; // input
wire locked; // output
wire ps_rdy; // output
wire [ 7:0] ps_out; // output[7:0]
wire en_port0_rd;
wire en_port0_regen;
wire en_port1_wr;
wire [ 1:0] port0_page; // input[1:0]
wire [ 1:0] port0_int_page; // input[1:0]
wire [ 1:0] port1_page; // input[1:0]
wire [ 1:0] port1_int_page;// input[1:0]
// additional control signals
wire cmda_tri; // input
wire inv_clk_div; // input
wire [ 7:0] dqs_pattern; // input[7:0] 8'h55
wire [ 7:0] dqm_pattern; // input[7:0] 8'h00
assign en_cmd0_wr= axiwr_bram_wen && (axiwr_bram_waddr[11:10]==2'h1);
assign en_port0_rd= axird_bram_ren && (axird_bram_raddr[11:10]==2'h0);