ZLayout EDA Library v1.0.0
Advanced Electronic Design Automation Layout Library with Bilingual Documentation
Loading...
Searching...
No Matches
advanced_layout_optimization.cpp
Go to the documentation of this file.
1
12
16#include <iostream>
17#include <chrono>
18#include <random>
19
20using namespace zlayout;
21using namespace zlayout::optimization;
22
27private:
28 std::mt19937 rng;
29
30public:
31 EDALayoutDemo() : rng(std::random_device{}()) {}
32
37 std::cout << "\n=== CPU Layout Optimization Demo ===" << std::endl;
38 std::cout << "This demonstrates why EDA layout is a complex, highly-coupled problem" << std::endl;
39
40 // Define chip area (5mm x 5mm)
41 geometry::Rectangle chip_area(0, 0, 5000, 5000);
42
43 // Create optimizer with realistic constraints
44 OptimizationConfig config;
45 config.wirelength_weight = 0.4; // Minimize wire length
46 config.timing_weight = 0.3; // Critical for CPU performance
47 config.area_weight = 0.2; // Minimize total area
48 config.power_weight = 0.1; // Manage power density
49 config.min_spacing = 2.0; // 2μm minimum spacing (advanced node)
50 config.max_iterations = 50000; // Sufficient for convergence
51
52 auto optimizer = OptimizerFactory::create_sa_optimizer(chip_area, config);
53
54 // Create CPU components with realistic properties
55 create_cpu_components(*optimizer);
56 create_cpu_nets(*optimizer);
57
58 std::cout << "Created realistic CPU design with:" << std::endl;
59 std::cout << "- ALU, FPU, Cache blocks" << std::endl;
60 std::cout << "- Critical timing paths" << std::endl;
61 std::cout << "- Power density constraints" << std::endl;
62
63 // Run optimization
64 auto start = std::chrono::high_resolution_clock::now();
65 auto result = optimizer->optimize();
66 auto end = std::chrono::high_resolution_clock::now();
67
68 auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
69
70 // Display results
71 std::cout << "\nOptimization Results:" << std::endl;
72 std::cout << " Total cost: " << result.total_cost << std::endl;
73 std::cout << " Wirelength cost: " << result.wirelength_cost << std::endl;
74 std::cout << " Timing cost: " << result.timing_cost << std::endl;
75 std::cout << " Area cost: " << result.area_cost << std::endl;
76 std::cout << " Power cost: " << result.power_cost << std::endl;
77 std::cout << " Constraint violations: " << result.constraint_violations << std::endl;
78 std::cout << " Optimization time: " << duration.count() << " ms" << std::endl;
79
80 auto stats = optimizer->get_statistics();
81 std::cout << " Acceptance rate: " << stats.acceptance_rate * 100 << "%" << std::endl;
82 std::cout << " Improvement rate: " << stats.improvement_rate * 100 << "%" << std::endl;
83
84 if (result.is_feasible()) {
85 std::cout << "✅ Layout optimization successful!" << std::endl;
86 } else {
87 std::cout << "⚠️ Layout has constraint violations" << std::endl;
88 }
89 }
90
95 std::cout << "\n=== Hierarchical Optimization Demo ===" << std::endl;
96 std::cout << "This shows how to handle billion-scale layouts through hierarchy" << std::endl;
97
98 // Large chip area (20mm x 20mm)
99 geometry::Rectangle chip_area(0, 0, 20000, 20000);
100
101 OptimizationConfig config;
102 config.max_components_per_block = 1000; // Manageable block size
103 config.enable_hierarchical = true;
104
105 auto optimizer = OptimizerFactory::create_hierarchical_optimizer(chip_area, config);
106
107 // Create multiple IP blocks
108 optimizer->create_ip_block("CPU_Core_0", geometry::Rectangle(1000, 1000, 4000, 4000));
109 optimizer->create_ip_block("CPU_Core_1", geometry::Rectangle(6000, 1000, 4000, 4000));
110 optimizer->create_ip_block("GPU_Block", geometry::Rectangle(11000, 1000, 8000, 8000));
111 optimizer->create_ip_block("Memory_Controller", geometry::Rectangle(1000, 6000, 18000, 4000));
112 optimizer->create_ip_block("IO_Complex", geometry::Rectangle(1000, 11000, 18000, 8000));
113
114 // Add components to each block
115 create_hierarchical_design(*optimizer);
116
117 std::cout << "Created hierarchical design with:" << std::endl;
118 std::cout << "- Multiple CPU cores" << std::endl;
119 std::cout << "- GPU compute block" << std::endl;
120 std::cout << "- Memory subsystem" << std::endl;
121 std::cout << "- I/O interfaces" << std::endl;
122
123 // Run hierarchical optimization
124 auto start = std::chrono::high_resolution_clock::now();
125 auto result = optimizer->optimize();
126 auto end = std::chrono::high_resolution_clock::now();
127
128 auto duration = std::chrono::duration_cast<std::chrono::seconds>(end - start);
129
130 std::cout << "\nHierarchical Optimization Results:" << std::endl;
131 std::cout << " Total cost: " << result.total_cost << std::endl;
132 std::cout << " Optimization time: " << duration.count() << " seconds" << std::endl;
133
134 auto final_layout = optimizer->get_final_layout();
135 std::cout << " Final layout components: " << final_layout.size() << std::endl;
136
137 std::cout << "✅ Hierarchical optimization demonstrates scalability to billion components!" << std::endl;
138 }
139
144 std::cout << "\n=== Force-Directed Placement Demo ===" << std::endl;
145 std::cout << "Fast initial placement using physics simulation" << std::endl;
146
147 geometry::Rectangle area(0, 0, 1000, 1000);
149
150 // Create simple circuit
151 std::vector<Component> components = {
152 Component("AND1", geometry::Rectangle(0, 0, 10, 10)),
153 Component("OR1", geometry::Rectangle(0, 0, 10, 10)),
154 Component("NOT1", geometry::Rectangle(0, 0, 5, 5)),
155 Component("FF1", geometry::Rectangle(0, 0, 15, 10)),
156 Component("MUX1", geometry::Rectangle(0, 0, 12, 8))
157 };
158
159 for (auto& comp : components) {
160 placer->add_component(&comp);
161 }
162
163 // Create nets that connect the components
164 Net clk_net("CLK");
165 clk_net.driver_component = "FF1";
166 clk_net.driver_pin = "CLK_OUT";
167 clk_net.sinks = {{"AND1", "CLK"}, {"OR1", "CLK"}, {"MUX1", "CLK"}};
168 clk_net.criticality = 1.0; // Critical timing net
169 placer->add_net(clk_net);
170
171 Net data_net("DATA");
172 data_net.driver_component = "AND1";
173 data_net.driver_pin = "OUT";
174 data_net.sinks = {{"OR1", "IN1"}, {"NOT1", "IN"}};
175 placer->add_net(data_net);
176
177 // Run force-directed placement
178 auto start = std::chrono::high_resolution_clock::now();
179 bool converged = placer->optimize(1000);
180 auto end = std::chrono::high_resolution_clock::now();
181
182 auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start);
183
184 std::cout << "Force-directed placement results:" << std::endl;
185 std::cout << " Converged: " << (converged ? "Yes" : "No") << std::endl;
186 std::cout << " Time: " << duration.count() << " μs" << std::endl;
187
188 std::cout << "Final component positions:" << std::endl;
189 for (const auto& comp : components) {
190 std::cout << " " << comp.name << ": ("
191 << comp.position.x << ", " << comp.position.y << ")" << std::endl;
192 }
193
194 std::cout << "✅ Force-directed placement provides fast initial solution!" << std::endl;
195 }
196
201 std::cout << "\n=== Why GPU Acceleration is Limited for EDA Layout ===" << std::endl;
202
203 std::cout << "EDA layout optimization has several characteristics that make GPU acceleration challenging:" << std::endl;
204
205 std::cout << "\n1. 🔗 High Coupling:" << std::endl;
206 std::cout << " - Moving one component affects all connected components" << std::endl;
207 std::cout << " - Like a 'Huarong Dao' puzzle - every move has global effects" << std::endl;
208 std::cout << " - Requires sequential decision making, not parallel computation" << std::endl;
209
210 std::cout << "\n2. 🎯 Complex Objectives:" << std::endl;
211 std::cout << " - Multi-objective optimization (area + timing + power + manufacturing)" << std::endl;
212 std::cout << " - Non-linear constraints (e.g., timing depends on path delays)" << std::endl;
213 std::cout << " - Requires sophisticated cost evaluation, not simple arithmetic" << std::endl;
214
215 std::cout << "\n3. 🧠 Algorithm Nature:" << std::endl;
216 std::cout << " - Simulated annealing uses random moves and acceptance probability" << std::endl;
217 std::cout << " - Force-directed algorithms need iterative convergence" << std::endl;
218 std::cout << " - These are inherently sequential, adaptive algorithms" << std::endl;
219
220 std::cout << "\n4. 📊 Where GPU CAN Help:" << std::endl;
221 std::cout << " - Massive geometry queries (our spatial indexing)" << std::endl;
222 std::cout << " - Design rule checking (parallel DRC on many shapes)" << std::endl;
223 std::cout << " - Timing analysis (parallel path evaluation)" << std::endl;
224 std::cout << " - But NOT the core placement optimization" << std::endl;
225
226 std::cout << "\n✅ Our focus on CPU-based algorithms with sophisticated heuristics" << std::endl;
227 std::cout << " is the right approach for EDA layout optimization!" << std::endl;
228 }
229
234 std::cout << "\n=== Algorithm Performance Comparison ===" << std::endl;
235
236 geometry::Rectangle area(0, 0, 500, 500);
237
238 // Test data
239 std::vector<Component> test_components;
240 std::vector<Net> test_nets;
241 create_test_circuit(test_components, test_nets, 20); // 20 components
242
243 std::cout << "Testing with " << test_components.size() << " components and "
244 << test_nets.size() << " nets" << std::endl;
245
246 // Test Force-Directed Placement
247 std::cout << "\n--- Force-Directed Placement ---" << std::endl;
248 auto start = std::chrono::high_resolution_clock::now();
249
250 auto force_placer = OptimizerFactory::create_force_directed_placer(area);
251 for (auto& comp : test_components) {
252 force_placer->add_component(&comp);
253 }
254 for (const auto& net : test_nets) {
255 force_placer->add_net(net);
256 }
257
258 bool fd_converged = force_placer->optimize(500);
259 auto fd_time = std::chrono::high_resolution_clock::now();
260 auto fd_duration = std::chrono::duration_cast<std::chrono::milliseconds>(fd_time - start);
261
262 std::cout << " Time: " << fd_duration.count() << " ms" << std::endl;
263 std::cout << " Converged: " << (fd_converged ? "Yes" : "No") << std::endl;
264 std::cout << " Best for: Fast initial placement" << std::endl;
265
266 // Test Simulated Annealing
267 std::cout << "\n--- Simulated Annealing ---" << std::endl;
268 start = std::chrono::high_resolution_clock::now();
269
270 OptimizationConfig sa_config;
271 sa_config.max_iterations = 10000; // Reduced for demo
272 auto sa_optimizer = OptimizerFactory::create_sa_optimizer(area, sa_config);
273
274 for (const auto& comp : test_components) {
275 sa_optimizer->add_component(comp);
276 }
277 for (const auto& net : test_nets) {
278 sa_optimizer->add_net(net);
279 }
280
281 auto sa_result = sa_optimizer->optimize();
282 auto sa_time = std::chrono::high_resolution_clock::now();
283 auto sa_duration = std::chrono::duration_cast<std::chrono::milliseconds>(sa_time - start);
284
285 std::cout << " Time: " << sa_duration.count() << " ms" << std::endl;
286 std::cout << " Final cost: " << sa_result.total_cost << std::endl;
287 std::cout << " Feasible: " << (sa_result.is_feasible() ? "Yes" : "No") << std::endl;
288 std::cout << " Best for: High-quality final placement" << std::endl;
289
290 auto sa_stats = sa_optimizer->get_statistics();
291 std::cout << " Acceptance rate: " << sa_stats.acceptance_rate * 100 << "%" << std::endl;
292
293 // Recommendation
294 std::cout << "\n--- Algorithm Recommendation ---" << std::endl;
295 auto recommended = OptimizerFactory::recommend_algorithm(
296 test_components.size(), test_nets.size(), true);
297
298 std::string rec_name;
299 switch (recommended) {
301 rec_name = "Force-Directed"; break;
303 rec_name = "Simulated Annealing"; break;
305 rec_name = "Hierarchical"; break;
307 rec_name = "Timing-Driven"; break;
308 default:
309 rec_name = "Analytical"; break;
310 }
311
312 std::cout << " Recommended algorithm: " << rec_name << std::endl;
313 std::cout << " (Based on problem size and timing criticality)" << std::endl;
314 }
315
316private:
317 void create_cpu_components(SimulatedAnnealingOptimizer& optimizer) {
318 // ALU
319 Component alu("ALU", geometry::Rectangle(0, 0, 100, 80));
320 alu.power_consumption = 500.0; // High power
321 optimizer.add_component(alu);
322
323 // FPU
324 Component fpu("FPU", geometry::Rectangle(0, 0, 120, 90));
325 fpu.power_consumption = 600.0; // Very high power
326 optimizer.add_component(fpu);
327
328 // L1 Cache
329 Component l1_cache("L1_CACHE", geometry::Rectangle(0, 0, 200, 150));
330 l1_cache.power_consumption = 200.0;
331 optimizer.add_component(l1_cache);
332
333 // Register File
334 Component reg_file("REG_FILE", geometry::Rectangle(0, 0, 80, 120));
335 reg_file.power_consumption = 300.0;
336 optimizer.add_component(reg_file);
337
338 // Control Unit
339 Component ctrl_unit("CTRL_UNIT", geometry::Rectangle(0, 0, 150, 100));
340 ctrl_unit.power_consumption = 150.0;
341 optimizer.add_component(ctrl_unit);
342
343 // Instruction Decoder
344 Component decoder("DECODER", geometry::Rectangle(0, 0, 90, 70));
345 decoder.power_consumption = 100.0;
346 optimizer.add_component(decoder);
347 }
348
349 void create_cpu_nets(SimulatedAnnealingOptimizer& optimizer) {
350 // Critical clock network
351 Net clk_net("CLK_TREE");
352 clk_net.driver_component = "CTRL_UNIT";
353 clk_net.driver_pin = "CLK_OUT";
354 clk_net.sinks = {
355 {"ALU", "CLK"}, {"FPU", "CLK"},
356 {"L1_CACHE", "CLK"}, {"REG_FILE", "CLK"}, {"DECODER", "CLK"}
357 };
358 clk_net.criticality = 1.0; // Most critical
359 clk_net.weight = 2.0;
360 optimizer.add_net(clk_net);
361
362 // Data path (critical for performance)
363 Net data_net("DATA_BUS");
364 data_net.driver_component = "REG_FILE";
365 data_net.driver_pin = "DATA_OUT";
366 data_net.sinks = {{"ALU", "A_IN"}, {"FPU", "A_IN"}};
367 data_net.criticality = 0.9;
368 data_net.weight = 1.5;
369 optimizer.add_net(data_net);
370
371 // Instruction path
372 Net inst_net("INST_BUS");
373 inst_net.driver_component = "L1_CACHE";
374 inst_net.driver_pin = "INST_OUT";
375 inst_net.sinks = {{"DECODER", "INST_IN"}, {"CTRL_UNIT", "INST_IN"}};
376 inst_net.criticality = 0.8;
377 optimizer.add_net(inst_net);
378
379 // Control signals
380 Net ctrl_net("CTRL_SIGNALS");
381 ctrl_net.driver_component = "CTRL_UNIT";
382 ctrl_net.driver_pin = "CTRL_OUT";
383 ctrl_net.sinks = {{"ALU", "CTRL"}, {"FPU", "CTRL"}, {"REG_FILE", "CTRL"}};
384 ctrl_net.criticality = 0.7;
385 optimizer.add_net(ctrl_net);
386 }
387
388 void create_hierarchical_design(HierarchicalOptimizer& optimizer) {
389 // Add components to CPU cores
390 for (int core = 0; core < 2; ++core) {
391 std::string block_name = "CPU_Core_" + std::to_string(core);
392
393 optimizer.add_component_to_block(block_name,
394 Component("ALU_" + std::to_string(core), geometry::Rectangle(0, 0, 50, 40)));
395 optimizer.add_component_to_block(block_name,
396 Component("FPU_" + std::to_string(core), geometry::Rectangle(0, 0, 60, 45)));
397 optimizer.add_component_to_block(block_name,
398 Component("L1_" + std::to_string(core), geometry::Rectangle(0, 0, 100, 75)));
399 }
400
401 // Add GPU components
402 for (int sm = 0; sm < 4; ++sm) {
403 optimizer.add_component_to_block("GPU_Block",
404 Component("SM_" + std::to_string(sm), geometry::Rectangle(0, 0, 80, 60)));
405 }
406
407 // Add memory components
408 optimizer.add_component_to_block("Memory_Controller",
409 Component("DDR_CTRL", geometry::Rectangle(0, 0, 200, 100)));
410 optimizer.add_component_to_block("Memory_Controller",
411 Component("L3_CACHE", geometry::Rectangle(0, 0, 300, 150)));
412
413 // Inter-block nets
414 Net memory_bus("MEMORY_BUS");
415 memory_bus.driver_component = "DDR_CTRL";
416 memory_bus.sinks = {{"L3_CACHE", "MEM_IN"}, {"L1_0", "MEM_IN"}, {"L1_1", "MEM_IN"}};
417 memory_bus.criticality = 0.8;
418 optimizer.add_net(memory_bus);
419 }
420
421 void create_test_circuit(std::vector<Component>& components,
422 std::vector<Net>& nets, size_t component_count) {
423 components.clear();
424 nets.clear();
425
426 // Create random components
427 std::uniform_real_distribution<double> size_dist(10, 50);
428 std::uniform_real_distribution<double> power_dist(10, 100);
429
430 for (size_t i = 0; i < component_count; ++i) {
431 double width = size_dist(rng);
432 double height = size_dist(rng);
433
434 Component comp("COMP_" + std::to_string(i),
435 geometry::Rectangle(0, 0, width, height));
436 comp.power_consumption = power_dist(rng);
437 components.push_back(comp);
438 }
439
440 // Create random nets
441 std::uniform_int_distribution<size_t> comp_dist(0, component_count - 1);
442 std::uniform_int_distribution<size_t> fanout_dist(1, 4);
443
444 for (size_t i = 0; i < component_count / 2; ++i) {
445 Net net("NET_" + std::to_string(i));
446
447 // Random driver
448 size_t driver_idx = comp_dist(rng);
449 net.driver_component = components[driver_idx].name;
450 net.driver_pin = "OUT";
451
452 // Random sinks
453 size_t fanout = fanout_dist(rng);
454 for (size_t j = 0; j < fanout; ++j) {
455 size_t sink_idx = comp_dist(rng);
456 if (sink_idx != driver_idx) {
457 net.sinks.emplace_back(components[sink_idx].name, "IN");
458 }
459 }
460
461 net.criticality = (i < 3) ? 0.9 : 0.5; // First few nets are critical
462 nets.push_back(net);
463 }
464 }
465};
466
467int main() {
468 std::cout << "=== Advanced EDA Layout Optimization Demo ===" << std::endl;
469 std::cout << "Demonstrating REAL EDA algorithms for complex layout optimization" << std::endl;
470
471 try {
472 EDALayoutDemo demo;
473
474 // Show why this is the right approach
476
477 // Demonstrate real algorithms
480 demo.compare_algorithms();
481
482 // Show scalability
484
485 std::cout << "\n🎉 All demonstrations completed successfully!" << std::endl;
486 std::cout << "\nKey Takeaways:" << std::endl;
487 std::cout << "✅ EDA layout optimization is a highly-coupled, complex problem" << std::endl;
488 std::cout << "✅ Sophisticated CPU algorithms (SA, force-directed) are more effective than GPU" << std::endl;
489 std::cout << "✅ Hierarchical approaches enable billion-scale optimization" << std::endl;
490 std::cout << "✅ Multi-objective optimization handles real EDA constraints" << std::endl;
491
492 } catch (const std::exception& e) {
493 std::cerr << "Error: " << e.what() << std::endl;
494 return 1;
495 }
496
497 return 0;
498}
Demonstrate the real challenges of EDA layout optimization.
void demonstrate_force_directed_placement()
Demonstrate force-directed placement.
void explain_gpu_limitations()
Show why GPU acceleration isn't suitable for layout optimization.
void demonstrate_hierarchical_optimization()
Demonstrate hierarchical optimization for billion-scale designs.
void demonstrate_cpu_layout_optimization()
Create a realistic CPU design example.
void compare_algorithms()
Algorithm performance comparison.
Axis-aligned rectangle for bounding boxes and simple EDA components.
Definition rectangle.hpp:26
void add_component_to_block(const std::string &block_name, const Component &comp)
Add component to an IP block.
void add_net(const Net &net)
Add net (automatically determines if inter-block or intra-block)
static std::unique_ptr< HierarchicalOptimizer > create_hierarchical_optimizer(const geometry::Rectangle &area, const OptimizationConfig &config=OptimizationConfig{})
static std::unique_ptr< SimulatedAnnealingOptimizer > create_sa_optimizer(const geometry::Rectangle &area, const OptimizationConfig &config=OptimizationConfig{})
static std::unique_ptr< ForceDirectedPlacer > create_force_directed_placer(const geometry::Rectangle &area)
static AlgorithmType recommend_algorithm(size_t component_count, size_t net_count, bool timing_critical=false)
Choose optimal algorithm based on problem characteristics.
Advanced EDA layout optimization algorithms.
Main namespace for ZLayout library.
Definition component.hpp:20
2D Point class for geometric calculations
Axis-aligned rectangle class for bounding boxes and simple components.
Circuit component with connectivity information.
Net (electrical connection) between components.
std::vector< std::pair< std::string, std::string > > sinks
Layout optimization objectives and constraints.