MyHDL

Type mismatch with earlier assignment:

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')

I don’t see any .next in your code?

def testunit() doesn’t have any outgoing signals, so what is the purpose of a0 and b0? Or is this a snippet from a larger piece of code?

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

In testunit, a0 and b0 are not signals while ma0 and mb0 are signals.
Assigning a signal to a non signal is non sense.

Note : Please edit and format your code correctly (using markdown tags) to make it readable.

Yes, you got it sent

Sorry for the fomatting. I now found out how to use </> …

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).

Great Nicolas!

Just got the same answer from Josy Boelen and found it simulates just right and converts too.

Will try the outcome in HW next.

Thanks to both of you – After checking some more I will write a ‘solved’ comment for everybody with a similar problem.

Stefan

Gesendet von Mail für Windows 10

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.

What’s wrong ?
What is the faulty code ?
The code under test should appear clearly in a separate function.

However, your code is simple enough to easily understand what wrong.
How do you think sqrt() function is implemented in hardware ?

Ah, yes.

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.

You’re right. I’ve read your code too quickly.

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.

So, what’s wrong ?

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.

Thanks to you DrPi!

To achieve performance, pipelining is the key.