@@ -44,264 +44,117 @@ module ttl_74181 #(parameter WIDTH = 4, DELAY_RISE = 0, DELAY_FALL = 0)
4444reg CP_computed;
4545reg CG_computed;
4646wire Equal_computed;
47- reg C_in_bar;
48- reg C_computed_bar;
4947reg C_computed;
5048reg [WIDTH- 1 :0 ] F_computed;
5149wire [WIDTH- 1 :0 ] P_internal;
5250wire [WIDTH- 1 :0 ] G_internal;
51+ wire [WIDTH- 1 :0 ] C_internal;
5352wire [WIDTH- 1 :0 ] CG_internal;
5453
54+ // structural declaration using gates and wires (see datasheet for the schematic):
55+
5556generate
5657 genvar i;
5758 for (i = 0 ; i < WIDTH; i = i + 1 )
5859 begin : gen_internals
60+ wire [WIDTH- 1 :0 ] C_and_P_term;
61+ wire [WIDTH- 1 :0 ] P_and_G_term;
62+ wire [WIDTH- 1 :0 ] G_term;
63+
5964 // first layer: internal propagate and generate signals from each A, B bit pair
60- // used for carry output C (in the logic section), and used for
61- // carry lookahead outputs CP and CG
65+ // used for all further computations (function output F, carry output C,
66+ // carry lookahead outputs CP and CG)
6267 //
6368 assign P_internal[i] = ~ (A_bar[i] & ~ B_bar[i] & Select[2 ] | A_bar[i] & B_bar[i] & Select[3 ]);
6469 assign G_internal[i] = ~ (A_bar[i] | B_bar[i] & Select[0 ] | ~ B_bar[i] & Select[1 ]);
6570
66- // second layer: internal carry generate signals from the propagate and generate signals,
67- // used for carry lookahead output CG
71+ // second layer: internal carry signals from the carry in and propagate and generate signals,
72+ // used for computation of F bits (these are for arithmetic functions only;
73+ // for logic functions the Mode signal inhibits all C_internal outputs)
6874 //
69- // the generated code has this structure (terms are then joined by |):
70- // CG_internal[0] = P_internal[1] & P_internal[2] & P_internal[3] & G_internal[0];
71- // CG_internal[1] = P_internal[2] & P_internal[3] & G_internal[1];
72- // CG_internal[2] = P_internal[3] & G_internal[2];
73- // CG_internal[3] = G_internal[3];
75+ // the generated code has this structure:
76+ // C_internal[0] = ~(C_in);
77+ // C_internal[1] = ~(C_in & P_internal[0] |
78+ // G_internal[0]);
79+ // C_internal[2] = ~(C_in & P_internal[0] & P_internal[1] |
80+ // P_internal[1] & G_internal[0] |
81+ // G_internal[1]);
82+ // C_internal[3] = ~(C_in & P_internal[0] & P_internal[1] & P_internal[2] |
83+ // P_internal[1] & P_internal[2] & G_internal[0] |
84+ // P_internal[2] & G_internal[1] |
85+ // G_internal[2]);
7486 //
75- if (i < WIDTH - 1 )
87+ if (i == 0 )
7688 begin
77- assign CG_internal [i] = ( & P_internal[(WIDTH - 1 ):(i + 1 )]) & G_internal[i] ;
89+ assign C_and_P_term [i] = C_in & ! Mode ;
7890 end
7991 else
8092 begin
81- assign CG_internal[i] = G_internal[i];
82- end
83- end
84- endgenerate
85-
86- always @(* )
87- begin
88- if (! Mode)
89- begin
90- // arithmetic
91-
92- C_in_bar = ~ C_in;
93-
94- // add (A PLUS B PLUS Carry)
95- if (Select == 4'b1001 )
96- begin
97- {C_computed_bar, F_computed} = {1'b0 , A_bar} + {1'b0 , B_bar} + C_in_bar;
98- end
99-
100- // subtract (A MINUS B MINUS 1 PLUS Carry)
101- if (Select == 4'b0110 )
102- begin
103- {C_computed_bar, F_computed} = {1'b0 , A_bar} - {1'b0 , B_bar} + {WIDTH{1'b1 }} + C_in_bar;
104- end
105-
106- // other arithmetic incorporating logic
107-
108- // A PLUS Carry
109- if (Select == 4'b0000 )
110- begin
111- {C_computed_bar, F_computed} = {1'b0 , A_bar} + C_in_bar;
112- end
113-
114- // A OR B PLUS Carry
115- if (Select == 4'b0001 )
116- begin
117- {C_computed_bar, F_computed} = {1'b0 , A_bar | B_bar} + C_in_bar;
118- end
119-
120- // A OR (NOT B) PLUS Carry
121- if (Select == 4'b0010 )
122- begin
123- {C_computed_bar, F_computed} = {1'b0 , A_bar | ~ B_bar} + C_in_bar;
124- end
125-
126- // MINUS 1 PLUS Carry
127- if (Select == 4'b0011 )
128- begin
129- {C_computed_bar, F_computed} = {WIDTH{1'b1 }} + C_in_bar;
130- end
131-
132- // A PLUS (A AND (NOT B)) PLUS Carry
133- if (Select == 4'b0100 )
134- begin
135- {C_computed_bar, F_computed} = {1'b0 , A_bar} + {1'b0 , A_bar & ~ B_bar} + C_in_bar;
136- end
137-
138- // (A OR B) PLUS (A AND (NOT B)) PLUS Carry
139- if (Select == 4'b0101 )
140- begin
141- {C_computed_bar, F_computed} = {1'b0 , A_bar | B_bar} + {1'b0 , A_bar & ~ B_bar} + C_in_bar;
142- end
143-
144- // (A AND (NOT B)) MINUS 1 PLUS Carry
145- if (Select == 4'b0111 )
146- begin
147- {C_computed_bar, F_computed} = {1'b0 , A_bar & ~ B_bar} + {WIDTH{1'b1 }} + C_in_bar;
148- end
149-
150- // A PLUS (A AND B) PLUS Carry
151- if (Select == 4'b1000 )
152- begin
153- {C_computed_bar, F_computed} = {1'b0 , A_bar} + {1'b0 , A_bar & B_bar} + C_in_bar;
154- end
155-
156- // (A OR (NOT B)) PLUS (A AND B) PLUS Carry
157- if (Select == 4'b1010 )
158- begin
159- {C_computed_bar, F_computed} = {1'b0 , A_bar | ~ B_bar} + {1'b0 , A_bar & B_bar} + C_in_bar;
160- end
161-
162- // (A AND B) MINUS 1 PLUS Carry
163- if (Select == 4'b1011 )
164- begin
165- {C_computed_bar, F_computed} = {1'b0 , A_bar & B_bar} + {WIDTH{1'b1 }} + C_in_bar;
166- end
167-
168- // A PLUS A (SHIFT LEFT) PLUS Carry
169- if (Select == 4'b1100 )
170- begin : sum_block
171- reg [WIDTH:0 ] extra_width_sum;
172-
173- extra_width_sum = A_bar << 1 ;
174-
175- {C_computed_bar, F_computed} = extra_width_sum + C_in_bar;
176- end
177-
178- // A PLUS (A OR B) PLUS Carry
179- if (Select == 4'b1101 )
180- begin
181- {C_computed_bar, F_computed} = {1'b0 , A_bar} + {1'b0 , A_bar | B_bar} + C_in_bar;
182- end
183-
184- // A PLUS (A OR (NOT B)) PLUS Carry
185- if (Select == 4'b1110 )
186- begin
187- {C_computed_bar, F_computed} = {1'b0 , A_bar} + {1'b0 , A_bar | ~ B_bar} + C_in_bar;
188- end
189-
190- // A MINUS 1 PLUS Carry
191- if (Select == 4'b1111 )
192- begin
193- {C_computed_bar, F_computed} = {1'b0 , A_bar} + {WIDTH{1'b1 }} + C_in_bar;
194- end
195-
196- C_computed = ~ C_computed_bar;
197- end
198- else
199- begin
200- // logic
201-
202- // NOT A
203- if (Select == 4'b0000 )
204- begin
205- F_computed = ~ A_bar;
206- end
207-
208- // NOT (A OR B)
209- if (Select == 4'b0001 )
210- begin
211- F_computed = ~ (A_bar | B_bar);
212- end
93+ localparam i_minus_1 = i - 1 ;
21394
214- // (NOT A) AND B
215- if (Select == 4'b0010 )
216- begin
217- F_computed = ~ A_bar & B_bar;
218- end
95+ assign C_and_P_term[i] = C_in & (& P_internal[i_minus_1:0 ]) & ! Mode;
21996
220- // 0
221- if (Select == 4'b0011 )
222- begin
223- F_computed = {WIDTH{1'b0 }};
224- end
97+ assign G_term[i] = G_internal[i_minus_1] & ! Mode;
22598
226- // NOT (A AND B)
227- if (Select == 4'b0100 )
228- begin
229- F_computed = ~ (A_bar & B_bar);
230- end
99+ if (i > 1 )
100+ begin
101+ genvar j;
102+ for (j = 0 ; j < i_minus_1; j = j + 1 )
103+ begin : gen_P_and_G_term
104+ localparam j_plus_one = j + 1 ;
231105
232- // NOT B
233- if (Select == 4'b0101 )
234- begin
235- F_computed = ~ B_bar;
106+ // these terms will be joined by | below:
107+ assign P_and_G_term[j] = ( & P_internal[i_minus_1:j_plus_one]) & G_internal[j] & ! Mode;
108+ end
109+ end
236110 end
237111
238- // A XOR B
239- if (Select == 4'b0110 )
112+ // internal carry signals aggregated from the above terms
113+ if (i == 0 )
240114 begin
241- F_computed = A_bar ^ B_bar ;
115+ assign C_internal[i] = ~ C_and_P_term[i] ;
242116 end
243-
244- // A AND (NOT B)
245- if (Select == 4'b0111 )
246- begin
247- F_computed = A_bar & ~ B_bar;
248- end
249-
250- // (NOT A) OR B
251- if (Select == 4'b1000 )
252- begin
253- F_computed = ~ A_bar | B_bar;
254- end
255-
256- // NOT (A XOR B)
257- if (Select == 4'b1001 )
117+ else if (i == 1 )
258118 begin
259- F_computed = ~ (A_bar ^ B_bar );
119+ assign C_internal[i] = ~ (C_and_P_term[i] | G_term[i] );
260120 end
261-
262- // B
263- if (Select == 4'b1010 )
264- begin
265- F_computed = B_bar;
266- end
267-
268- // A AND B
269- if (Select == 4'b1011 )
270- begin
271- F_computed = A_bar & B_bar;
272- end
273-
274- // 1
275- if (Select == 4'b1100 )
276- begin
277- F_computed = {WIDTH{1'b1 }};
278- end
279-
280- // A OR (NOT B)
281- if (Select == 4'b1101 )
121+ else
282122 begin
283- F_computed = A_bar | ~ B_bar ;
123+ assign C_internal[i] = ~ (C_and_P_term[i] | ( | P_and_G_term[(i - 2 ): 0 ]) | G_term[i]) ;
284124 end
285125
286- // A OR B
287- if (Select == 4'b1110 )
126+ // second layer, separate section: internal carry generate signals from the
127+ // propagate and generate signals, used for computation of:
128+ // carry output C, carry lookahead output CG
129+ //
130+ // the generated code has this structure (terms are then joined by |):
131+ // CG_internal[0] = P_internal[1] & P_internal[2] & P_internal[3] & G_internal[0];
132+ // CG_internal[1] = P_internal[2] & P_internal[3] & G_internal[1];
133+ // CG_internal[2] = P_internal[3] & G_internal[2];
134+ // CG_internal[3] = G_internal[3];
135+ //
136+ if (i < WIDTH - 1 )
288137 begin
289- F_computed = A_bar | B_bar ;
138+ assign CG_internal[i] = ( & P_internal[(WIDTH - 1 ):(i + 1 )]) & G_internal[i] ;
290139 end
291-
292- // A
293- if (Select == 4'b1111 )
140+ else
294141 begin
295- F_computed = A_bar ;
142+ assign CG_internal[i] = G_internal[i] ;
296143 end
297-
298- // third layer: carry bit
299- C_computed = C_in & (& P_internal) | (| CG_internal);
300144 end
145+ endgenerate
301146
147+ always @(* )
148+ begin
302149 // third layer: carry lookahead bits aggregated from the above terms
303150 CP_computed = ~ (& P_internal);
304151 CG_computed = ~ (| CG_internal);
152+
153+ // third layer: carry bit
154+ C_computed = C_in & (& P_internal) | (| CG_internal);
155+
156+ // third layer: F bits
157+ F_computed = P_internal ^ G_internal ^ C_internal;
305158end
306159
307160// output
0 commit comments