[myhdl-list] Re: Signal initialization
Brought to you by:
jandecaluwe
From: Jan D. <ja...@ja...> - 2004-10-26 20:58:10
|
David Brochart wrote: > There is another issue that I would like to bring up. In the following code: > > ------------------------------------------------------------- > > from myhdl import intbv, Signal, Simulation, instances, delay > > def test(a, b, c): > while 1: > yield a, b > c.next = a.val + b.val > print "Test function executed" > > def a_gen(a): > while 1: > yield delay(10) > a.next = 0 > > def top(): > a = Signal(intbv(0)) > b = Signal(intbv(1)) > c = Signal(intbv()) > a_gen_i = a_gen(a) > test_i = test(a, b, c) > return instances() > > > top_inst = top() > sim = Simulation(top_inst) > sim.run(100) > > ------------------------------------------------------------- > > The "test" function is never executed, because "a" and "b" never change their > value (always 0 and 1 respectively). It means that if another function uses the > "c" output value of "test", it will be wrong. It's exactly what you should expect according to MyHDL semantics, or VHDL or Verilog for that matter. The problem is rather that you expect this template to correspond to combinatorial logic, which is not correct. Of course the expectation is understandable because virtually everybody has it. But still, it's based on a historical error introduced by synthesis tools vendors. See further. > A workaround would be to initialize "a" like this: > > a = Signal(intbv(None)) > > So that "a" changes its value in the "a_gen" function. But then I found out that > in the general case it causes too many problems because some inputs might not be > initialized (still at "None") when the code is executed, resulting in an error. > We can solve this by executing the code only if all the input values are > different than "None". Writing this condition after every "yield" statement is > not very beautiful (maybe MyHDL could resume the function only if all the input > values are different than "None"?). Mm, this is complicated and would introduce "special" behavior which is going to be confusing. Quoting from the Zen of Python (>>> import this): "Special cases aren't special enough to break the rules." :-) > Another workaround would be to initialize "a" like that: > > a = Signal(intbv(0)) > > and writing "test" with the "yield" statement at the end: > > def test(a, b, c): > while 1: > c.next = a.val + b.val > print "Test function executed" > yield a, b > > This way, "test" is always executed at least once. I don't know if "always_comb" > corresponds to this configuration though. Exactly. That's how the combinatorial template should have been in the first place. And yes, that's how always_comb in SystemVerilog works. And also how it works in MyHDL therefore. See the code in _always_comb.py, you'll see the actual generator with the sensitivity list at the end. Background: in Verilog, the problem would often not be apparent, because all regs are implicitly initialized on x, which means that an event occurs as soon as they get a defined value. However, this doesn't mean that Verilog got it right. On the contrary, as is typical of its zero delay behavior, it made a complete mess out of it. The problem is what the following should do: reg a = 1; # reg declaration plus assignment at the same time In my opinion, the only sensible way to understand this would be as an initialization. But Verilog chose to create an event from x->1 anyway, for "compatibility". Or at least some simulators did. And this was how it was described in the Verilog 2001 standard. Finally, the SystemVerilog standardization realized the absurdity of the above, and explicitly determined that it should be treated as an initialization instead. In addition, it introduced the always_comb block with the semantics of the sensitivity list at the end, as it should be. Final note: there is a practical problem with synthesis. Synthesis tools may not support the sensitivity list at the end (or the always_comb block of SystemVerilog). Therefore, when a MyHDL always_comb is converted to Verilog, I still put the sensitivity list at the beginning. This issue is documented in section 6.7 of the manual. Regards, Jan -- Jan Decaluwe - Resources bvba - http://jandecaluwe.com Losbergenlaan 16, B-3010 Leuven, Belgium Python is fun, and now you can design hardware with it: http://jandecaluwe.com/Tools/MyHDL/Overview.html |