一、前序数据输入matlab前处理(python脚本)
1.生成三个python字典:次数numdict,位置posdict,功耗powerdict
次数:
输入文件:上一篇文章的统计结果addi.txt(提取两个下划线中间的数值,也就是标准单元例化名字)
注意:这个脚本处理前提是:例化名字是唯一处于两个下划线之间的内容,所以,提前去除其他包含下划线的字符的下划线比如:tb.cpu0.pc_dff._147_.count[31:0]: 0变成tb.cpu0.pcdff._147_.count[31:0]: 0
# 读取输入文件内容
with open('addi.txt', 'r') as file:
data = file.readlines()
# 处理每一行数据并生成字典
output_data = []
for line in data:
line = line.strip()
parts = line.split('_')
key = parts[1] # 提取两个下划线之间的数字作为键
num0 = parts[2].split(':')
num = [num0[2].strip()]
num = [int(val) for val in num]
output_data.append({key: num})
# 将结果写入输出文档
with open('numdict.py', 'w') as file:
file.write("numdict = {")
i = 0
for entry in output_data:
for key, num in entry.items():
i=i+1
if i == len(output_data):
file.write(f"{key}: ({str(num[0])})")
else:
file.write(f"{key}: ({str(num[0])}),\n")
file.write("}")
得到存于numdict.py的numdict:
位置:
读取文件cpu.pl1,方便起见我改了个文件属性变成txt
# 读取输入文件内容
with open('cpu.txt', 'r') as file:
data = file.readlines()
# 处理每一行数据并生成字典
output_data = []
for line in data:
line = line.strip()
parts = line.split('_')
if len(parts) >= 3:
key = parts[1] # 提取两个下划线之间的数字作为键
name0 = parts[0].split(':')
name = [str(name0[0])]
values = parts[2].split() # 使用':'分割前半部分,使用空格分割后半部分
values = [value.strip() for value in values] # 去除每个值的首尾空格
values = [float(val) for val in values]
last = name + values
output_data.append({key: last})
# 将结果写入输出文档
with open('posdict.py', 'w') as file:
file.write("posdict = {")
i = 0
for entry in output_data:
for key, last in entry.items():
i=i+1
if i == len(output_data):
file.write(f"{key}: ('{str(last[0])}', {', '.join(map(str, last[1:7]))})")
else:
file.write(f"{key}: ('{str(last[0])}', {', '.join(map(str, last[1:7]))}),\n")
file.write("}")
由于位置不会变,这个生成一次就行
功耗:
这个比较短,我就直接发结果(不一定准,自用)
powerdict = {'AND2X1': (15.6059, 0.046772), 'AND2X2': (24.5555, 0.034888), 'AOI21X1': (3.65931, 0.041587), 'AOI22X1': (6.81348, 0.072373), 'BUFX2': (19.7536, 0.014101), 'BUFX4': (51.5028, 0.036479), 'CLKBUF1': (119.075, 0.102383), 'CLKBUF2': (193.042, 0.171404),
'CLKBUF3': (267.008, 0.201889), 'DFFNEGX1': (50.8627, 0.073886), 'DFFPOSX1': (54.9774, 0.059749), 'DFFSR': (108.613, 0.12474), 'HAX1': (47.5649, 0.057877), 'INVX1': (1.74163, 0.004967), 'INVX2': (6.14796, 0.004945),
'INVX4': (12.3002, 0.012778), 'INVX8': (24.6582, 0.025733), 'LATCH': (24.5033, 0.123419), 'MUX2X1': (18.5503, 0.072023),
'NAND2X1': (3.29145, 0.018007), 'NAND3X1': (4.88738, 0.039227), 'NOR2X1': (3.61973, 0.018734), 'NOR3X1': (5.61171, 0.046889), 'OAI21X1': (5.1294, 0.040615), 'OR2X1': (13.7435, 0.049982),
'OR2X2': (22.6823, 0.038755), 'TBUFX1': (7.95467, 0.042784), 'TBUFX2': (18.1304, 0.057063), 'XNOR2X1': (29.9796, 0.112326), 'XOR2X1': (45.1492, 0.112719)}
2.用三个字典输出matlab能处理的数据
from posdict import posdict
from numdict import numdict
from power import powerdict
# 找到位置字典的每一个键名称
for key in posdict.keys():
# 对应找到每一个键在次数字典中所对应的键值(一位的元组)
if key in posdict and key in numdict:
posdict[key][5] = numdict[key] #第五位是次数
name = posdict[key][0]
if name in powerdict:
posdict[key][6] = powerdict[name][0] #第六位是静态
posdict[key][7] = powerdict[name][1]* posdict[key][5] #第七位是总动态
# 打开文件以写入模式
with open("addimat.txt", "w") as file:
# 遍历位置字典的每个键值对
for key, value in posdict.items():
# 将键和值转换为字符串,并写入文件
#file.write(f"{key}: {str(value[0])}, {str(value[1])}, {str(value[2])}, {str(value[3])}, {str(value[4])}, {str(value[5])}, {str(value[6])}, {str(value[7])}\n")
file.write(f"{key} {' '.join(map(str, value))}\n")
二、matlab数据处理,生成热力图
整理虚拟机得到的数据:
切换win,打开matlab
% 打开文档以读取模式
fileID = fopen('jalrmat.txt', 'r');
formatSpec = '%s %s %f %f %f %f %f %f %f';
dataArray = textscan(fileID, formatSpec);
fclose(fileID);
% 将数据存储在变量中
names = dataArray{1}; % 字符串数组
types = dataArray{2}; % 第二列数值数组
left_x_values = dataArray{3}; % 第三列数值数组
left_y_values = dataArray{4}; % 字符串数组
right_x_values = dataArray{5}; % 第三列数值数组
right_y_values = dataArray{6}; % 字符串数组
nums = dataArray{7}; % 字符串数组
power_leak = dataArray{8}; % 字符串数组
power_num = dataArray{9}; % 字符串数组
power_all = power_leak + power_num;
% 计算矩形的中心坐标以及宽度和高度
center_x = (left_x_values + right_x_values) / 2;
center_y = (left_y_values + right_y_values) / 2;
width = right_x_values - left_x_values;
height = right_y_values - left_y_values;
maxleak=max(power_leak);
maxnum=max(power_num);
maxall=max(power_all);
% 创建新的图形窗口for rect
figure(1);
Rect(power_leak, maxleak, 2, 2, 1, 'leak', center_x, center_y,width, height);
Rect(power_num, maxnum, 2, 2, 2, 'num', center_x, center_y,width, height);
Rect(power_all, maxall, 2, 2, [3,4], 'all', center_x, center_y,width, height);
% 将 x、y 坐标和功耗数值数据转换为网格形式
x_unique = unique(center_x);
y_unique = unique(center_y);
[X, Y] = meshgrid(x_unique, y_unique);
% 创建新的图形窗口for rect
figure(2);
smo(X, center_x, center_y, Y, x_unique,y_unique,power_leak, 1, 'leak',2,2,1);
smo(X, center_x, center_y, Y, x_unique,y_unique,power_num, 1, 'num', 2,2,2);
smo(X, center_x, center_y, Y, x_unique,y_unique,power_all, 1, 'all', 2, 2,[3,4]);
function smo(X, x, y, Y, x_unique,y_unique,power, s, title_name,m,n,q)
Z = zeros(size(X));
% 将功耗数值填入网格中
for i = 1:numel(x)
row = find(x_unique == x(i));
col = find(y_unique == y(i));
Z(col, row) = power(i);
end
% 对功耗图像进行高斯平滑处理
sigma = s; % 高斯核的标准差
Z_smooth = imgaussfilt(Z, sigma);
% 绘制功耗图
subplot(m,n,q)
s1=surf(X, Y, Z_smooth);
xlabel('X');
ylabel('Y');
zlabel('Power');
title('JALR Power Consumption',title_name);
% 添加颜色栏
colorbar;
shading flat
s1.FaceColor='interp';
end
function Rect(power_type, power_type_max, m,n,q, title_name, center_x, center_y, width, height)
% 绘制矩形块,并根据能耗值设置颜色
for i = 1:numel(center_x)
power =power_type(i)/power_type_max;
rgb = colormap('jet');
index=round( power *256);
%num绘制
if index == 0
index = index+1;
end
color = rgb(index,:);
%绘图
subplot(m,n,q)
rectangle('Position', [center_x(i)-width(i)/2, center_y(i)-height(i)/2, width(i), height(i)], 'EdgeColor', 'k', 'FaceColor', color);
end
% 添加颜色栏和标签
colormap('jet');
colorbar;
xlabel('X');
ylabel('Y');
title('JALR Rectangle Heatmap', title_name);
end
得到图像: