# Initialisation behaviour can be problematic

**URL:** https://discourse.myhdl.org/t/initialisation-behaviour-can-be-problematic/549
**Category:** Showcase
**Created:** [November 16, 2022, 2:08pm UTC](https://discourse.myhdl.org/t/initialisation-behaviour-can-be-problematic/549 "2022-11-16T14:08:37Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![stekar](https://avatars.discourse-cdn.com/v4/letter/s/8dc957/32.png) [@stekar](https://discourse.myhdl.org/u/stekar)
#### Post date: [November 16, 2022, 2:08pm UTC](https://discourse.myhdl.org/t/initialisation-behaviour-can-be-problematic/549/1 "2022-11-16T14:08:37Z")

</div>

After my conclusion ‘best practice’ i just came upon another behavior which differs between myhdl and cosim when producing synthesizable code:

> The initialization of variables  
> (moreover ‘adding to a variable doesn’t work’ in cosim when not initialized)

I describe this here to underline the necessity to simulate both in myhdl and cosim to understand what’s happening when your output in hardware is pure zeroes…unexpectedly.

My conclusion is: Don’t rely on the intbv initial value to init your variable.  
Do initialize in the simulation with a ResetSignal. And use this signal in hw then.

But try the code by running tb\_unittest.py. Start with line \*1) set so that things won’t work. Follow the lines marked \*1) to \*5) to reproduce an watch the results until things work. report.py also plots the results. More elaboration can be done with the .vcd output.  
I hope this helps newbie developers who don’t get their hw to work the same as the sim. replace unit\_test.py with your own unit and adapt …

Hints:  
-For cosimulation you will need a myhdl.vpi file which depends on your system. I found it easy to compile from c source for ubuntu. But i did not succeed in windows… but following the instructions in the myhdl handbook this should be feasible.

- For the report you will need the matplotlib library installed in python3  
If you dislike comment out report in tb\_unittest.py (You will get results anyway)  
otherwise use pip install matplotlib in a command window.

Here is my showcase consisting on three files

tb\_unittest.py:

```auto
'''
sk 16.11.2022
tb_unittest: cosimulation myhdl and verilog
instantiates a unit and a cosimulation of the unit and simulates this toplevel testbench
Also needed: myhdl.vpi defining communication between cosim objects, together with tb_xxx.v
define result file (insert the dump command in tb_xxx.v will write a dump_result.vcd)
finally does some python plotting of the results in out1.txt, out2.txt with the report_xx.py
'''
import os
from myhdl import Cosimulation, Simulation, block, Signal, delay, always, always_comb, always_seq, instance, instances, intbv,modbv, ResetSignal, now
from unit_test import unit_test
from report import report
from math import pi

n=12
nspi=16
tend=12e-4
dt=128e-6
Wn=2*pi*200

f1=open('out1.txt',"w")
f2=open('out2.txt',"w")

#Amplitude and freq when using internal sin/cos generator for standalone use
M=2.0/3.0 #amplitude of modulation: 2/3 is natural full sine, Max numerical is 1.0

CLKIN = Signal(bool(0))
RESET_N = ResetSignal(0,0,True)
FAULT_N = Signal(bool(0)) # FAULT_N wired or interrupt input
CLK8M = Signal(bool(0)) # clock output to DSP
RELAY_trig = Signal(intbv(0)[1:])

fastcounter = Signal(intbv(0, min=0, max=2**25)) #this counter runs at CLKIN, tap 12=ca.8kHz,
pwmcounter = Signal(modbv(0, min=0,max=2**11)) #this counter is fix 11 bits for 16MHz and 128us loop
strobe_counter_2M = Signal(intbv(0, min=0, max=2**3))
strobe_counter_16k= Signal(intbv(0, min=0, max=2**10))
strobe_counter_8k = Signal(intbv(0, min=0, max=2**11))
strobe2M = Signal(bool(0))
strobe16k = Signal(bool(0))
strobe8k = Signal(bool(0))
clk8k = Signal(bool(0))

# needed for debug
y10=Signal(intbv(0,min=-2**(n),max=2**(n))) # (probes)
y20=Signal(intbv(0,min=-2**(n),max=2**(n)))
y30=Signal(intbv(0,min=-2**(n),max=2**(n)))

def init():
	@instance
	def initialize():
		RESET_N.next = 0
		FAULT_N.next = 1
		yield delay(1000)
		RESET_N.next = 1 # *2) RESET_N.posedge necessary to make cosim work
		yield delay(100)
	return initialize

def osc():
	@always(delay(31))
	def driver():
		CLKIN.next = not CLKIN
	return driver

def clocks():
	@always_comb #CLKIN is 16MHz
	def clockwork():
		CLK8M.next=fastcounter[0]
		clk8k.next=fastcounter[10]
		RELAY_trig.next =fastcounter[24]
	return clockwork

def counters():
	@always_seq(CLKIN.posedge, reset=RESET_N)
	def mycounters():
		pwmcounter.next=pwmcounter+1
		fastcounter.next=fastcounter+1
	return mycounters

def fastreport():
	@always(CLKIN.negedge)
	def out1():
		#print('ns', now(),' ', clk8k,moda0,modb0,'gate:',gate)
		f1.write(str(now())+' '+str(RESET_N)+'\n')
	return out1

def slowreport():
	@always(clk8k.negedge) #new values calculated at posedge
	def out2():
		print('ns', now(),' ', y10, y20, y30)
		f2.write(str(y10)+' '+str(y20)+' '+str(y30)+'\n')
	return out2

def unit_testX(CLKIN,clk8k,RESET_N,y10,y20,y30,M,Wn,dt,n):
	# A Cosimulation object, used to simulate Verilog modules
	os.system("iverilog -o unit_test.o unit_test.v tb_unit_test.v")
	return Cosimulation("vvp -m ./myhdl.vpi unit_test.o", CLKIN=CLKIN, clk8k=clk8k, RESET_N=RESET_N, y10=y10, y20=y20, y30=y30)

init1=init()
osc1=osc()
clocks1=clocks()
counters1=counters()
fastreport1=fastreport()
slowreport1=slowreport()

dummy = unit_test(CLKIN,clk8k,RESET_N,y10,y20,y30,M,Wn,dt,n) #debug
dummy.convert(hdl='Verilog') #convert outputs unit_test.v and tb_unit_test.v
vcd=False
if vcd:
	ftb=open('tb_unit_test.v','r+')
	fd=open('dump.v','r')
	contentStr=ftb.read()
	additionalStr=fd.read()
	newStr=contentStr.replace('endmodule',additionalStr)
	ftb=open('tb_unit_test.v','w')
	ftb.write(newStr+'endmodule')
	ftb.close()
	fd.close()

#choose to simulate pure python or cosim *4) Init problem occurs only in cosimulation mode
# *3) and *5) overflow indication shows up only in pure python
#test1 = unit_test(CLKIN,clk8k,RESET_N,y10,y20,y30,M,Wn,dt,n) #debug pure python
test1 = unit_testX(CLKIN,clk8k,RESET_N,y10,y20,y30,M,Wn,dt,n) #debug cosimulation style

print("Simulating",test1)
sim = Simulation(init1, osc1, clocks1, counters1, test1, fastreport1, slowreport1)
sim.run(tend*1e9)
print("report written to out1.txt and out2.txt")
f1.close()
f2.close()

report(n)

```

unittest.py:

```auto

#unit_test.py 16.10.2022 sk testing multiply and add
from myhdl import *
from math import pi,sqrt
#from unit_cos import unit_cos
#from unit_pwm import unit_pwm

@block
def unit_test(CLKIN,clk8k,RESET_N,y10,y20,y30,M,Wn,dt,n):
	M0 = Signal(intbv(int(round(M*2**n-1)),min=0,max=2**n)) #modulation signal amplitude
	Wndt0 = Signal(intbv(int(round(Wn*dt*2**n/(pi/2))),min=0,max=2**n)) #rad/sec*time ->unit angle, standalone use
	Wt0 = Signal(intbv(0,min=0,max=2**(n-1))) #angle (integrated angular speed)
	ma0 = Signal(intbv(2**(n-1)-1,min=-2**(n-1),max=2**(n-1))) #modulation signals individally initialized
	mb0 = Signal(intbv(0,min=-2**(n-1),max=2**(n-1)))
	moda0 = Signal(intbv(0,min=-2**(n-1),max=2**(n-1)))
	modb0 = Signal(intbv(0,min=-2**(n-1),max=2**(n-1)))

	#helper
	m=2*n
	XH0 = Signal(intbv(0,min=-2 **m,max=2** m))

	@always(RESET_N.posedge)
	def initialize():
		#Wt0.next=100 # 0) No Way. Signal would have multiple drivers
		pass

	#probes to be sent to testbench
	@always(CLKIN.posedge)
	def probe():
		y10.next=moda0
		y20.next=modb0
		y30.next=Wt0

	@always(clk8k.posedge) # *1) Wt0 fails to increment (always 0)
	#@always_seq(clk8k.posedge, RESET_N) # *2) this will work and increment Wt0 - but RESET_N must be driven in testbench
	def loop():
		moda0.next=M0*ma0 # *3) this works even with missing reset *1) but only in cosim. myhdl detects overflow
		XH0.next=M0*ma0 # *4) this works both debug modes. But the initial values differ when compared with 3)
		modb0.next=XH0[:n]
		if Wt0>2**(n-1): # *5a) let an overflow happen and try both sim modes
		#if Wt0>(2**(n-1)-Wt0): # *5b) no overflow -> same results both sim modes
			Wt0.next=0
		else:
			Wt0.next=Wt0+Wndt0

	return instances()

```

report.py:

```auto
'''
sk 09.11.2022
do the report plotting in this separate file'''
import os
from numpy import pi,exp,sqrt,array,real,imag
from matplotlib.pyplot import *

def report(n):
	print('plotreport')
	t0=0.0 #normal time vector (control system dt)
	t10=0.0 #fast time vector (clock system clkdt)
	dt=128e-6
	clkdt=1/16e6 #clock sampling time
	a=exp(1j*(2*pi/3))

	f1=open('out1.txt',"r")
	f2=open('out2.txt',"r")
	# Inits ***************************
	t1=[]
	t=[]
	y1=[]
	y2=[]
	y3=[]

	# reading results file ***************************
	print('reading results from out1.txt and out2.txt')
	for line1 in f1:
		line1 = line1.split()
		t10=t10+clkdt
		t1.append(t10)
	f1.close()

	for line in f2:
		line2 = line.split()
		y10=int(line2[0],16) #python interpretes unsigned
		#if y10>=2**(n-1):
		#	y10=y10-2**n
		y20=int(line2[1],16)
		#if y20>=2**(n-1):
		#	y20=y20-2**n
		y30=int(line2[2],16)
		#if y30>=2**(n-1):
		#	y30=y30-2**n
		print('y: ', y10, ' ', y20, ' ',y30)

		y1.append(y10)
		y2.append(y20)
		y3.append(y30)
		t.append(t0)
		t0=t0+dt
	f2.close()

	print('finished reading results')

	t1=array(t1)
	t=array(t)

	y1=array(y1)
	y2=array(y2)
	y3=array(y3)

	print('plotting ...')

	plot(t,y1,'b',t,y2,'r',t,y3,'g')
	title('y1 b,y2 r,y3 g')
	grid()
	show()

```

---

<div class="post-metadata">

### Author: ![josyb](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.myhdl.org/josyb/32/5_2.png) [@josyb](https://discourse.myhdl.org/u/josyb)
#### Post date: [November 17, 2022, 2:19pm UTC](https://discourse.myhdl.org/t/initialisation-behaviour-can-be-problematic/549/2 "2022-11-17T14:19:29Z")

</div>

Stefan,

I think I don’t agree with you about your statement.  
Try:

```python
dummy.convert(hdl='Verilog', initial_values=True) # convert outputs unit_test.v and tb_unit_test.v

```

This will add initialization in the generated V\* code.  
Both simulator and synthesizer will accept that.  
The generated Verilog code can be optimized as Sigasi recommends replacing some old-type constructs with newer ones.

Also, if MyHDL simulation detects an overflow I would check my code why.

Best regards,  
Josy

---

<div class="post-metadata">

### Author: ![josyb](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.myhdl.org/josyb/32/5_2.png) [@josyb](https://discourse.myhdl.org/u/josyb)
#### Post date: [November 17, 2022, 6:34pm UTC](https://discourse.myhdl.org/t/initialisation-behaviour-can-be-problematic/549/3 "2022-11-17T18:34:34Z")

</div>

Stefan,

I compiled a myhdl.vpi back in 2020. I checked that it works with your code.  
Unfortunately I didn’t document how I compiled it. But IMO we can add the compiled .vpi to the repository: @jck what do you think?

Regards,  
Josy

---

<div class="post-metadata">

### Author: ![stekar](https://avatars.discourse-cdn.com/v4/letter/s/8dc957/32.png) [@stekar](https://discourse.myhdl.org/u/stekar)
#### Post date: [November 17, 2022, 8:28pm UTC](https://discourse.myhdl.org/t/initialisation-behaviour-can-be-problematic/549/4 "2022-11-17T20:28:13Z")

</div>

Hi josy,

I also compiled a myhdl.vpi on xubuntu just by running the command make in the same directory as the c source.

Unfortunately on windows 10 it’s not so easy. There is no make command available and gmake does’nt do it for some reason. I installed cygwin and tried with no success but did not insist. I think people have done it with the cygwin shell. So if you have a myhdl.vpi for windows 10 I’m interested.

Apart from that i fully agree with your comments on my post…

(I’m about to rewrite the simulation the new syntax way and that is not as difficult as i thought)

Kind regards

Stefan

---

<div class="post-metadata">

### Author: ![stekar](https://avatars.discourse-cdn.com/v4/letter/s/8dc957/32.png) [@stekar](https://discourse.myhdl.org/u/stekar)
#### Post date: [November 18, 2022, 8:26am UTC](https://discourse.myhdl.org/t/initialisation-behaviour-can-be-problematic/549/5 "2022-11-18T08:26:01Z")

</div>

Thanks josy for the tip about initialize\_values=True !

This makes my code work the way i expected it. Both in myhdl block simulation as cosim.  
(I would think this setting should be default - but there may be reasons for not?)

Then the multiplication:  
it’s tempting to write only

```auto
		moda0.next=M0*ma0          

```

But this is implicitly assuming that the final result is only the upper n bits of the 2n result of the multiplication. And myhdl complains…  
So indeed it is better to program explicitely

```auto
#helper
m=2*n
XH0 = Signal(intbv(0,min=-2 **m,max=2** m))

XH0.next=M0*ma0 # *4) need a intermediate Signal to store the full length
modb0.next=XH0[:n] # then slice off the lower n

```

And yes - the new way of writing statements is the way to go. So i rewrote the testbench and did some fresh up of the unit under test and the report to provide here.

tb\_unittest.py:

```auto
'''
Stefan Karrer 18.11.2022
tb_unittest: cosimulation myhdl and verilog
instantiates a unit and a cosimulation of the unit and simulates this toplevel testbench
Also needed: myhdl.vpi defining communication between cosim objects, together with tb_xxx.v
define result file (insert the dump command in tb_xxx.v will write a dump_result.vcd)
finally does some python plotting of the results in out1.txt, out2.txt with the report_xx.py
'''
import os
from myhdl import Cosimulation, Simulation, block, Signal, delay, always, always_comb, always_seq, instance, instances, intbv,modbv, ResetSignal, now
from unit_test import unit_test
from report import report
from math import pi

n=12 #data length parameter

tend=2e-3
dt=128e-6
Wn=2*pi*200

f1=open('out1.txt',"w")
f2=open('out2.txt',"w")

#Amplitude and freq when using internal sin/cos generator for standalone use
M=2.0/3.0 #amplitude of modulation: 2/3 is natural full sine, Max numerical is 1.0

# i/o signals
CLKIN = Signal(bool(0))
CLK8M = Signal(bool(0))
RESET_N = ResetSignal(1,0,True) # *2) initialize to 1
RELAY = Signal(bool(0))

#internal signals
fastcounter = Signal(intbv(0, min=0, max=2**25)) #this counter runs at CLKIN, 12=8kHz,
clk8k = Signal(bool(0))
RELAY_trig = Signal(bool(0))
pwmcounter = Signal(modbv(0, min=0,max=2**11)) #this counter is fix 11 bits for 16MHz and 128us loop

# probes needed for debug
y10=Signal(intbv(0,min=-2 **n,max=2** n))
y20=Signal(intbv(0,min=-2 **n,max=2** n))
y30=Signal(intbv(0,min=-2 **n,max=2** n))

print('translating unit_test to Verilog. Creates a cosim testbench interface')
unit_test(CLKIN,clk8k,RESET_N,y10,y20,y30,M,Wn,dt,n).convert(hdl='Verilog', initial_values=True) # *2) set initial_values True !!!

@block
def tb_unittest():

	@always(delay(31))
	def osc():
		CLKIN.next = not CLKIN

	@always_comb #CLKIN is 16MHz
	def clockwork():
		CLK8M.next=fastcounter[0]
		clk8k.next=fastcounter[10]
		RELAY_trig.next =fastcounter[24]

	@always_seq(CLKIN.posedge, reset=RESET_N)
	def counters():
		pwmcounter.next=pwmcounter+1
		fastcounter.next=fastcounter+1

	@always(CLKIN.negedge)
	def out1():
		#print('ns', now(),' ', clk8k,moda0,modb0,'gate:',gate)
		f1.write(str(now())+' '+str(clk8k)+'\n')

	@always(clk8k.negedge) #new values calculated at posedge
	def out2():
		print('ns', now(),' ', y10, y20, y30)
		f2.write(str(y10)+' '+str(y20)+' '+str(y30)+'\n')

	@block
	def unit_testX():
		# A Cosimulation object, used to simulate Verilog modules
		os.system("iverilog -o unit_test.o unit_test.v tb_unit_test.v")
		if cosim:
			return Cosimulation("vvp -m ./myhdl.vpi unit_test.o", CLKIN=CLKIN, clk8k=clk8k, RESET_N=RESET_N, y10=y10, y20=y20, y30=y30)
		else:
			return unit_test(CLKIN,clk8k,RESET_N,y10,y20,y30,M,Wn,dt,n)

	return instances(), unit_testX()

#choose to simulate pure python or cosim
cosim=True #get same results with cosim. But execution is slower
if cosim:
	print("running cosimulation")
else:
	print("running myhdl block")

dut=tb_unittest()
dut.run_sim(tend*1e9)

f1.close()
f2.close()

report(n) #plot results

```

unit\_test.py:

```auto
#unit_test.py 16.10.2022 sk testing multiply and add
from myhdl import *
from math import pi

@block
def unit_test(CLKIN,clk8k,RESET_N,y10,y20,y30,M,Wn,dt,n):
	M0 = Signal(intbv(int(round(M*2**n-1)),min=0,max=2**n)) #modulation signal amplitude
	Wndt0 = Signal(intbv(int(round(Wn*dt*2**n/(pi/2))),min=0,max=2**n)) #rad/sec*time ->unit angle, standalone use
	Wt0 = Signal(intbv(0,min=0,max=2**(n-1))) #angle (integrated angular speed)
	ma0 = Signal(intbv(2**(n-1)-1,min=-2**(n-1),max=2**(n-1))) #modulation signals individally initialized
	mb0 = Signal(intbv(0,min=-2**(n-1),max=2**(n-1)))
	moda0 = Signal(intbv(0,min=-2**(n-1),max=2**(n-1)))
	modb0 = Signal(intbv(0,min=-2**(n-1),max=2**(n-1)))

	#helper
	m=2*n
	XH0 = Signal(intbv(0,min=-2 **m,max=2** m))

	#probes to be sent to testbench
	@always(CLKIN.posedge)
	def probe():
		y10.next=moda0
		y20.next=modb0
		y30.next=Wt0

	@always(clk8k.posedge) # *1) Wt0 fails to increment (always 0) if initial_values is not True !!!
	def loop():
		XH0.next=M0*ma0 # *4) need a intermediate Signal to store the full result of 2n length
		modb0.next=XH0[:n] # then slice off the lower n
		#if Wt0>2**(n-1): # *5a) let an overflow happen. myhdl detects this. not so cosim.
		if Wt0>(2**(n-1)-Wt0): # *5b) no overflow here
			Wt0.next=0
		else:
			Wt0.next=Wt0+Wndt0

	return instances()

```

report.py:

```auto
'''
sk 16.11.2022
do the report plotting in this separate file'''
import os
#from numpy import pi,exp,sqrt,array,real,imag
from matplotlib.pyplot import *

def report(n):
	print('plotreport')
	t0=0.0 #normal time vector (control system dt)
	t10=0.0 #fast time vector (clock system clkdt)
	dt=128e-6
	clkdt=1/16e6 #clock sampling time

	f1=open('out1.txt',"r")
	f2=open('out2.txt',"r")
	# Inits ***************************
	t1=[]
	t=[]
	y1=[]
	y2=[]
	y3=[]

	# reading results file ***************************
	print('reading results from out1.txt and out2.txt')
	for line1 in f1:
		line1 = line1.split()
		t10=t10+clkdt
		t1.append(t10)
	f1.close()

	for line in f2:
		line2 = line.split()
		y10=int(line2[0],16) #python interpretes unsigned
		#if y10>=2**(n-1):
		#	y10=y10-2**n
		y20=int(line2[1],16)
		#if y20>=2**(n-1):
		#	y20=y20-2**n
		y30=int(line2[2],16)
		#if y30>=2**(n-1):
		#	y30=y30-2**n
		print('y: ', y10, ' ', y20, ' ',y30)

		y1.append(y10)
		y2.append(y20)
		y3.append(y30)
		t.append(t0)
		t0=t0+dt
	f2.close()

	plot(t,y1,'b',t,y2,'r',t,y3,'g')
	title('y1 b,y2 r,y3 g')
	grid()
	show()

```

---

<div class="post-metadata">

### Author: ![josyb](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.myhdl.org/josyb/32/5_2.png) [@josyb](https://discourse.myhdl.org/u/josyb)
#### Post date: [November 19, 2022, 4:41pm UTC](https://discourse.myhdl.org/t/initialisation-behaviour-can-be-problematic/549/6 "2022-11-19T16:41:35Z")

</div>

Hi Stefan,

I used/installed Msys2 to compile the .vpi; Google tells me I visited their website twice 🙂  
As mentioned above, I’d like to add it to the repo; but first I would like to test it more. I will send you this .vpi by DM

Best regards,  
Josy

---

<div class="post-metadata">

### Author: ![stekar](https://avatars.discourse-cdn.com/v4/letter/s/8dc957/32.png) [@stekar](https://discourse.myhdl.org/u/stekar)
#### Post date: [November 19, 2022, 8:43pm UTC](https://discourse.myhdl.org/t/initialisation-behaviour-can-be-problematic/549/7 "2022-11-19T20:43:36Z")

</div>

I think the myhdl.vpi for windows 10 issue should be discussed in a separate thread.  
I’ll open a new one.

I just want to say that above files are meant to be a good framework for anyone who wants to develop some myhdl unit without prior knowledge.

- The unit is embedded in a testbench that writes out to display and files.
- The files are then read by a report.py and displayed graphically with matplotlib which gives all new possibilities like filtering output data i.e. when pwm signals are analyzed.  
(not used in the framework).
- In addition the .vcd can be written by switch to further analyze time series with gtkwave.
- The unit itself is synthesizable, data is initialized (thank you josy).
- both myhdl block simulation as well as cosimulation can be used on a linux machine.

I just forgot to give the dump.insert file which contains the dump command to be added the (translated) testbench verilog file:

```auto
initial begin
    $dumpfile("dump_result.vcd");
    $dumpvars();
end

```

The new thread i call “how to use cosimulation on a windows machine?”
