Below code works fine when not converted - just simulated.
I cannot find the cause of the conversion error when the code is converted.
to explain:
this is only a snippet out of code that uses ma0 and mb0 as signals in many places, while a0,b0 and some other variables are used locally and temporarily for decisions only. That’s why i would declare these not as Signals.
Anyway: declaring a0,b0 Signals does not help
cast Signals to intbv is not possible i think.
the error occurs on the line a0=-ma0.
Does someone see how to do that?
#testunit.py 25.01.2021 sk
from myhdl import *
@block
def testunit(ma0,mb0,n):
a0=intbv(0,min=-2**(n-1),max=2**(n-1))
b0=intbv(0,min=-2**(n-1),max=2**(n-1))
@always(ma0,mb0)
def dispatch():
if mb0>=0:
state=0
a0=ma0[:]
b0=mb0[:]
else:
state=3
a0=-ma0[:]
b0=-mb0[:]
return instances()
#tb_testunit.py 26.01.2021 sk
import os
from myhdl import *
from testunit import testunit
print('testunit sk')
n=11
def tb_testunit(hdl):
ma0=Signal(intbv(0,min=-2**n,max=2**n)) #modulation signal
mb0=Signal(intbv(0,min=-2**n,max=2**n))
tb = testunit(ma0,mb0,n)
tb.convert(hdl=hdl)
tb_testunit(hdl='Verilog')
Yes josi, it is from a piece of code where i want to determine which of six sectors a given complex vector ma0 + j* mb0 is in.
So i start to determine if its in the upper or lower half plane.
Then i rotate 60 degrees as long as mb0 is positive, inreasing the sector each time.
The rotated vector is also needed as a result.
So there are several intermediate results to test before output is available.
I consider the intermediate results as temporary only not needing to be signals.
Now i cant copy and invert the input vector due to this error appearing (only when translating the code, not at simulation)
Has it to do with shadowing?
Can you share the complete code?
If you want to keep it non-public, send it to josyboelen@gmail.com (of course then Google knows …) perhaps best zip it with a password
I realize I havent given enough code for the reader to recognize my problem:
When Signals ma0 or mb0 change value i have to do a sequence of calculations and decisions based on the CURRENT values of these signals.
This works fine in simulation but is not convertible as my code snippet shows.
Using Signal.next=… will update my intermediary result first in the next step and the calculation becomes inconsistent. I may have to do a different design like a state machine for this approach i guess.
So there is no way to make my code snippet convert?
To make your design convert, instead of writing a0=-ma0[:] you should write a0[:]=-ma0.
This might not do what you expect. You have to check the generated code.
Keep in mind that MyHDL let you write code that you can simulate but not convert (like any conventional HDL).
After compiling my code did’nt work as simulated (you said so DrPi !)
So i wrote a little testcase which can explain to newbies like me what’s happening (or how i see it):
#testcase2.py sk 03.02.2021
#result of a multiplication
#using Signal and intbv mixed
#take decision based on intbv's value
from myhdl import *
from math import pi,sqrt
n=11
nspi=16
tend=1e-6
@block
def testcase():
CLK = Signal(bool(0))
RESET = ResetSignal(1,active = 0, isasync=True)
ma0 = Signal(modbv(0,min=-2**(n-1),max=2**(n-1))) #modulation signal
outSig = Signal(intbv(0,min=-2**(nspi-1),max=2**(nspi-1)))
sqrt3half=intbv(int(round(sqrt(3.0)/2.0*2**(n-1))))
#invsqrt3 =intbv(int(1.0/sqrt(3)*2**(n>>1)))[n>>1:0]
temp0= intbv(0,min=-2**(n-1),max=2**(n-1))
tempa0=intbv(0,min=-2**(n-1),max=2**(n-1))
tempb0=intbv(0,min=-2**(n-1),max=2**(n-1))
''' Clock driver 16MHz'''
@always(delay(31))
def driver():
CLK.next = not CLK
@instance
def init():
ma0.next=0x400 # #0x400 is max negative at n=11. 0x3ff is max pos
yield delay(100)
@always_seq(CLK.negedge,reset=RESET)
def multiplication():
tempa0[:]=ma0 #use [:] to cast Signal to intbv
# do some decisions and intermediary calculation (which you cannot do with Signals but with intbv's)
if tempa0>=0:
tempb0=tempa0
else:
#tempb0=-tempa0
tempb0=tempa0
#Now do a multiplication with intbv's
#temp0 = tempb0 * sqrt3half >> (n-1) #this will cast to integer L !
temp0[:] = tempb0 * sqrt3half >> (n-1) # use [:] to get the result in a intbv!
outSig.next=temp0 # cast back to Signal
print(ma0, 'tempa0 (b10)=', tempa0,'sqrt3half (b10)=',sqrt3half,' mult (b10)=',temp0,'outSig :',outSig)
return instances()
tc = testcase()
tc.run_sim(tend*1e9)
print('Simulated to tend='+str(tend))
I hope some expert myhdl user will look it over to tell whether my conclusions (in the comments) are correct.
There should not be any faulty code. And I’m not so far yet as to implement in hardware.
(In fact I thought pure python code can be used outside the generators - but well- I must be wrong - that helps of course)
The purpose of this testcase was just to show the difference between
intbv_variable = intbv_variable (which yields a integer)
and
intbv_variable[:]=intbv_variable (which yields the expected intbv)
as i.e. in the line
temp0[:] = tempb0 * sqrt3half >> (n-1)
I did’nt find this documented and wanted to show and ask whether I’m right with this conclusion which I found by experimenting with above code.
As a general rule, you should avoid using variables in a process. Variables behave differently from signals. It is easy to have “hidden” side effects with variables. This not specific to MyHDL but true with all HDL.
Yes, exactly.
My experience now is to use Signals only.
I got misled by the fact that my former dsp design for this special pulse width generator could be easily simulated with myhdl.
It was a flat combinatorial design and I used plain integers in this first approach.
This could even be converted and run correc- but used much resources so that I achieved only 7 bit precision. Wanted 11 bits.
Using intbv instead of plain integers simulated correctly, but did not work in hw.
To make it short: I fail to save on resources with this design and try next with a sequential design using signals only.