add helper routine for creating latched registers
[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, 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):
35 self.sync = sync
36 self.s = Signal(reset_less=True)
37 self.r = Signal(reset_less=True)
38 self.q = Signal(reset_less=True)
39 self.qn = Signal(reset_less=True)
40
41 def elaborate(self, platform):
42 m = Module()
43 q_int = Signal(reset_less=True)
44
45 if self.sync:
46 with m.If(self.s):
47 m.d.sync += q_int.eq(1)
48 with m.Elif(self.r):
49 m.d.sync += q_int.eq(0)
50 with m.Else():
51 m.d.sync += q_int.eq(q_int)
52 m.d.comb += self.q.eq(q_int)
53 else:
54 with m.If(self.s):
55 m.d.sync += q_int.eq(1)
56 m.d.comb += self.q.eq(1)
57 with m.Elif(self.r):
58 m.d.sync += q_int.eq(0)
59 m.d.comb += self.q.eq(0)
60 with m.Else():
61 m.d.sync += q_int.eq(q_int)
62 m.d.comb += self.q.eq(q_int)
63 m.d.comb += self.qn.eq(~self.q)
64
65 return m
66
67 def ports(self):
68 return self.s, self.r, self.q, self.qn
69
70
71 def sr_sim(dut):
72 yield dut.s.eq(0)
73 yield dut.r.eq(0)
74 yield
75 yield
76 yield
77 yield dut.s.eq(1)
78 yield
79 yield
80 yield
81 yield dut.s.eq(0)
82 yield
83 yield
84 yield
85 yield dut.r.eq(1)
86 yield
87 yield
88 yield
89 yield dut.r.eq(0)
90 yield
91 yield
92 yield
93
94 def test_sr():
95 dut = SRLatch()
96 vl = rtlil.convert(dut, ports=dut.ports())
97 with open("test_srlatch.il", "w") as f:
98 f.write(vl)
99
100 run_simulation(dut, sr_sim(dut), vcd_name='test_srlatch.vcd')
101
102 dut = SRLatch(sync=False)
103 vl = rtlil.convert(dut, ports=dut.ports())
104 with open("test_srlatch_async.il", "w") as f:
105 f.write(vl)
106
107 run_simulation(dut, sr_sim(dut), vcd_name='test_srlatch_async.vcd')
108
109 if __name__ == '__main__':
110 test_sr()