mirror of https://github.com/VLSIDA/OpenRAM.git
Characterization for extra rows
This commit is contained in:
parent
5b3846e1e5
commit
88bc1f09cb
|
|
@ -1063,7 +1063,8 @@ class delay(simulation):
|
|||
self.trimsp.set_configuration(self.num_banks,
|
||||
self.num_rows,
|
||||
self.num_cols,
|
||||
self.word_size)
|
||||
self.word_size,
|
||||
self.num_spare_rows)
|
||||
self.trimsp.trim(self.probe_address,self.probe_data)
|
||||
else:
|
||||
# The non-reduced netlist file when it is disabled
|
||||
|
|
|
|||
|
|
@ -287,7 +287,10 @@ class functional(simulation):
|
|||
|
||||
def gen_addr(self):
|
||||
""" Generates a random address value to write to. """
|
||||
random_value = random.randint(0,(2**self.addr_size)-1)
|
||||
if (self.num_spare_rows == 0):
|
||||
random_value = random.randint(0,(2**self.addr_size)-1)
|
||||
else:
|
||||
random_value = random.randint(0,((2**(self.addr_size-1)-1))+(self.num_spare_rows * self.words_per_row))
|
||||
addr_bits = self.convert_to_bin(random_value,True)
|
||||
return addr_bits
|
||||
|
||||
|
|
|
|||
|
|
@ -25,12 +25,14 @@ class simulation():
|
|||
self.word_size = self.sram.word_size
|
||||
self.addr_size = self.sram.addr_size
|
||||
self.write_size = self.sram.write_size
|
||||
self.num_spare_rows = self.sram.num_spare_rows
|
||||
self.sp_file = spfile
|
||||
|
||||
self.all_ports = self.sram.all_ports
|
||||
self.readwrite_ports = self.sram.readwrite_ports
|
||||
self.read_ports = self.sram.read_ports
|
||||
self.write_ports = self.sram.write_ports
|
||||
self.words_per_row = self.sram.words_per_row
|
||||
if self.write_size:
|
||||
self.num_wmasks = int(self.word_size/self.write_size)
|
||||
else:
|
||||
|
|
@ -135,7 +137,10 @@ class simulation():
|
|||
if c=="0":
|
||||
self.addr_values[port][bit].append(0)
|
||||
elif c=="1":
|
||||
self.addr_values[port][bit].append(1)
|
||||
if((self.num_spare_rows != 0) and (bit == (self.addr_size - 1))):
|
||||
self.addr_values[port][bit].append(0)
|
||||
else:
|
||||
self.addr_values[port][bit].append(1)
|
||||
else:
|
||||
debug.error("Non-binary address string",1)
|
||||
bit -= 1
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
# All rights reserved.
|
||||
#
|
||||
import debug
|
||||
from math import log
|
||||
from math import log,ceil
|
||||
import re
|
||||
|
||||
class trim_spice():
|
||||
|
|
@ -42,7 +42,7 @@ class trim_spice():
|
|||
self.word_size = word_size
|
||||
|
||||
self.words_per_row = self.num_columns / self.word_size
|
||||
self.row_addr_size = int(log(self.num_rows, 2))
|
||||
self.row_addr_size = ceil(log(self.num_rows, 2))
|
||||
self.col_addr_size = int(log(self.words_per_row, 2))
|
||||
self.bank_addr_size = self.col_addr_size + self.row_addr_size
|
||||
self.addr_size = self.bank_addr_size + int(log(self.num_banks, 2))
|
||||
|
|
|
|||
|
|
@ -52,11 +52,12 @@ import sram
|
|||
class fake_sram(sram.sram):
|
||||
""" This is an SRAM that doesn't actually create itself, just computes
|
||||
the sizes. """
|
||||
def __init__(self, word_size, num_words, num_banks, name):
|
||||
def __init__(self, word_size, num_words, num_banks, name, num_spare_rows):
|
||||
self.name = name
|
||||
self.word_size = word_size
|
||||
self.num_words = num_words
|
||||
self.num_banks = num_banks
|
||||
self.num_spare_rows = num_spare_rows
|
||||
c = reload(__import__(OPTS.bitcell))
|
||||
self.mod_bitcell = getattr(c, OPTS.bitcell)
|
||||
self.bitcell = self.mod_bitcell()
|
||||
|
|
|
|||
|
|
@ -532,6 +532,8 @@ def report_status():
|
|||
debug.error("{0} is not an integer in config file.".format(OPTS.sram_size))
|
||||
if type(OPTS.write_size) is not int and OPTS.write_size is not None:
|
||||
debug.error("{0} is not an integer in config file.".format(OPTS.write_size))
|
||||
if type(OPTS.num_spare_rows) is not int and OPT.num_spare_rows is not None:
|
||||
debug.error("{0} is not an integer in config file.".format(OPTS.num_spare_rows))
|
||||
|
||||
# If a write mask is specified by the user, the mask write size should be the same as
|
||||
# the word size so that an entire word is written at once.
|
||||
|
|
|
|||
|
|
@ -53,7 +53,8 @@ from sram_config import sram_config
|
|||
# Configure the SRAM organization
|
||||
c = sram_config(word_size=OPTS.word_size,
|
||||
num_words=OPTS.num_words,
|
||||
write_size=OPTS.write_size)
|
||||
write_size=OPTS.write_size,
|
||||
num_spare_rows=OPTS.num_spare_rows)
|
||||
debug.print_raw("Words per row: {}".format(c.words_per_row))
|
||||
|
||||
output_extensions = ["sp", "v", "lib", "py", "html", "log"]
|
||||
|
|
|
|||
|
|
@ -0,0 +1,95 @@
|
|||
#!/usr/bin/env python3
|
||||
# See LICENSE for licensing information.
|
||||
#
|
||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||
# (acting for and on behalf of Oklahoma State University)
|
||||
# All rights reserved.
|
||||
#
|
||||
import unittest
|
||||
from testutils import *
|
||||
import sys,os
|
||||
sys.path.append(os.getenv("OPENRAM_HOME"))
|
||||
import globals
|
||||
from globals import OPTS
|
||||
from sram_factory import factory
|
||||
import debug
|
||||
|
||||
class timing_sram_test(openram_test):
|
||||
|
||||
def runTest(self):
|
||||
config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME"))
|
||||
globals.init_openram(config_file)
|
||||
OPTS.spice_name="ngspice"
|
||||
OPTS.analytical_delay = False
|
||||
OPTS.netlist_only = True
|
||||
|
||||
# This is a hack to reload the characterizer __init__ with the spice version
|
||||
from importlib import reload
|
||||
import characterizer
|
||||
reload(characterizer)
|
||||
from characterizer import delay
|
||||
from sram_config import sram_config
|
||||
c = sram_config(word_size=1,
|
||||
num_words=16,
|
||||
num_banks=1,
|
||||
num_spare_rows=5)
|
||||
c.words_per_row=1
|
||||
c.recompute_sizes()
|
||||
debug.info(1, "Testing timing for sample 1bit, 16words SRAM with 1 bank")
|
||||
s = factory.create(module_type="sram", sram_config=c)
|
||||
|
||||
tempspice = OPTS.openram_temp + "temp.sp"
|
||||
s.sp_write(tempspice)
|
||||
|
||||
probe_address = "0" + ("1" * (s.s.addr_size - 1))
|
||||
probe_data = s.s.word_size - 1
|
||||
debug.info(1, "Probe address {0} probe data bit {1}".format(probe_address, probe_data))
|
||||
|
||||
corner = (OPTS.process_corners[0], OPTS.supply_voltages[0], OPTS.temperatures[0])
|
||||
d = delay(s.s, tempspice, corner)
|
||||
import tech
|
||||
loads = [tech.spice["dff_in_cap"]*4]
|
||||
slews = [tech.spice["rise_time"]*2]
|
||||
data, port_data = d.analyze(probe_address, probe_data, slews, loads)
|
||||
#Combine info about port into all data
|
||||
data.update(port_data[0])
|
||||
|
||||
if OPTS.tech_name == "freepdk45":
|
||||
golden_data = {'delay_hl': [0.2264205],
|
||||
'delay_lh': [0.2264205],
|
||||
'leakage_power': 0.0021017429999999997,
|
||||
'min_period': 0.859,
|
||||
'read0_power': [0.3339161],
|
||||
'read1_power': [0.31329440000000003],
|
||||
'slew_hl': [0.2590786],
|
||||
'slew_lh': [0.2590786],
|
||||
'write0_power': [0.36360849999999995],
|
||||
'write1_power': [0.3486931]}
|
||||
elif OPTS.tech_name == "scn4m_subm":
|
||||
golden_data = {'delay_hl': [1.85985],
|
||||
'delay_lh': [1.85985],
|
||||
'leakage_power': 0.006418553,
|
||||
'min_period': 6.875,
|
||||
'read0_power': [12.656310000000001],
|
||||
'read1_power': [12.11682],
|
||||
'slew_hl': [1.868942],
|
||||
'slew_lh': [1.868942],
|
||||
'write0_power': [13.978110000000001],
|
||||
'write1_power': [11.437930000000001]}
|
||||
else:
|
||||
self.assertTrue(False) # other techs fail
|
||||
|
||||
# Check if no too many or too few results
|
||||
self.assertTrue(len(data.keys())==len(golden_data.keys()))
|
||||
|
||||
self.assertTrue(self.check_golden_data(data,golden_data,0.25))
|
||||
|
||||
globals.end_openram()
|
||||
|
||||
# run the test from the command line
|
||||
if __name__ == "__main__":
|
||||
(OPTS, args) = globals.parse_args()
|
||||
del sys.argv[1:]
|
||||
header(__file__, OPTS.tech_name)
|
||||
unittest.main(testRunner=debugTestRunner())
|
||||
Loading…
Reference in New Issue