Thread: [myhdl-list] inference problem?
Brought to you by:
jandecaluwe
From: Haitao Z. <ha...@gm...> - 2005-02-26 05:15:07
|
I could not figure out why the following code could not generate correct Verilog code (the intermediate q1 is missing): def reg_dq(clk,d,q): def proc(): while 1: yield posedge(clk) q.next=d return proc() def reg_dq2(clk,d,q): if d._nrbits: q1=Signal(intbv(0))[d._nrbits:] else: q1=Signal(intbv(0)) def proc(): while 1: yield posedge(clk) q.next=q1 q1.next=d return proc() # reg1=reg_dq(clk,d,q1) # reg2=reg_dq(clk,q1,q) # return reg1, reg2 I fail to see the difference between this and the provided examples. This is just a simple try to generate a delay of 2. The commented out code didn't work either. I get two assignments to q instead. Thanks for any help. Haitao |
From: Jan D. <ja...@ja...> - 2005-02-26 21:35:32
|
Haitao Zhang wrote: > I could not figure out why the following code could not generate > correct Verilog code (the intermediate q1 is missing): > > def reg_dq(clk,d,q): > def proc(): > while 1: > yield posedge(clk) > q.next=d > return proc() > > def reg_dq2(clk,d,q): > if d._nrbits: > q1=Signal(intbv(0))[d._nrbits:] > else: > q1=Signal(intbv(0)) > def proc(): > while 1: > yield posedge(clk) > q.next=q1 > q1.next=d > return proc() > # reg1=reg_dq(clk,d,q1) > # reg2=reg_dq(clk,q1,q) > # return reg1, reg2 > > I fail to see the difference between this and the provided examples. > This is just a simple try to generate a delay of 2. The commented out > code didn't work either. I get two assignments to q instead. > > Thanks for any help. Yes, I infer that you didn't simulate this :-) Here's the problem: your intention is that q1 is a Signal, but it isn't. In fact, in MyHDL: q1 = Signal(intbv(0))[n:] is equivalent to: q1 = Signal(intbv(0)).val[n:] that is, you get a slice of the current underlying value, which is an intbv and not a signal. What you want is: q1 = Signal(intbv(0)[n:]) In this case, you get a signal with an intbv (with a defined bit width) as its underlying value. The reason why conversion currently behaves like it does has to do with namespace lookups. Perhaps more could be done to detect flaws, BUT in a Python context this is an upfront battle. You really should use the run-time (= simulation) to detect errors. I have written about this before: (from the manual, section 6.5.1) """ In the Python philosophy, the run-time rules. The Python compiler doesn't attempt to detect a lot of errors beyond syntax errors, which given Python's ultra-dynamic nature would be an almost impossible task anyway. To verify a Python program, one should run it, preferably using unit testing to verify each feature. The same philosophy should be used when converting a MyHDL description to Verilog: make sure the simulation runs fine first. Although the converter checks many things and attempts to issue clear error messages, there is no guarantee that it does a meaningful job unless the simulation runs fine. """ In other words, if the simulation works fine, my goal is to guarantee that the conversion (if it succeeds) is correct. Otherwise, all bets are off (even if conversion succeeds). Note that in this case, a trivial test bench would detect the error, as q1 in your code cannot have a next attribute. Miscellaneous remark: please don't use "private" attributes such as _nrbits. An intbv supports the 'len' function (which returns 0 for undefined bit widths.) Regards, Jan -- Jan Decaluwe - Resources bvba - http://jandecaluwe.com Losbergenlaan 16, B-3010 Leuven, Belgium Using Python as a hardware description language: http://jandecaluwe.com/Tools/MyHDL/Overview.html |
From: Haitao Z. <ha...@gm...> - 2005-02-26 22:14:01
|
Jan, Thanks! You spotted the problem! > Yes, I infer that you didn't simulate this :-) Right I didn't on this one. I want to build a model of my project in myhdl and before doing it I wanted to be sure that it can be converted so I am experimenting a bit to see how things go. I did try some other sims just not thought of doing it here. As you can tell I am new to myhdl, and also pretty new to Python. Thanks for all the good advice. Haitao > > Here's the problem: your intention is that q1 is a Signal, but it isn't. > In fact, in MyHDL: > > q1 = Signal(intbv(0))[n:] > > is equivalent to: > > q1 = Signal(intbv(0)).val[n:] > > that is, you get a slice of the current underlying value, which is an > intbv and not a signal. > > What you want is: > > q1 = Signal(intbv(0)[n:]) > > In this case, you get a signal with an intbv (with a defined bit width) > as its underlying value. > > The reason why conversion currently behaves like it does has to do > with namespace lookups. Perhaps more could be done to detect flaws, > BUT in a Python context this is an upfront battle. You really should > use the run-time (= simulation) to detect errors. I have written > about this before: > > (from the manual, section 6.5.1) > """ > In the Python philosophy, the run-time rules. The Python compiler > doesn't attempt to detect a lot of errors beyond syntax errors, which > given Python's ultra-dynamic nature would be an almost impossible task > anyway. To verify a Python program, one should run it, preferably > using unit testing to verify each feature. > > The same philosophy should be used when converting a MyHDL description > to Verilog: make sure the simulation runs fine first. Although the > converter checks many things and attempts to issue clear error > messages, there is no guarantee that it does a meaningful job unless > the simulation runs fine. > """ > > In other words, if the simulation works fine, my goal is to guarantee > that the conversion (if it succeeds) is correct. Otherwise, all bets > are off (even if conversion succeeds). > > Note that in this case, a trivial test bench would detect the error, > as q1 in your code cannot have a next attribute. > > Miscellaneous remark: please don't use "private" attributes such as > _nrbits. An intbv supports the 'len' function (which returns 0 for > undefined bit widths.) > > Regards, Jan > > -- > Jan Decaluwe - Resources bvba - http://jandecaluwe.com > Losbergenlaan 16, B-3010 Leuven, Belgium > Using Python as a hardware description language: > http://jandecaluwe.com/Tools/MyHDL/Overview.html > > ------------------------------------------------------- > SF email is sponsored by - The IT Product Guide > Read honest & candid reviews on hundreds of IT Products from real users. > Discover which products truly live up to the hype. Start reading now. > http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click > _______________________________________________ > myhdl-list mailing list > myh...@li... > https://lists.sourceforge.net/lists/listinfo/myhdl-list > |
From: Haitao Z. <ha...@gm...> - 2005-02-26 22:58:27
|
More challenge if you are still there:). This time I did simulate (but I haven't stepped throuigh toVerilog failure yet). The code simulates (here q2 has been defined globally): def reg_dq3(clk,d0,q3): reg1=reg_dq2(clk,d0,q2) reg2=reg_dq(clk,q2,q3) return reg1,reg2 If I do toVerilog like this: my_delay2=toVerilog(reg_dq3, clk, d0, q) it works. But if I change it to: my_delay2=toVerilog(reg_dq3, clk, cntr_out, q) toVerilog complains about shadowing. What is shadowing? Here is the trace: cntr_out d0 Traceback (most recent call last): File "./myhdl_test.py", line 20, in ? my_delay2=toVerilog(reg_dq3, clk, cntr_out, q) File "/usr/local/lib/python2.4/site-packages/myhdl/_toVerilog/_convert.py", line 92, in toVerilog _writeModuleHeader(vfile, intf) File "/usr/local/lib/python2.4/site-packages/myhdl/_toVerilog/_convert.py", line 122, in _writeModuleHeader raise ToVerilogError(_error.ShadowingSignal, portname) myhdl.ToVerilogError: Port is shadowed by internal signal: d0 On Sat, 26 Feb 2005 14:13:52 -0800, Haitao Zhang <ha...@gm...> wrote: > Jan, > Thanks! You spotted the problem! > > > Yes, I infer that you didn't simulate this :-) > > Right I didn't on this one. I want to build a model of my project in > myhdl and before doing it I wanted to be sure that it can be > converted so I am experimenting a bit to see how things go. I did try > some other sims just not thought of doing it here. As you can tell I > am new to myhdl, and also pretty new to Python. Thanks for all the > good advice. > > Haitao |
From: Jan D. <ja...@ja...> - 2005-03-02 09:56:32
|
Haitao Zhang wrote: > More challenge if you are still there:). This time I did simulate (but > I haven't stepped throuigh toVerilog failure yet). The code simulates > (here q2 has been defined globally): > > def reg_dq3(clk,d0,q3): > reg1=reg_dq2(clk,d0,q2) > reg2=reg_dq(clk,q2,q3) > return reg1,reg2 > > If I do toVerilog like this: > my_delay2=toVerilog(reg_dq3, clk, d0, q) > > it works. But if I change it to: > my_delay2=toVerilog(reg_dq3, clk, cntr_out, q) > > toVerilog complains about shadowing. What is shadowing? Shadowing refers to the following situation: def top(a, b, c, ...): a = Signal(...) ... In other words, an internal Signal "shadows" a port with the a same name. This is perfectly valid (though meaningless) in Python, but cannot be converted into meaningful Verilog. MyHDL attempts to detect this, and raises a error. What you describe is something else: a1 = Signal(a, b, c, ...): def top(a, b, c): ... instance = toVerilog(top, a1, b, c, ...) In other words, you use a different name for the Signal than for the port at instantiation time. This is perfectly valid Python and MyHDL, and could be converted into meaningful Verilog. However, the current port name test is too severe and detects this situation also, apart from the real "shadowing" case. Conclusion: in any case, the current error is misleading for the situation you encounter. This has to be solved. There are 3 options, and I ask for feedback: - top level signal names should be the same as their corresponding top level port names (as currently), and a clear error should be raised in the other case. - in the generated Verilog, the MyHDL port names should be used. - in the generated Verilog, the actual MyHDL signal names should be used. In this case, the Verilog module interface will use different port names than the MyHDL function. Jan -- Jan Decaluwe - Resources bvba - http://jandecaluwe.com Losbergenlaan 16, B-3010 Leuven, Belgium Using Python as a hardware description language: http://jandecaluwe.com/Tools/MyHDL/Overview.html |
From: David B. <dav...@fr...> - 2005-03-02 14:00:59
|
> Conclusion: in any case, the current error is misleading > for the situation you encounter. This has to be solved. > There are 3 options, and I ask for feedback: > > - top level signal names should be the same as their > corresponding top level port names (as currently), and > a clear error should be raised in the other case. It means we need to change the Python code from a pure simulation use to = a Verilog generation use if top level signal names and top level port names= were different. It would be nice not to have to do this. > - in the generated Verilog, the MyHDL port names should be > used. I think it is what we expect it to do. > - in the generated Verilog, the actual MyHDL signal names > should be used. In this case, the Verilog module interface > will use different port names than the MyHDL function. I think this would lead to confusion between the MyHDL description and th= e Verilog description. Regards, David. |
From: Haitao Z. <ha...@gm...> - 2005-03-02 19:22:06
|
Thanks for the explaination. There seems to be a little more to it: toVerilog does not always flag different port name and signal name as a problem (e.g. the q signal for the q3 port was fine). It actually seemed content to let most pass but somehow caught on to the particular example I gave. Even though the signals are defined in a single statement (therefore positional wise identical). Moving the function def around also does not make a difference. I agree with Dave in the subsequent email that one should use port names (as it currently seems to do correctly most of the times) for Verilog generation. Haitao On Wed, 02 Mar 2005 11:48:44 +0100, Jan Decaluwe <ja...@ja...> wrote: > Haitao Zhang wrote: > > More challenge if you are still there:). This time I did simulate (but > > I haven't stepped throuigh toVerilog failure yet). The code simulates > > (here q2 has been defined globally): > > > > def reg_dq3(clk,d0,q3): > > reg1=reg_dq2(clk,d0,q2) > > reg2=reg_dq(clk,q2,q3) > > return reg1,reg2 > > > > If I do toVerilog like this: > > my_delay2=toVerilog(reg_dq3, clk, d0, q) > > > > it works. But if I change it to: > > my_delay2=toVerilog(reg_dq3, clk, cntr_out, q) > > > > toVerilog complains about shadowing. What is shadowing? > > Shadowing refers to the following situation: > > def top(a, b, c, ...): > a = Signal(...) > ... > > In other words, an internal Signal "shadows" a port with the > a same name. This is perfectly valid (though meaningless) in > Python, but cannot be converted into meaningful Verilog. MyHDL > attempts to detect this, and raises a error. > > What you describe is something else: > > a1 = Signal(a, b, c, ...): > > def top(a, b, c): > ... > > instance = toVerilog(top, a1, b, c, ...) > > In other words, you use a different name for the Signal > than for the port at instantiation time. This is perfectly > valid Python and MyHDL, and could be converted into > meaningful Verilog. However, the current port name test > is too severe and detects this situation also, apart > from the real "shadowing" case. > > Conclusion: in any case, the current error is misleading > for the situation you encounter. This has to be solved. > There are 3 options, and I ask for feedback: > > - top level signal names should be the same as their > corresponding top level port names (as currently), and > a clear error should be raised in the other case. > - in the generated Verilog, the MyHDL port names should be > used. > - in the generated Verilog, the actual MyHDL signal names > should be used. In this case, the Verilog module interface > will use different port names than the MyHDL function. > > Jan > > -- > Jan Decaluwe - Resources bvba - http://jandecaluwe.com > Losbergenlaan 16, B-3010 Leuven, Belgium > Using Python as a hardware description language: > http://jandecaluwe.com/Tools/MyHDL/Overview.html > > ------------------------------------------------------- > SF email is sponsored by - The IT Product Guide > Read honest & candid reviews on hundreds of IT Products from real users. > Discover which products truly live up to the hype. Start reading now. > http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click > _______________________________________________ > myhdl-list mailing list > myh...@li... > https://lists.sourceforge.net/lists/listinfo/myhdl-list > |
From: Jan D. <ja...@ja...> - 2005-03-02 22:20:41
|
Haitao Zhang wrote: > Thanks for the explaination. There seems to be a little more to it: > toVerilog does not always flag different port name and signal name as > a problem (e.g. the q signal for the q3 port was fine). It actually > seemed content to let most pass but somehow caught on to the > particular example I gave. Haitao: Nice debugging work! To explain what happens, consider the following: >>> from myhdl import * >>> q = Signal(0) >>> def f(q3): ... return q is q3 ... >>> f(q) True The point is that inside f, q and q3 can now be used interchangeably. This is of course utterly confusing, but if you did write code like that, MyHDL can still generate correct Verilog code! (ain't it great?) It will choose one of the 2 names (q or q3) and use it consistently. However, if it chooses the one different from the port name, toVerilog will fail for the reason described in an earlier mail. Currently, the name choice is arbitrary, based on the occurence of the names/Signals in a dictionary. (Warning: seemingly unrelated statements can influence this - However: when the conversion works, it should be correct :-)) What it should do is always use the port name (as per the feedback I received, and I agree.) Regards, Jan -- Jan Decaluwe - Resources bvba - http://jandecaluwe.com Losbergenlaan 16, B-3010 Leuven, Belgium Using Python as a hardware description language: http://jandecaluwe.com/Tools/MyHDL/Overview.html |