HTML parsing for fake_sram added

This commit is contained in:
Bugra Onal 2022-08-12 23:29:33 -07:00
parent bd6621cb88
commit f602c6b263
2 changed files with 79 additions and 94 deletions

View File

@ -1,21 +1,53 @@
import sram_config from modules import sram_config
import OPTS from math import ceil
import re
class fake_sram(sram_config.sram_config): class fake_sram(sram_config):
""" This is an SRAM that doesn't actually create itself, just computes """
the sizes. """ This is an SRAM class that doesn't actually create an instance.
def __init__(self, word_size, num_words, num_banks, name, num_spare_rows): It will read neccessary members from HTML file from a previous run.
"""
def __init__(self, name, word_size, num_words, write_size=None, num_banks=1,
words_per_row=None, num_spare_rows=0, num_spare_cols=0):
self.name = name self.name = name
self.word_size = word_size self.word_size = word_size
self.num_words = num_words self.num_words = num_words
# Don't add a write mask if it is the same size as the data word
if write_size and write_size==word_size:
self.write_size = None
else:
self.write_size = write_size
self.num_banks = num_banks self.num_banks = num_banks
self.num_spare_rows = num_spare_rows self.num_spare_rows = num_spare_rows
# TODO: Get width and height from gds bbox self.num_spare_cols = num_spare_cols
self.width = 0
self.height = 0 try:
from tech import array_row_multiple
self.array_row_multiple = array_row_multiple
except ImportError:
self.array_row_multiple = 1
try:
from tech import array_col_multiple
self.array_col_multiple = array_col_multiple
except ImportError:
self.array_col_multiple = 1
if self.write_size:
self.num_wmasks = int(ceil(self.word_size / self.write_size))
else:
self.num_wmasks = 0
if not self.num_spare_cols:
self.num_spare_cols = 0
if not self.num_spare_rows:
self.num_spare_rows = 0
# This will get over-written when we determine the organization
self.words_per_row = words_per_row
self.compute_sizes() self.compute_sizes()
self.setup_multiport_constants()
def setup_multiport_constants(self): def setup_multiport_constants(self):
""" """
@ -27,7 +59,7 @@ class fake_sram(sram_config.sram_config):
A first W port (with no RW ports) will be: clk0, csb0, addr0, data0 A first W port (with no RW ports) will be: clk0, csb0, addr0, data0
""" """
total_ports = OPTS.num_rw_ports + OPTS.num_w_ports + OPTS.num_r_ports total_ports = self.num_rw_ports + self.num_w_ports + self.num_r_ports
# These are the read/write port indices. # These are the read/write port indices.
self.readwrite_ports = [] self.readwrite_ports = []
@ -44,91 +76,44 @@ class fake_sram(sram_config.sram_config):
# The order is always fixed as RW, W, R # The order is always fixed as RW, W, R
port_number = 0 port_number = 0
for port in range(OPTS.num_rw_ports): for port in range(self.num_rw_ports):
self.readwrite_ports.append(port_number) self.readwrite_ports.append(port_number)
self.write_ports.append(port_number) self.write_ports.append(port_number)
self.read_ports.append(port_number) self.read_ports.append(port_number)
port_number += 1 port_number += 1
for port in range(OPTS.num_w_ports): for port in range(self.num_w_ports):
self.write_ports.append(port_number) self.write_ports.append(port_number)
self.writeonly_ports.append(port_number) self.writeonly_ports.append(port_number)
port_number += 1 port_number += 1
for port in range(OPTS.num_r_ports): for port in range(self.num_r_ports):
self.read_ports.append(port_number) self.read_ports.append(port_number)
self.readonly_ports.append(port_number) self.readonly_ports.append(port_number)
port_number += 1 port_number += 1
def parse_characterizer_csv(f, pages): def parse_html(self, filename):
""" """
Parses output data of the Liberty file generator in order to construct the timing and Parse the HTML file generated from previous SRAM generation
current table and populate the members
""" """
#TODO: Func taken from datasheet_gen.py. Read datasheet.info and extract sram members with open(filename, 'r') as html:
with open(f) as csv_file: for line in html:
csv_reader = csv.reader(csv_file, delimiter=',') if 'Ports and Configuration' in line:
for row in csv_reader: tableRE = re.compile(r'<tr><td>(\w*)</td><td>(\w*)</td></tr>')
values = tableRE.finditer(line)
found = 0 for val in values:
col = 0 if val.group(1) == 'WORD_SIZE':
self.word_size = int(val.group(2))
# defines layout of csv file elif val.group(1) == 'NUM_WORDS':
NAME = row[col] self.num_words = int(val.group(2))
col += 1 elif val.group(1) == 'NUM_BANKS':
self.num_banks = int(val.group(2))
NUM_WORDS = row[col] elif val.group(1) == 'NUM_RW_PORTS':
col += 1 self.num_rw_ports = int(val.group(2))
elif val.group(1) == 'NUM_R_PORTS':
NUM_BANKS = row[col] self.num_r_ports = int(val.group(2))
col += 1 elif val.group(1) == 'NUM_W_PORTS':
self.num_w_ports = int(val.group(2))
NUM_RW_PORTS = row[col] elif val.group(1) == 'Area (&microm<sup>2</sup>)':
col += 1 self.height = int(val.group(2) ** 0.5)
self.width = int(val.group(2) ** 0.5)
NUM_W_PORTS = row[col] break
col += 1
NUM_R_PORTS = row[col]
col += 1
TECH_NAME = row[col]
col += 1
TEMP = row[col]
col += 1
VOLT = row[col]
col += 1
PROC = row[col]
col += 1
MIN_PERIOD = row[col]
col += 1
OUT_DIR = row[col]
col += 1
LIB_NAME = row[col]
col += 1
WORD_SIZE = row[col]
col += 1
ORIGIN_ID = row[col]
col += 1
DATETIME = row[col]
col += 1
ANALYTICAL_MODEL = row[col]
col += 1
DRC = row[col]
col += 1
LVS = row[col]
col += 1
AREA = row[col]
col += 1

View File

@ -24,7 +24,7 @@ from importlib import reload
USAGE = "Usage: {} [options] <config file>\nUse -h for help.\n".format(__file__) USAGE = "Usage: {} [options] <config file>\nUse -h for help.\n".format(__file__)
# Check that we are left with a single configuration file as argument. # Check that we are left with a single configuration file as argument.
if len(args) != 1: if len(args) != 2:
print(USAGE) print(USAGE)
sys.exit(2) sys.exit(2)
@ -37,8 +37,9 @@ init_openram(config_file=args[0], is_unit_test=False)
print_banner() print_banner()
# Configure the SRAM organization (duplicated from openram.py) # Configure the SRAM organization (duplicated from openram.py)
from sram_config import sram_config from characterizer.fake_sram import fake_sram
c = sram_config(word_size=OPTS.word_size, s = fake_sram(name=OPTS.output_name,
word_size=OPTS.word_size,
num_words=OPTS.num_words, num_words=OPTS.num_words,
write_size=OPTS.write_size, write_size=OPTS.write_size,
num_banks=OPTS.num_banks, num_banks=OPTS.num_banks,
@ -46,18 +47,17 @@ c = sram_config(word_size=OPTS.word_size,
num_spare_rows=OPTS.num_spare_rows, num_spare_rows=OPTS.num_spare_rows,
num_spare_cols=OPTS.num_spare_cols) num_spare_cols=OPTS.num_spare_cols)
s.parse_html(args[1])
s.setup_multiport_constants()
OPTS.netlist_only = True OPTS.netlist_only = True
OPTS.check_lvsdrc = False OPTS.check_lvsdrc = False
# Initialize and create a fake sram object
import fake_sran as sram
s = sram(name=OPTS.output_name, sram_config=c)
# Characterize the design # Characterize the design
start_time = datetime.datetime.now() start_time = datetime.datetime.now()
from characterizer import lib from characterizer import lib
debug.print_raw("LIB: Characterizing... ") debug.print_raw("LIB: Characterizing... ")
lib(out_dir=OPTS.output_path, sram=s.s, sp_file=s.get_sp_name()) lib(out_dir=OPTS.output_path, sram=s, sp_file=OPTS.output_path + OPTS.output_name + ".sp")
print_time("Characterization", datetime.datetime.now(), start_time) print_time("Characterization", datetime.datetime.now(), start_time)
# Output info about this run # Output info about this run