simcells.v: Generate the fine FF cell types by a python script.
authorMarcin Kościelnicki <mwk@0x04.net>
Thu, 26 Mar 2020 20:15:28 +0000 (21:15 +0100)
committerMarcelina Kościelnicka <mwk@0x04.net>
Thu, 2 Apr 2020 16:37:15 +0000 (18:37 +0200)
This makes adding more FF types in the future much more manageable.

Fixes #1824.

techlibs/common/gen_fine_ffs.py [new file with mode: 0644]
techlibs/common/simcells.v

diff --git a/techlibs/common/gen_fine_ffs.py b/techlibs/common/gen_fine_ffs.py
new file mode 100644 (file)
index 0000000..3a9aa6c
--- /dev/null
@@ -0,0 +1,239 @@
+TEMPLATES = [
+"""
+//  |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+//-
+//-     $_SR_{S:N|P}{R:N|P}_ (S, R, Q)
+//-
+//- A set-reset latch with {S:negative|positive} polarity SET and {R:negative|positive} polarity RESET.
+//-
+//- Truth table:    S R | Q
+//-                -----+---
+//-                 {S:0|1} {R:0|1} | x
+//-                 {S:0|1} {R:1|0} | 1
+//-                 {S:1|0} {R:0|1} | 0
+//-                 {S:1|0} {R:1|0} | y
+//-
+module \$_SR_{S:N|P}{R:N|P}_ (S, R, Q);
+input S, R;
+output reg Q;
+always @({S:neg|pos}edge S, {R:neg|pos}edge R) begin
+       if (R == {R:0|1})
+               Q <= 0;
+       else if (S == {S:0|1})
+               Q <= 1;
+end
+endmodule
+""",
+"""
+`ifdef SIMCELLS_FF
+//  |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+//-
+//-     $_FF_ (D, Q)
+//-
+//- A D-type flip-flop that is clocked from the implicit global clock. (This cell
+//- type is usually only used in netlists for formal verification.)
+//-
+module \$_FF_ (D, Q);
+input D;
+output reg Q;
+always @($global_clock) begin
+       Q <= D;
+end
+endmodule
+`endif
+""",
+"""
+//  |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+//-
+//-     $_DFF_{C:N|P}_ (D, C, Q)
+//-
+//- A {C:negative|positive} edge D-type flip-flop.
+//-
+//- Truth table:    D C | Q
+//-                -----+---
+//-                 d {C:\\|/} | d
+//-                 - - | q
+//-
+module \$_DFF_{C:N|P}_ (D, C, Q);
+input D, C;
+output reg Q;
+always @({C:neg|pos}edge C) begin
+       Q <= D;
+end
+endmodule
+""",
+"""
+//  |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+//-
+//-     $_DFFE_{C:N|P}{E:N|P}_ (D, C, E, Q)
+//-
+//- A {C:negative|positive} edge D-type flip-flop with {E:negative|positive} polarity enable.
+//-
+//- Truth table:    D C E | Q
+//-                -------+---
+//-                 d {C:\\|/} {E:0|1} | d
+//-                 - - - | q
+//-
+module \$_DFFE_{C:N|P}{E:N|P}_ (D, C, E, Q);
+input D, C, E;
+output reg Q;
+always @({C:neg|pos}edge C) begin
+       if ({E:!E|E}) Q <= D;
+end
+endmodule
+""",
+"""
+//  |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+//-
+//-     $_DFF_{C:N|P}{R:N|P}{V:0|1}_ (D, C, R, Q)
+//-
+//- A {C:negative|positive} edge D-type flip-flop with {R:negative|positive} polarity {V:reset|set}.
+//-
+//- Truth table:    D C R | Q
+//-                -------+---
+//-                 - - {R:0|1} | {V:0|1}
+//-                 d {C:\\|/} - | d
+//-                 - - - | q
+//-
+module \$_DFF_{C:N|P}{R:N|P}{V:0|1}_ (D, C, R, Q);
+input D, C, R;
+output reg Q;
+always @({C:neg|pos}edge C or {R:neg|pos}edge R) begin
+       if (R == {R:0|1})
+               Q <= {V:0|1};
+       else
+               Q <= D;
+end
+endmodule
+""",
+"""
+//  |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+//-
+//-     $_DFFSR_{C:N|P}{S:N|P}{R:N|P}_ (C, S, R, D, Q)
+//-
+//- A {C:negative|positive} edge D-type flip-flop with {S:negative|positive} polarity set and {R:negative|positive}
+//- polarity reset.
+//-
+//- Truth table:    C S R D | Q
+//-                ---------+---
+//-                 - - {R:0|1} - | 0
+//-                 - {S:0|1} - - | 1
+//-                 {C:\\|/} - - d | d
+//-                 - - - - | q
+//-
+module \$_DFFSR_{C:N|P}{S:N|P}{R:N|P}_ (C, S, R, D, Q);
+input C, S, R, D;
+output reg Q;
+always @({C:neg|pos}edge C, {S:neg|pos}edge S, {R:neg|pos}edge R) begin
+       if (R == {R:0|1})
+               Q <= 0;
+       else if (S == {S:0|1})
+               Q <= 1;
+       else
+               Q <= D;
+end
+endmodule
+""",
+"""
+//  |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+//-
+//-     $_DLATCH_{E:N|P}_ (E, D, Q)
+//-
+//- A {E:negative|positive} enable D-type latch.
+//-
+//- Truth table:    E D | Q
+//-                -----+---
+//-                 {E:0|1} d | d
+//-                 - - | q
+//-
+module \$_DLATCH_{E:N|P}_ (E, D, Q);
+input E, D;
+output reg Q;
+always @* begin
+       if (E == {E:0|1})
+               Q <= D;
+end
+endmodule
+""",
+"""
+//  |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+//-
+//-     $_DLATCHSR_{E:N|P}{S:N|P}{R:N|P}_ (E, S, R, D, Q)
+//-
+//- A {E:negative|positive} enable D-type latch with {S:negative|positive} polarity set and {R:negative|positive}
+//- polarity reset.
+//-
+//- Truth table:    E S R D | Q
+//-                ---------+---
+//-                 - - {R:0|1} - | 0
+//-                 - {S:0|1} - - | 1
+//-                 {E:0|1} - - d | d
+//-                 - - - - | q
+//-
+module \$_DLATCHSR_{E:N|P}{S:N|P}{R:N|P}_ (E, S, R, D, Q);
+input E, S, R, D;
+output reg Q;
+always @* begin
+       if (R == {R:0|1})
+               Q <= 0;
+       else if (S == {S:0|1})
+               Q <= 1;
+       else if (E == {E:0|1})
+               Q <= D;
+end
+endmodule
+""",
+]
+
+lines = []
+with open('simcells.v') as f:
+    for l in f:
+        lines.append(l)
+        if 'START AUTOGENERATED CELL TYPES' in l:
+            break
+
+with open('simcells.v', 'w') as f:
+    for l in lines:
+        f.write(l)
+    for template in TEMPLATES:
+        chunks = []
+        vars = {}
+        pos = 0
+        while pos < len(template):
+            if template[pos] != '{':
+                np = template.find('{', pos)
+                if np == -1:
+                    np = len(template)
+                chunks.append(template[pos:np])
+                pos = np
+            else:
+                np = template.index('}', pos)
+                sub = template[pos + 1:np]
+                pos = np + 1
+                var, _, vals = sub.partition(':')
+                if not vals:
+                    raise ValueError(sub)
+                vals = vals.split('|')
+                if var not in vars:
+                    vars[var] = len(vals)
+                else:
+                    if vars[var] != len(vals):
+                        raise ValueError(vars[var], vals)
+                chunks.append((var, vals))
+        combs = [{}]
+        for var in vars:
+            combs = [
+                {
+                    var: i,
+                    **comb,
+                }
+                for comb in combs
+                for i in range(vars[var])
+            ]
+        for comb in combs:
+            f.write(
+                ''.join(
+                    c if isinstance(c, str) else c[1][comb[c[0]]]
+                    for c in chunks
+                )
+            )
index 64720e598595f710108132ce0ac40aff8ca997c1..2bac78d38c376920bffc7bc8d8870a083b5f31fa 100644 (file)
@@ -456,11 +456,16 @@ output Y;
 assign Y = E ? A : 1'bz;
 endmodule
 
+// NOTE: the following cell types are autogenerated.  DO NOT EDIT them manually,
+// instead edit the templates in gen_ff_types.py and rerun it.
+
+// START AUTOGENERATED CELL TYPES
+
 //  |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
 //-
 //-     $_SR_NN_ (S, R, Q)
 //-
-//- A set-reset latch with negative polarity SET and RESET.
+//- A set-reset latch with negative polarity SET and negative polarity RESET.
 //-
 //- Truth table:    S R | Q
 //-                -----+---
@@ -532,7 +537,7 @@ endmodule
 //-
 //-     $_SR_PP_ (S, R, Q)
 //-
-//- A set-reset latch with positive polarity SET and RESET.
+//- A set-reset latch with positive polarity SET and positive polarity RESET.
 //-
 //- Truth table:    S R | Q
 //-                -----+---
@@ -871,7 +876,8 @@ endmodule
 //-
 //-     $_DFFSR_NNN_ (C, S, R, D, Q)
 //-
-//- A negative edge D-type flip-flop with negative polarity set and reset.
+//- A negative edge D-type flip-flop with negative polarity set and negative
+//- polarity reset.
 //-
 //- Truth table:    C S R D | Q
 //-                ---------+---
@@ -951,7 +957,8 @@ endmodule
 //-
 //-     $_DFFSR_NPP_ (C, S, R, D, Q)
 //-
-//- A negative edge D-type flip-flop with positive polarity set and reset.
+//- A negative edge D-type flip-flop with positive polarity set and positive
+//- polarity reset.
 //-
 //- Truth table:    C S R D | Q
 //-                ---------+---
@@ -977,7 +984,8 @@ endmodule
 //-
 //-     $_DFFSR_PNN_ (C, S, R, D, Q)
 //-
-//- A positive edge D-type flip-flop with negative polarity set and reset.
+//- A positive edge D-type flip-flop with negative polarity set and negative
+//- polarity reset.
 //-
 //- Truth table:    C S R D | Q
 //-                ---------+---
@@ -1057,7 +1065,8 @@ endmodule
 //-
 //-     $_DFFSR_PPP_ (C, S, R, D, Q)
 //-
-//- A positive edge D-type flip-flop with positive polarity set and reset.
+//- A positive edge D-type flip-flop with positive polarity set and positive
+//- polarity reset.
 //-
 //- Truth table:    C S R D | Q
 //-                ---------+---
@@ -1123,7 +1132,8 @@ endmodule
 //-
 //-     $_DLATCHSR_NNN_ (E, S, R, D, Q)
 //-
-//- A negative enable D-type latch with negative polarity set and reset.
+//- A negative enable D-type latch with negative polarity set and negative
+//- polarity reset.
 //-
 //- Truth table:    E S R D | Q
 //-                ---------+---
@@ -1149,8 +1159,8 @@ endmodule
 //-
 //-     $_DLATCHSR_NNP_ (E, S, R, D, Q)
 //-
-//- A negative enable D-type latch with negative polarity set and positive polarity
-//- reset.
+//- A negative enable D-type latch with negative polarity set and positive
+//- polarity reset.
 //-
 //- Truth table:    E S R D | Q
 //-                ---------+---
@@ -1176,8 +1186,8 @@ endmodule
 //-
 //-     $_DLATCHSR_NPN_ (E, S, R, D, Q)
 //-
-//- A negative enable D-type latch with positive polarity set and negative polarity
-//- reset.
+//- A negative enable D-type latch with positive polarity set and negative
+//- polarity reset.
 //-
 //- Truth table:    E S R D | Q
 //-                ---------+---
@@ -1203,7 +1213,8 @@ endmodule
 //-
 //-     $_DLATCHSR_NPP_ (E, S, R, D, Q)
 //-
-//- A negative enable D-type latch with positive polarity set and reset.
+//- A negative enable D-type latch with positive polarity set and positive
+//- polarity reset.
 //-
 //- Truth table:    E S R D | Q
 //-                ---------+---
@@ -1229,7 +1240,8 @@ endmodule
 //-
 //-     $_DLATCHSR_PNN_ (E, S, R, D, Q)
 //-
-//- A positive enable D-type latch with negative polarity set and reset.
+//- A positive enable D-type latch with negative polarity set and negative
+//- polarity reset.
 //-
 //- Truth table:    E S R D | Q
 //-                ---------+---
@@ -1255,8 +1267,8 @@ endmodule
 //-
 //-     $_DLATCHSR_PNP_ (E, S, R, D, Q)
 //-
-//- A positive enable D-type latch with negative polarity set and positive polarity
-//- reset.
+//- A positive enable D-type latch with negative polarity set and positive
+//- polarity reset.
 //-
 //- Truth table:    E S R D | Q
 //-                ---------+---
@@ -1282,8 +1294,8 @@ endmodule
 //-
 //-     $_DLATCHSR_PPN_ (E, S, R, D, Q)
 //-
-//- A positive enable D-type latch with positive polarity set and negative polarity
-//- reset.
+//- A positive enable D-type latch with positive polarity set and negative
+//- polarity reset.
 //-
 //- Truth table:    E S R D | Q
 //-                ---------+---
@@ -1309,7 +1321,8 @@ endmodule
 //-
 //-     $_DLATCHSR_PPP_ (E, S, R, D, Q)
 //-
-//- A positive enable D-type latch with positive polarity set and reset.
+//- A positive enable D-type latch with positive polarity set and positive
+//- polarity reset.
 //-
 //- Truth table:    E S R D | Q
 //-                ---------+---
@@ -1330,4 +1343,3 @@ always @* begin
                Q <= D;
 end
 endmodule
-