pax_global_header 0000666 0000000 0000000 00000000064 12456063403 0014515 g ustar 00root root 0000000 0000000 52 comment=27c9f81a8104ee48d3599d85e6eb021174a1dcd5
x393-27c9f81a8104ee48d3599d85e6eb021174a1dcd5/ 0000775 0000000 0000000 00000000000 12456063403 0017156 5 ustar 00root root 0000000 0000000 x393-27c9f81a8104ee48d3599d85e6eb021174a1dcd5/.editor_defines 0000664 0000000 0000000 00000000317 12456063403 0022143 0 ustar 00root root 0000000 0000000 // 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 IVERILOG x393-27c9f81a8104ee48d3599d85e6eb021174a1dcd5/.gitignore 0000664 0000000 0000000 00000000135 12456063403 0021145 0 ustar 00root root 0000000 0000000 unisims
vivado_*
syntax_*
simulation/*
ise_*
attic/*
IVERILOG_INCLUDE.v
x393.prj
*DEBUG_VDT*
x393-27c9f81a8104ee48d3599d85e6eb021174a1dcd5/.project 0000664 0000000 0000000 00000010365 12456063403 0020632 0 ustar 00root root 0000000 0000000
x393
org.python.pydev.PyDevBuilder
com.elphel.vdt.veditor.simulateBuilder
com.elphel.vdt.veditor.simulateBuilder.00000000Default.CleanCommand
echo 'Clean'
com.elphel.vdt.veditor.simulateBuilder.00000000Default.buildOrder
0
com.elphel.vdt.veditor.simulateBuilder.00000000Default.command
echo 'No Build Configuration Specified'
com.elphel.vdt.veditor.simulateBuilder.00000000Default.enable
true
com.elphel.vdt.veditor.simulateBuilder.00000000Default.name
Default
com.elphel.vdt.veditor.simulateBuilder.00000000Default.parser
com.elphel.vdt.veditor.simulateBuilder.00000000Default.workFolder
com.elphel.vdt.veditor.HdlNature
org.python.pydev.pythonNature
ise_logs/ISExst.log
1
ise_logs/ISExst-20140607155721361.log
ise_state/x393-synth.tgz
1
ise_state/x393-synth-20140607155721361.tgz
vivado_logs/VivadoBitstream.log
1
vivado_logs/VivadoBitstream-20140611174132808.log
vivado_logs/VivadoOpt.log
1
vivado_logs/VivadoOpt-20140611174132808.log
vivado_logs/VivadoOptPhys.log
1
vivado_logs/VivadoOptPhys-20140611174132808.log
vivado_logs/VivadoOptPower.log
1
vivado_logs/VivadoOptPower-20140611174132808.log
vivado_logs/VivadoPlace.log
1
vivado_logs/VivadoPlace-20140611174132808.log
vivado_logs/VivadoRoute.log
1
vivado_logs/VivadoRoute-20140611174132808.log
vivado_logs/VivadoSynthesis.log
1
vivado_logs/VivadoSynthesis-20140611174056482.log
vivado_logs/VivadoTimimgSummaryReportImplemented.log
1
vivado_logs/VivadoTimimgSummaryReportImplemented-20140611174132808.log
vivado_logs/VivadoTimimgSummaryReportSynthesis.log
1
vivado_logs/VivadoTimimgSummaryReportSynthesis-20140611174132808.log
vivado_logs/VivadoTimingReportImplemented.log
1
vivado_logs/VivadoTimingReportImplemented-20140611174132808.log
vivado_logs/VivadoTimingReportSynthesis.log
1
vivado_logs/VivadoTimingReportSynthesis-20140611174132808.log
vivado_state/x393-opt-phys.dcp
1
vivado_state/x393-opt-phys-20140611174132808.dcp
vivado_state/x393-place.dcp
1
vivado_state/x393-place-20140611174132808.dcp
vivado_state/x393-route.dcp
1
vivado_state/x393-route-20140611174132808.dcp
vivado_state/x393-synth.dcp
1
vivado_state/x393-synth-20140610113942407.dcp
x393-27c9f81a8104ee48d3599d85e6eb021174a1dcd5/.pydevproject 0000664 0000000 0000000 00000000456 12456063403 0021702 0 ustar 00root root 0000000 0000000
Default
python 2.7
x393-27c9f81a8104ee48d3599d85e6eb021174a1dcd5/.settings/ 0000775 0000000 0000000 00000000000 12456063403 0021074 5 ustar 00root root 0000000 0000000 x393-27c9f81a8104ee48d3599d85e6eb021174a1dcd5/.settings/com.elphel.vdt.FPGA_project.prefs 0000664 0000000 0000000 00000000660 12456063403 0027223 0 ustar 00root root 0000000 0000000 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-1
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
x393-27c9f81a8104ee48d3599d85e6eb021174a1dcd5/.settings/com.elphel.vdt.ISExst.prefs 0000664 0000000 0000000 00000000206 12456063403 0026133 0 ustar 00root root 0000000 0000000 ISExst_170_constraints=ddrc_test01.xcf
com.elphel.store.context.ISExst=ISExst_170_constraints<-@\#\#@->
eclipse.preferences.version=1
x393-27c9f81a8104ee48d3599d85e6eb021174a1dcd5/.settings/com.elphel.vdt.VivadoBitstream.prefs 0000664 0000000 0000000 00000000450 12456063403 0030060 0 ustar 00root root 0000000 0000000 VivadoBitstream_103_PreBitstreamTCL=set_property BITSTREAM.STARTUP.MATCH_CYCLE NoWait [current_design]<-@\#\#@->
VivadoBitstream_105_force=true
com.elphel.store.context.VivadoBitstream=VivadoBitstream_105_force<-@\#\#@->VivadoBitstream_103_PreBitstreamTCL<-@\#\#@->
eclipse.preferences.version=1
x393-27c9f81a8104ee48d3599d85e6eb021174a1dcd5/.settings/com.elphel.vdt.VivadoPlace.prefs 0000664 0000000 0000000 00000000216 12456063403 0027152 0 ustar 00root root 0000000 0000000 VivadoPlace_111_verbose_place=true
com.elphel.store.context.VivadoPlace=VivadoPlace_111_verbose_place<-@\#\#@->
eclipse.preferences.version=1
x393-27c9f81a8104ee48d3599d85e6eb021174a1dcd5/.settings/com.elphel.vdt.VivadoSynthesis.prefs 0000664 0000000 0000000 00000000566 12456063403 0030127 0 ustar 00root root 0000000 0000000 VivadoSynthesis_102_ConstraintsFiles=ddrc_test01.xdc<-@\#\#@->ddrc_test01_timing.xdc<-@\#\#@->
VivadoSynthesis_115_flatten_hierarchy=none
VivadoSynthesis_95_ShowInfo=false
com.elphel.store.context.VivadoSynthesis=VivadoSynthesis_102_ConstraintsFiles<-@\#\#@->VivadoSynthesis_95_ShowInfo<-@\#\#@->VivadoSynthesis_115_flatten_hierarchy<-@\#\#@->
eclipse.preferences.version=1
com.elphel.vdt.VivadoTimimgSummaryReportSynthesis.prefs 0000664 0000000 0000000 00000000355 12456063403 0033765 0 ustar 00root root 0000000 0000000 x393-27c9f81a8104ee48d3599d85e6eb021174a1dcd5/.settings VivadoTimimgSummaryReportSynthesis_102_DisableVivadoTimingSummary=true
com.elphel.store.context.VivadoTimimgSummaryReportSynthesis=VivadoTimimgSummaryReportSynthesis_102_DisableVivadoTimingSummary<-@\#\#@->
eclipse.preferences.version=1
com.elphel.vdt.VivadoTimingReportSynthesis.prefs 0000664 0000000 0000000 00000000312 12456063403 0032401 0 ustar 00root root 0000000 0000000 x393-27c9f81a8104ee48d3599d85e6eb021174a1dcd5/.settings VivadoTimingReportSynthesis_102_DisableVivadoTiming=true
com.elphel.store.context.VivadoTimingReportSynthesis=VivadoTimingReportSynthesis_102_DisableVivadoTiming<-@\#\#@->
eclipse.preferences.version=1
x393-27c9f81a8104ee48d3599d85e6eb021174a1dcd5/.settings/com.elphel.vdt.iverilog.prefs 0000664 0000000 0000000 00000001135 12456063403 0026576 0 ustar 00root root 0000000 0000000 com.elphel.store.context.iverilog=iverilog_81_TopModulesOther<-@\#\#@->iverilog_83_ExtraFiles<-@\#\#@->iverilog_88_ShowNoProblem<-@\#\#@->iverilog_77_Param_Exe<-@\#\#@->iverilog_78_VVP_Exe<-@\#\#@->iverilog_99_GrepFindErrWarn<-@\#\#@->iverilog_84_IncludeDir<-@\#\#@->
eclipse.preferences.version=1
iverilog_77_Param_Exe=/usr/local/bin/iverilog
iverilog_78_VVP_Exe=/usr/local/bin/vvp
iverilog_81_TopModulesOther=glbl<-@\#\#@->
iverilog_83_ExtraFiles=glbl.v<-@\#\#@->
iverilog_84_IncludeDir=/home/andrey/git/x393/ddr3<-@\#\#@->
iverilog_88_ShowNoProblem=true
iverilog_99_GrepFindErrWarn=error|warning|sorry
x393-27c9f81a8104ee48d3599d85e6eb021174a1dcd5/.settings/com.elphel.vdt.prefs 0000664 0000000 0000000 00000000227 12456063403 0024760 0 ustar 00root root 0000000 0000000 com.elphel.store.context.=com.elphel.vdt.PROJECT_DESING_MENU<-@\#\#@->
com.elphel.vdt.PROJECT_DESING_MENU=MainDesignMenu
eclipse.preferences.version=1
x393-27c9f81a8104ee48d3599d85e6eb021174a1dcd5/OSERDESE1.diff 0000664 0000000 0000000 00000231360 12456063403 0021307 0 ustar 00root root 0000000 0000000 --- /unisims/OSERDESE1.v 1969-12-31 17:00:00.000000000 -0700
+++ ../../vdt-projects/eddr3/unisims/OSERDESE1.v 2014-05-21 09:38:37.691045918 -0600
@@ -0,0 +1,3293 @@
+///////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 1995/2005 Xilinx, Inc.
+// All Right Reserved.
+///////////////////////////////////////////////////////////////////////////////
+// ____ ____
+// / /\/ /
+// /___/ \ / Vendor : Xilinx
+// \ \ \/ Version : 10.1
+// \ \ Description : Xilinx Timing Simulation Library Component
+// / / Source Synchronous Output Serializer
+// /___/ /\ Filename : OSERDESE1.v
+// \ \ / \ Timestamp : Tue Sep 16 15:30:44 PDT 2008
+// \___\/\___\
+//
+// Revision:
+// 09/16/08 - Initial version.
+// 12/05/08 - IR 495397.
+// 01/13/09 - IR 503429.
+// 01/15/09 - IR 503783 CLKPERF is not inverted for OFB/ofb_out.
+// 02/06/09 - CR 507373 Removed IOCLKGLITCH and CLKB
+// 02/26/09 - CR 510489 fixed SHIFTIN2_in
+// 03/16/09 - CR 512140 and 512139 -- sdf load errors
+// 01/27/10 - CR 546419 Updated specify block
+// 12/13/11 - Added `celldefine and `endcelldefine (CR 524859).
+// 09/04/12 - 676501 CLK -> OFB specify path missing
+// End Revision
+
+`timescale 1 ps / 1 ps
+`celldefine
+
+module OSERDESE1 (OCBEXTEND, OFB, OQ, SHIFTOUT1, SHIFTOUT2, TFB, TQ,
+ CLK, CLKDIV, CLKPERF, CLKPERFDELAY, D1, D2, D3, D4, D5, D6, OCE, ODV, RST, SHIFTIN1, SHIFTIN2, T1, T2, T3, T4, TCE, WC);
+
+
+ parameter DATA_RATE_OQ = "DDR";
+ parameter DATA_RATE_TQ = "DDR";
+ parameter integer DATA_WIDTH = 4;
+ parameter integer DDR3_DATA = 1;
+ parameter [0:0] INIT_OQ = 1'b0;
+ parameter [0:0] INIT_TQ = 1'b0;
+ parameter INTERFACE_TYPE = "DEFAULT";
+ parameter integer ODELAY_USED = 0;
+ parameter SERDES_MODE = "MASTER";
+ parameter [0:0] SRVAL_OQ = 1'b0;
+ parameter [0:0] SRVAL_TQ = 1'b0;
+ parameter integer TRISTATE_WIDTH = 4;
+
+
+ `ifdef XIL_TIMING
+ parameter LOC = "UNPLACED";
+ `endif
+
+//-------------------------------------------------------------
+// Outputs:
+//-------------------------------------------------------------
+// OQ: Data output
+// TQ: Output of tristate mux
+// SHIFTOUT1: Carry out data 1 for slave
+// SHIFTOUT2: Carry out data 2 for slave
+// OFB: O Feedback output
+
+//
+//-------------------------------------------------------------
+// Inputs:
+//-------------------------------------------------------------
+//
+// Inputs:
+// CLK: High speed clock from DCM
+// CLKB: Inverted High speed clock from DCM
+// CLKDIV: Low speed divided clock from DCM
+// CLKPERF: Performance Path clock
+// CLKPERFDELAY: delayed Performance Path clock
+// D1, D2, D3, D4, D5, D6 : Data inputs
+// OCE: Clock enable for output data flops
+// ODV: ODELAY value > 140 degrees
+// RST: Reset control
+// T1, T2, T3, T4: tristate inputs
+// SHIFTIN1: Carry in data 1 for master from slave
+// SHIFTIN2: Carry in data 2 for master from slave
+// TCE: Tristate clock enable
+// WC: Write command given by memory controller
+
+ output OCBEXTEND;
+ output OFB;
+ output OQ;
+ output SHIFTOUT1;
+ output SHIFTOUT2;
+ output TFB;
+ output TQ;
+
+ input CLK;
+ input CLKDIV;
+ input CLKPERF;
+ input CLKPERFDELAY;
+ input D1;
+ input D2;
+ input D3;
+ input D4;
+ input D5;
+ input D6;
+ input OCE;
+ input ODV;
+ input RST;
+ input SHIFTIN1;
+ input SHIFTIN2;
+ input T1;
+ input T2;
+ input T3;
+ input T4;
+ input TCE;
+ input WC;
+
+
+//
+ wire SERDES, DDR_CLK_EDGE;
+ wire [5:0] SRTYPE;
+ wire WC_DELAY;
+ wire [4:0] SELFHEAL;
+
+
+ wire load;
+ wire qmux1, qmux, tmux1, tmux2;
+ wire data1, data2, triin1, triin2;
+ wire d2rnk2;
+ wire CLKD;
+ wire CLKDIVD;
+ wire iodelay_state;
+
+// attribute
+ reg data_rate_int;
+ reg [3:0] data_width_int;
+ reg [1:0] tristate_width_int;
+ reg data_rate_oq_int;
+ reg [1:0] data_rate_tq_int;
+ reg ddr3_data_int;
+ reg interface_type_int;
+ reg odelay_used_int;
+ reg serdes_mode_int;
+
+// Output signals
+ wire ioclkglitch_out, ocbextend_out, ofb_out, oq_out, tq_out, shiftout1_out, shiftout2_out;
+
+// Other signals
+ tri0 GSR = glbl.GSR;
+
+ reg notifier;
+
+ wire CLK_in;
+ wire CLKDIV_in;
+ wire CLKPERF_in;
+ wire CLKPERFDELAY_in;
+ wire D1_in;
+ wire D2_in;
+ wire D3_in;
+ wire D4_in;
+ wire D5_in;
+ wire D6_in;
+ wire OCE_in;
+ wire ODV_in;
+ wire RST_in;
+ wire SHIFTIN1_in;
+ wire SHIFTIN2_in;
+ wire T1_in;
+ wire T2_in;
+ wire T3_in;
+ wire T4_in;
+ wire TCE_in;
+ wire WC_in;
+
+`ifndef XIL_TIMING
+
+ assign CLK_in = CLK;
+ assign CLKDIV_in = CLKDIV;
+ assign D1_in = D1;
+ assign D2_in = D2;
+ assign D3_in = D3;
+ assign D4_in = D4;
+ assign D5_in = D5;
+ assign D6_in = D6;
+ assign OCE_in = OCE;
+ assign T1_in = T1;
+ assign T2_in = T2;
+ assign T3_in = T3;
+ assign T4_in = T4;
+ assign TCE_in = TCE;
+ assign WC_in = WC;
+
+`endif // `ifndef XIL_TIMING
+
+
+ assign CLKPERF_in = CLKPERF;
+// assign CLKPERFDELAY_in = CLKPERFDELAY;
+// IR 495397 & IR 499954
+// assign CLKPERFDELAY_in = (CLKPERFDELAY === 1'bx)? 1'b0 : CLKPERFDELAY;
+ generate
+ case (ODELAY_USED)
+ 0: assign CLKPERFDELAY_in = CLKPERF;
+ 1: assign CLKPERFDELAY_in = (CLKPERFDELAY === 1'bx)? 1'b0 : CLKPERFDELAY;
+ endcase
+ endgenerate
+
+ assign SHIFTIN1_in = SHIFTIN1;
+ assign SHIFTIN2_in = SHIFTIN2;
+ assign ODV_in = ODV;
+ assign RST_in = RST;
+
+ buf b_ocbextend (OCBEXTEND, ocbextend_out);
+ buf b_ofb (OFB, ofb_out);
+ buf b_oq (OQ, oq_out);
+ buf b_shiftout1 (SHIFTOUT1, shiftout1_out);
+ buf b_shiftout2 (SHIFTOUT2, shiftout2_out);
+ buf b_tfb (TFB, tfb_out);
+ buf b_tq (TQ, tq_out);
+
+
+ initial begin
+
+//-------------------------------------------------
+//----- DATA_RATE_OQ check
+//-------------------------------------------------
+ case (DATA_RATE_OQ)
+ "SDR" : data_rate_oq_int <= 1'b1;
+ "DDR" : data_rate_oq_int <= 1'b0;
+ default : begin
+ $display("Attribute Syntax Error : The attribute DATA_RATE_OQ on OSERDESE1 instance %m is set to %s. Legal values for this attribute are SDR or DDR", DATA_RATE_OQ);
+ $display("finish OSERDESE1 1");
+ $finish;
+ end
+ endcase // case(DATA_RATE_OQ)
+
+//-------------------------------------------------
+//----- DATA_RATE_TQ check
+//-------------------------------------------------
+ case (DATA_RATE_TQ)
+
+ "BUF" : data_rate_tq_int <= 2'b00;
+ "SDR" : data_rate_tq_int <= 2'b01;
+ "DDR" : data_rate_tq_int <= 2'b10;
+ default : begin
+ $display("Attribute Syntax Error : The attribute DATA_RATE_TQ on OSERDESE1 instance %m is set to %s. Legal values for this attribute are BUF, SDR or DDR", DATA_RATE_TQ);
+ $display("finish OSERDESE1 2");
+ $finish;
+ end
+
+ endcase // case(DATA_RATE_TQ)
+
+//-------------------------------------------------
+//----- DATA_WIDTH check
+//-------------------------------------------------
+ case (DATA_WIDTH)
+
+ 2, 3, 4, 5, 6, 7, 8, 10 : data_width_int = DATA_WIDTH;
+ default : begin
+ $display("Attribute Syntax Error : The attribute DATA_WIDTH on OSERDESE1 instance %m is set to %d. Legal values for this attribute are 2, 3, 4, 5, 6, 7, 8, or 10", DATA_WIDTH);
+ $display("finish OSERDESE1 3");
+ $finish;
+ end
+ endcase // case(DATA_WIDTH)
+
+//-------------------------------------------------
+//----- DDR3_DATA check
+//-------------------------------------------------
+ case (DDR3_DATA)
+ 0 : ddr3_data_int <= 1'b0;
+ 1 : ddr3_data_int <= 1'b1;
+ default : begin
+ $display("Attribute Syntax Error : The attribute DDR3_DATA on OSERDESE1 instance %m is set to %d. Legal values for this attribute are 0 or 1", DDR3_DATA);
+ $display("finish OSERDESE1 4");
+ $finish;
+ end
+ endcase // case(DDR3_DATA)
+
+//-------------------------------------------------
+//----- INTERFACE_TYPE check
+//-------------------------------------------------
+ case (INTERFACE_TYPE)
+ "DEFAULT" : interface_type_int <= 1'b0;
+ "MEMORY_DDR3" : interface_type_int <= 1'b1;
+ default : begin
+ $display("Attribute Syntax Error : The attribute INTERFACE_TYPE on OSERDESE1 instance %m is set to %s. Legal values for this attribute are DEFAULT, or MEMORY_DDR3", INTERFACE_TYPE);
+ $display("finish OSERDESE1 5");
+ $finish;
+ end
+ endcase // INTERFACE_TYPE
+
+
+//-------------------------------------------------
+//----- ODELAY_USED check
+//-------------------------------------------------
+ case (ODELAY_USED)
+
+// "FALSE" : odelay_used_int <= 1'b0;
+// "TRUE" : odelay_used_int <= 1'b1;
+ 0 : odelay_used_int <= 1'b0;
+ 1 : odelay_used_int <= 1'b1;
+ default : begin
+ $display("Attribute Syntax Error : The attribute ODELAY_USED on OSERDESE1 instance %m is set to %s. Legal values for this attribute are FALSE or TRUE", ODELAY_USED);
+ $display("finish OSERDESE1 6");
+ $finish;
+ end
+
+ endcase // case(ODELAY_USED)
+
+//-------------------------------------------------
+//----- SERDES_MODE check
+//-------------------------------------------------
+ case (SERDES_MODE)
+
+ "MASTER" : serdes_mode_int <= 1'b0;
+ "SLAVE" : serdes_mode_int <= 1'b1;
+ default : begin
+ $display("Attribute Syntax Error : The attribute SERDES_MODE on OSERDESE1 instance %m is set to %s. Legal values for this attribute are MASTER or SLAVE", SERDES_MODE);
+ $display("finish OSERDESE1 7");
+ $finish;
+ end
+
+ endcase // case(SERDES_MODE)
+
+//-------------------------------------------------
+//----- TRISTATE_WIDTH check
+//-------------------------------------------------
+ case (TRISTATE_WIDTH)
+
+ 1 : tristate_width_int <= 2'b00;
+ 2 : tristate_width_int <= 2'b01;
+ 4 : tristate_width_int <= 2'b10;
+ default : begin
+ $display("Attribute Syntax Error : The attribute TRISTATE_WIDTH on OSERDESE1 instance %m is set to %d. Legal values for this attribute are 1, 2 or 4", TRISTATE_WIDTH);
+ $display("finish OSERDESE1 8");
+ $finish;
+ end
+
+ endcase // case(TRISTATE_WIDTH)
+// $display("Info: The attribute TRISTATE_WIDTH on OSERDESE1 instance %m is set to %d", TRISTATE_WIDTH);
+
+//-------------------------------------------------
+ end // initial begin
+
+//-------------------------------------------------
+
+ assign SERDES = 1'b1;
+ assign SRTYPE = 6'b111111;
+ assign DDR_CLK_EDGE = 1'b1;
+ assign WC_DELAY = 1'b0;
+ assign SELFHEAL = 5'b00000;
+
+ assign #0 CLKD = CLK;
+ assign #0 CLKDIVD = CLKDIV;
+
+
+ assign #10 ofb_out = (ODELAY_USED == 1)? CLKPERF : oq_out;
+ assign #10 tfb_out = iodelay_state;
+
+
+/////////////////////////////////////////////////////////
+//
+// Delay assignments
+//
+/////////////////////////////////////////////////////////
+
+// Data output delays
+defparam dfront.FFD = 1; // clock to out delay for flip flops
+// driven by clk
+defparam datao.FFD = 1; // clock to out delay for flip flops
+// driven by clk
+defparam dfront.FFCD = 1; // clock to out delay for flip flops
+// driven by clkdiv
+defparam dfront.MXD = 1; // mux delay
+
+defparam dfront.MXR1 = 1; // mux before 2nd rank of flops
+
+// Programmable load generator
+defparam dfront.ldgen.ffdcnt = 1;
+defparam dfront.ldgen.mxdcnt = 1;
+defparam dfront.ldgen.FFRST = 145; // clock to out delay for flop in PLSG
+
+// Tristate output delays
+defparam tfront.ffd = 1; // clock to out delay for flip flops
+defparam tfront.mxd = 1; // mux delay
+
+defparam trio.ffd = 1; // clock to out delay for flip flops
+defparam trio.mxd = 1; // mux delay
+
+//------------------------------------------------------------------
+// Instantiate output data section
+//------------------------------------------------------------------
+
+rank12d_oserdese1_vlog dfront (.D1(D1_in), .D2(D2_in), .D3(D3_in), .D4(D4_in), .D5(D5_in), .D6(D6_in),
+ .d2rnk2(d2rnk2),
+ .SHIFTIN1(SHIFTIN1_in), .SHIFTIN2(SHIFTIN2_in),
+ .C(CLK_in), .CLKDIV(CLKDIV_in), .SR(RST_in), .OCE(OCE_in),
+ .data1(data1), .data2(data2), .SHIFTOUT1(shiftout1_out), .SHIFTOUT2(shiftout2_out),
+ .DATA_RATE_OQ(data_rate_oq_int), .DATA_WIDTH(data_width_int),
+ .SERDES_MODE(serdes_mode_int), .load(load),
+ .IOCLK_GLITCH(ioclkglitch_out),
+ .INIT_OQ(INIT_OQ), .SRVAL_OQ(SRVAL_OQ));
+
+
+trif_oserdese1_vlog tfront (.T1(T1_in), .T2(T2_in), .T3(T3_in), .T4(T4_in), .load(load),
+ .C(CLK_in), .CLKDIV(CLKDIV_in), .SR(RST_in), .TCE(TCE_in),
+ .DATA_RATE_TQ(data_rate_tq_int), .TRISTATE_WIDTH(tristate_width_int),
+ .INIT_TQ(INIT_TQ), .SRVAL_TQ(SRVAL_TQ),
+ .data1(triin1), .data2(triin2));
+
+
+txbuffer_oserdese1_vlog DDR3FIFO (.iodelay_state(iodelay_state), .qmux1(qmux1), .qmux2(qmux2), .tmux1(tmux1), .tmux2(tmux2),
+ .d1(data1), .d2(data2), .t1(triin1), .t2(triin2), .trif(tq_out),
+ .WC(WC_in), .ODV(ODV_in), .extra(ocbextend_out),
+ .clk(CLK_in), .clkdiv(CLKDIV_in), .bufo(CLKPERFDELAY_in), .bufop(CLKPERF_in), .rst(RST_in),
+ .ODELAY_USED(odelay_used_int), .DDR3_DATA(ddr3_data_int),
+ .DDR3_MODE(interface_type_int));
+
+dout_oserdese1_vlog datao (.data1(qmux1), .data2(qmux2),
+ .CLK(CLK_in), .BUFO(CLKPERFDELAY_in), .SR(RST_in), .OCE(OCE_in),
+ .OQ(oq_out), .d2rnk2(d2rnk2),
+ .DATA_RATE_OQ(data_rate_oq_int),
+ .INIT_OQ(INIT_OQ), .SRVAL_OQ(SRVAL_OQ),
+ .DDR3_MODE(interface_type_int));
+
+tout_oserdese1_vlog trio (.data1(tmux1), .data2(tmux2),
+ .CLK(CLK_in), .BUFO(CLKPERFDELAY_in), .SR(RST_in), .TCE(TCE_in),
+ .DATA_RATE_TQ(data_rate_tq_int), .TRISTATE_WIDTH(tristate_width_int),
+ .INIT_TQ(INIT_TQ), .SRVAL_TQ(SRVAL_TQ),
+ .TQ(tq_out), .DDR3_MODE(interface_type_int));
+
+
+`ifndef XIL_TIMING
+ specify
+ ( CLK => OFB) = (100, 100);
+ ( CLK => OQ) = (100, 100);
+ ( CLK => TQ) = (100, 100);
+ ( CLKPERF => OQ) = (100, 100);
+ ( CLKPERF => TQ) = (100, 100);
+ ( CLKPERFDELAY => OQ) = (100, 100);
+ ( CLKPERFDELAY => TQ) = (100, 100);
+ ( T1 => TQ) = (0, 0);
+
+ specparam PATHPULSE$ = 0;
+
+ endspecify
+`endif // `ifndef XIL_TIMING
+
+`ifdef XIL_TIMING
+//*** Timing Checks Start here
+
+ specify
+ ( CLK => OFB) = (100:100:100, 100:100:100);
+ ( CLK => OQ) = (100:100:100, 100:100:100);
+ ( CLK => TQ) = (100:100:100, 100:100:100);
+ ( CLKPERF => OQ) = (100:100:100, 100:100:100);
+ ( CLKPERF => TQ) = (100:100:100, 100:100:100);
+ ( CLKPERFDELAY => OQ) = (100:100:100, 100:100:100);
+ ( CLKPERFDELAY => TQ) = (100:100:100, 100:100:100);
+ ( T1 => TQ) = (0:0:0, 0:0:0);
+
+ $setuphold (posedge CLK, negedge OCE, 0:0:0, 0:0:0, notifier,,, CLK_in, OCE_in);
+ $setuphold (posedge CLK, negedge T1, 0:0:0, 0:0:0, notifier,,, CLK_in, T1_in);
+ $setuphold (posedge CLK, negedge TCE, 0:0:0, 0:0:0, notifier,,, CLK_in, TCE_in);
+ $setuphold (posedge CLK, posedge OCE, 0:0:0, 0:0:0, notifier,,, CLK_in, OCE_in);
+ $setuphold (posedge CLK, posedge T1, 0:0:0, 0:0:0, notifier,,, CLK_in, T1_in);
+ $setuphold (posedge CLK, posedge TCE, 0:0:0, 0:0:0, notifier,,, CLK_in, TCE_in);
+ $setuphold (posedge CLKDIV, negedge D1, 0:0:0, 0:0:0, notifier,,, CLKDIV_in, D1_in);
+ $setuphold (posedge CLKDIV, negedge D2, 0:0:0, 0:0:0, notifier,,, CLKDIV_in, D2_in);
+ $setuphold (posedge CLKDIV, negedge D3, 0:0:0, 0:0:0, notifier,,, CLKDIV_in, D3_in);
+ $setuphold (posedge CLKDIV, negedge D4, 0:0:0, 0:0:0, notifier,,, CLKDIV_in, D4_in);
+ $setuphold (posedge CLKDIV, negedge D5, 0:0:0, 0:0:0, notifier,,, CLKDIV_in, D5_in);
+ $setuphold (posedge CLKDIV, negedge D6, 0:0:0, 0:0:0, notifier,,, CLKDIV_in, D6_in);
+ $setuphold (posedge CLKDIV, negedge RST, 0:0:0, 0:0:0, notifier,,, CLKDIV_in, RST_in);
+ $setuphold (posedge CLKDIV, negedge T1, 0:0:0, 0:0:0, notifier,,, CLKDIV_in, T1_in);
+ $setuphold (posedge CLKDIV, negedge T2, 0:0:0, 0:0:0, notifier,,, CLKDIV_in, T2_in);
+ $setuphold (posedge CLKDIV, negedge T3, 0:0:0, 0:0:0, notifier,,, CLKDIV_in, T3_in);
+ $setuphold (posedge CLKDIV, negedge T4, 0:0:0, 0:0:0, notifier,,, CLKDIV_in, T4_in);
+ $setuphold (posedge CLKDIV, negedge WC, 0:0:0, 0:0:0, notifier,,, CLKDIV_in, WC_in);
+ $setuphold (posedge CLKDIV, posedge D1, 0:0:0, 0:0:0, notifier,,, CLKDIV_in, D1_in);
+ $setuphold (posedge CLKDIV, posedge D2, 0:0:0, 0:0:0, notifier,,, CLKDIV_in, D2_in);
+ $setuphold (posedge CLKDIV, posedge D3, 0:0:0, 0:0:0, notifier,,, CLKDIV_in, D3_in);
+ $setuphold (posedge CLKDIV, posedge D4, 0:0:0, 0:0:0, notifier,,, CLKDIV_in, D4_in);
+ $setuphold (posedge CLKDIV, posedge D5, 0:0:0, 0:0:0, notifier,,, CLKDIV_in, D5_in);
+ $setuphold (posedge CLKDIV, posedge D6, 0:0:0, 0:0:0, notifier,,, CLKDIV_in, D6_in);
+ $setuphold (posedge CLKDIV, posedge RST, 0:0:0, 0:0:0, notifier,,, CLKDIV_in, RST_in);
+ $setuphold (posedge CLKDIV, posedge T1, 0:0:0, 0:0:0, notifier,,, CLKDIV_in, T1_in);
+ $setuphold (posedge CLKDIV, posedge T2, 0:0:0, 0:0:0, notifier,,, CLKDIV_in, T2_in);
+ $setuphold (posedge CLKDIV, posedge T3, 0:0:0, 0:0:0, notifier,,, CLKDIV_in, T3_in);
+ $setuphold (posedge CLKDIV, posedge T4, 0:0:0, 0:0:0, notifier,,, CLKDIV_in, T4_in);
+ $setuphold (posedge CLKDIV, posedge WC, 0:0:0, 0:0:0, notifier,,, CLKDIV_in, WC_in);
+
+ specparam PATHPULSE$ = 0;
+
+ endspecify
+`endif // `ifdef XIL_TIMING
+
+
+endmodule // OSERDESE1
+
+`timescale 1ps/1ps
+/////////////////////////////////////////////////////////
+//
+// module selfheal_oserdese1_vlog
+//
+///////////////////////////////////////////////////////
+//
+// Self healing circuit for Mt Blanc
+// This model ONLY works for SERDES operation!!
+//
+//
+//
+////////////////////////////////////////////////////////
+//
+//
+//
+/////////////////////////////////////////////////////////
+//
+// Inputs:
+// dq3 - dq0: Data from load counter
+// CLKDIV: Divided clock from PLL
+// srint: RESET from load generator
+// rst: Set/Reset control
+//
+//
+//
+// Outputs:
+// SHO: Data output
+//
+//
+//
+// Programmable Points
+// SELFHEAL: String of 5 bits. 1 as enable and 4 as compare
+// Test attributes in model
+//
+//
+//
+//
+//
+////////////////////////////////////////////////////////////////////////////////
+//
+
+module selfheal_oserdese1_vlog (dq3, dq2, dq1, dq0,
+ CLKDIV, srint, rst,
+ SHO);
+
+input dq3, dq2, dq1, dq0;
+
+input CLKDIV, srint, rst;
+
+output SHO;
+
+
+reg shr;
+
+reg SHO;
+
+
+wire clkint;
+
+wire error;
+
+wire rst_in, rst_self_heal;
+
+
+// Programmable Points
+
+wire [4:0] SELFHEAL;
+assign SELFHEAL = 5'b00000;
+
+
+
+//////////////////////////////////////////////////
+// Delay values
+//
+parameter FFD = 10; // clock to out delay for flip flops
+// driven by clk
+parameter FFCD = 10; // clock to out delay for flip flops
+// driven by clkdiv
+parameter MXD = 10; // 60 ps mux delay
+
+parameter MXR1 = 10;
+
+
+
+/////////////////////////////////////////
+
+
+assign clkint = CLKDIV & SELFHEAL[4];
+
+assign error = (((~SELFHEAL[4] ^ SELFHEAL[3]) ^ dq3) | ((~SELFHEAL[4] ^ SELFHEAL[2]) ^ dq2) | ((~SELFHEAL[4] ^ SELFHEAL[1]) ^ dq1) | ((~SELFHEAL[4] ^ SELFHEAL[0]) ^ dq0));
+
+assign rst_in = (~SELFHEAL[4] | ~srint);
+
+assign rst_self_heal = (rst | ~shr);
+
+/////////////////////////////////////////
+// Reset Flop
+////////////////////////////////////////
+
+always @ (posedge clkint or posedge rst)
+begin
+ begin
+ if (rst)
+ begin
+ shr <= # FFD 1'b0;
+ end
+ else begin
+ shr <= #FFD rst_in;
+ end
+ end
+end
+
+// Self heal flop
+always @ (posedge clkint or posedge rst_self_heal)
+begin
+ begin
+
+ if (rst_self_heal)
+ begin
+ SHO <= 1'b0;
+ end
+ else
+ begin
+ SHO <= # FFD error;
+ end
+ end
+end
+
+
+
+
+endmodule
+`timescale 1ps/1ps
+////////////////////////////////////////////////////////
+//
+// module plg_oserdese1_vlog
+//
+////////////////////////////////////////////////////////
+//
+// Programmable Load Generator (PLG)
+// Divide by 2-8 counter with load enable output
+//
+//
+/////////////////////////////////////////////////////////
+//
+// Inputs:
+// c23: Selects between divide by 2 or 3
+// c45: Selects between divide by 4 or 5
+// c67: Selects between divide by 6 or 7
+// sel: Selects which divide function is chosen
+// 00:2 or 3, 01:4 or 5, 10:6 or 7, 11:8
+// clk: High speed clock from DCM
+// clkdiv: Low speed clock from DCM
+// rst: Reset
+//
+//
+//
+// Outputs:
+//
+// load: Loads serdes register at terminal count
+//
+//
+// Test attributes:
+// INIT_LOADCNT: 4-bits to init counter
+// SRTYPE: 1-bit to control synchronous or asynchronous operation
+// SELFHEAL: 5-bits to control self healing feature
+//
+//
+//
+////////////////////////////////////////////////////////////////////////////////
+//
+
+module plg_oserdese1_vlog (c23, c45, c67, sel,
+ clk, clkdiv, rst,
+ load, IOCLK_GLITCH);
+
+input c23, c45, c67;
+
+input [1:0] sel;
+
+input clk, clkdiv, rst;
+
+output load;
+
+output IOCLK_GLITCH;
+
+wire SRTYPE;
+wire [3:0] INIT_LOADCNT;
+wire [4:0] SELFHEAL;
+assign SRTYPE = 1'b1;
+assign INIT_LOADCNT = 4'b0000;
+assign SELFHEAL = 5'b00000;
+
+reg q0, q1, q2, q3;
+
+reg qhr, qlr;
+
+reg load, mux;
+
+wire cntrrst;
+
+
+assign cntrrst = IOCLK_GLITCH | rst;
+
+
+
+// Parameters for gate delays
+parameter ffdcnt = 1;
+parameter mxdcnt = 1;
+parameter FFRST = 145; // clock to out delay for flop in PLSG
+
+
+
+//////////////////////////////////////////////////
+
+tri0 GSR = glbl.GSR;
+
+always @(GSR)
+begin
+ if (GSR)
+ begin
+ force q3 = INIT_LOADCNT[3];
+ force q2 = INIT_LOADCNT[2];
+ force q1 = INIT_LOADCNT[1];
+ force q0 = INIT_LOADCNT[0];
+ end
+ else
+ begin
+ release q3;
+ release q2;
+ release q1;
+ release q0;
+ end
+end
+
+
+
+
+
+
+
+// flops for counter
+// asynchronous reset
+always @ (posedge qhr or posedge clk)
+begin
+ if (qhr & !SRTYPE)
+ begin
+ q0 <= # ffdcnt 1'b0;
+ q1 <= # ffdcnt 1'b0;
+ q2 <= # ffdcnt 1'b0;
+ q3 <= # ffdcnt 1'b0;
+ end
+ else if (!SRTYPE)
+ begin
+ q3 <= # ffdcnt q2;
+ q2 <= # ffdcnt (!(!q0 & !q2) & q1);
+ q1 <= # ffdcnt q0;
+ q0 <= # ffdcnt mux;
+ end
+end
+// synchronous reset
+always @ (posedge clk)
+begin
+ if (qhr & SRTYPE)
+ begin
+ q0 <= # ffdcnt 1'b0;
+ q1 <= # ffdcnt 1'b0;
+ q2 <= # ffdcnt 1'b0;
+ q3 <= # ffdcnt 1'b0;
+ end
+ else if (SRTYPE)
+ begin
+ q3 <= # ffdcnt q2;
+ q2 <= # ffdcnt (!(!q0 & !q2) & q1);
+ q1 <= # ffdcnt q0;
+ q0 <= # ffdcnt mux;
+ end
+end
+
+
+// mux settings for counter
+always @ (sel or c23 or c45 or c67 or q0 or q1 or q2 or q3)
+ begin
+ case (sel)
+ 2'b00: mux <= # mxdcnt (!q0 & !(c23 & q1));
+ 2'b01: mux <= # mxdcnt (!q1 & !(c45 & q2));
+ 2'b10: mux <= # mxdcnt (!q2 & !(c67 & q3));
+ 2'b11: mux <= # mxdcnt !q3;
+ default: mux <= # mxdcnt 1'b0;
+ endcase
+ end
+
+
+// mux decoding for load signal
+always @ (sel or c23 or c45 or c67 or q0 or q1 or q2 or q3)
+ begin
+ case (sel)
+ 2'b00: load <= # mxdcnt q0;
+ 2'b01: load <= # mxdcnt q0 & q1;
+ 2'b10: load <= # mxdcnt q0 & q2;
+ 2'b11: load <= # mxdcnt q0 & q3;
+ default: load <= # mxdcnt 1'b0;
+ endcase
+ end
+
+// flops to reset counter
+
+// Low speed flop
+// asynchronous reset
+always @ (posedge cntrrst or posedge clkdiv)
+ begin
+ if (cntrrst & !SRTYPE)
+ begin
+ qlr <= # FFRST 1'b1;
+ end
+ else if (!SRTYPE)
+ begin
+ qlr <= # FFRST 1'b0;
+ end
+ end
+// synchronous reset
+always @ (posedge clkdiv)
+ begin
+ if (cntrrst & SRTYPE)
+ begin
+ qlr <= # FFRST 1'b1;
+ end
+ else if (SRTYPE)
+ begin
+ qlr <= # FFRST 1'b0;
+ end
+ end
+
+
+
+// High speed flop
+// asynchronous reset
+always @ (posedge cntrrst or posedge clk)
+ begin
+ if (cntrrst & !SRTYPE)
+ begin
+ qhr <= # ffdcnt 1'b1;
+ end
+ else if (!SRTYPE)
+ begin
+ qhr <= # ffdcnt qlr;
+ end
+ end
+// synchronous reset
+always @ (posedge clk)
+ begin
+ if (cntrrst & SRTYPE)
+ begin
+ qhr <= # ffdcnt 1'b1;
+ end
+ else if (SRTYPE)
+ begin
+ qhr <= # ffdcnt qlr;
+ end
+ end
+
+selfheal_oserdese1_vlog fixcntr (.dq3(q3), .dq2(q2), .dq1(q1), .dq0(q0),
+ .CLKDIV(clkdiv), .srint(qlr), .rst(rst),
+ .SHO(IOCLK_GLITCH));
+endmodule
+`timescale 1ps/1ps
+////////////////////////////////////////////////////////
+//
+// module rank12d_oserdese1_vlog
+//
+//
+// This model ONLY works for SERDES operation!!
+// Does not include tristate circuit
+//
+//
+////////////////////////////////////////////////////////
+//
+// Inputs:
+// D1: Data input 1
+// D2: Data input 2
+// D3: Data input 3
+// D4: Data input 4
+// D5: Data input 5
+// D6: Data input 6
+// C: High speed clock from DCM
+// OCE: Clock enable for output data flops
+// SR: Set/Reset control. For the last 3 flops in OQ
+// (d1rnk2, d2rnk2 and d2nrnk2) this function is
+// controlled bythe attributes SRVAL_OQ. In SERDES mode,
+// SR is a RESET ONLY for all other flops! The flops will
+// still be RESET even if SR is programmed to a SET!
+// CLKDIV: Low speed divided clock from DCM
+// SHIFTIN1: Carry in data 1 for master from slave
+// SHIFTIN2: Carry in data 2 for master from slave
+//
+//
+//
+// Outputs:
+// data1: Data output mux for top flop
+// data2: Data output mux for bottom flop
+// SHIFTOUT1: Carry out data 1 for slave
+// SHIFTOUT2: Carry out data 2 for slave
+// load: Used for the tristate when combined into a single model
+//
+//
+//
+// Programmable Points
+// DATA_RATE_OQ: Rate control for data output, 1-bit
+// sdr (1), ddr (0)
+// DATA_WIDTH: Input data width,
+// 4-bits, values can be from 2 to 10
+// SERDES_MODE: Denotes master (0) or slave (1)
+// SIM_X_INPUT: This attribute is NOT SUPPORTED in this model!!!
+//
+//
+//
+// Programmable points for Test model
+// SRTYPE: This is a 4-bit field Sets asynchronous (0) or synchronous (1) set/reset
+// 1st bit (msb) sets rank1 flops, 2nd bit sets 4 flops in rank 2,
+// 3rd bit sets "3 legacy flops, and 4th (lsb) bit sets the counter
+// INIT_ORANK1: Init value for 6 registers in 1st rank (6-bits)
+// INIT_ORANK2_PARTIAL: Init value for bottom 4 registers in the 2nd rank (4-bits)
+// INIT_LOADCNT: Init value for the load counter (4-bits)
+// The other 2 registers in the load counter have init bits, but are
+// not supported in this model
+// SERDES: Indicates that SERDES mode is chosen
+// SLEFHEAL: 5-bit to set self heal circuit
+//
+//
+////////////////////////////////////////////////////////////////////////////////
+//
+
+module rank12d_oserdese1_vlog (D1, D2, D3, D4, D5, D6, d2rnk2,
+ SHIFTIN1, SHIFTIN2,
+ C, CLKDIV, SR, OCE,
+ data1, data2, SHIFTOUT1, SHIFTOUT2,
+ DATA_RATE_OQ, DATA_WIDTH,
+ SERDES_MODE, load,
+ IOCLK_GLITCH,
+ INIT_OQ, SRVAL_OQ);
+
+input D1, D2, D3, D4, D5, D6;
+
+input d2rnk2;
+
+input SHIFTIN1, SHIFTIN2;
+
+input C, CLKDIV, SR, OCE;
+
+input INIT_OQ, SRVAL_OQ;
+
+output data1, data2;
+
+output SHIFTOUT1, SHIFTOUT2;
+
+output load;
+
+output IOCLK_GLITCH;
+
+// Programmable Points
+
+input DATA_RATE_OQ;
+
+input [3:0] DATA_WIDTH;
+
+input SERDES_MODE;
+
+wire DDR_CLK_EDGE, SERDES;
+wire [3:0] SRTYPE;
+wire [4:0] SELFHEAL;
+
+wire [3:0] INIT_ORANK2_PARTIAL;
+wire [5:0] INIT_ORANK1;
+
+assign DDR_CLK_EDGE = 1'b1;
+assign SERDES = 1'b1;
+assign SRTYPE = 4'b1111;
+assign SELFHEAL = 5'b00000;
+
+assign INIT_ORANK2_PARTIAL = 4'b0000;
+assign INIT_ORANK1 = 6'b000000;
+
+reg d1r, d2r, d3r, d4r, d5r, d6r;
+
+reg d3rnk2, d4rnk2, d5rnk2, d6rnk2;
+
+reg data1, data2, data3, data4, data5, data6;
+
+reg ddr_data, odata_edge, sdata_edge;
+
+reg c23, c45, c67;
+
+reg [1:0] sel;
+
+wire C2p, C3;
+
+wire loadint;
+
+wire [3:0] seloq;
+
+wire oqsr, oqrev;
+
+wire [2:0] sel1_4;
+
+wire [3:0] sel5_6;
+
+wire [4:0] plgcnt;
+
+assign C2p = (C & DDR_CLK_EDGE) | (!C & !DDR_CLK_EDGE);
+
+assign C3 = !C2p;
+
+assign plgcnt = {DATA_RATE_OQ,DATA_WIDTH};
+
+assign sel1_4 = {SERDES,loadint,DATA_RATE_OQ};
+
+assign sel5_6 = {SERDES,SERDES_MODE,loadint,DATA_RATE_OQ};
+
+assign load = loadint;
+
+assign seloq = {OCE,DATA_RATE_OQ,oqsr,oqrev};
+
+assign oqsr = !SRTYPE[1] & SR & !SRVAL_OQ;
+
+assign oqrev = !SRTYPE[1] & SR & SRVAL_OQ;
+
+
+
+//////////////////////////////////////////////////
+// Delay values
+//
+parameter FFD = 1; // clock to out delay for flip flops
+// driven by clk
+parameter FFCD = 1; // clock to out delay for flip flops
+// driven by clkdiv
+parameter MXD = 1; // 60 ps mux delay
+
+parameter MXR1 = 1;
+
+////////////////////////////////////////////
+// Initialization of flops with GSR for test model
+///////////////////////////////////////////
+
+tri0 GSR = glbl.GSR;
+
+always @(GSR)
+begin
+ if (GSR)
+ begin
+ force d6rnk2 = INIT_ORANK2_PARTIAL[3];
+ force d5rnk2 = INIT_ORANK2_PARTIAL[2];
+ force d4rnk2 = INIT_ORANK2_PARTIAL[1];
+ force d3rnk2 = INIT_ORANK2_PARTIAL[0];
+
+ force d6r = INIT_ORANK1[5];
+ force d5r = INIT_ORANK1[4];
+ force d4r = INIT_ORANK1[3];
+ force d3r = INIT_ORANK1[2];
+ force d2r = INIT_ORANK1[1];
+ force d1r = INIT_ORANK1[0];
+ end
+ else
+ begin
+ release d6rnk2;
+ release d5rnk2;
+ release d4rnk2;
+ release d3rnk2;
+ release d6r;
+ release d5r;
+ release d4r;
+ release d3r;
+ release d2r;
+ release d1r;
+ end
+end
+
+/////////////////////////////////////////
+
+
+
+// Assign shiftout1 and shiftout2
+
+assign SHIFTOUT1 = d3rnk2 & SERDES_MODE;
+
+assign SHIFTOUT2 = d4rnk2 & SERDES_MODE;
+
+
+
+
+
+
+// last 4 flops which only have reset and init
+// asynchronous operation
+always @ (posedge C or posedge SR)
+begin
+ begin
+ if (SR & !SRTYPE[2])
+ begin
+ d3rnk2 <= # FFD 1'b0;
+ d4rnk2 <= # FFD 1'b0;
+ d5rnk2 <= # FFD 1'b0;
+ d6rnk2 <= # FFD 1'b0;
+ end
+ else if (!SRTYPE[2])
+ begin
+ d3rnk2 <= # FFD data3;
+ d4rnk2 <= # FFD data4;
+ d5rnk2 <= # FFD data5;
+ d6rnk2 <= # FFD data6;
+
+ end
+ end
+end
+// synchronous operation
+always @ (posedge C)
+begin
+ begin
+ if (SR & SRTYPE[2])
+ begin
+ d3rnk2 <= # FFD 1'b0;
+ d4rnk2 <= # FFD 1'b0;
+ d5rnk2 <= # FFD 1'b0;
+ d6rnk2 <= # FFD 1'b0;
+ end
+ else if (SRTYPE[2])
+ begin
+ d3rnk2 <= # FFD data3;
+ d4rnk2 <= # FFD data4;
+ d5rnk2 <= # FFD data5;
+ d6rnk2 <= # FFD data6;
+
+ end
+ end
+end
+
+
+
+
+
+
+
+///////////////////////////////////////////////////
+// First rank of flops for input data
+//////////////////////////////////////////////////
+
+// asynchronous operation
+always @ (posedge CLKDIV or posedge SR)
+begin
+ begin
+ if (SR & !SRTYPE[3])
+ begin
+ d1r <= # FFCD 1'b0;
+ d2r <= # FFCD 1'b0;
+ d3r <= # FFCD 1'b0;
+ d4r <= # FFCD 1'b0;
+ d5r <= # FFCD 1'b0;
+ d6r <= # FFCD 1'b0;
+ end
+ else if (!SRTYPE[3])
+ begin
+ d1r <= # FFCD D1;
+ d2r <= # FFCD D2;
+ d3r <= # FFCD D3;
+ d4r <= # FFCD D4;
+ d5r <= # FFCD D5;
+ d6r <= # FFCD D6;
+
+ end
+ end
+end
+// synchronous operation
+always @ (posedge CLKDIV)
+begin
+ begin
+ if (SR & SRTYPE[3])
+ begin
+ d1r <= # FFCD 1'b0;
+ d2r <= # FFCD 1'b0;
+ d3r <= # FFCD 1'b0;
+ d4r <= # FFCD 1'b0;
+ d5r <= # FFCD 1'b0;
+ d6r <= # FFCD 1'b0;
+ end
+ else if (SRTYPE[3])
+ begin
+ d1r <= # FFCD D1;
+ d2r <= # FFCD D2;
+ d3r <= # FFCD D3;
+ d4r <= # FFCD D4;
+ d5r <= # FFCD D5;
+ d6r <= # FFCD D6;
+
+ end
+ end
+end
+
+// Muxs for 2nd rank of flops
+always @ (sel1_4 or d1r or d2rnk2 or d3rnk2)
+ begin
+
+ casex (sel1_4)
+ 3'b100: data1 <= # MXR1 d3rnk2;
+ 3'b110: data1 <= # MXR1 d1r;
+ 3'b101: data1 <= # MXR1 d2rnk2;
+ 3'b111: data1 <= # MXR1 d1r;
+ default: data1 <= # MXR1 d3rnk2;
+ endcase
+ end
+
+always @ (sel1_4 or d2r or d3rnk2 or d4rnk2)
+ begin
+ casex (sel1_4)
+ 3'b100: data2 <= # MXR1 d4rnk2;
+ 3'b110: data2 <= # MXR1 d2r;
+ 3'b101: data2 <= # MXR1 d3rnk2;
+ 3'b111: data2 <= # MXR1 d2r;
+ default: data2 <= # MXR1 d4rnk2;
+ endcase
+ end
+
+//Note: To stop data rate of 00 from being illegal, register data is fed to mux
+always @ (sel1_4 or d3r or d4rnk2 or d5rnk2)
+ begin
+ casex (sel1_4)
+ 3'b100: data3 <= # MXR1 d5rnk2;
+ 3'b110: data3 <= # MXR1 d3r;
+ 3'b101: data3 <= # MXR1 d4rnk2;
+ 3'b111: data3 <= # MXR1 d3r;
+ default: data3 <= # MXR1 d5rnk2;
+ endcase
+ end
+
+always @ (sel1_4 or d4r or d5rnk2 or d6rnk2)
+ begin
+ casex (sel1_4)
+ 3'b100: data4 <= # MXR1 d6rnk2;
+ 3'b110: data4 <= # MXR1 d4r;
+ 3'b101: data4 <= # MXR1 d5rnk2;
+ 3'b111: data4 <= # MXR1 d4r;
+ default: data4 <= # MXR1 d6rnk2;
+ endcase
+ end
+
+always @ (sel5_6 or d5r or d6rnk2 or SHIFTIN1)
+ begin
+ casex (sel5_6)
+ 4'b1000: data5 <= # MXR1 SHIFTIN1;
+ 4'b1010: data5 <= # MXR1 d5r;
+ 4'b1001: data5 <= # MXR1 d6rnk2;
+ 4'b1011: data5 <= # MXR1 d5r;
+ 4'b1100: data5 <= # MXR1 1'b0;
+ 4'b1110: data5 <= # MXR1 d5r;
+ 4'b1101: data5 <= # MXR1 d6rnk2;
+ 4'b1111: data5 <= # MXR1 d5r;
+ default: data5 <= # MXR1 SHIFTIN1;
+ endcase
+ end
+
+always @ (sel5_6 or D6 or d6r or SHIFTIN1 or SHIFTIN2)
+ begin
+ casex (sel5_6)
+ 4'b1000: data6 <= # MXR1 SHIFTIN2;
+ 4'b1010: data6 <= # MXR1 d6r;
+ 4'b1001: data6 <= # MXR1 SHIFTIN1;
+ 4'b1011: data6 <= # MXR1 d6r;
+ 4'b1100: data6 <= # MXR1 1'b0;
+ 4'b1110: data6 <= # MXR1 d6r;
+ 4'b1101: data6 <= # MXR1 1'b0;
+ 4'b1111: data6 <= # MXR1 d6r;
+ default: data6 <= # MXR1 SHIFTIN2;
+ endcase
+ end
+
+
+
+
+// instantiate programmable load generator
+plg_oserdese1_vlog ldgen (.c23(c23), .c45(c45), .c67(c67), .sel(sel),
+ .clk(C), .clkdiv(CLKDIV), .rst(SR),
+ .load(loadint), .IOCLK_GLITCH(IOCLK_GLITCH));
+
+// Set value of counter in programmable load generator
+always @ (plgcnt or c23 or c45 or c67 or sel)
+begin
+ casex (plgcnt)
+ 5'b00100: begin c23=1'b0; c45=1'b0; c67=1'b0; sel=2'b00; end
+ 5'b00110: begin c23=1'b1; c45=1'b0; c67=1'b0; sel=2'b00; end
+ 5'b01000: begin c23=1'b0; c45=1'b0; c67=1'b0; sel=2'b01; end
+ 5'b01010: begin c23=1'b0; c45=1'b1; c67=1'b0; sel=2'b01; end
+ 5'b10010: begin c23=1'b0; c45=1'b0; c67=1'b0; sel=2'b00; end
+ 5'b10011: begin c23=1'b1; c45=1'b0; c67=1'b0; sel=2'b00; end
+ 5'b10100: begin c23=1'b0; c45=1'b0; c67=1'b0; sel=2'b01; end
+ 5'b10101: begin c23=1'b0; c45=1'b1; c67=1'b0; sel=2'b01; end
+ 5'b10110: begin c23=1'b0; c45=1'b0; c67=1'b0; sel=2'b10; end
+ 5'b10111: begin c23=1'b0; c45=1'b0; c67=1'b1; sel=2'b10; end
+ 5'b11000: begin c23=1'b0; c45=1'b0; c67=1'b0; sel=2'b11; end
+ default: $display("DATA_WIDTH %b and DATA_RATE_OQ %b at %t is an illegal value", DATA_WIDTH, DATA_RATE_OQ, $time);
+ endcase
+end
+
+endmodule
+`timescale 1ps/1ps
+//////////////////////////////////////////////////////////
+//
+// module trif_oserdese1_vlog
+//
+/////////////////////////////////////////////////////////
+//
+// Inputs:
+//
+// T1, T2, T3, T4: tristate inputs
+// load: Programmable load generator output
+// TCE: Tristate clock enable
+// SR: Set/Reset control. For the last 3 flops in TQ
+// (qt1, qt2 and qt2n) this function is
+// controlled bythe attributes SRVAL_TQ. In SERDES mode,
+// SR is a RESET ONLY for all other flops! The flops will
+// still be RESET even if SR is programmed to a SET!
+// C, C2: High speed clocks
+// C2 drives 2nd latch and C3 (inverse of C2) drives
+// 3rd latch in output section
+// CLKDIV: Low speed clock
+//
+//
+//
+//
+// Outputs:
+//
+// TQ: Output of tristate mux
+//
+//
+// Programmable Options:
+//
+// DATA_RATE_TQ: 2-bit field for types of operaiton
+// 0 (buf from T1), 1 (registered output from T1), 2 (ddr)
+// TRISTATE_WIDTH: 2-bit field for input width
+// 0 (width 1), 1 (width 2), 2 (width 4)
+// INIT_TQ: Init TQ output (0,1)
+// SRVAL_TQ: This bit to controls value of SR input.
+// Only the last 3 flops (qt1, qt2 and qt2n) are
+// affected by this bit.For SERDES mode, this bit
+// should be set to '0' making SR a reset. This is the
+// desired state since all other flops only
+// respond to this pin as a reset. Their function
+// cannot be changed. SR is 'O' for SET and '1' for RESET.
+//
+//
+// Programmable Test Options:
+// SRTYPE: Control S and R as asynchronous (0) or synchronous (1)
+// 2-bit value. 1st bit (msb) controls the 4 input flops
+// and the 2nd bit (lsb) controls the "3 legacy flops"
+// DDR_CLK_EDGE: Same or opposite edge operation
+//
+//
+//
+////////////////////////////////////////////////////////////////////////////////
+//
+
+module trif_oserdese1_vlog (T1, T2, T3, T4, load,
+ C, CLKDIV, SR, TCE,
+ DATA_RATE_TQ, TRISTATE_WIDTH,
+ INIT_TQ, SRVAL_TQ,
+ data1, data2);
+
+input T1, T2, T3, T4, load;
+
+input C, CLKDIV, SR, TCE;
+
+input [1:0] TRISTATE_WIDTH;
+
+input [1:0] DATA_RATE_TQ;
+
+input INIT_TQ, SRVAL_TQ;
+
+output data1, data2;
+
+wire DDR_CLK_EDGE;
+wire [3:0] INIT_TRANK1;
+wire [1:0] SRTYPE;
+assign SRTYPE = 2'b11;
+assign DDR_CLK_EDGE = 1'b1;
+assign INIT_TRANK1 = 4'b0000;
+
+reg t1r, t2r, t3r, t4r;
+
+reg qt1, qt2, qt2n;
+
+reg data1, data2;
+
+reg sdata_edge, odata_edge, ddr_data;
+
+wire C2p, C3;
+
+wire load;
+
+wire [6:0] tqsel;
+
+wire [4:0] sel;
+
+assign sel = {load,DATA_RATE_TQ,TRISTATE_WIDTH};
+
+
+
+
+
+//////////////////////////////////////////////////
+
+
+// Parameters for gate delays
+parameter ffd = 1;
+parameter mxd = 1;
+
+
+/////////////////////////////
+// Initialization of Flops
+////////////////////////////
+
+tri0 GSR = glbl.GSR;
+
+always @(GSR)
+begin
+ if (GSR)
+ begin
+ force t1r = INIT_TRANK1[0];
+ force t2r = INIT_TRANK1[1];
+ force t3r = INIT_TRANK1[2];
+ force t4r = INIT_TRANK1[3];
+
+ end
+ else
+ begin
+ release t1r;
+ release t2r;
+ release t3r;
+ release t4r;
+ end
+end
+
+
+
+
+// First rank of flops
+// asynchronous reset operation
+always @ (posedge CLKDIV or posedge SR)
+begin
+ begin
+ if (SR & !SRTYPE[1])
+ begin
+ t1r <= # ffd 1'b0;
+ t2r <= # ffd 1'b0;
+ t3r <= # ffd 1'b0;
+ t4r <= # ffd 1'b0;
+ end
+ else if (!SRTYPE[1])
+ begin
+ t1r <= # ffd T1;
+ t2r <= # ffd T2;
+ t3r <= # ffd T3;
+ t4r <= # ffd T4;
+ end
+ end
+end
+
+// synchronous reset operation
+always @ (posedge CLKDIV)
+begin
+ begin
+ if (SR & SRTYPE[1])
+ begin
+ t1r <= # ffd 1'b0;
+ t2r <= # ffd 1'b0;
+ t3r <= # ffd 1'b0;
+ t4r <= # ffd 1'b0;
+ end
+ else if (SRTYPE[1])
+ begin
+ t1r <= # ffd T1;
+ t2r <= # ffd T2;
+ t3r <= # ffd T3;
+ t4r <= # ffd T4;
+ end
+ end
+end
+
+
+
+
+
+// Data Muxs for tristate otuput signals
+always @ (sel or T1 or t1r or t3r)
+ begin
+
+ casex (sel)
+ 5'b00000: data1 <= # mxd T1;
+ 5'b10000: data1 <= # mxd T1;
+ 5'bX0000: data1 <= # mxd T1;
+ 5'b00100: data1 <= # mxd T1;
+ 5'b10100: data1 <= # mxd T1;
+ 5'bX0100: data1 <= # mxd T1;
+ 5'b01001: data1 <= # mxd T1;
+ 5'b11001: data1 <= # mxd T1;
+ 5'b01010: data1 <= # mxd t3r;
+ 5'b11010: data1 <= # mxd t1r;
+// CR 551953 -- enabled TRISTATE_WIDTH to be 1 in DDR mode. No func change, but removed warnings
+ 5'b01000: ;
+ 5'b11000: ;
+ 5'bX1000: ;
+
+ default:
+ begin
+ $display("DATA_RATE_TQ %b and/or TRISTATE_WIDTH %b at time %t are not supported by OSERDES", DATA_RATE_TQ,TRISTATE_WIDTH,$time);
+ $display("1.sel= %b",sel);
+ end
+ endcase
+ end
+// For data 2, width of 1 is inserted as acceptable for buf and sdr
+// The capability exists in the device if the feature is added
+always @ (sel or T2 or t2r or t4r)
+ begin
+ casex (sel)
+ 5'b00000: data2 <= # mxd T2;
+ 5'b00100: data2 <= # mxd T2;
+ 5'b10000: data2 <= # mxd T2;
+ 5'b10100: data2 <= # mxd T2;
+ 5'bX0000: data2 <= # mxd T2;
+ 5'bX0100: data2 <= # mxd T2;
+ 5'b00X00: data2 <= # mxd T2;
+ 5'b10X00: data2 <= # mxd T2;
+ 5'bX0X00: data2 <= # mxd T2;
+ 5'b01001: data2 <= # mxd T2;
+ 5'b11001: data2 <= # mxd T2;
+ 5'bX1001: data2 <= # mxd T2;
+ 5'b01010: data2 <= # mxd t4r;
+ 5'b11010: data2 <= # mxd t2r;
+// CR 551953 -- enabled TRISTATE_WIDTH to be 1 in DDR mode. No func change, but removed warnings
+ 5'b01000: ;
+ 5'b11000: ;
+ 5'bX1000: ;
+
+ default:
+ begin
+ $display("DATA_RATE_TQ %b and/or TRISTATE_WIDTH %b at time %t are not supported by OSERDES", DATA_RATE_TQ,TRISTATE_WIDTH,$time);
+ $display("2.sel= %b",sel);
+ end
+ endcase
+ end
+
+
+endmodule
+`timescale 1ps/1ps
+//////////////////////////////////////////////////////////
+//
+// module txbuffer_oserdese1_vlog
+//
+/////////////////////////////////////////////////////////
+//
+// FIFO and Control circuit for OSERDES
+
+module txbuffer_oserdese1_vlog (iodelay_state, qmux1, qmux2, tmux1, tmux2,
+ d1, d2, t1, t2, trif,
+ WC, ODV, extra,
+ clk, clkdiv, bufo, bufop, rst,
+ ODELAY_USED, DDR3_DATA,
+ DDR3_MODE);
+
+input d1, d2, t1, t2;
+
+input trif;
+
+input WC, ODV;
+
+input rst;
+
+input clk, clkdiv, bufo, bufop;
+
+input ODELAY_USED, DDR3_DATA;
+
+input DDR3_MODE;
+
+output iodelay_state, extra;
+
+output qmux1, qmux2, tmux1, tmux2;
+
+wire WC_DELAY;
+assign WC_DELAY = 1'b0;
+
+wire rd_gap1;
+
+wire rst_bufo_p, rst_bufg_p;
+
+
+wire rst_bufo_rc, rst_bufg_wc, rst_cntr, rst_bufop_rc;
+
+wire [1:0] qwc, qrd;
+
+wire bufo_out;
+
+
+fifo_tdpipe_oserdese1_vlog data1 (.muxout(inv_qmux1), .din(~d1), .qwc(qwc), .qrd(qrd),
+ .rd_gap1(rd_gap1),
+ .bufg_clk(clk), .bufo_clk(bufo), .rst_bufo_p(rst_bufo_p), .rst_bufg_p(rst_bufg_p),
+ .DDR3_DATA(DDR3_DATA), .extra(extra), .ODV(ODV), .DDR3_MODE(DDR3_MODE)
+
+ );
+
+fifo_tdpipe_oserdese1_vlog data2 (.muxout(inv_qmux2), .din(~d2), .qwc(qwc), .qrd(qrd),
+ .rd_gap1(rd_gap1),
+ .bufg_clk(clk), .bufo_clk(bufo), .rst_bufo_p(rst_bufo_p), .rst_bufg_p(rst_bufg_p),
+ .DDR3_DATA(DDR3_DATA), .extra(extra), .ODV(ODV), .DDR3_MODE(DDR3_MODE)
+
+ );
+
+fifo_tdpipe_oserdese1_vlog tris1 (.muxout(inv_tmux1), .din(~t1), .qwc(qwc), .qrd(qrd),
+ .rd_gap1(rd_gap1),
+ .bufg_clk(clk), .bufo_clk(bufo), .rst_bufo_p(rst_bufo_p), .rst_bufg_p(rst_bufg_p),
+ .DDR3_DATA(DDR3_DATA), .extra(extra), .ODV(ODV), .DDR3_MODE(DDR3_MODE)
+
+ );
+
+fifo_tdpipe_oserdese1_vlog tris2 (.muxout(inv_tmux2), .din(~t2), .qwc(qwc), .qrd(qrd),
+ .rd_gap1(rd_gap1),
+ .bufg_clk(clk), .bufo_clk(bufo), .rst_bufo_p(rst_bufo_p), .rst_bufg_p(rst_bufg_p),
+ .DDR3_DATA(DDR3_DATA), .extra(extra), .ODV(ODV), .DDR3_MODE(DDR3_MODE)
+
+ );
+
+wire qmux1 = ~inv_qmux1;
+wire qmux2 = ~inv_qmux2;
+wire tmux1 = ~inv_tmux1;
+wire tmux2 = ~inv_tmux2;
+
+fifo_reset_oserdese1_vlog rstckt (.rst_bufo_p(rst_bufo_p), .rst_bufo_rc(rst_bufo_rc),
+ .rst_bufg_p(rst_bufg_p), .rst_bufg_wc(rst_bufg_wc),
+ .rst_cntr(rst_cntr),
+ .bufg_clk(clk), .bufo_clk(bufo), .clkdiv(clkdiv), .rst(rst),
+ .divide_2(WC_DELAY), .bufop_clk(bufop), .rst_bufop_rc(rst_bufop_rc)
+
+ );
+
+
+
+
+fifo_addr_oserdese1_vlog addcntr (.qwc(qwc), .qrd(qrd), .rd_gap1(rd_gap1), .rst_bufg_wc(rst_bufg_wc), .rst_bufo_rc(rst_bufo_rc), .bufg_clk(clk), .bufo_clk(bufo),
+ .data(DDR3_DATA), .extra(extra), .rst_bufop_rc(rst_bufop_rc), .bufop_clk(bufop)
+
+ );
+
+
+
+iodlyctrl_npre_oserdese1_vlog idlyctrl (.iodelay_state(iodelay_state), .bufo_out(bufo_out), .rst_cntr(rst_cntr),
+ .wc(WC), .trif(trif),
+ .rst(rst_bufg_p), .bufg_clk(clk), .bufo_clk(bufo), .bufg_clkdiv(clkdiv),
+ .ddr3_dimm(ODELAY_USED), .wl6(WC_DELAY)
+ );
+
+endmodule
+`timescale 1ps/1ps
+////////////////////////////////////////////////////////
+//
+// module fifo_tdpipe_oserdese1_vlog
+//
+////////////////////////////////////////////////////////
+
+// FIFO for write path
+
+module fifo_tdpipe_oserdese1_vlog (muxout, din, qwc, qrd,
+ rd_gap1,
+ bufg_clk, bufo_clk, rst_bufo_p, rst_bufg_p,
+ DDR3_DATA, extra, ODV, DDR3_MODE
+
+ );
+
+
+input din;
+
+input [1:0] qwc, qrd;
+
+input rd_gap1;
+
+input rst_bufo_p, rst_bufg_p;
+
+input bufg_clk, bufo_clk;
+
+input DDR3_DATA, ODV;
+
+input extra;
+
+input DDR3_MODE;
+
+output muxout;
+
+
+reg muxout;
+
+reg qout1, qout2;
+
+reg qout_int, qout_int2;
+
+reg [4:1] fifo;
+
+reg cin1;
+
+reg omux;
+
+wire [2:0] sel;
+
+reg pipe1, pipe2;
+
+wire selqoi, selqoi2;
+
+wire [2:0] selmuxout;
+
+
+
+
+
+
+// 4 flops that make up the basic FIFO. They are all clocked
+// off of fast BUFG. The first flop is the top flop in the chain.
+// The CE input is used to mux the inputs. If the flop is selected,
+// CE is high and it takes data from the output of the mux. If the
+// flop is not selected, it retains its data.
+
+always @ (posedge bufg_clk or posedge rst_bufg_p)
+ begin
+ if (rst_bufg_p)
+ begin
+ fifo <= #10 4'b0000;
+ end
+ else if (!qwc[1] & !qwc[0])
+ begin
+ fifo <= #10 {fifo[4:2],din};
+ end
+ else if (!qwc[1] & qwc[0])
+ begin
+ fifo <= #10 {fifo[4:3],din,fifo[1]};
+ end
+ else if (qwc[1] & qwc[0])
+ begin
+ fifo <= #10 {fifo[4],din,fifo[2:1]};
+ end
+ else if (qwc[1] & !qwc[0])
+ begin
+ fifo <= #10 {din,fifo[3:1]};
+ end
+ end
+
+
+
+// Capture stage top
+// This is the top flop of the "3 flops" for ODDR. This flop, along with the read
+// counter will be clocked off of bufo. A 4:1 mux wil decode the outputs of the
+// read counter and load the write data. A subsequent 2:1 mux will decode between
+// the fifo and the legacy operation
+
+
+// OMUX
+
+always @ (qrd or fifo)
+ begin
+ case (qrd)
+ 2'b00: omux <= #10 fifo[1];
+ 2'b01: omux <= #10 fifo[2];
+ 2'b10: omux <= #10 fifo[4];
+ 2'b11: omux <= #10 fifo[3];
+ default: omux <= #10 fifo[1];
+ endcase
+ end
+
+
+always @ (posedge bufo_clk or posedge rst_bufo_p)
+ begin
+ if (rst_bufo_p)
+ begin
+ qout_int <= #10 1'b0;
+ qout_int2 <= #10 1'b0;
+ end
+ else
+ begin
+ qout_int <= #10 omux;
+ qout_int2 <= #10 qout_int;
+ end
+ end
+
+assign #10 selqoi = ODV | rd_gap1;
+
+
+always @ (selqoi or qout_int or omux)
+ begin
+ case(selqoi)
+ 1'b0: qout1 <= #10 omux;
+ 1'b1: qout1 <= #10 qout_int;
+ default: qout1 <= #10 omux;
+ endcase
+ end
+
+assign #10 selqoi2 = ODV & rd_gap1;
+
+always @ (selqoi2 or qout_int2 or qout_int)
+ begin
+ case(selqoi2)
+ 1'b0: qout2 <= #10 qout_int;
+ 1'b1: qout2 <= #10 qout_int2;
+ default qout2 <= #10 qout_int;
+ endcase
+ end
+
+
+assign #14 selmuxout = {DDR3_MODE,DDR3_DATA,extra};
+
+
+always @ (selmuxout or din or omux or qout1 or qout2)
+ begin
+ case (selmuxout)
+ 3'b000: muxout = #1 din;
+ 3'b001: muxout = #1 din;
+ 3'b010: muxout = #1 din;
+ 3'b011: muxout = #1 din;
+ 3'b100: muxout = #1 omux;
+ 3'b101: muxout = #1 omux;
+ 3'b110: muxout = #1 qout1;
+ 3'b111: muxout = #1 qout2;
+ default: muxout = #10 din;
+ endcase
+ end
+
+
+
+endmodule
+`timescale 1ps/1ps
+////////////////////////////////////////////////////////
+//
+// module fifo_reset_oserdese1_vlog
+//
+////////////////////////////////////////////////////////
+//
+// TX FIFO reset
+//
+// This design performs 2 functions. One function is to reset all the
+// flops in the TX FIFO. The other function is to respond to the signal
+// rst_cntr. This signal comes from iodlyctrl and will be used to initiate an
+// orderly transition to switch the DQ/DQS I/O from and read to a write.
+// This process is required only for DDR3 DIMM support because the IODELAY
+// is used for both the inputs and the outputs. The signal from the
+// squelch circuit is a present fabric output. An additional input
+// indicating that a write command was issued will be
+// required for all I/O to support this signal.
+//
+// This design uses an asynchronous reset to reset all flops. After the
+// reset is disabled, a 0 is propagated through the pipe stages to terminate
+// the reset. The first 2 flops run off of the clkdiv domain. Their output
+// feeds a latch to cross between the clkdiv and bufg_clk domain. The pipe
+// stage for the bufg_clk domain is 3 deep, where the last flop is the
+// reset signal for the bufg_clk domain. The 2nd flop of the bufg_clk pipe
+// is fed to 2 flops that are in the bufo_clk domain. The 2 flops are
+// to resolve metastability between the 2 clock domains.
+//
+// The circuit to enable an orderly transition from read to write uses the
+// PREAMBLE_SYNCHED output of a portion of the squelch circuit. This pulse
+// will initiate the reset sequence and also generate an enable which will
+// switch the IODELAY from an IDELAY to an ODELAY. Timing is as specified in
+// the "State of the Union" presentation.
+//
+//
+
+
+module fifo_reset_oserdese1_vlog (rst_bufo_p, rst_bufo_rc,
+ rst_bufg_p, rst_bufg_wc,
+ rst_cntr,
+ bufg_clk, bufo_clk, clkdiv, rst,
+ divide_2, bufop_clk, rst_bufop_rc
+
+ );
+
+
+input rst_cntr;
+
+input rst;
+
+input bufg_clk, bufo_clk, clkdiv;
+
+input bufop_clk;
+
+
+// Memory cell input to support divide by 1 operation
+input divide_2;
+
+
+output rst_bufo_p, rst_bufo_rc;
+output rst_bufg_p, rst_bufg_wc;
+
+output rst_bufop_rc;
+
+
+reg [1:0] clkdiv_pipe;
+
+reg bufg_pipe;
+
+reg rst_cntr_reg;
+
+reg [2:0] bufo_rst_p, bufo_rst_rc;
+
+reg [1:0] bufop_rst_rc;
+
+reg [1:0] bufg_rst_p, bufg_rst_wc;
+
+wire bufg_clkdiv_latch, ltint1, ltint2, ltint3;
+
+wire latch_in;
+
+
+
+
+
+
+
+// 2 stage pipe for clkdiv domain to allow user to properly
+// time everything
+
+
+always @ (posedge bufg_clk or posedge rst)
+ begin
+ if (rst)
+ begin
+ rst_cntr_reg <= #10 1'b0;
+ end
+ else
+ begin
+ rst_cntr_reg <= #10 rst_cntr;
+ end
+ end
+
+
+always @ (posedge clkdiv or posedge rst)
+ begin
+ if (rst)
+ begin
+ clkdiv_pipe <= #10 2'b11;
+ end
+ else
+ begin
+ clkdiv_pipe <= #10 {clkdiv_pipe[0],1'b0};
+ end
+ end
+
+// Latch to compensate for clkdiv and bufg_clk clock skew
+// Built of actual gates
+
+assign #1 latch_in = clkdiv_pipe[1];
+
+assign #1 bufg_clkdiv_latch = !(ltint1 && ltint3);
+assign #1 ltint1 = !(latch_in && bufg_clk);
+assign #1 ltint2 = !(ltint1 && bufg_clk);
+assign #1 ltint3 = !(bufg_clkdiv_latch && ltint2);
+
+
+
+
+
+// BUFG flop to register latch signal
+always @ (posedge bufg_clk or posedge rst)
+ begin
+ if (rst)
+ begin
+ bufg_pipe <= #10 1'b1;
+ end
+ else
+ begin
+ bufg_pipe <= #10 bufg_clkdiv_latch;
+ end
+ end
+
+
+
+
+// BUFG clock domain resests
+
+always @ (posedge bufg_clk or posedge rst)
+ begin
+ if (rst)
+ begin
+ bufg_rst_p <= #10 2'b11;
+ end
+ else
+ begin
+ bufg_rst_p <= #10 {bufg_rst_p[0],bufg_pipe};
+ end
+ end
+
+
+always @ (posedge bufg_clk or posedge rst_cntr or posedge rst)
+ begin
+ if (rst || rst_cntr)
+ begin
+ bufg_rst_wc <= #10 2'b11;
+ end
+ else
+ begin
+ bufg_rst_wc <= #10 {bufg_rst_wc[0],bufg_pipe};
+ end
+ end
+
+
+
+// BUFO clock domain Resets
+always @ (posedge bufo_clk or posedge rst)
+ begin
+ if (rst)
+ begin
+ bufo_rst_p <= #10 3'b111;
+ end
+ else
+ begin
+ bufo_rst_p <= #10 {bufo_rst_p[1:0],bufg_pipe};
+ end
+ end
+
+always @ (posedge bufo_clk or posedge rst or posedge rst_cntr)
+ begin
+ if (rst || rst_cntr)
+ begin
+ bufo_rst_rc <= #10 3'b111;
+ end
+ else
+ begin
+ bufo_rst_rc <= #10 {bufo_rst_rc[1:0],bufg_pipe};
+ end
+ end
+
+
+
+always @ (posedge bufop_clk or posedge rst or posedge rst_cntr)
+ begin
+ if (rst || rst_cntr)
+ begin
+ bufop_rst_rc <= #10 2'b11;
+ end
+ else
+ begin
+ bufop_rst_rc <= #10 {bufop_rst_rc[0],bufg_pipe};
+ end
+ end
+
+
+// final reset assignments
+assign rst_bufo_rc = bufo_rst_rc[1];
+
+assign rst_bufo_p = bufo_rst_p[1];
+
+assign rst_bufop_rc = bufop_rst_rc[1];
+
+assign rst_bufg_wc = bufg_rst_wc[1];
+
+assign rst_bufg_p = bufg_rst_p[1];
+
+
+endmodule
+`timescale 1ps/1ps
+////////////////////////////////////////////////////////
+//
+// module fifo_addr_oserdese1_vlog
+//
+////////////////////////////////////////////////////////
+// Read and Write address generators for TX FIFO
+//
+// This circuit contains 2 greycode read and write address generators
+// that will be used with the TX FIFO. Both counters generate a
+// count sequence of 00 -> 01 -> 11 -> 10 -> 00.
+
+
+
+module fifo_addr_oserdese1_vlog (qwc, qrd, rd_gap1, rst_bufg_wc, rst_bufo_rc, bufg_clk, bufo_clk,
+ data, extra, rst_bufop_rc, bufop_clk
+
+ );
+
+
+input bufg_clk, bufo_clk;
+
+input rst_bufo_rc, rst_bufg_wc;
+
+input rst_bufop_rc;
+
+input data; // mc to tell if I/O is DDR3 DQ or DQS
+
+input bufop_clk;
+
+output [1:0]qwc, qrd; // Scalar port ``qwc'' has a vectored net declaration [1:0]
+
+output rd_gap1, extra;
+
+
+
+
+reg [1:0] qwc; // unisims/OSERDESE1.v:2073 error: Scalar port ``qwc'' has a vectored net declaration [1:0]
+
+reg [1:0] qrd; // unisims/OSERDESE1.v:2075: error: Scalar port ``qrd'' has a vectored net declaration [1:0]
+
+
+reg stop_rd, rd_gap1, extra;
+
+reg rd_cor, rd_cor_cnt, rd_cor_cnt1;
+
+
+wire qwc0_latch, qwc1_latch;
+
+wire li01, li02, li03;
+
+wire li11, li12, li13;
+
+
+wire qwc0_latchn, qwc1_latchn;
+
+wire li01n, li02n, li03n;
+
+wire li11n, li12n, li13n;
+
+
+reg stop_rdn, rd_cor_cntn, rd_cor_cnt1n, stop_rc;
+
+
+
+
+reg [1:0] qwcd;
+
+reg [1:0] qrdd;
+
+
+reg stop_rdd, rd_gap1d, extrad;
+
+reg rd_cord, rd_cor_cntd, rd_cor_cnt1d;
+
+
+wire qwcd0_latch, qwcd1_latch;
+
+wire li01d, li02d, li03d;
+
+wire li11d, li12d, li13d;
+
+
+
+// Write counter
+// The write counter uses 2 flops to create the grey code pattern of
+// 00 -> 01 -> 11 -> 10 -> 00. The write counter is initialized
+// to 11 and the read counter will be initialized to 00. This gives
+// a basic 2 clock separation to compensate for the phase differences.
+// The write counter is clocked off of the bufg clock
+
+always @ (posedge bufg_clk or posedge rst_bufg_wc)
+ begin
+ if (rst_bufg_wc)
+ begin
+ qwc <= # 10 2'b11;
+ end
+ else if (qwc[1] ^ qwc[0])
+ begin
+ qwc[1] <= # 10 ~qwc[1];
+ qwc[0] <= # 10 qwc[0];
+ end
+ else
+ begin
+ qwc[1] <= # 10 qwc[1];
+ qwc[0] <= # 10 ~qwc[0];
+ end
+ end
+
+
+
+
+
+
+// Read counter
+// The read counter uses 2 flops to create the grey code pattern of
+// 00 -> 01 -> 11 -> 10 -> 00. The read counter is initialized
+// to 00 and the write counter will be initialized to 11. This gives
+// a basic 2 clock separation to compensate for the phase differences.
+// The read counter is clocked off of the bufo clock
+
+always @ (posedge bufo_clk or posedge rst_bufo_rc)
+
+ begin
+ if (rst_bufo_rc)
+ begin
+ qrd <= # 10 2'b00;
+ end
+ else if (stop_rd && !data)
+ begin
+ qrd <= #10 qrd;
+ end
+ else if (qrd[1] ^ qrd[0])
+ begin
+ qrd[1] <= # 10 ~qrd[1];
+ qrd[0] <= # 10 qrd[0];
+ end
+ else
+ begin
+ qrd[1] <= # 10 qrd[1];
+ qrd[0] <= # 10 ~qrd[0];
+ end
+ end
+
+always @ (posedge bufo_clk or posedge rst_bufo_rc)
+
+ begin
+ if (rst_bufo_rc)
+ begin
+ rd_gap1 <= # 10 1'b0;
+ end
+// else if ((qwc1_latch && qwc0_latch) && (qrd[0] ^ qrd[1]))
+ else if ((qwc1_latch && qwc0_latch) && (qrd[0]))
+ begin
+ rd_gap1 <= # 10 1'b1;
+ end
+ else
+ begin
+ rd_gap1 <= # 10 rd_gap1;
+ end
+ end
+
+
+
+
+
+// Looking for 11
+
+assign #1 qwc0_latch = !(li01 & li03);
+assign #1 li01 = !(qwc[0] & bufo_clk);
+assign #1 li02 = !(li01 & bufo_clk);
+assign #1 li03 = !(qwc0_latch & li02);
+
+
+assign #1 qwc1_latch = !(li11 & li13);
+assign #1 li11 = !(qwc[1] & bufo_clk);
+assign #1 li12 = !(li11 & bufo_clk);
+assign #1 li13 = !(qwc1_latch & li12);
+
+
+// The following counter is to match the control counter to see if the
+// read counter did a hold after reset. This knowledge will enable the
+// computation of the 'extra' output. This in turn can add the
+// proper number of pipe stages to the output. The circuit must use
+// the output of BUFO and not be modified by ODELAY. This is because
+// the control pins PP clock was not modified by BUFO. If the
+// control pins PP clock was modified by BUFO, the reset must be done
+// with this in mind.
+
+// Read counter
+// The read counter uses 2 flops to create the grey code pattern of
+// 00 -> 01 -> 11 -> 10 -> 00. The read counter is initialized
+// to 00 and the write counter will be initialized to 11. This gives
+// a basic 2 clock separation to compensate for the phase differences.
+// The read counter is clocked off of the bufo clock
+
+always @ (posedge bufop_clk or posedge rst_bufop_rc)
+
+ begin
+ if (rst_bufop_rc)
+ begin
+ qrdd <= # 10 2'b00;
+ end
+ else if (qrdd[1] ^ qrdd[0])
+ begin
+ qrdd[1] <= # 10 ~qrdd[1];
+ qrdd[0] <= # 10 qrdd[0];
+ end
+ else
+ begin
+ qrdd[1] <= # 10 qrdd[1];
+ qrdd[0] <= # 10 ~qrdd[0];
+ end
+ end
+
+
+
+// Looking for 11
+
+assign #1 qwcd0_latch = !(li01d & li03d);
+assign #1 li01d = !(qwc[0] & bufop_clk);
+assign #1 li02d = !(li01d & bufop_clk);
+assign #1 li03d = !(qwcd0_latch & li02d);
+
+
+assign #1 qwcd1_latch = !(li11d & li13d);
+assign #1 li11d = !(qwc[1] & bufop_clk);
+assign #1 li12d = !(li11d & bufop_clk);
+assign #1 li13d = !(qwcd1_latch & li12d);
+
+
+
+// Circuit to fix read address counters in non data pins
+always @ (posedge bufop_clk or posedge rst_bufo_rc)
+
+ begin
+ if (rst_bufop_rc)
+ begin
+ stop_rd <= # 10 1'b0;
+ rd_cor_cnt <= #10 1'b0;
+ rd_cor_cnt1 <= #10 1'b0;
+ end
+ else if (((qwcd1_latch && qwcd0_latch) && (qrdd[0] ^ qrdd[1]) && !rd_cor_cnt1))
+ begin
+ stop_rd <= #10 1'b1;
+ rd_cor_cnt <= #10 1'b1;
+ rd_cor_cnt1 <= #10 rd_cor_cnt;
+ end
+ else
+ begin
+ stop_rd <= #10 1'b0;
+ rd_cor_cnt <= #10 1'b1;
+ rd_cor_cnt1 <= #10 rd_cor_cnt;
+ end
+ end
+
+// Circuit to inform data if control counters habe been fixed
+
+always @ (posedge bufop_clk or posedge rst_bufop_rc)
+ begin
+ if (rst_bufop_rc)
+ begin
+ extra <= #10 1'b0;
+ end
+ else if (stop_rd)
+ begin
+ extra <= #10 1'b1;
+ end
+ end
+
+endmodule
+`timescale 1ps/1ps
+////////////////////////////////////////////////////////
+//
+// module iodlyctrl_npre_oserdese1_vlog
+//
+////////////////////////////////////////////////////////
+//
+// Circuit to automatically switch IODELAY from IDELAY to ODELAY using knowledge
+// of write command. This circuit forces the user to wait 3 extra CLK/CLK# cycles
+// when performing a read to write turnaround. The JEDEC DDR3 spec states that
+// the turnaround can be done in 2 clock cycles. This circuit requires 5 clock
+// cycles.
+// This circuit is only used for a DDR3 appplication that uses DIMMs
+
+
+
+module iodlyctrl_npre_oserdese1_vlog (iodelay_state, bufo_out, rst_cntr,
+ wc, trif,
+ rst, bufg_clk, bufo_clk, bufg_clkdiv,
+ ddr3_dimm, wl6
+ );
+
+
+input wc;
+
+input trif;
+
+input rst;
+
+input bufo_clk, bufg_clk, bufg_clkdiv;
+
+input ddr3_dimm, wl6;
+
+output iodelay_state, rst_cntr;
+
+output bufo_out;
+
+
+reg qw0cd, qw1cd;
+
+reg turn, turn_p1;
+
+reg rst_cntr;
+
+reg w_to_w;
+
+reg [2:0] wtw_cntr;
+
+reg cmd0, cmd0_n6, cmd0_6, cmd1;
+
+
+
+
+wire wr_cmd0;
+
+wire lt0int1, lt0int2, lt0int3;
+
+wire lt1int1, lt1int2, lt1int3;
+
+wire latch_in;
+
+reg qwcd;
+
+
+
+
+
+assign bufo_out = bufo_clk;
+
+
+// create turn signal for IODELAY
+assign iodelay_state = (trif && ~w_to_w) & ((~turn && ~turn_p1) || ~ddr3_dimm);
+
+
+
+// Registers to detect write command
+
+// Registers using bufg clkdiv
+always @ (posedge bufg_clkdiv)
+begin
+ if (rst)
+ begin
+ qwcd <= #10 0;
+ end
+ else
+ begin
+ qwcd <= #10 wc;
+ end
+end
+
+
+
+// Latch to allow skew between CLK and CLKDIV from BUFGs
+assign #1 wr_cmd0 = !(lt0int1 && lt0int3);
+assign #1 lt0int1 = !(qwcd && bufg_clk);
+assign #1 lt0int2 = !(lt0int1 && bufg_clk);
+assign #1 lt0int3 = !(wr_cmd0 && lt0int2);
+
+always @ (posedge bufg_clk)
+ begin
+ if (rst)
+ begin
+ cmd0_n6 <= #10 1'b0;
+ cmd0_6 <= #10 1'b0;
+ end
+ else
+ begin
+ cmd0_n6 <= #10 wr_cmd0;
+ cmd0_6 <= #10 cmd0_n6;
+ end
+ end
+
+
+
+// mux to add extra pipe stage for WL = 6
+always @ (cmd0_n6 or wl6 or cmd0_6)
+ begin
+ case (wl6)
+ 1'b0: cmd0 <= #10 cmd0_n6;
+ 1'b1: cmd0 <= #10 cmd0_6;
+ default: cmd0 <= #10 cmd0_n6;
+ endcase
+ end
+
+
+// Turn IODELAY and reset FIFO read/write counters
+//always @ (posedge bufg_clk)
+// begin
+// if (rst)
+//
+// begin
+// turn <= #10 1'b0;
+// rst_cntr <= #10 1'b0;
+// end
+// else if (w_to_w)
+// begin
+// turn <= #10 1'b1;
+// rst_cntr <= #10 1'b0;
+// end
+// else if (cmd0 && !turn)
+// begin
+// turn <= #10 1'b1;
+// rst_cntr <= #10 1'b1;
+// end
+// else if (~trif)
+// begin
+// turn <= #10 1'b0;
+// rst_cntr <= #10 1'b0;
+// end
+// else if (turn)
+// begin
+// turn <= #10 1'b1;
+// rst_cntr <= #10 1'b0;
+// end
+// else
+// begin
+// turn <= #10 1'b0;
+// rst_cntr <= #10 1'b0;
+// end
+// end
+
+
+
+always @ (posedge bufg_clk)
+begin
+ begin
+ if (rst)
+ begin
+ turn <= #10 1'b0;
+ end
+ else
+ begin
+ turn <= #10 (w_to_w || (cmd0 && ~turn) ||
+ (~wtw_cntr[2] && turn));
+ end
+
+ end
+
+ begin
+ if (rst)
+ begin
+ rst_cntr <= #10 1'b0;
+ end
+ else
+ begin
+ rst_cntr <= #10 (~w_to_w && (cmd0 && ~turn));
+ end
+ end
+end
+
+
+
+
+always @ (posedge bufg_clk)
+ begin
+ if (rst)
+ begin
+ turn_p1 <= #10 1'b0;
+ end
+ else
+ begin
+ turn_p1 <= #10 turn;
+ end
+ end
+
+
+
+
+// Detect multiple write commands and don"t turn IODELAY
+//always @ (posedge bufg_clk)
+// begin
+// if (rst)
+// begin
+// w_to_w <= #10 1'b0;
+// wtw_cntr <= #10 3'b000;
+// end
+// else if (cmd0 && turn_p1)
+// begin
+// w_to_w <= #10 1'b1;
+// wtw_cntr <= #10 3'b000;
+// end
+// else if (wtw_cntr == 3'b101)
+// begin
+// w_to_w <= #10 1'b0;
+// wtw_cntr <= #10 3'b000;
+// end
+// else if (w_to_w)
+// begin
+// w_to_w <= #10 1'b1;
+// wtw_cntr <= #10 wtw_cntr + 1;
+// end
+// end
+
+
+always @ (posedge bufg_clk)
+begin
+ begin
+ if (rst)
+ begin
+ w_to_w <= #10 1'b0;
+ end
+ else
+ begin
+ w_to_w <= #10 ((cmd0 && turn_p1) ||
+ (w_to_w && (~wtw_cntr[2] || ~wtw_cntr[1])));
+ end
+ end
+end
+
+
+always @ (posedge bufg_clk)
+
+ begin
+ if (!(w_to_w || turn) || (cmd0 && turn_p1))
+ begin
+ wtw_cntr <= #10 3'b000;
+ end
+ else if (w_to_w || turn_p1)
+ begin
+ wtw_cntr <= #10 wtw_cntr + 1;
+ end
+ end
+
+endmodule
+`timescale 1ps/1ps
+////////////////////////////////////////////////////////
+//
+// MODULE dout_oserdese1_vlog
+//
+// This model ONLY works for SERDES operation!!
+// Does not include tristate circuit
+//
+/////////////////////////////////////////////////////////
+//
+// Inputs:
+// data1: Data from FIFO
+// data2: Data input FIFO
+// CLK: High speed clock from DCM
+// BUFO: Clock from performance path
+// OCE: Clock enable for output data flops
+// SR: Set/Reset control. For the last 3 flops in OQ
+// (d1rnk2, d2rnk2 and d2nrnk2) this function is
+// controlled bythe attributes SRVAL_OQ. In SERDES mode,
+// SR is a RESET ONLY for all other flops! The flops will
+// still be RESET even if SR is programmed to a SET!
+//
+//
+//
+// Outputs:
+// OQ: Data output
+//
+//
+//
+// Programmable Points
+// DATA_RATE_OQ: Rate control for data output, 1-bit
+// sdr (1), ddr (0)
+// INIT_OQ: Init OQ output "flop"
+// SRVAL_OQ: This bit to controls value of SR input.
+// Only the last 3 flops (d1rnk2, d2rnk2 and d2nrnk2)
+// are affected by this bit.For SERDES mode, this bit
+// should be set to '0' making SR a reset. This is the
+// desired state since all other flops only respond to
+// this pin as a reset. Their function cannot be
+// changed. SR is '1' for SET and '0' for RESET.
+//
+//
+//
+// Programmable points for Test model
+// SRTYPE: This is a 4-bit field Sets asynchronous (0) or synchronous (1) set/reset
+// 1st bit (msb) sets rank1 flops, 2nd bit sets 4 flops in rank 2,
+// 3rd bit sets "3 legacy flops, and 4th (lsb) bit sets the counter
+// DDR_CLK_EDGE: Controls use of 2 or 3 flops for single case. Default to 1 for
+// SERDES operation
+//
+//
+///////////////////////////////////////////////////////////////////////////////
+//
+
+module dout_oserdese1_vlog (data1, data2,
+ CLK, BUFO, SR, OCE,
+ OQ, d2rnk2,
+ DATA_RATE_OQ,
+ INIT_OQ, SRVAL_OQ,
+ DDR3_MODE);
+
+input data1, data2;
+
+input CLK, SR, OCE;
+
+input BUFO;
+
+input INIT_OQ, SRVAL_OQ;
+
+input DDR3_MODE;
+
+output OQ;
+
+output d2rnk2;
+
+
+// Programmable Points
+
+input DATA_RATE_OQ;
+
+wire DDR_CLK_EDGE;
+wire [3:0] SRTYPE;
+assign DDR_CLK_EDGE = 1'b1;
+assign SRTYPE = 4'b1111;
+reg d1rnk2, d2rnk2, d2nrnk2;
+
+reg OQ;
+
+reg ddr_data, odata_edge, sdata_edge;
+
+reg c23, c45, c67;
+
+wire C;
+
+wire C2p, C3;
+
+wire [3:0] seloq;
+
+wire oqsr, oqrev;
+
+assign C = (BUFO & DDR3_MODE) | (CLK & !DDR3_MODE);
+
+assign C2p = (C & DDR_CLK_EDGE) | (!C & !DDR_CLK_EDGE);
+
+assign C3 = !C2p;
+
+assign seloq = {OCE,DATA_RATE_OQ,oqsr,oqrev};
+
+assign oqsr = !SRTYPE[1] & SR & !SRVAL_OQ;
+
+assign oqrev = !SRTYPE[1] & SR & SRVAL_OQ;
+
+
+
+//////////////////////////////////////////////////
+// Delay values
+//
+parameter FFD = 1; // clock to out delay for flip flops
+// driven by clk
+parameter FFCD = 1; // clock to out delay for flip flops
+// driven by clkdiv
+parameter MXD = 1; // 60 ps mux delay
+
+parameter MXR1 = 1;
+
+////////////////////////////////////////////
+// Initialization of flops with GSR for test model
+///////////////////////////////////////////
+
+tri0 GSR = glbl.GSR;
+
+always @(GSR)
+begin
+ if (GSR)
+ begin
+ assign OQ = INIT_OQ;
+ assign d1rnk2 = INIT_OQ;
+ assign d2rnk2 = INIT_OQ;
+ assign d2nrnk2 = INIT_OQ;
+ end
+ else
+ begin
+ deassign OQ;
+ deassign d1rnk2;
+ deassign d2rnk2;
+ deassign d2nrnk2;
+ end
+end
+
+/////////////////////////////////////////
+
+
+
+
+
+
+/////////////////////////////////////////
+// 3 flops to create DDR operations of 4 latches
+////////////////////////////////////////
+
+// Representation of top latch
+// asynchronous operation
+always @ (posedge C or posedge SR)
+begin
+ begin
+ if (SR & !SRVAL_OQ & !SRTYPE[1])
+ begin
+ d1rnk2 <= # FFD 1'b0;
+ end
+ else if (SR & SRVAL_OQ & !SRTYPE[1])
+ begin
+ d1rnk2 <= # FFD 1'b1;
+ end
+ else if (!OCE & !SRTYPE[1])
+ begin
+ d1rnk2 <= # FFD OQ;
+ end
+ else if (!SRTYPE[1])
+ begin
+ d1rnk2 <= # FFD data1;
+ end
+ end
+end
+
+// synchronous operation
+always @ (posedge C)
+begin
+ begin
+
+ if (SR & !SRVAL_OQ & SRTYPE[1])
+ begin
+ d1rnk2 <= # FFD 1'b0;
+ end
+ else if (SR & SRVAL_OQ & SRTYPE[1])
+ begin
+ d1rnk2 <= # FFD 1'b1;
+ end
+ else if (!OCE & SRTYPE[1])
+ begin
+ d1rnk2 <= # FFD OQ;
+ end
+ else if (SRTYPE[1])
+ begin
+ d1rnk2 <= # FFD data1;
+ end
+ end
+end
+
+
+
+
+// Representation of 2nd latch
+// asynchronous operation
+always @ (posedge C2p or posedge SR)
+begin
+ begin
+ if (SR & !SRVAL_OQ & !SRTYPE[1])
+ begin
+ d2rnk2 <= # FFD 1'b0;
+ end
+ else if (SR & SRVAL_OQ & !SRTYPE[1])
+ begin
+ d2rnk2 <= # FFD 1'b1;
+ end
+ else if (!OCE & !SRTYPE[1])
+ begin
+ d2rnk2 <= # FFD OQ;
+ end
+ else if (!SRTYPE[1])
+ begin
+ d2rnk2 <= # FFD data2;
+ end
+ end
+end
+
+// synchronous operation
+always @ (posedge C2p)
+begin
+ begin
+
+ if (SR & !SRVAL_OQ & SRTYPE[1])
+ begin
+ d2rnk2 <= # FFD 1'b0;
+ end
+ else if (SR & SRVAL_OQ & SRTYPE[1])
+ begin
+ d2rnk2 <= # FFD 1'b1;
+ end
+ else if (!OCE & SRTYPE[1])
+ begin
+ d2rnk2 <= # FFD OQ;
+ end
+ else if (SRTYPE[1])
+ begin
+ d2rnk2 <= # FFD data2;
+ end
+ end
+end
+
+
+
+
+// Representation of 3rd flop ( latch and output latch)
+// asynchronous operation
+always @ (posedge C3 or posedge SR)
+begin
+ begin
+ if (SR & !SRVAL_OQ & !SRTYPE[1])
+ begin
+ d2nrnk2 <= # FFD 1'b0;
+ end
+ else if (SR & SRVAL_OQ & !SRTYPE[1])
+ begin
+ d2nrnk2 <= # FFD 1'b1;
+ end
+ else if (!OCE & !SRTYPE[1])
+ begin
+ d2nrnk2 <= # FFD OQ;
+ end
+ else if (!SRTYPE[1])
+ begin
+ d2nrnk2 <= # FFD d2rnk2;
+ end
+ end
+end
+
+// synchronous operation
+always @ (posedge C3)
+begin
+
+ begin
+ if (SR & !SRVAL_OQ & SRTYPE[1])
+ begin
+ d2nrnk2 <= # FFD 1'b0;
+ end
+ else if (SR & SRVAL_OQ & SRTYPE[1])
+ begin
+ d2nrnk2 <= # FFD 1'b1;
+ end
+ else if (!OCE & SRTYPE[1])
+ begin
+ d2nrnk2 <= # FFD OQ;
+ end
+ else if (SRTYPE[1])
+ begin
+ d2nrnk2 <= # FFD d2rnk2;
+ end
+ end
+end
+
+
+// Logic to generate same edge data from d1rnk2 and d2nrnk2;
+always @ (C or C3 or d1rnk2 or d2nrnk2)
+ begin
+ sdata_edge <= # MXD (d1rnk2 & C) | (d2nrnk2 & C3);
+ end
+
+// Mux to create opposite edge DDR data from d1rnk2 and d2rnk2
+always @ (C or d1rnk2 or d2rnk2)
+ begin
+ case (C)
+ 1'b0: odata_edge <= # MXD d2rnk2;
+ 1'b1: odata_edge <= # MXD d1rnk2;
+ default: odata_edge <= # MXD d1rnk2;
+ endcase
+ end
+
+// Logic to same edge and opposite data into just ddr data
+always @ (ddr_data or sdata_edge or odata_edge or DDR_CLK_EDGE)
+ begin
+ ddr_data <= # MXD (odata_edge & !DDR_CLK_EDGE) | (sdata_edge & DDR_CLK_EDGE);
+ end
+
+
+// Output mux to generate OQ
+always @ (seloq or d1rnk2 or ddr_data or OQ)
+ begin
+ casex (seloq)
+ 4'bXX01: OQ <= # MXD 1'b1;
+ 4'bXX10: OQ <= # MXD 1'b0;
+ 4'bXX11: OQ <= # MXD 1'b0;
+ 4'bX000: OQ <= # MXD ddr_data;
+ 4'bX100: OQ <= # MXD d1rnk2;
+ default: OQ <= # MXD ddr_data;
+ endcase
+ end
+
+
+endmodule
+`timescale 1ps/1ps
+//////////////////////////////////////////////////////////
+//
+// module tout_oserdese1_vlog
+//
+// Tristate Output cell for Mt Blanc
+//
+//
+////////////////////////////////////////////////////////
+//
+//
+//
+/////////////////////////////////////////////////////////
+//
+// Inputs:
+//
+// data1, data2: tristate inputs
+// TCE: Tristate clock enable
+// SR: Set/Reset control. For the last 3 flops in TQ
+// (qt1, qt2 and qt2n) this function is
+// controlled bythe attributes SRVAL_TQ. In SERDES mode,
+// SR is a RESET ONLY for all other flops! The flops will
+// still be RESET even if SR is programmed to a SET!
+// CLK: High speed clocks
+// C2 drives 2nd latch and C3 (inverse of C2) drives
+// 3rd latch in output section
+// BUFO: Performance path clock
+//
+//
+//
+//
+// Outputs:
+//
+// TQ: Output of tristate mux
+//
+//
+// Programmable Options:
+//
+// DATA_RATE_TQ: 2-bit field for types of operaiton
+// 0 (buf from T1), 1 (registered output from T1), 2 (ddr)
+// TRISTATE_WIDTH: 2-bit field for input width
+// 0 (width 1), 1 (width 2), 2 (width 4)
+// INIT_TQ: Init TQ output (0,1)
+// SRVAL_TQ: This bit to controls value of SR input.
+// Only the last 3 flops (qt1, qt2 and qt2n) are
+// affected by this bit.For SERDES mode, this bit
+// should be set to '0' making SR a reset. This is the
+// desired state since all other flops only
+// respond to this pin as a reset. Their function
+// cannot be changed. SR is 'O' for SET and '1' for RESET.
+//
+//
+// Programmable Test Options:
+// SRTYPE: Control S and R as asynchronous (0) or synchronous (1)
+// 2-bit value. 1st bit (msb) controls the 4 input flops
+// and the 2nd bit (lsb) controls the "3 legacy flops"
+// DDR_CLK_EDGE: Same or opposite edge operation
+//
+//
+//
+////////////////////////////////////////////////////////////////////////////////
+//
+
+module tout_oserdese1_vlog (data1, data2,
+ CLK, BUFO, SR, TCE,
+ DATA_RATE_TQ, TRISTATE_WIDTH,
+ INIT_TQ, SRVAL_TQ,
+ TQ, DDR3_MODE);
+
+input data1, data2;
+
+input CLK, BUFO, SR, TCE;
+
+input [1:0] DATA_RATE_TQ, TRISTATE_WIDTH;
+
+input INIT_TQ, SRVAL_TQ;
+
+input DDR3_MODE;
+
+output TQ;
+
+wire DDR_CLK_EDGE;
+wire [1:0] SRTYPE;
+assign SRTYPE = 2'b11;
+assign DDR_CLK_EDGE = 1'b1;
+
+reg TQ;
+
+reg t1r, t2r, t3r, t4r;
+
+reg qt1, qt2, qt2n;
+
+reg sdata_edge, odata_edge, ddr_data;
+
+wire C;
+
+wire C2p, C3;
+
+wire load;
+
+wire [5:0] tqsel;
+
+wire tqsr, tqrev;
+
+wire [4:0] sel;
+
+assign C = (BUFO & DDR3_MODE) | (CLK & !DDR3_MODE);
+
+assign C2p = (C & DDR_CLK_EDGE) | (!C & !DDR_CLK_EDGE);
+
+assign C3 = !C2p;
+
+assign tqsr = (!SRTYPE[0] & SR & !SRVAL_TQ) | (!SRTYPE[0] & SRVAL_TQ);
+
+assign tqrev = (!SRTYPE[0] & SR & SRVAL_TQ) | (!SRTYPE[0] & !SRVAL_TQ);
+
+assign tqsel = {TCE,DATA_RATE_TQ,TRISTATE_WIDTH,tqsr};
+
+
+
+
+
+//////////////////////////////////////////////////
+
+
+// Parameters for gate delays
+parameter ffd = 1;
+parameter mxd = 1;
+
+
+/////////////////////////////
+// Initialization of Flops
+////////////////////////////
+
+tri0 GSR = glbl.GSR;
+
+always @(GSR)
+begin
+ if (GSR)
+ begin
+ assign TQ = INIT_TQ;
+ assign qt1 = INIT_TQ;
+ assign qt2 = INIT_TQ;
+ assign qt2n = INIT_TQ;
+ end
+ else
+ begin
+ deassign TQ;
+ deassign qt1;
+ deassign qt2;
+ deassign qt2n;
+ end
+end
+
+
+
+/////////////////////////////////////////
+// 3 flops to create DDR operations of 4 latches
+////////////////////////////////////////
+
+// Representation of top latch
+// asynchronous operation
+always @ (posedge C or posedge SR)
+begin
+ begin
+ if (SR & !SRVAL_TQ & !SRTYPE[0])
+ begin
+ qt1 <= # ffd 1'b0;
+ end
+ else if (SR & SRVAL_TQ & !SRTYPE[0])
+ begin
+ qt1 <= # ffd 1'b1;
+ end
+ else if (!TCE & !SRTYPE[0])
+ begin
+ qt1 <= # ffd TQ;
+ end
+ else if (!SRTYPE[0])
+ begin
+ qt1 <= # ffd data1;
+ end
+ end
+end
+
+// synchronous operation
+always @ (posedge C)
+begin
+ begin
+
+ if (SR & !SRVAL_TQ & SRTYPE[0])
+ begin
+ qt1 <= # ffd 1'b0;
+ end
+ else if (SR & SRVAL_TQ & SRTYPE[0])
+ begin
+ qt1 <= # ffd 1'b1;
+ end
+ else if (!TCE & SRTYPE[0])
+ begin
+ qt1 <= # ffd TQ;
+ end
+ else if (SRTYPE[0])
+ begin
+ qt1 <= # ffd data1;
+ end
+ end
+end
+
+
+
+
+// Representation of 2nd latch
+// asynchronous operation
+always @ (posedge C2p or posedge SR)
+begin
+ begin
+ if (SR & !SRVAL_TQ & !SRTYPE[0])
+ begin
+ qt2 <= # ffd 1'b0;
+ end
+ else if (SR & SRVAL_TQ & !SRTYPE[0])
+ begin
+ qt2 <= # ffd 1'b1;
+ end
+ else if (!TCE & !SRTYPE[0])
+ begin
+ qt2 <= # ffd TQ;
+ end
+ else if (!SRTYPE[0])
+ begin
+ qt2 <= # ffd data2;
+ end
+ end
+end
+
+// synchronous operation
+always @ (posedge C2p)
+begin
+ begin
+ if (SR & !SRVAL_TQ & SRTYPE[0])
+ begin
+ qt2 <= # ffd 1'b0;
+ end
+ else if (SR & SRVAL_TQ & SRTYPE[0])
+ begin
+ qt2 <= # ffd 1'b1;
+ end
+ else if (!TCE & SRTYPE[0])
+ begin
+ qt2 <= # ffd TQ;
+ end
+ else if (SRTYPE[0])
+ begin
+ qt2 <= # ffd data2;
+ end
+ end
+end
+
+
+
+
+// Representation of 3rd flop ( latch and output latch)
+// asynchronous operation
+always @ (posedge C3 or posedge SR)
+begin
+ begin
+ if (SR & !SRVAL_TQ & !SRTYPE[0])
+ begin
+ qt2n <= # ffd 1'b0;
+ end
+ else if (SR & SRVAL_TQ & !SRTYPE[0])
+ begin
+ qt2n <= # ffd 1'b1;
+ end
+ else if (!TCE & !SRTYPE[0])
+ begin
+ qt2n <= # ffd TQ;
+ end
+ else if (!SRTYPE[0])
+ begin
+ qt2n <= # ffd qt2;
+ end
+ end
+end
+
+// synchronous operation
+always @ (posedge C3)
+begin
+
+ begin
+ if (SR & !SRVAL_TQ & SRTYPE[0])
+ begin
+ qt2n <= # ffd 1'b0;
+ end
+ else if (SR & SRVAL_TQ & SRTYPE[0])
+ begin
+ qt2n <= # ffd 1'b1;
+ end
+ else if (!TCE & SRTYPE[0])
+ begin
+ qt2n <= # ffd TQ;
+ end
+ else if (SRTYPE[0])
+ begin
+ qt2n <= # ffd qt2;
+ end
+ end
+end
+
+
+// Logic to generate same edge data from qt1, qt3;
+always @ (C or C3 or qt1 or qt2n)
+ begin
+ sdata_edge <= # mxd (qt1 & C) | (qt2n & C3);
+ end
+
+// Mux to create opposite edge DDR function
+always @ (C or qt1 or qt2)
+ begin
+ case (C)
+ 1'b0: odata_edge <= # mxd qt2;
+ 1'b1: odata_edge <= # mxd qt1;
+ default: odata_edge <= 1'b0;
+ endcase
+ end
+
+// Logic to same edge and opposite data into just ddr data
+always @ (ddr_data or sdata_edge or odata_edge or DDR_CLK_EDGE)
+ begin
+ ddr_data <= # mxd (odata_edge & !DDR_CLK_EDGE) | (sdata_edge & DDR_CLK_EDGE);
+ end
+
+// Output mux to generate TQ
+// Note that the TQ mux can also support T2 combinatorial or
+// registered outputs.
+always @ (tqsel or data1 or ddr_data or qt1 or TQ)
+ begin
+ casex (tqsel)
+ 6'bX01XX1: TQ <= # mxd 1'b0;
+ 6'bX10XX1: TQ <= # mxd 1'b0;
+ 6'bX01XX1: TQ <= # mxd 1'b0;
+ 6'bX10XX1: TQ <= # mxd 1'b0;
+ 6'bX0000X: TQ <= # mxd data1;
+ // 6'b001000: TQ <= # mxd TQ;
+ // 6'b010010: TQ <= # mxd TQ;
+ // 6'b010100: TQ <= # mxd TQ;
+ 6'bX01000: TQ <= # mxd qt1;
+ 6'bX10010: TQ <= # mxd ddr_data;
+ 6'bX10100: TQ <= # mxd ddr_data;
+ default: TQ <= # mxd ddr_data;
+ endcase
+ end
+
+
+endmodule
+
+`endcelldefine
x393-27c9f81a8104ee48d3599d85e6eb021174a1dcd5/README.md 0000664 0000000 0000000 00000000055 12456063403 0020435 0 ustar 00root root 0000000 0000000 x393
=====
FPGA code for Elphel 393 camera
x393-27c9f81a8104ee48d3599d85e6eb021174a1dcd5/axi/ 0000775 0000000 0000000 00000000000 12456063403 0017737 5 ustar 00root root 0000000 0000000 x393-27c9f81a8104ee48d3599d85e6eb021174a1dcd5/axi/axibram.v 0000664 0000000 0000000 00000035606 12456063403 0021563 0 ustar 00root root 0000000 0000000 /*******************************************************************************
* Module: axibram
* Date:2014-03-18
* Author: Andrey Filippov
* Description:
*
* Copyright (c) 2014 Elphel, Inc.
* axibram.v is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* axibram.v is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*******************************************************************************/
module axibram(
input aclk, // clock - should be buffered
input aresetn, // reset, active low
// AXI Read Address
input [31:0] araddr, // ARADDR[31:0], input
input arvalid, // ARVALID, input
output arready, // ARREADY, output
input [11:0] arid, // ARID[11:0], input
// input [ 1:0] arlock, // ARLOCK[1:0], input
// input [ 3:0] archache,// ARCACHE[3:0], input
// input [ 2:0] arprot, // ARPROT[2:0], input
input [ 3:0] arlen, // ARLEN[3:0], input
input [ 1:0] arsize, // ARSIZE[1:0], input
input [ 1:0] arburst, // ARBURST[1:0], input
// input [ 3:0] adqos, // ARQOS[3:0], input
// AXI Read Data
output [31:0] rdata, // RDATA[31:0], output
output reg rvalid, // RVALID, output
input rready, // RREADY, input
output reg [11:0] rid, // RID[11:0], output
output reg rlast, // RLAST, output
output [ 1:0] rresp, // RRESP[1:0], output
// AXI Write Address
input [31:0] awaddr, // AWADDR[31:0], input
input awvalid, // AWVALID, input
output awready, // AWREADY, output
input [11:0] awid, // AWID[11:0], input
// input [ 1:0] awlock, // AWLOCK[1:0], input
// input [ 3:0] awcache, // AWCACHE[3:0], input
// input [ 2:0] awprot, // AWPROT[2:0], input
input [ 3:0] awlen, // AWLEN[3:0], input
input [ 1:0] awsize, // AWSIZE[1:0], input
input [ 1:0] awburst, // AWBURST[1:0], input
// input [ 3:0] awqos, // AWQOS[3:0], input
// AXI PS Master GP0: Write Data
input [31:0] wdata, // WDATA[31:0], input
input wvalid, // WVALID, input
output wready, // WREADY, output
input [11:0] wid, // WID[11:0], input
input wlast, // WLAST, input
input [ 3:0] wstb, // WSTRB[3:0], input
// AXI PS Master GP0: Write Responce
output bvalid, // BVALID, output
input bready, // BREADY, input
output [11:0] bid, // BID[11:0], output
output [ 1:0] bresp // BRESP[1:0], output
);
// **** Read channel ****
wire ar_nempty;
wire ar_half_full;
assign arready=~ar_half_full;
wire [ 1:0] arburst_out;
// SuppressWarnings VEditor all
wire [ 1:0] arsize_out; // not used
wire [ 3:0] arlen_out;
wire [ 9:0] araddr_out;
wire [11:0] arid_out;
wire rst=~aresetn;
reg read_in_progress=0;
reg read_in_progress_d=0; // delayed by one active cycle (not skipped)
reg read_in_progress_or=0; // read_in_progress || read_in_progress_d
reg [ 9:0] read_address; // transfer address (not including lower bits
reg [ 3:0] read_left; // number of read transfers
// will ignore arsize - assuming always 32 bits (a*size[2:0]==2)
reg [ 1:0] rburst; // registered burst type
reg [ 3:0] rlen; // registered burst type
wire [ 9:0] next_rd_address_w; // next transfer address;
assign next_rd_address_w=
rburst[1]?
(rburst[0]? (10'h0):((read_address[9:0]+1) & {6'h3f, ~rlen[3:0]})):
(rburst[0]? (read_address[9:0]+1):(read_address[9:0]));
wire start_read_burst_w;
// wire bram_re_w;
wire bram_reg_re_w;
wire read_in_progress_w;
wire read_in_progress_d_w;
wire last_in_burst_w;
wire last_in_burst_d_w;
reg pre_last_in_burst_r;
assign rresp=2'b0;
// reduce combinatorial delay from rready (use it in final mux)
// assign bram_reg_re_w= read_in_progress && (!rvalid || rready);
// assign start_read_burst_w=ar_nempty && (!read_in_progress || (bram_reg_re_w && (read_left==4'b0))); // reduce delay from arready
assign last_in_burst_w= bram_reg_re_w && (read_left==4'b0);
assign last_in_burst_d_w=bram_reg_re_w && pre_last_in_burst_r;
// make sure ar_nempty is updated
// assign start_read_burst_w=ar_nempty && (!read_in_progress || last_in_burst_w); // reduce delay from arready
assign read_in_progress_w= start_read_burst_w || (read_in_progress && !last_in_burst_w); // reduce delay from arready
assign read_in_progress_d_w=(read_in_progress && bram_reg_re_w) ||
(read_in_progress && !last_in_burst_d_w); // reduce delay from arready
// assign read_in_progress_d_w=read_in_progress_d;
wire pre_rvalid_w;
assign pre_rvalid_w=bram_reg_re_w || (rvalid && !rready);
reg bram_reg_re_0;
wire pre_left_zero_w;
reg last_in_burst_1;
reg last_in_burst_0;
reg start_read_burst_0;
reg start_read_burst_1;
reg [11:0] pre_rid0;
reg [11:0] pre_rid;
always @ (posedge aclk or posedge rst) begin
if (rst) pre_last_in_burst_r <= 0;
// else if (start_read_burst_w) pre_last_in_burst_r <= (read_left==4'b0);
else if (bram_reg_re_w) pre_last_in_burst_r <= (read_left==4'b0);
if (rst) rburst[1:0] <= 0;
else if (start_read_burst_w) rburst[1:0] <= arburst_out[1:0];
if (rst) rlen[3:0] <= 0;
else if (start_read_burst_w) rlen[3:0] <= arlen_out[3:0];
if (rst) read_in_progress <= 0;
else read_in_progress <= read_in_progress_w;
if (rst) read_in_progress_d <= 0;
// else read_in_progress_d <= read_in_progress_d_w;
else if (bram_reg_re_w) read_in_progress_d <= read_in_progress_d_w;
if (rst) read_in_progress_or <= 0;
// else read_in_progress_or <= read_in_progress_d_w || read_in_progress_w;
// else if (bram_reg_re_w) read_in_progress_or <= read_in_progress_d_w || read_in_progress_w;
// FIXME:
else if (bram_reg_re_w || !read_in_progress_or) read_in_progress_or <= read_in_progress_d_w || read_in_progress_w;
// reg read_in_progress_d=0; // delayed by one active cycle (not skipped)
// reg read_in_progress_or=0; // read_in_progress || read_in_progress_d
if (rst) read_left <= 0;
else if (start_read_burst_w) read_left <= arlen_out[3:0]; // precedence over inc
else if (bram_reg_re_w) read_left <= read_left-1;
if (rst) read_address <= 10'b0;
else if (start_read_burst_w) read_address <= araddr_out[9:0]; // precedence over inc
else if (bram_reg_re_w) read_address <= next_rd_address_w;
if (rst) rvalid <= 1'b0;
else if (bram_reg_re_w && read_in_progress_d) rvalid <= 1'b1;
else if (rready) rvalid <= 1'b0;
if (rst) rlast <= 1'b0;
else if (last_in_burst_d_w) rlast <= 1'b1;
else if (rready) rlast <= 1'b0;
end
always @ (posedge aclk) begin
// bram_reg_re_0 <= read_in_progress_w && !pre_rvalid_w;
bram_reg_re_0 <= (ar_nempty && !read_in_progress) || (read_in_progress && !read_in_progress);
last_in_burst_1 <= read_in_progress_w && pre_left_zero_w;
last_in_burst_0 <= read_in_progress_w && !pre_rvalid_w && pre_left_zero_w;
start_read_burst_1 <= !read_in_progress_w || pre_left_zero_w;
start_read_burst_0 <= !read_in_progress_w || (!pre_rvalid_w && pre_left_zero_w);
if (start_read_burst_w) pre_rid0[11:0] <= arid_out[11:0];
if (bram_reg_re_w) pre_rid[11:0] <= pre_rid0[11:0];
if (bram_reg_re_w) rid[11:0] <= pre_rid[11:0];
end
// reducing rready combinatorial delay
assign pre_left_zero_w=start_read_burst_w?(arlen_out[3:0]==4'b0):(bram_reg_re_w && (read_left==4'b0001));
// assign bram_reg_re_w= read_in_progress && (!rvalid || rready);
assign bram_reg_re_w= read_in_progress_or && (!rvalid || rready); // slower/simplier
// assign bram_reg_re_w= rready? read_in_progress : bram_reg_re_0; // faster - more verification
assign last_in_burst_w=bram_reg_re_w && (read_left==4'b0); // slower/simplier
// assign last_in_burst_w=rready? (read_in_progress && (read_left==4'b0)): (bram_reg_re_0 && (read_left==4'b0));
// assign last_in_burst_w=rready? last_in_burst_1: last_in_burst_0; // faster (unfinished) - more verification
assign start_read_burst_w=ar_nempty && (!read_in_progress || (bram_reg_re_w && (read_left==4'b0))); // reduce delay from rready
// assign start_read_burst_w=ar_nempty && (!read_in_progress || ((rready? read_in_progress : bram_reg_re_0) && (read_left==4'b0)));
// assign start_read_burst_w=
// rready?
// (ar_nempty && (!read_in_progress || ((read_in_progress) && (read_left==4'b0)))):
// (ar_nempty && (!read_in_progress || ((bram_reg_re_0 ) && (read_left==4'b0))));
/*
assign start_read_burst_w=
ar_nempty*(rready?
(!read_in_progress || (read_left==4'b0)):
((!read_in_progress || ((bram_reg_re_0 ) && (read_left==4'b0)))));
*/
// assign start_read_burst_w= ar_nempty && (rready?start_read_burst_1:start_read_burst_0);
// **** Write channel: ****
wire aw_nempty;
wire aw_half_full;
assign awready=~aw_half_full;
wire [ 1:0] awburst_out;
// SuppressWarnings VEditor all
wire [ 1:0] awsize_out; // not used
wire [ 3:0] awlen_out;
wire [ 9:0] awaddr_out;
// SuppressWarnings VEditor all
wire [11:0] awid_out; // not used
wire w_nempty;
wire w_half_full;
assign wready=~w_half_full;
wire [31:0] wdata_out;
// SuppressWarnings VEditor all
wire wlast_out; // not used
wire [ 3:0] wstb_out; // WSTRB[3:0], input
wire [11:0] wid_out;
reg write_in_progress=0;
reg [ 9:0] write_address; // transfer address (not including lower bits
reg [ 3:0] write_left; // number of read transfers
// will ignore arsize - assuming always 32 bits (a*size[2:0]==2)
reg [ 1:0] wburst; // registered burst type
reg [ 3:0] wlen; // registered awlen type (for wrapped over transfers)
wire [ 9:0] next_wr_address_w; // next transfer address;
wire bram_we_w; // write BRAM memory
wire start_write_burst_w;
wire write_in_progress_w;
assign next_wr_address_w=
wburst[1]?
(wburst[0]? (10'h0):((write_address[9:0]+1) & {6'h3f, ~wlen[3:0]})):
(wburst[0]? (write_address[9:0]+1):(write_address[9:0]));
assign bram_we_w= 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)));
always @ (posedge aclk or posedge rst) begin
if (rst) wburst[1:0] <= 0;
else if (start_write_burst_w) wburst[1:0] <= awburst_out[1:0];
if (rst) wlen[3:0] <= 0;
else if (start_write_burst_w) wlen[3:0] <= awlen_out[3:0];
if (rst) write_in_progress <= 0;
else write_in_progress <= write_in_progress_w;
if (rst) write_left <= 0;
else if (start_write_burst_w) write_left <= awlen_out[3:0]; // precedence over inc
else if (bram_we_w) write_left <= write_left-1;
if (rst) write_address <= 10'b0;
else if (start_write_burst_w) write_address <= awaddr_out[9:0]; // precedence over inc
else if (bram_we_w) write_address <= next_wr_address_w;
end
// **** Write responce channel ****
wire [ 1:0] bresp_in;
assign bresp_in=2'b0;
/*
output bvalid, // BVALID, output
input bready, // BREADY, input
output [11:0] bid, // BID[11:0], output
output [ 1:0] bresp // BRESP[1:0], output
*/
/*
reg bram_reg_re_r;
always @ (posedge aclk) begin
bram_reg_re_r <= bram_reg_re_w;
end
*/
ram_1kx32_1kx32
#(
.REGISTERS(1) // 1 - registered output
)
ram_1kx32_1kx32_i
(
.rclk(aclk), // clock for read port
.raddr(read_in_progress?read_address[9:0]:10'h3ff), // read address
// .ren(read_in_progress_or) , // read port enable
.ren(bram_reg_re_w) , // read port enable
.regen(bram_reg_re_w), // output register enable
// .regen(bram_reg_re_r), // output register enable
.data_out(rdata[31:0]), // data out
.wclk(aclk), // clock for read port
.waddr(write_address[9:0]), // write address
.we(bram_we_w), // write port enable
.web(wstb_out[3:0]), // write byte enable
.data_in(wdata_out[31:0]) // data out
);
fifo_same_clock #( .DATA_WIDTH(30),.DATA_DEPTH(4))
raddr_i (
.rst(rst),
.clk(aclk),
.we(arvalid && arready),
.re(start_read_burst_w),
.data_in({arid[11:0], arburst[1:0],arsize[1:0],arlen[3:0],araddr[11:2]}),
.data_out({arid_out[11:0], arburst_out[1:0],arsize_out[1:0],arlen_out[3:0],araddr_out[9:0]}),
.nempty(ar_nempty),
.full(),
.half_full(ar_half_full)
);
fifo_same_clock #( .DATA_WIDTH(30),.DATA_DEPTH(4))
waddr_i (
.rst(rst),
.clk(aclk),
.we(awvalid && awready),
.re(start_write_burst_w),
.data_in({awid[11:0], awburst[1:0],awsize[1:0],awlen[3:0],awaddr[11:2]}),
.data_out({awid_out[11:0], awburst_out[1:0],awsize_out[1:0],awlen_out[3:0],awaddr_out[9:0]}),
.nempty(aw_nempty),
.full(),
.half_full(aw_half_full)
);
fifo_same_clock #( .DATA_WIDTH(49),.DATA_DEPTH(4))
wdata_i (
.rst(rst),
.clk(aclk),
.we(wvalid && wready),
.re(bram_we_w), //start_write_burst_w), // wrong
.data_in({wid[11:0],wlast,wstb[3:0],wdata[31:0]}),
.data_out({wid_out[11:0],wlast_out,wstb_out[3:0],wdata_out[31:0]}),
.nempty(w_nempty),
.full(),
.half_full(w_half_full)
);
fifo_same_clock #( .DATA_WIDTH(14),.DATA_DEPTH(4))
wresp_i (
.rst(rst),
.clk(aclk),
.we(bram_we_w),
.re(bready && bvalid),
.data_in({wid_out[11:0],bresp_in[1:0]}),
.data_out({bid[11:0],bresp[1:0]}),
.nempty(bvalid),
.full(),
.half_full()
);
endmodule
x393-27c9f81a8104ee48d3599d85e6eb021174a1dcd5/axi/axibram_read.v 0000664 0000000 0000000 00000027164 12456063403 0022556 0 ustar 00root root 0000000 0000000 /*******************************************************************************
* Module: axibram_read
* Date:2014-03-18
* Author: Andrey Filippov
* Description: Read block RAM memory over AXI PS Master GP0
*
* Copyright (c) 2014 Elphel, Inc.
* axibram_read.v is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* axibram_read.v is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*******************************************************************************/
module axibram_read #(
parameter ADDRESS_BITS = 10 // number of memory address bits
)(
input aclk, // clock - should be buffered
// input aresetn, // reset, active low
input rst, // reset, active high
// AXI Read Address
input [31:0] araddr, // ARADDR[31:0], input
input arvalid, // ARVALID, input
output arready, // ARREADY, output
input [11:0] arid, // ARID[11:0], input
// input [ 1:0] arlock, // ARLOCK[1:0], input
// input [ 3:0] archache,// ARCACHE[3:0], input
// input [ 2:0] arprot, // ARPROT[2:0], input
input [ 3:0] arlen, // ARLEN[3:0], input
input [ 1:0] arsize, // ARSIZE[1:0], input
input [ 1:0] arburst, // ARBURST[1:0], input
// input [ 3:0] adqos, // ARQOS[3:0], input
// AXI Read Data
output [31:0] rdata, // RDATA[31:0], output
output reg rvalid, // RVALID, output
input rready, // RREADY, input
output reg [11:0] rid, // RID[11:0], output
output reg rlast, // RLAST, output
output [ 1:0] rresp,
// External memory synchronization
output [ADDRESS_BITS-1:0] pre_araddr, // same as awaddr_out, early address to decode and return dev_ready
output start_burst, // start of read burst, valid pre_araddr, save externally to control ext. dev_ready multiplexer
input dev_ready, // extrernal combinatorial ready signal, multiplexed from different sources according to pre_araddr@start_burst
// External memory interface
output bram_rclk, // .rclk(aclk), // clock for read port
output [ADDRESS_BITS-1:0] bram_raddr, // .raddr(read_in_progress?read_address[9:0]:10'h3ff), // read address
output bram_ren, // .ren(bram_reg_re_w) , // read port enable
output bram_regen, // .regen(bram_reg_re_w), // output register enable
input [31:0] bram_rdata // .data_out(rdata[31:0]), // data out
// RRESP[1:0], output
);
// **** AXI Read channel ****
wire ar_nempty;
wire ar_half_full;
assign arready=~ar_half_full;
wire [ 1:0] arburst_out;
// SuppressWarnings VEditor all
wire [ 1:0] arsize_out; // not used
wire [ 3:0] arlen_out;
wire [ADDRESS_BITS-1:0] araddr_out;
wire [11:0] arid_out;
// wire rst=~aresetn;
reg read_in_progress=0;
reg read_in_progress_d=0; // delayed by one active cycle (not skipped)
reg read_in_progress_or=0; // read_in_progress || read_in_progress_d
reg [ADDRESS_BITS-1:0] read_address; // transfer address (not including lower bits
reg [ 3:0] read_left; // number of read transfers
// will ignore arsize - assuming always 32 bits (a*size[2:0]==2)
reg [ 1:0] rburst; // registered burst type
reg [ 3:0] rlen; // registered burst type
wire [ADDRESS_BITS-1:0] next_rd_address_w; // next transfer address;
assign next_rd_address_w= //SuppressThisWarning ISExst Result of 32-bit expression is truncated to fit in 13-bit target.
rburst[1]?
(rburst[0]? {ADDRESS_BITS{1'b0}}:((read_address[ADDRESS_BITS-1:0]+1) & {{(ADDRESS_BITS-4){1'b1}}, ~rlen[3:0]})):
(rburst[0]? (read_address[ADDRESS_BITS-1:0]+1):(read_address[ADDRESS_BITS-1:0]));
wire start_read_burst_w;
// wire bram_re_w;
wire bram_reg_re_w;
wire read_in_progress_w;
wire read_in_progress_d_w;
wire last_in_burst_w;
wire last_in_burst_d_w;
reg pre_last_in_burst_r;
assign rresp=2'b0;
// reduce combinatorial delay from rready (use it in final mux)
// assign bram_reg_re_w= read_in_progress && (!rvalid || rready);
// assign start_read_burst_w=ar_nempty && (!read_in_progress || (bram_reg_re_w && (read_left==4'b0))); // reduce delay from arready
assign last_in_burst_w= bram_reg_re_w && (read_left==4'b0);
assign last_in_burst_d_w=bram_reg_re_w && pre_last_in_burst_r;
// make sure ar_nempty is updated
// assign start_read_burst_w=ar_nempty && (!read_in_progress || last_in_burst_w); // reduce delay from arready
assign read_in_progress_w= start_read_burst_w || (read_in_progress && !last_in_burst_w); // reduce delay from arready
assign read_in_progress_d_w=(read_in_progress && bram_reg_re_w) ||
(read_in_progress && !last_in_burst_d_w); // reduce delay from arready
// assign read_in_progress_d_w=read_in_progress_d;
wire pre_rvalid_w;
assign pre_rvalid_w=bram_reg_re_w || (rvalid && !rready);
wire pre_left_zero_w;
// TODO: Speed up by moving registers
// SuppressWarnings VEditor all - not yet used
reg bram_reg_re_0;
// SuppressWarnings VEditor all - not yet used
reg last_in_burst_1;
// SuppressWarnings VEditor all - not yet used
reg last_in_burst_0;
// SuppressWarnings VEditor all - not yet used
reg start_read_burst_0;
// SuppressWarnings VEditor all - not yet used
reg start_read_burst_1;
reg [11:0] pre_rid0;
reg [11:0] pre_rid;
// External memory interface - synchronization with ready
assign pre_araddr= araddr_out[ADDRESS_BITS-1:0];
assign start_burst= start_read_burst_w;
//input dev_ready, // extrernal combinatorial ready signal, multiplexed from different sources according to pre_araddr@start_burst
// External memory interface
assign bram_rclk = aclk; // clock for read port
assign bram_raddr = read_in_progress?read_address[ADDRESS_BITS-1:0]:{ADDRESS_BITS{1'b1}}; // read address
assign bram_ren = bram_reg_re_w; // read port enable
assign bram_regen = bram_reg_re_w; // output register enable
assign rdata[31:0] = bram_rdata; // data out
always @ (posedge aclk or posedge rst) begin
if (rst) pre_last_in_burst_r <= 0;
// else if (start_read_burst_w) pre_last_in_burst_r <= (read_left==4'b0);
else if (bram_reg_re_w) pre_last_in_burst_r <= (read_left==4'b0);
if (rst) rburst[1:0] <= 0;
else if (start_read_burst_w) rburst[1:0] <= arburst_out[1:0];
if (rst) rlen[3:0] <= 0;
else if (start_read_burst_w) rlen[3:0] <= arlen_out[3:0];
if (rst) read_in_progress <= 0;
else read_in_progress <= read_in_progress_w;
if (rst) read_in_progress_d <= 0;
// else read_in_progress_d <= read_in_progress_d_w;
else if (bram_reg_re_w) read_in_progress_d <= read_in_progress_d_w;
if (rst) read_in_progress_or <= 0;
// else read_in_progress_or <= read_in_progress_d_w || read_in_progress_w;
// else if (bram_reg_re_w) read_in_progress_or <= read_in_progress_d_w || read_in_progress_w;
// FIXME:
else if (bram_reg_re_w || !read_in_progress_or) read_in_progress_or <= read_in_progress_d_w || read_in_progress_w;
// reg read_in_progress_d=0; // delayed by one active cycle (not skipped)
// reg read_in_progress_or=0; // read_in_progress || read_in_progress_d
if (rst) read_left <= 0;
else if (start_read_burst_w) read_left <= arlen_out[3:0]; // precedence over inc
else if (bram_reg_re_w) read_left <= read_left-1; //SuppressThisWarning ISExst Result of 32-bit expression is truncated to fit in 4-bit target.
if (rst) read_address <= {ADDRESS_BITS{1'b0}};
else if (start_read_burst_w) read_address <= araddr_out[ADDRESS_BITS-1:0]; // precedence over inc
else if (bram_reg_re_w) read_address <= next_rd_address_w;
if (rst) rvalid <= 1'b0;
else if (bram_reg_re_w && read_in_progress_d) rvalid <= 1'b1;
else if (rready) rvalid <= 1'b0;
if (rst) rlast <= 1'b0;
else if (last_in_burst_d_w) rlast <= 1'b1;
else if (rready) rlast <= 1'b0;
end
always @ (posedge aclk) begin //SuppressThisWarning ISExst Assignment to bram_reg_re_0 ignored, since the identifier is never used
// bram_reg_re_0 <= read_in_progress_w && !pre_rvalid_w;
bram_reg_re_0 <= (ar_nempty && !read_in_progress) || (read_in_progress && !read_in_progress);
last_in_burst_1 <= read_in_progress_w && pre_left_zero_w;
last_in_burst_0 <= read_in_progress_w && !pre_rvalid_w && pre_left_zero_w;
start_read_burst_1 <= !read_in_progress_w || pre_left_zero_w;
start_read_burst_0 <= !read_in_progress_w || (!pre_rvalid_w && pre_left_zero_w);
if (start_read_burst_w) pre_rid0[11:0] <= arid_out[11:0];
if (bram_reg_re_w) pre_rid[11:0] <= pre_rid0[11:0];
if (bram_reg_re_w) rid[11:0] <= pre_rid[11:0];
end
// reducing rready combinatorial delay
assign pre_left_zero_w=start_read_burst_w?(arlen_out[3:0]==4'b0):(bram_reg_re_w && (read_left==4'b0001));
// assign bram_reg_re_w= read_in_progress && (!rvalid || rready);
assign bram_reg_re_w= dev_ready && read_in_progress_or && (!rvalid || rready); // slower/simplier
// assign bram_reg_re_w= rready? read_in_progress : bram_reg_re_0; // faster - more verification
assign last_in_burst_w=bram_reg_re_w && (read_left==4'b0); // slower/simplier
// assign last_in_burst_w=rready? (read_in_progress && (read_left==4'b0)): (bram_reg_re_0 && (read_left==4'b0));
// assign last_in_burst_w=rready? last_in_burst_1: last_in_burst_0; // faster (unfinished) - more verification
assign start_read_burst_w=ar_nempty && (!read_in_progress || (bram_reg_re_w && (read_left==4'b0))); // reduce delay from rready
// assign start_read_burst_w=ar_nempty && (!read_in_progress || ((rready? read_in_progress : bram_reg_re_0) && (read_left==4'b0)));
// assign start_read_burst_w=
// rready?
// (ar_nempty && (!read_in_progress || ((read_in_progress) && (read_left==4'b0)))):
// (ar_nempty && (!read_in_progress || ((bram_reg_re_0 ) && (read_left==4'b0))));
/*
assign start_read_burst_w=
ar_nempty*(rready?
(!read_in_progress || (read_left==4'b0)):
((!read_in_progress || ((bram_reg_re_0 ) && (read_left==4'b0)))));
*/
// assign start_read_burst_w= ar_nempty && (rready?start_read_burst_1:start_read_burst_0);
fifo_same_clock #( .DATA_WIDTH(ADDRESS_BITS+20),.DATA_DEPTH(4))
raddr_i (
.rst(rst),
.clk(aclk),
.we(arvalid && arready),
.re(start_read_burst_w),
.data_in({arid[11:0], arburst[1:0],arsize[1:0],arlen[3:0],araddr[ADDRESS_BITS+1:2]}),
.data_out({arid_out[11:0], arburst_out[1:0],arsize_out[1:0],arlen_out[3:0],araddr_out[ADDRESS_BITS-1:0]}), //SuppressThisWarning ISExst Assignment to arsize ignored, since the identifier is never used
.nempty(ar_nempty),
.half_full(ar_half_full)
);
endmodule
x393-27c9f81a8104ee48d3599d85e6eb021174a1dcd5/axi/axibram_write.v 0000664 0000000 0000000 00000025244 12456063403 0022772 0 ustar 00root root 0000000 0000000 /*******************************************************************************
* Module: axibram_write
* Date:2014-03-18
* Author: Andrey Filippov
* Description: Read block RAM memory (or memories?) over AXI PS Master GP0
* Memory is supposed to be fast enough
*
* Copyright (c) 2014 Elphel, Inc.
* axibram_write.v is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* axibram_write.v is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*******************************************************************************/
`define DEBUG_FIFO 1
module axibram_write #(
parameter ADDRESS_BITS = 10 // number of memory address bits
)(
input aclk, // clock - should be buffered
// input aresetn, // reset, active low
input rst, // reset, active highw
// AXI Write Address
input [31:0] awaddr, // AWADDR[31:0], input
input awvalid, // AWVALID, input
output awready, // AWREADY, output
input [11:0] awid, // AWID[11:0], input
// input [ 1:0] awlock, // AWLOCK[1:0], input
// input [ 3:0] awcache, // AWCACHE[3:0], input
// input [ 2:0] awprot, // AWPROT[2:0], input
input [ 3:0] awlen, // AWLEN[3:0], input
input [ 1:0] awsize, // AWSIZE[1:0], input
input [ 1:0] awburst, // AWBURST[1:0], input
// input [ 3:0] awqos, // AWQOS[3:0], input
// AXI PS Master GP0: Write Data
input [31:0] wdata, // WDATA[31:0], input
input wvalid, // WVALID, input
output wready, // WREADY, output
input [11:0] wid, // WID[11:0], input
input wlast, // WLAST, input
input [ 3:0] wstb, // WSTRB[3:0], input
// AXI PS Master GP0: Write Responce
output bvalid, // BVALID, output
input bready, // BREADY, input
output [11:0] bid, // BID[11:0], output
output [ 1:0] bresp, // BRESP[1:0], output
// BRAM (and other write modules) interface
output [ADDRESS_BITS-1:0] pre_awaddr, // same as awaddr_out, early address to decode and return dev_ready
output start_burst, // start of write burst, valid pre_awaddr, save externally to control ext. dev_ready multiplexer
input dev_ready, // extrernal combinatorial ready signal, multiplexed from different sources according to pre_awaddr@start_burst
output bram_wclk,
output [ADDRESS_BITS-1:0] bram_waddr,
output bram_wen, // external memory wreite enable, (internally combined with registered dev_ready
output [3:0] bram_wstb,
output [31:0] bram_wdata
`ifdef DEBUG_FIFO
,
output waddr_under,
output wdata_under,
output wresp_under,
output waddr_over,
output wdata_over,
output wresp_over,
output [3:0] waddr_wcount,
output [3:0] waddr_rcount,
output [3:0] waddr_num_in_fifo,
output [3:0] wdata_wcount,
output [3:0] wdata_rcount,
output [3:0] wdata_num_in_fifo,
output [3:0] wresp_wcount,
output [3:0] wresp_rcount,
output [3:0] wresp_num_in_fifo,
output [3:0] wleft,
output [3:0] wlength,
output reg [3:0] wlen_in_dbg
`endif
);
// wire rst=~aresetn;
// **** Write channel: ****
wire aw_nempty;
wire aw_half_full;
assign awready=~aw_half_full;
wire [ 1:0] awburst_out;
// SuppressWarnings VEditor all
wire [ 1:0] awsize_out; // not used
wire [ 3:0] awlen_out;
wire [ADDRESS_BITS-1:0] awaddr_out;
// SuppressWarnings VEditor all
wire [11:0] awid_out; // not used
wire w_nempty;
wire w_half_full;
assign wready=~w_half_full;
wire [31:0] wdata_out;
// SuppressWarnings VEditor all
wire wlast_out; // not used
wire [ 3:0] wstb_out; // WSTRB[3:0], input
wire [11:0] wid_out;
reg write_in_progress=0;
reg [ADDRESS_BITS-1:0] write_address; // transfer address (not including lower bits
reg [ 3:0] write_left; // number of write transfers
// will ignore arsize - assuming always 32 bits (a*size[2:0]==2)
reg [ 1:0] wburst; // registered burst type
reg [ 3:0] wlen; // registered awlen type (for wrapped over transfers)
wire [ADDRESS_BITS-1:0] next_wr_address_w; // next transfer address;
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= //SuppressThisWarning ISExst Result of 32-bit expression is truncated to fit in 13-bit target.
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_ready && write_in_progress;
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_ready || (write_in_progress && !(w_nempty_ready && (write_left[3:0]==4'b0)));
assign write_in_progress_w=w_nempty_ready && 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;
else if (start_write_burst_w) wburst[1:0] <= awburst_out[1:0];
if (rst) wlen[3:0] <= 0;
else if (start_write_burst_w) wlen[3:0] <= awlen_out[3:0];
if (rst) write_in_progress <= 0;
else write_in_progress <= write_in_progress_w;
if (rst) write_left <= 0;
else if (start_write_burst_w) write_left <= awlen_out[3:0]; // precedence over inc
else if (bram_we_w) write_left <= write_left-1; //SuppressThisWarning ISExst Result of 32-bit expression is truncated to fit in 4-bit target.
if (rst) write_address <= {ADDRESS_BITS{1'b0}};
else if (start_write_burst_w) write_address <= awaddr_out[ADDRESS_BITS-1:0]; // precedence over inc
else if (bram_we_w) write_address <= next_wr_address_w;
if (rst) dev_ready_r <= 1'b0;
else dev_ready_r <= dev_ready;
end
// **** Write responce channel ****
wire [ 1:0] bresp_in;
assign bresp_in=2'b0;
/*
output bvalid, // BVALID, output
input bready, // BREADY, input
output [11:0] bid, // BID[11:0], output
output [ 1:0] bresp // BRESP[1:0], output
*/
/*
reg bram_reg_re_r;
always @ (posedge aclk) begin
bram_reg_re_r <= bram_reg_re_w;
end
*/
// external memory interface (write only)
assign pre_awaddr=awaddr_out[ADDRESS_BITS-1:0];
assign start_burst=start_write_burst_w;
assign bram_wclk = aclk;
assign bram_waddr = write_address[ADDRESS_BITS-1:0];
assign bram_wen = bram_we_w;
assign bram_wstb = wstb_out[3:0];
assign bram_wdata = wdata_out[31:0];
`ifdef DEBUG_FIFO
assign wleft=write_left;
assign wlength[3:0]=wlen[3:0];
always @ (posedge aclk) begin
wlen_in_dbg <= awlen[3:0];
end
`endif
fifo_same_clock #( .DATA_WIDTH(20+ADDRESS_BITS),.DATA_DEPTH(4))
waddr_i (
.rst (rst),
.clk (aclk),
.we (awvalid && awready),
.re (start_write_burst_w),
.data_in ({awid[11:0], awburst[1:0],awsize[1:0],awlen[3:0],awaddr[ADDRESS_BITS+1:2]}),
.data_out ({awid_out[11:0], awburst_out[1:0],awsize_out[1:0],awlen_out[3:0],awaddr_out[ADDRESS_BITS-1:0]}), //SuppressThisWarning ISExst Assignment to awsize_out ignored, since the identifier is never used
.nempty (aw_nempty),
.half_full (aw_half_full)
`ifdef DEBUG_FIFO
,
.under (waddr_under), // output reg
.over (waddr_over), // output reg
.wcount (waddr_wcount), // output[3:0] reg
.rcount (waddr_rcount), // output[3:0] reg
.num_in_fifo(waddr_num_in_fifo) // output[3:0]
`endif
);
fifo_same_clock #( .DATA_WIDTH(49),.DATA_DEPTH(4))
wdata_i (
.rst(rst),
.clk(aclk),
.we(wvalid && wready),
.re(bram_we_w), //start_write_burst_w), // wrong
.data_in({wid[11:0],wlast,wstb[3:0],wdata[31:0]}),
.data_out({wid_out[11:0],wlast_out,wstb_out[3:0],wdata_out[31:0]}), //SuppressThisWarning ISExst Assignment to wlast ignored, since the identifier is never used
.nempty(w_nempty),
.half_full(w_half_full)
`ifdef DEBUG_FIFO
,
.under (wdata_under), // output reg
.over (wdata_over), // output reg
.wcount (wdata_wcount), // output[3:0] reg
.rcount (wdata_rcount), // output[3:0] reg
.num_in_fifo(wdata_num_in_fifo) // output[3:0]
`endif
);
//debugging - slow down bresp
reg was_bresp_re=0;
wire bresp_re;
assign bresp_re=bready && bvalid && !was_bresp_re;
always @ (posedge rst or posedge aclk) begin
if (rst) was_bresp_re<=0;
else was_bresp_re <= bresp_re;
end
fifo_same_clock #( .DATA_WIDTH(14),.DATA_DEPTH(4))
wresp_i (
.rst(rst),
.clk(aclk),
.we(bram_we_w),
// .re(bready && bvalid),
.re(bresp_re), // not allowing RE next cycle after bvalid
.data_in({wid_out[11:0],bresp_in[1:0]}),
.data_out({bid[11:0],bresp[1:0]}),
.nempty(bvalid),
.half_full()
`ifdef DEBUG_FIFO
,
.under (wresp_under), // output reg
.over (wresp_over), // output reg
.wcount (wresp_wcount), // output[3:0] reg
.rcount (wresp_rcount), // output[3:0] reg
.num_in_fifo(wresp_num_in_fifo) // output[3:0]
`endif
);
endmodule
x393-27c9f81a8104ee48d3599d85e6eb021174a1dcd5/axi/macros393.v 0000664 0000000 0000000 00000003141 12456063403 0021650 0 ustar 00root root 0000000 0000000 /*
** -----------------------------------------------------------------------------**
** macros353.v
**
** temporary, modules to be moved
**
** Copyright (C) 2002 Elphel, Inc
**
** -----------------------------------------------------------------------------**
** This file is part of X353
** X353 is free software - hardware description language (HDL) code.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see .
** -----------------------------------------------------------------------------**
**
*/
module ram_WxD
#(
parameter integer DATA_WIDTH=16,
parameter integer DATA_DEPTH=4,
parameter integer DATA_2DEPTH=(1<