← Back to context

Comment by kens

18 days ago

There's a difference between what Verilog will allow and what is "synthesizable". In other words, there is a lot of stuff that you can express in Verilog, but when you try to turn it into an FPGA bitstream, the software will say, "Sorry, I don't know how to do that." Coming from a software background, this seems bizarre, as if C++ compilers rejected valid programs unless they stuck to easy constructs with obvious assembly implementations.

Using both edges of a clock is something that you can express in Verilog, but can't be directly mapped onto an FPGA, so the synthesis software will reject it. You'd probably want to double the clock rate and use alternating clock pulses instead of alternating edges. See: https://electronics.stackexchange.com/questions/39709/using-...

Coming from an electronics design background, I'm even more amazed that Verilog can't gracefully handle multi-phase clocks, let alone two phases of a single clock. That's a big part of getting the most out of your power and timing budget. Also, it seems half the discussion around clocking in FPGAs are around the metainstability of communicating between logic on separate single-phase clocks. If even one clock used two phases, you'd have entirely stateful conditions.

I've found that the FPGAs themselves can handle multi-phase clocks in combinatorial logic. If you want to use the built-in clock routing and latches, I would recommend running the output of the PLL to a LUT input, then outputting that input as well as its inverse from the LUT, routing each to a global clock input. That will keep the phase right at 180°, let you drive directly off global clock fanout, and let you run the clock at the highest frequency that the fabric supports.

> Coming from a software background, this seems bizarre, as if C++ compilers rejected valid programs unless they stuck to easy constructs with obvious assembly implementations.

To my understanding, isn’t it more like there being a perfectly good IR instruction coding for a feature, but with no extant ISA codegen targets that recognize that instruction? I.e. you get stuck at the step where you’re lowering the code for a specific FPGA impl.

And, as with compilers, one could get around this by defining a new abstract codegen target implemented only in the form of a software simulator, and adding support for the feature to that. Though it would be mightily unsatisfying to ultimately be constrained to run your FPGA bitstream on a CPU :)

  • The non-synthesizable features of Verilog not only work in current simulators, they were expressly developed for that purpose. Verilog has those features to describe conditions that might exist in a semiconductor as manufactured, but aren't part of any design, so that they can be more accurately simulated. For example, a pin state can be unknown, or two pins can be connected with a delay line. These allow a real-life semiconductor to be characterized well enough to insert into a simulation of the electronics circuit as a whole.

    It's more akin to directives than instructions. Debug instructions can also serve a similar purpose, although they actually run on the hardware, whereas compiler directives and non-synthesizable verilog instructions are never executed.