html parsing finished

This commit is contained in:
Jesse Cirimelli-Low 2019-01-15 19:47:48 -08:00
parent b66c53a99a
commit 903cafb336
5 changed files with 287 additions and 152 deletions

View File

@ -4,21 +4,22 @@ import csv
import base64 import base64
from globals import OPTS from globals import OPTS
class datasheet(): class datasheet():
""" """
Defines the layout,but not the data, of the html datasheet Defines the layout,but not the data, of the html datasheet
""" """
def __init__(self,identifier):
def __init__(self, identifier):
self.name = identifier self.name = identifier
self.html = "" self.html = ""
def generate_html(self): def generate_html(self):
""" """
Generates html tables using flask-table Generates html tables using flask-table
""" """
with open(os.path.abspath(os.environ.get("OPENRAM_HOME")) + '/datasheet/assets/datasheet.css', 'r') as datasheet_css: with open(os.path.abspath(os.environ.get("OPENRAM_HOME")) + '/datasheet/assets/datasheet.css', 'r') as datasheet_css:
#css styling is kept in a seperate file # css styling is kept in a seperate file
self.html += datasheet_css.read() self.html += datasheet_css.read()
@ -29,34 +30,34 @@ class datasheet():
for item in self.description: for item in self.description:
self.html += item + ',' self.html += item + ','
self.html += 'EOL' self.html += 'EOL'
self.html +='-->' self.html += '-->'
vlsi_logo = 0 vlsi_logo = 0
with open(os.path.abspath(os.environ.get("OPENRAM_HOME")) + '/datasheet/assets/vlsi_logo.png' , "rb") as image_file: with open(os.path.abspath(os.environ.get("OPENRAM_HOME")) + '/datasheet/assets/vlsi_logo.png', "rb") as image_file:
vlsi_logo = base64.b64encode(image_file.read()) vlsi_logo = base64.b64encode(image_file.read())
openram_logo = 0 openram_logo = 0
with open(os.path.abspath(os.environ.get("OPENRAM_HOME")) + '/datasheet/assets/openram_logo_placeholder.png' , "rb") as image_file: with open(os.path.abspath(os.environ.get("OPENRAM_HOME")) + '/datasheet/assets/openram_logo_placeholder.png', "rb") as image_file:
openram_logo = base64.b64encode(image_file.read()) openram_logo = base64.b64encode(image_file.read())
self.html += '<a href="https://vlsida.soe.ucsc.edu/"><img src="data:image/png;base64,{0}" alt="VLSIDA"></a>'.format(str(vlsi_logo)[
2:-1])
self.html += '<a href="https://vlsida.soe.ucsc.edu/"><img src="data:image/png;base64,{0}" alt="VLSIDA"></a>'.format(str(vlsi_logo)[2:-1]) self.html += '<p style="font-size: 18px;font-family: Trebuchet MS, Arial, Helvetica, sans-serif;">' + \
self.name + '.html' + '</p>'
self.html += '<p style="font-size: 18px;font-family: Trebuchet MS, Arial, Helvetica, sans-serif;">Compiled at: ' + self.time + '</p>'
self.html += '<p style="font-size: 18px;font-family: Trebuchet MS, Arial, Helvetica, sans-serif;">' + \
'DRC errors: ' + str(self.DRC) + '</p>'
self.html += '<p style="font-size: 18px;font-family: Trebuchet MS, Arial, Helvetica, sans-serif;">' + \
'LVS errors: ' + str(self.LVS) + '</p>'
self.html += '<p style="font-size: 18px;font-family: Trebuchet MS, Arial, Helvetica, sans-serif;">' + \
'Git commit id: ' + str(self.git_id) + '</p>'
self.html += '<p style="font-size: 26px;font-family: Trebuchet MS, Arial, Helvetica, sans-serif;">Ports and Configuration</p>'
self.html +='<p style="font-size: 18px;font-family: Trebuchet MS, Arial, Helvetica, sans-serif;">'+ self.name + '.html' + '</p>'
self.html +='<p style="font-size: 18px;font-family: Trebuchet MS, Arial, Helvetica, sans-serif;">Compiled at: '+ self.time + '</p>'
self.html +='<p style="font-size: 18px;font-family: Trebuchet MS, Arial, Helvetica, sans-serif;">'+ 'DRC errors: ' + str(self.DRC) + '</p>'
self.html +='<p style="font-size: 18px;font-family: Trebuchet MS, Arial, Helvetica, sans-serif;">'+ 'LVS errors: ' + str(self.LVS) + '</p>'
self.html += '<p style="font-size: 18px;font-family: Trebuchet MS, Arial, Helvetica, sans-serif;">'+ 'Git commit id: ' + str(self.git_id) + '</p>'
self.html +='<p style="font-size: 26px;font-family: Trebuchet MS, Arial, Helvetica, sans-serif;">Ports and Configuration</p>'
# self.html += in_out(self.io,table_id='data').__html__().replace('&lt;','<').replace('&#34;','"').replace('&gt;',">") # self.html += in_out(self.io,table_id='data').__html__().replace('&lt;','<').replace('&#34;','"').replace('&gt;',">")
self.html += self.io_table.to_html() self.html += self.io_table.to_html()
self.html +='<p style="font-size: 26px;font-family: Trebuchet MS, Arial, Helvetica, sans-serif;">Operating Conditions</p>' self.html += '<p style="font-size: 26px;font-family: Trebuchet MS, Arial, Helvetica, sans-serif;">Operating Conditions</p>'
# self.html += operating_conditions(self.operating,table_id='data').__html__() # self.html += operating_conditions(self.operating,table_id='data').__html__()
self.html += self.operating_table.to_html() self.html += self.operating_table.to_html()
@ -68,9 +69,6 @@ class datasheet():
# self.html += characterization_corners(self.corners,table_id='data').__html__() # self.html += characterization_corners(self.corners,table_id='data').__html__()
self.html += self.corners_table.to_html() self.html += self.corners_table.to_html()
self.html +='<p style="font-size: 26px;font-family: Trebuchet MS, Arial, Helvetica, sans-serif;">Deliverables</p>' self.html += '<p style="font-size: 26px;font-family: Trebuchet MS, Arial, Helvetica, sans-serif;">Deliverables</p>'
# self.html += deliverables(self.dlv,table_id='data').__html__().replace('&lt;','<').replace('&#34;','"').replace('&gt;',">") # self.html += deliverables(self.dlv,table_id='data').__html__().replace('&lt;','<').replace('&#34;','"').replace('&gt;',">")
self.html += self.dlv_table.to_html() self.html += self.dlv_table.to_html()

View File

@ -3,19 +3,19 @@
This is a script to load data from the characterization and layout processes into This is a script to load data from the characterization and layout processes into
a web friendly html datasheet. a web friendly html datasheet.
""" """
#TODO: # TODO:
#include log file # include log file
#Diagram generation # Diagram generation
#Improve css # Improve css
import debug
from globals import OPTS from globals import OPTS
import os, math import os
import optparse import math
import csv import csv
from datasheet import * import datasheet
from table_gen import * import table_gen
def process_name(corner): def process_name(corner):
""" """
@ -30,20 +30,20 @@ def process_name(corner):
else: else:
return "custom" return "custom"
def parse_characterizer_csv(sram,f,pages):
def parse_characterizer_csv(sram, f, pages):
""" """
Parses output data of the Liberty file generator in order to construct the timing and Parses output data of the Liberty file generator in order to construct the timing and
current table current table
""" """
with open(f) as csv_file: with open(f) as csv_file:
csv_reader = csv.reader(csv_file, delimiter=',') csv_reader = csv.reader(csv_file, delimiter=',')
line_count = 0
for row in csv_reader: for row in csv_reader:
found = 0 found = 0
col = 0 col = 0
#defines layout of csv file # defines layout of csv file
NAME = row[col] NAME = row[col]
col += 1 col += 1
@ -90,7 +90,7 @@ def parse_characterizer_csv(sram,f,pages):
col += 1 col += 1
DATETIME = row[col] DATETIME = row[col]
col+= 1 col += 1
DRC = row[col] DRC = row[col]
col += 1 col += 1
@ -100,14 +100,13 @@ def parse_characterizer_csv(sram,f,pages):
for sheet in pages: for sheet in pages:
if sheet.name == NAME: if sheet.name == NAME:
found = 1 found = 1
#if the .lib information is for an existing datasheet compare timing data # if the .lib information is for an existing datasheet compare timing data
for item in sheet.operating_table.rows: for item in sheet.operating_table.rows:
#check if the new corner data is worse than the previous worse corner data # check if the new corner data is worse than the previous worse corner data
if item[0] == 'Operating Temperature': if item[0] == 'Operating Temperature':
if float(TEMP) > float(item[3]): if float(TEMP) > float(item[3]):
@ -128,14 +127,13 @@ def parse_characterizer_csv(sram,f,pages):
if item[0] == 'Operating Frequncy (F)': if item[0] == 'Operating Frequncy (F)':
try: try:
if float(math.floor(1000/float(MIN_PERIOD)) < float(item[3])): if float(math.floor(1000/float(MIN_PERIOD)) < float(item[3])):
item[3] = str(math.floor(1000/float(MIN_PERIOD))) item[3] = str(math.floor(
1000/float(MIN_PERIOD)))
except Exception: except Exception:
pass pass
while(True): while(True):
if(row[col].startswith('DIN')): if(row[col].startswith('DIN')):
start = col start = col
for item in sheet.timing_table.rows: for item in sheet.timing_table.rows:
@ -253,7 +251,6 @@ def parse_characterizer_csv(sram,f,pages):
col += 1 col += 1
elif(row[col].startswith('WEb')): elif(row[col].startswith('WEb')):
start = col start = col
for item in sheet.timing_table.rows: for item in sheet.timing_table.rows:
@ -293,7 +290,6 @@ def parse_characterizer_csv(sram,f,pages):
col += 1 col += 1
elif(row[col].startswith('ADDR')): elif(row[col].startswith('ADDR')):
start = col start = col
for item in sheet.timing_table.rows: for item in sheet.timing_table.rows:
@ -333,198 +329,220 @@ def parse_characterizer_csv(sram,f,pages):
col += 1 col += 1
else: else:
break break
datasheet.new_sheet.corners_table.add_row([PROC, process_name(
new_sheet.corners_table.add_row([PROC,process_name(PROC),VOLT,TEMP,LIB_NAME.replace(OUT_DIR,'').replace(NAME,'')]) PROC), VOLT, TEMP, LIB_NAME.replace(OUT_DIR, '').replace(NAME, '')])
new_sheet.dlv_table.add_row(['.lib','Synthesis models','<a href="file://{0}">{1}</a>'.format(LIB_NAME,LIB_NAME.replace(OUT_DIR,''))]) datasheet.new_sheet.dlv_table.add_row(
['.lib', 'Synthesis models', '<a href="file://{0}">{1}</a>'.format(LIB_NAME, LIB_NAME.replace(OUT_DIR, ''))])
if found == 0: if found == 0:
#if this is the first corner for this sram, run first time configuration and set up tables # if this is the first corner for this sram, run first time configuration and set up tables
new_sheet = datasheet(NAME) new_sheet = datasheet.datasheet(NAME)
pages.append(new_sheet) pages.append(new_sheet)
new_sheet.git_id = ORIGIN_ID new_sheet.git_id = ORIGIN_ID
new_sheet.time = DATETIME new_sheet.time = DATETIME
new_sheet.DRC = DRC new_sheet.DRC = DRC
new_sheet.LVS = LVS new_sheet.LVS = LVS
new_sheet.description = [NAME, NUM_WORDS, NUM_BANKS, NUM_RW_PORTS, NUM_W_PORTS, NUM_R_PORTS, TECH_NAME, WORD_SIZE, ORIGIN_ID, DATETIME] new_sheet.description = [NAME, NUM_WORDS, NUM_BANKS, NUM_RW_PORTS,
NUM_W_PORTS, NUM_R_PORTS, TECH_NAME, WORD_SIZE, ORIGIN_ID, DATETIME]
new_sheet.corners_table = table_gen("corners") new_sheet.corners_table = table_gen.table_gen("corners")
new_sheet.corners_table.add_row(['Corner Name','Process','Power Supply','Temperature','Library Name Suffix']) new_sheet.corners_table.add_row(
new_sheet.corners_table.add_row([PROC,process_name(PROC),VOLT,TEMP,LIB_NAME.replace(OUT_DIR,'').replace(NAME,'')]) ['Corner Name', 'Process', 'Power Supply', 'Temperature', 'Library Name Suffix'])
new_sheet.operating_table = table_gen("operating_table") new_sheet.corners_table.add_row([PROC, process_name(
new_sheet.operating_table.add_row(['Parameter','Min','Typ','Max','Units']) PROC), VOLT, TEMP, LIB_NAME.replace(OUT_DIR, '').replace(NAME, '')])
new_sheet.operating_table.add_row(['Power supply (VDD) range',VOLT,VOLT,VOLT,'Volts']) new_sheet.operating_table = table_gen.table_gen("operating_table")
new_sheet.operating_table.add_row(['Operating Temperature',TEMP,TEMP,TEMP,'Celsius']) new_sheet.operating_table.add_row(
['Parameter', 'Min', 'Typ', 'Max', 'Units'])
new_sheet.operating_table.add_row(
['Power supply (VDD) range', VOLT, VOLT, VOLT, 'Volts'])
new_sheet.operating_table.add_row(
['Operating Temperature', TEMP, TEMP, TEMP, 'Celsius'])
try: try:
new_sheet.operating_table.add_row(['Operating Frequency (F)','','',str(math.floor(1000/float(MIN_PERIOD))),'MHz']) new_sheet.operating_table.add_row(['Operating Frequency (F)', '', '', str(
math.floor(1000/float(MIN_PERIOD))), 'MHz'])
except Exception: except Exception:
new_sheet.operating_table.add_row(['Operating Frequency (F)','','',"not available in netlist only",'MHz']) #failed to provide non-zero MIN_PERIOD # failed to provide non-zero MIN_PERIOD
new_sheet.timing_table = table_gen("timing") new_sheet.operating_table.add_row(
new_sheet.timing_table.add_row(['Parameter','Min','Max','Units']) ['Operating Frequency (F)', '', '', "not available in netlist only", 'MHz'])
new_sheet.timing_table = table_gen.table_gen("timing")
new_sheet.timing_table.add_row(
['Parameter', 'Min', 'Max', 'Units'])
while(True): while(True):
if(row[col].startswith('DIN')): if(row[col].startswith('DIN')):
start = col start = col
new_sheet.timing_table.add_row(['{0} setup rising'.format(row[start]),row[col+1],row[col+2],'ns']) new_sheet.timing_table.add_row(
['{0} setup rising'.format(row[start]), row[col+1], row[col+2], 'ns'])
col += 2 col += 2
new_sheet.timing_table.add_row(
new_sheet.timing_table.add_row(['{0} setup falling'.format(row[start]),row[col+1],row[col+2],'ns']) ['{0} setup falling'.format(row[start]), row[col+1], row[col+2], 'ns'])
col += 2 col += 2
new_sheet.timing_table.add_row(['{0} hold rising'.format(row[start]),row[col+1],row[col+2],'ns']) new_sheet.timing_table.add_row(
['{0} hold rising'.format(row[start]), row[col+1], row[col+2], 'ns'])
col += 2 col += 2
new_sheet.timing_table.add_row(['{0} hold falling'.format(row[start]),row[col+1],row[col+2],'ns']) new_sheet.timing_table.add_row(
['{0} hold falling'.format(row[start]), row[col+1], row[col+2], 'ns'])
col += 2 col += 2
col +=1 col += 1
elif(row[col].startswith('DOUT')): elif(row[col].startswith('DOUT')):
start = col start = col
new_sheet.timing_table.add_row(['{0} cell rise'.format(row[start]),row[col+1],row[col+2],'ns']) new_sheet.timing_table.add_row(
['{0} cell rise'.format(row[start]), row[col+1], row[col+2], 'ns'])
col += 2 col += 2
new_sheet.timing_table.add_row(
new_sheet.timing_table.add_row(['{0} cell fall'.format(row[start]),row[col+1],row[col+2],'ns']) ['{0} cell fall'.format(row[start]), row[col+1], row[col+2], 'ns'])
col += 2 col += 2
new_sheet.timing_table.add_row(['{0} rise transition'.format(row[start]),row[col+1],row[col+2],'ns']) new_sheet.timing_table.add_row(
['{0} rise transition'.format(row[start]), row[col+1], row[col+2], 'ns'])
col += 2 col += 2
new_sheet.timing_table.add_row(['{0} fall transition'.format(row[start]),row[col+1],row[col+2],'ns']) new_sheet.timing_table.add_row(
['{0} fall transition'.format(row[start]), row[col+1], row[col+2], 'ns'])
col += 2 col += 2
col +=1 col += 1
elif(row[col].startswith('CSb')): elif(row[col].startswith('CSb')):
start = col start = col
new_sheet.timing_table.add_row(['{0} setup rising'.format(row[start]),row[col+1],row[col+2],'ns']) new_sheet.timing_table.add_row(
['{0} setup rising'.format(row[start]), row[col+1], row[col+2], 'ns'])
col += 2 col += 2
new_sheet.timing_table.add_row(
new_sheet.timing_table.add_row(['{0} setup falling'.format(row[start]),row[col+1],row[col+2],'ns']) ['{0} setup falling'.format(row[start]), row[col+1], row[col+2], 'ns'])
col += 2 col += 2
new_sheet.timing_table.add_row(['{0} hold rising'.format(row[start]),row[col+1],row[col+2],'ns']) new_sheet.timing_table.add_row(
['{0} hold rising'.format(row[start]), row[col+1], row[col+2], 'ns'])
col += 2 col += 2
new_sheet.timing_table.add_row(['{0} hold falling'.format(row[start]),row[col+1],row[col+2],'ns']) new_sheet.timing_table.add_row(
['{0} hold falling'.format(row[start]), row[col+1], row[col+2], 'ns'])
col += 2 col += 2
col +=1 col += 1
elif(row[col].startswith('WEb')): elif(row[col].startswith('WEb')):
start = col start = col
new_sheet.timing_table.add_row(['{0} setup rising'.format(row[start]),row[col+1],row[col+2],'ns']) new_sheet.timing_table.add_row(
['{0} setup rising'.format(row[start]), row[col+1], row[col+2], 'ns'])
col += 2 col += 2
new_sheet.timing_table.add_row(
new_sheet.timing_table.add_row(['{0} setup falling'.format(row[start]),row[col+1],row[col+2],'ns']) ['{0} setup falling'.format(row[start]), row[col+1], row[col+2], 'ns'])
col += 2 col += 2
new_sheet.timing_table.add_row(['{0} hold rising'.format(row[start]),row[col+1],row[col+2],'ns']) new_sheet.timing_table.add_row(
['{0} hold rising'.format(row[start]), row[col+1], row[col+2], 'ns'])
col += 2 col += 2
new_sheet.timing_table.add_row(['{0} hold falling'.format(row[start]),row[col+1],row[col+2],'ns']) new_sheet.timing_table.add_row(
['{0} hold falling'.format(row[start]), row[col+1], row[col+2], 'ns'])
col += 2 col += 2
col +=1 col += 1
elif(row[col].startswith('ADDR')): elif(row[col].startswith('ADDR')):
start = col start = col
new_sheet.timing_table.add_row(['{0} setup rising'.format(row[start]),row[col+1],row[col+2],'ns']) new_sheet.timing_table.add_row(
['{0} setup rising'.format(row[start]), row[col+1], row[col+2], 'ns'])
col += 2 col += 2
new_sheet.timing_table.add_row(
new_sheet.timing_table.add_row(['{0} setup falling'.format(row[start]),row[col+1],row[col+2],'ns']) ['{0} setup falling'.format(row[start]), row[col+1], row[col+2], 'ns'])
col += 2 col += 2
new_sheet.timing_table.add_row(['{0} hold rising'.format(row[start]),row[col+1],row[col+2],'ns']) new_sheet.timing_table.add_row(
['{0} hold rising'.format(row[start]), row[col+1], row[col+2], 'ns'])
col += 2 col += 2
new_sheet.timing_table.add_row(['{0} hold falling'.format(row[start]),row[col+1],row[col+2],'ns']) new_sheet.timing_table.add_row(
['{0} hold falling'.format(row[start]), row[col+1], row[col+2], 'ns'])
col += 2 col += 2
col +=1 col += 1
else: else:
break break
new_sheet.dlv_table = table_gen.table_gen("dlv")
new_sheet.dlv_table.add_row(['Type', 'Description', 'Link'])
new_sheet.io_table = table_gen.table_gen("io")
new_sheet.dlv_table = table_gen("dlv")
new_sheet.dlv_table.add_row(['Type','Description','Link'])
new_sheet.io_table = table_gen("io")
new_sheet.io_table.add_row(['Type', 'Value']) new_sheet.io_table.add_row(['Type', 'Value'])
if not OPTS.netlist_only: if not OPTS.netlist_only:
#physical layout files should not be generated in netlist only mode # physical layout files should not be generated in netlist only mode
new_sheet.dlv_table.add_row(['.gds','GDSII layout views','<a href="{0}.{1}">{0}.{1}</a>'.format(OPTS.output_name,'gds')]) new_sheet.dlv_table.add_row(
new_sheet.dlv_table.add_row(['.lef','LEF files','<a href="{0}.{1}">{0}.{1}</a>'.format(OPTS.output_name,'lef')]) ['.gds', 'GDSII layout views', '<a href="{0}.{1}">{0}.{1}</a>'.format(OPTS.output_name, 'gds')])
new_sheet.dlv_table.add_row(
['.lef', 'LEF files', '<a href="{0}.{1}">{0}.{1}</a>'.format(OPTS.output_name, 'lef')])
new_sheet.dlv_table.add_row(['.log','OpenRAM compile log','<a href="{0}.{1}">{0}.{1}</a>'.format(OPTS.output_name,'log')])
new_sheet.dlv_table.add_row(['.v','Verilog simulation models','<a href="{0}.{1}">{0}.{1}</a>'.format(OPTS.output_name,'v')])
new_sheet.dlv_table.add_row(['.html','This datasheet','<a href="{0}.{1}">{0}.{1}</a>'.format(OPTS.output_name,'html')])
new_sheet.dlv_table.add_row(['.lib','Synthesis models','<a href="{1}">{1}</a>'.format(LIB_NAME,LIB_NAME.replace(OUT_DIR,''))])
new_sheet.dlv_table.add_row(['.py','OpenRAM configuration file','<a href="{0}.{1}">{0}.{1}</a>'.format(OPTS.output_name,'py')])
new_sheet.dlv_table.add_row(['.sp','SPICE netlists','<a href="{0}.{1}">{0}.{1}</a>'.format(OPTS.output_name,'sp')])
new_sheet.io_table.add_row(['WORD_SIZE',WORD_SIZE])
new_sheet.io_table.add_row(['NUM_WORDS',NUM_WORDS])
new_sheet.io_table.add_row(['NUM_BANKS',NUM_BANKS])
new_sheet.io_table.add_row(['NUM_RW_PORTS',NUM_RW_PORTS])
new_sheet.io_table.add_row(['NUM_R_PORTS',NUM_R_PORTS])
new_sheet.io_table.add_row(['NUM_W_PORTS',NUM_W_PORTS])
new_sheet.io_table.add_row(['Area',sram.width * sram.height])
new_sheet.dlv_table.add_row(
['.log', 'OpenRAM compile log', '<a href="{0}.{1}">{0}.{1}</a>'.format(OPTS.output_name, 'log')])
new_sheet.dlv_table.add_row(
['.v', 'Verilog simulation models', '<a href="{0}.{1}">{0}.{1}</a>'.format(OPTS.output_name, 'v')])
new_sheet.dlv_table.add_row(
['.html', 'This datasheet', '<a href="{0}.{1}">{0}.{1}</a>'.format(OPTS.output_name, 'html')])
new_sheet.dlv_table.add_row(
['.lib', 'Synthesis models', '<a href="{1}">{1}</a>'.format(LIB_NAME, LIB_NAME.replace(OUT_DIR, ''))])
new_sheet.dlv_table.add_row(
['.py', 'OpenRAM configuration file', '<a href="{0}.{1}">{0}.{1}</a>'.format(OPTS.output_name, 'py')])
new_sheet.dlv_table.add_row(
['.sp', 'SPICE netlists', '<a href="{0}.{1}">{0}.{1}</a>'.format(OPTS.output_name, 'sp')])
new_sheet.io_table.add_row(['WORD_SIZE', WORD_SIZE])
new_sheet.io_table.add_row(['NUM_WORDS', NUM_WORDS])
new_sheet.io_table.add_row(['NUM_BANKS', NUM_BANKS])
new_sheet.io_table.add_row(['NUM_RW_PORTS', NUM_RW_PORTS])
new_sheet.io_table.add_row(['NUM_R_PORTS', NUM_R_PORTS])
new_sheet.io_table.add_row(['NUM_W_PORTS', NUM_W_PORTS])
new_sheet.io_table.add_row(['Area', sram.width * sram.height])
class datasheet_gen(): class datasheet_gen():
def datasheet_write(sram,name): def datasheet_write(sram, name):
in_dir = OPTS.openram_temp in_dir = OPTS.openram_temp
if not (os.path.isdir(in_dir)): if not (os.path.isdir(in_dir)):
os.mkdir(in_dir) os.mkdir(in_dir)
datasheets = [] datasheets = []
parse_characterizer_csv(sram, in_dir + "/datasheet.info", datasheets) parse_characterizer_csv(sram, in_dir + "/datasheet.info", datasheets)
for sheets in datasheets: for sheets in datasheets:
with open(name, 'w+') as f: with open(name, 'w+') as f:
sheets.generate_html() sheets.generate_html()

View File

@ -0,0 +1,43 @@
class table_gen:
def __init__(self, name):
self.name = name
self.rows = []
self.table_id = 'data'
def add_row(self, row):
self.rows.append(row)
def gen_table_head(self):
html = ''
html += '<thead>'
html += '<tr>'
for col in self.rows[0]:
html += '<th>' + str(col) + '</th>'
html += '</tr>'
html += '</thead>'
return html
def gen_table_body(self):
html = ''
html += '<tbody>'
html += '<tr>'
for row in self.rows[1:]:
html += '<tr>'
for col in row:
html += '<td>' + str(col) + '</td>'
html += '</tr>'
html += '</tr>'
html += '</tbody>'
return html
def to_html(self):
html = ''
html += '<table id= \"'+self.table_id+'\">'
html += self.gen_table_head()
html += self.gen_table_body()
html += '</table>'
return html

View File

@ -0,0 +1,16 @@
import os
import base64
class library():
def __init__(self):
self.html = ''
def generate_html(self):
vlsi_logo = 0
with open(os.path.abspath(os.environ.get("OPENRAM_HOME")) + '/datasheet/assets/vlsi_logo.png', "rb") as image_file:
vlsi_logo = base64.b64encode(image_file.read())
self.html += '<a href="https://vlsida.soe.ucsc.edu/"><img src="data:image/png;base64,{0}" alt="VLSIDA"></a>'.format(str(vlsi_logo)[
2:-1])

View File

@ -0,0 +1,60 @@
import library
import csv
class library_item():
def __init__(self):
self.comment = ''
self.word_size = ''
self.num_words = ''
self.num_banks = ''
self.num_rw_ports = ''
self.num_r_ports = ''
self.num_w_ports = ''
self.Area = ''
self.git_id = ''
self.technology = ''
self.min_op = ''
class library_gen():
def library_write(name):
with open(name, 'w+') as f:
library_page.generate_html()
f.write(library_page.html)
def search_file(file, name):
length = len(name)
part = file.read(length)
i = 0
while True:
if part == name:
break
char = file.read(1)
if not char:
return
part = part[1:] + char
i += 1
return i
def parse_html(file):
item = library_item()
start_tag = '<!--'
end_tag = '-->'
with open(file, 'r') as f:
start_byte = library_gen.search_file(f, start_tag) + len(start_tag)
end_byte = library_gen.search_file(f, end_tag) + start_byte
f.seek(start_byte)
item.comment = f.read(end_byte - start_byte)
print(item.comment)
return item
def parse_comment(comment, item):
pass
library_page = library.library()
library_gen.parse_html('../../temp/sram_2_16_scn4m_subm.html')