add helper routine for creating latched registers
[ieee754fpu.git] / src / nmutil / latch.py
index 41a8df9442920e67336fd9a35604ae64442ec008..6cf5ab7ec93e5de0752cdfd2cf00f56c4edf7d8c 100644 (file)
@@ -2,6 +2,33 @@ from nmigen.compat.sim import run_simulation
 from nmigen.cli import verilog, rtlil
 from nmigen import Signal, Module, Elaboratable
 
+""" jk latch
+
+module jk(q,q1,j,k,c);
+output q,q1;
+input j,k,c;
+reg q,q1;
+initial begin q=1'b0; q1=1'b1; end
+always @ (posedge c)
+  begin
+    case({j,k})
+         {1'b0,1'b0}:begin q=q; q1=q1; end
+         {1'b0,1'b1}: begin q=1'b0; q1=1'b1; end
+         {1'b1,1'b0}:begin q=1'b1; q1=1'b0; end
+         {1'b1,1'b1}: begin q=~q; q1=~q1; end
+    endcase
+   end
+endmodule
+"""
+
+def latchregister(m, incoming, outgoing, settrue):
+    reg = Signal.like(incoming) # make register same as input. reset is OK.
+    with m.If(settrue):
+        m.d.sync += reg.eq(incoming)      # latch input into register
+        m.d.comb += outgoing.eq(incoming) # return input (combinatorial)
+    with m.Else():
+        m.d.comb += outgoing.eq(reg) # return input (combinatorial)
+
 
 class SRLatch(Elaboratable):
     def __init__(self, sync=True):
@@ -20,20 +47,20 @@ class SRLatch(Elaboratable):
                 m.d.sync += q_int.eq(1)
             with m.Elif(self.r):
                 m.d.sync += q_int.eq(0)
+            with m.Else():
+                m.d.sync += q_int.eq(q_int)
             m.d.comb += self.q.eq(q_int)
-            m.d.comb += self.qn.eq(~q_int)
         else:
             with m.If(self.s):
                 m.d.sync += q_int.eq(1)
                 m.d.comb += self.q.eq(1)
-                m.d.comb += self.qn.eq(0)
             with m.Elif(self.r):
                 m.d.sync += q_int.eq(0)
                 m.d.comb += self.q.eq(0)
-                m.d.comb += self.qn.eq(1)
             with m.Else():
+                m.d.sync += q_int.eq(q_int)
                 m.d.comb += self.q.eq(q_int)
-                m.d.comb += self.qn.eq(~q_int)
+        m.d.comb += self.qn.eq(~self.q)
 
         return m
 
@@ -72,5 +99,12 @@ def test_sr():
 
     run_simulation(dut, sr_sim(dut), vcd_name='test_srlatch.vcd')
 
+    dut = SRLatch(sync=False)
+    vl = rtlil.convert(dut, ports=dut.ports())
+    with open("test_srlatch_async.il", "w") as f:
+        f.write(vl)
+
+    run_simulation(dut, sr_sim(dut), vcd_name='test_srlatch_async.vcd')
+
 if __name__ == '__main__':
     test_sr()