mirror of https://github.com/VLSIDA/OpenRAM.git
Modified some testing and initial delay chain sizes.
This commit is contained in:
parent
8d7823e4dd
commit
12723adb0c
|
|
@ -5,3 +5,4 @@
|
|||
*.out
|
||||
*.toc
|
||||
*.synctex.gz
|
||||
**/model_data
|
||||
|
|
@ -227,7 +227,11 @@ class model_check(delay):
|
|||
def get_num_delay_stages(self):
|
||||
"""Gets the number of stages in the delay chain from the control logic"""
|
||||
return len(self.sram.control_logic_rw.replica_bitline.delay_fanout_list)
|
||||
|
||||
|
||||
def get_num_delay_stage_fanout(self):
|
||||
"""Gets fanout in each stage in the delay chain. Assumes each stage is the same"""
|
||||
return self.sram.control_logic_rw.replica_bitline.delay_fanout_list[0]
|
||||
|
||||
def get_num_wl_en_driver_stages(self):
|
||||
"""Gets the number of stages in the wl_en driver from the control logic"""
|
||||
return self.sram.control_logic_rw.wl_en_driver.num_stages
|
||||
|
|
|
|||
|
|
@ -30,13 +30,13 @@ class control_logic(design.design):
|
|||
self.port_type = port_type
|
||||
|
||||
self.num_cols = word_size*words_per_row
|
||||
self.num_words = num_rows * words_per_row
|
||||
self.num_words = num_rows*words_per_row
|
||||
|
||||
self.enable_delay_chain_resizing = False
|
||||
self.enable_delay_chain_resizing = True
|
||||
|
||||
#self.sram=None #disable re-sizing for debugging, FIXME: resizing is not working, needs to be adjusted for new control logic.
|
||||
self.wl_timing_tolerance = 1 #Determines how much larger the sen delay should be. Accounts for possible error in model.
|
||||
self.parasitic_inv_delay = parameter["min_inv_para_delay"] #Keeping 0 for now until further testing.
|
||||
#Determines how much larger the sen delay should be. Accounts for possible error in model.
|
||||
self.wl_timing_tolerance = 1
|
||||
self.parasitic_inv_delay = parameter["min_inv_para_delay"]
|
||||
self.wl_stage_efforts = None
|
||||
self.sen_stage_efforts = None
|
||||
|
||||
|
|
@ -159,16 +159,16 @@ class control_logic(design.design):
|
|||
#Resize if necessary, condition depends on resizing method
|
||||
if self.sram != None and self.enable_delay_chain_resizing and not self.does_sen_total_timing_match():
|
||||
#This resizes to match fall and rise delays, can make the delay chain weird sizes.
|
||||
# stage_list = self.get_dynamic_delay_fanout_list(delay_stages_heuristic, delay_fanout_heuristic)
|
||||
# self.replica_bitline = factory.create(module_type="replica_bitline",
|
||||
# delay_fanout_list=stage_list,
|
||||
# bitcell_loads=bitcell_loads)
|
||||
stage_list = self.get_dynamic_delay_fanout_list(delay_stages_heuristic, delay_fanout_heuristic)
|
||||
self.replica_bitline = factory.create(module_type="replica_bitline",
|
||||
delay_fanout_list=stage_list,
|
||||
bitcell_loads=bitcell_loads)
|
||||
|
||||
#This resizes based on total delay.
|
||||
delay_stages, delay_fanout = self.get_dynamic_delay_chain_size(delay_stages_heuristic, delay_fanout_heuristic)
|
||||
self.replica_bitline = factory.create(module_type="replica_bitline",
|
||||
delay_fanout_list=[delay_fanout]*delay_stages,
|
||||
bitcell_loads=bitcell_loads)
|
||||
# delay_stages, delay_fanout = self.get_dynamic_delay_chain_size(delay_stages_heuristic, delay_fanout_heuristic)
|
||||
# self.replica_bitline = factory.create(module_type="replica_bitline",
|
||||
# delay_fanout_list=[delay_fanout]*delay_stages,
|
||||
# bitcell_loads=bitcell_loads)
|
||||
|
||||
self.sen_delay_rise,self.sen_delay_fall = self.get_delays_to_sen() #get the new timing
|
||||
self.delay_chain_resized = True
|
||||
|
|
@ -177,13 +177,10 @@ class control_logic(design.design):
|
|||
|
||||
def get_heuristic_delay_chain_size(self):
|
||||
"""Use a basic heuristic to determine the size of the delay chain used for the Sense Amp Enable """
|
||||
# FIXME: These should be tuned according to the additional size parameters
|
||||
delay_fanout = 3 # This can be anything >=2
|
||||
delay_fanout = 2 # This can be anything >=2
|
||||
# Delay stages Must be non-inverting
|
||||
if self.words_per_row >= 4:
|
||||
delay_stages = 8
|
||||
elif self.words_per_row == 2:
|
||||
delay_stages = 6
|
||||
if self.words_per_row >= 2:
|
||||
delay_stages = 4
|
||||
else:
|
||||
delay_stages = 2
|
||||
|
||||
|
|
@ -247,6 +244,8 @@ class control_logic(design.design):
|
|||
required_delay_rise = self.wl_delay_rise*self.wl_timing_tolerance - (self.sen_delay_rise-previous_delay_chain_delay/2)
|
||||
debug.info(2,"Required delays from chain: fall={}, rise={}".format(required_delay_fall,required_delay_rise))
|
||||
|
||||
#If the fanout is different between rise/fall by this amount. Stage algorithm is made more pessimistic.
|
||||
WARNING_FANOUT_DIFF = 5
|
||||
#The stages need to be equal (or at least a even number of stages with matching rise/fall delays)
|
||||
while True:
|
||||
stages_fall = self.calculate_stages_with_fixed_fanout(required_delay_fall,fanout_fall)
|
||||
|
|
@ -254,7 +253,8 @@ class control_logic(design.design):
|
|||
debug.info(1,"Fall stages={}, rise stages={}".format(stages_fall,stages_rise))
|
||||
if stages_fall == stages_rise:
|
||||
break
|
||||
elif abs(stages_fall-stages_rise) == 1:
|
||||
elif abs(stages_fall-stages_rise) == 1 and WARNING_FANOUT_DIFF < abs(fanout_fall-fanout_rise):
|
||||
debug.info(1, "Delay chain fanouts between stages are large. Making chain size larger for safety.")
|
||||
break
|
||||
#There should also be a condition to make sure the fanout does not get too large.
|
||||
#Otherwise, increase the fanout of delay with the most stages, calculate new stages
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ Run a regression test on various srams
|
|||
"""
|
||||
import csv,sys,os
|
||||
import pandas as pd
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
import unittest
|
||||
from testutils import header,openram_test
|
||||
|
|
@ -19,13 +20,14 @@ MODEL_DIR = "model_data/"
|
|||
class data_collection(openram_test):
|
||||
|
||||
def runTest(self):
|
||||
|
||||
word_size, num_words, words_per_row = 4, 16, 1
|
||||
self.init_data_gen()
|
||||
self.set_delay_chain(2,3)
|
||||
self.save_data_sram_corners(word_size, num_words, words_per_row)
|
||||
wl_dataframe, sae_dataframe = self.get_csv_data()
|
||||
self.evaluate_data(wl_dataframe, sae_dataframe)
|
||||
ratio_data = self.calculate_delay_ratios_of_srams()
|
||||
self.display_data(ratio_data)
|
||||
# word_size, num_words, words_per_row = 4, 16, 1
|
||||
# self.init_data_gen()
|
||||
# self.set_delay_chain(2,3)
|
||||
# self.save_data_sram_corners(word_size, num_words, words_per_row)
|
||||
# wl_dataframe, sae_dataframe = self.get_csv_data()
|
||||
# self.evaluate_data(wl_dataframe, sae_dataframe)
|
||||
|
||||
#Run again but with different delay chain sizes
|
||||
# self.init_data_gen()
|
||||
|
|
@ -34,12 +36,27 @@ class data_collection(openram_test):
|
|||
# wl_dataframe, sae_dataframe = self.get_csv_data()
|
||||
# self.evaluate_data(wl_dataframe, sae_dataframe)
|
||||
|
||||
model_delay_ratios, meas_delay_ratios, ratio_error = self.compare_model_to_measure()
|
||||
debug.info(1, "model_delay_ratios={}".format(model_delay_ratios))
|
||||
debug.info(1, "meas_delay_ratios={}".format(meas_delay_ratios))
|
||||
debug.info(1, "ratio_error={}".format(ratio_error))
|
||||
globals.end_openram()
|
||||
# model_delay_ratios, meas_delay_ratios, ratio_error = self.compare_model_to_measure()
|
||||
# debug.info(1, "model_delay_ratios={}".format(model_delay_ratios))
|
||||
# debug.info(1, "meas_delay_ratios={}".format(meas_delay_ratios))
|
||||
# debug.info(1, "ratio_error={}".format(ratio_error))
|
||||
# globals.end_openram()
|
||||
|
||||
def calculate_delay_ratios_of_srams(self):
|
||||
"""Runs delay measurements on several sram configurations.
|
||||
Computes the delay ratio for each one."""
|
||||
delay_ratio_data = {}
|
||||
config_tuple_list = [(32, 1024, None)]
|
||||
#config_tuple_list = [(1, 16, 1),(4, 16, 1), (16, 16, 1), (32, 32, 1)]
|
||||
for sram_config in config_tuple_list:
|
||||
word_size, num_words, words_per_row = sram_config
|
||||
self.init_data_gen()
|
||||
self.save_data_sram_corners(word_size, num_words, words_per_row)
|
||||
model_delay_ratios, meas_delay_ratios, ratio_error = self.compare_model_to_measure()
|
||||
delay_ratio_data[sram_config] = ratio_error
|
||||
debug.info(1, "Ratio percentage error={}".format(ratio_error))
|
||||
return delay_ratio_data
|
||||
|
||||
def get_csv_data(self):
|
||||
"""Hardcoded Hack to get the measurement data from the csv into lists. """
|
||||
wl_files_name = [file_name for file_name in self.file_names if "wl_measures" in file_name][0]
|
||||
|
|
@ -79,11 +96,30 @@ class data_collection(openram_test):
|
|||
corner = (wl_meas[proc_pos+1], wl_meas[volt_pos+1], wl_meas[temp_pos+1])
|
||||
meas_delay_ratios[corner] = wl_meas[wl_sum_pos+1]/sae_meas[sae_sum_pos+1]
|
||||
model_delay_ratios[corner] = wl_model[wl_sum_pos+1]/sae_model[sae_sum_pos+1]
|
||||
debug.info(1,"wl_model sum={}, sae_model_sum={}".format(wl_model[wl_sum_pos+1], sae_model[sae_sum_pos+1]))
|
||||
ratio_error[corner] = 100*abs(model_delay_ratios[corner]-meas_delay_ratios[corner])/meas_delay_ratios[corner]
|
||||
#Not using absolute error, positive error means model was larger, negative error means it was smaller.
|
||||
ratio_error[corner] = 100*(model_delay_ratios[corner]-meas_delay_ratios[corner])/meas_delay_ratios[corner]
|
||||
|
||||
return model_delay_ratios, meas_delay_ratios, ratio_error
|
||||
|
||||
|
||||
def display_data(self, data):
|
||||
"""Displays the ratio data using matplotlib (requires graphics)"""
|
||||
config_data = []
|
||||
xticks = []
|
||||
#Organize data
|
||||
#First key level if the sram configuration (wordsize, num words, words per row)
|
||||
for config,corner_data_dict in data.items():
|
||||
#Second level is the corner data for that configuration.
|
||||
for corner, corner_data in corner_data_dict.items():
|
||||
#Right now I am only testing with a single corner, will not work with more than 1 corner
|
||||
config_data.append(corner_data)
|
||||
xticks.append("{}b,{}w,{}wpr".format(*config))
|
||||
#plot data
|
||||
data_range = [i+1 for i in range(len(data))]
|
||||
shapes = ['ro', 'bo', 'go', 'co', 'mo']
|
||||
plt.xticks(data_range, xticks)
|
||||
plt.plot(data_range, config_data, 'ro')
|
||||
plt.show()
|
||||
|
||||
def calculate_delay_error(self, wl_dataframe, sae_dataframe):
|
||||
"""Calculates the percentage difference in delays between the wordline and sense amp enable"""
|
||||
start_data_pos = len(self.config_fields) #items before this point are configuration related
|
||||
|
|
@ -123,6 +159,9 @@ class data_collection(openram_test):
|
|||
def save_data_sram_corners(self, word_size, num_words, words_per_row):
|
||||
"""Performs corner analysis on a single SRAM configuration"""
|
||||
self.create_sram(word_size, num_words, words_per_row)
|
||||
#Setting to none forces SRAM to determine the value. Must be checked after sram creation
|
||||
if not words_per_row:
|
||||
words_per_row = self.sram.s.words_per_row
|
||||
#Run on one size to initialize CSV writing (csv names come from return value). Strange, but it is okay for now.
|
||||
corner_gen = self.corner_combination_generator()
|
||||
init_corner = next(corner_gen)
|
||||
|
|
@ -150,7 +189,7 @@ class data_collection(openram_test):
|
|||
OPTS.trim_netlist = False
|
||||
OPTS.netlist_only = True
|
||||
OPTS.analytical_delay = False
|
||||
OPTS.use_tech_delay_chain_size = True
|
||||
#OPTS.use_tech_delay_chain_size = True
|
||||
# This is a hack to reload the characterizer __init__ with the spice version
|
||||
from importlib import reload
|
||||
import characterizer
|
||||
|
|
@ -209,13 +248,16 @@ class data_collection(openram_test):
|
|||
self.csv_files = {}
|
||||
self.csv_writers = {}
|
||||
self.file_names = []
|
||||
delay_stages = self.delay_obj.get_num_delay_stages()
|
||||
delay_stage_fanout = self.delay_obj.get_num_delay_stage_fanout()
|
||||
|
||||
for data_name, header_list in header_dict.items():
|
||||
file_name = '{}data_{}b_{}word_{}way_dc{}x{}_{}.csv'.format(MODEL_DIR,
|
||||
word_size,
|
||||
num_words,
|
||||
words_per_row,
|
||||
parameter["static_delay_stages"],
|
||||
parameter["static_fanout_per_stage"],
|
||||
delay_stages,
|
||||
delay_stage_fanout,
|
||||
data_name)
|
||||
self.file_names.append(file_name)
|
||||
self.csv_files[data_name] = open(file_name, 'w')
|
||||
|
|
@ -238,13 +280,11 @@ class data_collection(openram_test):
|
|||
self.sram_spice = OPTS.openram_temp + "temp.sp"
|
||||
self.sram.sp_write(self.sram_spice)
|
||||
|
||||
debug.info(1, "SRAM column address size={}".format(self.sram.s.col_addr_size))
|
||||
|
||||
def get_sram_data(self, corner):
|
||||
"""Generates the delay object using the corner and runs a simulation for data."""
|
||||
from characterizer import model_check
|
||||
self.delay_obj = model_check(self.sram.s, self.sram_spice, corner)
|
||||
|
||||
|
||||
import tech
|
||||
#Only 1 at a time
|
||||
probe_address = "1" * self.sram.s.addr_size
|
||||
|
|
@ -253,6 +293,7 @@ class data_collection(openram_test):
|
|||
slews = [tech.spice["rise_time"]*2]
|
||||
|
||||
sram_data = self.delay_obj.analyze(probe_address,probe_data,slews,loads)
|
||||
|
||||
return sram_data
|
||||
|
||||
def remove_lists_from_dict(self, dict):
|
||||
|
|
|
|||
|
|
@ -1,2 +0,0 @@
|
|||
word_size,num_words,words_per_row,dc_resized,process,voltage,temp,Xsram.Xcontrol0.Xand2_rbl_in.zb_int,Xsram.Xcontrol0.rbl_in,Xsram.Xcontrol0.Xreplica_bitline.Xdelay_chain.dout_1,Xsram.Xcontrol0.Xreplica_bitline.delayed_en,Xsram.Xcontrol0.pre_s_en,Xsram.Xcontrol0.Xbuf_s_en.Zb1_int,Xsram.s_en0,sum
|
||||
4,16,1,False,TT,1.0,25,0.020618,0.0062215,0.018563000000000003,0.017233000000000002,0.007710799999999999,0.0099965,0.045221000000000004,0.12556380000000003
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
word_size,num_words,words_per_row,dc_resized,process,voltage,temp,Xsram.Xcontrol0.Xand2_rbl_in.zb_int,Xsram.Xcontrol0.rbl_in,Xsram.Xcontrol0.Xreplica_bitline.Xdelay_chain.dout_1,Xsram.Xcontrol0.Xreplica_bitline.delayed_en,Xsram.Xcontrol0.pre_s_en,Xsram.Xcontrol0.Xbuf_s_en.Zb1_int,Xsram.s_en0,sum
|
||||
4,16,1,False,TT,1.0,25,8.8,2.65,6.4,7.4,3.4,7.15,7.15,42.949999999999996
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
word_size,num_words,words_per_row,dc_resized,process,voltage,temp,Xsram.Xcontrol0.Xbuf_wl_en.Zb1_int,Xsram.Xcontrol0.Xbuf_wl_en.Zb2_int,Xsram.Xcontrol0.Xbuf_wl_en.Zb3_int,Xsram.wl_en0,Xsram.Xbank0.Xwordline_driver0.wl_bar_15,Xsram.Xbank0.wl_15,sum
|
||||
4,16,1,False,TT,1.0,25,0.010512,0.0089216,0.014109,0.013643,0.014564,0.0086745,0.0704241
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
word_size,num_words,words_per_row,dc_resized,process,voltage,temp,Xsram.Xcontrol0.Xbuf_wl_en.Zb1_int,Xsram.Xcontrol0.Xbuf_wl_en.Zb2_int,Xsram.Xcontrol0.Xbuf_wl_en.Zb3_int,Xsram.wl_en0,Xsram.Xbank0.Xwordline_driver0.wl_bar_15,Xsram.Xbank0.wl_15,sum
|
||||
4,16,1,False,TT,1.0,25,5.4,5.4,5.733333333333333,4.4,5.8,5.4,32.13333333333334
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
word_size,num_words,words_per_row,dc_resized,process,voltage,temp,Xsram.Xcontrol0.Xand2_rbl_in.zb_int,Xsram.Xcontrol0.rbl_in,Xsram.Xcontrol0.Xreplica_bitline.Xdelay_chain.dout_1,Xsram.Xcontrol0.Xreplica_bitline.Xdelay_chain.dout_2,Xsram.Xcontrol0.Xreplica_bitline.Xdelay_chain.dout_3,Xsram.Xcontrol0.Xreplica_bitline.delayed_en,Xsram.Xcontrol0.pre_s_en,Xsram.Xcontrol0.Xbuf_s_en.Zb1_int,Xsram.s_en0,sum
|
||||
4,16,1,False,TT,1.0,25,0.020572,0.006256,0.015678,0.014110000000000001,0.017755,0.013415,0.0076344,0.010162,0.04153,0.14711239999999998
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
word_size,num_words,words_per_row,dc_resized,process,voltage,temp,Xsram.Xcontrol0.Xand2_rbl_in.zb_int,Xsram.Xcontrol0.rbl_in,Xsram.Xcontrol0.Xreplica_bitline.Xdelay_chain.dout_1,Xsram.Xcontrol0.Xreplica_bitline.Xdelay_chain.dout_2,Xsram.Xcontrol0.Xreplica_bitline.Xdelay_chain.dout_3,Xsram.Xcontrol0.Xreplica_bitline.delayed_en,Xsram.Xcontrol0.pre_s_en,Xsram.Xcontrol0.Xbuf_s_en.Zb1_int,Xsram.s_en0,sum
|
||||
4,16,1,False,TT,1.0,25,8.8,2.65,5.4,5.4,5.4,6.4,3.4,7.15,7.15,51.74999999999999
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
word_size,num_words,words_per_row,dc_resized,process,voltage,temp,Xsram.Xcontrol0.Xbuf_wl_en.Zb1_int,Xsram.Xcontrol0.Xbuf_wl_en.Zb2_int,Xsram.Xcontrol0.Xbuf_wl_en.Zb3_int,Xsram.wl_en0,Xsram.Xbank0.Xwordline_driver0.wl_bar_15,Xsram.Xbank0.wl_15,sum
|
||||
4,16,1,False,TT,1.0,25,0.010463,0.0089004,0.014107,0.013630000000000001,0.0146,0.0086902,0.0703906
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
word_size,num_words,words_per_row,dc_resized,process,voltage,temp,Xsram.Xcontrol0.Xbuf_wl_en.Zb1_int,Xsram.Xcontrol0.Xbuf_wl_en.Zb2_int,Xsram.Xcontrol0.Xbuf_wl_en.Zb3_int,Xsram.wl_en0,Xsram.Xbank0.Xwordline_driver0.wl_bar_15,Xsram.Xbank0.wl_15,sum
|
||||
4,16,1,False,TT,1.0,25,5.4,5.4,5.733333333333333,4.4,5.8,5.4,32.13333333333334
|
||||
|
Loading…
Reference in New Issue