convert MkClkCon to iterator
[pinmux.git] / src / migen / safeinmux.py
1 from functools import reduce
2 from math import log
3 from migen.fhdl.module import Module
4 from migen.fhdl.structure import Mux, Signal, Array, Constant, If, Case
5 from migen.fhdl import verilog
6 from migen.sim.core import run_simulation
7
8
9 def orop(x1, x2):
10 return x1 | x2
11
12
13 class SafeInputMux(Module):
14 def __init__(self, inwidth):
15 wlog = int(log(inwidth, 2))
16 self.inputs = Array()
17 for i in range(inwidth):
18 self.inputs.append(Signal(1, name_override="input_{}".format(i)))
19 self.output = Signal(name_override="output")
20 self.selector = Signal(max=inwidth + 1)
21 self.io = set(self.inputs) | set([self.output, self.selector])
22 sel_r = Signal(max=inwidth + 1)
23 sel25 = Signal(max=1 << inwidth)
24 zero = Constant(0)
25 muxes = []
26 for i in range(len(self.inputs)):
27 x = Constant(1 << i, inwidth)
28 choose = Signal()
29 choose.eq(self.selector & x)
30 muxes.append(Mux(self.selector & x, self.inputs[i], zero))
31 mux = self.output.eq(reduce(orop, muxes))
32 self.comb += mux
33 self.sync += sel_r.eq(self.selector)
34
35 d = {}
36 x = 1
37 for i in range(inwidth):
38 d[i] = (sel25.eq(x << i),)
39
40 self.sync += If(self.selector != sel_r,
41 sel25.eq(0),
42 ).Else(
43 Case(sel_r, d)
44 )
45
46
47 class Blinker(Module):
48 def __init__(self, led, maxperiod1, maxperiod2, select):
49 self.counter = Signal(max=maxperiod1 + 1)
50 self.period1 = Signal(max=maxperiod1 + 1)
51 self.period2 = Signal(max=maxperiod2 + 1)
52 self.selector = Signal(max=select + 1)
53 self.period = Signal(max=maxperiod1 + 1)
54 self.comb += self.period.eq(Mux(self.selector,
55 self.period1, self.period2))
56 self.comb += self.period1.eq(maxperiod1)
57 self.comb += self.period2.eq(maxperiod2)
58 self.sync += If(self.counter == 0,
59 led.eq(~led),
60 self.counter.eq(self.period)
61 ).Else(
62 self.counter.eq(self.counter - 1)
63 )
64 self.led = led
65
66
67 def tb(dut):
68 swap = 0
69 for val in [0, 1]:
70 for i in range(4):
71 yield dut.inputs[i].eq(val)
72 for sel in [0, 1, 2, 3]:
73 yield dut.selector.eq(sel)
74 yield # run one more clock
75 yield
76 s = ''
77 ins = []
78 for x in range(len(dut.inputs)):
79 ins.append((yield dut.inputs[x]))
80 for x in range(len(dut.inputs)):
81 s += ("{0} ".format(ins[x]))
82 sel = (yield dut.selector)
83 out = (yield dut.output)
84 yield
85 print("{0} out={1} sel={2}".format(s, out, sel))
86
87 print ("%d %d" % (out, ins[sel]))
88 #assert out == ins[sel]
89
90
91 if __name__ == '__main__':
92 mux = SafeInputMux(4)
93 print(verilog.convert(mux, mux.io))
94
95 mux = SafeInputMux(4)
96 run_simulation(mux, tb(mux), vcd_name="safeinputmux.vcd")