@@ -136,53 +136,111 @@ module serializer
136136 position <= position == 4'd9 ? 4'd0 : position + 1'd1 ;
137137 end
138138 `else
139- altlvds_tx ALTLVDS_TX_component (
140- .tx_in ({ 10'b1111100000 , tmds_reversed[2 ], tmds_reversed[1 ], tmds_reversed[0 ]} ),
141- .tx_inclock (clk_pixel_x5),
142- .tx_out ({ tmds_clock, tmds[2 ], tmds[1 ], tmds[0 ]} ),
143- .tx_outclock (),
144- .pll_areset (1'b0 ),
145- .sync_inclock (1'b0 ),
146- .tx_coreclock (),
147- .tx_data_reset (reset),
148- .tx_enable (1'b1 ),
149- .tx_locked (),
150- .tx_pll_enable (1'b1 ),
151- .tx_syncclock (clk_pixel));
152- defparam
153- ALTLVDS_TX_component.center_align_msb = " UNUSED" ,
154- ALTLVDS_TX_component.common_rx_tx_pll = " OFF" ,
155- ALTLVDS_TX_component.coreclock_divide_by = 1 ,
156- // ALTLVDS_TX_component.data_rate = "800.0 Mbps",
157- ALTLVDS_TX_component.deserialization_factor = 10 ,
158- ALTLVDS_TX_component.differential_drive = 0 ,
159- ALTLVDS_TX_component.enable_clock_pin_mode = " UNUSED" ,
160- ALTLVDS_TX_component.implement_in_les = " OFF" ,
161- ALTLVDS_TX_component.inclock_boost = 0 ,
162- ALTLVDS_TX_component.inclock_data_alignment = " EDGE_ALIGNED" ,
163- ALTLVDS_TX_component.inclock_period = int '(10000000 .0 / (VIDEO_RATE * 10 .0 )),
164- ALTLVDS_TX_component.inclock_phase_shift = 0 ,
165- // ALTLVDS_TX_component.intended_device_family = "Cyclone V",
166- ALTLVDS_TX_component.lpm_hint = " CBX_MODULE_PREFIX=altlvds_tx_inst" ,
167- ALTLVDS_TX_component.lpm_type = " altlvds_tx" ,
168- ALTLVDS_TX_component.multi_clock = " OFF" ,
169- ALTLVDS_TX_component.number_of_channels = 4 ,
170- // ALTLVDS_TX_component.outclock_alignment = "EDGE_ALIGNED",
171- // ALTLVDS_TX_component.outclock_divide_by = 1,
172- // ALTLVDS_TX_component.outclock_duty_cycle = 50,
173- // ALTLVDS_TX_component.outclock_multiply_by = 1,
174- // ALTLVDS_TX_component.outclock_phase_shift = 0,
175- // ALTLVDS_TX_component.outclock_resource = "Dual-Regional clock",
176- ALTLVDS_TX_component.output_data_rate = int '(VIDEO_RATE * 10 .0 ),
177- ALTLVDS_TX_component.pll_compensation_mode = " AUTO" ,
178- ALTLVDS_TX_component.pll_self_reset_on_loss_lock = " OFF" ,
179- ALTLVDS_TX_component.preemphasis_setting = 0 ,
180- // ALTLVDS_TX_component.refclk_frequency = "20.000000 MHz",
181- ALTLVDS_TX_component.registered_input = " OFF" ,
182- ALTLVDS_TX_component.use_external_pll = " ON" ,
183- ALTLVDS_TX_component.use_no_phase_shift = " ON" ,
184- ALTLVDS_TX_component.vod_setting = 0 ,
185- ALTLVDS_TX_component.clk_src_is_pll = " off" ;
139+ `ifdef ALTERA_RESERVED_QIS
140+ altlvds_tx ALTLVDS_TX_component (
141+ .tx_in ({ 10'b1111100000 , tmds_reversed[2 ], tmds_reversed[1 ], tmds_reversed[0 ]} ),
142+ .tx_inclock (clk_pixel_x5),
143+ .tx_out ({ tmds_clock, tmds[2 ], tmds[1 ], tmds[0 ]} ),
144+ .tx_outclock (),
145+ .pll_areset (1'b0 ),
146+ .sync_inclock (1'b0 ),
147+ .tx_coreclock (),
148+ .tx_data_reset (reset),
149+ .tx_enable (1'b1 ),
150+ .tx_locked (),
151+ .tx_pll_enable (1'b1 ),
152+ .tx_syncclock (clk_pixel));
153+ defparam
154+ ALTLVDS_TX_component.center_align_msb = " UNUSED" ,
155+ ALTLVDS_TX_component.common_rx_tx_pll = " OFF" ,
156+ ALTLVDS_TX_component.coreclock_divide_by = 1 ,
157+ // ALTLVDS_TX_component.data_rate = "800.0 Mbps",
158+ ALTLVDS_TX_component.deserialization_factor = 10 ,
159+ ALTLVDS_TX_component.differential_drive = 0 ,
160+ ALTLVDS_TX_component.enable_clock_pin_mode = " UNUSED" ,
161+ ALTLVDS_TX_component.implement_in_les = " OFF" ,
162+ ALTLVDS_TX_component.inclock_boost = 0 ,
163+ ALTLVDS_TX_component.inclock_data_alignment = " EDGE_ALIGNED" ,
164+ ALTLVDS_TX_component.inclock_period = int '(10000000 .0 / (VIDEO_RATE * 10 .0 )),
165+ ALTLVDS_TX_component.inclock_phase_shift = 0 ,
166+ // ALTLVDS_TX_component.intended_device_family = "Cyclone V",
167+ ALTLVDS_TX_component.lpm_hint = " CBX_MODULE_PREFIX=altlvds_tx_inst" ,
168+ ALTLVDS_TX_component.lpm_type = " altlvds_tx" ,
169+ ALTLVDS_TX_component.multi_clock = " OFF" ,
170+ ALTLVDS_TX_component.number_of_channels = 4 ,
171+ // ALTLVDS_TX_component.outclock_alignment = "EDGE_ALIGNED",
172+ // ALTLVDS_TX_component.outclock_divide_by = 1,
173+ // ALTLVDS_TX_component.outclock_duty_cycle = 50,
174+ // ALTLVDS_TX_component.outclock_multiply_by = 1,
175+ // ALTLVDS_TX_component.outclock_phase_shift = 0,
176+ // ALTLVDS_TX_component.outclock_resource = "Dual-Regional clock",
177+ ALTLVDS_TX_component.output_data_rate = int '(VIDEO_RATE * 10 .0 ),
178+ ALTLVDS_TX_component.pll_compensation_mode = " AUTO" ,
179+ ALTLVDS_TX_component.pll_self_reset_on_loss_lock = " OFF" ,
180+ ALTLVDS_TX_component.preemphasis_setting = 0 ,
181+ // ALTLVDS_TX_component.refclk_frequency = "20.000000 MHz",
182+ ALTLVDS_TX_component.registered_input = " OFF" ,
183+ ALTLVDS_TX_component.use_external_pll = " ON" ,
184+ ALTLVDS_TX_component.use_no_phase_shift = " ON" ,
185+ ALTLVDS_TX_component.vod_setting = 0 ,
186+ ALTLVDS_TX_component.clk_src_is_pll = " off" ;
187+ `else
188+ // We don't know what the platform is so the best bet is an IP-less implementation.
189+ // Shift registers are loaded with a set of values from tmds_channels every clk_pixel.
190+ // They are shifted out on clk_pixel_x5 by the time the next set is loaded.
191+ logic [9 : 0 ] tmds_shift [NUM_CHANNELS - 1 : 0 ] = '{ 10'd0 , 10'd0 , 10'd0 } ;
192+
193+ logic tmds_control = 1'd0 ;
194+ always_ff @ (posedge clk_pixel)
195+ tmds_control <= ! tmds_control;
196+
197+ logic [3 : 0 ] tmds_control_synchronizer_chain = 4'd0 ;
198+ always_ff @ (posedge clk_pixel_x5)
199+ tmds_control_synchronizer_chain <= { tmds_control, tmds_control_synchronizer_chain[3 : 1 ]} ;
200+
201+ logic load;
202+ assign load = tmds_control_synchronizer_chain[1 ] ^ tmds_control_synchronizer_chain[0 ];
203+ logic [9 : 0 ] tmds_mux [NUM_CHANNELS - 1 : 0 ];
204+ always_comb
205+ begin
206+ if (load)
207+ tmds_mux = tmds_internal;
208+ else
209+ tmds_mux = tmds_shift;
210+ end
211+
212+ // See Section 5.4.1
213+ for (i = 0 ; i < NUM_CHANNELS ; i++ )
214+ begin : tmds_shifting
215+ always_ff @ (posedge clk_pixel_x5)
216+ tmds_shift[i] <= load ? tmds_mux[i] : tmds_shift[i] >> 2 ;
217+ end
218+
219+ logic [9 : 0 ] tmds_shift_clk_pixel = 10'b0000011111 ;
220+ always_ff @ (posedge clk_pixel_x5)
221+ tmds_shift_clk_pixel <= load ? 10'b0000011111 : { tmds_shift_clk_pixel[1 : 0 ], tmds_shift_clk_pixel[9 : 2 ]} ;
222+
223+ logic [NUM_CHANNELS - 1 : 0 ] tmds_shift_negedge_temp;
224+ for (i = 0 ; i < NUM_CHANNELS ; i++ )
225+ begin : tmds_driving
226+ always_ff @ (posedge clk_pixel_x5)
227+ begin
228+ tmds[i] <= tmds_shift[i][0 ];
229+ tmds_shift_negedge_temp[i] <= tmds_shift[i][1 ];
230+ end
231+ always_ff @ (negedge clk_pixel_x5)
232+ tmds[i] <= tmds_shift_negedge_temp[i];
233+ end
234+ logic tmds_clock_negedge_temp;
235+ always_ff @ (posedge clk_pixel_x5)
236+ begin
237+ tmds_clock <= tmds_shift_clk_pixel[0 ];
238+ tmds_clock_negedge_temp <= tmds_shift_clk_pixel[1 ];
239+ end
240+ always_ff @ (negedge clk_pixel_x5)
241+ tmds_clock <= tmds_shift_negedge_temp;
242+
243+ `endif
186244 `endif
187245 `endif
188246`endif
0 commit comments