<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Triangle Signal Generator
A triangle wave is a periodic waveform that linearly ramps between two  values.
Step1:  We can wire up the GPIO pins to a logic analyzer to verify that our circuit produces the correct triangle waveform.
We can also use Saleae's export data feature to output a csv file. We'll load this data into Python and plot the results.
Step2:  TODO
<ASSISTANT_TASK:>
Python Code:
import magma as m
m.set_mantle_target('ice40')
import mantle
def DefineTriangle(n):
    T = m.Bits(n)
    class _Triangle(m.Circuit):
        name = f'Triangle{n}'
        IO  = ['I', m.In(T), 'O', m.Out(T)]
    
        @classmethod
        def definition(io):
            invert = mantle.Invert(n)
            mux = mantle.Mux(2, n)
            m.wire( mux( io.I, invert(io.I), io.I[n-1] ), io.O )
    return _Triangle
def Triangle(n):
    return DefineTriangle(n)()
from loam.boards.icestick import IceStick
N = 8
icestick = IceStick()
icestick.Clock.on()
for i in range(N):
    icestick.J3[i].output().on()
main = icestick.main()  
counter = mantle.Counter(32)
sawtooth = counter.O[8:8+N]
tri = Triangle(N)
m.wire( tri(sawtooth), main.J3 )
m.EndDefine()
m.compile('build/triangle', main)
%%bash
cd build
cat triangle.pcf
yosys -q -p 'synth_ice40 -top main -blif triangle.blif' triangle.v
arachne-pnr -q -d 1k -o triangle.txt -p triangle.pcf triangle.blif 
icepack triangle.txt triangle.bin
iceprog triangle.bin
Explanation: Triangle Signal Generator
A triangle wave is a periodic waveform that linearly ramps between two  values.
End of explanation
import csv
import magma as m
with open("data/triangle-capture.csv") as triangle_capture_csv:
    csv_reader = csv.reader(triangle_capture_csv)
    next(csv_reader, None)  # skip the headers
    rows = [row for row in csv_reader]
timestamps = [float(row[0]) for row in rows]
values = [m.bitutils.seq2int(tuple(int(x) for x in row[1:])) for row in rows]
Explanation: We can wire up the GPIO pins to a logic analyzer to verify that our circuit produces the correct triangle waveform.
We can also use Saleae's export data feature to output a csv file. We'll load this data into Python and plot the results.
End of explanation
import matplotlib.pyplot as plt
%matplotlib inline
plt.plot(timestamps[:1000], values[:1000], "-")
Explanation: TODO: Why do we have this little bit of jitter? Logic analyzer is running at 25 MS/s, 3.3+ Volts for 1s
End of explanation
<END_TASK>