Skip to content

Commit

Permalink
Merge pull request #1 from luccareinehr/main
Browse files Browse the repository at this point in the history
Get mpw-1 folder from OpenFASOC repo
  • Loading branch information
msaligane authored Sep 16, 2022
2 parents 1b40686 + bce9cd2 commit f571097
Show file tree
Hide file tree
Showing 326 changed files with 22,245 additions and 0 deletions.
60 changes: 60 additions & 0 deletions mpw-1/testsetup/MATLAB/CalcAcc.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
ChipNo_list = [11, 12, 13, 14, 15, 16];
temp_list = -40:10:120;
supply_list = [1.8];
TZiK = 273.15; scale = 1;
p1 = 5; % 0C
p2 = 13; % 80C

plim_low = 3; % -20C
plim_high = 15; % 100C

% Re-organize Measured Data
freq_data_array = zeros(length(temp_list), length(supply_list), length(ChipNo_list), 64);
for c=1:length(ChipNo_list)
for t=1:length(temp_list)
for s=1:length(supply_list)
file = ['../MeasResults/ChipNo', num2str(ChipNo_list(c)), '/Meas_ChipNo', num2str(ChipNo_list(c)), '_Vdio3.0Vdd', num2str(supply_list(s)), '_', num2str(temp_list(t)), 'C.csv'];
dtable = readtable(file, 'PreserveVariableNames', 1);
for design = 1:64
freq_data_array(t, s, c, design) = table2array(dtable(design, 'Freq0 (kHz)'));
end
end
end
end

% Fit each node
param_array = zeros(2, length(supply_list), length(ChipNo_list), 64);
T_array = zeros(length(temp_list), length(supply_list), length(ChipNo_list), 64);
T_err_array = zeros(length(temp_list), length(supply_list), length(ChipNo_list), 64);
err_range_array = zeros(4, length(supply_list), length(ChipNo_list), 64);

for c=1:length(ChipNo_list)
for design = 1:64
for s = 1:length(supply_list)
freq_list = freq_data_array(:, s, c, design);
k = (temp_list(p2)-temp_list(p1)) / (log(freq_list(p2))*(temp_list(p2) + TZiK)*scale - log(freq_list(p1))*(temp_list(p1) + TZiK)*scale);
b = -k*log(freq_list(p1))*(temp_list(p1) + TZiK)*scale;
param_array(1, s, c, design) = k; param_array(2, s, c, design) = b;

for t = 1:length(temp_list)
T_array(t, s, c, design) = (scale * TZiK * k * log(freq_list(t)) + b) / (1 - scale * k * log(freq_list(t)));
T_err_array(t, s, c, design) = T_array(t, s, c, design) - temp_list(t);
end
err_range_array(1, s, c, design) = max(T_err_array(plim_low:plim_high, s, c, design)); % largest positive error
err_range_array(2, s, c, design) = min(T_err_array(plim_low:plim_high, s, c, design)); % largest negative error
err_range_array(3, s, c, design) = max(abs(T_err_array(plim_low:plim_high, s, c, design))); % largest absolute error
err_range_array(4, s, c, design) = sum(abs(T_err_array(plim_low:plim_high, s, c, design)))/(plim_high - plim_low + 1 - 2); % mean absolute error
end
end
end

c = 4;
[max_abs_error_lst, design] = min(err_range_array(3, 1, c, :));
fprintf("At 1.8V, Design %d has lowest maximum absolute error of %.4f \n", design, max_abs_error_lst);
[mean_abs_error_lst, design] = min(err_range_array(4, 1, c, :));
fprintf("At 1.8V, Design %d has lowest mean absolute error of %.4f \n", design, mean_abs_error_lst);

%[max_abs_error_lst, design] = min(err_range_array(3, 2, c, :));
%fprintf("At 1.2V, Design %d has lowest maximum absolute error of %.4f \n", design, max_abs_error_lst);
%[mean_abs_error_lst, design] = min(err_range_array(4, 2, c, :));
%fprintf("At 1.2V, Design %d has lowest mean absolute error of %.4f \n", design, mean_abs_error_lst);
41 changes: 41 additions & 0 deletions mpw-1/testsetup/MATLAB/DesignToConfig.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
clc; clear all;
% This script generates an excel sheet that maps the design number of a
% sensor to its silicon configurations: header type, std cell type, N_hdr
% and N_inv.

% Initialize Arrays
SensorDesign = zeros(64,1);
HeaderType = strings(64,1);
StdCellType = strings(64,1);
N_hdr = zeros(64,1);
N_inv = zeros(64,1);

for i = 0:63
SensorDesign(i+1, 1) = i;

% Determine Header Type
hdrType = floor(i/32);
if (hdrType == 0)
HeaderType(i+1, 1) = "A";
else
HeaderType(i+1, 1) = "B";
end

% Determine StdCellType
stdCellType = floor(mod(i, 32)/16);
if (stdCellType == 0)
StdCellType(i+1, 1) = "hs";
else
StdCellType(i+1, 1) = "hd";
end

% Determine N_hdr
N_hdr(i+1, 1) = 2*floor(mod(i, 16)/4) + 3;

% Determine N_inv
N_inv(i+1, 1) = 2*mod(i, 4) + 5;
end

T = table(SensorDesign, HeaderType, StdCellType, N_hdr, N_inv);
filename = "../SensorToConfigMapping.xlsx";
writetable(T, filename, 'Sheet', 'Sheet', 'WriteVariableNames', true);
25 changes: 25 additions & 0 deletions mpw-1/testsetup/MATLAB/EvalDesignFoM.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
function [design, FoM, power, res, EnC] = EvalDesignFoM(drange, min_order, inacc_B_arr, inacc_th, FoM_B_arr, power_B_arr, res_B_arr, EnC_B_arr)
% Find the best design based on FoM

design = 1;
FoM_min = 1e6;
for i = 1:length(drange)
d = drange(i);
% Only find for those with a reasonable inaccuracy
if (inacc_B_arr(1, d) < inacc_th)
[~, sorted_ind] = sort(FoM_B_arr(1, :, d));
FoM_Nth_min = FoM_B_arr(1, sorted_ind(min_order), d);
if (FoM_Nth_min < FoM_min) && (FoM_Nth_min > 0)
FoM_min = FoM_Nth_min;
design = d;
end
end
end

[~, sorted_ind] = sort(FoM_B_arr(1, :, design));
FoM = FoM_B_arr(1, sorted_ind(min_order), design);
power = power_B_arr(1, sorted_ind(min_order), design);
res = res_B_arr(1, sorted_ind(min_order), design);
EnC = EnC_B_arr(1, sorted_ind(min_order), design);

end
102 changes: 102 additions & 0 deletions mpw-1/testsetup/MATLAB/EvalDesignGivenRange.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
function [params, inacc_arr, params_sec, inacc_arr_sec, Nc_A, indlist_A, inacc_B, indlist_B] = ...
EvalDesignGivenRange(freq_arr, tlist, tstart_ind, twin_len, pcalib, inacc_th, Nc_B, order_sec)
% This function evaluate a single temperature design/instance's inaccuracy
% across multiple chips under a given temperature range.
% It returns fitted parameter pairs for each chip,
% inaccuracies across chips and temperatures, and
% metric A: the number of chips with inaccuracy below a threshold and
% their indices, and
% metric B: the minimal-possible max-inaccuracy given the number of good
% chips we need, also return the their indices.

% metric A is about the best reliability or least variation
% while metric B is about the best inaccuracy

% Input:
% freq_arr - Ntemp x Nchip
% tlist - Ntemp x 1
% tstart_ind - 1x1, index of starting temperature
% twin_len - 1x1, length of temperature range, in 10C-step indices
% pcalib - 1x1, calibration point index w.r.t. tstart_ind, e.g., 2 means
% 20C above tlow and under thigh
% inacc_th - 1x1, threshold of inaccuracy
% Nc_B - 1x1, number of good chips we need

% Output:
% params - 2 x Nchip
% inacc_arr - Ntemp x Nchip
% Nc_A - 1x1, the number of chips with inaccuracy below a threshold
% indlist_A - 2 x Nchip, the chip indices for metric A
% inacc_B - 1x1, the minimal-possible max-inaccuracy given Nc_B,
% indlist_B - 2 x Nc_B, the chip indices for metric B

TZiK = 273.15; scale = 1;

[Ntemp, Nchip] = size(freq_arr);
params = zeros(2, Nchip);
T_array = zeros(Ntemp, Nchip);
inacc_arr = zeros(Ntemp, Nchip);
metric_arr = zeros(3, Nchip);

% Fit the design for each chip
p1 = tstart_ind + pcalib;
p2 = tstart_ind + twin_len - pcalib;
for c = 1:Nchip
% Fit the curve
flist = freq_arr(:, c);
k = (tlist(p2) - tlist(p1)) / (log(flist(p2)) * (tlist(p2) + TZiK) * scale - log(flist(p1)) * (tlist(p1) + TZiK) * scale);
b = tlist(p1) - k * log(flist(p1)) * (tlist(p1) + TZiK) * scale;
params(1, c) = k; params(2, c) = b;

% Calculate estimated temperatures and inaccuracies
for t = 1:Ntemp
T_array(t, c) = (scale * TZiK * k * log(flist(t)) + b) / (1 - scale * k * log(flist(t)));
inacc_arr(t, c) = T_array(t, c) - tlist(t);
end

% Calculate max inaccuracies in the given range
if ( sum(isnan(inacc_arr(tstart_ind:(tstart_ind + twin_len), c))) == 0 )
metric_arr(1, c) = max(inacc_arr(tstart_ind:(tstart_ind + twin_len), c)); % largest positive error
metric_arr(2, c) = min(inacc_arr(tstart_ind:(tstart_ind + twin_len), c)); % largest negative error
metric_arr(3, c) = max(abs(metric_arr(1,c)), abs(metric_arr(2,c))); % largest absolute error
else
metric_arr(:, c) = [NaN; NaN; NaN];
end
end

% Metric A
Nc_A = 0; indlist_A = zeros(2, Nchip);
for c = 1:Nchip
if (metric_arr(3, c) <= inacc_th)
Nc_A = Nc_A + 1;
indlist_A(:, Nc_A) = [c; metric_arr(3,c)];
end
end

% Metric B
[sorted_inacc, sorted_ind] = sort(metric_arr(3, :));
inacc_B = sorted_inacc(Nc_B);
indlist_B = [sorted_ind(1:Nc_B); sorted_inacc(1:Nc_B)];

% Systematic Error Correction
if (inacc_B < 20) % Only do SEC when inaccuracy is not too bad
% get the estimated temp of best Nc_B chips
T_est = T_array(tstart_ind:(tstart_ind + twin_len), indlist_B(1, :));
% define Nth-order polynomial correction: T_sec = pN * T_est^N + ... + p1 * T_est + p0
% param = [p0, p1, ... pN]
T_left = tlist(tstart_ind:(tstart_ind + twin_len))';
T_sec = @(param, T) PolyNthOrder(param, T);
T_right = @(param, T) mean(T_sec(param, T), 2);
% Do Optimization
param0 = zeros(1, order_sec + 1); param0(2) = 1;
opts = optimoptions('lsqcurvefit', 'Display','off');
[params_sec, ~, ~, ~, ~] = lsqcurvefit(T_right, param0, T_est, T_left, [], [], opts);
% Calculate Corrected Temperature estimation and errors
T_array_sec = T_sec(params_sec, T_array);
inacc_arr_sec = T_array_sec - tlist';
else
params_sec = zeros(1, order_sec+1); params_sec(2) = 1;
inacc_arr_sec = inacc_arr;
end

end
27 changes: 27 additions & 0 deletions mpw-1/testsetup/MATLAB/EvalDesignInacc.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
function [design, inacc_sub_arr, inacc_sub_arr_sec, pos_inacc, neg_inacc, sigma, sigma_sec, pos_sigma_inacc, neg_sigma_inacc] = EvalDesignInacc(drange, inacc_arr, inacc_arr_sec, inacc_B_arr, indlist_B_arr, tstart_ind, twin_len)
% Find the best design based on inacc_B given design # range, and evaluate
% its inaccuracies

[~, design] = min(inacc_B_arr(1, drange));
design = drange(design);

inacc_sub_arr = inacc_arr(tstart_ind:(tstart_ind + twin_len), indlist_B_arr(1, :, design), design);
inacc_sub_arr_sec = inacc_arr_sec(tstart_ind:(tstart_ind + twin_len), indlist_B_arr(1, :, design), design);
% Calculate Max/Min Inaccuracy
pos_inacc = max(max(inacc_sub_arr));
neg_inacc = min(min(inacc_sub_arr));
pos_inacc_sec = max(max(inacc_sub_arr_sec));
neg_inacc_sec = min(min(inacc_sub_arr_sec));
pos_inacc = [pos_inacc; pos_inacc_sec];
neg_inacc = [neg_inacc; neg_inacc_sec];
% Calculate 3-sigma Inaccuracy
sigma = [3*std(inacc_sub_arr, 1, 2), -3*std(inacc_sub_arr, 1, 2)] + mean(inacc_sub_arr, 2);
pos_sigma_inacc = max(max(sigma));
neg_sigma_inacc = min(min(sigma));
sigma_sec = [3*std(inacc_sub_arr_sec, 1, 2), -3*std(inacc_sub_arr_sec, 1, 2)] + mean(inacc_sub_arr_sec, 2);
pos_sigma_inacc_sec = max(max(sigma_sec));
neg_sigma_inacc_sec = min(min(sigma_sec));
pos_sigma_inacc = [pos_sigma_inacc; pos_sigma_inacc_sec];
neg_sigma_inacc = [neg_sigma_inacc; neg_sigma_inacc_sec];

end
53 changes: 53 additions & 0 deletions mpw-1/testsetup/MATLAB/ExploreHighRange.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
fprintf("Explore High Temp Range......\n");
% Explore high-temp range
tstart_ind = 5; % 0C
twin_len = 12; % 0C + 120C = 120C
pcalib = 1; % +/- 10C calibration
% Explore the best designs out of 64
params_arr = zeros(2, Nchip, 64);
inacc_arr = zeros(Ntemp, Nchip, 64);
params_sec_arr = zeros(order_sec + 1, 64);
inacc_arr_sec = zeros(Ntemp, Nchip, 64);
Nc_A_arr = zeros(1, 64);
indlist_A_arr = zeros(2, Nchip, 64);
inacc_B_arr = zeros(1, 64);
indlist_B_arr = zeros(2, Nc_B, 64);
for design = 1:64
freq_arr = freq_data_array(:, :, design);
[params, inacc, params_sec, inacc_sec, Nc_A, indlist_A, inacc_B, indlist_B] = ...
EvalDesignGivenRange(freq_arr, tlist, tstart_ind, twin_len, pcalib, inacc_th, Nc_B, order_sec);
params_arr(:, :, design) = params;
inacc_arr(:, :, design) = inacc;
params_sec_arr(:, design) = params_sec;
inacc_arr_sec(:, :, design) = inacc_sec;
Nc_A_arr(:, design) = Nc_A;
indlist_A_arr(:, :, design) = indlist_A;
inacc_B_arr(:, design) = inacc_B;
indlist_B_arr(:, :, design) = indlist_B;
end

% Best design with header-A
[design, inacc_sub_arr, inacc_sub_arr_sec, pos_inacc, neg_inacc, ~, sigma_sec, pos_sigma_inacc, neg_sigma_inacc] = ...
EvalDesignInacc(1:32, inacc_arr, inacc_arr_sec, inacc_B_arr, indlist_B_arr, tstart_ind, twin_len);
fprintf("Header-A Design %d has lowest maximum absolute error. \n", design);
fprintf("Max/Min error w/o SEC is %f/+%f degreeC. \n", neg_inacc(1), pos_inacc(1));
fprintf("3-sigma error w/o SEC is %f/+%f degreeC. \n", neg_sigma_inacc(1), pos_sigma_inacc(1));
fprintf("Max/Min error w/ SEC is %f/+%f degreeC. \n", neg_inacc(2), pos_inacc(2));
fprintf("3-sigma error w/ SEC is %f/+%f degreeC. \n", neg_sigma_inacc(2), pos_sigma_inacc(2));
% Plot Inaccuracy and 3-sigma against temp
[fig, hdl] = PlotInacc(fig, tlist(tstart_ind:(tstart_ind + twin_len)), inacc_sub_arr, inacc_sub_arr_sec, sigma_sec, design);
saveas(hdl, './Figures/InaccVStemp_hdrA_hr.emf');
fprintf("\n");

% Best design with header-B
[design, inacc_sub_arr, inacc_sub_arr_sec, pos_inacc, neg_inacc, ~, sigma_sec, pos_sigma_inacc, neg_sigma_inacc] = ...
EvalDesignInacc(33:64, inacc_arr, inacc_arr_sec, inacc_B_arr, indlist_B_arr, tstart_ind, twin_len);
fprintf("Header-B Design %d has lowest maximum absolute error. \n", design);
fprintf("Max/Min error w/o SEC is %f/+%f degreeC. \n", neg_inacc(1), pos_inacc(1));
fprintf("3-sigma error w/o SEC is %f/+%f degreeC. \n", neg_sigma_inacc(1), pos_sigma_inacc(1));
fprintf("Max/Min error w/ SEC is %f/+%f degreeC. \n", neg_inacc(2), pos_inacc(2));
fprintf("3-sigma error w/ SEC is %f/+%f degreeC. \n", neg_sigma_inacc(2), pos_sigma_inacc(2));
% Plot Inaccuracy and 3-sigma against temp
[fig, hdl] = PlotInacc(fig, tlist(tstart_ind:(tstart_ind + twin_len)), inacc_sub_arr, inacc_sub_arr_sec, sigma_sec, design);
saveas(hdl, './Figures/InaccVStemp_hdrB_hr.emf');
fprintf("\n");
Loading

0 comments on commit f571097

Please sign in to comment.