x393  1.0
FPGAcodeforElphelNC393camera
sens_parallel12.v
Go to the documentation of this file.
1 
39 `timescale 1ns/1ps
40 
41 module sens_parallel12 #(
42  parameter SENSIO_ADDR = 'h330,
43  parameter SENSIO_ADDR_MASK = 'h7f8,
44  parameter SENSIO_CTRL = 'h0,
45  parameter SENSIO_STATUS = 'h1,
46  parameter SENSIO_JTAG = 'h2,
47  parameter SENSIO_WIDTH = 'h3, // set line width (1.. 2^16) if 0 - use HACT
48  parameter SENSIO_DELAYS = 'h4, // 'h4..'h7 - each address sets 4 delays through 4 bytes of 32-bit data
49  parameter SENSIO_STATUS_REG = 'h21,
50 
51  parameter SENS_JTAG_PGMEN = 8,
52  parameter SENS_JTAG_PROG = 6,
53  parameter SENS_JTAG_TCK = 4,
54  parameter SENS_JTAG_TMS = 2,
55  parameter SENS_JTAG_TDI = 0,
56 
57  parameter SENS_CTRL_MRST= 0, // 1: 0
58  parameter SENS_CTRL_ARST= 2, // 3: 2
59  parameter SENS_CTRL_ARO= 4, // 5: 4
60  parameter SENS_CTRL_RST_MMCM= 6, // 7: 6
61  parameter SENS_CTRL_EXT_CLK= 8, // 9: 8
62  parameter SENS_CTRL_LD_DLY= 10, // 10
63  parameter SENS_CTRL_QUADRANTS = 12, // 17:12, enable - 20
65  parameter SENS_CTRL_QUADRANTS_EN = 20, // 17:12, enable - 20 (2 bits reserved)
66 
67 
68  parameter LINE_WIDTH_BITS = 16,
69 
70  parameter IODELAY_GRP ="IODELAY_SENSOR", // may need different for different channels?
71  parameter integer IDELAY_VALUE = 0,
72  parameter integer PXD_DRIVE = 12,
73  parameter PXD_IBUF_LOW_PWR = "TRUE",
74  parameter PXD_IOSTANDARD = "DEFAULT",
75  parameter PXD_SLEW = "SLOW",
76  parameter real SENS_REFCLK_FREQUENCY = 300.0,
77  parameter SENS_HIGH_PERFORMANCE_MODE = "FALSE",
78 
79  parameter SENS_PHASE_WIDTH= 8, // number of bits for te phase counter (depends on divisors)
80 // parameter SENS_PCLK_PERIOD = 10.000, // input period in ns, 0..100.000 - MANDATORY, resolution down to 1 ps
81  parameter SENS_BANDWIDTH = "OPTIMIZED", //"OPTIMIZED", "HIGH","LOW"
82 
83  parameter CLKIN_PERIOD_SENSOR = 10.000, // input period in ns, 0..100.000 - MANDATORY, resolution down to 1 ps
84  parameter CLKFBOUT_MULT_SENSOR = 8, // 100 MHz --> 800 MHz
85  parameter CLKFBOUT_PHASE_SENSOR = 0.000, // CLOCK FEEDBACK phase in degrees (3 significant digits, -360.000...+360.000)
86  parameter IPCLK_PHASE = 0.000,
87  parameter IPCLK2X_PHASE = 0.000,
88  parameter BUF_IPCLK = "BUFR",
89  parameter BUF_IPCLK2X = "BUFR",
90 
91 
92  parameter SENS_DIVCLK_DIVIDE = 1, // Integer 1..106. Divides all outputs with respect to CLKIN
93  parameter SENS_REF_JITTER1 = 0.010, // Expected jitter on CLKIN1 (0.000..0.999)
94  parameter SENS_REF_JITTER2 = 0.010,
95  parameter SENS_SS_EN = "FALSE", // Enables Spread Spectrum mode
96  parameter SENS_SS_MODE = "CENTER_HIGH",//"CENTER_HIGH","CENTER_LOW","DOWN_HIGH","DOWN_LOW"
97  parameter SENS_SS_MOD_PERIOD = 10000, // integer 4000-40000 - SS modulation period in ns
98  parameter STATUS_ALIVE_WIDTH = 4
99 )(
100 // input rst,
101  input pclk, // global clock input, pixel rate (96MHz for MT9P006)
102  input mclk_rst,
103  input prst,
104  output prsts, // @pclk - includes sensor reset and sensor PLL reset
105  output irst,
106 
107  output ipclk, // re-generated sensor output clock (regional clock to drive external fifo)
108  output ipclk2x,// twice frequency regenerated sensor clock (possibly to run external fifo)
109 // input pclk2x, // maybe not needed here
110  input trigger_mode, // running in triggered mode (0 - free running mode)
111  input trig, // per-sensor trigger input
112  // sensor pads excluding i2c
113  inout vact,
114  inout hact, //output in fillfactory mode
115  inout bpf, // output in fillfactory mode
116  inout [11:0] pxd, //actually only 2 LSBs are inouts
117  inout mrst,
118  inout senspgm, // SENSPGM I/O pin
119 
120  inout arst,
121  inout aro,
122  output dclk, // externally connected to inout port
123  // output
124  output reg [11:0] pxd_out,
125  output reg vact_out,
126  output hact_out,
127 
128  input [STATUS_ALIVE_WIDTH-1:0] status_alive_1cyc, //extra toggle @mclk bits to report with status
129 
130  // JTAG to program 10359
131 // input xpgmen, // enable programming mode for external FPGA
132 // input xfpgaprog, // PROG_B to be sent to an external FPGA
133 // output xfpgadone, // state of the MRST pin ("DONE" pin on external FPGA)
134 // input xfpgatck, // TCK to be sent to external FPGA
135 // input xfpgatms, // TMS to be sent to external FPGA
136 // input xfpgatdi, // TDI to be sent to external FPGA
137 // output xfpgatdo, // TDO read from external FPGA
138 // output senspgmin,
139 
140  // programming interface
141  input mclk, // global clock, half DDR3 clock, synchronizes all I/O through the command port
142  input [7:0] cmd_ad, // byte-serial command address/data (up to 6 bytes: AL-AH-D0-D1-D2-D3
143  input cmd_stb, // strobe (with first byte) for the command a/d
144  output [7:0] status_ad, // status address/data - up to 5 bytes: A - {seq,status[1:0]} - status[2:9] - status[10:17] - status[18:25]
145  output status_rq, // input request to send status downstream
146  input status_start // Acknowledge of the first status packet byte (address)
147 );
148 
149  // delaying vact and pxd by one clock cycle to match hact register
150  wire [11:0] pxd_out_pre;
152 
153  reg [2:0] irst_r;
154  wire ibpf;
156 
157  reg [31:0] data_r;
158  reg [3:0] set_idelay;
161  reg [1:0] set_width_r; // to make double-cycle subtract
162  wire set_width_ipclk_w; //re-clocked to ipclk
163  reg set_width_ipclk_r; // copy from mclk domain when reset is off
164  wire set_width_ipclk = set_width_ipclk_w || set_width_ipclk_r; //re-clocked to ipclk
166 
167  reg [LINE_WIDTH_BITS-1:0] line_width_m1; // regenerated HACT duration;
168  reg [LINE_WIDTH_BITS-1:0] line_width_m1_ipclk; // regenerated HACT duration;
169 
170  reg line_width_internal; // use regenetrated ( 0 - use HACT as is)
173 
174 // reg set_quad; // [1:0] - px, [3:2] - HACT, [5:4] - VACT,
175  wire clk_fb;
176 
177  wire [2:0] set_pxd_delay;
179 
180  wire ps_rdy;
181  wire [7:0] ps_out;
185 
186  // programmed resets to the sensor
187  reg iaro_soft = 0;
188  wire iaro;
189  reg iarst = 0;
190  reg imrst = 0;
191  reg rst_mmcm=1; // rst and command - en/dis
192  reg [SENS_CTRL_QUADRANTS_WIDTH-1:0] quadrants=0; //90-degree shifts for data {1:0], hact [3:2] and vact [5:4]
193  reg ld_idelay=0;
194  reg sel_ext_clk=0; // select clock source from the sensor (0 - use internal clock - to sensor)
195 
196 
197 
198 // wire [17:0] status;
199 // wire [18:0] status;
200 // wire [22:0] status;
201  wire [25:0] status; // added byte-wide xfpgatdo
202 
203  wire cmd_we;
204  wire [2:0] cmd_a;
205  wire [31:0] cmd_data;
206 
207  wire xfpgadone; // state of the MRST pin ("DONE" pin on external FPGA)
208  wire xfpgatdo; // TDO read from external FPGA
209  reg [7:0] xfpgatdo_byte; // tdo signal shifted left at each TCK _/~
210  wire senspgmin;
211 
212  reg xpgmen=0; // enable programming mode for external FPGA
213  reg xfpgaprog=0; // PROG_B to be sent to an external FPGA
214  reg xfpgatck=0; // TCK to be sent to external FPGA
215  reg xfpgatms=0; // TMS to be sent to external FPGA
216  reg xfpgatdi=0; // TDI to be sent to external FPGA
217  wire hact_ext; // received hact signal
218  reg hact_ext_r; // received hact signal, delayed by 1 clock
219  reg hact_r; // received or regenerated hact
220 
221 // for debug/test alive
222  reg vact_r;
223  reg hact_r2;
231 
232  reg [1:0] prst_with_sens_mrst = 2'h3; // prst extended to include sensor reset and rst_mmcm
233  wire async_prst_with_sens_mrst = ~imrst | rst_mmcm; // mclk domain
234 
235  assign prsts = prst_with_sens_mrst[0]; // @pclk - includes sensor reset and sensor PLL reset
236 
237 
238  assign set_pxd_delay = set_idelay[2:0];
239  assign set_other_delay = set_idelay[3];
240 // assign status = {pxd_out_pre[1],vact_alive, hact_ext_alive, hact_alive, locked_pxd_mmcm,
241 // clkin_pxd_stopped_mmcm, clkfb_pxd_stopped_mmcm, xfpgadone,
242 // ps_rdy, ps_out, xfpgatdo, senspgmin};
243 // wire [25:0] status; // added byte-wide xfpgatdo
244 
245  assign status = {
246 /// irst, async_prst_with_sens_mrst, imrst, rst_mmcm, pxd_out_pre[1],
247  xfpgatdo_byte[7:0],
251 
252  assign hact_out = hact_r;
253  assign iaro = trigger_mode? ~trig : iaro_soft;
254 
255  assign irst=irst_r[2];
256 
257  always @ (posedge ipclk) begin
258 // irst_r <= {irst_r[1:0], prst};
259  irst_r <= {irst_r[1:0], prsts}; // extended reset that includes sensor reset and rst_mmcm
260  set_width_ipclk_r <= irst_r[2] && !irst_r[1];
261  end
262 
263  always @(posedge pclk or posedge async_prst_with_sens_mrst) begin
265  else if (prst) prst_with_sens_mrst <= 2'h3;
267  end
268 
269  always @(posedge mclk) begin
270  if (mclk_rst) data_r <= 0;
271  else if (cmd_we) data_r <= cmd_data;
272 
273  if (mclk_rst) set_idelay <= 0;
274  else set_idelay <= {4{cmd_we}} & {(cmd_a==(SENSIO_DELAYS+3)),
275  (cmd_a==(SENSIO_DELAYS+2)),
276  (cmd_a==(SENSIO_DELAYS+1)),
277  (cmd_a==(SENSIO_DELAYS+0))};
278  if (mclk_rst) set_status_r <=0;
279  else set_status_r <= cmd_we && (cmd_a== SENSIO_STATUS);
280 
281  if (mclk_rst) set_ctrl_r <=0;
282  else set_ctrl_r <= cmd_we && (cmd_a== SENSIO_CTRL);
283 
284  if (mclk_rst) set_jtag_r <=0;
285  else set_jtag_r <= cmd_we && (cmd_a== SENSIO_JTAG);
286 
287  if (mclk_rst) xpgmen <= 0;
289 
290  if (mclk_rst) xfpgaprog <= 0;
292 
293  if (mclk_rst) xfpgatck <= 0;
295 
296  // shift xfpgatdo to xfpgatdo_byte each time xfpgatck is 0->1
297  if (mclk_rst) xfpgatdo_byte <= 0;
299 
300  if (mclk_rst) xfpgatms <= 0;
302 
303  if (mclk_rst) xfpgatdi <= 0;
305 
306  if (mclk_rst) imrst <= 0;
308 
309  if (mclk_rst) iarst <= 0;
311 
312  if (mclk_rst) iaro_soft <= 0;
314 
315  if (mclk_rst) rst_mmcm <= 0;
317 
318  if (mclk_rst) sel_ext_clk <= 0;
320 
321  if (mclk_rst) quadrants <= 0;
323 
324  if (mclk_rst) ld_idelay <= 0;
326 
327  if (mclk_rst) set_width_r <= 0;
328  else set_width_r <= {set_width_r[0],cmd_we && (cmd_a== SENSIO_WIDTH)};
329 
330  if (mclk_rst) line_width_m1 <= 0;
331  else if (set_width_r[1]) line_width_m1 <= data_r[LINE_WIDTH_BITS-1:0] -1;
332 
333  if (mclk_rst) line_width_internal <= 0;
334  else if (set_width_r[1]) line_width_internal <= ~ (|data_r[LINE_WIDTH_BITS:0]); // line width is 0
335  end
336 
337  always @(posedge ipclk) begin
338  if (irst) line_width_m1_ipclk <= 0;
340 
343  // regenerate/propagate HACT
344  if (irst) hact_ext_r <= 1'b0;
345  else hact_ext_r <= hact_ext;
346 
347  if (irst) hact_r <= 0;
348  else if (hact_ext && !hact_ext_r) hact_r <= 1;
349  else if (line_width_internal_ipclk?(hact_ext ==0):(hact_cntr == 0)) hact_r <= 0;
350 
351  if (irst) hact_cntr <= 0;
352  else if (hact_ext && !hact_ext_r) hact_cntr <= line_width_m1_ipclk; // from mclk
354 
355  pxd_out <= pxd_out_pre;
357 
358  // for debug/test alive
359  vact_r <= vact_out_pre;
360  hact_r2 <= hact_r;
361 
362  end
363 
364  // for debug/test alive
365  always @(posedge mclk) begin
366  if (mclk_rst || set_status_r) vact_alive <= 0;
367  else if (vact_a_mclk) vact_alive <= 1;
368 
369  if (mclk_rst || set_status_r) hact_ext_alive <= 0;
370  else if (hact_ext_a_mclk) hact_ext_alive <= 1;
371 
372  if (mclk_rst || set_status_r) hact_alive <= 0;
373  else if (hact_a_mclk) hact_alive <= 1;
374 
375  if (mclk_rst || set_status_r) status_alive <= 0;
377 
378  end
379 
380 /*
381  Control programming of external FPGA on the sensor/sensor multiplexor board
382  Mulptiplex status signals into a single line
383  bits:
384  9: 8 - 3 - set xpgmen,
385  - 2 - reset xpgmen,
386  - 0, 1 - no changes to xpgmen
387  7: 6 - 3 - set xfpgaprog,
388  - 2 - reset xfpgaprog,
389  - 0, 1 - no changes to xfpgaprog
390  5: 4 - 3 - set xfpgatck,
391  - 2 - reset xfpgatck,
392  - 0, 1 - no changes to xfpgatck
393  3: 2 - 3 - set xfpgatms,
394  - 2 - reset xfpgatms,
395  - 0, 1 - no changes to xfpgatms
396  1: 0 - 3 - set xfpgatdi,
397  - 2 - reset xfpgatdi,
398  - 0, 1 - no changes to xfpgatdi
399  parameter SENS_CTRL_MRST= 0, // 1: 0
400  parameter SENS_CTRL_ARST= 2, // 3: 2
401  parameter SENS_CTRL_ARO= 4, // 5: 4
402  parameter SENS_CTRL_RST_MMCM= 6, // 7: 6
403  parameter SENS_CTRL_EXT_CLK= 8, // 9: 8
404  parameter SENS_CTRL_LD_DLY= 10, // 10
405  parameter SENS_CTRL_QUADRANTS=12, // 17:12, enable - 20
406 
407 */
408 
409  pulse_cross_clock pulse_cross_clock_set_width_ipclk_i (
410  .rst (mclk_rst), // input
411  .src_clk (mclk), // input
412  .dst_clk (ipclk), // input
413  .in_pulse (set_width_r[1]), // input
414  .out_pulse (set_width_ipclk_w), // output
415  .busy() // output
416  );
417 
418 
419 
421  .ADDR (SENSIO_ADDR),
422  .ADDR_MASK (SENSIO_ADDR_MASK),
423  .NUM_CYCLES (6),
424  .ADDR_WIDTH (3),
425  .DATA_WIDTH (32)
426  ) cmd_deser_sens_io_i (
427  .rst (1'b0), // rst), // input
428  .clk (mclk), // input
429  .srst (mclk_rst), // input
430  .ad (cmd_ad), // input[7:0]
431  .stb (cmd_stb), // input
432  .addr (cmd_a), // output[15:0]
433  .data (cmd_data), // output[31:0]
434  .we (cmd_we) // output
435  );
436 
438  .STATUS_REG_ADDR(SENSIO_STATUS_REG),
439 // .PAYLOAD_BITS(15+3+STATUS_ALIVE_WIDTH) // STATUS_PAYLOAD_BITS)
440 // .PAYLOAD_BITS(15+3+STATUS_ALIVE_WIDTH+1) // STATUS_PAYLOAD_BITS)
441  .PAYLOAD_BITS(26) // STATUS_PAYLOAD_BITS)
442  ) status_generate_sens_io_i (
443  .rst (1'b0), // rst), // input
444  .clk (mclk), // input
445  .srst (mclk_rst), // input
446  .we (set_status_r), // input
447  .wd (data_r[7:0]), // input[7:0]
448 // .status ({status_alive,status}), // input[25:0]
449  .status ({status}), // input[25:0]
450  .ad (status_ad), // output[7:0]
451  .rq (status_rq), // output
452  .start (status_start) // input
453  );
454 
455 
456 
457 
458  // 2 lower PXD bits are multifunction (used for JTAG), instance them individually
462  .PXD_DRIVE (PXD_DRIVE),
465  .PXD_SLEW (PXD_SLEW),
466  .REFCLK_FREQUENCY (SENS_REFCLK_FREQUENCY),
467  .HIGH_PERFORMANCE_MODE (SENS_HIGH_PERFORMANCE_MODE)
468  ) pxd_pxd0_i (
469  .pxd (pxd[0]), // inout
470  .pxd_out (xfpgatdi), // input
471  .pxd_en (xpgmen), // input
472  .pxd_async (), // output
473  .pxd_in (pxd_out_pre[0]), // output
474  .ipclk (ipclk), // input
475  .ipclk2x (ipclk2x), // input
476  .mrst (mclk_rst), // input
477  .irst (irst), // input
478  .mclk (mclk), // input
479  .dly_data (data_r[7:0]), // input[7:0]
480  .set_idelay (set_pxd_delay[0]),// input
481  .ld_idelay (ld_idelay), // input
482  .quadrant (quadrants[1:0]) // input[1:0]
483  );
484 
485 // debugging implementation
486 //assign xfpgatdo = pxd_out[1];
487  /* Instance template for module iobuf **/
488 //`define DEBUF_JTAG 1
489 `ifdef DEBUF_JTAG
490  iobuf #(
491  .DRIVE (PXD_DRIVE),
492  .IBUF_LOW_PWR (PXD_IBUF_LOW_PWR),
493  .IOSTANDARD (PXD_IOSTANDARD),
494  .SLEW (PXD_SLEW)
495  ) pxd_pxd1_i (
496  .O (pxd_out_pre[1]), // output
497  .IO (pxd[1]), // inout
498  .I (1'b0), // input
499  .T (1'b1) // input
500  );
501  assign xfpgatdo = pxd_out_pre[1];
502 `else
503  wire n_xfpgatdo;
504  assign xfpgatdo = !n_xfpgatdo;
505  pxd_single #(
508  .PXD_DRIVE (PXD_DRIVE),
511  .PXD_SLEW (PXD_SLEW),
512  .REFCLK_FREQUENCY (SENS_REFCLK_FREQUENCY),
513  .HIGH_PERFORMANCE_MODE (SENS_HIGH_PERFORMANCE_MODE)
514  ) pxd_pxd1_i (
515  .pxd (pxd[1]), // inout
516  .pxd_out (1'b0), // input
517  .pxd_en (1'b0), // input
518  .pxd_async (n_xfpgatdo), // output
519  .pxd_in (pxd_out_pre[1]), // output
520  .ipclk (ipclk), // input
521  .ipclk2x (ipclk2x), // input
522  .mrst (mclk_rst), // input
523  .irst (irst), // input
524  .mclk (mclk), // input
525  .dly_data (data_r[15:8]), // input[7:0]
526  .set_idelay (set_pxd_delay[0]),// input
527  .ld_idelay (ld_idelay), // input
528  .quadrant (quadrants[1:0]) // input[1:0]
529  );
530 `endif
531 
532 
533 
534  // bits 2..11 are just PXD inputs, instance them all together
535  generate
536  genvar i;
537  for (i=2; i < 12; i=i+1) begin: pxd_block
538  pxd_single #(
541  .PXD_DRIVE (PXD_DRIVE),
544  .PXD_SLEW (PXD_SLEW),
545  .REFCLK_FREQUENCY (SENS_REFCLK_FREQUENCY),
546  .HIGH_PERFORMANCE_MODE (SENS_HIGH_PERFORMANCE_MODE)
547  ) pxd_pxd2_12_i (
548  .pxd (pxd[i]), // inout
549  .pxd_out (1'b0), // input
550  .pxd_en (1'b0), // input
551  .pxd_async (), // output
552  .pxd_in (pxd_out_pre[i]), // output
553  .ipclk (ipclk), // input
554  .ipclk2x (ipclk2x), // input
555  .mrst (mclk_rst), // input
556  .irst (irst), // input
557  .mclk (mclk), // input
558 // .dly_data (data_r[8*((i+2)&3)+:8]), // input[7:0] alternating bytes of 32-bit word
559 // .set_idelay (set_pxd_delay[(i+2)>>2]),// input 0 for pxd[3:2], 1 for pxd[7:4], 2 for pxd [11:8]
560  .dly_data (data_r[8 * (i & 3) +: 8]), // input[7:0] alternating bytes of 32-bit word
561  .set_idelay (set_pxd_delay[i >> 2]),// input 0 for pxd[3:2], 1 for pxd[7:4], 2 for pxd [11:8]
562  .ld_idelay (ld_idelay), // input
563  .quadrant (quadrants[1:0]) // input[1:0]
564  );
565  end
566  endgenerate
567 
568  pxd_single #(
571  .PXD_DRIVE (PXD_DRIVE),
574  .PXD_SLEW (PXD_SLEW),
575  .REFCLK_FREQUENCY (SENS_REFCLK_FREQUENCY),
576  .HIGH_PERFORMANCE_MODE (SENS_HIGH_PERFORMANCE_MODE)
577  ) pxd_hact_i (
578  .pxd (hact), // inout
579  .pxd_out (1'b0), // input
580  .pxd_en (1'b0), // input
581  .pxd_async (), // output
582  .pxd_in (hact_ext), // output
583  .ipclk (ipclk), // input
584  .ipclk2x (ipclk2x), // input
585  .mrst (mclk_rst), // input
586  .irst (irst), // input
587  .mclk (mclk), // input
588  .dly_data (data_r[7:0]), // input[7:0]
589  .set_idelay (set_other_delay),// input
590  .ld_idelay (ld_idelay), // input
591  .quadrant (quadrants[3:2]) // input[1:0]
592  );
593 
594  pxd_single #(
597  .PXD_DRIVE (PXD_DRIVE),
600  .PXD_SLEW (PXD_SLEW),
601  .REFCLK_FREQUENCY (SENS_REFCLK_FREQUENCY),
602  .HIGH_PERFORMANCE_MODE (SENS_HIGH_PERFORMANCE_MODE)
603  ) pxd_vact_i (
604  .pxd (vact), // inout
605  .pxd_out (1'b0), // input
606  .pxd_en (1'b0), // input
607  .pxd_async (), // output
608  .pxd_in (vact_out_pre), // output
609  .ipclk (ipclk), // input
610  .ipclk2x (ipclk2x), // input
611  .mrst (mclk_rst), // input
612  .irst (irst), // input
613  .mclk (mclk), // input
614  .dly_data (data_r[15:8]), // input[7:0]
615  .set_idelay (set_other_delay),// input
616  .ld_idelay (ld_idelay), // input
617  .quadrant (quadrants[5:4]) // input[1:0]
618  );
619  // receive clock from sensor
620  pxd_clock #(
623  .PXD_DRIVE (PXD_DRIVE),
626  .PXD_SLEW (PXD_SLEW),
627  .REFCLK_FREQUENCY (SENS_REFCLK_FREQUENCY),
628  .HIGH_PERFORMANCE_MODE (SENS_HIGH_PERFORMANCE_MODE)
629  ) pxd_clock_i (
630  .pxclk (bpf), // inout
631  .pxclk_out (1'b0), // input
632  .pxclk_en (1'b0), // input
633  .pxclk_in (ibpf), // output
634  .rst (mclk_rst), // input
635  .mclk (mclk), // input
636  .dly_data (data_r[23:16]), // input[7:0]
637  .set_idelay (set_other_delay), // input
638  .ld_idelay (ld_idelay) // input
639  );
640  // generate dclk output
641  oddr_ss #(
642  .IOSTANDARD (PXD_IOSTANDARD),
643  .SLEW (PXD_SLEW),
644  .DDR_CLK_EDGE ("OPPOSITE_EDGE"),
645  .INIT (1'b0),
646  .SRTYPE ("SYNC")
647  ) dclk_i (
648  .clk (pclk), // input
649  .ce (1'b1), // input
650  .rst (prst), // input
651  .set (1'b0), // input
652  .din (2'b01), // input[1:0]
653  .tin (1'b0), // input
654  .dq (dclk) // output
655  );
656 
657  // generate ARO/TCK
658  iobuf #(
659  .DRIVE (PXD_DRIVE),
660  .IBUF_LOW_PWR (PXD_IBUF_LOW_PWR),
661  .IOSTANDARD (PXD_IOSTANDARD),
662  .SLEW (PXD_SLEW)
663  ) aro_tck_i (
664  .O (), // output - currently not used
665  .IO (aro), // inout I/O pad
666  .I (xpgmen? xfpgatck : iaro), // input
667  .T (1'b0) // input - always on
668  );
669 
670  // generate ARST/TMS
671  iobuf #(
672  .DRIVE (PXD_DRIVE),
673  .IBUF_LOW_PWR (PXD_IBUF_LOW_PWR),
674  .IOSTANDARD (PXD_IOSTANDARD),
675  .SLEW (PXD_SLEW)
676  ) arst_tms_i (
677  .O (), // output - currently not used
678  .IO (arst), // inout I/O pad
679  .I (xpgmen? xfpgatms : iarst), // input
680  .T (1'b0) // input - always on
681  );
682 
683  // generate MRST/ receive DONE
684  iobuf #(
685  .DRIVE (PXD_DRIVE),
686  .IBUF_LOW_PWR (PXD_IBUF_LOW_PWR),
687  .IOSTANDARD (PXD_IOSTANDARD),
688  .SLEW (PXD_SLEW)
689  ) mrst_done_i (
690  .O (xfpgadone), // output - done from external FPGA
691  .IO (mrst), // inout I/O pad
692  .I (imrst), // input
693  .T (xpgmen) // input - disable when reading DONE
694  );
695 
696  // Probe programmable/ control PROGRAM pin
697  reg [1:0] xpgmen_d;
698  reg force_senspgm=0;
699 
700  iobuf #(
701  .DRIVE (PXD_DRIVE),
702  .IBUF_LOW_PWR (PXD_IBUF_LOW_PWR),
703  .IOSTANDARD (PXD_IOSTANDARD),
704  .SLEW (PXD_SLEW)
705  ) senspgm_i (
706  .O (senspgmin), // output -senspgm pin state
707  .IO (senspgm), // inout I/O pad
708  .I (xpgmen?(~xfpgaprog):force_senspgm), // input
709  .T (~(xpgmen || force_senspgm)) // input - disable when reading DONE
710  );
711  // pullup for mrst (used as input for "DONE") and senspgm (grounded on sensor boards)
712  mpullup i_mrst_pullup(mrst);
713  mpullup i_senspgm_pullup(senspgm);
714  always @ (posedge mclk) begin
715  if (mclk_rst) force_senspgm <= 0;
716  else if (xpgmen_d[1:0]==2'b10) force_senspgm <= senspgmin;
717  if (mclk_rst) xpgmen_d <= 0;
718  else xpgmen_d <= {xpgmen_d[0], xpgmen};
719  end
720 
721  // generate phase-shifterd pixel clock (and 2x version) from either the internal clock (that is output to the sensor) or from the clock
722  // received from the sensor (may need to reset MMCM after resetting sensor)
723  mmcm_phase_cntr #(
724  .PHASE_WIDTH (SENS_PHASE_WIDTH),
725  .CLKIN_PERIOD (CLKIN_PERIOD_SENSOR), // SENS_PCLK_PERIOD), assuming both sources have the same frequency!
726  .BANDWIDTH (SENS_BANDWIDTH),
727  .CLKFBOUT_MULT_F (CLKFBOUT_MULT_SENSOR), //8
728  .DIVCLK_DIVIDE (SENS_DIVCLK_DIVIDE),
729  .CLKFBOUT_PHASE (CLKFBOUT_PHASE_SENSOR),
730  .CLKOUT0_PHASE (IPCLK_PHASE),
731  .CLKOUT1_PHASE (IPCLK2X_PHASE),
732 // .CLKOUT2_PHASE (0.000),
733 // .CLKOUT3_PHASE (0.000),
734 // .CLKOUT4_PHASE (0.000),
735 // .CLKOUT5_PHASE (0.000),
736 // .CLKOUT6_PHASE (0.000),
737  .CLKFBOUT_USE_FINE_PS("FALSE"),
738  .CLKOUT0_USE_FINE_PS ("TRUE"),
739  .CLKOUT1_USE_FINE_PS ("TRUE"),
740 // .CLKOUT2_USE_FINE_PS ("FALSE"),
741 // .CLKOUT3_USE_FINE_PS ("FALSE"),
742 // .CLKOUT4_USE_FINE_PS("FALSE"),
743 // .CLKOUT5_USE_FINE_PS("FALSE"),
744 // .CLKOUT6_USE_FINE_PS("FALSE"),
745  .CLKOUT0_DIVIDE_F (8.000),
746  .CLKOUT1_DIVIDE (4),
747 // .CLKOUT2_DIVIDE (1),
748 // .CLKOUT3_DIVIDE (1),
749 // .CLKOUT4_DIVIDE(1),
750 // .CLKOUT5_DIVIDE(1),
751 // .CLKOUT6_DIVIDE(1),
752  .COMPENSATION ("ZHOLD"),
753  .REF_JITTER1 (SENS_REF_JITTER1),
754  .REF_JITTER2 (SENS_REF_JITTER2),
755  .SS_EN (SENS_SS_EN),
756  .SS_MODE (SENS_SS_MODE),
757  .SS_MOD_PERIOD (SENS_SS_MOD_PERIOD),
758  .STARTUP_WAIT ("FALSE")
759  ) mmcm_phase_cntr_i (
760  .clkin1 (pclk), // input
761  .clkin2 (ibpf), // input
762  .sel_clk2 (sel_ext_clk), // input
763  .clkfbin (clk_fb), // input
764  .rst (rst_mmcm), // input
765  .pwrdwn (1'b0), // input
766  .psclk (mclk), // input
767  .ps_we (set_other_delay), // input
768  .ps_din (data_r[31:24]), // input[7:0]
769  .ps_ready (ps_rdy), // output
770  .ps_dout (ps_out), // output[7:0] reg
771  .clkout0 (ipclk_pre), // output
772  .clkout1 (ipclk2x_pre), // output
773  .clkout2(), // output
774  .clkout3(), // output
775  .clkout4(), // output
776  .clkout5(), // output
777  .clkout6(), // output
778  .clkout0b(), // output
779  .clkout1b(), // output
780  .clkout2b(), // output
781  .clkout3b(), // output
782  .clkfbout (clk_fb), // output
783  .clkfboutb(), // output
787  // output
788  );
789  generate
790  if (BUF_IPCLK == "BUFG") BUFG clk1x_i (.O(ipclk), .I(ipclk_pre));
791  else if (BUF_IPCLK == "BUFH") BUFH clk1x_i (.O(ipclk), .I(ipclk_pre));
792  else if (BUF_IPCLK == "BUFR") BUFR clk1x_i (.O(ipclk), .I(ipclk_pre), .CE(1'b1), .CLR(prst));
793  else if (BUF_IPCLK == "BUFMR") BUFMR clk1x_i (.O(ipclk), .I(ipclk_pre));
794  else if (BUF_IPCLK == "BUFIO") BUFIO clk1x_i (.O(ipclk), .I(ipclk_pre));
795  else assign ipclk = ipclk_pre;
796  endgenerate
797 
798  generate
799  if (BUF_IPCLK2X == "BUFG") BUFG clk2x_i (.O(ipclk2x), .I(ipclk2x_pre));
800  else if (BUF_IPCLK2X == "BUFH") BUFH clk2x_i (.O(ipclk2x), .I(ipclk2x_pre));
801  else if (BUF_IPCLK2X == "BUFR") BUFR clk2x_i (.O(ipclk2x), .I(ipclk2x_pre), .CE(1'b1), .CLR(prst));
802  else if (BUF_IPCLK2X == "BUFMR") BUFMR clk2x_i (.O(ipclk2x), .I(ipclk2x_pre));
803  else if (BUF_IPCLK2X == "BUFIO") BUFIO clk2x_i (.O(ipclk2x), .I(ipclk2x_pre));
804  else assign ipclk2x = ipclk2x_pre;
805  endgenerate
806 
807 // BUFR ipclk_bufr_i (.O(ipclk), .CE(), .CLR(), .I(ipclk_pre));
808 // BUFR ipclk2x_bufr_i (.O(ipclk2x), .CE(), .CLR(), .I(ipclk2x_pre));
809 
810 // for debug/test alive
811  pulse_cross_clock pulse_cross_clock_vact_a_mclk_i (
812  .rst (irst), // input
813  .src_clk (ipclk), // input
814  .dst_clk (mclk), // input
815  .in_pulse (vact_out_pre && !vact_r), // input
816  .out_pulse (vact_a_mclk), // output
817  .busy() // output
818  );
819 
820  pulse_cross_clock pulse_cross_clock_hact_ext_a_mclk_i (
821  .rst (irst), // input
822  .src_clk (ipclk), // input
823  .dst_clk (mclk), // input
824  .in_pulse (hact_ext && !hact_ext_r), // input
825  .out_pulse (hact_ext_a_mclk), // output
826  .busy() // output
827  );
828 
829  pulse_cross_clock pulse_cross_clock_hact_a_mclk_i (
830  .rst (irst), // input
831  .src_clk (ipclk), // input
832  .dst_clk (mclk), // input
833  .in_pulse (hact_r && !hact_r2), // input
834  .out_pulse (hact_a_mclk), // output
835  .busy() // output
836  );
837 
838 
839 endmodule
840 
841 
7752quadrantsreg[SENS_CTRL_QUADRANTS_WIDTH-1:0]
11504rst
Definition: oddr_ss.v:50
pulse_cross_clock_hact_a_mclk_i pulse_cross_clock
real 7673SENS_REFCLK_FREQUENCY300.0
cmd_deser_sens_io_i cmd_deser
7676SENS_BANDWIDTH"OPTIMIZED"
7677CLKIN_PERIOD_SENSOR10.000
11507tin
Definition: oddr_ss.v:53
6799pxclk_en
Definition: pxd_clock.v:54
[1:0] 6828quadrant
Definition: pxd_single.v:65
7670PXD_IBUF_LOW_PWR"TRUE"
[1:0] 11506din
Definition: oddr_ss.v:52
7719pxd_out_prewire[11:0]
pxd_clock_i pxd_clock
11290T
Definition: iobuf.v:51
clk2x_i BUFG[generate]
7729set_width_rreg[1:0]
i_senspgm_pullup mpullup
7781async_prst_with_sens_mrstwire
7745clkin_pxd_stopped_mmcmwire
[ADDR_MASK2!=0?2:ADDR_MASK1!=0?1:0:0] 9935we
Definition: cmd_deser.v:60
7738hact_cntrreg[LINE_WIDTH_BITS-1:0]
clk2x_i BUFH[generate]
7761xfpgatdo_bytereg[7:0]
7671PXD_IOSTANDARD"DEFAULT"
7679CLKFBOUT_PHASE_SENSOR0.000
[7:0] 6825dly_data
Definition: pxd_single.v:62
11503ce
Definition: oddr_ss.v:49
clk2x_i BUFR[generate]
7780prst_with_sens_mrstreg[1:0]
mmcm_phase_cntr_i mmcm_phase_cntr
11508dq
Definition: oddr_ss.v:54
[7:0] 6803dly_data
Definition: pxd_clock.v:58
[STATUS_ALIVE_WIDTH-1:0] 7712status_alive_1cyc
[DATA_WIDTH-1:0] 9934data
Definition: cmd_deser.v:59
7726set_idelayreg[3:0]
[PHASE_WIDTH-1:0] 11433ps_dout
clk2x_i BUFIO[generate]
integer 7668IDELAY_VALUE0
7688SENS_SS_MODE"CENTER_HIGH"
6805ld_idelay
Definition: pxd_clock.v:60
11505set
Definition: oddr_ss.v:51
clk2x_i BUFMR[generate]
11288IO
Definition: iobuf.v:49
reg [11:0] 7709pxd_out
[PHASE_WIDTH-1:0] 11431ps_din
[7:0] 9931ad
Definition: cmd_deser.v:56
11502clk
Definition: oddr_ss.v:48
[ADDR_WIDTH-1:0] 9933addr
Definition: cmd_deser.v:58
6798pxclk_out
Definition: pxd_clock.v:53
pxd_vact_i pxd_single
7758cmd_datawire[31:0]
7737line_width_internal_ipclkreg
7755statuswire[25:0]
6804set_idelay
Definition: pxd_clock.v:59
integer 7669PXD_DRIVE12
7735line_width_m1_ipclkreg[LINE_WIDTH_BITS-1:0]
status_generate_sens_io_i status_generate
7746clkfb_pxd_stopped_mmcmwire
7674SENS_HIGH_PERFORMANCE_MODE"FALSE"
7734line_width_m1reg[LINE_WIDTH_BITS-1:0]
6800pxclk_in
Definition: pxd_clock.v:55
7689SENS_SS_MOD_PERIOD10000
7740set_pxd_delaywire[2:0]
[ALL_BITS-1:0] 10777status
7667IODELAY_GRP"IODELAY_SENSOR"
11287O
Definition: iobuf.v:48
7779status_alivereg[STATUS_ALIVE_WIDTH-1:0]
11289I
Definition: iobuf.v:50