diff options
-rw-r--r-- | frontends/verilog/const2ast.cc | 3 | ||||
-rw-r--r-- | passes/techmap/deminout.cc | 2 | ||||
-rw-r--r-- | passes/techmap/iopadmap.cc | 16 | ||||
-rw-r--r-- | techlibs/common/gen_fine_ffs.py | 239 | ||||
-rw-r--r-- | techlibs/common/simcells.v | 50 | ||||
-rw-r--r-- | tests/techmap/iopadmap.ys | 10 |
6 files changed, 298 insertions, 22 deletions
diff --git a/frontends/verilog/const2ast.cc b/frontends/verilog/const2ast.cc index 49281f7e7..230dfadbf 100644 --- a/frontends/verilog/const2ast.cc +++ b/frontends/verilog/const2ast.cc @@ -139,6 +139,9 @@ static void my_strtobin(std::vector<RTLIL::State> &data, const char *str, int le data.resize(len_in_bits, msb); } + if (len_in_bits == 0) + log_file_error(current_filename, get_line_num(), "Illegal integer constant size of zero (IEEE 1800-2012, 5.7).\n"); + if (len > len_in_bits) log_warning("Literal has a width of %d bit, but value requires %d bit. (%s:%d)\n", len_in_bits, len, current_filename.c_str(), get_line_num()); diff --git a/passes/techmap/deminout.cc b/passes/techmap/deminout.cc index 35d43b106..a7dce9c81 100644 --- a/passes/techmap/deminout.cc +++ b/passes/techmap/deminout.cc @@ -113,7 +113,7 @@ struct DeminoutPass : public Pass { { if (bits_numports[bit] > 1 || bits_inout.count(bit)) new_input = true, new_output = true; - if (bit == State::S0 || bit == State::S1) + if (!bit.wire) new_output = true; if (bits_written.count(bit)) { new_output = true; diff --git a/passes/techmap/iopadmap.cc b/passes/techmap/iopadmap.cc index 4504633ee..a18d02652 100644 --- a/passes/techmap/iopadmap.cc +++ b/passes/techmap/iopadmap.cc @@ -229,11 +229,13 @@ struct IopadmapPass : public Pass { for (auto module : design->selected_modules()) { dict<Wire *, dict<int, pair<Cell *, IdString>>> rewrite_bits; + pool<SigSig> remove_conns; if (!toutpad_celltype.empty() || !tinoutpad_celltype.empty()) { dict<SigBit, Cell *> tbuf_bits; pool<SigBit> driven_bits; + dict<SigBit, SigSig> z_conns; // Gather tristate buffers and always-on drivers. for (auto cell : module->cells()) @@ -252,8 +254,10 @@ struct IopadmapPass : public Pass { for (int i = 0; i < GetSize(conn.first); i++) { SigBit dstbit = conn.first[i]; SigBit srcbit = conn.second[i]; - if (!srcbit.wire && srcbit.data == State::Sz) + if (!srcbit.wire && srcbit.data == State::Sz) { + z_conns[dstbit] = conn; continue; + } driven_bits.insert(dstbit); } @@ -302,6 +306,8 @@ struct IopadmapPass : public Pass { // enable. en_sig = SigBit(State::S0); data_sig = SigBit(State::Sx); + if (z_conns.count(wire_bit)) + remove_conns.insert(z_conns[wire_bit]); } if (wire->port_input) @@ -454,6 +460,14 @@ struct IopadmapPass : public Pass { } } + if (!remove_conns.empty()) { + std::vector<SigSig> new_conns; + for (auto &conn : module->connections()) + if (!remove_conns.count(conn)) + new_conns.push_back(conn); + module->new_connections(new_conns); + } + for (auto &it : rewrite_bits) { RTLIL::Wire *wire = it.first; RTLIL::Wire *new_wire = module->addWire( diff --git a/techlibs/common/gen_fine_ffs.py b/techlibs/common/gen_fine_ffs.py new file mode 100644 index 000000000..3a9aa6c59 --- /dev/null +++ b/techlibs/common/gen_fine_ffs.py @@ -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 + ) + ) diff --git a/techlibs/common/simcells.v b/techlibs/common/simcells.v index 64720e598..2bac78d38 100644 --- a/techlibs/common/simcells.v +++ b/techlibs/common/simcells.v @@ -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 - diff --git a/tests/techmap/iopadmap.ys b/tests/techmap/iopadmap.ys index 25ea94dfc..df029b3a0 100644 --- a/tests/techmap/iopadmap.ys +++ b/tests/techmap/iopadmap.ys @@ -55,13 +55,19 @@ obuf b (.i(i), .o(tmp)); assign o = tmp; endmodule +module k(inout o, o2); +assign o = 1'bz; +endmodule + EOT opt_clean tribuf simplemap -iopadmap -bits -inpad ibuf o:i -outpad obuf i:o -toutpad obuft oe:i:o -tinoutpad iobuf oe:o:i:io a b c d e f g h i j +iopadmap -bits -inpad ibuf o:i -outpad obuf i:o -toutpad obuft oe:i:o -tinoutpad iobuf oe:o:i:io a b c d e f g h i j k opt_clean +hierarchy -check +check select -assert-count 1 a/t:ibuf select -assert-count 1 a/t:obuf @@ -140,6 +146,8 @@ select -assert-count 0 i/t:obuf select -assert-count 1 j/t:ibuf select -assert-count 1 j/t:obuf +select -assert-count 2 k/t:iobuf + # Check that \init attributes get moved from output buffer # to buffer input |