blob: db249d2b1d7e0dad3174e11eee7be4b40f910d2b [file] [log] [blame]
Tim Edwards3245e2f2020-10-10 14:02:11 -04001// This routine synchronizes the
2
3module caravel_clocking(
4`ifdef LVS
5 input vdd1v8,
6 input vss,
7`endif
8 input resetb, // Master (negative sense) reset
9 input ext_clk_sel, // 0=use PLL clock, 1=use external (pad) clock
10 input ext_clk, // External pad (slow) clock
11 input pll_clk, // Internal PLL (fast) clock
12 input [2:0] sel, // Select clock divider value (0=thru, 1=divide-by-2, etc.)
13 input ext_reset, // Positive sense reset from housekeeping SPI.
14 output core_clk, // Output core clock
15 output resetb_sync // Output propagated and buffered reset
16);
17
18 wire pll_clk_sel;
19 reg use_pll_first;
20 reg use_pll_second;
21 reg ext_clk_syncd_pre;
22 reg ext_clk_syncd;
23
24 assign pll_clk_sel = ~ext_clk_sel;
25
26 // Note that this implementation does not guard against switching to
27 // the PLL clock if the PLL clock is not present.
28
29 always @(posedge pll_clk or negedge resetb) begin
30 if (resetb == 1'b0) begin
31 use_pll_first <= 1'b0;
32 use_pll_second <= 1'b0;
33 ext_clk_syncd <= 1'b0;
34 end else begin
35 use_pll_first <= pll_clk_sel;
36 use_pll_second <= use_pll_first;
37 ext_clk_syncd_pre <= ext_clk; // Sync ext_clk to pll_clk
38 ext_clk_syncd <= ext_clk_syncd_pre; // Do this twice (resolve metastability)
39 end
40 end
41
42 // Apply PLL clock divider
43
44 clock_div #(
45 .SIZE(3)
46 ) divider (
47 .in(pll_clk),
48 .out(pll_clk_divided),
49 .N(sel),
50 .resetb(resetb)
51 );
52
53 // Multiplex the clock output
54
55 assign core_ext_clk = (use_pll_first) ? ext_clk_syncd : ext_clk;
56 assign core_clk = (use_pll_second) ? pll_clk_divided : core_ext_clk;
57
58 // Reset assignment. "reset" comes from POR, while "ext_reset"
59 // comes from standalone SPI (and is normally zero unless
60 // activated from the SPI).
61
62 // Staged-delay reset
63 reg [2:0] reset_delay;
64
65 always @(posedge core_clk or negedge resetb) begin
66 if (resetb == 1'b0) begin
67 reset_delay <= 3'b111;
68 end else begin
69 reset_delay <= {1'b0, reset_delay[2:1]};
70 end
71 end
72
73 assign resetb_sync = ~(reset_delay[0] | ext_reset);
74
75endmodule