ASIC DESIGN FLOW REPORT -
Matrix Multiplication
Pradyumna Katageri Simran Sarvajith R.
2025ovl1036 2025ovl1053 2025ovl1050
Ashwini Singh Shubham Sachdeva
2025ovl1009 2025ovl1055
August 1, 2026
Contents
Project 3 : Matrix Multiplication Hardware Implementation 3
1.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.2 Problem Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.3 Design Specifications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.3.1 Inputs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.3.2 Outputs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.3.3 Functional Requirements . . . . . . . . . . . . . . . . . . . . . . . 4
1.3.4 RTL Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.4 Functional Verification . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
1.5 Logic Synthesis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
1.5.1 Yosys Flow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
1.5.2 Synthesized Netlist . . . . . . . . . . . . . . . . . . . . . . . . . . 14
1.5.3 Synthesis Report . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
1.6 Floorplanning . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
1.6.1 Setup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
1.6.2 Floorplan Parameters . . . . . . . . . . . . . . . . . . . . . . . . . 16
1.6.3 Floorplan Output . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
1.7 Placement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
1.7.1 Final Placement . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
1.8 Clock Tree Synthesis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
1.8.1 CTS Results . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
1.8.2 Timing Report . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
1.9 Routing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
1.9.1 Global Routing . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
1.9.2 GDSII Layout . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
1.10 Performance Results . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
1.11 Challenges Encountered . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
1.12 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
1
Listings
1.1 FFT RTL Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.2 Testbench for the Parallel Sorting Architecture . . . . . . . . . . . . . . . 12
1.3 TCL Script to generate netlist . . . . . . . . . . . . . . . . . . . . . . . . 14
2
Project 3 : Matrix Multiplication
Hardware Implementation
1.1 Introduction
In digital signal processing and hardware accelerators, multiplication operations form
the computational core of arithmetic evaluation. The efficiency and latency of scalar
multiplication directly determine the computational speed and hardware area of the
overall design. To achieve high-throughput performance with minimal gate latency, fast
multipliers such as Dadda tree multipliers are employed. This design implements an 8 × 8
signed scalar multiplier utilizing Baugh-Wooley partial-product generation and a 4-stage
Dadda reduction tree optimized for fixed-point arithmetic.
1.2 Problem Statement
Standard array multipliers introduce significant critical path delays due to long carry-
propagation chains. Furthermore, signed arithmetic requires handling two’s-complement
sign extensions effectively without incurring severe area overhead. The objective is to design
and implement a high-performance, fully structural 8×8 signed Dadda multiplier operating
on Q4.4 fixed-point inputs. The module must utilize the Baugh-Wooley algorithm for sign
correction, reduce partial products through a minimum-adder Dadda tree, and terminate at
a fully registered output stage to achieve timing closure under tight frequency constraints.
1.3 Design Specifications
1.3.1 Inputs
• clk: System clock signal.
• rst n: Active-low asynchronous reset signal.
• A: 8-bit signed multiplier operand in Q4.4 fixed-point format (logic [7:0]).
• B: 8-bit signed multiplicand operand in Q4.4 fixed-point format (logic [7:0]).
1.3.2 Outputs
• product q8 8: 16-bit product output in Q8.8 fixed-point format, fully registered
(logic [15:0]).
3
1.3.3 Functional Requirements
1. Partial Product Generation (Baugh-Wooley Algorithm):
• Generate partial products pp[i][j] for i, j ∈ [0, 7] using Baugh-Wooley signed
arithmetic.
• Apply NAND logic where (i == 7) ⊕ (j == 7) (border terms) and AND logic
for all other matrix entries.
• Include fixed sign-extension correction bits corr8 at column 8 and corr15 at
column 15.
2. Dadda Tree Reduction Network:
• Reduce initial partial product column heights (maximum height of 8) down to
a 2-row representation across 4 structural stages.
• Stage 1: Reduce column heights to target height 6 using structural half adders
(structural ha) and full adders (structural fa).
• Stage 2: Reduce column heights from 6 to target height 4.
• Stage 3: Reduce column heights from 4 to target height 3.
• Stage 4: Reduce column heights from 3 to target height 2, producing the final
sum vector (sum vec) and carry vector (car vec).
3. Sequential Output Pipeline & Registering:
• Perform vector addition of sum vec and car vec within a sequential block
triggered on the rising edge of clk or falling edge of rst n.
• Reset product q8 8 to 16’sd0 when rst n is logic low.
• Register the final Q8.8 product output at the boundary flip-flops to terminate
critical timing paths.
1.3.4 RTL Code
1 module structural_ha (
2 input logic a ,
3 input logic b ,
4 output logic sum ,
5 output logic cout
6 );
7 assign sum = a ^ b ;
8 assign cout = a & b ;
9 endmodule
10
11 module structural_fa (
12 input logic a ,
13 input logic b ,
14 input logic cin ,
15 output logic sum ,
16 output logic cout
17 );
18 assign sum = a ^ b ^ cin ;
4
19 assign cout = ( a & b ) | ( b & cin ) | ( a & cin ) ;
20 endmodule
21
22
23 module dadda_8x8_signed (
24 input logic clk ,
25 input logic rst_n ,
26 input logic [7:0] A , // Q4 .4 operand
27 input logic [7:0] B , // Q4 .4 operand
28 output logic [15:0] product_q8_8 // Q8 .8 result , fully registered
29 );
30
31 // STAGE 0 : Baugh - Wooley Partial - Product Generation
32 //
33 // Inversion rule ( one index equals 7 , the other does not ) :
34 // pp [ i ][ j ] = ~( A [ i ] & B [ j ]) when ( i ==7) XOR ( j ==7)
35 // pp [ i ][ j ] = A[i] & B[j] otherwise
36 //
37 // All indices in the generate block are elaboration - time constants
38
39 logic pp [0:7][0:7];
40
41 genvar gi , gj ;
42 generate
43 for ( gi = 0; gi <= 7; gi ++) begin : gen_row
44 for ( gj = 0; gj <= 7; gj ++) begin : gen_col
45 if (( gi == 7) ^ ( gj == 7) )
46 assign pp [ gi ][ gj ] = ~( A [ gi ] & B [ gj ]) ; // NAND
border term
47 else
48 assign pp [ gi ][ gj ] = ( A [ gi ] & B [ gj ]) ; // AND inner
/ corner
49 end
50 end
51 endgenerate
52
53
54 // Baugh - Wooley correction constants
55 // corr8 ? adds 2^8 to the partial - product sum
56 // corr15 ? adds 2^15 to the partial - product sum
57 // Together : 2^8 + 2^15 ? 2^8 - 2^15 ( mod 2^16) ?
correct BW
58
59 wire corr8 = 1 ’ b1 ;
60 wire corr15 = 1 ’ b1 ;
61
62 // STAGE 1 ? Reduce to target height 6
63
64 // --- col 6 ( h =7 ? 6) : 1 HA
----------------------------------------
65 logic s1_6a , c1_67 ;
66 structural_ha ha_s1_c6 (
67 .a ( pp [0][6]) ,
68 .b ( pp [1][5]) ,
69 . sum ( s1_6a ) ,
70 . cout ( c1_67 )
71 );
72
5
73 // --- col 7 ( h =8 + c1_67 = 9 ? 6) : 1 FA + 1 HA
--------------------
74 logic s1_7a , c1_78a ;
75 logic s1_7b , c1_78b ;
76
77 structural_fa fa_s1_c7a (
78 .a ( pp [0][7]) ,
79 .b ( pp [1][6]) ,
80 . cin ( pp [2][5]) ,
81 . sum ( s1_7a ) ,
82 . cout ( c1_78a )
83 );
84 structural_ha ha_s1_c7 (
85 .a ( pp [3][4]) ,
86 .b ( pp [4][3]) ,
87 . sum ( s1_7b ) ,
88 . cout ( c1_78b )
89 );
90
91 // --- col 8 ( h =8 + c1_78a + c1_78b = 10 ? 6) : 2 FA
----------------
92 logic s1_8a , c1_89a ;
93 logic s1_8b , c1_89b ;
94
95 structural_fa fa_s1_c8a (
96 .a ( pp [1][7]) ,
97 .b ( pp [2][6]) ,
98 . cin ( pp [3][5]) ,
99 . sum ( s1_8a ) ,
100 . cout ( c1_89a )
101 );
102 structural_fa fa_s1_c8b (
103 .a ( pp [4][4]) ,
104 .b ( pp [5][3]) ,
105 . cin ( pp [6][2]) ,
106 . sum ( s1_8b ) ,
107 . cout ( c1_89b )
108 );
109
110 // --- col 9 ( h =6 + c1_89a + c1_89b = 8 ? 6) : 1 FA
-----------------
111 logic s1_9a , c1_910 ;
112 structural_fa fa_s1_c9 (
113 .a ( pp [2][7]) ,
114 .b ( pp [3][6]) ,
115 . cin ( pp [4][5]) ,
116 . sum ( s1_9a ) ,
117 . cout ( c1_910 )
118 );
119
120 // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
121 // STAGE 2 ? Reduce to target height 4
122 // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
123
124 // col 4 ( h =5 ? 4) : 1 HA
125 logic s2_4a , c2_45 ;
126 structural_ha ha_s2_c4 (
127 .a ( pp [0][4]) ,
6
128 .b ( pp [1][3]) ,
129 . sum ( s2_4a ) ,
130 . cout ( c2_45 )
131 );
132
133 // col 5 ( h =6 + c2_45 = 7 ? 4) : 1 FA + 1 HA
134 logic s2_5a , c2_56a ;
135 logic s2_5b , c2_56b ;
136
137 structural_fa fa_s2_c5 (
138 .a ( pp [0][5]) ,
139 .b ( pp [1][4]) ,
140 . cin ( pp [2][3]) ,
141 . sum ( s2_5a ) ,
142 . cout ( c2_56a )
143 );
144 structural_ha ha_s2_c5 (
145 .a ( pp [3][2]) ,
146 .b ( pp [4][1]) ,
147 . sum ( s2_5b ) ,
148 . cout ( c2_56b )
149 );
150
151 // col 6 ( h =6 + c2_56a + c2_56b = 8 ? 4) : 2 FA
152 logic s2_6a , c2_67a ;
153 logic s2_6b , c2_67b ;
154
155 structural_fa fa_s2_c6a (
156 .a ( s1_6a ) ,
157 .b ( pp [2][4]) ,
158 . cin ( pp [3][3]) ,
159 . sum ( s2_6a ) ,
160 . cout ( c2_67a )
161 );
162 structural_fa fa_s2_c6b (
163 .a ( pp [4][2]) ,
164 .b ( pp [5][1]) ,
165 . cin ( pp [6][0]) ,
166 . sum ( s2_6b ) ,
167 . cout ( c2_67b )
168 );
169
170 // col 7 ( h =6 + c2_67a + c2_67b = 8 ? 4) : 2 FA
171 logic s2_7a , c2_78a ;
172 logic s2_7b , c2_78b ;
173
174 structural_fa fa_s2_c7a (
175 .a ( s1_7a ) ,
176 .b ( s1_7b ) ,
177 . cin ( pp [5][2]) ,
178 . sum ( s2_7a ) ,
179 . cout ( c2_78a )
180 );
181 structural_fa fa_s2_c7b (
182 .a ( pp [6][1]) ,
183 .b ( pp [7][0]) ,
184 . cin ( c1_67 ) ,
185 . sum ( s2_7b ) ,
7
186 . cout ( c2_78b )
187 );
188
189 // col 8 ( h =6 + c2_78a + c2_78b = 8 ? 4) : 2 FA
190 logic s2_8a , c2_89a ;
191 logic s2_8b , c2_89b ;
192
193 structural_fa fa_s2_c8a (
194 .a ( s1_8a ) ,
195 .b ( s1_8b ) ,
196 . cin ( pp [7][1]) ,
197 . sum ( s2_8a ) ,
198 . cout ( c2_89a )
199 );
200 structural_fa fa_s2_c8b (
201 .a ( corr8 ) ,
202 .b ( c1_78a ) ,
203 . cin ( c1_78b ) ,
204 . sum ( s2_8b ) ,
205 . cout ( c2_89b )
206 );
207
208 // --- col 9 ( h =6 + c2_89a + c2_89b = 8 ? 4) : 2 FA
-----------------
209 logic s2_9a , c2_910a ;
210 logic s2_9b , c2_910b ;
211
212 structural_fa fa_s2_c9a (
213 .a ( s1_9a ) ,
214 .b ( pp [5][4]) ,
215 . cin ( pp [6][3]) ,
216 . sum ( s2_9a ) ,
217 . cout ( c2_910a )
218 );
219 structural_fa fa_s2_c9b (
220 .a ( pp [7][2]) ,
221 .b ( c1_89a ) ,
222 . cin ( c1_89b ) ,
223 . sum ( s2_9b ) ,
224 . cout ( c2_910b )
225 );
226
227 // --- col 10 ( h =6 + c2_910a + c2_910b = 8 ? 4) : 2 FA
---------------
228 logic s2_10a , c2_1011a ;
229 logic s2_10b , c2_1011b ;
230
231 structural_fa fa_s2_c10a (
232 .a ( pp [3][7]) ,
233 .b ( pp [4][6]) ,
234 . cin ( pp [5][5]) ,
235 . sum ( s2_10a ) ,
236 . cout ( c2_1011a )
237 );
238 structural_fa fa_s2_c10b (
239 .a ( pp [6][4]) ,
240 .b ( pp [7][3]) ,
241 . cin ( c1_910 ) ,
8
242 . sum ( s2_10b ) ,
243 . cout ( c2_1011b )
244 );
245
246 // --- col 11 ( h =4 + c2_1011a + c2_1011b = 6 ? 4) : 1 FA
-------------
247 logic s2_11a , c2_1112 ;
248 structural_fa fa_s2_c11 (
249 .a ( pp [4][7]) ,
250 .b ( pp [5][6]) ,
251 . cin ( pp [6][5]) ,
252 . sum ( s2_11a ) ,
253 . cout ( c2_1112 )
254 );
255
256 // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
257 // STAGE 3 ? Reduce to target height 3
258 // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
259
260 // --- col 3 ( h =4 ? 3) : 1 HA - - - - - - - - - - -
261 logic s3_3a , c3_34 ;
262 structural_ha ha_s3_c3 (
263 .a ( pp [0][3]) ,
264 .b ( pp [1][2]) ,
265 . sum ( s3_3a ) ,
266 . cout ( c3_34 )
267 );
268
269 // --- col 4 ( h =4 + c3_34 = 5 ? 3) : 1 FA
----------------------------
270 logic s3_4a , c3_45 ;
271 structural_fa fa_s3_c4 (
272 .a ( s2_4a ) ,
273 .b ( pp [2][2]) ,
274 . cin ( pp [3][1]) ,
275 . sum ( s3_4a ) ,
276 . cout ( c3_45 )
277 );
278
279 // --- col 5 ( h =4 + c3_45 = 5 ? 3) : 1 FA
----------------------------
280 logic s3_5a , c3_56 ;
281 structural_fa fa_s3_c5 (
282 .a ( s2_5a ) ,
283 .b ( s2_5b ) ,
284 . cin ( pp [5][0]) ,
285 . sum ( s3_5a ) ,
286 . cout ( c3_56 )
287 );
288
289 // --- col 6 ( h =4 + c3_56 = 5 ? 3) : 1 FA
----------------------------
290 logic s3_6a , c3_67 ;
291 structural_fa fa_s3_c6 (
292 .a ( s2_6a ) ,
293 .b ( s2_6b ) ,
294 . cin ( c2_56a ) ,
295 . sum ( s3_6a ) ,
9
296 . cout ( c3_67 )
297 );
298
299 // --- col 7 ( h =4 + c3_67 = 5 ? 3) : 1 FA
----------------------------
300 logic s3_7a , c3_78 ;
301 structural_fa fa_s3_c7 (
302 .a ( s2_7a ) ,
303 .b ( s2_7b ) ,
304 . cin ( c2_67a ) ,
305 . sum ( s3_7a ) ,
306 . cout ( c3_78 )
307 );
308
309 // --- col 8 ( h =4 + c3_78 = 5 ? 3) : 1 FA
----------------------------
310 logic s3_8a , c3_89 ;
311 structural_fa fa_s3_c8 (
312 .a ( s2_8a ) ,
313 .b ( s2_8b ) ,
314 . cin ( c2_78a ) ,
315 . sum ( s3_8a ) ,
316 . cout ( c3_89 )
317 );
318
319 // --- col 9 ( h =4 + c3_89 = 5 ? 3) : 1 FA
----------------------------
320 logic s3_9a , c3_910 ;
321 structural_fa fa_s3_c9 (
322 .a ( s2_9a ) ,
323 .b ( s2_9b ) ,
324 . cin ( c2_89a ) ,
325 . sum ( s3_9a ) ,
326 . cout ( c3_910 )
327 );
328
329 // --- col 10 ( h =4 + c3_910 = 5 ? 3) : 1 FA
---------------------------
330 logic s3_10a , c3_1011 ;
331 structural_fa fa_s3_c10 (
332 .a ( s2_10a ) ,
333 .b ( s2_10b ) ,
334 . cin ( c2_910a ) ,
335 . sum ( s3_10a ) ,
336 . cout ( c3_1011 )
337 );
338
339 // --- col 11 ( h =4 + c3_1011 = 5 ? 3) : 1 FA
--------------------------
340 logic s3_11a , c3_1112 ;
341 structural_fa fa_s3_c11 (
342 .a ( s2_11a ) ,
343 .b ( pp [7][4]) ,
344 . cin ( c2_1011a ) ,
345 . sum ( s3_11a ) ,
346 . cout ( c3_1112 )
347 );
348
10
349 // --- col 12 ( h =4 + c3_1112 = 5 ? 3) : 1 FA
--------------------------
350 logic s3_12a , c3_1213 ;
351 structural_fa fa_s3_c12 (
352 .a ( pp [5][7]) ,
353 .b ( pp [6][6]) ,
354 . cin ( pp [7][5]) ,
355 . sum ( s3_12a ) ,
356 . cout ( c3_1213 )
357 );
358
359
360 // STAGE 4 ? Reduce to target height 2 ( final two - row
representation )
361
362 logic [15:0] sum_vec ;
363 logic [15:0] car_vec ;
364
365 logic c4_23 , c4_34 , c4_45 , c4_56 , c4_67 , c4_78 ;
366 logic c4_89 , c4_910 , c4_1011 , c4_1112 , c4_1213 , c4_1314 ;
367
368 structural_fa fa_s4_c2 (. a ( pp [0][2]) , . b ( pp [1][1]) , . cin ( pp
[2][0]) , . sum ( sum_vec [2]) , . cout ( c4_23 ) ) ;
369 structural_fa fa_s4_c3 (. a ( s3_3a ) , . b ( pp [2][1]) , . cin ( pp
[3][0]) , . sum ( sum_vec [3]) , . cout ( c4_34 ) ) ;
370 structural_fa fa_s4_c4 (. a ( s3_4a ) , . b ( pp [4][0]) , . cin ( c3_34
), . sum ( sum_vec [4]) , . cout ( c4_45 ) ) ;
371 structural_fa fa_s4_c5 (. a ( s3_5a ) , . b ( c2_45 ) , . cin ( c3_45
), . sum ( sum_vec [5]) , . cout ( c4_56 ) ) ;
372 structural_fa fa_s4_c6 (. a ( s3_6a ) , . b ( c2_56b ) , . cin ( c3_56
), . sum ( sum_vec [6]) , . cout ( c4_67 ) ) ;
373 structural_fa fa_s4_c7 (. a ( s3_7a ) , . b ( c2_67b ) , . cin ( c3_67
), . sum ( sum_vec [7]) , . cout ( c4_78 ) ) ;
374 structural_fa fa_s4_c8 (. a ( s3_8a ) , . b ( c2_78b ) , . cin ( c3_78
), . sum ( sum_vec [8]) , . cout ( c4_89 ) ) ;
375 structural_fa fa_s4_c9 (. a ( s3_9a ) , . b ( c2_89b ) , . cin ( c3_89
), . sum ( sum_vec [9]) , . cout ( c4_910 ) ) ;
376 structural_fa fa_s4_c10 (. a ( s3_10a ) , . b ( c2_910b ) , . cin (
c3_910 ) , . sum ( sum_vec [10]) , . cout ( c4_1011 ) ) ;
377 structural_fa fa_s4_c11 (. a ( s3_11a ) , . b ( c2_1011b ) , . cin (
c3_1011 ) , . sum ( sum_vec [11]) , . cout ( c4_1112 ) ) ;
378 structural_fa fa_s4_c12 (. a ( s3_12a ) , . b ( c2_1112 ) , . cin (
c3_1112 ) , . sum ( sum_vec [12]) , . cout ( c4_1213 ) ) ;
379 structural_fa fa_s4_c13 (. a ( pp [6][7]) , . b ( pp [7][6]) , . cin (
c3_1213 ) , . sum ( sum_vec [13]) , . cout ( c4_1314 ) ) ;
380
381 // Direct mappings
382 assign sum_vec [0] = pp [0][0];
383 assign sum_vec [1] = pp [0][1];
384 assign sum_vec [14] = pp [7][7];
385 assign sum_vec [15] = 1 ’ b0 ;
386
387 // Carry vector routing
388 assign car_vec [0] = 1 ’ b0 ;
389 assign car_vec [1] = pp [1][0];
390 assign car_vec [2] = 1 ’ b0 ;
391 assign car_vec [3] = c4_23 ;
392 assign car_vec [4] = c4_34 ;
11
393 assign car_vec [5] = c4_45 ;
394 assign car_vec [6] = c4_56 ;
395 assign car_vec [7] = c4_67 ;
396 assign car_vec [8] = c4_78 ;
397 assign car_vec [9] = c4_89 ;
398 assign car_vec [10] = c4_910 ;
399 assign car_vec [11] = c4_1011 ;
400 assign car_vec [12] = c4_1112 ;
401 assign car_vec [13] = c4_1213 ;
402 assign car_vec [14] = c4_1314 ;
403 assign car_vec [15] = corr15 ;
404
405
406 always_ff @ ( posedge clk or negedge rst_n ) begin
407 if (! rst_n ) begin
408 product_q8_8 <= 16 ’ sd0 ;
409 end else begin
410 product_q8_8 <= $signed ( sum_vec ) + $signed ( car_vec ) ;
411 end
412 end
413
414 endmodule
Listing 1.1: FFT RTL Code
1.4 Functional Verification
Listing 1.2: Testbench for the Parallel Sorting Architecture
1
3 ‘timescale 1 ns /1 ps
4
5 module tb_so rt8_pa rallel ;
6
7 parameter WIDTH = 8;
8
9 reg clk ;
10 reg rst_n ;
11
12 reg [ WIDTH -1:0] x1 , x2 , x3 , x4 ;
13 reg [ WIDTH -1:0] x5 , x6 , x7 , x8 ;
14
15 wire [ WIDTH -1:0] y1 , y2 , y3 , y4 ;
16 wire [ WIDTH -1:0] y5 , y6 , y7 , y8 ;
17
18 // DUT Instantiation
19 sort8_parallel #( WIDTH ) DUT (
20 . clk ( clk ) ,
21 . rst_n ( rst_n ) ,
22 . x1 ( x1 ) , . x2 ( x2 ) , . x3 ( x3 ) , . x4 ( x4 ) ,
23 . x5 ( x5 ) , . x6 ( x6 ) , . x7 ( x7 ) , . x8 ( x8 ) ,
24 . y1 ( y1 ) , . y2 ( y2 ) , . y3 ( y3 ) , . y4 ( y4 ) ,
12
25 . y5 ( y5 ) , . y6 ( y6 ) , . y7 ( y7 ) , . y8 ( y8 )
26 );
27
28 // Clock Generation
29 always #5 clk = ~ clk ;
30
31 // Test Stimulus
32 initial begin
33 clk = 0;
34 rst_n = 0;
35
36 x1 = 8 ’ d35 ; x2 = 8 ’ d12 ;
37 x3 = 8 ’ d78 ; x4 = 8 ’ d45 ;
38 x5 = 8 ’ d21 ; x6 = 8 ’ d63 ;
39 x7 = 8 ’ d10 ; x8 = 8 ’ d54 ;
40
41 #20 rst_n = 1;
42
43 #200;
44 $finish ;
45 end
46
47 endmodule
Figure 1.1: Matrix Multiplication Waveform
13
1.5 Logic Synthesis
Logic synthesis converts high-level Verilog RTL descriptions into a technology-mapped gate-
level netlist using the open-source **Yosys** synthesis suite. Yosys processes structural
and behavioral RTL constructs, performs high-level optimizations, and maps the design
logic to target standard cell Liberty (.lib) libraries using the **nandgate45** technology
mapping engine.
1.5.1 Yosys Flow
The synthesis workflow is driven by a Yosys script (‘.tcl‘ or ‘.ys‘) that orchestrates RTL
parsing, elaboration, technology mapping, and netlist generation.
Listing 1.3: TCL Script to generate netlist
1 # Read Liberty
2 read_liberty - lib ../ lib / N a n g a t e O p e n C e l l L i b r a r y _ t y p i c a l . lib
3
4 # Read RTL
5 read_verilog ../ rtl /* . v
6
7 # Top module
8 hierarchy - check - top matrix_mul . v
9
10 # Generic synthesis
11 synth - top kmeans
12
13 # Technology mapping
14 dfflibmap - liberty ../ lib / N a n g a t e O p e n C e l l L i b r a r y _ t y p i c a l . lib
15 abc - liberty ../ lib / N a n g a t e O p e n C e l l L i b r a r y _ t y p i c a l . lib
16
17 # Clean up
18 opt_clean
19 check
20
21 # Write synthesized netlist
22 write_verilog results / matrix_mul . v
1.5.2 Synthesized Netlist
Following synthesis execution, Yosys exports a clean, structural gate-level Verilog netlist
mapped to target technology cells.
14
Figure 1.2: Matrix Multiplication Netlist
Figure 1.3: Matrix Multiplication Netlist
Verilog
1.5.3 Synthesis Report
Post-synthesis performance, gate count, and static power metrics are generated. OpenSTA
evaluates static timing across target operating corners to confirm that setup and hold
timing constraints are met prior to floorplanning.
15
Table 1.1: Synthesis Summary of the Dadda 8×8 Signed Multiplier
Parameter Value
Synthesis Tool Yosys
Technology Library Nangate45
Top Module dadda 8x8 signed
Total Standard Cells 250
Sequential Cells 16
Combinational Cells 234
Estimated Chip Area 470.554 µm2
Area Occupied by Sequential Cells 85.120 µm2
Sequential Area Percentage 18.09%
Synthesis Status Successful
1.6 Floorplanning
1.6.1 Setup
Physical implementation in OpenROAD begins by ingesting technology LEF, standard
cell LEF, Liberty files, and the synthesized gate-level netlist.
1.6.2 Floorplan Parameters
Table 1.2: Floorplanning Summary
Parameter Value
WNS 0.00 ns
TNS 0.00 ns
Worst Slack 7.95 ns
Minimum Clock Period 2.05 ns
Maximum Operating Frequency 486.96 MHz
Timing Status MET
16
1.6.3 Floorplan Output
Figure 1.4: Floorplan
1.7 Placement
Placement positions standard cell instances inside the core area using OpenROAD’s
automated placement engines:
1. Global Placement: Executed using the **RePlace** engine, an electrostatics-
based analytical placer that distributes instances across the core area to minimize
wirelength and wire congestion without enforcing row snapping.
2. Detailed Placement: Executed using OpenROAD’s **Detailed Placer (DPL)**,
which snaps cell instances to valid standard cell sites, resolves cell overlaps, and
legalizes cell positions to ensure a 100% placement DRC-clean layout.
17
1.7.1 Final Placement
Figure 1.5: Final Placement
1.8 Clock Tree Synthesis
Clock Tree Synthesis is executed in OpenROAD using **TritonCTS**, which constructs
balanced H-tree topologies to minimize clock skew and insertion delay across flip-flops.
Following CTS, global routing (**FastRoute**) generates grid-level tile paths, and de-
tailed routing (**TritonRoute**) places exact physical wires and vias to achieve 100%
connectivity and DRC-clean routing.
18
1.8.1 CTS Results
Figure 1.6: Clock Tree
1.8.2 Timing Report
Table 1.3: Timing Analysis Summary
Parameter Value
Worst Negative Slack (WNS) 0.00 ns
Total Negative Slack (TNS) 0.00 ns
Worst Slack 6.47 ns
Minimum Clock Period 3.53 ns
Maximum Operating Frequency 283.29 MHz
Hold Timing MET
Setup Timing MET
Overall Timing Status Timing Closure Achieved
19
1.9 Routing
Routing in the open-source OpenROAD flow manages routing complexity using a decoupled
two-stage architecture: **Global Routing** followed by **Detailed Routing**. This
approach separates high-level wire planning from fine-grained physical track assignment
and DRC closure.
1.9.1 Global Routing
Global routing is performed using the integrated **FastRoute** engine. FastRoute does
not lay down actual physical metal wires; instead, it plans topological paths across a 3D
grid of Global Cells (GCells):
• Congestion Mitigation: Evaluates available track capacity against net density
across metal layers to avoid routing bottlenecks.
• Routing Guide Generation: Generates 3D spatial region boxes known as Routing
Guides for every signal net. These guides define the bounding corridor inside which
the detailed router must place physical wires.
• Antenna Strategy: Analyzes long interconnects for process antenna hazards,
triggering layer hops or antenna diode insertion where necessary.
20
Figure 1.7: Final Routing
21
1.9.2 GDSII Layout
Figure 1.8: Final Layout
22
1.10 Performance Results
Table 1.4: Performance Summary of the Dadda 8×8 Signed Multiplier
Metric Value
Technology Library Nangate45
RTL Language Verilog HDL
Total Standard Cells 250
Sequential Cells 16
Combinational Cells 234
Estimated Chip Area 470.554 µm2
Total Power 1.22 × 10−4 W
Worst Negative Slack (WNS) 0.00 ns
Total Negative Slack (TNS) 0.00 ns
Worst Slack 7.95 ns
Minimum Clock Period 2.05 ns
Maximum Operating Frequency 486.96 MHz
Timing Status MET
1.11 Challenges Encountered
• Implementing the Dadda reduction tree required careful organization of the partial
products into multiple reduction stages using half adders and full adders. Incorrect
mapping of the reduction stages initially resulted in incorrect multiplication outputs.
• Developing a fully structural RTL implementation was challenging, as the mul-
tiplier had to be constructed using individual half-adder and full-adder modules
instead of relying on behavioral multiplication operators. Maintaining correct signal
connectivity across multiple reduction stages required extensive debugging.
• Integrating the structural Verilog design with the OpenROAD ASIC flow required
resolving synthesis issues related to module hierarchy, SystemVerilog compatibility,
technology mapping, and timing constraints before successful physical implementa-
tion.
• Functional verification was performed iteratively to validate the generated partial
products, Dadda reduction stages, and final product output. Multiple simulation
runs were required to identify and correct arithmetic and connectivity errors.
• Achieving timing closure while maintaining a compact hardware implementation
required optimization through buffer insertion, gate sizing, and placement refinement
during the physical design flow. The final implementation successfully met all timing
constraints with positive slack.
23
1.12 Conclusion
This project successfully executed the complete RTL-to-GDSII physical design flow for a
hardware Matrix Multiplier architecture.
Starting from RTL synthesis and SDC constraint optimization, the design progressed
through core floorplanning, global and detailed placement, and Clock Tree Synthesis
(CTS). Detailed routing successfully achieved 100% logical connectivity while eliminating
all physical Design Rule Check (DRC) and process antenna violations.
Post-route timing, power, and area (PPA) signoff verified that setup and hold margins
were satisfied across target operating conditions. The resulting clean GDSII layout
validates the hardware architecture’s performance, routability, and manufacturability,
confirming its readiness for final tape-out.
24