diff options
Diffstat (limited to 'techlibs/common/techmap.v')
| -rw-r--r-- | techlibs/common/techmap.v | 39 | 
1 files changed, 38 insertions, 1 deletions
diff --git a/techlibs/common/techmap.v b/techlibs/common/techmap.v index 667773e1b..91d385b80 100644 --- a/techlibs/common/techmap.v +++ b/techlibs/common/techmap.v @@ -59,7 +59,7 @@ module _90_simplemap_compare_ops;  endmodule  (* techmap_simplemap *) -(* techmap_celltype = "$pos $slice $concat $mux $tribuf" *) +(* techmap_celltype = "$pos $slice $concat $mux $tribuf $bmux" *)  module _90_simplemap_various;  endmodule @@ -597,6 +597,43 @@ module _90_pmux (A, B, S, Y);  	assign Y = |S ? Y_B : A;  endmodule +// -------------------------------------------------------- +// Demultiplexers +// -------------------------------------------------------- + +(* techmap_celltype = "$demux" *) +module _90_demux (A, S, Y); +	parameter WIDTH = 1; +	parameter S_WIDTH = 1; + +	(* force_downto *) +	input [WIDTH-1:0] A; +	(* force_downto *) +	input [S_WIDTH-1:0] S; +	(* force_downto *) +	output [(WIDTH << S_WIDTH)-1:0] Y; + +	generate +		if (S_WIDTH == 0) begin +			assign Y = A; +		end else if (S_WIDTH == 1) begin +			assign Y[0+:WIDTH] = S ? 0 : A; +			assign Y[WIDTH+:WIDTH] = S ? A : 0; +		end else begin +			localparam SPLIT = S_WIDTH / 2; +			wire [(1 << (S_WIDTH-SPLIT))-1:0] YH; +			wire [(1 << SPLIT)-1:0] YL; +			$demux #(.WIDTH(1), .S_WIDTH(SPLIT)) lo (.A(1'b1), .S(S[SPLIT-1:0]), .Y(YL)); +			$demux #(.WIDTH(1), .S_WIDTH(S_WIDTH-SPLIT)) hi (.A(1'b1), .S(S[S_WIDTH-1:SPLIT]), .Y(YH)); +			genvar i; +			for (i = 0; i < (1 << S_WIDTH); i = i + 1) begin +				localparam [S_WIDTH-1:0] IDX = i; +				assign Y[i*WIDTH+:WIDTH] = (YL[IDX[SPLIT-1:0]] & YH[IDX[S_WIDTH-1:SPLIT]]) ? A : 0; +			end +		end +	endgenerate +endmodule +  // --------------------------------------------------------  // LUTs  | 
