PWM

This example shows how to generate a pulse-width modulation signal.


In [1]:
import magma as m
m.set_mantle_target('ice40')

In [2]:
from mantle import Counter, ULE
from loam.boards.icestick import IceStick

N = 8

def PWM(n):
    return ULE(n)

icestick = IceStick()
icestick.Clock.on()
for i in range(8):
    icestick.J1[i].input().on()
icestick.J3[0].output().on()

main = icestick.main()

counter = Counter(32)
sawtooth = counter.O[8:8+N]
# alternatively, reverse bits before feeding to comparitor
# sawtooth = array([counter.O[8+N-1-i] for i in range(N)])

pwm = PWM(N)
m.wire( pwm( sawtooth, main.J1 ), main.J3 )

m.EndDefine()


import lattice ice40
import lattice mantle40

In [3]:
m.compile('build/pwm', main)

In [4]:
%%bash
cd build
cat pwm.pcf
yosys -q -p 'synth_ice40 -top main -blif pwm.blif' pwm.v
arachne-pnr -q -d 1k -o pwm.txt -p pwm.pcf pwm.blif 
icepack pwm.txt pwm.bin
iceprog pwm.bin


set_io J1[0] 112
set_io J1[1] 113
set_io J1[2] 114
set_io J1[3] 115
set_io J1[4] 116
set_io J1[5] 117
set_io J1[6] 118
set_io J1[7] 119
set_io J3 62
set_io CLKIN 21
init..
cdone: high
reset..
cdone: low
flash ID: 0x20 0xBA 0x16 0x10 0x00 0x00 0x23 0x64 0x34 0x65 0x03 0x00 0x71 0x00 0x26 0x27 0x12 0x16 0xD3 0xE4
file size: 32220
erase 64kB sector at 0x000000..
programming..
reading..
VERIFY OK
cdone: high
Bye.

We can wire up the GPIO pins to a logic analyzer to verify that our circuit produces the correct waveform.


In [ ]: