168 lines
2.9 KiB
Verilog
168 lines
2.9 KiB
Verilog
/*
|
|
* sysmgr_sim.v
|
|
*
|
|
* vim: ts=4 sw=4
|
|
*
|
|
* System Clock / Reset generation (simulated)
|
|
*
|
|
* Copyright (C) 2023 Sylvain Munaut <tnt@246tNt.com>
|
|
* SPDX-License-Identifier: CERN-OHL-P-2.0
|
|
*/
|
|
|
|
`default_nettype none
|
|
|
|
module sysmgr_sim (
|
|
// 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
|
|
// -------
|
|
|
|
reg clk_base = 1'b0;
|
|
|
|
wire pll_lock;
|
|
|
|
reg [2:0] clk_div = 3'b000;
|
|
reg clk_sys_i;
|
|
wire clk_led_i;
|
|
|
|
reg [7:0] rst_cnt = 8'h00;
|
|
reg rst_i = 1;
|
|
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_ena_dly;
|
|
wire usb_ena_i;
|
|
|
|
reg sys_off;
|
|
|
|
|
|
// SB_HFOSC
|
|
// -------
|
|
// Generates 48 MHz
|
|
|
|
always #10.42 clk_base = ~clk_base;
|
|
|
|
|
|
// PLL
|
|
// ---
|
|
|
|
assign clk_usb = usb_ena_i & clk_base;
|
|
assign pll_lock = usb_ena_i;
|
|
|
|
|
|
// Dividers
|
|
// --------
|
|
|
|
// Counter
|
|
always @(posedge clk_base)
|
|
clk_div <= clk_div + 1;
|
|
|
|
// SYS is div-by-2 + gated
|
|
always @(posedge clk_base)
|
|
clk_sys_i <= clk_div[0] & ~sys_off;
|
|
|
|
// LED is div-by-8
|
|
assign clk_led_i = clk_div[2];
|
|
|
|
// Global buffers
|
|
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_ena_dly <= usb_ena ? 4'b1111 : { usb_ena_dly[2:0], 1'b0 };
|
|
|
|
assign usb_ena_i = usb_ena_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
|
|
sys_start_s <= { ~sys_start_s[1] & sys_start_s[0], sys_start_s[0], sys_start };
|
|
sys_stop_s <= { ~sys_stop_s[1] & sys_stop_s[0], sys_stop_s[0], sys_stop };
|
|
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)
|
|
rst_cnt <= rst_cnt + rst_i;
|
|
|
|
always @(posedge clk_led)
|
|
rst_i <= (rst_cnt[7:4] != 4'hf);
|
|
|
|
// 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
|