1module mux_if_unbal_4_1 #(parameter N=4, parameter W=1) (input [N*W-1:0] i, input [$clog2(N)-1:0] s, output reg [W-1:0] o);
2always @*
3    if (s == 0) o <= i[0*W+:W];
4    else if (s == 1) o <= i[1*W+:W];
5    else if (s == 2) o <= i[2*W+:W];
6    else if (s == 3) o <= i[3*W+:W];
7    else o <= {W{1'bx}};
8endmodule
9
10module mux_if_unbal_5_3 #(parameter N=5, parameter W=3) (input [N*W-1:0] i, input [$clog2(N)-1:0] s, output reg [W-1:0] o);
11always @* begin
12    o <= {W{1'bx}};
13    if (s == 0) o <= i[0*W+:W];
14    if (s == 1) o <= i[1*W+:W];
15    if (s == 2) o <= i[2*W+:W];
16    if (s == 3) o <= i[3*W+:W];
17    if (s == 4) o <= i[4*W+:W];
18end
19endmodule
20
21module mux_if_unbal_5_3_invert #(parameter N=5, parameter W=3) (input [N*W-1:0] i, input [$clog2(N)-1:0] s, output reg [W-1:0] o);
22always @*
23    if (s != 0)
24	   	if (s != 1)
25			if (s != 2)
26				if (s != 3)
27					if (s != 4) o <= i[4*W+:W];
28					else o <= i[0*W+:W];
29				else o <= i[3*W+:W];
30			else o <= i[2*W+:W];
31		else o <= i[1*W+:W];
32    else o <= {W{1'bx}};
33endmodule
34
35module mux_if_unbal_5_3_width_mismatch #(parameter N=5, parameter W=3) (input [N*W-1:0] i, input [$clog2(N)-1:0] s, output reg [W-1:0] o);
36always @* begin
37    o <= {W{1'bx}};
38    if (s == 0) o <= i[0*W+:W];
39    if (s == 1) o <= i[1*W+:W];
40    if (s == 2) o[W-2:0] <= i[2*W+:W-1];
41    if (s == 3) o <= i[3*W+:W];
42    if (s == 4) o <= i[4*W+:W];
43end
44endmodule
45
46module mux_if_unbal_4_1_missing #(parameter N=5, parameter W=3) (input [N*W-1:0] i, input [$clog2(N)-1:0] s, output reg [W-1:0] o);
47always @* begin
48    if (s == 0) o <= i[0*W+:W];
49//    else if (s == 1) o <= i[1*W+:W];
50//    else if (s == 2) o <= i[2*W+:W];
51    else if (s == 3) o <= i[3*W+:W];
52    else o <= {W{1'bx}};
53end
54endmodule
55
56module mux_if_unbal_5_3_order #(parameter N=5, parameter W=3) (input [N*W-1:0] i, input [$clog2(N)-1:0] s, output reg [W-1:0] o);
57always @* begin
58    o <= {W{1'bx}};
59    if (s == 3) o <= i[3*W+:W];
60    if (s == 2) o <= i[2*W+:W];
61    if (s == 1) o <= i[1*W+:W];
62    if (s == 4) o <= i[4*W+:W];
63    if (s == 0) o <= i[0*W+:W];
64end
65endmodule
66
67module mux_if_unbal_4_1_nonexcl #(parameter N=4, parameter W=1) (input [N*W-1:0] i, input [$clog2(N)-1:0] s, output reg [W-1:0] o);
68always @*
69    if (s == 0) o <= i[0*W+:W];
70    else if (s == 1) o <= i[1*W+:W];
71    else if (s == 2) o <= i[2*W+:W];
72    else if (s == 3) o <= i[3*W+:W];
73	else if (s == 0) o <= {W{1'b0}};
74    else o <= {W{1'bx}};
75endmodule
76
77module mux_if_unbal_5_3_nonexcl #(parameter N=5, parameter W=3) (input [N*W-1:0] i, input [$clog2(N)-1:0] s, output reg [W-1:0] o);
78always @* begin
79    o <= {W{1'bx}};
80    if (s == 0) o <= i[0*W+:W];
81    if (s == 1) o <= i[1*W+:W];
82    if (s == 2) o <= i[2*W+:W];
83    if (s == 3) o <= i[3*W+:W];
84    if (s == 4) o <= i[4*W+:W];
85	if (s == 0) o <= i[2*W+:W];
86end
87endmodule
88
89module mux_case_unbal_8_7#(parameter N=8, parameter W=7) (input [N*W-1:0] i, input [$clog2(N)-1:0] s, output reg [W-1:0] o);
90always @* begin
91    o <= {W{1'bx}};
92    case (s)
93    0: o <= i[0*W+:W];
94    default:
95        case (s)
96        1: o <= i[1*W+:W];
97        2: o <= i[2*W+:W];
98        default:
99            case (s)
100            3: o <= i[3*W+:W];
101            4: o <= i[4*W+:W];
102            5: o <= i[5*W+:W];
103            default:
104                case (s)
105                    6: o <= i[6*W+:W];
106                    default: o <= i[7*W+:W];
107                endcase
108            endcase
109        endcase
110    endcase
111end
112endmodule
113
114module mux_if_bal_8_2 #(parameter N=8, parameter W=2) (input [N*W-1:0] i, input [$clog2(N)-1:0] s, output reg [W-1:0] o);
115always @*
116    if (s[0] == 1'b0)
117     if (s[1] == 1'b0)
118      if (s[2] == 1'b0)
119       o <= i[0*W+:W];
120      else
121       o <= i[1*W+:W];
122     else
123      if (s[2] == 1'b0)
124       o <= i[2*W+:W];
125      else
126       o <= i[3*W+:W];
127    else
128     if (s[1] == 1'b0)
129      if (s[2] == 1'b0)
130       o <= i[4*W+:W];
131      else
132       o <= i[5*W+:W];
133     else
134      if (s[2] == 1'b0)
135       o <= i[6*W+:W];
136      else
137       o <= i[7*W+:W];
138endmodule
139
140module mux_if_bal_5_1 #(parameter N=5, parameter W=1) (input [N*W-1:0] i, input [$clog2(N)-1:0] s, output reg [W-1:0] o);
141always @*
142    if (s[0] == 1'b0)
143     if (s[1] == 1'b0)
144      if (s[2] == 1'b0)
145       o <= i[0*W+:W];
146      else
147       o <= i[1*W+:W];
148     else
149      if (s[2] == 1'b0)
150       o <= i[2*W+:W];
151      else
152       o <= i[3*W+:W];
153    else
154     o <= i[4*W+:W];
155endmodule
156
157module clairexen_nonexclusive_select (
158        input wire x, y, z,
159        input wire a, b, c, d,
160        output reg o
161);
162        always @* begin
163                o = a;
164                if (x) o = b;
165                if (y) o = c;
166                if (z) o = d;
167        end
168endmodule
169
170module clairexen_freduce (
171        input wire [1:0] s,
172        input wire a, b, c, d,
173        output reg [3:0] o
174);
175        always @* begin
176                o = {4{a}};
177                if (s == 0) o = {3{b}};
178                if (s == 1) o = {2{c}};
179                if (s == 2) o = d;
180        end
181endmodule
182
183module case_nonexclusive_select (
184        input wire [1:0] x, y,
185        input wire a, b, c, d, e,
186        output reg o
187);
188        always @* begin
189            case (x)
190                0: o = b;
191                2: o = b;
192                1: o = c;
193                default: begin
194                    o = a;
195                    if (y == 0) o = d;
196                    if (y == 1) o = e;
197                end
198        endcase
199        end
200endmodule
201
202module case_nonoverlap (
203        input wire [2:0] x,
204        input wire a, b, c, d, e,
205        output reg o
206);
207        always @* begin
208            case (x)
209                0, 2: o = b; // Creates $reduce_or
210                1: o = c;
211                default:
212                    case (x)
213                        3: o = d; 4: o = d; // Creates $reduce_or
214                        5: o = e;
215                        default: o = 1'b0;
216                    endcase
217        endcase
218        end
219endmodule
220
221module case_overlap (
222        input wire [2:0] x,
223        input wire a, b, c, d, e,
224        output reg o
225);
226        always @* begin
227            case (x)
228                0, 2: o = b; // Creates $reduce_or
229                1: o = c;
230                default:
231                    case (x)
232                        0: o = 1'b1; // OVERLAP!
233                        3, 4: o = d; // Creates $reduce_or
234                        5: o = e;
235                        default: o = 1'b0;
236                    endcase
237        endcase
238        end
239endmodule
240
241module case_overlap2 (
242        input wire [2:0] x,
243        input wire a, b, c, d, e,
244        output reg o
245);
246        always @* begin
247            case (x)
248                0: o = b; 2: o = b; // Creates $reduce_or
249                1: o = c;
250                default:
251                    case (x)
252                        0: o = d; 2: o = d; // Creates $reduce_or
253                        3: o = d; 4: o = d; // Creates $reduce_or
254                        5: o = e;
255                        default: o = 1'b0;
256                    endcase
257        endcase
258        end
259endmodule
260