yosys/techlibs/common/gen_fine_ffs.py

392 lines
10 KiB
Python

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
//- -----+---
//- - {R:0|1} | 0
//- {S:0|1} - | 1
//- - - | q
//-
module \$_SR_{S:N|P}{R:N|P}_ (S, R, Q);
input S, R;
output reg Q;
always @* 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---|
//-
//- $_DFFE_{C:N|P}{R:N|P}{V:0|1}{E:N|P}_ (D, C, R, E, Q)
//-
//- A {C:negative|positive} edge D-type flip-flop with {R:negative|positive} polarity {V:reset|set} and {E:negative|positive}
//- polarity clock enable.
//-
//- Truth table: D C R E | Q
//- ---------+---
//- - - {R:0|1} - | {V:0|1}
//- d {C:\\|/} - {E:0|1} | d
//- - - - - | q
//-
module \$_DFFE_{C:N|P}{R:N|P}{V:0|1}{E:N|P}_ (D, C, R, E, Q);
input D, C, R, E;
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 if (E == {E:0|1})
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---|
//-
//- $_DFFSRE_{C:N|P}{S:N|P}{R:N|P}{E:N|P}_ (C, S, R, E, D, Q)
//-
//- A {C:negative|positive} edge D-type flip-flop with {S:negative|positive} polarity set, {R:negative|positive}
//- polarity reset and {E:negative|positive} polarity clock enable.
//-
//- Truth table: C S R E D | Q
//- -----------+---
//- - - {R:0|1} - - | 0
//- - {S:0|1} - - - | 1
//- {C:\\|/} - - {E:0|1} d | d
//- - - - - - | q
//-
module \$_DFFSRE_{C:N|P}{S:N|P}{R:N|P}{E:N|P}_ (C, S, R, E, D, Q);
input C, S, R, E, 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 if (E == {E:0|1})
Q <= D;
end
endmodule
""",
"""
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
//-
//- $_SDFF_{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 synchronous {V:reset|set}.
//-
//- Truth table: D C R | Q
//- -------+---
//- - {C:\\|/} {R:0|1} | {V:0|1}
//- d {C:\\|/} - | d
//- - - - | q
//-
module \$_SDFF_{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) 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---|
//-
//- $_SDFFE_{C:N|P}{R:N|P}{V:0|1}{E:N|P}_ (D, C, R, E, Q)
//-
//- A {C:negative|positive} edge D-type flip-flop with {R:negative|positive} polarity synchronous {V:reset|set} and {E:negative|positive}
//- polarity clock enable (with {V:reset|set} having priority).
//-
//- Truth table: D C R E | Q
//- ---------+---
//- - {C:\\|/} {R:0|1} - | {V:0|1}
//- d {C:\\|/} - {E:0|1} | d
//- - - - - | q
//-
module \$_SDFFE_{C:N|P}{R:N|P}{V:0|1}{E:N|P}_ (D, C, R, E, Q);
input D, C, R, E;
output reg Q;
always @({C:neg|pos}edge C) begin
if (R == {R:0|1})
Q <= {V:0|1};
else if (E == {E:0|1})
Q <= D;
end
endmodule
""",
"""
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
//-
//- $_SDFFCE_{C:N|P}{R:N|P}{V:0|1}{E:N|P}_ (D, C, R, E, Q)
//-
//- A {C:negative|positive} edge D-type flip-flop with {R:negative|positive} polarity synchronous {V:reset|set} and {E:negative|positive}
//- polarity clock enable (with clock enable having priority).
//-
//- Truth table: D C R E | Q
//- ---------+---
//- - {C:\\|/} {R:0|1} {E:0|1} | {V:0|1}
//- d {C:\\|/} - {E:0|1} | d
//- - - - - | q
//-
module \$_SDFFCE_{C:N|P}{R:N|P}{V:0|1}{E:N|P}_ (D, C, R, E, Q);
input D, C, R, E;
output reg Q;
always @({C:neg|pos}edge C) begin
if (E == {E:0|1}) begin
if (R == {R:0|1})
Q <= {V:0|1};
else
Q <= D;
end
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---|
//-
//- $_DLATCH_{E:N|P}{R:N|P}{V:0|1}_ (E, R, D, Q)
//-
//- A {E:negative|positive} enable D-type latch with {R:negative|positive} polarity {V:reset|set}.
//-
//- Truth table: E R D | Q
//- -------+---
//- - {R:0|1} - | {V:0|1}
//- {E:0|1} - d | d
//- - - - | q
//-
module \$_DLATCH_{E:N|P}{R:N|P}{V:0|1}_ (E, R, D, Q);
input E, R, D;
output reg Q;
always @* begin
if (R == {R:0|1})
Q <= {V:0|1};
else 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
)
)