2023-03-11 22:54:12 +00:00
|
|
|
/*
|
|
|
|
* sysmgr.v
|
|
|
|
*
|
|
|
|
* vim: ts=4 sw=4
|
|
|
|
*
|
|
|
|
* System Clock / Reset generation
|
|
|
|
*
|
|
|
|
* Copyright (C) 2023 Sylvain Munaut <tnt@246tNt.com>
|
|
|
|
* SPDX-License-Identifier: CERN-OHL-P-2.0
|
|
|
|
*/
|
|
|
|
|
|
|
|
`default_nettype none
|
|
|
|
|
|
|
|
module sysmgr (
|
|
|
|
// Control
|
|
|
|
input wire sys_start,
|
|
|
|
input wire sys_stop,
|
|
|
|
input wire usb_ena,
|
|
|
|
|
|
|
|
// LED clock ( 6 MHz )
|
|
|
|
output wire clk_led,
|
|
|
|
output wire rst_led,
|
|
|
|
|
|
|
|
// System clock ( 24 MHz )
|
|
|
|
output wire clk_sys,
|
|
|
|
output wire rst_sys,
|
|
|
|
|
|
|
|
// USB ( 48 MHz )
|
|
|
|
output wire clk_usb,
|
|
|
|
output wire rst_usb
|
|
|
|
);
|
|
|
|
|
|
|
|
// Signals
|
|
|
|
// -------
|
|
|
|
|
|
|
|
wire clk_osc;
|
|
|
|
wire clk_base;
|
|
|
|
|
|
|
|
wire pll_lock;
|
|
|
|
|
|
|
|
reg [3:0] clk_div;
|
|
|
|
reg clk_usb_i;
|
|
|
|
reg clk_sys_i;
|
|
|
|
wire clk_led_i;
|
|
|
|
|
|
|
|
reg [3:0] rst_cnt;
|
|
|
|
wire rst_i;
|
|
|
|
wire rst_gbuf;
|
|
|
|
|
|
|
|
reg [2:0] sys_start_s;
|
|
|
|
reg [2:0] sys_stop_s;
|
|
|
|
|
|
|
|
wire usb_rst_trig;
|
|
|
|
reg [3:0] usb_rst_cnt;
|
|
|
|
wire usb_rst_i;
|
|
|
|
reg [3:0] usb_off_dly;
|
|
|
|
|
|
|
|
reg sys_off;
|
|
|
|
wire usb_off;
|
|
|
|
|
|
|
|
|
|
|
|
// SB_HFOSC
|
|
|
|
// -------
|
|
|
|
// Generates 12 MHz
|
|
|
|
|
|
|
|
(* ROUTE_THROUGH_FABRIC = 1 *)
|
|
|
|
SB_HFOSC #(
|
|
|
|
.CLKHF_DIV("0b10")
|
|
|
|
) osc_I (
|
|
|
|
.CLKHFPU(1'b1),
|
|
|
|
.CLKHFEN(1'b1),
|
|
|
|
.CLKHF(clk_osc)
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
// PLL
|
|
|
|
// ---
|
|
|
|
|
|
|
|
SB_PLL40_CORE #(
|
|
|
|
.DIVR (4'b0000),
|
|
|
|
.DIVF (7'b0111111),
|
|
|
|
.DIVQ (3'b011),
|
|
|
|
.FILTER_RANGE (3'b001),
|
|
|
|
.FEEDBACK_PATH ("SIMPLE"),
|
|
|
|
.DELAY_ADJUSTMENT_MODE_FEEDBACK ("FIXED"),
|
|
|
|
.FDA_FEEDBACK (4'b0000),
|
|
|
|
.SHIFTREG_DIV_MODE (2'b00),
|
|
|
|
.PLLOUT_SELECT ("GENCLK"),
|
|
|
|
.ENABLE_ICEGATE (1'b0)
|
|
|
|
) pll_I (
|
|
|
|
.REFERENCECLK (clk_osc),
|
|
|
|
.PLLOUTCORE (clk_base),
|
|
|
|
.PLLOUTGLOBAL (),
|
|
|
|
.EXTFEEDBACK (1'b0),
|
|
|
|
.DYNAMICDELAY (8'h00),
|
|
|
|
.RESETB (1'b1),
|
|
|
|
.BYPASS (1'b0),
|
|
|
|
.LATCHINPUTVALUE (1'b0),
|
|
|
|
.LOCK (pll_lock),
|
|
|
|
.SDI (1'b0),
|
|
|
|
.SDO (),
|
|
|
|
.SCLK (1'b0)
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
// Dividers
|
|
|
|
// --------
|
|
|
|
|
|
|
|
// Counter
|
|
|
|
always @(posedge clk_base)
|
|
|
|
clk_div <= clk_div + 1;
|
|
|
|
|
|
|
|
// USB is div-by-2 + gated
|
|
|
|
always @(posedge clk_base)
|
|
|
|
clk_usb_i <= clk_div[0] & ~usb_off;
|
|
|
|
|
2023-03-22 20:54:35 +00:00
|
|
|
// SYS is div-by-8 + gated
|
2023-03-11 22:54:12 +00:00
|
|
|
always @(posedge clk_base)
|
2023-03-22 20:54:35 +00:00
|
|
|
clk_sys_i <= clk_div[2] & ~sys_off;
|
2023-03-11 22:54:12 +00:00
|
|
|
|
|
|
|
// LED is div-by-16
|
|
|
|
assign clk_led_i = clk_div[3];
|
|
|
|
|
|
|
|
// Global buffers
|
|
|
|
SB_GB clk_usb_gbuf_I (
|
|
|
|
.USER_SIGNAL_TO_GLOBAL_BUFFER(clk_usb_i),
|
|
|
|
.GLOBAL_BUFFER_OUTPUT(clk_usb)
|
|
|
|
);
|
|
|
|
|
|
|
|
SB_GB clk_sys_gbuf_I (
|
|
|
|
.USER_SIGNAL_TO_GLOBAL_BUFFER(clk_sys_i),
|
|
|
|
.GLOBAL_BUFFER_OUTPUT(clk_sys)
|
|
|
|
);
|
|
|
|
|
|
|
|
SB_GB clk_led_gbuf_I (
|
|
|
|
.USER_SIGNAL_TO_GLOBAL_BUFFER(clk_led_i),
|
|
|
|
.GLOBAL_BUFFER_OUTPUT(clk_led)
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
// USB Enable
|
|
|
|
// ----------
|
|
|
|
|
|
|
|
// Delay falling latch signal
|
|
|
|
always @(posedge clk_base)
|
|
|
|
usb_off_dly <= usb_ena ? 4'b0000 : { usb_off_dly[2:0], 1'b1 };
|
|
|
|
|
|
|
|
assign usb_off = usb_off_dly[3];
|
|
|
|
|
|
|
|
|
|
|
|
// USB Reset
|
|
|
|
// ---------
|
|
|
|
|
|
|
|
// Reset trigger
|
|
|
|
assign usb_rst_trig = ~usb_ena | ~pll_lock;
|
|
|
|
|
|
|
|
// Reset counter
|
|
|
|
always @(posedge clk_usb or posedge usb_rst_trig)
|
|
|
|
if (usb_rst_trig)
|
|
|
|
usb_rst_cnt <= 4'h8;
|
|
|
|
else
|
|
|
|
usb_rst_cnt <= usb_rst_cnt + usb_rst_i;
|
|
|
|
|
|
|
|
assign usb_rst_i = usb_rst_cnt[3];
|
|
|
|
|
|
|
|
// Global buffer
|
|
|
|
SB_GB rst_usb_gbuf_I (
|
|
|
|
.USER_SIGNAL_TO_GLOBAL_BUFFER(usb_rst_i),
|
|
|
|
.GLOBAL_BUFFER_OUTPUT(rst_usb)
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
// SYS Enable
|
|
|
|
// ----------
|
|
|
|
|
|
|
|
// Synch triggers
|
|
|
|
always @(posedge clk_base)
|
|
|
|
begin
|
2023-03-12 21:41:48 +00:00
|
|
|
sys_start_s <= { sys_start_s[1], sys_start_s[0], sys_start };
|
|
|
|
sys_stop_s <= { ~sys_stop_s[1] & sys_stop_s[0], sys_stop_s[0], sys_stop };
|
2023-03-11 22:54:12 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
always @(posedge clk_base)
|
|
|
|
sys_off <= (sys_off & ~rst_i & ~sys_start_s[2]) | sys_stop_s[2];
|
|
|
|
|
|
|
|
|
|
|
|
// Reset LED / SYS
|
|
|
|
// ---------------
|
|
|
|
|
|
|
|
// Counter
|
|
|
|
always @(posedge clk_led or negedge pll_lock)
|
|
|
|
if (~pll_lock)
|
|
|
|
rst_cnt <= 4'h8;
|
|
|
|
else
|
|
|
|
rst_cnt <= rst_cnt + rst_i;
|
|
|
|
|
|
|
|
assign rst_i = rst_cnt[3];
|
|
|
|
|
|
|
|
// Global buffer
|
|
|
|
SB_GB rst_gbuf_I (
|
|
|
|
.USER_SIGNAL_TO_GLOBAL_BUFFER(rst_i),
|
|
|
|
.GLOBAL_BUFFER_OUTPUT(rst_gbuf)
|
|
|
|
);
|
|
|
|
|
|
|
|
// Distribution
|
|
|
|
assign rst_led = rst_gbuf;
|
|
|
|
assign rst_sys = rst_gbuf;
|
|
|
|
|
|
|
|
endmodule // sysmgr
|