aboutsummaryrefslogtreecommitdiffstats
path: root/techlibs/common
diff options
context:
space:
mode:
Diffstat (limited to 'techlibs/common')
-rw-r--r--techlibs/common/Makefile.inc1
-rw-r--r--techlibs/common/cmp2lcu.v116
-rw-r--r--techlibs/common/cmp2lut.v8
-rw-r--r--techlibs/common/gen_fine_ffs.py238
-rw-r--r--techlibs/common/simcells.v86
-rw-r--r--techlibs/common/simlib.v2
-rw-r--r--techlibs/common/synth.cc6
7 files changed, 406 insertions, 51 deletions
diff --git a/techlibs/common/Makefile.inc b/techlibs/common/Makefile.inc
index d5e69a241..7b1e4b430 100644
--- a/techlibs/common/Makefile.inc
+++ b/techlibs/common/Makefile.inc
@@ -30,3 +30,4 @@ $(eval $(call add_share_file,share,techlibs/common/cmp2lut.v))
$(eval $(call add_share_file,share,techlibs/common/cells.lib))
$(eval $(call add_share_file,share,techlibs/common/mul2dsp.v))
$(eval $(call add_share_file,share,techlibs/common/abc9_model.v))
+$(eval $(call add_share_file,share,techlibs/common/cmp2lcu.v))
diff --git a/techlibs/common/cmp2lcu.v b/techlibs/common/cmp2lcu.v
new file mode 100644
index 000000000..b6f4aeed6
--- /dev/null
+++ b/techlibs/common/cmp2lcu.v
@@ -0,0 +1,116 @@
+// This pass performs an optimisation that decomposes wide arithmetic
+// comparisons into LUT-size chunks (as guided by the `LUT_WIDTH
+// macro) connected to a single lookahead-carry-unit $lcu cell,
+// which is typically mapped to dedicated (and fast) FPGA
+// carry-chains.
+(* techmap_celltype = "$lt $le $gt $ge" *)
+module _80_lcu_cmp_ (A, B, Y);
+
+parameter A_SIGNED = 0;
+parameter B_SIGNED = 0;
+parameter A_WIDTH = 0;
+parameter B_WIDTH = 0;
+parameter Y_WIDTH = 0;
+
+input [A_WIDTH-1:0] A;
+input [B_WIDTH-1:0] B;
+output [Y_WIDTH-1:0] Y;
+
+parameter _TECHMAP_CELLTYPE_ = "";
+
+generate
+ if (_TECHMAP_CELLTYPE_ == "" || `LUT_WIDTH < 2)
+ wire _TECHMAP_FAIL_ = 1;
+ else if (_TECHMAP_CELLTYPE_ == "$lt") begin
+ // Transform $lt into $gt by swapping A and B
+ $gt #(.A_SIGNED(B_SIGNED), .B_SIGNED(A_SIGNED), .A_WIDTH(B_WIDTH), .B_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) _TECHMAP_REPLACE_ (.A(B), .B(A), .Y(Y));
+ end
+ else if (_TECHMAP_CELLTYPE_ == "$le") begin
+ // Transform $le into $ge by swapping A and B
+ $ge #(.A_SIGNED(B_SIGNED), .B_SIGNED(A_SIGNED), .A_WIDTH(B_WIDTH), .B_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) _TECHMAP_REPLACE_ (.A(B), .B(A), .Y(Y));
+ end
+ else begin
+ // Perform sign extension on A and B
+ localparam WIDTH = A_WIDTH > B_WIDTH ? A_WIDTH : B_WIDTH;
+ wire [WIDTH-1:0] AA = {{(WIDTH-A_WIDTH){A_SIGNED ? A[A_WIDTH-1] : 1'b0}}, A};
+ wire [WIDTH-1:0] BB = {{(WIDTH-B_WIDTH){B_SIGNED ? B[B_WIDTH-1] : 1'b0}}, B};
+ // For $ge operation, start with the assumption that A and B are
+ // equal (propagating this equality if A and B turn out to be so)
+ if (_TECHMAP_CELLTYPE_ == "$ge")
+ localparam CI = 1'b1;
+ else
+ localparam CI = 1'b0;
+ $__CMP2LCU #(.AB_WIDTH(WIDTH), .AB_SIGNED(A_SIGNED && B_SIGNED), .LCU_WIDTH(1), .BUDGET(`LUT_WIDTH), .CI(CI))
+ _TECHMAP_REPLACE_ (.A(AA), .B(BB), .P(1'b1), .G(1'b0), .Y(Y));
+ end
+endgenerate
+endmodule
+
+module $__CMP2LCU (A, B, P, G, Y);
+
+parameter AB_WIDTH = 0;
+parameter AB_SIGNED = 0;
+parameter LCU_WIDTH = 1;
+parameter BUDGET = 0;
+parameter CI = 0;
+
+input [AB_WIDTH-1:0] A; // A from original $gt/$ge
+input [AB_WIDTH-1:0] B; // B from original $gt/$ge
+input [LCU_WIDTH-1:0] P; // P of $lcu
+input [LCU_WIDTH-1:0] G; // G of $lcu
+output Y;
+
+parameter [AB_WIDTH-1:0] _TECHMAP_CONSTMSK_A_ = 0;
+parameter [AB_WIDTH-1:0] _TECHMAP_CONSTMSK_B_ = 0;
+parameter [LCU_WIDTH-1:0] _TECHMAP_CONSTMSK_P_ = 0;
+
+generate
+ if (AB_WIDTH == 0) begin
+ wire [LCU_WIDTH-1:0] CO;
+ $lcu #(.WIDTH(LCU_WIDTH)) _TECHMAP_REPLACE_ (.P(P), .G(G), .CI(CI), .CO(CO));
+ assign Y = CO[LCU_WIDTH-1];
+ end
+ else begin
+ if (_TECHMAP_CONSTMSK_A_[AB_WIDTH-1:0] && _TECHMAP_CONSTMSK_B_[AB_WIDTH-1:0])
+ localparam COST = 0;
+ else if (_TECHMAP_CONSTMSK_A_[AB_WIDTH-1:0] || _TECHMAP_CONSTMSK_B_[AB_WIDTH-1:0])
+ localparam COST = 1;
+ else
+ localparam COST = 2;
+
+ if (BUDGET < COST)
+ $__CMP2LCU #(.AB_WIDTH(AB_WIDTH), .AB_SIGNED(AB_SIGNED), .LCU_WIDTH(LCU_WIDTH+1), .BUDGET(`LUT_WIDTH), .CI(CI))
+ _TECHMAP_REPLACE_ (.A(A), .B(B), .P({P, 1'b1}), .G({G, 1'b0}), .Y(Y));
+ else begin
+ wire PP, GG;
+ // Bit-wise equality (xnor) of A and B
+ assign PP = A[AB_WIDTH-1] ^~ B[AB_WIDTH-1];
+ if (AB_SIGNED)
+ assign GG = ~A[AB_WIDTH-1] & B[AB_WIDTH-1];
+ else if (_TECHMAP_CONSTMSK_P_[LCU_WIDTH-1]) // First compare for LUT if P (and G) is constant
+ assign GG = A[AB_WIDTH-1] & ~B[AB_WIDTH-1];
+ else
+ // Priority "encoder" that checks A[i] == 1'b1 && B[i] == 1'b0
+ // from MSB down, deferring to less significant bits if the
+ // MSBs are equal
+ assign GG = P[0] & (A[AB_WIDTH-1] & ~B[AB_WIDTH-1]);
+ if (LCU_WIDTH == 1) begin
+ // Propagate only if all pairs are equal
+ // (inconclusive evidence to say A >= B)
+ wire P_ = P[0] & PP;
+ // Generate if any comparisons call for it
+ wire G_ = G[0] | GG;
+ end
+ else begin
+ // Propagate only if all pairs are equal
+ // (inconclusive evidence to say A >= B)
+ wire [LCU_WIDTH-1:0] P_ = {P[LCU_WIDTH-1:1], P[0] & PP};
+ // Generate if any comparisons call for it
+ wire [LCU_WIDTH-1:0] G_ = {G[LCU_WIDTH-1:1], G[0] | GG};
+ end
+ $__CMP2LCU #(.AB_WIDTH(AB_WIDTH-1), .AB_SIGNED(1'b0), .LCU_WIDTH(LCU_WIDTH), .BUDGET(BUDGET-COST), .CI(CI))
+ _TECHMAP_REPLACE_ (.A(A[AB_WIDTH-2:0]), .B(B[AB_WIDTH-2:0]), .P(P_), .G(G_), .Y(Y));
+ end
+ end
+endgenerate
+endmodule
diff --git a/techlibs/common/cmp2lut.v b/techlibs/common/cmp2lut.v
index 1c8192b85..8ecd356cc 100644
--- a/techlibs/common/cmp2lut.v
+++ b/techlibs/common/cmp2lut.v
@@ -57,10 +57,6 @@ function automatic [(1 << `LUT_WIDTH)-1:0] gen_lut;
o_bit = (lhs > rhs);
if (operation == 3)
o_bit = (lhs >= rhs);
- if (operation == 4)
- o_bit = (lhs == rhs);
- if (operation == 5)
- o_bit = (lhs != rhs);
gen_lut = gen_lut | (o_bit << n);
end
end
@@ -75,10 +71,6 @@ generate
localparam operation = 2;
if (_TECHMAP_CELLTYPE_ == "$ge")
localparam operation = 3;
- if (_TECHMAP_CELLTYPE_ == "$eq")
- localparam operation = 4;
- if (_TECHMAP_CELLTYPE_ == "$ne")
- localparam operation = 5;
if (A_WIDTH > `LUT_WIDTH || B_WIDTH > `LUT_WIDTH || Y_WIDTH != 1)
wire _TECHMAP_FAIL_ = 1;
diff --git a/techlibs/common/gen_fine_ffs.py b/techlibs/common/gen_fine_ffs.py
new file mode 100644
index 000000000..0abe48f61
--- /dev/null
+++ b/techlibs/common/gen_fine_ffs.py
@@ -0,0 +1,238 @@
+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---|
+//-
+//- $_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..157e8d23b 100644
--- a/techlibs/common/simcells.v
+++ b/techlibs/common/simcells.v
@@ -456,23 +456,27 @@ 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
//- -----+---
-//- 0 0 | x
-//- 0 1 | 1
-//- 1 0 | 0
-//- 1 1 | y
+//- - 0 | 0
+//- 0 - | 1
+//- - - | q
//-
module \$_SR_NN_ (S, R, Q);
input S, R;
output reg Q;
-always @(negedge S, negedge R) begin
+always @* begin
if (R == 0)
Q <= 0;
else if (S == 0)
@@ -488,15 +492,14 @@ endmodule
//-
//- Truth table: S R | Q
//- -----+---
-//- 0 1 | x
-//- 0 0 | 1
-//- 1 1 | 0
-//- 1 0 | y
+//- - 1 | 0
+//- 0 - | 1
+//- - - | q
//-
module \$_SR_NP_ (S, R, Q);
input S, R;
output reg Q;
-always @(negedge S, posedge R) begin
+always @* begin
if (R == 1)
Q <= 0;
else if (S == 0)
@@ -512,15 +515,14 @@ endmodule
//-
//- Truth table: S R | Q
//- -----+---
-//- 1 0 | x
-//- 1 1 | 1
-//- 0 0 | 0
-//- 0 1 | y
+//- - 0 | 0
+//- 1 - | 1
+//- - - | q
//-
module \$_SR_PN_ (S, R, Q);
input S, R;
output reg Q;
-always @(posedge S, negedge R) begin
+always @* begin
if (R == 0)
Q <= 0;
else if (S == 1)
@@ -532,19 +534,18 @@ 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
//- -----+---
-//- 1 1 | x
-//- 1 0 | 1
-//- 0 1 | 0
-//- 0 0 | y
+//- - 1 | 0
+//- 1 - | 1
+//- - - | q
//-
module \$_SR_PP_ (S, R, Q);
input S, R;
output reg Q;
-always @(posedge S, posedge R) begin
+always @* begin
if (R == 1)
Q <= 0;
else if (S == 1)
@@ -871,7 +872,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 +953,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 +980,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 +1061,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 +1128,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 +1155,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 +1182,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 +1209,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 +1236,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 +1263,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 +1290,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 +1317,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 +1339,3 @@ always @* begin
Q <= D;
end
endmodule
-
diff --git a/techlibs/common/simlib.v b/techlibs/common/simlib.v
index 7845a3fed..2cdddeabb 100644
--- a/techlibs/common/simlib.v
+++ b/techlibs/common/simlib.v
@@ -1633,7 +1633,7 @@ wire [WIDTH-1:0] pos_clr = CLR_POLARITY ? CLR : ~CLR;
genvar i;
generate
for (i = 0; i < WIDTH; i = i+1) begin:bitslices
- always @(posedge pos_set[i], posedge pos_clr[i])
+ always @*
if (pos_clr[i])
Q[i] <= 0;
else if (pos_set[i])
diff --git a/techlibs/common/synth.cc b/techlibs/common/synth.cc
index e7a192c07..d6dffdd7f 100644
--- a/techlibs/common/synth.cc
+++ b/techlibs/common/synth.cc
@@ -225,9 +225,9 @@ struct SynthPass : public ScriptPass
run("peepopt");
run("opt_clean");
if (help_mode)
- run("techmap -map +/cmp2lut.v", " (if -lut)");
- else
- run(stringf("techmap -map +/cmp2lut.v -D LUT_WIDTH=%d", lut));
+ run("techmap -map +/cmp2lut.v -map +/cmp2lcu.v", " (if -lut)");
+ else if (lut)
+ run(stringf("techmap -map +/cmp2lut.v -map +/cmp2lcu.v -D LUT_WIDTH=%d", lut));
if (!noalumacc)
run("alumacc", " (unless -noalumacc)");
if (!noshare)