allow SRLatch to be multibit
[ieee754fpu.git] / src / nmutil / latch.py
1 from nmigen.compat.sim import run_simulation
2 from nmigen.cli import verilog, rtlil
3 from nmigen import Signal, Module, Const, Elaboratable
4
5 """ jk latch
6
7 module jk(q,q1,j,k,c);
8 output q,q1;
9 input j,k,c;
10 reg q,q1;
11 initial begin q=1'b0; q1=1'b1; end
12 always @ (posedge c)
13 begin
14 case({j,k})
15 {1'b0,1'b0}:begin q=q; q1=q1; end
16 {1'b0,1'b1}: begin q=1'b0; q1=1'b1; end
17 {1'b1,1'b0}:begin q=1'b1; q1=1'b0; end
18 {1'b1,1'b1}: begin q=~q; q1=~q1; end
19 endcase
20 end
21 endmodule
22 """
23
24 def latchregister(m, incoming, outgoing, settrue):
25 reg = Signal.like(incoming) # make register same as input. reset is OK.
26 with m.If(settrue):
27 m.d.sync += reg.eq(incoming) # latch input into register
28 m.d.comb += outgoing.eq(incoming) # return input (combinatorial)
29 with m.Else():
30 m.d.comb += outgoing.eq(reg) # return input (combinatorial)
31
32
33 class SRLatch(Elaboratable):
34 def __init__(self, sync=True, llen=1):
35 self.sync = sync
36 self.llen = llen
37 self.s = Signal(llen, reset=0)
38 self.r = Signal(llen, reset=(1<<llen)-1) # defaults to off
39 self.q = Signal(llen, reset_less=True)
40 self.qn = Signal(llen, reset_less=True)
41 self.qlq = Signal(llen, reset_less=True)
42
43 def elaborate(self, platform):
44 m = Module()
45 q_int = Signal(self.llen)
46
47 m.d.sync += q_int.eq((q_int & ~self.r) | self.s)
48 if self.sync:
49 m.d.comb += self.q.eq(q_int)
50 else:
51 m.d.comb += self.q.eq((q_int & ~self.r) | self.s)
52 m.d.comb += self.qn.eq(~self.q)
53 m.d.comb += self.qlq.eq(self.q | q_int) # useful output
54
55 return m
56
57 def ports(self):
58 return self.s, self.r, self.q, self.qn
59
60
61 def sr_sim(dut):
62 yield dut.s.eq(0)
63 yield dut.r.eq(0)
64 yield
65 yield
66 yield
67 yield dut.s.eq(1)
68 yield
69 yield
70 yield
71 yield dut.s.eq(0)
72 yield
73 yield
74 yield
75 yield dut.r.eq(1)
76 yield
77 yield
78 yield
79 yield dut.r.eq(0)
80 yield
81 yield
82 yield
83
84 def test_sr():
85 dut = SRLatch()
86 vl = rtlil.convert(dut, ports=dut.ports())
87 with open("test_srlatch.il", "w") as f:
88 f.write(vl)
89
90 run_simulation(dut, sr_sim(dut), vcd_name='test_srlatch.vcd')
91
92 dut = SRLatch(sync=False)
93 vl = rtlil.convert(dut, ports=dut.ports())
94 with open("test_srlatch_async.il", "w") as f:
95 f.write(vl)
96
97 run_simulation(dut, sr_sim(dut), vcd_name='test_srlatch_async.vcd')
98
99 if __name__ == '__main__':
100 test_sr()