diff options
| author | Marcelina KoĆcielnicka <mwk@0x04.net> | 2020-05-18 18:15:03 +0200 | 
|---|---|---|
| committer | Marcelina KoĆcielnicka <mwk@0x04.net> | 2020-05-19 01:42:40 +0200 | 
| commit | aee439360bba642dcbffe5b803aa9a994b11d183 (patch) | |
| tree | a5c15b4a6172ea3ff651f88174fff7d5269ad1c2 | |
| parent | 2d573a0ff680eb9f38358943fbf134f765ba1451 (diff) | |
| download | yosys-aee439360bba642dcbffe5b803aa9a994b11d183.tar.gz yosys-aee439360bba642dcbffe5b803aa9a994b11d183.tar.bz2 yosys-aee439360bba642dcbffe5b803aa9a994b11d183.zip  | |
Add force_downto and force_upto wire attributes.
Fixes #2058.
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  | 
