|
@@ -122,7 +122,6 @@ module max80
|
|
|
|
|
|
// PLL and reset
|
|
|
parameter reset_pow2 = 12; // Assert internal reset for 4096 cycles after PLL lock
|
|
|
- reg [reset_pow2-1:0] rst_ctr = 1'b0;
|
|
|
reg rst_n = 1'b0; // Internal reset
|
|
|
wire [1:0] pll_locked;
|
|
|
|
|
@@ -155,18 +154,28 @@ module max80
|
|
|
|
|
|
wire all_plls_locked = &pll_locked;
|
|
|
|
|
|
+ // sys_clk pulse generation of various powers of two
|
|
|
+ // Also used to generate rst_n
|
|
|
+ reg [23:1] sys_clk_ctr;
|
|
|
+ reg [23:1] sys_clk_ctr_q;
|
|
|
+ reg [23:1] sys_clk_stb;
|
|
|
+
|
|
|
always @(negedge all_plls_locked or posedge sys_clk)
|
|
|
if (~&all_plls_locked)
|
|
|
begin
|
|
|
- rst_ctr <= 1'b0;
|
|
|
- rst_n <= 1'b0;
|
|
|
- reset_cmd_q <= 1'b0;
|
|
|
+ rst_n <= 1'b0;
|
|
|
+ reset_cmd_q <= 1'b0;
|
|
|
+ sys_clk_ctr <= 1'b0;
|
|
|
+ sys_clk_ctr_q <= 1'b0;
|
|
|
+ sys_clk_stb <= 1'b0;
|
|
|
end
|
|
|
else
|
|
|
begin
|
|
|
- reset_cmd_q <= rst_n & (reset_cmd_q | reset_cmd);
|
|
|
- if (~rst_n)
|
|
|
- { rst_n, rst_ctr } <= rst_ctr + 1'b1;
|
|
|
+ sys_clk_ctr <= sys_clk_ctr + 1'b1;
|
|
|
+ sys_clk_ctr_q <= sys_clk_ctr;
|
|
|
+ sys_clk_stb <= ~sys_clk_ctr & sys_clk_ctr_q;
|
|
|
+ reset_cmd_q <= rst_n & (reset_cmd_q | reset_cmd);
|
|
|
+ rst_n <= rst_n | sys_clk_stb[reset_pow2];
|
|
|
end
|
|
|
|
|
|
// Unused device stubs - remove when used
|
|
@@ -287,6 +296,40 @@ module max80
|
|
|
assign abc_int800_x = opt_mosfet(abc_int & abc800, mosfet_installed[5]);
|
|
|
assign abc_xm_x = opt_mosfet(abc_xm, mosfet_installed[6]);
|
|
|
|
|
|
+ // Detect ABC-bus clock: need a minimum frequency of 84/64 MHz
|
|
|
+ // to be considered live...
|
|
|
+ reg [2:0] abc_clk_ctr;
|
|
|
+ reg [1:0] abc_clk_q;
|
|
|
+ reg abc_clk_active;
|
|
|
+ always @(negedge rst_n or posedge sys_clk)
|
|
|
+ if (~rst_n)
|
|
|
+ begin
|
|
|
+ abc_clk_q <= 2'b0;
|
|
|
+ abc_clk_ctr <= 3'b0;
|
|
|
+ abc_clk_active <= 1'b0;
|
|
|
+ end
|
|
|
+ else
|
|
|
+ begin
|
|
|
+ abc_clk_q <= { abc_clk_q[0], abc_clk };
|
|
|
+ case ( {(abc_clk_q == 2'b10), sys_clk_stb[6]} )
|
|
|
+ 5'b10: begin
|
|
|
+ if (abc_clk_ctr == 3'b111)
|
|
|
+ abc_clk_active <= 1'b1;
|
|
|
+ else
|
|
|
+ abc_clk_ctr <= abc_clk_ctr + 1'b1;
|
|
|
+ end
|
|
|
+ 5'b01: begin
|
|
|
+ if (abc_clk_ctr == 3'b000)
|
|
|
+ abc_clk_active <= 1'b0;
|
|
|
+ else
|
|
|
+ abc_clk_ctr <= abc_clk_ctr - 1'b1;
|
|
|
+ end
|
|
|
+ default: begin
|
|
|
+ // nothing
|
|
|
+ end
|
|
|
+ endcase // case ( {(abc_clk_q == 2'10), sys_clk_stb[6]} )
|
|
|
+ end // else: !if(~rst_n)
|
|
|
+
|
|
|
// ABC-bus extension header (exth_c and exth_h are input only)
|
|
|
// The naming of pins is kind of nonsensical:
|
|
|
//
|
|
@@ -647,7 +690,7 @@ module max80
|
|
|
assign reset_cmd = iodev_valid_reset & cpu_mem_wstrb[0] & cpu_mem_wdata[0];
|
|
|
|
|
|
// ABC80/800 status (change the name of the reset device...)
|
|
|
- assign iodev_rdev_reset = { 31'b0, abc800 };
|
|
|
+ assign iodev_rdev_reset = { 30'b0, abc800, abc_clk_active };
|
|
|
|
|
|
// LED indication from the CPU
|
|
|
reg [2:0] led_q;
|