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 ) )