mirror of https://github.com/VLSIDA/OpenRAM.git
HTML parsing for fake_sram added
This commit is contained in:
parent
bd6621cb88
commit
f602c6b263
|
|
@ -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 (µm<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
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue