Closed RGD2 closed 8 years ago
The lattice chips don't have support for initial values on registers. They are cleared on startup and reset. There is little the tools can do to fix this, so you need to route an initialization signal as far as I know. I usually do something like this:
reg ready = 0
always @(posedge clk) begin
if (ready)
<run>
else begin
<initialize>
ready = 1
end
end
although I'm a Verilog novice. Clifford might have better suggestions.
This issue has come up a few times and I wonder if Yosys could generate a more informative message. Not only is the init unprocessed, it conflicts with the init that will be implemented and the design is very unlikely to work in that case.
This comes up every once in a while. I've now added support for nonzero init values to yosys synthesis for ice40 in commit 0793f1b. This will add additional inverters into the design for the nonzero bits (as @cseed pointed out already: the hardware registers in the ice40 fpga are always reset to zero).
Note that the Lattice tools ignore register init values! So your HDL code is not portable between our open source synthesis flow and the commercial one if you rely on this feature in your code.
However, in general it is not recommended to use global reset behavior in FPGAs for anything other than maybe creating a real reset signal. Remember that you have no control over the timing of the release of the global reset signal with respect to the clock(s) in your design, nor can you assume that the PLLs are already locked when the global reset is released. So by using the initial values of the registers for more than just a trivial reset generator you risk adding impossible-to-debug race conditions to your design.
Xilinx's Ken Chapman wrote two Xilinx white papers on this issue: https://forums.xilinx.com/t5/PLD-Blog/That-Dangerous-Asynchronous-Reset/ba-p/12856
[..] especially since such a signal ought to be routed by clock lines on chips that have those, and each such line is always precious.
Why? The iCE40 FPGAs have 8 global signals. That is more than enough for most applications, and they are here exactly for things like reset signals.. Furthermore, the iCE40 logic tiles have built-in support for (synchonous and asynchronous) resets. So besides this one global signal (and the logic for creating it) there are no additional resources needed to implement a proper reset signal in an iCE40 design. When you are using the PLLs you can directly use the PLL LOCK
control output as reset signal. In this case there is no overhead at all in terms of used logic resources.
Jfyi: I'm usually using something like the following to create a reset signal:
reg [7:0] resetn_counter = 0;
assign resetn = &resetn_counter;
always @(posedge clk) begin
if (!resetn)
resetn_counter <= resetn_counter + 1;
end
Hi Guys, Thanks for getting back to me so quickly!
@cseed Aha! that figures - This is the first time I've started using the ice40's, I have been accustomed to Spartan3/6 and MachXO2's, and initialising things in the MachXO2 seems to work fine - maybe it's a bug with iceCube2? (which I've never used, the Lattice MachXO2's use Diamond).
@cliffordwolf Thanks! Works great now :)
Those clock lines do get eaten up pretty quickly once one is bridging between a few different devices and clock domains - for instance I have one design which has about 9 clocks (not mine - my version only has 5!)
Keep up the good work!
@cseed FYI These lattice chips do have support for initial values: bit LC_i[18] is the "Set_NoReset" bit, otherwise known as "what initial value the register will force to when the global reset line is asserted". Which must also be what initial value those flip flops will output after they come up out of config, even if the verilog doesn't explicitly talk about a reset.
Of course this only applies to actual registers, not wires and latches and what not.
it's referenced in cliffordwolf/icestorm/docs/logic_tile.html if you're interested.
These lattice chips do have support for initial values: bit LC_i[18]
No. They do not.
As I have already mentioned above, each FF has a reset input that can be used within the design. The Set_NoReset bit controls if this reset input sets or resets the FF. This has nothing to do with the global reset.
Yes, it does.
ice40lp/hx family datasheet page 2-2, footnote right at the bottom, my emphasis added:
"1. If Set/Reset is not used, then the flip-flop is never set/reset, except when cleared immediately after configuration."
Certainly sounds like a post-configuration "global" reset if ever I heard of one.
This calls for a trial by experiment.
come to think of it, this is probably why it has a AsyncSetReset bit too - with respect to the design's clock, the configuration set/reset pulse surely won't be synchronous, since it'll depend on the configuration logic's own clock.
Ok, looks like I stand corrected. Sorry @cliffordwolf !
I just tried setting said bits manually in the dff and nothing, for all three combinations. Maybe the vendor tools do something in addition to get it to work - besides just wrapping the DFF in two inverters, that is.
I guess i ought to use the PLL's lock for that anyway.
Yep: Top of page 2-4:
"Global Reset Control The global reset control signal connects to all PLB and PIO flip-flops on the iCE40 device. The global reset signal is automatically asserted throughout the configuration process, forcing all flip-flops to their defined wake-up state. For PLB flip-flops, the wake-up state is always reset, regardless of the PLB flip-flop primitive used in the application.". Doh.
Maybe the vendor tools do something in addition to get it to work
As I have said before: The Lattice tools ignore all register initializations:
Note that the Lattice tools ignore register init values! So your HDL code is not portable between our open source synthesis flow and the commercial one if you rely on this feature in your code.
Hi Great Work!
Also I'm not sure whether this issue rightly belongs here, on arachne-pnr or icestorm.
Here it is, code such as:
Starts the FPGA up with rng set to zero... which prevents it from working because it needs at least one bit set initially as a seed. So it has to have a reset pin of some sort connected.
Which I believe best practise depreciates for initial values on SRAM FPGA's, since if a reset is really needed, say due to ionising radiation upset or what-not, the whole configuration ought to be reset, not just some data within it.
There is an error in the CHECK pass of yosys:
I also tried setting that one in an
intial
block, which didn't generate any "not synthesizable" errors, through it also didn't work.I guess this can be worked-around, but it's awkward to use a saturating counter to generate an extra reset-shortly-after-power-up signal which is then never used again, especially since such a signal ought to be routed by clock lines on chips that have those, and each such line is always precious.
Anyway, Thanks so very much for having as much working as you do! You guys are champions!