From ab6afb7ca817bdedcd73ddbaec68599719aa25da Mon Sep 17 00:00:00 2001 From: Jesse Cirimelli-Low Date: Wed, 17 Oct 2018 19:27:09 -0700 Subject: [PATCH] fixed html typos, added logo, added placeholder timing and current, began ports section --- compiler/characterizer/lib.py | 19 ++++++++------- compiler/datasheet/assets/vlsi_logo.png | Bin 0 -> 26952 bytes compiler/datasheet/datasheet.py | 22 ++++++++++++++--- compiler/datasheet/datasheet_gen.py | 31 ++++++++++++++++++------ compiler/datasheet/in_out.py | 11 +++++++++ 5 files changed, 63 insertions(+), 20 deletions(-) create mode 100644 compiler/datasheet/assets/vlsi_logo.png create mode 100644 compiler/datasheet/in_out.py diff --git a/compiler/characterizer/lib.py b/compiler/characterizer/lib.py index 03d9961e..436ee301 100644 --- a/compiler/characterizer/lib.py +++ b/compiler/characterizer/lib.py @@ -526,15 +526,15 @@ class lib: for (corner, lib_name) in zip(self.corners, self.lib_files): - ports = "" - if OPTS.num_rw_ports>0: - ports += "{}_".format(OPTS.num_rw_ports) - if OPTS.num_w_ports>0: - ports += "{}_".format(OPTS.num_w_ports) - if OPTS.num_r_ports>0: - ports += "{}_".format(OPTS.num_r_ports) +# ports = "" +# if OPTS.num_rw_ports>0: +# ports += "{}_".format(OPTS.num_rw_ports) +# if OPTS.num_w_ports>0: +# ports += "{}_".format(OPTS.num_w_ports) +# if OPTS.num_r_ports>0: +# ports += "{}_".format(OPTS.num_r_ports) - datasheet.write("{0},{1},{2},{3},{4},{5},{6},{7},{8},{9},{10},{11},{12}".format("sram_{0}_{1}_{2}{3}".format(OPTS.word_size, OPTS.num_words, ports, OPTS.tech_name), + datasheet.write("{0},{1},{2},{3},{4},{5},{6},{7},{8},{9},{10},{11},{12},{13}".format("sram_{0}_{1}_{2}".format(OPTS.word_size, OPTS.num_words, OPTS.tech_name), OPTS.num_words, OPTS.num_banks, OPTS.num_rw_ports, @@ -546,7 +546,8 @@ class lib: self.corner[0], round_time(self.char_sram_results["min_period"]), self.out_dir, - lib_name)) + lib_name, + OPTS.word_size)) datasheet.close() diff --git a/compiler/datasheet/assets/vlsi_logo.png b/compiler/datasheet/assets/vlsi_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..3f02a45e9adcde6f8d72e7cabbddceae9b32d076 GIT binary patch literal 26952 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 literal 0 HcmV?d00001 diff --git a/compiler/datasheet/datasheet.py b/compiler/datasheet/datasheet.py index 396215a8..543c75fa 100644 --- a/compiler/datasheet/datasheet.py +++ b/compiler/datasheet/datasheet.py @@ -3,16 +3,21 @@ from operating_conditions import * from characterization_corners import * from deliverables import * from timing_and_current_data import * +from in_out import * +import os +from globals import OPTS class datasheet(): def __init__(self,identifier): + self.io = [] self.corners = [] self.timing = [] self.operating = [] self.dlv = [] self.name = identifier self.html = "" + def generate_html(self): self.html = """""" - self.html +='

{0}

' - self.html +='

{0}

' - self.html +='

{0}

' + self.html +='

'+ self.name + '.html' + '

' +# self.html +='

{0}

' +# self.html +='

{0}

' + + self.html +='

Ports and Configuration (DEBUG)

' + self.html += in_out(self.io,table_id='data').__html__().replace('<','<').replace('"','"').replace('>',">") + self.html +='

Operating Conditions

' self.html += operating_conditions(self.operating,table_id='data').__html__() + self.html += '

Timing and Current Data

' self.html += timing_and_current_data(self.timing,table_id='data').__html__() + self.html += '

Characterization Corners

' self.html += characterization_corners(self.corners,table_id='data').__html__() + self.html +='

Deliverables

' self.html += deliverables(self.dlv,table_id='data').__html__().replace('<','<').replace('"','"').replace('>',">") - + self.html +='

*Feature only supported with characterizer

' + + self.html +='VLSIDA' diff --git a/compiler/datasheet/datasheet_gen.py b/compiler/datasheet/datasheet_gen.py index 6bfb165f..5bf4c9d6 100644 --- a/compiler/datasheet/datasheet_gen.py +++ b/compiler/datasheet/datasheet_gen.py @@ -19,6 +19,7 @@ from operating_conditions import * from timing_and_current_data import * from characterization_corners import * from datasheet import * +from in_out import * def process_name(corner): if corner == "TT": @@ -43,12 +44,13 @@ def parse_file(f,pages): NUM_W_PORTS = row[4] NUM_R_PORTS = row[5] TECH_NAME = row[6] - TEMP = row[7] - VOLT = row[8] + TEMP = row[8] + VOLT = row[7] PROC = row[9] MIN_PERIOD = row[10] OUT_DIR = row[11] LIB_NAME = row[12] + WORD_SIZE = row[13] for sheet in pages: @@ -95,20 +97,35 @@ def parse_file(f,pages): new_sheet.operating.append(operating_conditions_item('Power supply (VDD) range',VOLT,VOLT,VOLT,'Volts')) new_sheet.operating.append(operating_conditions_item('Operating Temperature',TEMP,TEMP,TEMP,'Celsius')) try: - new_sheet.operating.append(operating_conditions_item('Operating Frequency (F)','','',str(math.floor(1000/float(MIN_PERIOD))),'MHz')) + new_sheet.operating.append(operating_conditions_item('Operating Frequency (F)*','','',str(math.floor(1000/float(MIN_PERIOD))),'MHz')) except Exception: - new_sheet.operating.append(operating_conditions_item('Operating Frequency (F)','','',"unknown",'MHz')) #analytical model fails to provide MIN_PERIOD + new_sheet.operating.append(operating_conditions_item('Operating Frequency (F)*','','',"unknown",'MHz')) #analytical model fails to provide MIN_PERIOD - + new_sheet.timing.append(timing_and_current_data_item('Cycle time','2','3','4')) + new_sheet.timing.append(timing_and_current_data_item('Access time','2','3','4')) + new_sheet.timing.append(timing_and_current_data_item('Positive clk setup','2','3','4')) + new_sheet.timing.append(timing_and_current_data_item('Positive clk hold','2','3','4')) + new_sheet.timing.append(timing_and_current_data_item('RW setup','2','3','4')) + new_sheet.timing.append(timing_and_current_data_item('RW hold','2','3','4')) + new_sheet.timing.append(timing_and_current_data_item('AC current','2','3','4')) + new_sheet.timing.append(timing_and_current_data_item('Standby current','2','3','4')) + new_sheet.timing.append(timing_and_current_data_item('Area','2','3','4')) - new_sheet.timing.append(timing_and_current_data_item('1','2','3','4')) - new_sheet.dlv.append(deliverables_item('.sp','SPICE netlists','
{1}.{2}'.format(OUT_DIR,NAME,'sp'))) new_sheet.dlv.append(deliverables_item('.v','Verilog simulation models','{1}.{2}'.format(OUT_DIR,NAME,'v'))) new_sheet.dlv.append(deliverables_item('.gds','GDSII layout views','{1}.{2}'.format(OUT_DIR,NAME,'gds'))) new_sheet.dlv.append(deliverables_item('.lef','LEF files','{1}.{2}'.format(OUT_DIR,NAME,'lef'))) new_sheet.dlv.append(deliverables_item('.lib','Synthesis models','{1}'.format(LIB_NAME,LIB_NAME.replace(OUT_DIR,'')))) + + new_sheet.io.append(in_out_item('WORD_SIZE',WORD_SIZE)) + new_sheet.io.append(in_out_item('NUM_WORDS',NUM_WORDS)) + new_sheet.io.append(in_out_item('NUM_BANKS',NUM_BANKS)) + new_sheet.io.append(in_out_item('NUM_RW_PORTS',NUM_RW_PORTS)) + new_sheet.io.append(in_out_item('NUM_R_PORTS',NUM_R_PORTS)) + new_sheet.io.append(in_out_item('NUM_W_PORTS',NUM_W_PORTS)) + + diff --git a/compiler/datasheet/in_out.py b/compiler/datasheet/in_out.py new file mode 100644 index 00000000..f656dba6 --- /dev/null +++ b/compiler/datasheet/in_out.py @@ -0,0 +1,11 @@ +from flask_table import * + +class in_out(Table): + typ = Col('Type') + description = Col('Description') + + +class in_out_item(object): + def __init__(self, typ, description): + self.typ = typ + self.description = description