UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Explorer
Explorer
5,258 Views
Registered: ‎06-08-2017

ISERDESE2 unknown outputs

Jump to solution

Hello,

 

I am trying to perform 1:8 deserialization on a Kintex-7 device. I am trying to simulate the deserialization, but most of the bits are just unknown at the output of the deserializer. My "vector" of outputs from the deserializer is called data_out, and only bits 6, 7, 14, 15, 22, 23, 30, 31, 38, 39 have known values. 7, 15, 23, 31, 39 are equal to INIT_Q1 (should be equal to Q1). 6, 14, 22, 30, 38 are equal to INIT_Q3 (should be equal to Q2).

 

I am not sure what is going on here. Any insight would be much appreciated!

 

Thank you,

Daniel

 

Code for deserializing ADC output:

 

// `include "timescale.v"
`timescale 1ps/1ps // this was in the SelectIO design

module LTC2195(
	input	 wire							clk_in,
	input	 wire						   rst_in,

	input  wire 			  			cmd_trig_in,
	input  wire 			  [15:0] cmd_addr_in,
	input	 wire 			  [15:0] cmd_data_in,
	
	output wire						 	spi_scs_out,
	output wire						 	spi_sck_out,
	output wire						 	spi_sdo_out,
	input  wire						 	spi_sdi_in,
	
	output wire		 					ENC_out_p,
	output wire							ENC_out_n,
	input  wire		 					DCO_in_p,
	input  wire							DCO_in_n,
	input  wire		 					FR_in_p,
	input  wire							FR_in_n,
	input  wire		 			[1:0]	D0_in_p,
	input  wire		 			[1:0]	D0_in_n,
	input  wire		 			[1:0]	D1_in_p,
	input  wire		 			[1:0]	D1_in_n,
	
	output reg	signed	  [15:0] ADC0_out,
	output reg	signed	  [15:0] ADC1_out,
	output reg					[7:0] FR_out
);

// Parameters
parameter 	SMP_DLY	= 8'h0;
parameter	CLKDIV = 8'd120; //800MHz/100 = 8Mhz, slowest ADC can go is 5MHz. CLKDIV_min = 8.


///////////////////////////////////////////////////////////////////////////////
// FSM to control ENC phase shifter

reg PS_clk, PS_en, PS_inc;
wire PS_done, PS_locked;
wire [7:0] PS_status;

// State machine definitions
localparam PS_IDLE 	= 4'h0;
localparam PS_TRIG  	= 4'h1;
localparam PS_DECIDE	= 4'h2;
localparam PS_UP1A  	= 4'h3;
localparam PS_UP1B  	= 4'h4;
localparam PS_UP1C  	= 4'h5;
localparam PS_UP2  	= 4'h6;
localparam PS_UP3  	= 4'h7;
localparam PS_DOWN1A = 4'h8;
localparam PS_DOWN1B = 4'h9;
localparam PS_DOWN1C = 4'hA;
localparam PS_DOWN2  = 4'hB;
localparam PS_DOWN3  = 4'hC;

// State
// The next line makes synthesis happy
// synthesis attribute INIT of PS_state_f is "R"
reg  [3:0] PS_state_f;
reg  [8:0] PS_value_f, PS_target_f;

// State machine - combinatorial part
function [3:0] PS_next_state;
	input    [3:0] state;
	input    [8:0] value;
	input    [8:0] target;
	input				trigger;
	input	  [15:0]	address;
	input				done;
//	input				status;
	input				locked;
	
	begin
		case (state)
			PS_IDLE: 
				if (trigger && (address[15:8] == 8'h32))
					PS_next_state = PS_TRIG;
				else
					PS_next_state = PS_IDLE;
			PS_TRIG:
					PS_next_state = PS_DECIDE;
			PS_DECIDE:
				if (locked == 1'b0)
					PS_next_state = PS_DECIDE;
//				else if ((target > value) && (!status || (value < 9'h100)))	//No status output available on MMCM
				else if ((target > value) && (value < 9'h100))
					PS_next_state = PS_UP1A;
//				else if ((target < value) && (!status || (value > 9'h100)))
				else if ((target < value) && (value > 9'h100))
					PS_next_state = PS_DOWN1A;
				else
					PS_next_state = PS_IDLE;
			PS_UP1A:
					PS_next_state = PS_UP1B;
			PS_UP1B:
					PS_next_state = PS_UP1C;
			PS_UP1C:
					PS_next_state = PS_UP2;
			PS_UP2:
				if (done == 1'b1)
					PS_next_state = PS_UP3;
				else
					PS_next_state = PS_UP2;
			PS_UP3:
					PS_next_state = PS_DECIDE;
			PS_DOWN1A:
					PS_next_state = PS_DOWN1B;
			PS_DOWN1B:
					PS_next_state = PS_DOWN1C;
			PS_DOWN1C:
					PS_next_state = PS_DOWN2;
			PS_DOWN2:
				if (done == 1'b1)
					PS_next_state = PS_DOWN3;
				else
					PS_next_state = PS_DOWN2;
			PS_DOWN3:
					PS_next_state = PS_DECIDE;
			default:
					PS_next_state = PS_IDLE;
		endcase
	end
endfunction

// State machine - sequential part
always @(posedge clk_in or posedge rst_in) begin
	if (rst_in) begin
		PS_state_f <= PS_DECIDE;
		PS_value_f <= 9'h100; // 256
		PS_target_f <= 9'h17C; // = decimal 380 = 256 + 124
		PS_clk <= 1'b0;
		PS_en <= 1'b0;
		PS_inc <= 1'b0;
	end
	else begin
//		PS_state_f <= PS_next_state(PS_state_f, PS_value_f, PS_target_f, cmd_trig_in, cmd_addr_in, PS_done, PS_status[0], PS_locked);
		PS_state_f <= PS_next_state(PS_state_f, PS_value_f, PS_target_f, cmd_trig_in, cmd_addr_in, PS_done, PS_locked);
		case (PS_state_f)
			PS_IDLE: begin
				PS_clk <= 1'b0;
				PS_en <= 1'b0;
				PS_inc <= 1'b0;
			end
			PS_TRIG: begin
				PS_target_f <= cmd_data_in[8:0];
			end
			PS_DECIDE: begin
				
			end
			PS_UP1A: begin
				PS_en <= 1'b1;
				PS_inc <= 1'b1;
			end
			PS_UP1B: begin
				PS_clk <= 1'b1;
			end
			PS_UP1C: begin
				PS_en <= 1'b0;
				PS_clk <= 1'b0;
			end
			PS_UP2: begin
				PS_clk <= ~PS_clk;
			end
			PS_UP3: begin
				PS_clk <= 1'b0;
				PS_value_f <= PS_value_f + 9'h1;
			end
			PS_DOWN1A: begin
				PS_en <= 1'b1;
				PS_inc <= 1'b0;
			end
			PS_DOWN1B: begin
				PS_clk <= 1'b1;
			end
			PS_DOWN1C: begin
				PS_en <= 1'b0;
				PS_clk <= 1'b0;
			end
			PS_DOWN2: begin
				PS_clk <= ~PS_clk;
			end
			PS_DOWN3: begin
				PS_clk <= 1'b0;
				PS_value_f <= PS_value_f - 9'h1;
			end
		endcase
	end
end

///////////////////////////////////////////////////////////////////////////////
// LVDS ENC output
wire	clkPSInt, clk8xInt, clk2xInt, clkDivInt;		//clock for phase shifting of ENC, and clock for deserialization (LVDS inputs block below)

//There are no DCMs in 7 series devices. Their functionality is encompassed by PLLs and MMCMs.
//I instantiate an MMCM below.
// MMCME2_ADV: Advanced Mixed Mode Clock Manager
MMCME2_ADV #(
	.BANDWIDTH("OPTIMIZED"), 	// Jitter programming (OPTIMIZED, HIGH, LOW)
	.CLKFBOUT_MULT_F(8.0), 		// 600MHz (minimum for vco
	.CLKFBOUT_PHASE(0.0), 		// Phase offset in degrees of CLKFB (-360.000-360.000).
	// CLKIN_PERIOD: Input clock period in ns to ps resolution (i.e. 33.333 is 30 MHz).
	.CLKIN1_PERIOD(10.0),
	// CLKOUT0_DIVIDE - CLKOUT6_DIVIDE: Divide amount for CLKOUT (1-128)
	.CLKOUT1_DIVIDE(CLKDIV/8),		//8 x f_CLK0 for deserialization
	.CLKOUT2_DIVIDE(4),				//This clock for IDELAYCTRL must be 200MHz
	.CLKOUT3_DIVIDE(CLKDIV),		//Unshifted clock for deserialization
	.CLKOUT0_DIVIDE_F(CLKDIV), 	//f_CLK0 = 800MHz/CLKDIV
	// CLKOUT0_DUTY_CYCLE - CLKOUT6_DUTY_CYCLE: Duty cycle for CLKOUT outputs (0.01-0.99).
	.CLKOUT0_DUTY_CYCLE(0.5),
	.CLKOUT1_DUTY_CYCLE(0.5),
	.CLKOUT2_DUTY_CYCLE(0.5),
	.CLKOUT3_DUTY_CYCLE(0.5),
	// CLKOUT0_PHASE - CLKOUT6_PHASE: Phase offset for CLKOUT outputs (-360.000-360.000).
	.CLKOUT0_PHASE(0.0),
	.CLKOUT1_PHASE(0.0),
	.CLKOUT2_PHASE(0.0),
	.CLKOUT3_PHASE(0.0),
	.COMPENSATION("ZHOLD"), // ZHOLD, BUF_IN, EXTERNAL, INTERNAL
	.DIVCLK_DIVIDE(1), // Master division value (1-106)
	// REF_JITTER: Reference input jitter in UI (0.000-0.999).
	.REF_JITTER1(0.01),
	.STARTUP_WAIT("FALSE"), 		// Delays DONE until MMCM is locked (FALSE, TRUE)
	// USE_FINE_PS: Fine phase shift enable (TRUE/FALSE)
	.CLKFBOUT_USE_FINE_PS("FALSE"),
	.CLKOUT0_USE_FINE_PS("TRUE"),
	.CLKOUT1_USE_FINE_PS("FALSE"),
	.CLKOUT2_USE_FINE_PS("FALSE"),
	.CLKOUT3_USE_FINE_PS("FALSE")
)
MMCME2_ADV_inst (
	// Clock Outputs: 1-bit (each) output: User configurable clock outputs
	.CLKOUT0(clkPSInt), 				// Phase shifted clock for ENC
	.CLKOUT1(clk8xInt), 				// Deserialization clock for LVDS inputs
	.CLKOUT2(clk2xInt),				//	Clock for IDELAY control, 200MHz
	.CLKOUT3(clkDivInt),				//	Divided clock for deserialization
	// Dynamic Phase Shift Ports: 1-bit (each) output: Ports used for dynamic phase shifting of the outputs
	.PSDONE(PS_done), 				// 1-bit output: Phase shift done
	// Feedback Clocks: 1-bit (each) output: Clock feedback ports
	.CLKFBOUT(clkPSf), 				// 1-bit output: Feedback clock
	.LOCKED(PS_locked), 				// 1-bit output: LOCK
	// Clock Inputs: 1-bit (each) input: Clock inputs
	.CLKIN1(clk_in), 					// 1-bit input: Primary clock
	// Control Ports: 1-bit (each) input: MMCM control ports
	.CLKINSEL(1'b1), 					// 1-bit input: Clock select, High=CLKIN1 Low=CLKIN2
	.PWRDWN(1'b0), 					// 1-bit input: Power-down
	.RST(rst_in), 						// 1-bit input: Reset
	// DRP Ports: 7-bit (each) input: Dynamic reconfiguration ports
	.DWE(1'b0), 						// 1-bit input: DRP write enable
	// Dynamic Phase Shift Ports: 1-bit (each) input: Ports used for dynamic phase shifting of the outputs
	.PSCLK(PS_clk), 					// 1-bit input: Phase shift clock
	.PSEN(PS_en), 						// 1-bit input: Phase shift enable
	.PSINCDEC(PS_inc), 				// 1-bit input: Phase shift increment/decrement
	// Feedback Clocks: 1-bit (each) input: Clock feedback ports
	.CLKFBIN(clkPSf) 					// 1-bit input: Feedback clock
);

BUFG BUFG_clkPS (
	.O(clkPS), 		// 1-bit output: Clock output
	.I(clkPSInt) 	// 1-bit input: Clock input
);

// DDR register
wire ENC_out;
// ODDR: Output Double Data Rate Output Register with Set, Reset, and Clock Enable.
ODDR #(
	.DDR_CLK_EDGE("OPPOSITE_EDGE"), 	// "OPPOSITE_EDGE" or "SAME_EDGE"
	.INIT(1'b0), 		// Initial value of Q: 1'b0 or 1'b1
	.SRTYPE("ASYNC") 	// Set/Reset type: "SYNC" or "ASYNC"
) ODDR_inst (
	.Q(ENC_out), 	// 1-bit DDR output
	.C(clkPS), 		// 1-bit clock input
	.CE(1'b1), 		// 1-bit clock enable input
	.D1(1'b0), 		// 1-bit data input (positive edge)
	.D2(1'b1), 		// 1-bit data input (negative edge)
	.R(rst_in), 	// 1-bit reset
	.S() 				// 1-bit set
);

// Output buffer
OBUFDS #(
	.IOSTANDARD("LVDS_25")
)
obufds_inst(
	.O(ENC_out_p),
	.OB(ENC_out_n),
	.I(ENC_out)
);

///////////////////////////////////////////////////////////////////////////////
// LVDS DCO input

// Input buffer
wire DCO_in;

// IBUFDS: Differential Input Buffer
IBUFDS #(
	.DIFF_TERM("TRUE"), 		// Differential Termination
	.IBUF_LOW_PWR("TRUE"), 	// Low power="TRUE", Highest performance="FALSE"
	.IOSTANDARD("LVDS_25") 	// Specify the input I/O standard
) IBUFDS_inst (
	.O(DCO_in), 	// Buffer output
	.I(DCO_in_p), 	// Diff_p buffer input (connect directly to top-level port)
	.IB(DCO_in_n) 	// Diff_n buffer input (connect directly to top-level port)
);

///////////////////////////////////////////////////////////////////////////////
// LVDS inputs

localparam N_LVDS = 5;		//Number of LVDS channels
localparam N_SERIAL = 8;	//Number of bits in serial channel

wire   [N_LVDS-1:0] data_in_p, data_in_n;
assign data_in_p = {FR_in_p, D1_in_p, D0_in_p};
assign data_in_n = {FR_in_n, D1_in_n, D0_in_n};

wire [N_LVDS*N_SERIAL-1:0] data_out;

always @(posedge clk_in) begin
	//Order to get bits in right place
	ADC0_out <= {
		data_out[ 0], 	data_out[ 8], 	data_out[ 1], 	data_out[ 9], 	data_out[ 2], 	data_out[ 10], 	data_out[ 3], 	data_out[ 11],
		data_out[4], 	data_out[12], 	data_out[5], 	data_out[13], 	data_out[ 6], 	data_out[14], 		data_out[ 7], 	data_out[15]
	};
	ADC1_out <= {
		data_out[16 + 0], data_out[16 + 8], 	data_out[16 + 1], data_out[16 + 9], 	data_out[16 + 2], data_out[16 + 10], data_out[16 + 3], data_out[16 + 11],
		data_out[16 + 4], data_out[16 + 12],	data_out[16 + 5], data_out[16 + 13],	data_out[16 + 6], data_out[16 + 14], data_out[16 + 7], data_out[16 +15]
	};	
	FR_out <= data_out[39:32];	//filling up remaining channels (extra from loop)?
end

// Generate the serial data clock - SDR at 8x the frequency of the ENC signal for a 2 wire interface
wire clk8x, clkDiv;

// Buffers for deserialization clocks.
BUFG BUFG_8x (
	.O(clk8x), 		// 1-bit output: Clock output
	.I(clk8xInt) 	// 1-bit input: Clock input
);

BUFG BUFG_clkDiv (
	.O(clkDiv), 	// 1-bit output: Clock output
	.I(clkDivInt) 	// 1-bit input: Clock input
);

// We have multiple bits - step over every bit, instantiating the required elements

wire [N_LVDS-1:0] data_in_from_pins; 			// between the input buffer and the delay
wire [N_LVDS-1:0] data_in_from_pins_delay; 	// between the delay and the deserializer

//Delay stuff unused right now
/*
// I added 50 to all the values here because I couldn't reach the middle of the eye with the encode phase shifter (it had hit the end of its range)
//Removed the 50 to route design.
//If I want to implement delay I have to figure out IDELAYCTRL issue, and map delay values from IODELAY2 to IDELAYE2.
function integer delay_value;
	input i;
	begin
		case (i)
			0:	delay_value = 0;
			1:	delay_value = 2;
			2:	delay_value = 5;
			3:	delay_value = 8;
			4:	delay_value = 9;
			5:	delay_value = 9;
			6:	delay_value = 9;
			7:	delay_value = 8;
			8:	delay_value = 0;
			default:
				delay_value = 0;
		endcase
	end
endfunction
*/
/*
// Buffer for IDELAYCTRL clock.
BUFG BUFG_2x (
	.O(clk2x), 		// 1-bit output: Clock output
	.I(clk2xInt) 	// 1-bit input: Clock input
);

// IDELAYCTRL: IDELAYE2/ODELAYE2 Tap Delay Value Control
// Needed for IDELAYE2
(* IODELAY_GROUP = "Input_Delay" *) // Specifies group name for associated IDELAYs/ODELAYs and IDELAYCTRL
IDELAYCTRL IDELAYCTRL_inst (
	.RDY(), 				// 1-bit output: Ready output
	.REFCLK(clk2x), 	// 1-bit input: Reference clock input
	.RST(rst_in) 		// 1-bit input: Active high reset input
);
*/
genvar pin_count;
generate for (pin_count = 0; pin_count < N_LVDS; pin_count = pin_count + 1) begin: pins
	
	// IBUFDS: Differential Input Buffer
	IBUFDS #(
		.DIFF_TERM("TRUE"), 			// Differential Termination
		.IBUF_LOW_PWR("FALSE"), 	// Low power="TRUE", Highest performance="FALSE"
		.IOSTANDARD("LVDS_25") 		// Specify the input I/O standard
	) IBUFDS_inst (
		.O(data_in_from_pins[pin_count]), 	// Buffer output
		.I(data_in_p[pin_count]), 				// Diff_p buffer input (connect directly to top-level port)
		.IB(data_in_n[pin_count]) 				// Diff_n buffer input (connect directly to top-level port)
	);
	
	/*
	// IDELAYE2: Input Fixed or Variable Delay Element
	(* IODELAY_GROUP = "Input_Delay" *) // Specifies group name for associated IDELAYs/ODELAYs and IDELAYCTRL
	IDELAYE2 #(
		.CINVCTRL_SEL("FALSE"), 					// Enable dynamic clock inversion (FALSE, TRUE)
		.DELAY_SRC("IDATAIN"), 						// Delay input (IDATAIN, DATAIN)
		.HIGH_PERFORMANCE_MODE("TRUE"), 			// Reduced jitter ("TRUE"), Reduced power ("FALSE")
		.IDELAY_TYPE("FIXED"), 						// FIXED, VARIABLE, VAR_LOAD, VAR_LOAD_PIPE
		.IDELAY_VALUE(delay_value(pin_count)),	// Input delay tap setting (0-31)
		.PIPE_SEL("FALSE"), 							// Select pipelined mode, FALSE, TRUE
		.REFCLK_FREQUENCY(200.0), 					// IDELAYCTRL clock input frequency in MHz (190.0-210.0, 290.0-310.0).
		.SIGNAL_PATTERN("DATA") 					// DATA, CLOCK input signal
	)
	IDELAYE2_inst (
		.IDATAIN(data_in_from_pins[pin_count]), 			// 1-bit input: Data input from the I/O
		.DATAOUT(data_in_from_pins_delay[pin_count]), 	// 1-bit output: Delayed data output
		.C(1'b0), 													// 1-bit input: Clock input
		.CE(1'b0), 												// 1-bit input: Active high enable increment/decrement input
		.CINVCTRL(), 												// 1-bit input: Dynamic clock inversion input
		.CNTVALUEIN(), 											// 5-bit input: Counter value input
		.DATAIN(), 													// 1-bit input: Internal delay data input
		.INC(),	 													// 1-bit input: Increment / Decrement tap delay input
		.LD(), 														// 1-bit input: Load IDELAY_VALUE input
		.LDPIPEEN(1'b0),		 									// 1-bit input: Enable PIPELINE register to load data input
		.REGRST(1'b0),	 											// 1-bit input: Active-high reset tap-delay input
		.CNTVALUEOUT()												// 5-bit output: Counter value output
	);	
	*/
	
	 // ISERDESE2: Input SERial/DESerializer with Bitslip
ISERDESE2 #(
.DATA_RATE("SDR"), // DDR, SDR
.DATA_WIDTH(8), // Parallel data width (2-8,10,14)
.DYN_CLKDIV_INV_EN("FALSE"), // Enable DYNCLKDIVINVSEL inversion (FALSE, TRUE)
.DYN_CLK_INV_EN("FALSE"), // Enable DYNCLKINVSEL inversion (FALSE, TRUE)
// INIT_Q1 - INIT_Q4: Initial value on the Q outputs (0/1)
.INIT_Q1(1'b0),
.INIT_Q2(1'b0),
.INIT_Q3(1'b0),
.INIT_Q4(1'b0),
.INTERFACE_TYPE("NETWORKING"), // MEMORY, MEMORY_DDR3, MEMORY_QDR, NETWORKING, OVERSAMPLE
.IOBDELAY("NONE"), // NONE, BOTH, IBUF, IFD
.NUM_CE(2), // Number of clock enables (1,2)
.OFB_USED("FALSE"), // Select OFB path (FALSE, TRUE)
.SERDES_MODE("MASTER"), // MASTER, SLAVE
// SRVAL_Q1 - SRVAL_Q4: Q output values when SR is used (0/1)
.SRVAL_Q1(1'b0),
.SRVAL_Q2(1'b0),
.SRVAL_Q3(1'b0),
.SRVAL_Q4(1'b0)
)
ISERDESE2_inst (
.O(), // 1-bit output: Combinatorial output
// Q1 - Q8: 1-bit (each) output: Registered data outputs
.Q1(data_out[N_SERIAL*pin_count+7]),
.Q2(data_out[N_SERIAL*pin_count+6]),
.Q3(data_out[N_SERIAL*pin_count+5]),
.Q4(data_out[N_SERIAL*pin_count+4]),
.Q5(data_out[N_SERIAL*pin_count+3]),
.Q6(data_out[N_SERIAL*pin_count+2]),
.Q7(data_out[N_SERIAL*pin_count+1]),
.Q8(data_out[N_SERIAL*pin_count+0]),
// SHIFTOUT1, SHIFTOUT2: 1-bit (each) output: Data width expansion output ports
.SHIFTOUT1(),
.SHIFTOUT2(),
.BITSLIP(), // 1-bit input: The BITSLIP pin performs a Bitslip operation synchronous to
// CLKDIV when asserted (active High). Subsequently, the data seen on the Q1
// to Q8 output ports will shift, as in a barrel-shifter operation, one
// position every time Bitslip is invoked (DDR operation is different from
// SDR).
// CE1, CE2: 1-bit (each) input: Data register clock enable inputs
.CE1(1'b1),
.CE2(1'b1),
.CLKDIVP(1'b0), // 1-bit input: TBD
// Clocks: 1-bit (each) input: ISERDESE2 clock input ports
.CLK(CLK), // 1-bit input: High-speed clock
.CLKB(clk8x), // 1-bit input: High-speed secondary clock
.CLKDIV(clkDiv), // 1-bit input: Divided clock
.OCLK(1'b0), // 1-bit input: High speed output clock used when INTERFACE_TYPE="MEMORY"
// Dynamic Clock Inversions: 1-bit (each) input: Dynamic clock inversion pins to switch clock polarity
.DYNCLKDIVSEL(), // 1-bit input: Dynamic CLKDIV inversion
.DYNCLKSEL(), // 1-bit input: Dynamic CLK/CLKB inversion
// Input Data: 1-bit (each) input: ISERDESE2 data input ports
.D(data_in_from_pins[pin_count]), // 1-bit input: Data input
.DDLY(), // 1-bit input: Serial data from IDELAYE2
.OFB(), // 1-bit input: Data feedback from OSERDESE2
.OCLKB(), // 1-bit input: High speed negative edge output clock
.RST(rst_in), // 1-bit input: Active high asynchronous reset
// SHIFTIN1, SHIFTIN2: 1-bit (each) input: Data width expansion input ports
.SHIFTIN1(1'b0),
.SHIFTIN2(1'b0)
); end endgenerate

Here's my testbench:

`timescale 1ns / 1ps

////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer:
//
// Create Date:   13:38:51 06/08/2017
// Design Name:   LTC2195
// Module Name:   C:/Users/dschussheim/Documents/GitHub/digital-servo/firmware/LTC2195_tb.v
// Project Name:  SuperLaserLand
// Target Device:  
// Tool versions:  
// Description: 
//
// Verilog Test Fixture created by ISE for module: LTC2195
//
// Dependencies:
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
////////////////////////////////////////////////////////////////////////////////

module LTC2195_tb;

	// Inputs
	reg clk_in;
	reg rst_in;
	reg cmd_trig_in;
	reg [15:0] cmd_addr_in;
	reg [15:0] cmd_data_in;
	reg spi_sdi_in;
	reg DCO_in_p;
	reg DCO_in_n;
	reg FR_in_p;
	reg FR_in_n;
	reg [1:0] D0_in_p;
	reg [1:0] D0_in_n;
	reg [1:0] D1_in_p;
	reg [1:0] D1_in_n;

	// Outputs
	wire spi_scs_out;
	wire spi_sck_out;
	wire spi_sdo_out;
	wire ENC_out_p;
	wire ENC_out_n;
	wire [15:0] ADC0_out;
	wire [15:0] ADC1_out;
	wire [7:0] FR_out;

	// Instantiate the Unit Under Test (UUT)
	LTC2195 uut (
		.clk_in(clk_in), 
		.rst_in(rst_in), 
		.cmd_trig_in(cmd_trig_in), 
		.cmd_addr_in(cmd_addr_in), 
		.cmd_data_in(cmd_data_in), 
		.spi_scs_out(spi_scs_out), 
		.spi_sck_out(spi_sck_out), 
		.spi_sdo_out(spi_sdo_out), 
		.spi_sdi_in(spi_sdi_in), 
		.ENC_out_p(ENC_out_p), 
		.ENC_out_n(ENC_out_n), 
		.DCO_in_p(DCO_in_p), 
		.DCO_in_n(DCO_in_n), 
		.FR_in_p(FR_in_p), 
		.FR_in_n(FR_in_n), 
		.D0_in_p(D0_in_p), 
		.D0_in_n(D0_in_n), 
		.D1_in_p(D1_in_p), 
		.D1_in_n(D1_in_n), 
		.ADC0_out(ADC0_out), 
		.ADC1_out(ADC1_out), 
		.FR_out(FR_out)
	);

	initial begin
		// Initialize Inputs
		clk_in = 0;
		rst_in = 0;
		cmd_trig_in = 0;
		cmd_addr_in = 0;
		cmd_data_in = 0;
		spi_sdi_in = 0;
		DCO_in_p = 0;
		DCO_in_n = ~DCO_in_p;
		FR_in_p = 0;
		FR_in_n = ~FR_in_p;
		D0_in_p = 2'b11;
		D0_in_n = ~D0_in_p;
		D1_in_p = 2'b00;
		D1_in_n = ~D1_in_p;


        
		// Add stimulus here
		#500	rst_in = 1;
		#100	rst_in = 0; //DCM SP says reset must be high for at least 3 valid clock cycles


	end
      
	//Clock
	always 
		#5 clk_in = ~clk_in;  // 100 MHz
	always
		#1.25	DCO_in_p = ~DCO_in_p;
	always
		#1.25	DCO_in_n = ~DCO_in_n;
	always
		#5	FR_in_p = ~FR_in_p;
	always
		#5	FR_in_n = ~FR_in_n;

	
		
endmodule

 

0 Kudos
1 Solution

Accepted Solutions
Highlighted
Explorer
Explorer
8,627 Views
Registered: ‎06-08-2017

Re: ISERDESE2 unknown outputs

Jump to solution

Simulation works fine in Vivado 2017.2.

 

I guess there is a bug in the simulation compiler for ISE!

View solution in original post

0 Kudos
8 Replies
Teacher muzaffer
Teacher
5,246 Views
Registered: ‎03-31-2012

Re: ISERDESE2 unknown outputs

Jump to solution

@dschussheim connect floating inputs to iserdes (specifically bitslip to zero) and see if that makes a difference.

- Please mark the Answer as "Accept as solution" if information provided is helpful.
Give Kudos to a post which you think is helpful and reply oriented.
0 Kudos
Explorer
Explorer
5,240 Views
Registered: ‎06-08-2017

Re: ISERDESE2 unknown outputs

Jump to solution

@muzaffer Thanks for your reply. Tying unused inputs to ground didn't change anything on the output....

 

I put together a simpler module that only has the deserializer (for readability). Q = xxxxxx00 for the code below. In general, Q[0] = INIT_Q1, Q[1] = INIT_Q3.

 

module deserializer(
    output [7:0] Q,
    input D,
    input clk,
    input clkDiv,
    input rst
    );

parameter DATA_WIDTH = 8;

// ISERDESE2: Input SERial/DESerializer with Bitslip
ISERDESE2 #(
	.DATA_RATE("SDR"), 					// DDR, SDR
	.DATA_WIDTH(DATA_WIDTH), 			// Parallel data width (2-8,10,14)
	.DYN_CLKDIV_INV_EN("FALSE"), 		// Enable DYNCLKDIVINVSEL inversion (FALSE, TRUE)
	.DYN_CLK_INV_EN("FALSE"), 			// Enable DYNCLKINVSEL inversion (FALSE, TRUE)
	// INIT_Q1 - INIT_Q4: Initial value on the Q outputs (0/1)
	.INIT_Q1(1'b0),
	.INIT_Q2(1'b0),
	.INIT_Q3(1'b0),
	.INIT_Q4(1'b0),
	.INTERFACE_TYPE("NETWORKING"),	// MEMORY, MEMORY_DDR3, MEMORY_QDR, NETWORKING, OVERSAMPLE
	.IOBDELAY("NONE"), 					// NONE, BOTH, IBUF, IFD
	.NUM_CE(2), 							// Number of clock enables (1,2)
	.OFB_USED("FALSE"), 					// Select OFB path (FALSE, TRUE)
	.SERDES_MODE("MASTER"), 			// MASTER, SLAVE
	// SRVAL_Q1 - SRVAL_Q4: Q output values when SR is used (0/1)
	.SRVAL_Q1(1'b0),
	.SRVAL_Q2(1'b0),
	.SRVAL_Q3(1'b0),
	.SRVAL_Q4(1'b0)
)
ISERDESE2_inst (
	.O(), 				// 1-bit output: Combinatorial output
	// Q1 - Q8: 1-bit (each) output: Registered data outputs
	.Q1(Q[0]),
	.Q2(Q[1]),
	.Q3(Q[2]),
	.Q4(Q[3]),
	.Q5(Q[4]),
	.Q6(Q[5]),
	.Q7(Q[6]),
	.Q8(Q[7]),
	// SHIFTOUT1, SHIFTOUT2: 1-bit (each) output: Data width expansion output ports
	.SHIFTOUT1(),
	.SHIFTOUT2(),
	.BITSLIP(1'b0), 		// 1-bit input: The BITSLIP pin performs a Bitslip operation synchronous to
	// CLKDIV when asserted (active High). Subsequently, the data seen on the Q1
	// to Q8 output ports will shift, as in a barrel-shifter operation, one
	// position every time Bitslip is invoked (DDR operation is different from
	// SDR).
	// CE1, CE2: 1-bit (each) input: Data register clock enable inputs
	.CE1(1'b1),
	.CE2(1'b1),
	.CLKDIVP(1'b0), 	// 1-bit input: TBD
	// Clocks: 1-bit (each) input: ISERDESE2 clock input ports
	.CLK(clk), 			// 1-bit input: High-speed clock
	.CLKB(1'b0), 			// 1-bit input: High-speed secondary clock
	.CLKDIV(clkDiv), 	// 1-bit input: Divided clock
	.OCLK(1'b0), 			// 1-bit input: High speed output clock used when INTERFACE_TYPE="MEMORY"
	// Dynamic Clock Inversions: 1-bit (each) input: Dynamic clock inversion pins to switch clock polarity
	.DYNCLKDIVSEL(1'b0),	// 1-bit input: Dynamic CLKDIV inversion
	.DYNCLKSEL(1'b0), 		// 1-bit input: Dynamic CLK/CLKB inversion
	// Input Data: 1-bit (each) input: ISERDESE2 data input ports
	.D(D), 				// 1-bit input: Data input
	.DDLY(1'b0), 			// 1-bit input: Serial data from IDELAYE2
	.OFB(1'b0), 				// 1-bit input: Data feedback from OSERDESE2
	.OCLKB(1'b0), 			// 1-bit input: High speed negative edge output clock
	.RST(rst), 		// 1-bit input: Active high asynchronous reset
	// SHIFTIN1, SHIFTIN2: 1-bit (each) input: Data width expansion input ports
	.SHIFTIN1(1'b0),
	.SHIFTIN2(1'b0)
);

endmodule

Testbench

module deserializer_tb;

	// Inputs
	reg D;
	reg clk;
	reg clkDiv;
	reg rst;

	// Outputs
	wire [7:0] Q;

	// Instantiate the Unit Under Test (UUT)
	deserializer uut (
		.Q(Q), 
		.D(D), 
		.clk(clk), 
		.clkDiv(clkDiv)
	);

	initial begin
		// Initialize Inputs
		D = 0;
		clk = 0;
		clkDiv = 0;
		rst = 0;
		// Wait 100 ns for global reset to finish
		#300;
       rst = 1;
		 #500 rst = 0;
		// Add stimulus here

	end
	always
		#10 clk = ~clk;
	always
		#80 clkDiv = ~clkDiv;
      
endmodule

 

0 Kudos
Explorer
Explorer
5,239 Views
Registered: ‎06-08-2017

Re: ISERDESE2 unknown outputs

Jump to solution
One thing I noticed is that the rst input does not change the output of ISERDESE2 at all.
0 Kudos
Teacher muzaffer
Teacher
5,199 Views
Registered: ‎03-31-2012

Re: ISERDESE2 unknown outputs

Jump to solution

@dschussheim try

 

	.CLKB(!clk), 			// 1-bit input: High-speed secondary clock
- Please mark the Answer as "Accept as solution" if information provided is helpful.
Give Kudos to a post which you think is helpful and reply oriented.
0 Kudos
Explorer
Explorer
5,172 Views
Registered: ‎06-08-2017

Re: ISERDESE2 unknown outputs

Jump to solution

@muzaffer My CLK/CLKDIV inputs were not aligned properly in simulation. Now they are aligned. I get all xxxx at outputs regardless of inputs. CLKB being grounded or inverted version of CLK does not change outputs.

 

I tried BUFIO(.I(clk),.o(clk_in)) --> .CLK(clk_in), and BUFR(.I(clk),.O(.clkDiv_in)) (divide by 8) --> .CLKDIV(clkDiv_in), and .CLKB(!clk_in).

 

With the buffered clk inputs I get similar behavior to before, where Q1 and Q2 are determined by INIT_Q1 and INIT_Q3, but now if either of those initial values are 1, I get an x.

 

Just for reference I am using ISE webpack 14.7/iSim 14.7

 

module deserializer(
	output	wire	[3:0]	Q,
    input 	wire			D,
    input 	wire			clk,
    input 	wire			clkDiv,
	 input 	wire			rst
    );

parameter DATA_WIDTH = 4;

// BUFIO: Local Clock Buffer for I/O
BUFIO BUFIO_inst (
	.O(clk_in), // 1-bit output: Clock output (connect to I/O clock loads).
	.I(clk) // 1-bit input: Clock input (connect to an IBUF or BUFMR).
);

// BUFR: Regional Clock Buffer for I/O and Logic Resources within a Clock Region
// 7 Series
// Xilinx HDL Libraries Guide, version 14.7
BUFR #(
	.BUFR_DIVIDE("4"), // Values: "BYPASS, 1, 2, 3, 4, 5, 6, 7, 8"
	.SIM_DEVICE("7SERIES") // Must be set to "7SERIES"
)
BUFR_inst (
	.O(clkDiv_in), // 1-bit output: Clock output port
	.CE(1'b1), // 1-bit input: Active high, clock enable (Divided modes only)
	.CLR(rst), // 1-bit input: Active high, asynchronous clear (Divided modes only)
	.I(clk) // 1-bit input: Clock buffer input driven by an IBUF, MMCM or local interconnect
);


// ISERDESE2: Input SERial/DESerializer with Bitslip
ISERDESE2 #(
	.DATA_RATE("SDR"), 					// DDR, SDR
	.DATA_WIDTH(DATA_WIDTH), 			// Parallel data width (2-8,10,14)
	.DYN_CLKDIV_INV_EN("FALSE"), 		// Enable DYNCLKDIVINVSEL inversion (FALSE, TRUE)
	.DYN_CLK_INV_EN("FALSE"), 			// Enable DYNCLKINVSEL inversion (FALSE, TRUE)
	// INIT_Q1 - INIT_Q4: Initial value on the Q outputs (0/1)
	.INIT_Q1(1'b0),
	.INIT_Q2(1'b1),
	.INIT_Q3(1'b0),
	.INIT_Q4(1'b0),
	.INTERFACE_TYPE("NETWORKING"),	// MEMORY, MEMORY_DDR3, MEMORY_QDR, NETWORKING, OVERSAMPLE
	.IOBDELAY("NONE"), 					// NONE, BOTH, IBUF, IFD
	.NUM_CE(1), 							// Number of clock enables (1,2)
	.OFB_USED("FALSE"), 					// Select OFB path (FALSE, TRUE)
	.SERDES_MODE("MASTER"), 			// MASTER, SLAVE
	// SRVAL_Q1 - SRVAL_Q4: Q output values when SR is used (0/1)
	.SRVAL_Q1(1'b0),
	.SRVAL_Q2(1'b0),
	.SRVAL_Q3(1'b0),
	.SRVAL_Q4(1'b0)
)
ISERDESE2_inst (
	.O(), 				// 1-bit output: Combinatorial output
	// Q1 - Q8: 1-bit (each) output: Registered data outputs
	.Q1(Q[0]),
	.Q2(Q[1]),
	.Q3(Q[2]),
	.Q4(Q[3]),
	.Q5(),
	.Q6(),
	.Q7(),
	.Q8(),
	// SHIFTOUT1, SHIFTOUT2: 1-bit (each) output: Data width expansion output ports
	.SHIFTOUT1(),
	.SHIFTOUT2(),
	.BITSLIP(1'b0), 		// 1-bit input: The BITSLIP pin performs a Bitslip operation synchronous to
	// CLKDIV when asserted (active High). Subsequently, the data seen on the Q1
	// to Q8 output ports will shift, as in a barrel-shifter operation, one
	// position every time Bitslip is invoked (DDR operation is different from
	// SDR).
	// CE1, CE2: 1-bit (each) input: Data register clock enable inputs
	.CE1(1'b1),
	.CE2(1'b0),
	.CLKDIVP(1'b0), 	// 1-bit input: TBD
	// Clocks: 1-bit (each) input: ISERDESE2 clock input ports
	.CLK(clk_in), 			// 1-bit input: High-speed clock
	.CLKB(!clk_in), 			// 1-bit input: High-speed secondary clock
	.CLKDIV(clkDiv_in), 	// 1-bit input: Divided clock
	.OCLK(1'b0), 			// 1-bit input: High speed output clock used when INTERFACE_TYPE="MEMORY"
	// Dynamic Clock Inversions: 1-bit (each) input: Dynamic clock inversion pins to switch clock polarity
	.DYNCLKDIVSEL(1'b0),	// 1-bit input: Dynamic CLKDIV inversion
	.DYNCLKSEL(1'b0), 		// 1-bit input: Dynamic CLK/CLKB inversion
	// Input Data: 1-bit (each) input: ISERDESE2 data input ports
	.D(D), 				// 1-bit input: Data input
	.DDLY(1'b0), 			// 1-bit input: Serial data from IDELAYE2
	.OFB(1'b0), 				// 1-bit input: Data feedback from OSERDESE2
	.OCLKB(1'b0), 			// 1-bit input: High speed negative edge output clock
	.RST(rst), 		// 1-bit input: Active high asynchronous reset
	// SHIFTIN1, SHIFTIN2: 1-bit (each) input: Data width expansion input ports
	.SHIFTIN1(1'b0),
	.SHIFTIN2(1'b0)
);

endmodule

 

 

0 Kudos
Explorer
Explorer
5,162 Views
Registered: ‎06-08-2017

Re: ISERDESE2 unknown outputs

Jump to solution

I think this may be a simulation issue. When I switch to "OVERSAMPLE" mode, and give the proper clocks as per UG471, ISERDESE2 simulates fine. The problem is, I need 1:8 deserialization, and only "NETWORKING" supports this data width.

 

Has anyone else used NETWORKING mode on ISERDESE2, or know anything useful about it? It should not be this complicated to use a deserializer....

0 Kudos
Highlighted
Explorer
Explorer
8,628 Views
Registered: ‎06-08-2017

Re: ISERDESE2 unknown outputs

Jump to solution

Simulation works fine in Vivado 2017.2.

 

I guess there is a bug in the simulation compiler for ISE!

View solution in original post

0 Kudos
Community Manager
Community Manager
5,126 Views
Registered: ‎08-08-2007

Re: ISERDESE2 unknown outputs

Jump to solution

Networking would be the most popular mode for the ISERDES (outside MIG of course). Might be worth looking at an Xapp like Xapp1017 :https://www.xilinx.com/support/documentation/application_notes/xapp1017-lvds-ddr-deserial.pdf

It has an example design with a test bench. 

Thanks,
Sandy

-------------------------------------------------------------------------
Don’t forget to reply, kudo, and accept as solution.
-------------------------------------------------------------------------
0 Kudos