Commit 1153e80a authored by Andrey Filippov's avatar Andrey Filippov

Switching 103993-> 10399A hardware

parent 71b73ccb
......@@ -2004,7 +2004,21 @@ simul_axi_hp_wr #(
.uart_in (sns1_dp[4]), // input sns_txd
.uart_out (sns1_dn[4]) // output sns_rxd
);
`ifdef BOSON_REVA // 103993 REVA board
simul_103993A_serializer #(
.PCLK_FREQ_MHZ(BOSON_FPS * 0.45) // 27.0)
) simul_103993_serializer_1_i (
.ta({2'b10, boson_pxd1[ 4: 0]}), // input[6:0]
.tb({2'b10, boson_pxd1[ 9: 5]}), // input[6:0]
.tc({2'b10, boson_pxd1[14:10]}), // input[6:0]
.td({3'b100,boson_dvalid1, boson_vsync1,boson_hsync1,boson_pxd1[15]}), // input[6:0]
.pclk(boson_pclk1), // input
.dp(sns1_dp[3:0]), // output[3:0]
.dn(sns1_dn[3:0]), // output[3:0]
.clkp(sns1_clkp), // output
.clkn(sns1_clkn) // output
);
`else
simul_103993_serializer #(
.PCLK_FREQ_MHZ(BOSON_FPS * 0.45) // 27.0)
) simul_103993_serializer_1_i (
......@@ -2020,7 +2034,7 @@ simul_axi_hp_wr #(
.clkp (sns1_clkp), // output
.clkn (sns1_clkn) // output
);
`endif
simul_boson640 #(
.DATA_FILE (BOSON_DATA_FILE), // "/input_data/pattern_160_120_16.dat"),
.WIDTH (BOSON_WIDTH), // 160), 640),
......@@ -2044,7 +2058,21 @@ simul_axi_hp_wr #(
.uart_in (sns2_dp[4]), // input sns_txd
.uart_out (sns2_dn[4]) // output sns_rxd
);
`ifdef BOSON_REVA // 103993 REVA board
simul_103993A_serializer #(
.PCLK_FREQ_MHZ(BOSON_FPS * 0.45) // 27.0)
) simul_103993_serializer_2_i (
.ta({2'b10, boson_pxd2[ 4: 0]}), // input[6:0]
.tb({2'b10, boson_pxd2[ 9: 5]}), // input[6:0]
.tc({2'b10, boson_pxd2[14:10]}), // input[6:0]
.td({3'b100,boson_dvalid2, boson_vsync2,boson_hsync2,boson_pxd2[15]}), // input[6:0]
.pclk(boson_pclk2), // input
.dp(sns2_dp[3:0]), // output[3:0]
.dn(sns2_dn[3:0]), // output[3:0]
.clkp(sns2_clkp), // output
.clkn(sns2_clkn) // output
);
`else
simul_103993_serializer #(
.PCLK_FREQ_MHZ(BOSON_FPS * 0.45) // 27.0)
) simul_103993_serializer_2_i (
......@@ -2060,6 +2088,7 @@ simul_axi_hp_wr #(
.clkp (sns2_clkp), // output
.clkn (sns2_clkn) // output
);
`endif
simul_boson640 #(
.DATA_FILE (BOSON_DATA_FILE), // "/input_data/pattern_160_120_16.dat"),
......@@ -2085,6 +2114,21 @@ simul_axi_hp_wr #(
.uart_out (sns3_dn[4]) // output sns_rxd
);
`ifdef BOSON_REVA // 103993 REVA board
simul_103993A_serializer #(
.PCLK_FREQ_MHZ(BOSON_FPS * 0.45) // 27.0)
) simul_103993_serializer_3_i (
.ta({2'b10, boson_pxd3[ 4: 0]}), // input[6:0]
.tb({2'b10, boson_pxd3[ 9: 5]}), // input[6:0]
.tc({2'b10, boson_pxd3[14:10]}), // input[6:0]
.td({3'b100,boson_dvalid3, boson_vsync3,boson_hsync3,boson_pxd3[15]}), // input[6:0]
.pclk(boson_pclk3), // input
.dp(sns3_dp[3:0]), // output[3:0]
.dn(sns3_dn[3:0]), // output[3:0]
.clkp(sns3_clkp), // output
.clkn(sns3_clkn) // output
);
`else
simul_103993_serializer #(
.PCLK_FREQ_MHZ(BOSON_FPS * 0.45) // 27.0)
) simul_103993_serializer_3_i (
......@@ -2100,6 +2144,7 @@ simul_axi_hp_wr #(
.clkp (sns3_clkp), // output
.clkn (sns3_clkn) // output
);
`endif
simul_boson640 #(
.DATA_FILE (BOSON_DATA_FILE), // "/input_data/pattern_160_120_16.dat"),
......@@ -2124,7 +2169,21 @@ simul_axi_hp_wr #(
.uart_in (sns4_dp[4]), // input sns_txd
.uart_out (sns4_dn[4]) // output sns_rxd
);
`ifdef BOSON_REVA // 103993 REVA board
simul_103993A_serializer #(
.PCLK_FREQ_MHZ(BOSON_FPS * 0.45) // 27.0)
) simul_103993_serializer_4_i (
.ta({2'b10, boson_pxd4[ 4: 0]}), // input[6:0]
.tb({2'b10, boson_pxd4[ 9: 5]}), // input[6:0]
.tc({2'b10, boson_pxd4[14:10]}), // input[6:0]
.td({3'b100,boson_dvalid4, boson_vsync4,boson_hsync4,boson_pxd4[15]}), // input[6:0]
.pclk(boson_pclk4), // input
.dp(sns4_dp[3:0]), // output[3:0]
.dn(sns4_dn[3:0]), // output[3:0]
.clkp(sns4_clkp), // output
.clkn(sns4_clkn) // output
);
`else
simul_103993_serializer #(
.PCLK_FREQ_MHZ(BOSON_FPS * 0.45) // 27.0)
) simul_103993_serializer_4_i (
......@@ -2140,9 +2199,7 @@ simul_axi_hp_wr #(
.clkp (sns4_clkp), // output
.clkn (sns4_clkn) // output
);
`endif
`else
......
......@@ -35,7 +35,8 @@
* contains all the components and scripts required to completely simulate it
* with at least one of the Free Software programs.
*/
parameter FPGA_VERSION = 32'h03934006; // Boson640, adjusted initial phase to 70.5 degrees (47 counts)
parameter FPGA_VERSION = 32'h03934010; // Boson640, for 103993A
// parameter FPGA_VERSION = 32'h03934006; // Boson640, adjusted initial phase to 70.5 degrees (47 counts)
// parameter FPGA_VERSION = 32'h03934005; // Boson640, testing
// parameter FPGA_VERSION = 32'h03934005; // Boson640, implementing DRP to control MMCME2/PLLE2 trying more BUFR
// parameter FPGA_VERSION = 32'h03934004; // Boson640, implementing DRP to control MMCME2/PLLE2
......
......@@ -727,12 +727,17 @@
`endif
`elsif BOSON
parameter CLKIN_PERIOD_SENSOR = 37.037, // input period in ns, 0..100.000 - MANDATORY, resolution down to 1 ps
`ifdef BOSON_REVA
parameter CLKFBOUT_MULT_SENSOR = 35, // 945 MHz 28, // 27 MHz --> 756 MHz
`else
parameter CLKFBOUT_MULT_SENSOR = 30, // 27 MHz --> 810 MHz (3*270MHz)
`endif
//MMCME2_ADV_i has a CLKFBOUT_PHASE value (-20.000) with CLKFBOUT_USE_FINE_PS set to FALSE. It should be a multiple of [45 / CLKFBOUT_MULT_F] = [45 / 30.000] = 1.500.
`ifdef SIMULATION
parameter CLKFBOUT_PHASE_SENSOR = 54.0, // CLOCK FEEDBACK phase in degrees (3 significant digits, -360.000...+360.000)
`else
parameter CLKFBOUT_PHASE_SENSOR = 70.5, // -22.5, // -21.0, // 19.5, // CLOCK FEEDBACK phase in degrees (3 significant digits, -360.000...+360.000)
//It should be a multiple of [45 / CLKFBOUT_MULT_F] = [45 / 35.000] = 1.286
parameter CLKFBOUT_PHASE_SENSOR = 0.0, // 70.5, // -22.5, // -21.0, // 19.5, // CLOCK FEEDBACK phase in degrees (3 significant digits, -360.000...+360.000)
`endif
parameter PCLK_PHASE = 0.000, // not used
parameter IPCLK1X_PHASE = 0.000, // -3.000, // trying both ways (PCLK_PHASE inside sens_103993)
......@@ -850,7 +855,11 @@
//`ifdef HISPI
parameter HISPI_MSB_FIRST = 0,
`ifdef BOSON
`ifdef BOSON_REVA
parameter HISPI_NUMLANES = 4,
`else
parameter HISPI_NUMLANES = 3,
`endif
`else
parameter HISPI_NUMLANES = 4,
`endif
......
......@@ -1951,7 +1951,8 @@ uart_print_packet 0 False False
ClkReg1, ClkReg2 = self.drp_phase_addr(clk_out)
data1 = self.drp_read_reg(num_sensor, ClkReg1)
data2 = self.drp_read_reg(num_sensor, ClkReg2)
phase = ((data1 >> 13) & 7) | ((data2 & 0x1f) << 3)
# phase = ((data1 >> 13) & 7) | ((data2 & 0x1f) << 3)
phase = ((data1 >> 13) & 7) | ((data2 & 0x3f) << 3)
return phase
def drp_write_clock_phase(self,
......@@ -1967,9 +1968,9 @@ uart_print_packet 0 False False
ClkReg1, ClkReg2 = self.drp_phase_addr(clk_out)
data1 = (phase & 7) << 13
data2 = (phase >> 3) & 0x1f
data2 = (phase >> 3) & 0x3f
self.drp_write_reg(num_sensor, addr=ClkReg1, data=data1, mask=0xe000)
self.drp_write_reg(num_sensor, addr=ClkReg2, data=data2, mask=0x001f)
self.drp_write_reg(num_sensor, addr=ClkReg2, data=data2, mask=0x003f)
def jtag_get_tdo(self, chn):
seq_num = ((self.get_status_sensor_io(num_sensor = chn) >> 26) + 1) & 0x3f
......
......@@ -118,7 +118,11 @@ module sens_103993 #(
parameter SENS_SS_MOD_PERIOD = 10000, // integer 4000-40000 - SS modulation period in ns
// parameter LVDS_MSB_FIRST = 0,
`ifdef BOSON_REVA
parameter NUMLANES = 4,
`else
parameter NUMLANES = 3,
`endif
parameter LVDS_DELAY_CLK = "FALSE",
parameter LVDS_MMCM = "TRUE",
parameter LVDS_CAPACITANCE = "DONT_CARE",
......@@ -283,7 +287,11 @@ module sens_103993 #(
wire senspgmin; // detect sensorboard
// GP0..GP3 are not yet used, fake-use gp_comb to keep
wire [3:0] gp;
`ifdef BOSON_REVA
wire [0:0] dummy; // to keep iostandard of unused pins in a bank
`else
wire [2:0] dummy; // to keep iostandard of unused pins in a bank
`endif
wire gp_comb = (^gp[3:0]) ^ (^dummy);
reg test_patt;
reg [7:0] perr_cntr;
......@@ -483,13 +491,76 @@ module sens_103993 #(
wire clkin_pxd_stopped_mmcm1;
wire clkfb_pxd_stopped_mmcm1;
*/
`ifdef USE_SERIALIZER_103993
`ifdef BOSON_REVA
sens_103993A_lanes #(
.IODELAY_GRP (IODELAY_GRP),
.IDELAY_VALUE (IDELAY_VALUE),
.REFCLK_FREQUENCY (REFCLK_FREQUENCY),
.HIGH_PERFORMANCE_MODE (HIGH_PERFORMANCE_MODE),
.SENS_BANDWIDTH (SENS_BANDWIDTH),
.CLKIN_PERIOD_SENSOR (CLKIN_PERIOD_SENSOR), // 37.037),
.CLKFBOUT_MULT_SENSOR (CLKFBOUT_MULT_SENSOR), // (30),
.CLKFBOUT_PHASE_SENSOR (CLKFBOUT_PHASE_SENSOR), // (54.0),
.PCLK_PHASE (PCLK_PHASE), // (0.000),
.IPCLK1X_PHASE (IPCLK1X_PHASE), //(0.000), // not actually used
.IPCLK2X_PHASE (IPCLK2X_PHASE), //(0.000),
.BUF_PCLK (BUF_PCLK), // "BUFR"),
.BUF_IPCLK1X (BUF_IPCLK1X),
.BUF_IPCLK2X (BUF_IPCLK2X), // "BUFR"),
.BUF_CLK_FB (BUF_CLK_FB),
.SENS_DIVCLK_DIVIDE (SENS_DIVCLK_DIVIDE), // 1),
.SENS_REF_JITTER1 (SENS_REF_JITTER1), // 0.010),
.SENS_REF_JITTER2 (SENS_REF_JITTER2), // 0.010),
.SENS_SS_EN (SENS_SS_EN), // "FALSE"),
.SENS_SS_MODE (SENS_SS_MODE), // "CENTER_HIGH"),
.SENS_SS_MOD_PERIOD (SENS_SS_MOD_PERIOD), // 10000),
.NUMLANES (NUMLANES), // 3),
.LVDS_DELAY_CLK (LVDS_DELAY_CLK), // "FALSE"),
.LVDS_MMCM (LVDS_MMCM), // "TRUE"),
.LVDS_CAPACITANCE (LVDS_CAPACITANCE), // "DONT_CARE"),
.LVDS_DIFF_TERM (LVDS_DIFF_TERM), // "TRUE"),
.LVDS_UNTUNED_SPLIT (LVDS_UNTUNED_SPLIT), // "FALSE"),
.LVDS_DQS_BIAS (LVDS_DQS_BIAS), // "TRUE"),
.LVDS_IBUF_DELAY_VALUE (LVDS_IBUF_DELAY_VALUE), // "0"),
.LVDS_IBUF_LOW_PWR (LVDS_IBUF_LOW_PWR), // "TRUE"),
.LVDS_IFD_DELAY_VALUE (LVDS_IFD_DELAY_VALUE), // "AUTO"),
.LVDS_IOSTANDARD (LVDS_IOSTANDARD), // "DIFF_SSTL18_I")
.DEGLITCH_DVALID (1),
.DEGLITCH_HSYNC (3),
.DEGLITCH_VSYNC (7)
) sens_103993_l3_i ( // same instance name
.pclk (pclk), // output
.prsts (prsts), // input,
.sns_dp (sns_dp[3:0]), // input[3:0]
.sns_dn (sns_dn[3:0]), // input[3:0]
.sns_clkp (sns_clkp), // input
.sns_clkn (sns_clkn), // input
.pxd_out (pxd_w), // output[15:0]
.vsync (vsync), // output
.hsync (hsync), // output
.dvalid (dvalid_w), // output
.mclk (mclk), // input
.mrst (mrst), // input
.dly_data (data_r[31:0]), // input[31:0]
.set_idelay ({NUMLANES{set_idelays}}),// input[2:0]
.apply_idelay (ld_idelay), // input
.set_clk_phase (set_iclk_phase), // input
.rst_mmcm (rst_mmcm), // input
.perr (perr), // output
.test_out (test_out), // output[7:0] // should be 0x17
.locked_pxd_mmcm (locked_pclk), // output
.clkin_pxd_stopped_mmcm (clkin_pxd_stopped_mmcm), // output
.clkfb_pxd_stopped_mmcm (clkfb_pxd_stopped_mmcm), // output
.drp_cmd (drp_cmd), // input[1:0]
.drp_bit (drp_bit), // output
.drp_odd_bit (drp_odd_bit) // output
);
`elsif USE_SERIALIZER_103993
sens_103993_lanes #(
.IODELAY_GRP (IODELAY_GRP),
.IDELAY_VALUE (IDELAY_VALUE),
.REFCLK_FREQUENCY (REFCLK_FREQUENCY),
.HIGH_PERFORMANCE_MODE (HIGH_PERFORMANCE_MODE),
// .SENS_PHASE_WIDTH (SENS_PHASE_WIDTH),
.SENS_BANDWIDTH (SENS_BANDWIDTH),
.CLKIN_PERIOD_SENSOR (CLKIN_PERIOD_SENSOR), // 37.037),
.CLKFBOUT_MULT_SENSOR (CLKFBOUT_MULT_SENSOR), // (30),
......@@ -767,7 +838,8 @@ module sens_103993 #(
.T (1'b0) // input
);
*/
`ifdef BOSON_REVA
`else
ibuf_ibufg #(
.CAPACITANCE (PXD_CAPACITANCE),
.IBUF_DELAY_VALUE("0"),
......@@ -788,7 +860,7 @@ module sens_103993 #(
.O(dummy[2]), // output
.I(sns_dp[3]) // input
);
`endif
// end of dummy
// pulldown to detect sensor presense
......
/*!
* <b>Module:</b>sens_103993A_clock
* @file sens_103993A_clock.v
* @date 2020-12-16
* @author Andrey Filippov
*
* @brief Recover iclk/iclk2x from the 103993 differntial clock
*
* @copyright Copyright (c) 2020 Elphel, Inc .
*
* <b>License:</b>
*
* sens_103993A_clock.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.
*
* sens_103993A_clock.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 <http://www.gnu.org/licenses/> .
*
* Additional permission under GNU GPL version 3 section 7:
* If you modify this Program, or any covered work, by linking or combining it
* with independent modules provided by the FPGA vendor only (this permission
* does not extend to any 3-rd party modules, "soft cores" or macros) under
* different license terms solely for the purpose of generating binary "bitstream"
* files and/or simulating the code, the copyright holders of this Program give
* you the right to distribute the covered work without those independent modules
* as long as the source code for them is available from the FPGA vendor free of
* charge, and there is no dependence on any encrypted modules for simulating of
* the combined code. This permission applies to you if the distributed code
* contains all the components and scripts required to completely simulate it
* with at least one of the Free Software programs.
*/
`timescale 1ns/1ps
module sens_103993A_clock#(
// parameter SENS_PHASE_WIDTH= 8, // number of bits for te phase counter (depends on divisors)
parameter SENS_BANDWIDTH = "OPTIMIZED", //"OPTIMIZED", "HIGH","LOW"
parameter CLKIN_PERIOD_SENSOR = 37.037, // input period in ns, 0..100.000 - MANDATORY, resolution down to 1 ps 1000/27.0
parameter CLKFBOUT_MULT_SENSOR = 35, // 945 MHz // 28, // 27 MHz --> 756 MHz
parameter CLKFBOUT_PHASE_SENSOR = 0.000, // CLOCK FEEDBACK phase in degrees (3 significant digits, -360.000...+360.000)
parameter PCLK_PHASE = 0.000,
parameter IPCLK2X_PHASE = 0.000,
parameter IPCLK1X_PHASE = 0.000,
parameter BUF_PCLK = "BUFR",
parameter BUF_IPCLK2X = "BUFR",
parameter BUF_IPCLK1X = "BUFR",
parameter BUF_CLK_FB = "BUFR", // was localparam BUF_CLK_FB = BUF_IPCLK2X;
parameter SENS_DIVCLK_DIVIDE = 1, // Integer 1..106. Divides all outputs with respect to CLKIN
parameter SENS_REF_JITTER1 = 0.010, // Expected jitter on CLKIN1 (0.000..0.999)
parameter SENS_REF_JITTER2 = 0.010,
parameter SENS_SS_EN = "FALSE", // Enables Spread Spectrum mode
parameter SENS_SS_MODE = "CENTER_HIGH",//"CENTER_HIGH","CENTER_LOW","DOWN_HIGH","DOWN_LOW"
parameter SENS_SS_MOD_PERIOD = 10000, // integer 4000-40000 - SS modulation period in ns
// Used with delay
parameter IODELAY_GRP = "IODELAY_SENSOR", // may need different for different channels?
parameter integer IDELAY_VALUE = 0,
parameter real REFCLK_FREQUENCY = 200.0,
parameter HIGH_PERFORMANCE_MODE = "FALSE",
parameter LVDS_DELAY_CLK = "FALSE",
parameter LVDS_MMCM = "TRUE",
parameter LVDS_CAPACITANCE = "DONT_CARE",
parameter LVDS_DIFF_TERM = "TRUE",
parameter LVDS_UNTUNED_SPLIT = "FALSE", // Very power-hungry
parameter LVDS_DQS_BIAS = "TRUE",
parameter LVDS_IBUF_DELAY_VALUE = "0",
parameter LVDS_IBUF_LOW_PWR = "TRUE",
parameter LVDS_IFD_DELAY_VALUE = "AUTO",
parameter LVDS_IOSTANDARD = "DIFF_SSTL18_I", //"DIFF_SSTL18_II" for high current (13.4mA vs 8mA)
parameter DRP_ADDRESS_LENGTH = 7,
parameter DRP_DATA_LENGTH = 16
)(
input mclk,
input mrst,
input [7:0] phase,
input set_phase,
input apply, // only used when delay, not phase
input rst_mmcm,
input clp_p,
input clk_n,
output ipclk2x, // 330 MHz
output ipclk1x, // 165 MHz
output pclk, // 27 MHz
output locked_pxd_mmcm,
output clkin_pxd_stopped_mmcm, // output
output clkfb_pxd_stopped_mmcm, // output
output for_pclk, // @posedge ipclk1x: copy 7 bits from posedge ipclk1x to negedge ipclk1x to be copief on posedge pclk
output for_pclk_last, // @posedge ipclk1x: next for_pclk will apply to last 7 bits (count 0..3)
input [1:0] drp_cmd,
output drp_bit,
output drp_odd_bit
);
localparam DELAY_FOR_PCLK = 3; // 3 ipclk1x clocks
// localparam BUF_CLK_FB = BUF_IPCLK2X;
wire pclk_pre;
wire ipclk2x_pre;
wire ipclk1x_pre;
wire clk_fb_pre;
wire clk_fb;
wire prst = mrst;
wire clk_in;
wire clk_int;
wire ipclk2x_alt; // to use for nonIOB trigger
// 3-reg sync chain
reg sync_neg_pclk;
reg sync_neg_ipclk2x;
reg [DELAY_FOR_PCLK:0] sync_neg_ipclk1x;
reg for_pclk_r;
assign for_pclk = for_pclk_r;
assign for_pclk_last = for_pclk_r & ~sync_neg_ipclk1x[DELAY_FOR_PCLK];
generate
if (LVDS_UNTUNED_SPLIT == "TRUE") begin
ibufds_ibufgds_50 #(
.CAPACITANCE (LVDS_CAPACITANCE),
.DIFF_TERM (LVDS_DIFF_TERM),
.DQS_BIAS (LVDS_DQS_BIAS),
.IBUF_DELAY_VALUE (LVDS_IBUF_DELAY_VALUE),
.IBUF_LOW_PWR (LVDS_IBUF_LOW_PWR),
.IFD_DELAY_VALUE (LVDS_IFD_DELAY_VALUE),
.IOSTANDARD (LVDS_IOSTANDARD)
) ibufds_ibufgds0_i (
.O (clk_int), // output
.I (clp_p), // input
.IB (clk_n) // input
);
// variable termination
end else if (LVDS_UNTUNED_SPLIT == "40") begin
ibufds_ibufgds_40 #(
.CAPACITANCE (LVDS_CAPACITANCE),
.DIFF_TERM (LVDS_DIFF_TERM),
.DQS_BIAS (LVDS_DQS_BIAS),
.IBUF_DELAY_VALUE (LVDS_IBUF_DELAY_VALUE),
.IBUF_LOW_PWR (LVDS_IBUF_LOW_PWR),
.IFD_DELAY_VALUE (LVDS_IFD_DELAY_VALUE),
.IOSTANDARD (LVDS_IOSTANDARD)
) ibufds_ibufgds0_i (
.O (clk_int), // output
.I (clp_p), // input
.IB (clk_n) // input
);
end else if (LVDS_UNTUNED_SPLIT == "50") begin
ibufds_ibufgds_50 #(
.CAPACITANCE (LVDS_CAPACITANCE),
.DIFF_TERM (LVDS_DIFF_TERM),
.DQS_BIAS (LVDS_DQS_BIAS),
.IBUF_DELAY_VALUE (LVDS_IBUF_DELAY_VALUE),
.IBUF_LOW_PWR (LVDS_IBUF_LOW_PWR),
.IFD_DELAY_VALUE (LVDS_IFD_DELAY_VALUE),
.IOSTANDARD (LVDS_IOSTANDARD)
) ibufds_ibufgds0_i (
.O (clk_int), // output
.I (clp_p), // input
.IB (clk_n) // input
);
end else if (LVDS_UNTUNED_SPLIT == "60") begin
ibufds_ibufgds_60 #(
.CAPACITANCE (LVDS_CAPACITANCE),
.DIFF_TERM (LVDS_DIFF_TERM),
.DQS_BIAS (LVDS_DQS_BIAS),
.IBUF_DELAY_VALUE (LVDS_IBUF_DELAY_VALUE),
.IBUF_LOW_PWR (LVDS_IBUF_LOW_PWR),
.IFD_DELAY_VALUE (LVDS_IFD_DELAY_VALUE),
.IOSTANDARD (LVDS_IOSTANDARD)
) ibufds_ibufgds0_i (
.O (clk_int), // output
.I (clp_p), // input
.IB (clk_n) // input
);
end else begin
ibufds_ibufgds #(
.CAPACITANCE (LVDS_CAPACITANCE),
.DIFF_TERM (LVDS_DIFF_TERM),
.DQS_BIAS (LVDS_DQS_BIAS),
.IBUF_DELAY_VALUE (LVDS_IBUF_DELAY_VALUE),
.IBUF_LOW_PWR (LVDS_IBUF_LOW_PWR),
.IFD_DELAY_VALUE (LVDS_IFD_DELAY_VALUE),
.IOSTANDARD (LVDS_IOSTANDARD)
) ibufds_ibufgds0_i (
.O (clk_int), // output
.I (clp_p), // input
.IB (clk_n) // input
);
end
endgenerate
generate
if (LVDS_DELAY_CLK == "TRUE") begin // Avoid - delay output is routed using general routing resources even from the clock-capable
idelay_nofine # (
.IODELAY_GRP (IODELAY_GRP),
.DELAY_VALUE (IDELAY_VALUE),
.REFCLK_FREQUENCY (REFCLK_FREQUENCY),
.HIGH_PERFORMANCE_MODE (HIGH_PERFORMANCE_MODE)
) clk_dly_i(
.clk (mclk),
.rst (mrst),
.set (apply),
.ld (set_phase),
.delay (phase[7:3]), // skip lsb, not MSB
.data_in (clk_int),
.data_out (clk_in)
);
end else begin // just testing placement
assign clk_in = clk_int;
end
endgenerate
// generate phase-shifterd pixel clock (and 2x version) from either the internal clock (that is output to the sensor) or from the clock
// received from the sensor (may need to reset MMCM after resetting sensor)
generate
if (LVDS_MMCM == "TRUE") begin
mmcm_drp #(
.CLKIN_PERIOD (CLKIN_PERIOD_SENSOR),
.BANDWIDTH (SENS_BANDWIDTH),
.CLKFBOUT_MULT_F (CLKFBOUT_MULT_SENSOR), // 28
.DIVCLK_DIVIDE (SENS_DIVCLK_DIVIDE),
.CLKFBOUT_PHASE (CLKFBOUT_PHASE_SENSOR),
.CLKOUT0_PHASE (PCLK_PHASE),
.CLKOUT1_PHASE (IPCLK2X_PHASE),
.CLKOUT2_PHASE (IPCLK1X_PHASE),
.CLKFBOUT_USE_FINE_PS("FALSE"),
.CLKOUT0_USE_FINE_PS ("FALSE"), //"TRUE"),
.CLKOUT1_USE_FINE_PS ("FALSE"), //"TRUE"),
.CLKOUT2_USE_FINE_PS ("FALSE"), //"TRUE"),
.CLKOUT0_DIVIDE_F (CLKFBOUT_MULT_SENSOR), // /35 -> 27 MHz
.CLKOUT1_DIVIDE (2*CLKFBOUT_MULT_SENSOR / 7), // /10 -> 94.5 MHz
.CLKOUT2_DIVIDE (4*CLKFBOUT_MULT_SENSOR / 7), // /20 -> 47.25 MHz
.COMPENSATION ("ZHOLD"),
.REF_JITTER1 (SENS_REF_JITTER1),
.REF_JITTER2 (SENS_REF_JITTER2),
.SS_EN (SENS_SS_EN),
.SS_MODE (SENS_SS_MODE),
.SS_MOD_PERIOD (SENS_SS_MOD_PERIOD),
.STARTUP_WAIT ("FALSE"),
.DRP_ADDRESS_LENGTH (DRP_ADDRESS_LENGTH),
.DRP_DATA_LENGTH (DRP_DATA_LENGTH)
) mmcm_or_pll_i (
.clkin1 (clk_in), // input 27MHz
.clkin2 (1'b0), // input
.sel_clk2 (1'b0), // input
.clkfbin (clk_fb), // input
.rst (rst_mmcm), // input
.pwrdwn (1'b0), // input
.clkout0 (pclk_pre), // output -> 27 MHz
.clkout1 (ipclk2x_pre), // output 135 Mhz
.clkout2 (ipclk1x_pre), // output 67.5 MHz
.clkout3 (), // output
.clkout4 (), // output
.clkout5 (), // output
.clkout6 (), // output
.clkout0b (), // output
.clkout1b (), // output
.clkout2b (), // output
.clkout3b (), // output
.clkfbout (clk_fb_pre), // output
.clkfboutb (), // output
.locked (locked_pxd_mmcm), // output
.clkin_stopped (clkin_pxd_stopped_mmcm), // output
.clkfb_stopped (clkfb_pxd_stopped_mmcm), // output
.drp_clk (mclk), // input
.drp_cmd (drp_cmd), // input[1:0]
.drp_out_bit (drp_bit), // output
.drp_out_odd_bit (drp_odd_bit) // output
);
end else begin
pll_drp #(
.CLKIN_PERIOD (CLKIN_PERIOD_SENSOR),
.BANDWIDTH (SENS_BANDWIDTH),
.CLKFBOUT_MULT (CLKFBOUT_MULT_SENSOR), // 28
.DIVCLK_DIVIDE (SENS_DIVCLK_DIVIDE),
.CLKFBOUT_PHASE (CLKFBOUT_PHASE_SENSOR),
.CLKOUT0_PHASE (PCLK_PHASE),
.CLKOUT1_PHASE (IPCLK2X_PHASE),
.CLKOUT2_PHASE (IPCLK1X_PHASE),
.CLKOUT0_DIVIDE (CLKFBOUT_MULT_SENSOR), // /28 -> 27 MHz
.CLKOUT1_DIVIDE (2*CLKFBOUT_MULT_SENSOR / 7), // /8 -> 94.5 MHz
.CLKOUT2_DIVIDE (4*CLKFBOUT_MULT_SENSOR / 7), // /16 -> 47.25 MHz
.REF_JITTER1 (SENS_REF_JITTER1),
.STARTUP_WAIT ("FALSE"),
.DRP_ADDRESS_LENGTH (DRP_ADDRESS_LENGTH),
.DRP_DATA_LENGTH (DRP_DATA_LENGTH)
) mmcm_or_pll_i (
.clkin (clk_in), // input
.clkfbin (clk_fb), // input
.rst (rst_mmcm), // input
.pwrdwn (1'b0), // input
.clkout0 (pclk_pre), // output -> 27MHz
.clkout1 (ipclk2x_pre), // output 135 Mhz
.clkout2 (ipclk1x_pre), // output 67.5 MHz
.clkout3 (), // output
.clkout4 (), // output
.clkout5 (), // output
.clkfbout (clk_fb_pre), // output
.locked (locked_pxd_mmcm), // output
.drp_clk (mclk), // input
.drp_cmd (drp_cmd), // input[1:0]
.drp_out_bit (drp_bit), // output
.drp_out_odd_bit (drp_odd_bit) // output
);
assign clkin_pxd_stopped_mmcm = 0;
assign clkfb_pxd_stopped_mmcm = 0;
end
endgenerate
generate
if (BUF_CLK_FB == "BUFG") BUFG clk2x_i (.O(clk_fb), .I(clk_fb_pre));
else if (BUF_CLK_FB == "BUFH") BUFH clk2x_i (.O(clk_fb), .I(clk_fb_pre));
else if (BUF_CLK_FB == "BUFR") BUFR clk2x_i (.O(clk_fb), .I(clk_fb_pre), .CE(1'b1), .CLR(prst));
else if (BUF_CLK_FB == "BUFMR") BUFMR clk2x_i (.O(clk_fb), .I(clk_fb_pre));
else if (BUF_CLK_FB == "BUFIO") BUFIO clk2x_i (.O(clk_fb), .I(clk_fb_pre));
else assign clk_fb = clk_fb_pre;
endgenerate
generate
if (BUF_IPCLK2X == "BUFG") BUFG clk2x_i (.O(ipclk2x), .I(ipclk2x_pre));
else if (BUF_IPCLK2X == "BUFH") BUFH clk2x_i (.O(ipclk2x), .I(ipclk2x_pre));
else if (BUF_IPCLK2X == "BUFR") BUFR clk2x_i (.O(ipclk2x), .I(ipclk2x_pre), .CE(1'b1), .CLR(prst));
else if (BUF_IPCLK2X == "BUFIO") BUFIO clk2x_i (.O(ipclk2x), .I(ipclk2x_pre));
else if (BUF_IPCLK2X == "BUFMR") begin
wire ipclk2xr_pre2;
BUFMR clk2x2_i (.O(ipclk2xr_pre2), .I(ipclk2x_pre));
BUFR clk2x_i (.O(ipclk2x), .I(ipclk2xr_pre2), .CE(1'b1), .CLR(prst));
end else if (BUF_IPCLK2X == "BUFMIO") begin
wire ipclk2x_pre2;
BUFMR clk2x2_i (.O(ipclk2x_pre2), .I(ipclk2x_pre));
BUFIO clk2x_i (.O(ipclk2x), .I(ipclk2x_pre2));
end else assign ipclk2x = ipclk2x_pre;
if (BUF_IPCLK2X == "BUFIO") begin
BUFH clk2x_alt_i (.O(ipclk2x_alt), .I(ipclk2x_pre));
end else begin
assign ipclk2x_alt = ipclk2x;
end
endgenerate
generate
if (BUF_IPCLK1X == "BUFG") BUFG clk1x_i (.O(ipclk1x), .I(ipclk1x_pre));
else if (BUF_IPCLK1X == "BUFH") BUFH clk1x_i (.O(ipclk1x), .I(ipclk1x_pre));
else if (BUF_IPCLK1X == "BUFR") BUFR clk1x_i (.O(ipclk1x), .I(ipclk1x_pre), .CE(1'b1), .CLR(prst));
else if (BUF_IPCLK1X == "BUFIO") BUFIO clk1x_i (.O(ipclk1x), .I(ipclk1x_pre));
else if (BUF_IPCLK2X == "BUFMR") begin
wire ipclk1xr_pre2;
BUFMR clk1x2_i (.O(ipclk1xr_pre2), .I(ipclk1x_pre));
BUFR clk1x_i (.O(ipclk1x), .I(ipclk1xr_pre2), .CE(1'b1), .CLR(prst));
end else if (BUF_IPCLK2X == "BUFMIO") begin
wire ipclk1x_pre2;
BUFMR clk1x2_i (.O(ipclk1x_pre2), .I(ipclk1x_pre));
BUFIO clk1x_i (.O(ipclk1x), .I(ipclk1x_pre2));
end else assign ipclk1x = ipclk1x_pre;
endgenerate
generate
if (BUF_PCLK == "BUFG") BUFG clk2x_i (.O(pclk), .I(pclk_pre));
else if (BUF_PCLK == "BUFH") BUFH clk2x_i (.O(pclk), .I(pclk_pre));
else if (BUF_PCLK == "BUFR") BUFR clk2x_i (.O(pclk), .I(pclk_pre), .CE(1'b1), .CLR(prst));
else if (BUF_PCLK == "BUFIO") BUFIO clk2x_i (.O(pclk), .I(pclk_pre));
else if (BUF_PCLK == "BUFMR") BUFMR clk2x_i (.O(pclk), .I(pclk_pre));
else assign pclk = pclk_pre;
endgenerate
always @(negedge pclk or posedge sync_neg_ipclk1x[0]) begin
if (sync_neg_ipclk1x[0]) sync_neg_pclk <= 0;
else sync_neg_pclk <= locked_pxd_mmcm; // !prst;
end
always @(negedge ipclk2x_alt) begin
sync_neg_ipclk2x <= sync_neg_pclk;
end
always @ (negedge ipclk1x) begin
sync_neg_ipclk1x <= { sync_neg_ipclk1x[DELAY_FOR_PCLK-1:0], locked_pxd_mmcm & sync_neg_ipclk2x};
for_pclk_r <= ~sync_neg_ipclk1x[DELAY_FOR_PCLK];
end
endmodule
/*!
* <b>Module:</b> sens_103993A_lane
* @file sens_103993A_lane.v
* @date 2021-03-26
* @author eyesis
*
* @brief
*
* @copyright Copyright (c) 2021 <set up in Preferences-Verilog/VHDL Editor-Templates> .
*
* <b>License </b>
*
* sens_103993A_lane.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.
*
* sens_103993A_lane.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 <http://www.gnu.org/licenses/> .
*
* Additional permission under GNU GPL version 3 section 7:
* If you modify this Program, or any covered work, by linking or combining it
* with independent modules provided by the FPGA vendor only (this permission
* does not extend to any 3-rd party modules, "soft cores" or macros) under
* different license terms solely for the purpose of generating binary "bitstream"
* files and/or simulating the code, the copyright holders of this Program give
* you the right to distribute the covered work without those independent modules
* as long as the source code for them is available from the FPGA vendor free of
* charge, and there is no dependence on any encrypted modules for simulating of
* the combined code. This permission applies to you if the distributed code
* contains all the components and scripts required to completely simulate it
* with at least one of the Free Software programs.
*/
`timescale 1ns/1ps
module sens_103993A_lane#(
parameter IODELAY_GRP = "IODELAY_SENSOR", // may need different for different channels?
parameter integer IDELAY_VALUE = 0,
parameter real REFCLK_FREQUENCY = 200.0,
parameter HIGH_PERFORMANCE_MODE = "FALSE",
// parameter NUMLANES = 3,
parameter LVDS_CAPACITANCE = "DONT_CARE",
parameter LVDS_DIFF_TERM = "TRUE",
parameter LVDS_UNTUNED_SPLIT = "FALSE", // Very power-hungry
parameter LVDS_DQS_BIAS = "TRUE",
parameter LVDS_IBUF_DELAY_VALUE = "0",
parameter LVDS_IBUF_LOW_PWR = "TRUE",
parameter LVDS_IFD_DELAY_VALUE = "AUTO",
parameter LVDS_IOSTANDARD = "DIFF_SSTL18_I" //"DIFF_SSTL18_II" for high current (13.4mA vs 8mA)
)(
input mclk,
input mrst,
input [7:0] dly_data, // delay value (3 LSB - fine delay) - @posedge mclk
input ld_idelay, // mclk synchronous load idelay value
input apply_idelay, // mclk synchronous set idealy value
input pclk, // 27 MHz
input ipclk2x, // 135 MHz
input ipclk1x, // 67.5 MHz
input rst, // reset// @posedge iclk
input for_pclk, // @posedge ipclk1x copy 10 bits form ipclk1x domain to pclk (alternating 2/3 iplck1x intervals)
input for_pclk_last, // @posedge ipclk1x: next for_pclk will apply to last 7 bits (count 0..3)
input din_p,
input din_n,
output [6:0] dout);
wire din;
wire din_dly;
wire [9:0] deser_w; // deserializer 4-bit output and previous values
reg [5:0] deser_r;
reg [6:0] dout_r;
reg [6:0] pre_dout_r;
reg [3:0] bshift; // one-hot shift of the data output
assign dout=dout_r;
assign deser_w[9:4] = deser_r[5:0];
generate
if (LVDS_UNTUNED_SPLIT == "TRUE") begin
ibufds_ibufgds_50 #(
.CAPACITANCE (LVDS_CAPACITANCE),
.DIFF_TERM (LVDS_DIFF_TERM),
.DQS_BIAS (LVDS_DQS_BIAS),
.IBUF_DELAY_VALUE (LVDS_IBUF_DELAY_VALUE),
.IBUF_LOW_PWR (LVDS_IBUF_LOW_PWR),
.IFD_DELAY_VALUE (LVDS_IFD_DELAY_VALUE),
.IOSTANDARD (LVDS_IOSTANDARD)
) ibufds_ibufgds0_i (
.O (din), // output
.I (din_p), // input
.IB (din_n) // input
);
end else if (LVDS_UNTUNED_SPLIT == "40") begin
ibufds_ibufgds_40 #(
.CAPACITANCE (LVDS_CAPACITANCE),
.DIFF_TERM (LVDS_DIFF_TERM),
.DQS_BIAS (LVDS_DQS_BIAS),
.IBUF_DELAY_VALUE (LVDS_IBUF_DELAY_VALUE),
.IBUF_LOW_PWR (LVDS_IBUF_LOW_PWR),
.IFD_DELAY_VALUE (LVDS_IFD_DELAY_VALUE),
.IOSTANDARD (LVDS_IOSTANDARD)
) ibufds_ibufgds0_i (
.O (din), // output
.I (din_p), // input
.IB (din_n) // input
);
end else if (LVDS_UNTUNED_SPLIT == "50") begin
ibufds_ibufgds_50 #(
.CAPACITANCE (LVDS_CAPACITANCE),
.DIFF_TERM (LVDS_DIFF_TERM),
.DQS_BIAS (LVDS_DQS_BIAS),
.IBUF_DELAY_VALUE (LVDS_IBUF_DELAY_VALUE),
.IBUF_LOW_PWR (LVDS_IBUF_LOW_PWR),
.IFD_DELAY_VALUE (LVDS_IFD_DELAY_VALUE),
.IOSTANDARD (LVDS_IOSTANDARD)
) ibufds_ibufgds0_i (
.O (din), // output
.I (din_p), // input
.IB (din_n) // inputpre_dout_r
);
end else if (LVDS_UNTUNED_SPLIT == "60") begin
ibufds_ibufgds_60 #(
.CAPACITANCE (LVDS_CAPACITANCE),
.DIFF_TERM (LVDS_DIFF_TERM),
.DQS_BIAS (LVDS_DQS_BIAS),
.IBUF_DELAY_VALUE (LVDS_IBUF_DELAY_VALUE),
.IBUF_LOW_PWR (LVDS_IBUF_LOW_PWR),
.IFD_DELAY_VALUE (LVDS_IFD_DELAY_VALUE),
.IOSTANDARD (LVDS_IOSTANDARD)
) ibufds_ibufgds0_i (
.O (din), // output
.I (din_p), // input
.IB (din_n) // input
);
end else begin
ibufds_ibufgds #(
.CAPACITANCE (LVDS_CAPACITANCE),
.DIFF_TERM (LVDS_DIFF_TERM),
.DQS_BIAS (LVDS_DQS_BIAS),
.IBUF_DELAY_VALUE (LVDS_IBUF_DELAY_VALUE),
.IBUF_LOW_PWR (LVDS_IBUF_LOW_PWR),
.IFD_DELAY_VALUE (LVDS_IFD_DELAY_VALUE),
.IOSTANDARD (LVDS_IOSTANDARD)
) ibufds_ibufgds0_i (
.O (din), // output
.I (din_p), // input
.IB (din_n) // input
);
end
endgenerate
idelay_nofine # (
.IODELAY_GRP (IODELAY_GRP),
.DELAY_VALUE (IDELAY_VALUE),
.REFCLK_FREQUENCY (REFCLK_FREQUENCY),
.HIGH_PERFORMANCE_MODE (HIGH_PERFORMANCE_MODE)
) pxd_dly_i(
.clk (mclk),
.rst (mrst),
.set (apply_idelay),
.ld (ld_idelay),
.delay (dly_data[7:3]),
.data_in (din),
.data_out (din_dly)
);
iserdes_mem #(
.DYN_CLKDIV_INV_EN ("FALSE"),
.MSB_FIRST (1) // MSB is received first
) iserdes_pxd_i (
.iclk (ipclk2x), // source-synchronous clock
.oclk (ipclk2x), // system clock, phase should allow iclk-to-oclk jitter with setup/hold margin
.oclk_div (ipclk1x), // oclk divided by 2, front aligned
.inv_clk_div (1'b0), // invert oclk_div (this clock is shared between iserdes and oserdes. Works only in MEMORY_DDR3 mode?
.rst (rst), // reset
.d_direct (1'b0), // direct input from IOB, normally not used, controlled by IOBDELAY parameter (set to "NONE")
.ddly (din_dly), // serial input from idelay
.dout (deser_w[3:0]), // parallel data out
.comb_out() // output
);
always @ (negedge ipclk1x) begin
deser_r <= {deser_r[1:0],deser_w[3:0]};
end
always @ (negedge ipclk1x) begin
if (for_pclk) bshift <= for_pclk_last ? 4'b0001 : {bshift[2:0],1'b0};
if (for_pclk) pre_dout_r <=
({7{bshift[0]}} & deser_w[6:0]) |
({7{bshift[1]}} & deser_w[7:1]) |
({7{bshift[2]}} & deser_w[8:2]) |
({7{bshift[3]}} & deser_w[9:3]);
end
always @ (posedge pclk) begin
dout_r <= pre_dout_r;
end
endmodule
/*!
* <b>Module:</b> sens_103993A_lanes
* @file sens_103993A_lanes.v
* @date 2021-03-26
* @author eyesis
*
* @brief 3-lane deserializer for Boson640
*
* @copyright Copyright (c) 2021 <set up in Preferences-Verilog/VHDL Editor-Templates> .
*
* <b>License </b>
*
* sens_103993A_lanes.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.
*
* sens_103993A_lanes.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 <http://www.gnu.org/licenses/> .
*
* Additional permission under GNU GPL version 3 section 7:
* If you modify this Program, or any covered work, by linking or combining it
* with independent modules provided by the FPGA vendor only (this permission
* does not extend to any 3-rd party modules, "soft cores" or macros) under
* different license terms solely for the purpose of generating binary "bitstream"
* files and/or simulating the code, the copyright holders of this Program give
* you the right to distribute the covered work without those independent modules
* as long as the source code for them is available from the FPGA vendor free of
* charge, and there is no dependence on any encrypted modules for simulating of
* the combined code. This permission applies to you if the distributed code
* contains all the components and scripts required to completely simulate it
* with at least one of the Free Software programs.
*/
`timescale 1ns/1ps
module sens_103993A_lanes #(
parameter IODELAY_GRP = "IODELAY_SENSOR",
parameter integer IDELAY_VALUE = 0,
parameter real REFCLK_FREQUENCY = 200.0,
parameter HIGH_PERFORMANCE_MODE = "FALSE",
// parameter SENS_PHASE_WIDTH= 8, // number of bits for te phase counter (depends on divisors)
parameter SENS_BANDWIDTH = "OPTIMIZED", //"OPTIMIZED", "HIGH","LOW"
parameter CLKIN_PERIOD_SENSOR = 37.037, // input period in ns, 0..100.000 - MANDATORY, resolution down to 1 ps
parameter CLKFBOUT_MULT_SENSOR = 35, // 945 MHz 28, // 27 MHz --> 756 MHz
parameter CLKFBOUT_PHASE_SENSOR = 0.000, // CLOCK FEEDBACK phase in degrees (3 significant digits, -360.000...+360.000)
parameter PCLK_PHASE = 0.000,
parameter IPCLK2X_PHASE = 0.000,
parameter IPCLK1X_PHASE = 0.000, /// new
parameter BUF_PCLK = "BUFR",
parameter BUF_IPCLK2X = "BUFR",
parameter BUF_IPCLK1X = "BUFR", /// new
parameter BUF_CLK_FB = "BUFR", /// new
parameter SENS_DIVCLK_DIVIDE = 1, // Integer 1..106. Divides all outputs with respect to CLKIN
parameter SENS_REF_JITTER1 = 0.010, // Expected jitter on CLKIN1 (0.000..0.999)
parameter SENS_REF_JITTER2 = 0.010,
parameter SENS_SS_EN = "FALSE", // Enables Spread Spectrum mode
parameter SENS_SS_MODE = "CENTER_HIGH",//"CENTER_HIGH","CENTER_LOW","DOWN_HIGH","DOWN_LOW"
parameter SENS_SS_MOD_PERIOD = 10000, // integer 4000-40000 - SS modulation period in ns
parameter NUMLANES = 4,
parameter LVDS_DELAY_CLK = "FALSE",
parameter LVDS_MMCM = "TRUE",
parameter LVDS_CAPACITANCE = "DONT_CARE",
parameter LVDS_DIFF_TERM = "TRUE",
parameter LVDS_UNTUNED_SPLIT = "FALSE", // Very power-hungry
parameter LVDS_DQS_BIAS = "TRUE",
parameter LVDS_IBUF_DELAY_VALUE = "0",
parameter LVDS_IBUF_LOW_PWR = "TRUE",
parameter LVDS_IFD_DELAY_VALUE = "AUTO",
parameter LVDS_IOSTANDARD = "DIFF_SSTL18_I", //"DIFF_SSTL18_II" for high current (13.4mA vs 8mA),
parameter DEGLITCH_DVALID = 1,
parameter DEGLITCH_HSYNC = 3,
parameter DEGLITCH_VSYNC = 7
)(
output pclk, // global clock input, pixel rate (27MHz for 103993) (220MHz for MT9F002)
input prsts,
// I/O pads
input [NUMLANES-1:0] sns_dp,
input [NUMLANES-1:0] sns_dn,
input sns_clkp,
input sns_clkn,
// output
output [15:0] pxd_out,
output vsync,
output hsync,
output dvalid,
// delay control inputs
input mclk,
input mrst,
input [NUMLANES * 8-1:0] dly_data, // delay value (3 LSB - fine delay) - @posedge mclk
input [NUMLANES-1:0] set_idelay, // mclk synchronous load idelay value
input apply_idelay, // mclk synchronous set idelay value
input set_clk_phase, // mclk synchronous set idelay value
input rst_mmcm,
// MMCP output status
output perr, // parity error
output [7:0] test_out,
output locked_pxd_mmcm,
output clkin_pxd_stopped_mmcm, // output
output clkfb_pxd_stopped_mmcm, // output
input [1:0] drp_cmd,
output drp_bit,
output drp_odd_bit
);
wire [NUMLANES * 7-1:0] sns_d;
wire ipclk2x;// re-generated clock (135 MHz)
wire ipclk1x;// re-generated clock (67.5 MHz)
reg [15:0] pxd_out_r;
reg [15:0] pxd_out_r2;
reg perr_r;
wire [15:0] pxd_w;
wire for_pclk;
wire for_pclk_last;
assign pxd_out = (DEGLITCH_DVALID>0) ? pxd_out_r: pxd_out_r2;
assign perr = perr_r;
assign test_out = {sns_d[27:26],sns_d[20:19],sns_d[13:12],sns_d[6:5]}; // should be 8'haa
assign pxd_w = {sns_d[19:12],sns_d[9:2]};
sens_103993A_clock #(
.SENS_BANDWIDTH (SENS_BANDWIDTH),
.CLKIN_PERIOD_SENSOR (CLKIN_PERIOD_SENSOR),
.CLKFBOUT_MULT_SENSOR (CLKFBOUT_MULT_SENSOR),
.CLKFBOUT_PHASE_SENSOR (CLKFBOUT_PHASE_SENSOR),
.PCLK_PHASE (PCLK_PHASE),
.IPCLK2X_PHASE (IPCLK2X_PHASE),
.IPCLK1X_PHASE (IPCLK1X_PHASE),
.BUF_PCLK (BUF_PCLK),
.BUF_IPCLK2X (BUF_IPCLK2X),
.BUF_IPCLK1X (BUF_IPCLK1X),
.BUF_CLK_FB (BUF_CLK_FB),
.SENS_DIVCLK_DIVIDE (SENS_DIVCLK_DIVIDE),
.SENS_REF_JITTER1 (SENS_REF_JITTER1),
.SENS_REF_JITTER2 (SENS_REF_JITTER2),
.SENS_SS_EN (SENS_SS_EN),
.SENS_SS_MODE (SENS_SS_MODE),
.SENS_SS_MOD_PERIOD (SENS_SS_MOD_PERIOD),
.IODELAY_GRP (IODELAY_GRP),
.IDELAY_VALUE (IDELAY_VALUE),
.REFCLK_FREQUENCY (REFCLK_FREQUENCY),
.HIGH_PERFORMANCE_MODE (HIGH_PERFORMANCE_MODE),
.LVDS_DELAY_CLK (LVDS_DELAY_CLK),
.LVDS_MMCM (LVDS_MMCM),
.LVDS_CAPACITANCE (LVDS_CAPACITANCE),
.LVDS_DIFF_TERM (LVDS_DIFF_TERM),
.LVDS_UNTUNED_SPLIT (LVDS_UNTUNED_SPLIT),
.LVDS_DQS_BIAS (LVDS_DQS_BIAS),
.LVDS_IBUF_DELAY_VALUE (LVDS_IBUF_DELAY_VALUE),
.LVDS_IBUF_LOW_PWR (LVDS_IBUF_LOW_PWR),
.LVDS_IFD_DELAY_VALUE (LVDS_IFD_DELAY_VALUE),
.LVDS_IOSTANDARD (LVDS_IOSTANDARD)
) sens_103993_clock_i ( // same instance name as in sens_103993_l3
.mclk (mclk), // input
.mrst (mrst), // input
.phase (dly_data[7:0]), // input[7:0]
.set_phase (set_clk_phase), // input
.apply (apply_idelay), // input
.rst_mmcm (rst_mmcm), // input
.clp_p (sns_clkp), // input
.clk_n (sns_clkn), // input
.ipclk2x (ipclk2x), // output
.ipclk1x (ipclk1x), // output
.pclk (pclk), // output 27MHz
.locked_pxd_mmcm (locked_pxd_mmcm), // output
.clkin_pxd_stopped_mmcm (clkin_pxd_stopped_mmcm), // output
.clkfb_pxd_stopped_mmcm (clkfb_pxd_stopped_mmcm), // output
.for_pclk (for_pclk), // output
.for_pclk_last (for_pclk_last), // output
.drp_cmd (drp_cmd), // input[1:0]
.drp_bit (drp_bit), // output
.drp_odd_bit (drp_odd_bit) // output
);
generate
genvar i;
for (i=0; i < NUMLANES; i=i+1) begin: lane_block
sens_103993A_lane #(
.IODELAY_GRP (IODELAY_GRP),
.IDELAY_VALUE (IDELAY_VALUE),
.REFCLK_FREQUENCY (REFCLK_FREQUENCY),
.HIGH_PERFORMANCE_MODE (HIGH_PERFORMANCE_MODE),
.LVDS_CAPACITANCE (LVDS_CAPACITANCE), // "DONT_CARE"),
.LVDS_DIFF_TERM (LVDS_DIFF_TERM), // "TRUE"),
.LVDS_UNTUNED_SPLIT (LVDS_UNTUNED_SPLIT), // "FALSE"),
.LVDS_DQS_BIAS (LVDS_DQS_BIAS), // "TRUE"),
.LVDS_IBUF_DELAY_VALUE (LVDS_IBUF_DELAY_VALUE), // "0"),
.LVDS_IBUF_LOW_PWR (LVDS_IBUF_LOW_PWR), // "TRUE"),
.LVDS_IFD_DELAY_VALUE (LVDS_IFD_DELAY_VALUE), // "AUTO"),
.LVDS_IOSTANDARD (LVDS_IOSTANDARD) // "DIFF_SSTL18_I")
) sens_103993_lane_i (
.mclk (mclk), // input
.mrst (mrst), // input
// .dly_data (dly_data[7 + 8*i +: 8]), // input[7:0] dly_data[3 + 8*i +: 5
.dly_data (dly_data[8*i +: 8]), // input[7:0] dly_data[3 + 8*i +: 5
.ld_idelay (set_idelay[i]), // input
.apply_idelay (apply_idelay), // input
.pclk (pclk), // input
.ipclk2x (ipclk2x), // input
.ipclk1x (ipclk1x), // input
.rst (mrst), // input
.for_pclk (for_pclk), // input
.for_pclk_last (for_pclk_last), // input
.din_p (sns_dp[i]), // input
.din_n (sns_dn[i]), // input
.dout (sns_d[7*i +: 7]) // output[6:0]
);
end
endgenerate
always @(posedge pclk) begin
pxd_out_r <= pxd_w;
pxd_out_r2 <= pxd_out_r;
perr_r <= ~sns_d[27] | sns_d[26] | sns_d[25] | ~sns_d[20] | sns_d[19] | ~sns_d[13] | sns_d[13] | ~sns_d[6] | sns_d[5];
end
deglitch #(
.CLOCKS(DEGLITCH_DVALID)
) deglitch_dvalid_i (
.clk(pclk), // input
.rst(prsts), // input
.d(sns_d[24]), // input
.q(dvalid) // output
);
deglitch #(
.CLOCKS(DEGLITCH_HSYNC)
) deglitch_hsync_i (
.clk(pclk), // input
.rst(prsts), // input
.d(sns_d[22]), // input
.q(hsync) // output
);
deglitch #(
.CLOCKS(DEGLITCH_VSYNC)
) deglitch_vsync_i (
.clk(pclk), // input
.rst(prsts), // input
.d(sns_d[23]), // input
.q(vsync) // output
);
endmodule
/*!
* <b>Module:</b> simul_103993A_serializer
* @file simul_103993A_serializer.v
* @date 2020-12-23
* @author eyesis
*
* @brief Serializer for Boson640 output based on SN65LVDS301
*
* @copyright Copyright (c) 2020 <set up in Preferences-Verilog/VHDL Editor-Templates> .
*
* <b>License </b>
*
* simul_103993A_serializer.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.
*
* simul_103993A_serializer.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 <http://www.gnu.org/licenses/> .
*
* Additional permission under GNU GPL version 3 section 7:
* If you modify this Program, or any covered work, by linking or combining it
* with independent modules provided by the FPGA vendor only (this permission
* does not extend to any 3-rd party modules, "soft cores" or macros) under
* different license terms solely for the purpose of generating binary "bitstream"
* files and/or simulating the code, the copyright holders of this Program give
* you the right to distribute the covered work without those independent modules
* as long as the source code for them is available from the FPGA vendor free of
* charge, and there is no dependence on any encrypted modules for simulating of
* the combined code. This permission applies to you if the distributed code
* contains all the components and scripts required to completely simulate it
* with at least one of the Free Software programs.
*/
`timescale 1ns/1ps
module simul_103993A_serializer#(
parameter PCLK_FREQ_MHZ = 27.0
)(
input [6:0] ta,
input [6:0] tb,
input [6:0] tc,
input [6:0] td,
input pclk,
output [3:0] dp,
output [3:0] dn,
output clkp,
output clkn
);
localparam PERIOD = 1000.0/PCLK_FREQ_MHZ;
wire [13:0] dclocks;
assign #(PERIOD/14) dclocks[ 0] = pclk;
assign #(PERIOD/14) dclocks[ 1] = dclocks[ 0];
assign #(PERIOD/14) dclocks[ 2] = dclocks[ 1];
assign #(PERIOD/14) dclocks[ 3] = dclocks[ 2];
assign #(PERIOD/14) dclocks[ 4] = dclocks[ 3];
assign #(PERIOD/14) dclocks[ 5] = dclocks[ 4];
assign #(PERIOD/14) dclocks[ 6] = dclocks[ 5];
assign #(PERIOD/14) dclocks[ 6] = dclocks[ 5];
assign #(PERIOD/14) dclocks[ 7] = dclocks[ 6];
assign #(PERIOD/14) dclocks[ 8] = dclocks[ 7];
assign #(PERIOD/14) dclocks[ 9] = dclocks[ 8];
assign #(PERIOD/14) dclocks[10] = dclocks[ 9];
assign #(PERIOD/14) dclocks[11] = dclocks[10];
assign #(PERIOD/14) dclocks[12] = dclocks[11];
assign #(PERIOD/14) dclocks[13] = dclocks[12];
wire clk7 = (~dclocks[ 1] & dclocks[ 0]) |
(~dclocks[ 3] & dclocks[ 2]) |
(~dclocks[ 5] & dclocks[ 4]) |
(~dclocks[ 7] & dclocks[ 6]) |
(~dclocks[ 9] & dclocks[ 8]) |
(~dclocks[11] & dclocks[10]) |
(~dclocks[13] & dclocks[12]);
reg [6:0] r_ta;
reg [6:0] r_tb;
reg [6:0] r_tc;
reg [6:0] r_td;
reg [6:0] sr_ta;
reg [6:0] sr_tb;
reg [6:0] sr_tc;
reg [6:0] sr_td;
reg [6:0] sr_clk;
reg [1:0] clk_r;
reg set_sr;
assign dp = {sr_td[6], sr_tc[6], sr_tb[6], sr_ta[6]};
assign dn = ~{sr_td[6], sr_tc[6], sr_tb[6], sr_ta[6]};
assign clkp = sr_clk [6];
assign clkn = ~sr_clk [6];
always @ (posedge pclk) begin
r_ta <= ta;
r_tb <= tb;
r_tc <= tc;
r_td <= td;
end
always @ (posedge clk7) begin
clk_r <= {clk_r[0], pclk};
set_sr <= clk_r[0] && !clk_r[1];
if (set_sr) begin
sr_ta <= r_ta;
sr_tb <= r_tb;
sr_tc <= r_tc;
sr_td <= r_td;
sr_clk <= 7'b1100011;
end else begin
sr_ta <= {sr_ta[5:0], 1'b0};
sr_tb <= {sr_tb[5:0], 1'b0};
sr_tc <= {sr_tc[5:0], 1'b0};
sr_td <= {sr_td[5:0], 1'b0};
sr_clk <= {sr_clk[5:0], 1'b0};
end
end
endmodule
......@@ -81,6 +81,7 @@
`ifdef BOSON
`define PCLK_MASTER /* pclk is generated by the sensors, no global pclk and prst!*/
`define BOSON_REVA 1 /* 103993 REVA board*/
`endif
`define MON_HISPI // Measure HISPI timing
// `define USE_OLD_XDCT393
......
No preview for this file type
This source diff could not be displayed because it is too large. You can view the blob instead.
Copyright 1986-2017 Xilinx, Inc. All Rights Reserved.
-------------------------------------------------------------------------------------
| Tool Version : Vivado v.2017.4 (lin64) Build 2086221 Fri Dec 15 20:54:30 MST 2017
| Date : Wed Mar 31 22:30:11 2021
| Date : Fri Apr 2 01:44:50 2021
| Host : elphel-desktop running 64-bit Ubuntu 14.04.5 LTS
| Command : report_utilization -file vivado_build/x393_boson_utilization.report
| Design : x393
......@@ -31,13 +31,13 @@ Table of Contents
+----------------------------+-------+-------+-----------+-------+
| Site Type | Used | Fixed | Available | Util% |
+----------------------------+-------+-------+-----------+-------+
| Slice LUTs | 43590 | 0 | 78600 | 55.46 |
| LUT as Logic | 40218 | 0 | 78600 | 51.17 |
| LUT as Memory | 3372 | 0 | 26600 | 12.68 |
| Slice LUTs | 43731 | 0 | 78600 | 55.64 |
| LUT as Logic | 40349 | 0 | 78600 | 51.33 |
| LUT as Memory | 3382 | 0 | 26600 | 12.71 |
| LUT as Distributed RAM | 2834 | 0 | | |
| LUT as Shift Register | 538 | 0 | | |
| Slice Registers | 55947 | 0 | 157200 | 35.59 |
| Register as Flip Flop | 55947 | 0 | 157200 | 35.59 |
| LUT as Shift Register | 548 | 0 | | |
| Slice Registers | 55910 | 0 | 157200 | 35.57 |
| Register as Flip Flop | 55910 | 0 | 157200 | 35.57 |
| Register as Latch | 0 | 0 | 157200 | 0.00 |
| F7 Muxes | 30 | 0 | 39300 | 0.08 |
| F8 Muxes | 0 | 0 | 19650 | 0.00 |
......@@ -58,8 +58,8 @@ Table of Contents
| 0 | Yes | - | - |
| 16 | Yes | - | Set |
| 676 | Yes | - | Reset |
| 1215 | Yes | Set | - |
| 54040 | Yes | Reset | - |
| 1219 | Yes | Set | - |
| 53999 | Yes | Reset | - |
+-------+--------------+-------------+--------------+
......@@ -69,27 +69,27 @@ Table of Contents
+-------------------------------------------+-------+-------+-----------+-------+
| Site Type | Used | Fixed | Available | Util% |
+-------------------------------------------+-------+-------+-----------+-------+
| Slice | 16994 | 0 | 19650 | 86.48 |
| SLICEL | 11201 | 0 | | |
| SLICEM | 5793 | 0 | | |
| LUT as Logic | 40218 | 0 | 78600 | 51.17 |
| using O5 output only | 5 | | | |
| using O6 output only | 31260 | | | |
| using O5 and O6 | 8953 | | | |
| LUT as Memory | 3372 | 0 | 26600 | 12.68 |
| Slice | 17026 | 0 | 19650 | 86.65 |
| SLICEL | 11218 | 0 | | |
| SLICEM | 5808 | 0 | | |
| LUT as Logic | 40349 | 0 | 78600 | 51.33 |
| using O5 output only | 3 | | | |
| using O6 output only | 31464 | | | |
| using O5 and O6 | 8882 | | | |
| LUT as Memory | 3382 | 0 | 26600 | 12.71 |
| LUT as Distributed RAM | 2834 | 0 | | |
| using O5 output only | 2 | | | |
| using O6 output only | 84 | | | |
| using O5 and O6 | 2748 | | | |
| LUT as Shift Register | 538 | 0 | | |
| using O5 output only | 258 | | | |
| using O6 output only | 225 | | | |
| using O5 and O6 | 55 | | | |
| LUT Flip Flop Pairs | 25490 | 0 | 78600 | 32.43 |
| fully used LUT-FF pairs | 4916 | | | |
| LUT-FF pairs with one unused LUT output | 18340 | | | |
| LUT-FF pairs with one unused Flip Flop | 18216 | | | |
| Unique Control Sets | 5213 | | | |
| LUT as Shift Register | 548 | 0 | | |
| using O5 output only | 262 | | | |
| using O6 output only | 237 | | | |
| using O5 and O6 | 49 | | | |
| LUT Flip Flop Pairs | 25423 | 0 | 78600 | 32.34 |
| fully used LUT-FF pairs | 4862 | | | |
| LUT-FF pairs with one unused LUT output | 18383 | | | |
| LUT-FF pairs with one unused Flip Flop | 18136 | | | |
| Unique Control Sets | 5278 | | | |
+-------------------------------------------+-------+-------+-----------+-------+
* Note: Review the Control Sets Report for more information regarding control sets.
......@@ -137,19 +137,19 @@ Table of Contents
| OUT_FIFO | 0 | 0 | 20 | 0.00 |
| IN_FIFO | 0 | 0 | 20 | 0.00 |
| IDELAYCTRL | 3 | 0 | 5 | 60.00 |
| IBUFDS | 18 | 18 | 155 | 11.61 |
| IBUFDS | 22 | 22 | 155 | 14.19 |
| GTXE2_COMMON | 0 | 0 | 1 | 0.00 |
| GTXE2_CHANNEL | 1 | 1 | 4 | 25.00 |
| PHASER_OUT/PHASER_OUT_PHY | 0 | 0 | 20 | 0.00 |
| PHASER_IN/PHASER_IN_PHY | 0 | 0 | 20 | 0.00 |
| IDELAYE2/IDELAYE2_FINEDELAY | 30 | 30 | 250 | 12.00 |
| IDELAYE2 only | 12 | 12 | | |
| IDELAYE2/IDELAYE2_FINEDELAY | 34 | 34 | 250 | 13.60 |
| IDELAYE2 only | 16 | 16 | | |
| IDELAYE2_FINEDELAY only | 18 | 18 | | |
| ODELAYE2/ODELAYE2_FINEDELAY | 43 | 43 | 150 | 28.67 |
| ODELAYE2_FINEDELAY only | 43 | 43 | | |
| IBUFDS_GTE2 | 1 | 1 | 2 | 50.00 |
| ILOGIC | 28 | 28 | 163 | 17.18 |
| ISERDES | 28 | 28 | | |
| ILOGIC | 32 | 32 | 163 | 19.63 |
| ISERDES | 32 | 32 | | |
| OLOGIC | 44 | 44 | 163 | 26.99 |
| OUTFF_ODDR_Register | 1 | 1 | | |
| OSERDES | 43 | 43 | | |
......@@ -168,7 +168,7 @@ Table of Contents
| MMCME2_ADV | 3 | 0 | 5 | 60.00 |
| PLLE2_ADV | 3 | 0 | 5 | 60.00 |
| BUFMRCE | 0 | 0 | 10 | 0.00 |
| BUFHCE | 0 | 0 | 96 | 0.00 |
| BUFHCE | 2 | 0 | 96 | 2.08 |
| BUFR | 8 | 0 | 20 | 40.00 |
+--------------+------+-------+-----------+-------+
......@@ -197,37 +197,37 @@ Table of Contents
+------------------------+-------+----------------------+
| Ref Name | Used | Functional Category |
+------------------------+-------+----------------------+
| FDRE | 54040 | Flop & Latch |
| LUT3 | 11867 | LUT |
| LUT6 | 10465 | LUT |
| LUT2 | 8616 | LUT |
| LUT4 | 8437 | LUT |
| LUT5 | 8158 | LUT |
| FDRE | 53999 | Flop & Latch |
| LUT3 | 11860 | LUT |
| LUT6 | 10460 | LUT |
| LUT2 | 8628 | LUT |
| LUT4 | 8367 | LUT |
| LUT5 | 8282 | LUT |
| RAMD32 | 4174 | Distributed Memory |
| CARRY4 | 2805 | CarryLogic |
| LUT1 | 1628 | LUT |
| LUT1 | 1634 | LUT |
| RAMS32 | 1408 | Distributed Memory |
| FDSE | 1215 | Flop & Latch |
| FDSE | 1219 | Flop & Latch |
| FDCE | 676 | Flop & Latch |
| SRL16E | 489 | Distributed Memory |
| SRL16E | 493 | Distributed Memory |
| SRLC32E | 104 | Distributed Memory |
| DSP48E1 | 76 | Block Arithmetic |
| RAMB18E1 | 74 | Block Memory |
| OBUFT | 69 | IO |
| IBUF | 59 | IO |
| RAMB36E1 | 54 | Block Memory |
| IBUF | 51 | IO |
| OSERDESE2 | 43 | IO |
| ODELAYE2_FINEDELAY | 43 | IO |
| ISERDESE2 | 32 | IO |
| MUXF7 | 30 | MuxFx |
| ISERDESE2 | 28 | IO |
| IBUFDS | 22 | IO |
| OBUFT_DCIEN | 18 | IO |
| IDELAYE2_FINEDELAY | 18 | IO |
| IBUF_IBUFDISABLE | 18 | IO |
| IBUFDS | 18 | IO |
| IDELAYE2 | 16 | IO |
| FDPE | 16 | Flop & Latch |
| BUFG | 15 | Clock |
| PULLUP | 12 | I/O |
| IDELAYE2 | 12 | IO |
| OBUF | 11 | IO |
| BUFR | 8 | Clock |
| OBUFTDS_DCIEN | 4 | IO |
......@@ -238,6 +238,7 @@ Table of Contents
| IDELAYCTRL | 3 | IO |
| BUFIO | 3 | Clock |
| OBUFTDS | 2 | IO |
| BUFH | 2 | Clock |
| PS7 | 1 | Specialized Resource |
| ODDR | 1 | IO |
| IBUFDS_GTE2 | 1 | IO |
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment