VLSI 电路单元的自动布局-2024华数杯B题

摘要

超大规模集成电路设计通常采用电子设计自动化(EDA)的方式进行,布局是 EDA 工具的核心的核心。本文通过构建的线长评估模型及网格密度评估模型, 并在此基础上对模型进行优化,最后利用模型实现 VLSI 电路单元的自动布局。

问题一:基于结合直线型斯坦纳最小树思想的优化 HPWL 模型评估与电路 单元连线接口坐标相关的线长。本题需要建立与电路单元连线接口坐标相关的线 长评估模型,最小化每组估计线长与对应 RSMT 的差值,应用模型评估总连接 线长。本文首先初步构建常规 HPWL 数学模型,接着创新性地结合直线型斯坦 纳最小树的思想,在模型中加入斯坦纳点,通过曼哈顿距离约束和斯坦纳点位置 条件等对模型进行约束,形成最终的优化模型,详见第页式(1-16)和(1-17)。通过 python 算法进行计算,最终绘制出预估 HPWL 与实际对比图,详见第 8 页图 8

问题二:基于含密度单元约束的最小化总连接线长的优化模型评估网格密 度。本题需要先问题一 HPWL 线长评估模型,再整合密度计算,建立一个最小 化总连接线长且满足单元密度约束的网格密度评估模型,最终通过对比密度阈值, 完成全局布局。问题关键还在于判断网格和电路单元是否重叠后计算网格重叠的 电路单元总面积,求解每个网格的密度单元,最终建立的模型详见式(2-20)和 (2-21)。通过 python 运行优化算法,计算得出优化后的电路单元坐标,详见第 14 页表 1,优化后求解得到全局布局电路单元的位置,详见第 14 页图 14,计算求 得最优总连接线长为 874480,最优全局布线密度为 15.8687%。

问题三:建立动态调整的网格布线密度改进模型。本题要求深入分析给定的 网格布线密度模型,识别并解决其问题,应用改进模型于问题二中全局布局结果, 以重新计算布线密度。经过分析,所给模型仅进行密度计算,无法动态调整布线。 本文基于原有模型,通过加入电路单元、网格以及电路单元连线接口坐标来动态 调整布线。本题基于问题二的方法调整重叠约束条件来计算重叠面积,采用常规 HPEL 公式直接求出布线区域面积以及连接线口外接矩形面积,最终得到改进后 的网格布线密度模型,详见式(3-16)。通过 python 运行上述模型,计算问题 2 中 更新后的全局布局结果的最优全局布线密度为 130.5073%,绘制出网格布线密度 矩阵热力图,详见第 24 页图 23。

问题四:基于优先级法的多目标优化全局布局模型。本题要求基于问题二模 型引入网格布线密度模型,在满足单元密度约束的条件下,最小化总连接线长及 网格布线密度的最大值,为多目标优化问题。本题采用优先级法,由于最小化总 线长优于最小化网格布线密度最大值,先求解最小化总线长的单目标规划模型, 再以总线长最优值为约束,求解最小化网格布线密度的单目标优化模型,建立的 模型详见式(4-11)至(4-15)。通过 python 算法,应用修正后的模型完成全局布局, 计算得到最优总连接线长为 782856,优化后求解得到全局布局电路单元的位置 详见第 23 页图 22,网格布线密度详见第 24 页图 23。 本文成功构建线长评估模型及网格密度评估模型,有效实现动态调整网格布 线,完成电路单元的全局布局。

关键词:优先级法、HPWL 模型、直线型斯坦纳最小树、超大规模集成电路

2.1 问题一 本题需要建立一个与电路单元连线接口坐标相关的线长评估模型,并要求每 组估计线长与对应 RSMT 的差值尽可能小、能应用于评估总连接线长。根据题 目所给 3 组具有不同连线接口数的两种线长估计示意图,知晓了 HPWL 和 RSMT 两种线长的计算方法。 因此,本文首先初步构建常规 HPWL 数学模型。因为在 VLSI 布局中,需要 考虑布线在网格上的约束,线路只能水平或垂直地放置,两个连接线口之间的距 离即为曼哈顿距离。因此在一组电路单元组中,用连接线口横纵坐标的最大值与 最小值的差值表示 HPWL 长度,即连线接口外接矩形周长的一半,再将所有电 路单元组连接线口的线长相加,即为总线长。同时,为了满足每组估计线长尽可 能接近 RSMT,对常规 HPWL 模型进行优化。 本文创新性地借鉴直线型斯坦纳最小树的思想,在模型中加入斯坦纳点,能 够更精确地估计和减少 VLSI 布局中的布线长度,使其更接近 RSMT。通过曼哈 顿距离约束和斯坦纳点位置条件等,对模型进行约束,形成最终的优化模型,输 出附件 1 中的总连接线长和每组估计线长与对应 RSMT 的差值,与常规 HPWL 模型进行对比,比较优劣。

2.2 问题二 本题需要先建立一个与电路单元坐标相关的网格密度评估模型,再联系线长 评估模型,整合密度计算,建立一个最小化总连接线长且满足单元密度约束的优 化模型。最终需要通过与密度阈值对比,完成全局布局,输出总连接线长,并可 视化结果。 在建立网格密度评估模型时,因为只有当网格和电路单元重叠时才有密度, 因此判断二者是否重叠是问题二的关键。当电路单元的右下角在网格的左边或上 方,或电路单元的左下角在网格的右边或下方,二者不重叠,可以通过坐标判定。 在附件二所给条件中,已知布局区域尺寸,以及水平方向、竖直方向网格数,可 以求得每个网格的尺寸,并根据其在水平、竖直方向的位置,求得四个角坐标; 已知每个电路单元左下角坐标和宽度、高度,同样可以求得电路单元四个角的坐 标。若二者重叠,需要计算重叠区域面积,再将网格内所有重叠区域面积相加, 即为网格重叠的电路单元总面积。求解其与网格面积比值,得到每个网格的密度 单元。 由附件二同样已知密度阈值,通过联系问题一 HPWL 线长评估模型,设置 密度阈值约束,建立含密度单元约束的最小化总连接线长的优化模型。运行优化 4 算法,迭代地调整电路单元的位置和可能的斯坦纳点,最终输出总连接线长,并 可视化结果。

2.3 问题三 本题要求对给定的网格布线密度模型进行深入分析,识别并解决其存在的问 题,改进后的模型应能更准确地反映实际的布线情况。随后,将此改进模型应用 于问题 2 中得到的全局布局结果,以重新计算布线密度。最终,需要输出全局布 线密度,并将计算得到的布线密度结果以可视化的方式展现出来。 先对题目中的网格布线密度模型进行分析,发现所给模型仅仅只是简单的密 度计算,并未涉及动态变化。而由问题二可知,在密度阈值的约束下。需要调整 单元密度,即电路单元的位置会发生变化,这是题目所给模型无法解决的。因此, 本文选择在原有模型的基础上,通过加入电路单元、网格以及电路单元连线接口 坐标来动态调整布线以及实现网格布线密度的实时变化。本题在求解布线密度时, 依然涉及重叠面积的计算,可以采用问题二的方法,不同点在于在一组电路单元 中,只要网格坐标的取值在电路单元连线接口坐标的最大值和最小值之间,即为 重叠。而布线区域面积以及连接线口外接矩形面积带入坐标可用常规 HPEL 公式 直接求出,最终得到改进后的网格布线密度模型。在问题二更新后的全局布局结 果的基础上,利用改进后模型,输出布线密度,并可视化结果。

2.4 问题四 本题要求在问题二模型的基础上,引入网格布线密度模型,在满足单元密度 约束的条件下,既最小化总连接线长,又最小化网格布线密度最大值。根据所提 供信息,输出总连接线长,并可视化结果。 因为需要满足两个目标,为多目标优化问题。先考虑权重法,即将总连接线 长和网格布线密度赋予不同的权重。但在处理数据时发现,由于缺少初始网格布 线密度信息,很难将其归一化,并且二者的权重很难确定,因此权重法不适于本 题。同时,在查询资料时知晓,总线长相较于网格布线密度对信号传播、性能好 坏、制作成本、热管理电路特性等更敏感、更重要,因此选择采用优先级法,根 据目标重要性分为不同优先级,先求优先级高的目标函数的最优值,在确保优先 级高的目标获得不低于最优值的条件下,再求优先级低的目标函数。本题中最小 化总线长优于最小化网格布线密度最大值,先求解最小化总线长的单目标规划模 型,再以最小化总线长最优值为约束,求解最小化网格布线密度的单目标优化模 型,输出最终结果并可视化。

import pandas as pd 
import numpy as np 
import matplotlib.pyplot as plt 
# 读取附件 1 的数据
data = pd.read_excel('附件 1.xlsx') 
def calculate_hpwl(coordinates): 
 x_coords = [coord[0] for coord in coordinates] 
 y_coords = [coord[1] for coord in coordinates] 
 hpwl_x = max(x_coords) - min(x_coords) 
 hpwl_y = max(y_coords) - min(y_coords)
 return hpwl_x + hpwl_y 
def calculate_steiner_points(coordinates): 
 x_coords = [coord[0] for coord in coordinates] 
 y_coords = [coord[1] for coord in coordinates] 
 steiner_x = np.median(x_coords) 
 steiner_y = np.median(y_coords) 
 return steiner_x, steiner_y 
def calculate_optimized_hpwl(coordinates): 
 steiner_point = calculate_steiner_points(coordinates) 
 total_distance = 0 
 for coord in coordinates: 
 total_distance += abs(coord[0] - steiner_point[0]) + abs(coord[1] -
steiner_point[1]) 
 return total_distance 
# 计算每组的预测 HPWL 和表格中的 HPWL 
predicted_hpwl = [] 
actual_hpwl = [] 
predicted_rsmt_diff = [] 
actual_rsmt_diff = [] 
for index, row in data.iterrows(): 
 coordinates = eval(row['(对应连线接口坐标)']) 
 optimized_hpwl = calculate_optimized_hpwl(coordinates) 
 predicted_hpwl.append(optimized_hpwl) 
 actual_hpwl.append(row['HPWL']) 
 predicted_rsmt_diff.append(abs(optimized_hpwl - row['RSMT'])) 
 actual_rsmt_diff.append(abs(row['HPWL'] - row['RSMT'])) 
# 绘制预测的 HPWL 和表格中的 HPWL 对比图线表
plt.figure(figsize=(10, 6)) 
plt.plot(predicted_hpwl, label='Predicted HPWL', marker='o') 
plt.plot(actual_hpwl, label='Actual HPWL', marker='x') 
plt.xlabel('Group Index') 
plt.ylabel('HPWL') 
plt.title('Predicted HPWL vs Actual HPWL') 
plt.legend() 
plt.grid(True) 
plt.savefig('hpwl_comparison.svg', format='svg') 
plt.show() 
# 绘制每组估计线长与对应 RSMT 的差值和实际线长与对应 RSMT 的差值对
比图线表
plt.figure(figsize=(10, 6)) 
plt.plot(predicted_rsmt_diff, label='Difference (Predicted HPWL - RSMT)', 
marker='o') 
plt.plot(actual_rsmt_diff, label='Difference (Actual HPWL - RSMT)', marker='x') 
plt.xlabel('Group Index')
plt.ylabel('Difference') 
plt.title('Difference between HPWL and RSMT') 
plt.legend() 
plt.grid(True) 
plt.savefig('hpwl_rsmt_difference.svg', format='svg') 
plt.show() 

 

import numpy as np 
import pandas as pd 
import matplotlib.pyplot as plt 
# 参数设置
layout_width = 38080 
layout_height = 37800 
grid_width = layout_width / 64 
grid_height = layout_height / 60 
density_threshold = 0.9 
# 从 Excel 文件中读取电路单元数据
def read_cells_from_excel(file_path): 
 df = pd.read_excel(file_path) 
 cells = [] 
 for index, row in df.iterrows(): 
 # 解析(左下角 X,Y 坐标)字段
 coords = row["(左下角 X,Y 坐标)"].strip('()').split(',') 
 x = int(coords[0]) 
 y = int(coords[1]) 
 cells.append({ 
 "name": row["电路单元名称"], 
 "x": x, 
 "y": y, 
 "width": int(row["宽度"]), 
 "height": int(row["高度"]) 
 }) 
 return cells 
# 计算电路单元的四个角坐标
def calculate_cell_corners(cell): 
 left = cell["x"] 
 right = cell["x"] + cell["width"] 
 bottom = cell["y"] 
 top = cell["y"] + cell["height"] 
 return left, right, bottom, top 
# 计算网格密度
def calculate_grid_density(cells, grid_width, grid_height): 
 grid_density = np.zeros((64, 60))
 for cell in cells: 
 left, right, bottom, top = calculate_cell_corners(cell) 
 x_start = int(left / grid_width) 
 x_end = int(right / grid_width) 
 y_start = int(bottom / grid_height) 
 y_end = int(top / grid_height) 
 for i in range(x_start, x_end + 1): 
 for j in range(y_start, y_end + 1): 
 if 0 <= i < 64 and 0 <= j < 60: 
 grid_density[i, j] += cell["width"] * cell["height"] 
 grid_density /= (grid_width * grid_height) 
 return grid_density 
# 计算全局布线密度
def calculate_global_routing_density(grid_density): 
 return np.mean(grid_density) 
# 计算总连接线长(HPWL)
def calculate_total_hpwl(cells): 
 total_hpwl = 0 
 for cell in cells: 
 left, right, bottom, top = calculate_cell_corners(cell) 
 hpwl = (right - left) + (top - bottom) # 计算 HPWL 
 total_hpwl += hpwl 
 return total_hpwl 
# 优化布局
def optimize_layout(cells, grid_width, grid_height, density_threshold): 
 best_layout = cells.copy() 
 best_total_hpwl = calculate_total_hpwl(best_layout) 
 best_density = calculate_grid_density(best_layout, grid_width, grid_height) 
 best_global_density = calculate_global_routing_density(best_density) 
 
 for _ in range(1000): # 迭代次数
 new_layout = best_layout.copy() 
 # 随机移动一个单元
 cell_to_move = np.random.choice(new_layout) 
 cell_to_move["x"] += np.random.randint(-100, 100) 
 cell_to_move["y"] += np.random.randint(-100, 100) 
 
 new_total_hpwl = calculate_total_hpwl(new_layout) 
 new_density = calculate_grid_density(new_layout, grid_width, 
grid_height) 
 new_global_density = calculate_global_routing_density(new_density) 
 
 if new_total_hpwl < best_total_hpwl and np.all(new_density <= 
density_threshold): 
 best_layout = new_layout 
 best_total_hpwl = new_total_hpwl
 best_density = new_density 
 best_global_density = new_global_density 
 
 return best_layout, best_total_hpwl, best_global_density 
# 导出电路单元坐标位置
def export_cell_positions(cells, file_path): 
 data = [] 
 for cell in cells: 
 data.append({ 
 "电路单元名称": cell["name"], 
 "(左下角 X,Y 坐标)": f"({cell['x']},{cell['y']})", 
 "宽度": cell["width"], 
 "高度": cell["height"] 
 }) 
 df = pd.DataFrame(data) 
 df.to_excel(file_path, index=False) 
# 读取 Excel 文件
file_path = "附件 2.xlsx" 
cells = read_cells_from_excel(file_path) 
# 运行优化
best_layout, best_total_hpwl, best_global_density = optimize_layout(cells, 
grid_width, grid_height, density_threshold) 
# 导出优化后的电路单元坐标位置
export_cell_positions(best_layout, "优化后的电路单元坐标位置.xlsx") 
# 可视化结果
plt.figure(figsize=(10, 10)) 
for cell in best_layout: 
 plt.gca().add_patch(plt.Rectangle((cell["x"], cell["y"]), cell["width"],
cell["height"], fill=True, color='blue', alpha=0.5)) 
plt.xlim(0, layout_width) 
plt.ylim(0, layout_height) 
plt.title(f"Total HPWL: {best_total_hpwl}, Global Density: 
{best_global_density:.4f}") 
# 保存为 SVG 图像
plt.savefig("best_layout.svg", format='svg') 
plt.show() 
print(f"最优总连接线长(HPWL): {best_total_hpwl}") 
print(f"最优全局布线密度: {best_global_density:.4f}") 
import numpy as np 
import pandas as pd 
import matplotlib.pyplot as plt 
# 读取附件 1 和附件 2 的数据
attachment1 = pd.read_excel('附件 1.xlsx') 
attachment2 = pd.read_excel('附件 2.xlsx') 
# 布局区域尺寸和网格划分
layout_width = 38080 
layout_height = 37800 
grid_width = 64 
grid_height = 60 
density_threshold = 0.9 
# 计算网格尺寸
grid_size_x = layout_width / grid_width 
grid_size_y = layout_height / grid_height 
# 初始化网格布线密度矩阵
grid_routing_density = np.zeros((grid_height, grid_width)) 
# 改进的网格布线密度模型
def calculate_routing_density(group, cell_info): 
 total_density = 0 
 for _, row in group.iterrows(): 
 cell_names = row['组名称'].split(',') 
 coords = row['(对应连线接口坐标)'].strip('()').split('),(') 
 coords = [tuple(map(int, coord.split(','))) for coord in coords] 
 
 # 计算外接矩形的面积
 x_coords = [coord[0] for coord in coords] 
 y_coords = [coord[1] for coord in coords] 
 rect_width = max(x_coords) - min(x_coords) 
 rect_height = max(y_coords) - min(y_coords) 
 rect_area = rect_width * rect_height 
 
 # 计算布线区域面积
 hpwl = row['HPWL'] 
 routing_area = hpwl * 1 # 假设线宽为 1 
 
 # 计算每组单元的布线密度
 if rect_area == 0: 
 continue 
 density = routing_area / rect_area 
 
 # 计算重叠面积
 for i in range(grid_height): 
 for j in range(grid_width): 
 grid_x = j * grid_size_x 
 grid_y = i * grid_size_y 
 overlap_width = min(max(x_coords), grid_x + grid_size_x) -
max(min(x_coords), grid_x) 
 overlap_height = min(max(y_coords), grid_y + grid_size_y) -
max(min(y_coords), grid_y) 
 if overlap_width > 0 and overlap_height > 0: 
 overlap_area = overlap_width * overlap_height 
 grid_routing_density[i, j] += density * overlap_area 
 
 return grid_routing_density 
# 应用改进后的布线密度模型
grid_routing_density = calculate_routing_density(attachment1, attachment2) 
# 计算全局布线密度
global_routing_density = np.mean(grid_routing_density) 
# 可视化结果
plt.imshow(grid_routing_density, cmap='hot_r', interpolation='nearest') 
plt.colorbar(label='布线密度') 
plt.title(f'全局布线密度: {global_routing_density:.4f}') 
plt.xlabel('网格列') 
plt.ylabel('网格行') 
# 保存为 SVG 图像
plt.savefig("grid_routing_density.svg", format='svg') 
plt.show() 
print(f"全局布线密度: {global_routing_density:.4f}" 
import numpy as np 
import pandas as pd 
from scipy.optimize import minimize 
# 读取数据
def load_data(): 
 group_data = pd.read_excel('附件 1.xlsx', sheet_name='Sheet1') 
 cell_data = pd.read_excel('附件 2.xlsx', sheet_name='Sheet1') 
 return group_data, cell_data 
# 计算曼哈顿距离
def manhattan_distance(p1, p2):
 return abs(p1[0] - p2[0]) + abs(p1[1] - p2[1]) 
# 主目标函数: 最小化总连接线长
def objective_function(params, *data): 
 group_data, cell_data = data 
 total_length = 0 
 for group in group_data.values: 
 coords = [tuple(map(int, coord.strip('()').split(','))) for coord in 
group[2].strip('()').split('),(')] 
 length = sum(manhattan_distance(coords[i], coords[i+1]) for i in 
range(len(coords) - 1)) 
 total_length += length 
 return total_length 
# 约束条件: 网格密度不超过密度阈值
def constraint_density(params, *data): 
 group_data, cell_data = data 
 density = 0 
 return 0.9 - density 
# 约束条件: 斯坦纳点位置约束
def constraint_steiner(params, *data): 
 group_data, cell_data = data 
 return 0 
# 初始猜测
initial_guess = np.random.rand(10) # 或者根据实际情况设置
# 读取数据
group_data, cell_data = load_data() 
# 设定约束
constraints = [{'type': 'ineq', 'fun': constraint_density, 'args': (group_data, cell_data)},
 {'type': 'eq', 'fun': constraint_steiner, 'args': (group_data, 
cell_data)}] 
# 最小化总连接线长
result = minimize(objective_function, initial_guess, args=(group_data, cell_data), 
 constraints=constraints, method='SLSQP') 
# 打印结果
print("最优总连接线长:", result.fun) 
print("最优解:", result.x)

以上是四个的代码,模型的化不难,这里没有太多空间能展开细说啦,要完整PDF私信我!!!

你可能感兴趣的:(算法,python,数学建模)