x393  1.0
FPGAcodeforElphelNC393camera
clocks393.v
Go to the documentation of this file.
1 
39 `timescale 1ns/1ps
40 
41 module clocks393#(
42  parameter CLK_ADDR = 'h728, // ..'h729
43  parameter CLK_MASK = 'h7fe, //
44  parameter CLK_STATUS_REG_ADDR = 'h3a, //
45  parameter CLK_CNTRL = 0,
46  parameter CLK_STATUS = 1,
47 
48  parameter CLK_RESET = 'h0, // which clocks should stay reset after release of masrter reset {ff1,ff0,mem,sync,xclk,pclk,xclk}
49  parameter CLK_PWDWN = 'h0, // which clocks should stay powered down after release of masrter reset {sync,xclk,pclk,xclk}
50 
51  parameter CLKIN_PERIOD_AXIHP = 20, //ns >1.25, 600<Fvco<1200
52  parameter DIVCLK_DIVIDE_AXIHP = 1,
53  parameter CLKFBOUT_MULT_AXIHP = 18, // Fvco=Fclkin*CLKFBOUT_MULT_F/DIVCLK_DIVIDE, Fout=Fvco/CLKOUT#_DIVIDE
54  parameter CLKOUT_DIV_AXIHP = 6, // To get 150MHz for the reference clock
55  parameter BUF_CLK1X_AXIHP = "BUFG", // "BUFG", "BUFH", "BUFR", "NONE"
56 
57  parameter CLKIN_PERIOD_PCLK = 42, // 24MHz
58  parameter DIVCLK_DIVIDE_PCLK = 1,
59  parameter CLKFBOUT_MULT_PCLK = 40, // 960 MHz
60  parameter CLKOUT_DIV_PCLK = 10, // 96MHz
61  parameter BUF_CLK1X_PCLK = "BUFG",
62 `ifdef USE_PCLK2X
63  parameter CLKOUT_DIV_PCLK2X = 5, // 192 MHz
64  parameter PHASE_CLK2X_PCLK = 0.000,
65  parameter BUF_CLK1X_PCLK2X = "BUFG",
66 `endif
67  parameter CLKIN_PERIOD_XCLK = 20, // 50MHz
68  parameter DIVCLK_DIVIDE_XCLK = 1,
69  parameter CLKFBOUT_MULT_XCLK = 20, // 50*20=1000 MHz
70  parameter CLKOUT_DIV_XCLK = 10, // 100 MHz
71  parameter BUF_CLK1X_XCLK = "BUFG",
72 `ifdef USE_XCLK2X
73  parameter CLKOUT_DIV_XCLK2X = 5, // 200 MHz
74  parameter PHASE_CLK2X_XCLK = 0.000,
75  parameter BUF_CLK1X_XCLK2X = "BUFG",
76 `endif
77  parameter CLKIN_PERIOD_SYNC = 20, // 50MHz
78  parameter DIVCLK_DIVIDE_SYNC = 1,
79  parameter CLKFBOUT_MULT_SYNC = 20, // 50*20=1000 MHz
80  parameter CLKOUT_DIV_SYNC = 10, // 100 MHz
81  parameter BUF_CLK1X_SYNC = "BUFG",
82 
83  parameter MEMCLK_CAPACITANCE = "DONT_CARE",
84  parameter MEMCLK_IBUF_LOW_PWR = "TRUE",
85  parameter MEMCLK_IOSTANDARD = "DEFAULT",
86 
87  parameter FFCLK0_CAPACITANCE = "DONT_CARE",
88  parameter FFCLK0_DIFF_TERM = "FALSE",
89  parameter FFCLK0_IBUF_LOW_PWR = "TRUE",
90  parameter FFCLK0_IOSTANDARD = "DEFAULT",
91 
92  parameter FFCLK1_CAPACITANCE = "DONT_CARE",
93  parameter FFCLK1_DIFF_TERM = "FALSE",
94  parameter FFCLK1_IBUF_LOW_PWR = "TRUE",
95  parameter FFCLK1_IOSTANDARD = "DEFAULT"
96 
97 )(
98  input async_rst, // always reset MMCM/PLL
99  input mclk, // global clock, comes from the memory controller (uses aclk generated here)
100  input mrst,
101  // command/status interface
102  input [7:0] cmd_ad, // byte-serial command address/data (up to 6 bytes: AL-AH-D0-D1-D2-D3
103  input cmd_stb, // strobe (with first byte) for the command a/d
104  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]
105  output status_rq, // input request to send status downstream
106  input status_start, // Acknowledge of the first status packet byte (address)
107  input [3:0] fclk, // 4 clocks coming from the Zynq PS. Currently only [0] is used
108  input memclk_pad, // connected to external clock generator (VDD=1.5V)
109  input ffclk0p_pad, // differential clock (P) same power as sensors 0 and 1 (VCC_SENS01)
110  input ffclk0n_pad, // differential clock (N) same power as sensors 0 and 1 (VCC_SENS01)
111  input ffclk1p_pad, // differential clock (P) same power as sensors 0 and 1 (VCC_SENS01)
112  input ffclk1n_pad, // differential clock (N) same power as sensors 0 and 1 (VCC_SENS01)
113  output aclk, // global clock 50 MHz (used for maxi0)
114  output hclk, // global clock 150MHz (used for afi*, saxi*)
115  output pclk, // global clock for sensors (now 96MHz), based on external clock generator
116 `ifdef USE_PCLK2X
117  output pclk2x, // global clock for sennors, 2x frequency (now 192MHz)
118 `endif
119  output xclk, // global clock for compressor (now 100MHz)
120 `ifdef USE_XCLK2X
121  output xclk2x, // global clock for compressor, 2x frequency (now 200MHz)
122 `endif
123  output sync_clk, // global clock for camsync module (96 MHz for 353 compatibility - switch to 100MHz)?
124  output time_ref, // non-global, just RTC (currently just mclk/8 = 25 MHz)
125  input [1:0] extra_status, // just extra two status bits from the top module
126  output locked_sync_clk,
127  output locked_xclk,
128  output locked_pclk,
129  output locked_hclk
130 );
131  wire memclk;
132  wire ffclk0;
133  wire ffclk1;
134  wire [8:0] status_data;
135  wire [10:0] cmd_data;
136  wire cmd_we;
137  wire [0:0] cmd_a;
138 
141  wire [3:0] locked;
142  reg [6:0] reset_clk = CLK_RESET;
143  reg [3:0] pwrdwn_clk = CLK_PWDWN;
144  reg [2:0] test_clk; // FF to test input clocks are running
145  wire memclk_rst = reset_clk[4];
146  wire ffclk0_rst = reset_clk[5];
147  wire ffclk1_rst = reset_clk[6];
148 
149  assign locked_sync_clk = locked[3];
150  assign locked_xclk = locked[2];
151  assign locked_pclk = locked[1];
152  assign locked_hclk = locked[0];
153 
154  always @ (posedge mclk) begin
155  if (mrst) reset_clk <= CLK_RESET;
156  else if (set_ctrl_w) reset_clk <= {cmd_data[10:8], cmd_data[3:0]};
157 
159  else if (set_ctrl_w) pwrdwn_clk <= cmd_data[7:4];
160  end
162  always @ (posedge memclk or posedge memclk_rst) if (async_rst || memclk_rst) test_clk[0] <= 0; else test_clk[0] <= ~test_clk[0];
163  always @ (posedge ffclk0 or posedge ffclk0_rst) if (async_rst || ffclk0_rst) test_clk[1] <= 0; else test_clk[1] <= ~test_clk[1];
164  always @ (posedge ffclk1 or posedge ffclk1_rst) if (async_rst || ffclk1_rst) test_clk[2] <= 0; else test_clk[2] <= ~test_clk[2];
165 
166  cmd_deser #(
167  .ADDR (CLK_ADDR),
168  .ADDR_MASK (CLK_MASK),
169  .NUM_CYCLES (4),
170  .ADDR_WIDTH (1),
171  .DATA_WIDTH (11)
172  ) cmd_deser_32bit_i (
173  .rst (1'b0), // rst), // input
174  .clk (mclk), // input
175  .srst (mrst), // input
176  .ad (cmd_ad), // input[7:0]
177  .stb (cmd_stb), // input
178  .addr (cmd_a), // output[3:0]
179  .data (cmd_data), // output[31:0]
180  .we (cmd_we) // output
181  );
182 
183  status_generate #(
184  .STATUS_REG_ADDR (CLK_STATUS_REG_ADDR),
185  .PAYLOAD_BITS (9),
186  .REGISTER_STATUS (0)
187  ) status_generate_i (
188  .rst (1'b0), // rst), // input
189  .clk (mclk), // input
190  .srst (mrst), // input
191  .we (set_status_w), // input
192  .wd (cmd_data[7:0]), // input[7:0]
193  .status (status_data), // input[14:0]
194  .ad (status_ad), // output[7:0]
195  .rq (status_rq), // output
196  .start (status_start) // input
197  );
198 
199  BUFG bufg_axi_aclk_i (.O(aclk), .I(fclk[0]));
200 
202  .CLKIN_PERIOD (CLKIN_PERIOD_AXIHP),
203  .DIVCLK_DIVIDE (DIVCLK_DIVIDE_AXIHP),
204  .CLKFBOUT_MULT (CLKFBOUT_MULT_AXIHP),
205  .CLKOUT_DIV_CLK1X (CLKOUT_DIV_AXIHP),
206  .BUF_CLK1X (BUF_CLK1X_AXIHP),
207  .BUF_CLK2X ("NONE")
208  ) dual_clock_axihp_i (
209  .rst (async_rst || reset_clk[0]), // input
210  .clk_in (aclk), // input
211  .pwrdwn (pwrdwn_clk[0]), // input
212  .clk1x (hclk), // output
213  .clk2x (), // output
214  .locked (locked[0]) // output
215  );
216 
218  .CLKIN_PERIOD (CLKIN_PERIOD_PCLK),
219  .DIVCLK_DIVIDE (DIVCLK_DIVIDE_PCLK),
220  .CLKFBOUT_MULT (CLKFBOUT_MULT_PCLK),
221  .CLKOUT_DIV_CLK1X (CLKOUT_DIV_PCLK),
222  .BUF_CLK1X (BUF_CLK1X_PCLK)
223 `ifdef USE_PCLK2X
224  ,.CLKOUT_DIV_CLK2X (CLKOUT_DIV_PCLK2X),
225  .PHASE_CLK2X (PHASE_CLK2X_PCLK),
226  .BUF_CLK2X (BUF_CLK1X_PCLK2X)
227 `else
228  ,.BUF_CLK2X ("NONE")
229 `endif
230  ) dual_clock_pclk_i (
231  .rst (async_rst || reset_clk[1]), // input
232  .clk_in (ffclk0), // input
233  .pwrdwn (pwrdwn_clk[1]), // input
234  .clk1x (pclk), // output
235 `ifdef USE_PCLK2X
236  .clk2x (pclk2x), // output
237 `else
238  .clk2x (), // output not connected
239 `endif
240  .locked (locked[1]) // output
241  );
242 
244  .CLKIN_PERIOD (CLKIN_PERIOD_XCLK),
245  .DIVCLK_DIVIDE (DIVCLK_DIVIDE_XCLK),
246  .CLKFBOUT_MULT (CLKFBOUT_MULT_XCLK),
247  .CLKOUT_DIV_CLK1X (CLKOUT_DIV_XCLK),
248  .BUF_CLK1X (BUF_CLK1X_XCLK),
249 `ifdef USE_XCLK2X
250  .CLKOUT_DIV_CLK2X (CLKOUT_DIV_XCLK2X),
251  .PHASE_CLK2X (PHASE_CLK2X_XCLK),
252  .BUF_CLK2X (BUF_CLK1X_XCLK2X)
253 `else
254  .BUF_CLK2X ("NONE")
255 `endif
256  ) dual_clock_xclk_i (
257  .rst (async_rst || reset_clk[2]), // input
258  .clk_in (aclk), // input
259  .pwrdwn (pwrdwn_clk[2]), // input
260  .clk1x (xclk), // output
261 `ifdef USE_XCLK2X
262  .clk2x (xclk2x), // output
263 `else
264  .clk2x (), // output
265 `endif
266  .locked (locked[2]) // output
267  );
268 
270  .CLKIN_PERIOD (CLKIN_PERIOD_SYNC),
271  .DIVCLK_DIVIDE (DIVCLK_DIVIDE_SYNC),
272  .CLKFBOUT_MULT (CLKFBOUT_MULT_SYNC),
273  .CLKOUT_DIV_CLK1X (CLKOUT_DIV_SYNC),
274  .BUF_CLK1X (BUF_CLK1X_SYNC),
275  .BUF_CLK2X ("NONE")
276  ) dual_clock_sync_clk_i (
277  .rst (async_rst || reset_clk[3]), // input
278  .clk_in (aclk), // input
279  .pwrdwn (pwrdwn_clk[3]), // input
280  .clk1x (sync_clk), // output
281  .clk2x (), // output
282  .locked (locked[3]) // output
283  );
284 
285 
286  ibuf_ibufg #(
287  .CAPACITANCE (MEMCLK_CAPACITANCE),
288  .IBUF_LOW_PWR (MEMCLK_IBUF_LOW_PWR),
289  .IOSTANDARD (MEMCLK_IOSTANDARD)
290  ) ibuf_ibufg_i (
291  .O (memclk), // output
292  .I (memclk_pad) // input
293  );
295  ibufds_ibufgds #(
296  .CAPACITANCE (FFCLK0_CAPACITANCE),
297  .DIFF_TERM (FFCLK0_DIFF_TERM),
298  .IBUF_LOW_PWR (FFCLK0_IBUF_LOW_PWR),
299  .IOSTANDARD (FFCLK0_IOSTANDARD)
300  ) ibufds_ibufgds0_i (
301  .O (ffclk0), // output
302  .I (ffclk0p_pad), // input
303  .IB (ffclk0n_pad) // input
304  );
305 
306  ibufds_ibufgds #(
307  .CAPACITANCE (FFCLK1_CAPACITANCE),
308  .DIFF_TERM (FFCLK1_DIFF_TERM),
309  .IBUF_LOW_PWR (FFCLK1_IBUF_LOW_PWR),
310  .IOSTANDARD (FFCLK1_IOSTANDARD)
311  ) ibufds_ibufgds10_i (
312  .O (ffclk1), // output
313  .I (ffclk1p_pad), // input
314  .IB (ffclk1n_pad) // input
315  );
316 
317  // RTC reference: integer number of microseconds, less than mclk/2. Not a global clock
318  // temporary:
319  reg [2:0] time_ref_r;
320  always @ (posedge mclk) if (mrst) time_ref_r <= 0; else time_ref_r <= time_ref_r + 1;
321  assign time_ref = time_ref_r[2];
322 
323 endmodule
324 
325 
9776CLKOUT_DIV_SYNC10
Definition: clocks393.v:78
9782FFCLK0_DIFF_TERM"FALSE"
Definition: clocks393.v:86
9825pwrdwn_clkreg[3:0]
Definition: clocks393.v:139
9824reset_clkreg[6:0]
Definition: clocks393.v:138
9765CLKFBOUT_MULT_PCLK40
Definition: clocks393.v:59
9751CLK_ADDR'h728
Definition: clocks393.v:42
9763CLKIN_PERIOD_PCLK42
Definition: clocks393.v:57
9826test_clkreg[2:0]
Definition: clocks393.v:140
9827memclk_rstwire
Definition: clocks393.v:141
9816ffclk1wire
Definition: clocks393.v:129
9754CLK_CNTRL0
Definition: clocks393.v:45
ibuf_ibufg_i ibuf_ibufg
Definition: clocks393.v:274
bufg_axi_aclk_i BUFG
Definition: clocks393.v:195
9812locked_pclk
Definition: clocks393.v:124
9761CLKOUT_DIV_AXIHP6
Definition: clocks393.v:54
9757CLK_PWDWN'h0
Definition: clocks393.v:49
9786FFCLK1_DIFF_TERM"FALSE"
Definition: clocks393.v:91
9758CLKIN_PERIOD_AXIHP20
Definition: clocks393.v:51
[7:0] 9794status_ad
Definition: clocks393.v:102
9815ffclk0wire
Definition: clocks393.v:128
9770CLKFBOUT_MULT_XCLK20
Definition: clocks393.v:68
9796status_start
Definition: clocks393.v:104
9777BUF_CLK1X_SYNC"BUFG"
Definition: clocks393.v:79
9759DIVCLK_DIVIDE_AXIHP1
Definition: clocks393.v:52
9801ffclk1p_pad
Definition: clocks393.v:109
9814memclkwire
Definition: clocks393.v:127
9830time_ref_rreg[2:0]
Definition: clocks393.v:307
9823lockedwire[3:0]
Definition: clocks393.v:137
9768CLKIN_PERIOD_XCLK20
Definition: clocks393.v:66
[ADDR_MASK2!=0?2:ADDR_MASK1!=0?1:0:0] 9935we
Definition: cmd_deser.v:60
9752CLK_MASK'h7fe
Definition: clocks393.v:43
9799ffclk0p_pad
Definition: clocks393.v:107
9787FFCLK1_IBUF_LOW_PWR"TRUE"
Definition: clocks393.v:92
9829ffclk1_rstwire
Definition: clocks393.v:143
9764DIVCLK_DIVIDE_PCLK1
Definition: clocks393.v:58
9772BUF_CLK1X_XCLK"BUFG"
Definition: clocks393.v:70
9798memclk_pad
Definition: clocks393.v:106
9817status_datawire[8:0]
Definition: clocks393.v:130
9818cmd_datawire[10:0]
Definition: clocks393.v:131
9756CLK_RESET'h0
Definition: clocks393.v:48
9788FFCLK1_IOSTANDARD"DEFAULT"
Definition: clocks393.v:93
9773CLKIN_PERIOD_SYNC20
Definition: clocks393.v:75
9766CLKOUT_DIV_PCLK10
Definition: clocks393.v:60
9779MEMCLK_IBUF_LOW_PWR"TRUE"
Definition: clocks393.v:82
9828ffclk0_rstwire
Definition: clocks393.v:142
9810locked_sync_clk
Definition: clocks393.v:122
9753CLK_STATUS_REG_ADDR'h3a
Definition: clocks393.v:44
[3:0] 9797fclk
Definition: clocks393.v:105
9802ffclk1n_pad
Definition: clocks393.v:110
9769DIVCLK_DIVIDE_XCLK1
Definition: clocks393.v:67
9775CLKFBOUT_MULT_SYNC20
Definition: clocks393.v:77
cmd_deser_32bit_i cmd_deser
Definition: clocks393.v:162
9780MEMCLK_IOSTANDARD"DEFAULT"
Definition: clocks393.v:83
[DATA_WIDTH-1:0] 9934data
Definition: cmd_deser.v:59
[1:0] 9809extra_status
Definition: clocks393.v:121
ibufds_ibufgds10_i ibufds_ibufgds
Definition: clocks393.v:294
9785FFCLK1_CAPACITANCE"DONT_CARE"
Definition: clocks393.v:90
9819cmd_wewire
Definition: clocks393.v:132
[7:0] 9931ad
Definition: cmd_deser.v:56
[ADDR_WIDTH-1:0] 9933addr
Definition: cmd_deser.v:58
9821set_ctrl_wwire
Definition: clocks393.v:135
9760CLKFBOUT_MULT_AXIHP18
Definition: clocks393.v:53
9822set_status_wwire
Definition: clocks393.v:136
9820cmd_awire[0:0]
Definition: clocks393.v:133
9784FFCLK0_IOSTANDARD"DEFAULT"
Definition: clocks393.v:88
9781FFCLK0_CAPACITANCE"DONT_CARE"
Definition: clocks393.v:85
status_generate_i status_generate
Definition: clocks393.v:179
9762BUF_CLK1X_AXIHP"BUFG"
Definition: clocks393.v:55
9800ffclk0n_pad
Definition: clocks393.v:108
9789async_rst
Definition: clocks393.v:96
9811locked_xclk
Definition: clocks393.v:123
9755CLK_STATUS1
Definition: clocks393.v:46
dual_clock_sync_clk_i dual_clock_source
Definition: clocks393.v:257
[ALL_BITS-1:0] 10777status
9767BUF_CLK1X_PCLK"BUFG"
Definition: clocks393.v:61
9778MEMCLK_CAPACITANCE"DONT_CARE"
Definition: clocks393.v:81
9774DIVCLK_DIVIDE_SYNC1
Definition: clocks393.v:76
9783FFCLK0_IBUF_LOW_PWR"TRUE"
Definition: clocks393.v:87
[7:0] 9792cmd_ad
Definition: clocks393.v:100
9771CLKOUT_DIV_XCLK10
Definition: clocks393.v:69
9813locked_hclk
Definition: clocks393.v:125