Best practice: my conclusion after months of development

Please comment my conclusion, even after months of development with myhdl i have not seen all of course.

my conclusion on pure python simulation and cosim is essentially that you have to do both all the time while developing. My first attempt was to develop all code in myhdl (pure python) and then feed the verilog translated from python into the toolchain onto a tinyfpga.
→ the result is disappointing and no clue why…

This following setup allows for checking every single change in code both ways.
(as an example):

my unit is in the file unit_pwm10.py and defines a block like i.e.

@block
def unit_pwm(a,b,c…):
.
.

My testbench is in the file tb_unit_pwm and looks like i.e

from unit_pwm10 import unit_pwm #import your unit to the testbench

osc1=osc() #define necessary signals to run unit
clocks1=clocks()
counters1=counters()
strobes1=strobes()
.
.
.
def unit_pwmX(a,b,c…): #instantiate a cosimulation object
# A Cosimulation object, used to simulate Verilog modules
os.system(“iverilog -o unit_pwm.o unit_pwm.v tb_unit_pwm.v”)
return Cosimulation(“vvp -m ./myhdl.vpi unit_pwm.o”, a=a, b=b, c=c…)

unit = unit_pwm(a,b,c…) #instantiate a unit just for convert
unit.convert(hdl=‘Verilog’) #convert outputs unit_pwm.v and tb_unit_pwm.v
vcd=True #do insert some lines into t_unit_pwm.v to dump data to a .vcd file
if vcd:
ftb=open(‘tb_unit_pwm.v’,‘r+’)
fd=open(‘dump.v’,‘r’)
contentStr=ftb.read()
additionalStr=fd.read()
newStr=contentStr.replace(‘endmodule’,additionalStr)
ftb=open(‘tb_unit_pwm.v’,‘w’)
ftb.write(newStr+‘endmodule’)
ftb.close()
fd.close()

#choose one or the other to simulate pure python or cosim
#pwm1 = unit_pwm(a,b,c…) #debug pure python way
pwm1 = unit_pwmX(a,b,c…) #debug with cosim

print(“Simulating”,pwm1) #shows you at execution time whether the pure python simulation or cosim is running
sim = Simulation(osc1, clocks1, counters1, strobes1, pwm1, … all that is needed to run pwm1)
sim.run(tend*1e9) #enter tend in s

where:
dump.v is a dummy name to insert two commands to write the .vcd files it contains only:
initial begin
$dumpfile(“dump_result.vcd”);
$dumpvars();
end

advantage:
Working step by step with intermediate cosimulation showed me i.e. that my n bit constant factor sqrt(3)/2 must be defined as
sqrt3half= Signal(intbv(round(sqrt(3.0)/2.02**n))[n:])
and not as
sqrt3half= intbv(round(sqrt(3.0)/2.0
2**n))[n:]
introducing the latter definition resulted in all output values be zero…therefore “no clue why…”

But i must say that working with myhdl is fun because it allows you to put probes into your code and printing them on screen…saving to files…plotting them with matplotlib for instance… and learning this way how to program parallel stuff.

Congrats to the developers of myhdl!

Hi Stefan,

I must confess that I am not using CoSimulation; I convert to VHDL and as CoSimulation is not (or was not) supported I never tried.
So far I only have been bitten once where the simulation in MyHDL differed from running the actual hardware.

One tip:
bracket your code with:
```python
the code goes here
```

and it will look a lot nicer to the reader:

from unit_pwm10 import unit_pwm #import your unit to the testbench

osc1 = osc() #define necessary signals to run unit
clocks1 = clocks()
counters1 = counters()
strobes1 = strobes()
.
.
.
def unit_pwmX(a,b,c…): #instantiate a cosimulation object
    # A Cosimulation object, used to simulate Verilog modules
    os.system(“iverilog -o unit_pwm.o unit_pwm.v tb_unit_pwm.v”)
    return Cosimulation(“vvp -m ./myhdl.vpi unit_pwm.o”, a=a, b=b, c=c…)

unit = unit_pwm(a,b,c…) #instantiate a unit just for convert
unit.convert(hdl=‘Verilog’) #convert outputs unit_pwm.v and tb_unit_pwm.v
vcd = True #do insert some lines into t_unit_pwm.v to dump data to a .vcd file
if vcd:
    ftb = open(‘tb_unit_pwm.v’,‘r+’)
    fd = open(‘dump.v’,‘r’)
    contentStr = ftb.read()
    additionalStr = fd.read()
    newStr = contentStr.replace(‘endmodule’,additionalStr)
    ftb = open(‘tb_unit_pwm.v’,‘w’)
    ftb.write(newStr+‘endmodule’)
    ftb.close()
    fd.close()

#choose one or the other to simulate pure python or cosim
#pwm1 = unit_pwm(a,b,c…) #debug pure python way
pwm1 = unit_pwmX(a,b,c…) #debug with cosim

print(“Simulating”,pwm1) #shows you at execution time whether the pure python simulation or cosim is running
sim = Simulation(osc1, clocks1, counters1, strobes1, pwm1, … all that is needed to run pwm1)
sim.run(tend*1e9) #enter tend in s

It will also copy nicely to run it as all indents will be preserved

Regards,
Josy

Thank you Josy!
I’m using atom editor with apio as a toolchain to compile the verilog code and download to tinyfpga.
This toolchain works reliably but it doesn’t generate much info about the generated code…warnings etc.

So in an early stage of development I can advise to also generate the code with the fpga manufacturers toolchain and analyse the warnings. In my case this is icecube by lattice which can be used free of cost.
This gave me important hints i could trace back to my programming errors in myhdl.
(Often my python code worked but not so the verilog until i got a feeling for do’s and dont’s to produce production code from myhdl)

Now after some hard work learning I’m very glad to know these tools, especially myhdl.
Learned some python too in the process…

Now I will have a look at your suggestion about formatting that forum message!