aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarcelina Koƛcielnicka <mwk@0x04.net>2020-05-18 18:15:03 +0200
committerMarcelina Koƛcielnicka <mwk@0x04.net>2020-05-19 01:42:40 +0200
commitaee439360bba642dcbffe5b803aa9a994b11d183 (patch)
treea5c15b4a6172ea3ff651f88174fff7d5269ad1c2
parent2d573a0ff680eb9f38358943fbf134f765ba1451 (diff)
downloadyosys-aee439360bba642dcbffe5b803aa9a994b11d183.tar.gz
yosys-aee439360bba642dcbffe5b803aa9a994b11d183.tar.bz2
yosys-aee439360bba642dcbffe5b803aa9a994b11d183.zip
Add force_downto and force_upto wire attributes.
Fixes #2058.
-rw-r--r--frontends/ast/genrtlil.cc2
-rw-r--r--frontends/ast/simplify.cc19
-rw-r--r--kernel/constids.inc2
-rw-r--r--techlibs/achronix/speedster22i/cells_arith.v6
-rw-r--r--techlibs/achronix/speedster22i/cells_map.v1
-rw-r--r--techlibs/anlogic/arith_map.v9
-rw-r--r--techlibs/anlogic/cells_map.v1
-rw-r--r--techlibs/common/adff2dff.v3
-rw-r--r--techlibs/common/cmp2lcu.v12
-rw-r--r--techlibs/common/cmp2lut.v3
-rw-r--r--techlibs/common/dff2ff.v2
-rw-r--r--techlibs/common/mul2dsp.v18
-rw-r--r--techlibs/common/techmap.v73
-rw-r--r--techlibs/coolrunner2/cells_counter_map.v1
-rw-r--r--techlibs/ecp5/arith_map.v10
-rw-r--r--techlibs/ecp5/cells_map.v1
-rw-r--r--techlibs/efinix/arith_map.v11
-rw-r--r--techlibs/efinix/cells_map.v1
-rw-r--r--techlibs/gowin/arith_map.v8
-rw-r--r--techlibs/gowin/cells_map.v1
-rw-r--r--techlibs/greenpak4/cells_map.v2
-rw-r--r--techlibs/ice40/arith_map.v8
-rw-r--r--techlibs/ice40/cells_map.v1
-rw-r--r--techlibs/intel/arria10gx/cells_arith.v6
-rw-r--r--techlibs/intel/arria10gx/cells_map.v1
-rw-r--r--techlibs/intel/cyclone10lp/cells_arith.v6
-rw-r--r--techlibs/intel/cyclone10lp/cells_map.v1
-rw-r--r--techlibs/intel/cycloneiv/cells_arith.v6
-rw-r--r--techlibs/intel/cycloneiv/cells_map.v1
-rw-r--r--techlibs/intel/cycloneive/arith_map.v6
-rw-r--r--techlibs/intel/cycloneive/cells_map.v1
-rw-r--r--techlibs/intel/cyclonev/cells_arith.v6
-rw-r--r--techlibs/intel/cyclonev/cells_map.v1
-rw-r--r--techlibs/intel/max10/cells_arith.v6
-rw-r--r--techlibs/intel/max10/cells_map.v1
-rw-r--r--techlibs/intel_alm/common/alm_map.v1
-rw-r--r--techlibs/intel_alm/common/arith_alm_map.v7
-rw-r--r--techlibs/sf2/cells_map.v1
-rw-r--r--techlibs/xilinx/arith_map.v23
-rw-r--r--techlibs/xilinx/cells_map.v6
-rw-r--r--techlibs/xilinx/lut_map.v1
-rw-r--r--techlibs/xilinx/mux_map.v3
-rw-r--r--tests/arch/xilinx/mux.ys6
43 files changed, 258 insertions, 27 deletions
diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc
index d4e9baa5f..cdc3adc9c 100644
--- a/frontends/ast/genrtlil.cc
+++ b/frontends/ast/genrtlil.cc
@@ -1055,7 +1055,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
if (!range_valid)
log_file_error(filename, location.first_line, "Signal `%s' with non-constant width!\n", str.c_str());
- if (!(range_left >= range_right || (range_left == -1 && range_right == 0)))
+ if (!(range_left + 1 >= range_right))
log_file_error(filename, location.first_line, "Signal `%s' with invalid width range %d!\n", str.c_str(), range_left - range_right + 1);
RTLIL::Wire *wire = current_module->addWire(str, range_left - range_right + 1);
diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc
index f629df387..3314819fb 100644
--- a/frontends/ast/simplify.cc
+++ b/frontends/ast/simplify.cc
@@ -1098,6 +1098,25 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
range_swapped = children[0]->range_swapped;
range_left = children[0]->range_left;
range_right = children[0]->range_right;
+ bool force_upto = false, force_downto = false;
+ if (attributes.count(ID::force_upto)) {
+ AstNode *val = attributes[ID::force_upto];
+ if (val->type != AST_CONSTANT)
+ log_file_error(filename, location.first_line, "Attribute `force_upto' with non-constant value!\n");
+ force_upto = val->asAttrConst().as_bool();
+ }
+ if (attributes.count(ID::force_downto)) {
+ AstNode *val = attributes[ID::force_downto];
+ if (val->type != AST_CONSTANT)
+ log_file_error(filename, location.first_line, "Attribute `force_downto' with non-constant value!\n");
+ force_downto = val->asAttrConst().as_bool();
+ }
+ if (force_upto && force_downto)
+ log_file_error(filename, location.first_line, "Attributes `force_downto' and `force_upto' cannot be both set!\n");
+ if ((force_upto && !range_swapped) || (force_downto && range_swapped)) {
+ std::swap(range_left, range_right);
+ range_swapped = force_upto;
+ }
}
} else {
if (!range_valid)
diff --git a/kernel/constids.inc b/kernel/constids.inc
index 345bfaee8..93c3a7609 100644
--- a/kernel/constids.inc
+++ b/kernel/constids.inc
@@ -79,6 +79,8 @@ X(equiv_merged)
X(equiv_region)
X(extract_order)
X(F)
+X(force_downto)
+X(force_upto)
X(fsm_encoding)
X(fsm_export)
X(FULL)
diff --git a/techlibs/achronix/speedster22i/cells_arith.v b/techlibs/achronix/speedster22i/cells_arith.v
index e2194cbd7..8529706a7 100644
--- a/techlibs/achronix/speedster22i/cells_arith.v
+++ b/techlibs/achronix/speedster22i/cells_arith.v
@@ -26,8 +26,11 @@ module _80_altera_max10_alu (A, B, CI, BI, X, Y, CO);
parameter B_WIDTH = 1;
parameter Y_WIDTH = 1;
+ (* force_downto *)
input [A_WIDTH-1:0] A;
+ (* force_downto *)
input [B_WIDTH-1:0] B;
+ (* force_downto *)
output [Y_WIDTH-1:0] X, Y;
input CI, BI;
@@ -36,11 +39,14 @@ module _80_altera_max10_alu (A, B, CI, BI, X, Y, CO);
wire _TECHMAP_FAIL_ = Y_WIDTH <= 4;
+ (* force_downto *)
wire [Y_WIDTH-1:0] A_buf, B_buf;
\$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf));
\$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf));
+ (* force_downto *)
wire [Y_WIDTH-1:0] AA = A_buf;
+ (* force_downto *)
wire [Y_WIDTH-1:0] BB = BI ? ~B_buf : B_buf;
//wire [Y_WIDTH:0] C = {CO, CI};
wire [Y_WIDTH+1:0] COx;
diff --git a/techlibs/achronix/speedster22i/cells_map.v b/techlibs/achronix/speedster22i/cells_map.v
index 9f647cbef..a19e53f49 100644
--- a/techlibs/achronix/speedster22i/cells_map.v
+++ b/techlibs/achronix/speedster22i/cells_map.v
@@ -38,6 +38,7 @@ endmodule
module \$lut (A, Y);
parameter WIDTH = 0;
parameter LUT = 0;
+ (* force_downto *)
input [WIDTH-1:0] A;
output Y;
generate
diff --git a/techlibs/anlogic/arith_map.v b/techlibs/anlogic/arith_map.v
index 1186543da..23e190bcb 100644
--- a/techlibs/anlogic/arith_map.v
+++ b/techlibs/anlogic/arith_map.v
@@ -26,24 +26,33 @@ module _80_anlogic_alu (A, B, CI, BI, X, Y, CO);
parameter B_WIDTH = 1;
parameter Y_WIDTH = 1;
+ (* force_downto *)
input [A_WIDTH-1:0] A;
+ (* force_downto *)
input [B_WIDTH-1:0] B;
+ (* force_downto *)
output [Y_WIDTH-1:0] X, Y;
input CI, BI;
+ (* force_downto *)
output [Y_WIDTH-1:0] CO;
wire CIx;
+ (* force_downto *)
wire [Y_WIDTH-1:0] COx;
wire _TECHMAP_FAIL_ = Y_WIDTH <= 2;
+ (* force_downto *)
wire [Y_WIDTH-1:0] A_buf, B_buf;
\$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf));
\$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf));
+ (* force_downto *)
wire [Y_WIDTH-1:0] AA = A_buf;
+ (* force_downto *)
wire [Y_WIDTH-1:0] BB = BI ? ~B_buf : B_buf;
+ (* force_downto *)
wire [Y_WIDTH-1:0] C = { COx, CIx };
wire dummy;
diff --git a/techlibs/anlogic/cells_map.v b/techlibs/anlogic/cells_map.v
index 8ac087d9d..0bcea9856 100644
--- a/techlibs/anlogic/cells_map.v
+++ b/techlibs/anlogic/cells_map.v
@@ -32,6 +32,7 @@ module \$lut (A, Y);
parameter WIDTH = 0;
parameter LUT = 0;
+ (* force_downto *)
input [WIDTH-1:0] A;
output Y;
diff --git a/techlibs/common/adff2dff.v b/techlibs/common/adff2dff.v
index 86744d415..eca0110eb 100644
--- a/techlibs/common/adff2dff.v
+++ b/techlibs/common/adff2dff.v
@@ -6,8 +6,11 @@ module adff2dff (CLK, ARST, D, Q);
parameter ARST_VALUE = 0;
input CLK, ARST;
+ (* force_downto *)
input [WIDTH-1:0] D;
+ (* force_downto *)
output reg [WIDTH-1:0] Q;
+ (* force_downto *)
wire reg [WIDTH-1:0] NEXT_Q;
wire [1023:0] _TECHMAP_DO_ = "proc;;";
diff --git a/techlibs/common/cmp2lcu.v b/techlibs/common/cmp2lcu.v
index e42f346d1..a221727e7 100644
--- a/techlibs/common/cmp2lcu.v
+++ b/techlibs/common/cmp2lcu.v
@@ -12,8 +12,11 @@ parameter A_WIDTH = 0;
parameter B_WIDTH = 0;
parameter Y_WIDTH = 0;
+(* force_downto *)
input [A_WIDTH-1:0] A;
+(* force_downto *)
input [B_WIDTH-1:0] B;
+(* force_downto *)
output [Y_WIDTH-1:0] Y;
parameter _TECHMAP_CELLTYPE_ = "";
@@ -32,7 +35,9 @@ generate
else begin
// Perform sign extension on A and B
localparam WIDTH = A_WIDTH > B_WIDTH ? A_WIDTH : B_WIDTH;
+ (* force_downto *)
wire [WIDTH-1:0] AA = {{(WIDTH-A_WIDTH){A_SIGNED ? A[A_WIDTH-1] : 1'b0}}, A};
+ (* force_downto *)
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)
@@ -54,9 +59,13 @@ parameter LCU_WIDTH = 1;
parameter BUDGET = 0;
parameter CI = 0;
+(* force_downto *)
input [AB_WIDTH-1:0] A; // A from original $gt/$ge
+(* force_downto *)
input [AB_WIDTH-1:0] B; // B from original $gt/$ge
+(* force_downto *)
input [LCU_WIDTH-1:0] P; // P of $lcu
+(* force_downto *)
input [LCU_WIDTH-1:0] G; // G of $lcu
output Y;
@@ -66,6 +75,7 @@ parameter [LCU_WIDTH-1:0] _TECHMAP_CONSTMSK_P_ = 0;
generate
if (AB_WIDTH == 0) begin
+ (* force_downto *)
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];
@@ -104,8 +114,10 @@ generate
else begin
// Propagate only if all pairs are equal
// (inconclusive evidence to say A >= B)
+ (* force_downto *)
wire [LCU_WIDTH-1:0] P_ = {P[LCU_WIDTH-1:1], P[0] & PP};
// Generate if any comparisons call for it
+ (* force_downto *)
wire [LCU_WIDTH-1:0] G_ = {G[LCU_WIDTH-1:1], G[0] | GG};
end
if (AB_WIDTH == 1)
diff --git a/techlibs/common/cmp2lut.v b/techlibs/common/cmp2lut.v
index 8ecd356cc..ec8f98e8d 100644
--- a/techlibs/common/cmp2lut.v
+++ b/techlibs/common/cmp2lut.v
@@ -16,8 +16,11 @@ parameter A_WIDTH = 0;
parameter B_WIDTH = 0;
parameter Y_WIDTH = 0;
+(* force_downto *)
input [A_WIDTH-1:0] A;
+(* force_downto *)
input [B_WIDTH-1:0] B;
+(* force_downto *)
output [Y_WIDTH-1:0] Y;
parameter _TECHMAP_CELLTYPE_ = "";
diff --git a/techlibs/common/dff2ff.v b/techlibs/common/dff2ff.v
index 2dc4d20d3..33a79ffff 100644
--- a/techlibs/common/dff2ff.v
+++ b/techlibs/common/dff2ff.v
@@ -4,7 +4,9 @@ module dff2ff (CLK, D, Q);
parameter CLK_POLARITY = 1;
input CLK;
+ (* force_downto *)
input [WIDTH-1:0] D;
+ (* force_downto *)
output reg [WIDTH-1:0] Q;
wire [1023:0] _TECHMAP_DO_ = "proc;;";
diff --git a/techlibs/common/mul2dsp.v b/techlibs/common/mul2dsp.v
index 4cabb4453..bec47d01f 100644
--- a/techlibs/common/mul2dsp.v
+++ b/techlibs/common/mul2dsp.v
@@ -57,8 +57,11 @@ module _80_mul (A, B, Y);
parameter B_WIDTH = 1;
parameter Y_WIDTH = 1;
+ (* force_downto *)
input [A_WIDTH-1:0] A;
+ (* force_downto *)
input [B_WIDTH-1:0] B;
+ (* force_downto *)
output [Y_WIDTH-1:0] Y;
parameter _TECHMAP_CELLTYPE_ = "";
@@ -119,13 +122,19 @@ module _80_mul (A, B, Y);
localparam last_A_WIDTH = A_WIDTH-n*(`DSP_A_MAXWIDTH_PARTIAL-sign_headroom);
localparam last_Y_WIDTH = B_WIDTH+last_A_WIDTH;
if (A_SIGNED && B_SIGNED) begin
+ (* force_downto *)
wire signed [partial_Y_WIDTH-1:0] partial [n-1:0];
+ (* force_downto *)
wire signed [last_Y_WIDTH-1:0] last_partial;
+ (* force_downto *)
wire signed [Y_WIDTH-1:0] partial_sum [n:0];
end
else begin
+ (* force_downto *)
wire [partial_Y_WIDTH-1:0] partial [n-1:0];
+ (* force_downto *)
wire [last_Y_WIDTH-1:0] last_partial;
+ (* force_downto *)
wire [Y_WIDTH-1:0] partial_sum [n:0];
end
@@ -170,13 +179,19 @@ module _80_mul (A, B, Y);
localparam last_B_WIDTH = B_WIDTH-n*(`DSP_B_MAXWIDTH_PARTIAL-sign_headroom);
localparam last_Y_WIDTH = A_WIDTH+last_B_WIDTH;
if (A_SIGNED && B_SIGNED) begin
+ (* force_downto *)
wire signed [partial_Y_WIDTH-1:0] partial [n-1:0];
+ (* force_downto *)
wire signed [last_Y_WIDTH-1:0] last_partial;
+ (* force_downto *)
wire signed [Y_WIDTH-1:0] partial_sum [n:0];
end
else begin
+ (* force_downto *)
wire [partial_Y_WIDTH-1:0] partial [n-1:0];
+ (* force_downto *)
wire [last_Y_WIDTH-1:0] last_partial;
+ (* force_downto *)
wire [Y_WIDTH-1:0] partial_sum [n:0];
end
@@ -249,8 +264,11 @@ module _90_soft_mul (A, B, Y);
parameter B_WIDTH = 1;
parameter Y_WIDTH = 1;
+ (* force_downto *)
input [A_WIDTH-1:0] A;
+ (* force_downto *)
input [B_WIDTH-1:0] B;
+ (* force_downto *)
output [Y_WIDTH-1:0] Y;
// Indirection necessary since mapping
diff --git a/techlibs/common/techmap.v b/techlibs/common/techmap.v
index 225cff449..c1efc378b 100644
--- a/techlibs/common/techmap.v
+++ b/techlibs/common/techmap.v
@@ -85,8 +85,11 @@ module _90_shift_ops_shr_shl_sshl_sshr (A, B, Y);
localparam shift_left = _TECHMAP_CELLTYPE_ == "$shl" || _TECHMAP_CELLTYPE_ == "$sshl";
localparam sign_extend = A_SIGNED && _TECHMAP_CELLTYPE_ == "$sshr";
+ (* force_downto *)
input [A_WIDTH-1:0] A;
+ (* force_downto *)
input [B_WIDTH-1:0] B;
+ (* force_downto *)
output [Y_WIDTH-1:0] Y;
localparam WIDTH = `MAX(A_WIDTH, Y_WIDTH);
@@ -96,6 +99,7 @@ module _90_shift_ops_shr_shl_sshl_sshr (A, B, Y);
wire [1023:0] _TECHMAP_DO_01_ = "RECURSION; CONSTMAP; opt_muxtree; opt_expr -mux_undef -mux_bool -fine;;;";
integer i;
+ (* force_downto *)
reg [WIDTH-1:0] buffer;
reg overflow;
@@ -125,8 +129,11 @@ module _90_shift_shiftx (A, B, Y);
parameter B_WIDTH = 1;
parameter Y_WIDTH = 1;
+ (* force_downto *)
input [A_WIDTH-1:0] A;
+ (* force_downto *)
input [B_WIDTH-1:0] B;
+ (* force_downto *)
output [Y_WIDTH-1:0] Y;
parameter _TECHMAP_CELLTYPE_ = "";
@@ -173,6 +180,7 @@ module _90_shift_shiftx (A, B, Y);
wire [1023:0] _TECHMAP_DO_01_ = "CONSTMAP; opt_muxtree; opt_expr -mux_undef -mux_bool -fine;;;";
integer i;
+ (* force_downto *)
reg [WIDTH-1:0] buffer;
reg overflow;
@@ -216,9 +224,12 @@ endmodule
module _90_fa (A, B, C, X, Y);
parameter WIDTH = 1;
+ (* force_downto *)
input [WIDTH-1:0] A, B, C;
+ (* force_downto *)
output [WIDTH-1:0] X, Y;
+ (* force_downto *)
wire [WIDTH-1:0] t1, t2, t3;
assign t1 = A ^ B, t2 = A & B, t3 = C & t1;
@@ -229,12 +240,15 @@ endmodule
module _90_lcu (P, G, CI, CO);
parameter WIDTH = 2;
+ (* force_downto *)
input [WIDTH-1:0] P, G;
input CI;
+ (* force_downto *)
output [WIDTH-1:0] CO;
integer i, j;
+ (* force_downto *)
reg [WIDTH-1:0] p, g;
wire [1023:0] _TECHMAP_DO_ = "proc; opt -fast";
@@ -278,38 +292,26 @@ module _90_alu (A, B, CI, BI, X, Y, CO);
parameter B_WIDTH = 1;
parameter Y_WIDTH = 1;
+ (* force_downto *)
input [A_WIDTH-1:0] A;
+ (* force_downto *)
input [B_WIDTH-1:0] B;
+ (* force_downto *)
output [Y_WIDTH-1:0] X, Y;
input CI, BI;
+ (* force_downto *)
output [Y_WIDTH-1:0] CO;
- wire [Y_WIDTH-1:0] AA, BB;
+ (* force_downto *)
+ wire [Y_WIDTH-1:0] AA = A_buf;
+ (* force_downto *)
wire [Y_WIDTH-1:0] BB = BI ? ~B_buf : B_buf;
- if (A_WIDTH == 0) begin
- wire [Y_WIDTH-1:0] B_buf;
- \$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf));
-
- assign AA = {Y_WIDTH{1'b0}};
- assign BB = BI ? ~B_buf : B_buf;
- end
- else if (B_WIDTH == 0) begin
- wire [Y_WIDTH-1:0] A_buf;
- \$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf));
-
- assign AA = A_buf;
- assign BB = {Y_WIDTH{BI ? 1'b0 : 1'b1}};
- end
- else begin
- wire [Y_WIDTH-1:0] A_buf, B_buf;
- \$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf));
- \$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf));
-
- assign AA = A_buf;
- assign BB = BI ? ~B_buf : B_buf;
- end
+ (* force_downto *)
+ wire [Y_WIDTH-1:0] A_buf, B_buf;
+ \$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf));
+ \$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf));
\$lcu #(.WIDTH(Y_WIDTH)) lcu (.P(X), .G(AA & BB), .CI(CI), .CO(CO));
@@ -335,15 +337,19 @@ endmodule
module \$__div_mod_u (A, B, Y, R);
parameter WIDTH = 1;
+ (* force_downto *)
input [WIDTH-1:0] A, B;
+ (* force_downto *)
output [WIDTH-1:0] Y, R;
+ (* force_downto *)
wire [WIDTH*WIDTH-1:0] chaindata;
assign R = chaindata[WIDTH*WIDTH-1:WIDTH*(WIDTH-1)];
genvar i;
generate begin
for (i = 0; i < WIDTH; i=i+1) begin:stage
+ (* force_downto *)
wire [WIDTH-1:0] stage_in;
if (i == 0) begin:cp
@@ -369,14 +375,19 @@ module \$__div_mod (A, B, Y, R);
A_WIDTH >= B_WIDTH && A_WIDTH >= Y_WIDTH ? A_WIDTH :
B_WIDTH >= A_WIDTH && B_WIDTH >= Y_WIDTH ? B_WIDTH : Y_WIDTH;
+ (* force_downto *)
input [A_WIDTH-1:0] A;
+ (* force_downto *)
input [B_WIDTH-1:0] B;
+ (* force_downto *)
output [Y_WIDTH-1:0] Y, R;
+ (* force_downto *)
wire [WIDTH-1:0] A_buf, B_buf;
\$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(WIDTH)) A_conv (.A(A), .Y(A_buf));
\$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(WIDTH)) B_conv (.A(B), .Y(B_buf));
+ (* force_downto *)
wire [WIDTH-1:0] A_buf_u, B_buf_u, Y_u, R_u;
assign A_buf_u = A_SIGNED && A_buf[WIDTH-1] ? -A_buf : A_buf;
assign B_buf_u = B_SIGNED && B_buf[WIDTH-1] ? -B_buf : B_buf;
@@ -402,8 +413,11 @@ module _90_div (A, B, Y);
parameter B_WIDTH = 1;
parameter Y_WIDTH = 1;
+ (* force_downto *)
input [A_WIDTH-1:0] A;
+ (* force_downto *)
input [B_WIDTH-1:0] B;
+ (* force_downto *)
output [Y_WIDTH-1:0] Y;
\$__div_mod #(
@@ -427,8 +441,11 @@ module _90_mod (A, B, Y);
parameter B_WIDTH = 1;
parameter Y_WIDTH = 1;
+ (* force_downto *)
input [A_WIDTH-1:0] A;
+ (* force_downto *)
input [B_WIDTH-1:0] B;
+ (* force_downto *)
output [Y_WIDTH-1:0] Y;
\$__div_mod #(
@@ -457,8 +474,11 @@ module _90_pow (A, B, Y);
parameter B_WIDTH = 1;
parameter Y_WIDTH = 1;
+ (* force_downto *)
input [A_WIDTH-1:0] A;
+ (* force_downto *)
input [B_WIDTH-1:0] B;
+ (* force_downto *)
output [Y_WIDTH-1:0] Y;
wire _TECHMAP_FAIL_ = 1;
@@ -474,20 +494,27 @@ module _90_pmux (A, B, S, Y);
parameter WIDTH = 1;
parameter S_WIDTH = 1;
+ (* force_downto *)
input [WIDTH-1:0] A;
+ (* force_downto *)
input [WIDTH*S_WIDTH-1:0] B;
+ (* force_downto *)
input [S_WIDTH-1:0] S;
+ (* force_downto *)
output [WIDTH-1:0] Y;
+ (* force_downto *)
wire [WIDTH-1:0] Y_B;
genvar i, j;
generate
+ (* force_downto *)
wire [WIDTH*S_WIDTH-1:0] B_AND_S;
for (i = 0; i < S_WIDTH; i = i + 1) begin:B_AND
assign B_AND_S[WIDTH*(i+1)-1:WIDTH*i] = B[WIDTH*(i+1)-1:WIDTH*i] & {WIDTH{S[i]}};
end:B_AND
for (i = 0; i < WIDTH; i = i + 1) begin:B_OR
+ (* force_downto *)
wire [S_WIDTH-1:0] B_AND_BITS;
for (j = 0; j < S_WIDTH; j = j + 1) begin:B_AND_BITS_COLLECT
assign B_AND_BITS[j] = B_AND_S[WIDTH*j+i];
diff --git a/techlibs/coolrunner2/cells_counter_map.v b/techlibs/coolrunner2/cells_counter_map.v
index b474fa522..f9c44c80f 100644
--- a/techlibs/coolrunner2/cells_counter_map.v
+++ b/techlibs/coolrunner2/cells_counter_map.v
@@ -3,6 +3,7 @@ module \$__COUNT_ (CE, CLK, OUT, POUT, RST, UP);
input wire CE;
input wire CLK;
output wire OUT;
+ (* force_downto *)
output wire[WIDTH-1:0] POUT;
input wire RST;
input wire UP;
diff --git a/techlibs/ecp5/arith_map.v b/techlibs/ecp5/arith_map.v
index 17bde0497..ffd42469c 100644
--- a/techlibs/ecp5/arith_map.v
+++ b/techlibs/ecp5/arith_map.v
@@ -26,15 +26,20 @@ module _80_ecp5_alu (A, B, CI, BI, X, Y, CO);
parameter B_WIDTH = 1;
parameter Y_WIDTH = 1;
+ (* force_downto *)
input [A_WIDTH-1:0] A;
+ (* force_downto *)
input [B_WIDTH-1:0] B;
+ (* force_downto *)
output [Y_WIDTH-1:0] X, Y;
input CI, BI;
+ (* force_downto *)
output [Y_WIDTH-1:0] CO;
wire _TECHMAP_FAIL_ = Y_WIDTH <= 4;
+ (* force_downto *)
wire [Y_WIDTH-1:0] A_buf, B_buf;
\$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf));
\$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf));
@@ -48,10 +53,15 @@ module _80_ecp5_alu (A, B, CI, BI, X, Y, CO);
localparam Y_WIDTH2 = round_up2(Y_WIDTH);
+ (* force_downto *)
wire [Y_WIDTH2-1:0] AA = A_buf;
+ (* force_downto *)
wire [Y_WIDTH2-1:0] BB = BI ? ~B_buf : B_buf;
+ (* force_downto *)
wire [Y_WIDTH2-1:0] BX = B_buf;
+ (* force_downto *)
wire [Y_WIDTH2-1:0] C = {CO, CI};
+ (* force_downto *)
wire [Y_WIDTH2-1:0] FCO, Y1;
genvar i;
diff --git a/techlibs/ecp5/cells_map.v b/techlibs/ecp5/cells_map.v
index c031703a9..e19ac9ab9 100644
--- a/techlibs/ecp5/cells_map.v
+++ b/techlibs/ecp5/cells_map.v
@@ -70,6 +70,7 @@ module \$lut (A, Y);
parameter WIDTH = 0;
parameter LUT = 0;
+ (* force_downto *)
input [WIDTH-1:0] A;
output Y;
diff --git a/techlibs/efinix/arith_map.v b/techlibs/efinix/arith_map.v
index 178f57bc5..4dac360b9 100644
--- a/techlibs/efinix/arith_map.v
+++ b/techlibs/efinix/arith_map.v
@@ -26,24 +26,33 @@ module _80_efinix_alu (A, B, CI, BI, X, Y, CO);
parameter B_WIDTH = 1;
parameter Y_WIDTH = 1;
+ (* force_downto *)
input [A_WIDTH-1:0] A;
+ (* force_downto *)
input [B_WIDTH-1:0] B;
+ (* force_downto *)
output [Y_WIDTH-1:0] X, Y;
input CI, BI;
+ (* force_downto *)
output [Y_WIDTH-1:0] CO;
wire CIx;
+ (* force_downto *)
wire [Y_WIDTH-1:0] COx;
wire _TECHMAP_FAIL_ = Y_WIDTH <= 2;
+ (* force_downto *)
wire [Y_WIDTH-1:0] A_buf, B_buf;
\$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf));
\$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf));
+ (* force_downto *)
wire [Y_WIDTH-1:0] AA = A_buf;
+ (* force_downto *)
wire [Y_WIDTH-1:0] BB = BI ? ~B_buf : B_buf;
+ (* force_downto *)
wire [Y_WIDTH-1:0] C = { COx, CIx };
EFX_ADD #(.I0_POLARITY(1'b1),.I1_POLARITY(1'b1))
@@ -76,4 +85,4 @@ module _80_efinix_alu (A, B, CI, BI, X, Y, CO);
/* End implementation */
assign X = AA ^ BB;
-endmodule \ No newline at end of file
+endmodule
diff --git a/techlibs/efinix/cells_map.v b/techlibs/efinix/cells_map.v
index 3ecec3bac..1090f8b27 100644
--- a/techlibs/efinix/cells_map.v
+++ b/techlibs/efinix/cells_map.v
@@ -34,6 +34,7 @@ module \$lut (A, Y);
parameter WIDTH = 0;
parameter LUT = 0;
+ (* force_downto *)
input [WIDTH-1:0] A;
output Y;
diff --git a/techlibs/gowin/arith_map.v b/techlibs/gowin/arith_map.v
index b6f9e8c38..42aaba870 100644
--- a/techlibs/gowin/arith_map.v
+++ b/techlibs/gowin/arith_map.v
@@ -26,21 +26,29 @@ module _80_gw1n_alu(A, B, CI, BI, X, Y, CO);
parameter B_WIDTH = 1;
parameter Y_WIDTH = 1;
+ (* force_downto *)
input [A_WIDTH-1:0] A;
+ (* force_downto *)
input [B_WIDTH-1:0] B;
+ (* force_downto *)
output [Y_WIDTH-1:0] X, Y;
input CI, BI;
+ (* force_downto *)
output [Y_WIDTH-1:0] CO;
wire _TECHMAP_FAIL_ = Y_WIDTH <= 2;
+ (* force_downto *)
wire [Y_WIDTH-1:0] A_buf, B_buf;
\$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf));
\$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf));
+ (* force_downto *)
wire [Y_WIDTH-1:0] AA = A_buf;
+ (* force_downto *)
wire [Y_WIDTH-1:0] BB = B_buf;
+ (* force_downto *)
wire [Y_WIDTH-1:0] C = {CO, CI};
genvar i;
diff --git a/techlibs/gowin/cells_map.v b/techlibs/gowin/cells_map.v
index aee912256..b44350616 100644
--- a/techlibs/gowin/cells_map.v
+++ b/techlibs/gowin/cells_map.v
@@ -232,6 +232,7 @@ module \$lut (A, Y);
parameter WIDTH = 0;
parameter LUT = 0;
+ (* force_downto *)
input [WIDTH-1:0] A;
output Y;
diff --git a/techlibs/greenpak4/cells_map.v b/techlibs/greenpak4/cells_map.v
index 51c85183d..316be3f73 100644
--- a/techlibs/greenpak4/cells_map.v
+++ b/techlibs/greenpak4/cells_map.v
@@ -115,6 +115,7 @@ module \$lut (A, Y);
parameter WIDTH = 0;
parameter LUT = 0;
+ (* force_downto *)
input [WIDTH-1:0] A;
output Y;
@@ -150,6 +151,7 @@ module \$__COUNT_ (CE, CLK, OUT, POUT, RST, UP);
input wire CE;
input wire CLK;
output reg OUT;
+ (* force_downto *)
output reg[WIDTH-1:0] POUT;
input wire RST;
input wire UP;
diff --git a/techlibs/ice40/arith_map.v b/techlibs/ice40/arith_map.v
index ed4140e44..3950e882b 100644
--- a/techlibs/ice40/arith_map.v
+++ b/techlibs/ice40/arith_map.v
@@ -25,21 +25,29 @@ module _80_ice40_alu (A, B, CI, BI, X, Y, CO);
parameter B_WIDTH = 1;
parameter Y_WIDTH = 1;
+ (* force_downto *)
input [A_WIDTH-1:0] A;
+ (* force_downto *)
input [B_WIDTH-1:0] B;
+ (* force_downto *)
output [Y_WIDTH-1:0] X, Y;
input CI, BI;
+ (* force_downto *)
output [Y_WIDTH-1:0] CO;
wire _TECHMAP_FAIL_ = Y_WIDTH <= 2;
+ (* force_downto *)
wire [Y_WIDTH-1:0] A_buf, B_buf;
\$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf));
\$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf));
+ (* force_downto *)
wire [Y_WIDTH-1:0] AA = A_buf;
+ (* force_downto *)
wire [Y_WIDTH-1:0] BB = BI ? ~B_buf : B_buf;
+ (* force_downto *)
wire [Y_WIDTH-1:0] C = {CO, CI};
genvar i;
diff --git a/techlibs/ice40/cells_map.v b/techlibs/ice40/cells_map.v
index e9ccca239..7e5c07879 100644
--- a/techlibs/ice40/cells_map.v
+++ b/techlibs/ice40/cells_map.v
@@ -2,6 +2,7 @@ module \$lut (A, Y);
parameter WIDTH = 0;
parameter LUT = 0;
+ (* force_downto *)
input [WIDTH-1:0] A;
output Y;
diff --git a/techlibs/intel/arria10gx/cells_arith.v b/techlibs/intel/arria10gx/cells_arith.v
index 89fb4561f..6a52a0f95 100644
--- a/techlibs/intel/arria10gx/cells_arith.v
+++ b/techlibs/intel/arria10gx/cells_arith.v
@@ -26,8 +26,11 @@ module _80_altera_a10gx_alu (A, B, CI, BI, X, Y, CO);
parameter B_WIDTH = 1;
parameter Y_WIDTH = 1;
+ (* force_downto *)
input [A_WIDTH-1:0] A;
+ (* force_downto *)
input [B_WIDTH-1:0] B;
+ (* force_downto *)
output [Y_WIDTH-1:0] X, Y;
input CI, BI;
@@ -36,11 +39,14 @@ module _80_altera_a10gx_alu (A, B, CI, BI, X, Y, CO);
wire _TECHMAP_FAIL_ = Y_WIDTH <= 4;
+ (* force_downto *)
wire [Y_WIDTH-1:0] A_buf, B_buf;
\$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf));
\$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf));
+ (* force_downto *)
wire [Y_WIDTH-1:0] AA = A_buf;
+ (* force_downto *)
wire [Y_WIDTH-1:0] BB = BI ? ~B_buf : B_buf;
//wire [Y_WIDTH:0] C = {CO, CI};
wire [Y_WIDTH+1:0] COx;
diff --git a/techlibs/intel/arria10gx/cells_map.v b/techlibs/intel/arria10gx/cells_map.v
index 1430e8551..83f5881da 100644
--- a/techlibs/intel/arria10gx/cells_map.v
+++ b/techlibs/intel/arria10gx/cells_map.v
@@ -30,6 +30,7 @@ endmodule
module \$lut (A, Y);
parameter WIDTH = 0;
parameter LUT = 0;
+ (* force_downto *)
input [WIDTH-1:0] A;
output Y;
generate
diff --git a/techlibs/intel/cyclone10lp/cells_arith.v b/techlibs/intel/cyclone10lp/cells_arith.v
index 5ae8d6cea..d8c46e865 100644
--- a/techlibs/intel/cyclone10lp/cells_arith.v
+++ b/techlibs/intel/cyclone10lp/cells_arith.v
@@ -26,8 +26,11 @@ module _80_altera_a10gx_alu (A, B, CI, BI, X, Y, CO);
parameter B_WIDTH = 1;
parameter Y_WIDTH = 1;
+ (* force_downto *)
input [A_WIDTH-1:0] A;
+ (* force_downto *)
input [B_WIDTH-1:0] B;
+ (* force_downto *)
output [Y_WIDTH-1:0] X, Y;
input CI, BI;
@@ -36,11 +39,14 @@ module _80_altera_a10gx_alu (A, B, CI, BI, X, Y, CO);
wire _TECHMAP_FAIL_ = Y_WIDTH <= 4;
+ (* force_downto *)
wire [Y_WIDTH-1:0] A_buf, B_buf;
\$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf));
\$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf));
+ (* force_downto *)
wire [Y_WIDTH-1:0] AA = A_buf;
+ (* force_downto *)
wire [Y_WIDTH-1:0] BB = BI ? ~B_buf : B_buf;
//wire [Y_WIDTH:0] C = {CO, CI};
wire [Y_WIDTH+1:0] COx;
diff --git a/techlibs/intel/cyclone10lp/cells_map.v b/techlibs/intel/cyclone10lp/cells_map.v
index c2f6f403c..2a80ea678 100644
--- a/techlibs/intel/cyclone10lp/cells_map.v
+++ b/techlibs/intel/cyclone10lp/cells_map.v
@@ -71,6 +71,7 @@ endmodule
module \$lut (A, Y);
parameter WIDTH = 0;
parameter LUT = 0;
+ (* force_downto *)
input [WIDTH-1:0] A;
output Y;
generate
diff --git a/techlibs/intel/cycloneiv/cells_arith.v b/techlibs/intel/cycloneiv/cells_arith.v
index 010a4b5da..f7bc3cd65 100644
--- a/techlibs/intel/cycloneiv/cells_arith.v
+++ b/techlibs/intel/cycloneiv/cells_arith.v
@@ -70,8 +70,11 @@ module _80_cycloneiv_alu (A, B, CI, BI, X, Y, CO);
parameter B_WIDTH = 1;
parameter Y_WIDTH = 1;
+ (* force_downto *)
input [A_WIDTH-1:0] A;
+ (* force_downto *)
input [B_WIDTH-1:0] B;
+ (* force_downto *)
output [Y_WIDTH-1:0] X, Y;
input CI, BI;
@@ -79,11 +82,14 @@ module _80_cycloneiv_alu (A, B, CI, BI, X, Y, CO);
wire _TECHMAP_FAIL_ = Y_WIDTH < 6;
+ (* force_downto *)
wire [Y_WIDTH-1:0] A_buf, B_buf;
\$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf));
\$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf));
+ (* force_downto *)
wire [Y_WIDTH-1:0] AA = A_buf;
+ (* force_downto *)
wire [Y_WIDTH-1:0] BB = BI ? ~B_buf : B_buf;
wire [Y_WIDTH:0] C = {CO, CI};
diff --git a/techlibs/intel/cycloneiv/cells_map.v b/techlibs/intel/cycloneiv/cells_map.v
index 191488430..9d8a5a2b7 100644
--- a/techlibs/intel/cycloneiv/cells_map.v
+++ b/techlibs/intel/cycloneiv/cells_map.v
@@ -71,6 +71,7 @@ endmodule
module \$lut (A, Y);
parameter WIDTH = 0;
parameter LUT = 0;
+ (* force_downto *)
input [WIDTH-1:0] A;
output Y;
generate
diff --git a/techlibs/intel/cycloneive/arith_map.v b/techlibs/intel/cycloneive/arith_map.v
index 49e36aa25..a755e10db 100644
--- a/techlibs/intel/cycloneive/arith_map.v
+++ b/techlibs/intel/cycloneive/arith_map.v
@@ -66,8 +66,11 @@ module _80_cycloneive_alu (A, B, CI, BI, X, Y, CO);
parameter B_WIDTH = 1;
parameter Y_WIDTH = 1;
+ (* force_downto *)
input [A_WIDTH-1:0] A;
+ (* force_downto *)
input [B_WIDTH-1:0] B;
+ (* force_downto *)
output [Y_WIDTH-1:0] X, Y;
input CI, BI;
@@ -75,11 +78,14 @@ module _80_cycloneive_alu (A, B, CI, BI, X, Y, CO);
wire _TECHMAP_FAIL_ = Y_WIDTH < 5;
+ (* force_downto *)
wire [Y_WIDTH-1:0] A_buf, B_buf;
\$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf));
\$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf));
+ (* force_downto *)
wire [Y_WIDTH-1:0] AA = A_buf;
+ (* force_downto *)
wire [Y_WIDTH-1:0] BB = BI ? ~B_buf : B_buf;
wire [Y_WIDTH:0] C = {CO, CI};
diff --git a/techlibs/intel/cycloneive/cells_map.v b/techlibs/intel/cycloneive/cells_map.v
index abeb92eef..fead2837b 100644
--- a/techlibs/intel/cycloneive/cells_map.v
+++ b/techlibs/intel/cycloneive/cells_map.v
@@ -71,6 +71,7 @@ endmodule
module \$lut (A, Y);
parameter WIDTH = 0;
parameter LUT = 0;
+ (* force_downto *)
input [WIDTH-1:0] A;
output Y;
generate
diff --git a/techlibs/intel/cyclonev/cells_arith.v b/techlibs/intel/cyclonev/cells_arith.v
index 89fb4561f..6a52a0f95 100644
--- a/techlibs/intel/cyclonev/cells_arith.v
+++ b/techlibs/intel/cyclonev/cells_arith.v
@@ -26,8 +26,11 @@ module _80_altera_a10gx_alu (A, B, CI, BI, X, Y, CO);
parameter B_WIDTH = 1;
parameter Y_WIDTH = 1;
+ (* force_downto *)
input [A_WIDTH-1:0] A;
+ (* force_downto *)
input [B_WIDTH-1:0] B;
+ (* force_downto *)
output [Y_WIDTH-1:0] X, Y;
input CI, BI;
@@ -36,11 +39,14 @@ module _80_altera_a10gx_alu (A, B, CI, BI, X, Y, CO);
wire _TECHMAP_FAIL_ = Y_WIDTH <= 4;
+ (* force_downto *)
wire [Y_WIDTH-1:0] A_buf, B_buf;
\$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf));
\$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf));
+ (* force_downto *)
wire [Y_WIDTH-1:0] AA = A_buf;
+ (* force_downto *)
wire [Y_WIDTH-1:0] BB = BI ? ~B_buf : B_buf;
//wire [Y_WIDTH:0] C = {CO, CI};
wire [Y_WIDTH+1:0] COx;
diff --git a/techlibs/intel/cyclonev/cells_map.v b/techlibs/intel/cyclonev/cells_map.v
index f8d142bc9..eb4cd54d1 100644
--- a/techlibs/intel/cyclonev/cells_map.v
+++ b/techlibs/intel/cyclonev/cells_map.v
@@ -71,6 +71,7 @@ endmodule
module \$lut (A, Y);
parameter WIDTH = 0;
parameter LUT = 0;
+ (* force_downto *)
input [WIDTH-1:0] A;
output Y;
wire VCC;
diff --git a/techlibs/intel/max10/cells_arith.v b/techlibs/intel/max10/cells_arith.v
index e2194cbd7..8529706a7 100644
--- a/techlibs/intel/max10/cells_arith.v
+++ b/techlibs/intel/max10/cells_arith.v
@@ -26,8 +26,11 @@ module _80_altera_max10_alu (A, B, CI, BI, X, Y, CO);
parameter B_WIDTH = 1;
parameter Y_WIDTH = 1;
+ (* force_downto *)
input [A_WIDTH-1:0] A;
+ (* force_downto *)
input [B_WIDTH-1:0] B;
+ (* force_downto *)
output [Y_WIDTH-1:0] X, Y;
input CI, BI;
@@ -36,11 +39,14 @@ module _80_altera_max10_alu (A, B, CI, BI, X, Y, CO);
wire _TECHMAP_FAIL_ = Y_WIDTH <= 4;
+ (* force_downto *)
wire [Y_WIDTH-1:0] A_buf, B_buf;
\$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf));
\$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf));
+ (* force_downto *)
wire [Y_WIDTH-1:0] AA = A_buf;
+ (* force_downto *)
wire [Y_WIDTH-1:0] BB = BI ? ~B_buf : B_buf;
//wire [Y_WIDTH:0] C = {CO, CI};
wire [Y_WIDTH+1:0] COx;
diff --git a/techlibs/intel/max10/cells_map.v b/techlibs/intel/max10/cells_map.v
index 6d604e072..6a4072049 100644
--- a/techlibs/intel/max10/cells_map.v
+++ b/techlibs/intel/max10/cells_map.v
@@ -71,6 +71,7 @@ endmodule
module \$lut (A, Y);
parameter WIDTH = 0;
parameter LUT = 0;
+ (* force_downto *)
input [WIDTH-1:0] A;
output Y;
generate
diff --git a/techlibs/intel_alm/common/alm_map.v b/techlibs/intel_alm/common/alm_map.v
index fe646c5d6..6697b2e78 100644
--- a/techlibs/intel_alm/common/alm_map.v
+++ b/techlibs/intel_alm/common/alm_map.v
@@ -3,6 +3,7 @@ module \$lut (A, Y);
parameter WIDTH = 1;
parameter LUT = 0;
+(* force_downto *)
input [WIDTH-1:0] A;
output Y;
diff --git a/techlibs/intel_alm/common/arith_alm_map.v b/techlibs/intel_alm/common/arith_alm_map.v
index ddf81d9d0..8515eeb56 100644
--- a/techlibs/intel_alm/common/arith_alm_map.v
+++ b/techlibs/intel_alm/common/arith_alm_map.v
@@ -11,17 +11,24 @@ parameter Y_WIDTH = 1;
parameter _TECHMAP_CONSTMSK_CI_ = 0;
parameter _TECHMAP_CONSTVAL_CI_ = 0;
+(* force_downto *)
input [A_WIDTH-1:0] A;
+(* force_downto *)
input [B_WIDTH-1:0] B;
input CI, BI;
+(* force_downto *)
output [Y_WIDTH-1:0] X, Y, CO;
+(* force_downto *)
wire [Y_WIDTH-1:0] A_buf, B_buf;
\$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf));
\$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf));
+(* force_downto *)
wire [Y_WIDTH-1:0] AA = A_buf;
+(* force_downto *)
wire [Y_WIDTH-1:0] BB = BI ? ~B_buf : B_buf;
+(* force_downto *)
wire [Y_WIDTH-1:0] BX = B_buf;
wire [Y_WIDTH:0] ALM_CARRY;
diff --git a/techlibs/sf2/cells_map.v b/techlibs/sf2/cells_map.v
index 6ad7807d2..9fddc0f41 100644
--- a/techlibs/sf2/cells_map.v
+++ b/techlibs/sf2/cells_map.v
@@ -59,6 +59,7 @@ module \$lut (A, Y);
parameter WIDTH = 0;
parameter LUT = 0;
+ (* force_downto *)
input [WIDTH-1:0] A;
output Y;
diff --git a/techlibs/xilinx/arith_map.v b/techlibs/xilinx/arith_map.v
index 2b8b0dcc1..2fc216908 100644
--- a/techlibs/xilinx/arith_map.v
+++ b/techlibs/xilinx/arith_map.v
@@ -24,9 +24,11 @@
module _80_xilinx_lcu (P, G, CI, CO);
parameter WIDTH = 2;
+ (* force_downto *)
input [WIDTH-1:0] P, G;
input CI;
+ (* force_downto *)
output [WIDTH-1:0] CO;
wire _TECHMAP_FAIL_ = WIDTH <= 2;
@@ -41,7 +43,9 @@ module _80_xilinx_lcu (P, G, CI, CO);
generate if (EXPLICIT_CARRY || `LUT_SIZE == 4) begin
+ (* force_downto *)
wire [WIDTH-1:0] C = {CO, CI};
+ (* force_downto *)
wire [WIDTH-1:0] S = P & ~G;
generate for (i = 0; i < WIDTH; i = i + 1) begin:slice
@@ -59,8 +63,11 @@ end else begin
localparam MAX_WIDTH = CARRY4_COUNT * 4;
localparam PAD_WIDTH = MAX_WIDTH - WIDTH;
+ (* force_downto *)
wire [MAX_WIDTH-1:0] S = {{PAD_WIDTH{1'b0}}, P & ~G};
+ (* force_downto *)
wire [MAX_WIDTH-1:0] GG = {{PAD_WIDTH{1'b0}}, G};
+ (* force_downto *)
wire [MAX_WIDTH-1:0] C;
assign CO = C;
@@ -103,20 +110,27 @@ module _80_xilinx_alu (A, B, CI, BI, X, Y, CO);
parameter _TECHMAP_CONSTVAL_CI_ = 0;
parameter _TECHMAP_CONSTMSK_CI_ = 0;
+ (* force_downto *)
input [A_WIDTH-1:0] A;
+ (* force_downto *)
input [B_WIDTH-1:0] B;
+ (* force_downto *)
output [Y_WIDTH-1:0] X, Y;
input CI, BI;
+ (* force_downto *)
output [Y_WIDTH-1:0] CO;
wire _TECHMAP_FAIL_ = Y_WIDTH <= 2;
+ (* force_downto *)
wire [Y_WIDTH-1:0] A_buf, B_buf;
\$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf));
\$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf));
+ (* force_downto *)
wire [Y_WIDTH-1:0] AA = A_buf;
+ (* force_downto *)
wire [Y_WIDTH-1:0] BB = BI ? ~B_buf : B_buf;
genvar i;
@@ -129,7 +143,9 @@ module _80_xilinx_alu (A, B, CI, BI, X, Y, CO);
generate if (`LUT_SIZE == 4) begin
+ (* force_downto *)
wire [Y_WIDTH-1:0] C = {CO, CI};
+ (* force_downto *)
wire [Y_WIDTH-1:0] S = {AA ^ BB};
genvar i;
@@ -149,6 +165,7 @@ generate if (`LUT_SIZE == 4) begin
end else if (EXPLICIT_CARRY) begin
+ (* force_downto *)
wire [Y_WIDTH-1:0] S = AA ^ BB;
wire CINIT;
@@ -161,7 +178,9 @@ end else if (EXPLICIT_CARRY) begin
// So we maintain two wire sets, CO_CHAIN is the carry that is for VPR,
// e.g. off fabric dedicated chain. CO is the carry outputs that are
// available to the fabric.
+ (* force_downto *)
wire [Y_WIDTH-1:0] CO_CHAIN;
+ (* force_downto *)
wire [Y_WIDTH-1:0] C = {CO_CHAIN, CINIT};
// If carry chain is being initialized to a constant, techmap the constant
@@ -250,10 +269,14 @@ end else begin
localparam MAX_WIDTH = CARRY4_COUNT * 4;
localparam PAD_WIDTH = MAX_WIDTH - Y_WIDTH;
+ (* force_downto *)
wire [MAX_WIDTH-1:0] S = {{PAD_WIDTH{1'b0}}, AA ^ BB};
+ (* force_downto *)
wire [MAX_WIDTH-1:0] DI = {{PAD_WIDTH{1'b0}}, AA};
+ (* force_downto *)
wire [MAX_WIDTH-1:0] O;
+ (* force_downto *)
wire [MAX_WIDTH-1:0] C;
assign Y = O, CO = C;
diff --git a/techlibs/xilinx/cells_map.v b/techlibs/xilinx/cells_map.v
index cc180f2b9..801949d22 100644
--- a/techlibs/xilinx/cells_map.v
+++ b/techlibs/xilinx/cells_map.v
@@ -184,8 +184,11 @@ module \$__XILINX_SHIFTX (A, B, Y);
parameter B_WIDTH = 1;
parameter Y_WIDTH = 1;
+ (* force_downto *)
input [A_WIDTH-1:0] A;
+ (* force_downto *)
input [B_WIDTH-1:0] B;
+ (* force_downto *)
output [Y_WIDTH-1:0] Y;
parameter [A_WIDTH-1:0] _TECHMAP_CONSTMSK_A_ = 0;
@@ -321,8 +324,11 @@ module _90__XILINX_SHIFTX (A, B, Y);
parameter B_WIDTH = 1;
parameter Y_WIDTH = 1;
+ (* force_downto *)
input [A_WIDTH-1:0] A;
+ (* force_downto *)
input [B_WIDTH-1:0] B;
+ (* force_downto *)
output [Y_WIDTH-1:0] Y;
\$shiftx #(.A_SIGNED(A_SIGNED), .B_SIGNED(B_SIGNED), .A_WIDTH(A_WIDTH), .B_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) _TECHMAP_REPLACE_ (.A(A), .B(B), .Y(Y));
diff --git a/techlibs/xilinx/lut_map.v b/techlibs/xilinx/lut_map.v
index ec2e3b234..2ab6075f1 100644
--- a/techlibs/xilinx/lut_map.v
+++ b/techlibs/xilinx/lut_map.v
@@ -26,6 +26,7 @@ module \$lut (A, Y);
parameter WIDTH = 0;
parameter LUT = 0;
+ (* force_downto *)
input [WIDTH-1:0] A;
output Y;
diff --git a/techlibs/xilinx/mux_map.v b/techlibs/xilinx/mux_map.v
index 91aaf2118..bb31d21ec 100644
--- a/techlibs/xilinx/mux_map.v
+++ b/techlibs/xilinx/mux_map.v
@@ -30,8 +30,11 @@ module \$shiftx (A, B, Y);
parameter B_WIDTH = 1;
parameter Y_WIDTH = 1;
+ (* force_downto *)
input [A_WIDTH-1:0] A;
+ (* force_downto *)
input [B_WIDTH-1:0] B;
+ (* force_downto *)
output [Y_WIDTH-1:0] Y;
parameter [B_WIDTH-1:0] _TECHMAP_CONSTMSK_B_ = 0;
diff --git a/tests/arch/xilinx/mux.ys b/tests/arch/xilinx/mux.ys
index 99817738d..1b2788448 100644
--- a/tests/arch/xilinx/mux.ys
+++ b/tests/arch/xilinx/mux.ys
@@ -40,8 +40,10 @@ proc
equiv_opt -assert -map +/xilinx/cells_sim.v synth_xilinx -noiopad # equivalency check
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
cd mux16 # Constrain all select calls below inside the top module
-select -assert-min 5 t:LUT6
+select -assert-max 2 t:LUT4
+select -assert-min 4 t:LUT6
select -assert-max 7 t:LUT6
select -assert-max 2 t:MUXF7
+dump
-select -assert-none t:LUT6 t:MUXF7 %% t:* %D
+select -assert-none t:LUT6 t:LUT4 t:MUXF7 %% t:* %D