I am trying to write a Verilog module that generates a power-on reset signal for a few clock cycles. I am synthesizing using Lattice iCEcube2 + Synplify Pro targeting an iCE40 HX1K on the Nandland Go Board.
If I write the the module like this, it is getting optimized out:
`default_nettype none module reset_generator #( parameter COUNT_WIDTH = 2 ) ( input wire i_clk, output wire o_rst ); reg [COUNT_WIDTH:0] rst_count; assign o_rst = !rst_count[COUNT_WIDTH]; always @(posedge i_clk) begin if (o_rst == 1) begin rst_count <= rst_count + 1; end end endmodule
iCEcube2 outputs this warning:
... @N:CL189 : reset_generator.v(13) | Register bit rst_count is always 1. @N:CL159 : reset_generator.v(6) | Input i_clk is unused. ... @N:BN115 : ball_absolute_mv_vga_top.v(19) | Removing instance reset_gen (in view: work.ball_absolute_mv_vga_top(verilog)) of type view:work.reset_generator_4s(verilog) because it does not drive other instances. ...
And I can verify that the
o_rst signal is indeed never set to
1. I thought all registers were initialized to
0, so I'm not sure why it thinks
rst_count is always 1.
However, if I explicitly set
0, like this:
reg [COUNT_WIDTH:0] rst_count = 0;
Now it no longer is getting optimized out and works as expected, but iCEcube2 shows this warning:
@W:FX1039 : reset_generator.v(13) | User-specified initial value defined for instance reset_gen.rst_count[4:0] is being ignored.
This warning also implies that initial values are 0. So why does the first version get optimized out? And why does adding an initial value that gets ignored change the behavior? Is this just a quirk of iCEcube2 and/or Synplify Pro?
EDIT 1: I'm using a power-on reset because Lattice can only initialize registers to zero, and I'd like some to start off with non-zero values.
o_rst of this
reset_generator component is hooked up to another component at a higher level like this:
wire w_reset; reset_generator #( .COUNT_WIDTH(4) ) reset_gen ( .i_clk(i_clk), .o_rst(w_reset) ); ball_absolute ball_absolute ( .clk(i_clk), .reset(w_reset), .vsync(o_vga_vsync), // ... );
The reason it does this is because
ball_absolute has a pair of X/Y registers for the ball's position on the screen. I'd like the ball to start in the middle of the screen, not at
(0, 0). And because Lattice can only initialize registers to
0, I want to use a power-on reset signal to set X/Y to non-zero values.
The full project is actually up on GitHub.
EDIT 2: I also understand that a PLL Lock signal could be used as a power-on reset, but unfortunately the HX1K does not have any PLLs. The Go Board uses an external crystal for the clock.