Fixed merging issues with power branch
|
|
@ -2,3 +2,7 @@
|
|||
*~
|
||||
*.pyc
|
||||
*.log
|
||||
*.aux
|
||||
*.out
|
||||
*.toc
|
||||
*.synctex.gz
|
||||
|
|
|
|||
61
README.md
|
|
@ -7,9 +7,14 @@ https://github.com/mguthaus/OpenRAM/blob/master/OpenRAM_ICCAD_2016_presentation.
|
|||
The OpenRAM compiler has very few dependencies:
|
||||
* ngspice-26 (or later) or HSpice I-2013.12-1 (or later) or CustomSim 2017 (or later)
|
||||
* Python 2.7 and higher (currently excludes Python 3 and up)
|
||||
* Python numpy
|
||||
* a setup script for each technology
|
||||
* a technology directory for each technology with the base cells
|
||||
|
||||
If you want to perform DRC and LVS, you will need either:
|
||||
* Calibre (for FreePDK45 or SCMOS)
|
||||
* Magic + Netgen (for SCMOS only)
|
||||
|
||||
You must set two environment variables: OPENRAM_HOME should point to
|
||||
the compiler source directory. OPENERAM_TECH should point to a root
|
||||
technology directory that contains subdirs of all other technologies.
|
||||
|
|
@ -36,6 +41,12 @@ For example, in csh/tcsh, add to your .tcshrc:
|
|||
We do not distribute the PDK, but you may get it from:
|
||||
https://www.eda.ncsu.edu/wiki/FreePDK45:Contents
|
||||
|
||||
If you are using SCMOS, you should install Magic and netgen from:
|
||||
http://opencircuitdesign.com/magic/
|
||||
http://opencircuitdesign.com/netgen/
|
||||
In addition, you will need to install the MOSIS SCMOS rules for scn3me_subm
|
||||
that are part of QFlow:
|
||||
http://opencircuitdesign.com/qflow/
|
||||
|
||||
# DIRECTORY STRUCTURE
|
||||
|
||||
|
|
@ -120,27 +131,34 @@ This is where simulations and DRC/LVS get run so there is no network
|
|||
traffic. The directory name is unique for each person and run of
|
||||
OpenRAM to not clobber any files and allow simultaneous runs. If it
|
||||
passes, the files are deleted. If it fails, you will see these files:
|
||||
* _calibreDRC.rul_ is the DRC rule file.
|
||||
* dc_runset is the command file for caliber.
|
||||
* temp.gds is the layout
|
||||
* test1.drc.err is the std err output of the command
|
||||
* test1.drc.out is the standard output of the command
|
||||
* test1.drc.db is the DRC results file
|
||||
* (.mag files if using SCMOS)
|
||||
* temp.sp is the netlist
|
||||
* test1.drc.err is the std err output of the DRC command
|
||||
* test1.drc.out is the standard output of the DRC command
|
||||
* test1.drc.results is the DRC results file
|
||||
* test1.lvs.err is the std err output of the LVS command
|
||||
* test1.lvs.out is the standard output of the LVS command
|
||||
* test1.lvs.results is the DRC results file
|
||||
|
||||
Depending on your DRC/LVS tools, there will also be:
|
||||
* _calibreDRC.rul_ is the DRC rule file (Calibre)
|
||||
* dc_runset is the command file (Calibre)
|
||||
* extracted.sp (Calibre)
|
||||
* run_lvs.sh is a Netgen script for LVS (Netgen)
|
||||
* run_drc.sh is a Magic script for DRC (Magic)
|
||||
* <topcell>.spice (Magic)
|
||||
|
||||
If DRC/LVS fails, the first thing is to check if it ran in the .out and
|
||||
.err file. This shows the standard output and error output from
|
||||
running DRC/LVS. If there is a setup problem it will be shown here.
|
||||
|
||||
If DRC/LVS runs, but doesn't pass, you then should look at the .db
|
||||
If DRC/LVS runs, but doesn't pass, you then should look at the .results
|
||||
file. If the DRC fails, it will typically show you the command that was used
|
||||
to run caliber. It is something like this:
|
||||
```
|
||||
calibre -gui -drc /tmp/openram_mrg_28781_temp/drc_runset -batch 2>
|
||||
/tmp/openram_mrg_28781_temp/test1.drc.err 1>
|
||||
/tmp/openram_mrg_28781_temp/test1.drc.out
|
||||
```
|
||||
To debug, you will need a layout viewer. I prefer to use glade on my
|
||||
Mac, but you can also use Calibre, Magic, etc.
|
||||
to run Calibre or Magic+Netgen.
|
||||
|
||||
To debug, you will need a layout viewer. I prefer to use Glade
|
||||
on my Mac, but you can also use Calibre, Magic, etc.
|
||||
|
||||
1. Calibre
|
||||
|
||||
|
|
@ -184,12 +202,19 @@ ui().importCds("default",
|
|||
between processes, you have to change the importCds command (or you
|
||||
can manually run the command each time you start glade).
|
||||
|
||||
To load the errors, you simply do Verify->Import Caliber Errors select
|
||||
the .db file from calibre.
|
||||
To load the errors, you simply do Verify->Import Calibre Errors select
|
||||
the .results file from Calibre.
|
||||
|
||||
3. It is possible to use other viewers as well, such as:
|
||||
3. Magic
|
||||
|
||||
Magic is only supported in SCMOS. You will need to install the MOSIS SCMOS rules
|
||||
and Magic from: http://opencircuitdesign.com/
|
||||
|
||||
When running DRC or extraction, OpenRAM will load the GDS file, save
|
||||
the .ext/.mag files, and export an extracted netlist (.spice).
|
||||
|
||||
4. It is possible to use other viewers as well, such as:
|
||||
* LayoutEditor http://www.layouteditor.net/
|
||||
* Magic http://opencircuitdesign.com/magic/
|
||||
|
||||
|
||||
# Example to output/input .gds layout files from/to Cadence
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ class design(hierarchy_spice.spice, hierarchy_layout.layout):
|
|||
return inst_map
|
||||
|
||||
|
||||
def DRC_LVS(self):
|
||||
def DRC_LVS(self, final_verification=False):
|
||||
"""Checks both DRC and LVS for a module"""
|
||||
if OPTS.check_lvsdrc:
|
||||
tempspice = OPTS.openram_temp + "/temp.sp"
|
||||
|
|
@ -85,7 +85,7 @@ class design(hierarchy_spice.spice, hierarchy_layout.layout):
|
|||
self.sp_write(tempspice)
|
||||
self.gds_write(tempgds)
|
||||
debug.check(verify.run_drc(self.name, tempgds) == 0,"DRC failed for {0}".format(self.name))
|
||||
debug.check(verify.run_lvs(self.name, tempgds, tempspice) == 0,"LVS failed for {0}".format(self.name))
|
||||
debug.check(verify.run_lvs(self.name, tempgds, tempspice, final_verification) == 0,"LVS failed for {0}".format(self.name))
|
||||
os.remove(tempspice)
|
||||
os.remove(tempgds)
|
||||
|
||||
|
|
@ -97,14 +97,14 @@ class design(hierarchy_spice.spice, hierarchy_layout.layout):
|
|||
debug.check(verify.run_drc(self.name, tempgds) == 0,"DRC failed for {0}".format(self.name))
|
||||
os.remove(tempgds)
|
||||
|
||||
def LVS(self):
|
||||
def LVS(self, final_verification=False):
|
||||
"""Checks LVS for a module"""
|
||||
if OPTS.check_lvsdrc:
|
||||
tempspice = OPTS.openram_temp + "/temp.sp"
|
||||
tempgds = OPTS.openram_temp + "/temp.gds"
|
||||
self.sp_write(tempspice)
|
||||
self.gds_write(tempgds)
|
||||
debug.check(verify.run_lvs(self.name, tempgds, tempspice) == 0,"LVS failed for {0}".format(self.name))
|
||||
debug.check(verify.run_lvs(self.name, tempgds, tempspice, final_verification) == 0,"LVS failed for {0}".format(self.name))
|
||||
os.remove(tempspice)
|
||||
os.remove(tempgds)
|
||||
|
||||
|
|
@ -60,21 +60,44 @@ class layout(lef.lef):
|
|||
def find_lowest_coords(self):
|
||||
"""Finds the lowest set of 2d cartesian coordinates within
|
||||
this layout"""
|
||||
|
||||
lowestx1 = min(obj.lx() for obj in self.objs if obj.name!="label")
|
||||
lowesty1 = min(obj.by() for obj in self.objs if obj.name!="label")
|
||||
lowestx2 = min(inst.lx() for inst in self.insts)
|
||||
lowesty2 = min(inst.by() for inst in self.insts)
|
||||
return vector(min(lowestx1, lowestx2), min(lowesty1, lowesty2))
|
||||
|
||||
if len(self.objs)>0:
|
||||
lowestx1 = min(obj.lx() for obj in self.objs if obj.name!="label")
|
||||
lowesty1 = min(obj.by() for obj in self.objs if obj.name!="label")
|
||||
else:
|
||||
lowestx1=lowesty1=None
|
||||
if len(self.insts)>0:
|
||||
lowestx2 = min(inst.lx() for inst in self.insts)
|
||||
lowesty2 = min(inst.by() for inst in self.insts)
|
||||
else:
|
||||
lowestx2=lowesty2=None
|
||||
if lowestx1==None:
|
||||
return vector(lowestx2,lowesty2)
|
||||
elif lowestx2==None:
|
||||
return vector(lowestx1,lowesty1)
|
||||
else:
|
||||
return vector(min(lowestx1, lowestx2), min(lowesty1, lowesty2))
|
||||
|
||||
def find_highest_coords(self):
|
||||
"""Finds the highest set of 2d cartesian coordinates within
|
||||
this layout"""
|
||||
highestx1 = min(obj.rx() for obj in self.objs if obj.name!="label")
|
||||
highesty1 = min(obj.uy() for obj in self.objs if obj.name!="label")
|
||||
highestx2 = min(inst.rx() for inst in self.insts)
|
||||
highesty2 = min(inst.uy() for inst in self.insts)
|
||||
return vector(min(highestx1, highestx2), min(highesty1, highesty2))
|
||||
|
||||
if len(self.objs)>0:
|
||||
highestx1 = max(obj.rx() for obj in self.objs if obj.name!="label")
|
||||
highesty1 = max(obj.uy() for obj in self.objs if obj.name!="label")
|
||||
else:
|
||||
highestx1=highesty1=None
|
||||
if len(self.insts)>0:
|
||||
highestx2 = max(inst.rx() for inst in self.insts)
|
||||
highesty2 = max(inst.uy() for inst in self.insts)
|
||||
else:
|
||||
highestx2=highesty2=None
|
||||
if highestx1==None:
|
||||
return vector(highestx2,highesty2)
|
||||
elif highestx2==None:
|
||||
return vector(highestx1,highesty1)
|
||||
else:
|
||||
return vector(max(highestx1, highestx2), max(highesty1, highesty2))
|
||||
|
||||
|
||||
def translate_all(self, offset):
|
||||
|
|
@ -143,9 +166,11 @@ class layout(lef.lef):
|
|||
debug.error("Nonrectilinear center rect!",-1)
|
||||
elif start.x!=end.x:
|
||||
offset = vector(0,0.5*minwidth_layer)
|
||||
return self.add_rect(layer,start-offset,end.x-start.x,minwidth_layer)
|
||||
else:
|
||||
offset = vector(0.5*minwidth_layer,0)
|
||||
return self.add_rect(layer,start-offset,end.x-start.x,minwidth_layer)
|
||||
return self.add_rect(layer,start-offset,minwidth_layer,end.y-start.y)
|
||||
|
||||
|
||||
|
||||
def get_pin(self, text):
|
||||
|
|
@ -283,7 +308,7 @@ class layout(lef.lef):
|
|||
path.path(obj=self,
|
||||
layer=layer,
|
||||
position_list=coordinates,
|
||||
width=drc["minwidth_{}".format(layer)])
|
||||
width=width)
|
||||
|
||||
def add_route(self, design, layers, coordinates):
|
||||
"""Connects a routing path on given layer,coordinates,width. The
|
||||
|
|
@ -92,7 +92,8 @@ class path():
|
|||
self.add_line(layer_name=self.layer_name,
|
||||
length=abs(line_length),
|
||||
offset=offset,
|
||||
orientation="horizontal")
|
||||
orientation="horizontal",
|
||||
layer_width=self.layer_width)
|
||||
# if we have y motion
|
||||
elif pl[index][1] != pl[index + 1][1]:
|
||||
line_length = pl[index + 1][1] - pl[index][1]
|
||||
|
|
@ -104,15 +105,15 @@ class path():
|
|||
self.add_line(layer_name=self.layer_name,
|
||||
length=abs(line_length),
|
||||
offset=offset,
|
||||
orientation="vertical")
|
||||
orientation="vertical",
|
||||
layer_width=self.layer_width)
|
||||
|
||||
def add_line(self, layer_name, length, offset, orientation):
|
||||
def add_line(self, layer_name, length, offset, orientation, layer_width):
|
||||
"""
|
||||
straight line object with layer_minwidth
|
||||
(orientation: "vertical" or "horizontal") default is vertical
|
||||
"""
|
||||
|
||||
layer_width = drc["minwidth_{0}".format(layer_name)]
|
||||
width = layer_width
|
||||
height = length
|
||||
|
||||
|
|
@ -7,7 +7,7 @@ from vector3d import vector3d
|
|||
|
||||
class route():
|
||||
"""
|
||||
Object route
|
||||
Object route (used by the router module)
|
||||
Add a route of minimium metal width between a set of points.
|
||||
The wire must be completely rectilinear and the
|
||||
z-dimension of the points refers to the layers (plus via)
|
||||
|
|
@ -12,8 +12,6 @@ class wire(path):
|
|||
The points are the center of the wire.
|
||||
The layer stack is the vertical, contact/via, and horizontal layers, respectively.
|
||||
"""
|
||||
unique_id = 1
|
||||
|
||||
def __init__(self, obj, layer_stack, position_list):
|
||||
self.obj = obj
|
||||
self.layer_stack = layer_stack
|
||||
|
|
@ -85,7 +83,8 @@ class wire(path):
|
|||
self.add_line(layer_name=self.horiz_layer_name,
|
||||
length=abs(line_length),
|
||||
offset=temp_offset,
|
||||
orientation="horizontal")
|
||||
orientation="horizontal",
|
||||
layer_width=self.horiz_layer_width)
|
||||
elif pl[index][1] != pl[index + 1][1]:
|
||||
line_length = pl[index + 1][1] - pl[index][1]
|
||||
temp_offset = [pl[index][0] - 0.5 * self.vert_layer_width,
|
||||
|
|
@ -96,7 +95,8 @@ class wire(path):
|
|||
self.add_line(layer_name=self.vert_layer_name,
|
||||
length=abs(line_length),
|
||||
offset=temp_offset,
|
||||
orientation="vertical")
|
||||
orientation="vertical",
|
||||
layer_width=self.vert_layer_width)
|
||||
|
||||
def assert_node(self, A, B):
|
||||
""" Check if the node movements are not big enough for the
|
||||
|
|
@ -10,20 +10,25 @@ from globals import OPTS
|
|||
|
||||
class delay():
|
||||
"""
|
||||
Functions to measure the delay of the SRAM at a given address and
|
||||
Functions to measure the delay of an SRAM at a given address and
|
||||
data bit.
|
||||
"""
|
||||
|
||||
def __init__(self,sram,spfile):
|
||||
def __init__(self,sram,spfile, corner):
|
||||
self.name = sram.name
|
||||
self.num_words = sram.num_words
|
||||
self.word_size = sram.word_size
|
||||
self.addr_size = sram.addr_size
|
||||
self.sram_sp_file = spfile
|
||||
|
||||
self.vdd = tech.spice["supply_voltage"]
|
||||
self.gnd = tech.spice["gnd_voltage"]
|
||||
|
||||
self.set_corner(corner)
|
||||
|
||||
def set_corner(self,corner):
|
||||
""" Set the corner values """
|
||||
self.corner = corner
|
||||
(self.process, self.vdd_voltage, self.temperature) = corner
|
||||
self.gnd_voltage = 0
|
||||
|
||||
|
||||
def check_arguments(self):
|
||||
"""Checks if arguments given for write_stimulus() meets requirements"""
|
||||
|
|
@ -40,9 +45,9 @@ class delay():
|
|||
|
||||
|
||||
def write_stimulus(self, period, load, slew):
|
||||
"""Creates a stimulus file for simulations to probe a certain bitcell, given an address and data-position of the data-word
|
||||
(probe-address form: '111010000' LSB=0, MSB=1)
|
||||
(probe_data form: number corresponding to the bit position of data-bus, begins with position 0)
|
||||
""" Creates a stimulus file for simulations to probe a bitcell at a given clock period.
|
||||
Address and bit were previously set with set_probe().
|
||||
Input slew (in ns) and output capacitive load (in fF) are required for charaterization.
|
||||
"""
|
||||
self.check_arguments()
|
||||
|
||||
|
|
@ -52,159 +57,160 @@ class delay():
|
|||
# creates and opens stimulus file for writing
|
||||
temp_stim = "{0}/stim.sp".format(OPTS.openram_temp)
|
||||
self.sf = open(temp_stim, "w")
|
||||
self.sf.write("* Stimulus for period of {0}n load={1} slew={2}\n\n".format(period,load,slew))
|
||||
|
||||
self.sf.write("* Stimulus for period of {0}n load={1}fF slew={2}ns\n\n".format(period,load,slew))
|
||||
self.stim = stimuli.stimuli(self.sf, self.corner)
|
||||
# include files in stimulus file
|
||||
model_list = tech.spice["fet_models"] + [self.sram_sp_file]
|
||||
stimuli.write_include(stim_file=self.sf, models=model_list)
|
||||
self.stim.write_include(self.sram_sp_file)
|
||||
|
||||
# add vdd/gnd statements
|
||||
|
||||
self.sf.write("* Global Power Supplies\n")
|
||||
stimuli.write_supply(self.sf)
|
||||
self.sf.write("\n* Global Power Supplies\n")
|
||||
self.stim.write_supply()
|
||||
|
||||
# instantiate the sram
|
||||
self.sf.write("* Instantiation of the SRAM\n")
|
||||
stimuli.inst_sram(stim_file=self.sf,
|
||||
abits=self.addr_size,
|
||||
dbits=self.word_size,
|
||||
sram_name=self.name)
|
||||
self.sf.write("\n* Instantiation of the SRAM\n")
|
||||
self.stim.inst_sram(abits=self.addr_size,
|
||||
dbits=self.word_size,
|
||||
sram_name=self.name)
|
||||
|
||||
self.sf.write("* SRAM output loads\n")
|
||||
self.sf.write("\n* SRAM output loads\n")
|
||||
for i in range(self.word_size):
|
||||
self.sf.write("CD{0} d[{0}] 0 {1}f\n".format(i,load))
|
||||
|
||||
# add access transistors for data-bus
|
||||
self.sf.write("* Transmission Gates for data-bus and control signals\n")
|
||||
stimuli.inst_accesstx(stim_file=self.sf, dbits=self.word_size)
|
||||
self.sf.write("\n* Transmission Gates for data-bus and control signals\n")
|
||||
self.stim.inst_accesstx(dbits=self.word_size)
|
||||
|
||||
# generate data and addr signals
|
||||
self.sf.write("* Generation of data and address signals\n")
|
||||
self.sf.write("\n* Generation of data and address signals\n")
|
||||
for i in range(self.word_size):
|
||||
if i == self.probe_data:
|
||||
stimuli.gen_data(stim_file=self.sf,
|
||||
clk_times=self.cycle_times,
|
||||
sig_name="data[{0}]".format(i),
|
||||
period=period,
|
||||
slew=slew)
|
||||
self.gen_data(clk_times=self.cycle_times,
|
||||
sig_name="data[{0}]".format(i),
|
||||
period=period,
|
||||
slew=slew)
|
||||
else:
|
||||
stimuli.gen_constant(stim_file=self.sf,
|
||||
sig_name="d[{0}]".format(i),
|
||||
v_val=self.gnd)
|
||||
self.stim.gen_constant(sig_name="d[{0}]".format(i),
|
||||
v_val=self.gnd_voltage)
|
||||
|
||||
stimuli.gen_addr(self.sf,
|
||||
clk_times=self.cycle_times,
|
||||
addr=self.probe_address,
|
||||
period=period,
|
||||
slew=slew)
|
||||
self.gen_addr(clk_times=self.cycle_times,
|
||||
addr=self.probe_address,
|
||||
period=period,
|
||||
slew=slew)
|
||||
|
||||
# generate control signals
|
||||
self.sf.write("* Generation of control signals\n")
|
||||
stimuli.gen_csb(self.sf, self.cycle_times, period, slew)
|
||||
stimuli.gen_web(self.sf, self.cycle_times, period, slew)
|
||||
stimuli.gen_oeb(self.sf, self.cycle_times, period, slew)
|
||||
self.sf.write("\n* Generation of control signals\n")
|
||||
self.gen_csb(self.cycle_times, period, slew)
|
||||
self.gen_web(self.cycle_times, period, slew)
|
||||
self.gen_oeb(self.cycle_times, period, slew)
|
||||
|
||||
self.sf.write("* Generation of global clock signal\n")
|
||||
stimuli.gen_pulse(stim_file=self.sf,
|
||||
sig_name="CLK",
|
||||
v1=self.gnd,
|
||||
v2=self.vdd,
|
||||
offset=period,
|
||||
period=period,
|
||||
t_rise = slew,
|
||||
t_fall = slew)
|
||||
self.sf.write("\n* Generation of global clock signal\n")
|
||||
self.stim.gen_pulse(sig_name="CLK",
|
||||
v1=self.gnd_voltage,
|
||||
v2=self.vdd_voltage,
|
||||
offset=period,
|
||||
period=period,
|
||||
t_rise=slew,
|
||||
t_fall=slew)
|
||||
|
||||
self.write_measures(period)
|
||||
|
||||
# run until the last cycle time
|
||||
stimuli.write_control(self.sf,self.cycle_times[-1])
|
||||
# run until the end of the cycle time
|
||||
self.stim.write_control(self.cycle_times[-1] + period)
|
||||
|
||||
self.sf.close()
|
||||
|
||||
def write_measures(self,period):
|
||||
# meas statement for delay and power measurements
|
||||
self.sf.write("* Measure statements for delay and power\n")
|
||||
"""
|
||||
Write the measure statements to quantify the delay and power results.
|
||||
"""
|
||||
|
||||
self.sf.write("\n* Measure statements for delay and power\n")
|
||||
|
||||
# Output some comments to aid where cycles start and
|
||||
# what is happening
|
||||
for comment in self.cycle_comments:
|
||||
self.sf.write("* {}\n".format(comment))
|
||||
|
||||
# Trigger on the clk of the appropriate cycle
|
||||
trig_name = "clk"
|
||||
targ_name = "{0}".format("d[{0}]".format(self.probe_data))
|
||||
trig_val = targ_val = 0.5 * self.vdd
|
||||
# add measure statments for delay0
|
||||
# delay the target to measure after the negetive edge
|
||||
stimuli.gen_meas_delay(stim_file=self.sf,
|
||||
meas_name="DELAY0",
|
||||
trig_name=trig_name,
|
||||
targ_name=targ_name,
|
||||
trig_val=trig_val,
|
||||
targ_val=targ_val,
|
||||
trig_dir="FALL",
|
||||
targ_dir="FALL",
|
||||
td=self.cycle_times[self.read0_cycle]+0.5*period)
|
||||
trig_val = targ_val = 0.5 * self.vdd_voltage
|
||||
|
||||
stimuli.gen_meas_delay(stim_file=self.sf,
|
||||
meas_name="DELAY1",
|
||||
trig_name=trig_name,
|
||||
targ_name=targ_name,
|
||||
trig_val=trig_val,
|
||||
targ_val=targ_val,
|
||||
trig_dir="FALL",
|
||||
targ_dir="RISE",
|
||||
td=self.cycle_times[self.read1_cycle]+0.5*period)
|
||||
# Delay the target to measure after the negative edge
|
||||
self.stim.gen_meas_delay(meas_name="DELAY0",
|
||||
trig_name=trig_name,
|
||||
targ_name=targ_name,
|
||||
trig_val=trig_val,
|
||||
targ_val=targ_val,
|
||||
trig_dir="FALL",
|
||||
targ_dir="FALL",
|
||||
trig_td=self.cycle_times[self.read0_cycle],
|
||||
targ_td=self.cycle_times[self.read0_cycle]+0.5*period)
|
||||
|
||||
stimuli.gen_meas_delay(stim_file=self.sf,
|
||||
meas_name="SLEW0",
|
||||
trig_name=targ_name,
|
||||
targ_name=targ_name,
|
||||
trig_val=0.9*self.vdd,
|
||||
targ_val=0.1*self.vdd,
|
||||
trig_dir="FALL",
|
||||
targ_dir="FALL",
|
||||
td=self.cycle_times[self.read0_cycle]+0.5*period)
|
||||
self.stim.gen_meas_delay(meas_name="DELAY1",
|
||||
trig_name=trig_name,
|
||||
targ_name=targ_name,
|
||||
trig_val=trig_val,
|
||||
targ_val=targ_val,
|
||||
trig_dir="FALL",
|
||||
targ_dir="RISE",
|
||||
trig_td=self.cycle_times[self.read1_cycle],
|
||||
targ_td=self.cycle_times[self.read1_cycle]+0.5*period)
|
||||
|
||||
stimuli.gen_meas_delay(stim_file=self.sf,
|
||||
meas_name="SLEW1",
|
||||
trig_name=targ_name,
|
||||
targ_name=targ_name,
|
||||
trig_val=0.1*self.vdd,
|
||||
targ_val=0.9*self.vdd,
|
||||
trig_dir="RISE",
|
||||
targ_dir="RISE",
|
||||
td=self.cycle_times[self.read1_cycle]+0.5*period)
|
||||
self.stim.gen_meas_delay(meas_name="SLEW0",
|
||||
trig_name=targ_name,
|
||||
targ_name=targ_name,
|
||||
trig_val=0.9*self.vdd_voltage,
|
||||
targ_val=0.1*self.vdd_voltage,
|
||||
trig_dir="FALL",
|
||||
targ_dir="FALL",
|
||||
trig_td=self.cycle_times[self.read0_cycle],
|
||||
targ_td=self.cycle_times[self.read0_cycle]+0.5*period)
|
||||
|
||||
self.stim.gen_meas_delay(meas_name="SLEW1",
|
||||
trig_name=targ_name,
|
||||
targ_name=targ_name,
|
||||
trig_val=0.1*self.vdd_voltage,
|
||||
targ_val=0.9*self.vdd_voltage,
|
||||
trig_dir="RISE",
|
||||
targ_dir="RISE",
|
||||
trig_td=self.cycle_times[self.read1_cycle],
|
||||
targ_td=self.cycle_times[self.read1_cycle]+0.5*period)
|
||||
|
||||
# add measure statements for power
|
||||
t_initial = self.cycle_times[self.write0_cycle]
|
||||
t_final = self.cycle_times[self.write0_cycle+1]
|
||||
stimuli.gen_meas_power(stim_file=self.sf,
|
||||
meas_name="WRITE0_POWER",
|
||||
t_initial=t_initial,
|
||||
t_final=t_final)
|
||||
self.stim.gen_meas_power(meas_name="WRITE0_POWER",
|
||||
t_initial=t_initial,
|
||||
t_final=t_final)
|
||||
|
||||
t_initial = self.cycle_times[self.write1_cycle]
|
||||
t_final = self.cycle_times[self.write1_cycle+1]
|
||||
stimuli.gen_meas_power(stim_file=self.sf,
|
||||
meas_name="WRITE1_POWER",
|
||||
t_initial=t_initial,
|
||||
t_final=t_final)
|
||||
self.stim.gen_meas_power(meas_name="WRITE1_POWER",
|
||||
t_initial=t_initial,
|
||||
t_final=t_final)
|
||||
|
||||
t_initial = self.cycle_times[self.read0_cycle]
|
||||
t_final = self.cycle_times[self.read0_cycle+1]
|
||||
stimuli.gen_meas_power(stim_file=self.sf,
|
||||
meas_name="READ0_POWER",
|
||||
t_initial=t_initial,
|
||||
t_final=t_final)
|
||||
self.stim.gen_meas_power(meas_name="READ0_POWER",
|
||||
t_initial=t_initial,
|
||||
t_final=t_final)
|
||||
|
||||
t_initial = self.cycle_times[self.read1_cycle]
|
||||
t_final = self.cycle_times[self.read1_cycle+1]
|
||||
stimuli.gen_meas_power(stim_file=self.sf,
|
||||
meas_name="READ1_POWER",
|
||||
t_initial=t_initial,
|
||||
t_final=t_final)
|
||||
self.stim.gen_meas_power(meas_name="READ1_POWER",
|
||||
t_initial=t_initial,
|
||||
t_final=t_final)
|
||||
|
||||
def find_feasible_period(self, load, slew):
|
||||
"""Uses an initial period and finds a feasible period before we
|
||||
"""
|
||||
Uses an initial period and finds a feasible period before we
|
||||
run the binary search algorithm to find min period. We check if
|
||||
the given clock period is valid and if it's not, we continue to
|
||||
double the period until we find a valid period to use as a
|
||||
starting point. """
|
||||
starting point.
|
||||
"""
|
||||
|
||||
feasible_period = tech.spice["feasible_period"]
|
||||
time_out = 8
|
||||
|
|
@ -220,17 +226,23 @@ class delay():
|
|||
feasible_period = 2 * feasible_period
|
||||
continue
|
||||
|
||||
debug.info(1, "Found feasible_period: {0}ns feasible_delay1/0 {1}ns/{2}ns slew {3}ns/{4}ns".format(feasible_period,feasible_delay1,feasible_delay0,feasible_slew1,feasible_slew0))
|
||||
debug.info(1, "Found feasible_period: {0}ns feasible_delay1/0 {1}ns/{2}ns slew {3}ns/{4}ns".format(feasible_period,
|
||||
feasible_delay1,
|
||||
feasible_delay0,
|
||||
feasible_slew1,
|
||||
feasible_slew0))
|
||||
return (feasible_period, feasible_delay1, feasible_delay0)
|
||||
|
||||
|
||||
def run_simulation(self, period, load, slew):
|
||||
""" This tries to simulate a period and checks if the result
|
||||
works. If so, it returns True and the delays and slews."""
|
||||
"""
|
||||
This tries to simulate a period and checks if the result
|
||||
works. If so, it returns True and the delays and slews.
|
||||
"""
|
||||
|
||||
# Checking from not data_value to data_value
|
||||
self.write_stimulus(period, load, slew)
|
||||
stimuli.run_sim()
|
||||
self.stim.run_sim()
|
||||
delay0 = ch.convert_to_float(ch.parse_output("timing", "delay0"))
|
||||
delay1 = ch.convert_to_float(ch.parse_output("timing", "delay1"))
|
||||
slew0 = ch.convert_to_float(ch.parse_output("timing", "slew0"))
|
||||
|
|
@ -238,15 +250,37 @@ class delay():
|
|||
|
||||
# if it failed or the read was longer than a period
|
||||
if type(delay0)!=float or type(delay1)!=float or type(slew1)!=float or type(slew0)!=float:
|
||||
debug.info(2,"Failed simulation: period {0} load {1} slew {2}, delay0={3}n delay1={4}ns slew0={5}n slew1={6}n".format(period,
|
||||
load,
|
||||
slew,
|
||||
delay0,
|
||||
delay1,
|
||||
slew0,
|
||||
slew1))
|
||||
return (False,0,0,0,0)
|
||||
# Scale delays to ns (they previously could have not been floats)
|
||||
delay0 *= 1e9
|
||||
delay1 *= 1e9
|
||||
slew0 *= 1e9
|
||||
slew1 *= 1e9
|
||||
if delay0>period or delay1>period or slew0>period or slew1>period:
|
||||
debug.info(2,"UNsuccessful simulation: period {0} load {1} slew {2}, delay0={3}n delay1={4}ns slew0={5}n slew1={6}n".format(period,
|
||||
load,
|
||||
slew,
|
||||
delay0,
|
||||
delay1,
|
||||
slew0,
|
||||
slew1))
|
||||
return (False,0,0,0,0)
|
||||
else:
|
||||
debug.info(2,"Successful simulation: period {0} load {1} slew {2}, delay0={3}n delay1={4}ns slew0={5}n slew1={6}n".format(period,load,slew,delay0,delay1,slew0,slew1))
|
||||
debug.info(2,"Successful simulation: period {0} load {1} slew {2}, delay0={3}n delay1={4}ns slew0={5}n slew1={6}n".format(period,
|
||||
load,
|
||||
slew,
|
||||
delay0,
|
||||
delay1,
|
||||
slew0,
|
||||
slew1))
|
||||
# For debug, you sometimes want to inspect each simulation.
|
||||
#key=raw_input("press return to continue")
|
||||
|
||||
# The delay is from the negative edge for our SRAM
|
||||
|
|
@ -255,8 +289,10 @@ class delay():
|
|||
|
||||
|
||||
def find_min_period(self,feasible_period, load, slew, feasible_delay1, feasible_delay0):
|
||||
"""Searches for the smallest period with output delays being within 5% of
|
||||
long period. """
|
||||
"""
|
||||
Searches for the smallest period with output delays being within 5% of
|
||||
long period.
|
||||
"""
|
||||
|
||||
previous_period = ub_period = feasible_period
|
||||
lb_period = 0.0
|
||||
|
|
@ -284,26 +320,36 @@ class delay():
|
|||
|
||||
|
||||
def try_period(self, period, load, slew, feasible_delay1, feasible_delay0):
|
||||
""" This tries to simulate a period and checks if the result
|
||||
works. If it does and the delay is within 5% still, it returns True."""
|
||||
"""
|
||||
This tries to simulate a period and checks if the result
|
||||
works. If it does and the delay is within 5% still, it returns True.
|
||||
"""
|
||||
|
||||
# Checking from not data_value to data_value
|
||||
self.write_stimulus(period,load,slew)
|
||||
stimuli.run_sim()
|
||||
self.stim.run_sim()
|
||||
delay0 = ch.convert_to_float(ch.parse_output("timing", "delay0"))
|
||||
delay1 = ch.convert_to_float(ch.parse_output("timing", "delay1"))
|
||||
slew0 = ch.convert_to_float(ch.parse_output("timing", "slew0"))
|
||||
slew1 = ch.convert_to_float(ch.parse_output("timing", "slew1"))
|
||||
# if it failed or the read was longer than a period
|
||||
if type(delay0)!=float or type(delay1)!=float or type(slew1)!=float or type(slew0)!=float:
|
||||
debug.info(2,"Invalid measures: Period {0}, delay0={1}ns, delay1={2}ns slew0={3}ns slew1={4}ns".format(period, delay0, delay1, slew0, slew1))
|
||||
debug.info(2,"Invalid measures: Period {0}, delay0={1}ns, delay1={2}ns slew0={3}ns slew1={4}ns".format(period,
|
||||
delay0,
|
||||
delay1,
|
||||
slew0,
|
||||
slew1))
|
||||
return False
|
||||
delay0 *= 1e9
|
||||
delay1 *= 1e9
|
||||
slew0 *= 1e9
|
||||
slew1 *= 1e9
|
||||
if delay0>period or delay1>period or slew0>period or slew1>period:
|
||||
debug.info(2,"Too long delay/slew: Period {0}, delay0={1}ns, delay1={2}ns slew0={3}ns slew1={4}ns".format(period, delay0, delay1, slew0, slew1))
|
||||
debug.info(2,"Too long delay/slew: Period {0}, delay0={1}ns, delay1={2}ns slew0={3}ns slew1={4}ns".format(period,
|
||||
delay0,
|
||||
delay1,
|
||||
slew0,
|
||||
slew1))
|
||||
return False
|
||||
else:
|
||||
if not ch.relative_compare(delay1,feasible_delay1,error_tolerance=0.05):
|
||||
|
|
@ -316,7 +362,11 @@ class delay():
|
|||
|
||||
#key=raw_input("press return to continue")
|
||||
|
||||
debug.info(2,"Successful period {0}, delay0={1}ns, delay1={2}ns slew0={3}ns slew1={4}ns".format(period, delay0, delay1, slew0, slew1))
|
||||
debug.info(2,"Successful period {0}, delay0={1}ns, delay1={2}ns slew0={3}ns slew1={4}ns".format(period,
|
||||
delay0,
|
||||
delay1,
|
||||
slew0,
|
||||
slew1))
|
||||
return True
|
||||
|
||||
def set_probe(self,probe_address, probe_data):
|
||||
|
|
@ -394,47 +444,96 @@ class delay():
|
|||
of the cycles to do a timing evaluation. The last time is the end of the simulation
|
||||
and does not need a rising edge."""
|
||||
|
||||
# idle cycle, no operation
|
||||
t_current = period
|
||||
self.cycle_comments = []
|
||||
self.cycle_times = []
|
||||
|
||||
# cycle0: W data 1 address 1111 to initialize cell to a value
|
||||
t_current = 0
|
||||
|
||||
# idle cycle, no operation
|
||||
msg = "Idle cycle (no clock)"
|
||||
self.cycle_comments.append("Cycle{0}\t{1}ns:\t{2}".format(0,
|
||||
t_current,
|
||||
msg))
|
||||
self.cycle_times.append(t_current)
|
||||
t_current += period
|
||||
|
||||
# cycle1: W data 0 address 1111 (to ensure a write of value works)
|
||||
# One period
|
||||
msg = "W data 1 address 11..11 to initialize cell"
|
||||
self.cycle_times.append(t_current)
|
||||
self.write0_cycle=1
|
||||
self.cycle_comments.append("Cycle{0}\t{1}ns:\t{2}".format(len(self.cycle_times)-1,
|
||||
t_current,
|
||||
msg))
|
||||
t_current += period
|
||||
|
||||
# One period
|
||||
msg = "W data 0 address 11..11 (to ensure a write of value works)"
|
||||
self.cycle_times.append(t_current)
|
||||
self.write0_cycle=len(self.cycle_times)-1
|
||||
self.cycle_comments.append("Cycle{0}\t{1}ns:\t{2}".format(len(self.cycle_times)-1,
|
||||
t_current,
|
||||
msg))
|
||||
t_current += period
|
||||
|
||||
# cycle2: W data 1 address 0000 (to clear the data bus cap)
|
||||
# One period
|
||||
msg = "W data 1 address 00..00 (to clear bus caps)"
|
||||
self.cycle_times.append(t_current)
|
||||
self.cycle_comments.append("Cycle{0}\t{1}ns:\t{2}".format(len(self.cycle_times)-1,
|
||||
t_current,
|
||||
msg))
|
||||
t_current += period
|
||||
|
||||
# One period
|
||||
msg = "R data 0 address 11..11 to check W0 worked"
|
||||
self.cycle_times.append(t_current)
|
||||
self.read0_cycle=len(self.cycle_times)-1
|
||||
self.cycle_comments.append("Cycle{0}\t{1}ns:\t{2}".format(len(self.cycle_times)-1,
|
||||
t_current,
|
||||
msg))
|
||||
t_current += period
|
||||
|
||||
# One period
|
||||
msg = "Idle cycle"
|
||||
self.cycle_comments.append("Cycle{0}\t{1}ns:\t{2}".format(len(self.cycle_times)-1,
|
||||
t_current,
|
||||
msg))
|
||||
self.cycle_times.append(t_current)
|
||||
t_current += period
|
||||
|
||||
# cycle3: R data 0 address 1111 to check W0 works
|
||||
# One period
|
||||
msg = "W data 1 address 11..11 (to ensure a write of value worked)"
|
||||
self.cycle_times.append(t_current)
|
||||
self.read0_cycle=3
|
||||
self.write1_cycle=len(self.cycle_times)-1
|
||||
self.cycle_comments.append("Cycle{0}\t{1}ns:\t{2}".format(len(self.cycle_times)-1,
|
||||
t_current,
|
||||
msg))
|
||||
t_current += period
|
||||
|
||||
# cycle4: W data 1 address 1111 (to ensure a write of value works)
|
||||
self.cycle_times.append(t_current)
|
||||
self.write1_cycle=4
|
||||
t_current += period
|
||||
|
||||
# cycle5: W data 0 address 0000 (to clear the data bus cap)
|
||||
# One period
|
||||
msg = "W data 0 address 00..00 (to clear bus caps)"
|
||||
self.cycle_times.append(t_current)
|
||||
self.cycle_comments.append("Cycle{0}\t{1}ns:\t{2}".format(len(self.cycle_times)-1,
|
||||
t_current,
|
||||
msg))
|
||||
t_current += period
|
||||
|
||||
# cycle6: R data 1 address 1111 to check W1 works
|
||||
# One period
|
||||
msg = "R data 1 address 11..11 to check W1 worked"
|
||||
self.cycle_times.append(t_current)
|
||||
self.read1_cycle=6
|
||||
self.read1_cycle=len(self.cycle_times)-1
|
||||
self.cycle_comments.append("Cycle{0}\t{1}ns:\t{2}".format(len(self.cycle_times)-1,
|
||||
t_current,
|
||||
msg))
|
||||
t_current += period
|
||||
|
||||
# cycle7: wait a clock period to end the simulation
|
||||
# One period
|
||||
msg = "Idle cycle"
|
||||
self.cycle_comments.append("Cycle{0}\t{1}ns:\t{2}".format(len(self.cycle_times)-1,
|
||||
t_current,
|
||||
msg))
|
||||
self.cycle_times.append(t_current)
|
||||
t_current += period
|
||||
|
||||
|
||||
|
||||
def analytical_model(self,sram, slews, loads):
|
||||
""" Just return the analytical model results for the SRAM.
|
||||
"""
|
||||
|
|
@ -465,3 +564,54 @@ class delay():
|
|||
}
|
||||
return data
|
||||
|
||||
def gen_data(self, clk_times, sig_name, period, slew):
|
||||
""" Generates the PWL data inputs for a simulation timing test. """
|
||||
# values for NOP, W1, W0, W1, R0, NOP, W1, W0, R1, NOP
|
||||
# we are asserting the opposite value on the other side of the tx gate during
|
||||
# the read to be "worst case". Otherwise, it can actually assist the read.
|
||||
values = [0, 1, 0, 1, 1, 1, 1, 0, 0, 0 ]
|
||||
self.stim.gen_pwl(sig_name, clk_times, values, period, slew, 0.05)
|
||||
|
||||
def gen_addr(self, clk_times, addr, period, slew):
|
||||
"""
|
||||
Generates the address inputs for a simulation timing test.
|
||||
This alternates between all 1's and all 0's for the address.
|
||||
"""
|
||||
|
||||
zero_values = [0, 0, 0, 1, 0, 0, 0, 1, 0, 0 ]
|
||||
ones_values = [1, 1, 1, 0, 1, 0, 1, 0, 1, 1 ]
|
||||
|
||||
for i in range(len(addr)):
|
||||
sig_name = "A[{0}]".format(i)
|
||||
if addr[i]=="1":
|
||||
self.stim.gen_pwl(sig_name, clk_times, ones_values, period, slew, 0.05)
|
||||
else:
|
||||
self.stim.gen_pwl(sig_name, clk_times, zero_values, period, slew, 0.05)
|
||||
|
||||
|
||||
def gen_csb(self, clk_times, period, slew):
|
||||
""" Generates the PWL CSb signal """
|
||||
# values for NOP, W1, W0, W1, R0, NOP, W1, W0, R1, NOP
|
||||
# Keep CSb asserted in NOP for measuring >1 period
|
||||
values = [1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
|
||||
self.stim.gen_pwl("csb", clk_times, values, period, slew, 0.05)
|
||||
|
||||
def gen_web(self, clk_times, period, slew):
|
||||
""" Generates the PWL WEb signal """
|
||||
# values for NOP, W1, W0, W1, R0, NOP, W1, W0, R1, NOP
|
||||
# Keep WEb deasserted in NOP for measuring >1 period
|
||||
values = [1, 0, 0, 0, 1, 1, 0, 0, 1, 1]
|
||||
self.stim.gen_pwl("web", clk_times, values, period, slew, 0.05)
|
||||
|
||||
# Keep acc_en deasserted in NOP for measuring >1 period
|
||||
values = [1, 0, 0, 0, 1, 1, 0, 0, 1, 1]
|
||||
self.stim.gen_pwl("acc_en", clk_times, values, period, slew, 0)
|
||||
values = [0, 1, 1, 1, 0, 0, 1, 1, 0, 0]
|
||||
self.stim.gen_pwl("acc_en_inv", clk_times, values, period, slew, 0)
|
||||
|
||||
def gen_oeb(self, clk_times, period, slew):
|
||||
""" Generates the PWL WEb signal """
|
||||
# values for NOP, W1, W0, W1, R0, W1, W0, R1, NOP
|
||||
# Keep OEb asserted in NOP for measuring >1 period
|
||||
values = [1, 1, 1, 1, 0, 0, 1, 1, 0, 0]
|
||||
self.stim.gen_pwl("oeb", clk_times, values, period, slew, 0.05)
|
||||
|
|
|
|||
|
|
@ -1,8 +1,5 @@
|
|||
import os
|
||||
import sys
|
||||
import re
|
||||
import os,sys,re,shutil
|
||||
import debug
|
||||
import tech
|
||||
import math
|
||||
import setup_hold
|
||||
import delay
|
||||
|
|
@ -15,15 +12,23 @@ from globals import OPTS
|
|||
class lib:
|
||||
""" lib file generation."""
|
||||
|
||||
def __init__(self, libname, sram, spfile, use_model=OPTS.analytical_delay):
|
||||
def __init__(self, out_dir, sram, sp_file, use_model=OPTS.analytical_delay):
|
||||
self.out_dir = out_dir
|
||||
self.sram = sram
|
||||
self.sp_file = spfile
|
||||
self.sp_file = sp_file
|
||||
self.use_model = use_model
|
||||
self.name = sram.name
|
||||
self.num_words = sram.num_words
|
||||
self.word_size = sram.word_size
|
||||
self.addr_size = sram.addr_size
|
||||
|
||||
self.prepare_netlist()
|
||||
|
||||
self.prepare_tables()
|
||||
|
||||
self.create_corners()
|
||||
|
||||
self.characterize_corners()
|
||||
|
||||
def prepare_netlist(self):
|
||||
""" Determine whether to use regular or trimmed netlist. """
|
||||
|
||||
# Set up to trim the netlist here if that is enabled
|
||||
if OPTS.trim_netlist:
|
||||
self.sim_sp_file = "{}reduced.sp".format(OPTS.openram_temp)
|
||||
|
|
@ -34,13 +39,17 @@ class lib:
|
|||
self.sram.word_size)
|
||||
else:
|
||||
# Else, use the non-reduced netlist file for simulation
|
||||
self.sim_sp_file = self.sp_file
|
||||
|
||||
self.sim_sp_file = "{}sram.sp".format(OPTS.openram_temp)
|
||||
# Make a copy in temp for debugging
|
||||
shutil.copy(self.sp_file, self.sim_sp_file)
|
||||
|
||||
def prepare_tables(self):
|
||||
""" Determine the load/slews if they aren't specified in the config file. """
|
||||
# These are the parameters to determine the table sizes
|
||||
#self.load_scales = np.array([0.1, 0.25, 0.5, 1, 2, 4, 8])
|
||||
self.load_scales = np.array([0.25, 1, 8])
|
||||
#self.load_scales = np.array([0.25, 1])
|
||||
self.load = tech.spice["FF_in_cap"]
|
||||
self.load = tech.spice["msflop_in_cap"]
|
||||
self.loads = self.load_scales*self.load
|
||||
debug.info(1,"Loads: {0}".format(self.loads))
|
||||
|
||||
|
|
@ -50,9 +59,43 @@ class lib:
|
|||
self.slew = tech.spice["rise_time"]
|
||||
self.slews = self.slew_scales*self.slew
|
||||
debug.info(1,"Slews: {0}".format(self.slews))
|
||||
|
||||
debug.info(1,"Writing to {0}".format(libname))
|
||||
self.lib = open(libname, "w")
|
||||
|
||||
|
||||
def create_corners(self):
|
||||
""" Create corners for characterization. """
|
||||
# Get the corners from the options file
|
||||
self.temperatures = OPTS.temperatures
|
||||
self.supply_voltages = OPTS.supply_voltages
|
||||
self.process_corners = OPTS.process_corners
|
||||
|
||||
# Enumerate all possible corners
|
||||
self.corners = []
|
||||
self.lib_files = []
|
||||
for proc in self.process_corners:
|
||||
for temp in self.temperatures:
|
||||
for volt in self.supply_voltages:
|
||||
self.corner_name = "{0}_{1}_{2}V_{3}C".format(self.sram.name,
|
||||
proc,
|
||||
volt,
|
||||
temp)
|
||||
self.corner_name = self.corner_name.replace(".","") # Remove decimals
|
||||
lib_name = self.out_dir+"{}.lib".format(self.corner_name)
|
||||
|
||||
# A corner is a tuple of PVT
|
||||
self.corners.append((proc, volt, temp))
|
||||
self.lib_files.append(lib_name)
|
||||
|
||||
def characterize_corners(self):
|
||||
""" Characterize the list of corners. """
|
||||
for (self.corner,lib_name) in zip(self.corners,self.lib_files):
|
||||
debug.info(1,"Corner: " + str(self.corner))
|
||||
(self.process, self.voltage, self.temperature) = self.corner
|
||||
self.lib = open(lib_name, "w")
|
||||
debug.info(1,"Writing to {0}".format(lib_name))
|
||||
self.characterize()
|
||||
|
||||
def characterize(self):
|
||||
""" Characterize the current corner. """
|
||||
|
||||
self.write_header()
|
||||
|
||||
|
|
@ -68,7 +111,7 @@ class lib:
|
|||
|
||||
def write_header(self):
|
||||
""" Write the header information """
|
||||
self.lib.write("library ({0}_lib)".format(self.name))
|
||||
self.lib.write("library ({0}_lib)".format(self.corner_name))
|
||||
self.lib.write("{\n")
|
||||
self.lib.write(" delay_model : \"table_lookup\";\n")
|
||||
|
||||
|
|
@ -80,12 +123,12 @@ class lib:
|
|||
|
||||
self.write_bus()
|
||||
|
||||
self.lib.write("cell ({0})".format(self.name))
|
||||
self.lib.write("cell ({0})".format(self.sram.name))
|
||||
self.lib.write("{\n")
|
||||
self.lib.write(" memory(){ \n")
|
||||
self.lib.write(" type : ram;\n")
|
||||
self.lib.write(" address_width : {0};\n".format(self.addr_size))
|
||||
self.lib.write(" word_width : {0};\n".format(self.word_size))
|
||||
self.lib.write(" address_width : {0};\n".format(self.sram.addr_size))
|
||||
self.lib.write(" word_width : {0};\n".format(self.sram.word_size))
|
||||
self.lib.write(" }\n")
|
||||
self.lib.write(" interface_timing : true;\n")
|
||||
self.lib.write(" dont_use : true;\n")
|
||||
|
|
@ -104,9 +147,9 @@ class lib:
|
|||
self.lib.write(" capacitive_load_unit(1 ,fF) ;\n")
|
||||
self.lib.write(" leakage_power_unit : \"1mW\" ;\n")
|
||||
self.lib.write(" pulling_resistance_unit :\"1kohm\" ;\n")
|
||||
self.lib.write(" operating_conditions(TT){\n")
|
||||
self.lib.write(" voltage : {0} ;\n".format(tech.spice["supply_voltage"]))
|
||||
self.lib.write(" temperature : 25.000 ;\n")
|
||||
self.lib.write(" operating_conditions({}){{\n".format(self.process))
|
||||
self.lib.write(" voltage : {} ;\n".format(self.voltage))
|
||||
self.lib.write(" temperature : {};\n".format(self.temperature))
|
||||
self.lib.write(" }\n\n")
|
||||
|
||||
def write_defaults(self):
|
||||
|
|
@ -207,17 +250,17 @@ class lib:
|
|||
self.lib.write(" type (DATA){\n")
|
||||
self.lib.write(" base_type : array;\n")
|
||||
self.lib.write(" data_type : bit;\n")
|
||||
self.lib.write(" bit_width : {0};\n".format(self.word_size))
|
||||
self.lib.write(" bit_width : {0};\n".format(self.sram.word_size))
|
||||
self.lib.write(" bit_from : 0;\n")
|
||||
self.lib.write(" bit_to : {0};\n".format(self.word_size - 1))
|
||||
self.lib.write(" bit_to : {0};\n".format(self.sram.word_size - 1))
|
||||
self.lib.write(" }\n\n")
|
||||
|
||||
self.lib.write(" type (ADDR){\n")
|
||||
self.lib.write(" base_type : array;\n")
|
||||
self.lib.write(" data_type : bit;\n")
|
||||
self.lib.write(" bit_width : {0};\n".format(self.addr_size))
|
||||
self.lib.write(" bit_width : {0};\n".format(self.sram.addr_size))
|
||||
self.lib.write(" bit_from : 0;\n")
|
||||
self.lib.write(" bit_to : {0};\n".format(self.addr_size - 1))
|
||||
self.lib.write(" bit_to : {0};\n".format(self.sram.addr_size - 1))
|
||||
self.lib.write(" }\n\n")
|
||||
|
||||
|
||||
|
|
@ -261,7 +304,7 @@ class lib:
|
|||
self.lib.write(" bus(DATA){\n")
|
||||
self.lib.write(" bus_type : DATA; \n")
|
||||
self.lib.write(" direction : inout; \n")
|
||||
self.lib.write(" max_capacitance : {0}; \n".format(8*tech.spice["FF_in_cap"]))
|
||||
self.lib.write(" max_capacitance : {0}; \n".format(8*tech.spice["msflop_in_cap"]))
|
||||
self.lib.write(" three_state : \"!OEb & !clk\"; \n")
|
||||
self.lib.write(" memory_write(){ \n")
|
||||
self.lib.write(" address : ADDR; \n")
|
||||
|
|
@ -270,7 +313,7 @@ class lib:
|
|||
self.lib.write(" memory_read(){ \n")
|
||||
self.lib.write(" address : ADDR; \n")
|
||||
self.lib.write(" }\n")
|
||||
self.lib.write(" pin(DATA[{0}:0])".format(self.word_size - 1))
|
||||
self.lib.write(" pin(DATA[{0}:0])".format(self.sram.word_size - 1))
|
||||
self.lib.write("{\n")
|
||||
|
||||
self.lib.write(" internal_power(){\n")
|
||||
|
|
@ -325,10 +368,10 @@ class lib:
|
|||
self.lib.write(" bus(ADDR){\n")
|
||||
self.lib.write(" bus_type : ADDR; \n")
|
||||
self.lib.write(" direction : input; \n")
|
||||
self.lib.write(" capacitance : {0}; \n".format(tech.spice["FF_in_cap"]))
|
||||
self.lib.write(" capacitance : {0}; \n".format(tech.spice["msflop_in_cap"]))
|
||||
self.lib.write(" max_transition : {0};\n".format(self.slews[-1]))
|
||||
self.lib.write(" fanout_load : 1.000000;\n")
|
||||
self.lib.write(" pin(ADDR[{0}:0])".format(self.addr_size - 1))
|
||||
self.lib.write(" pin(ADDR[{0}:0])".format(self.sram.addr_size - 1))
|
||||
self.lib.write("{\n")
|
||||
|
||||
self.write_FF_setuphold()
|
||||
|
|
@ -344,7 +387,7 @@ class lib:
|
|||
self.lib.write(" pin({0})".format(i))
|
||||
self.lib.write("{\n")
|
||||
self.lib.write(" direction : input; \n")
|
||||
self.lib.write(" capacitance : {0}; \n".format(tech.spice["FF_in_cap"]))
|
||||
self.lib.write(" capacitance : {0}; \n".format(tech.spice["msflop_in_cap"]))
|
||||
self.write_FF_setuphold()
|
||||
self.lib.write(" }\n\n")
|
||||
|
||||
|
|
@ -357,7 +400,7 @@ class lib:
|
|||
self.lib.write(" pin(clk){\n")
|
||||
self.lib.write(" clock : true;\n")
|
||||
self.lib.write(" direction : input; \n")
|
||||
self.lib.write(" capacitance : {0}; \n".format(tech.spice["FF_in_cap"]))
|
||||
self.lib.write(" capacitance : {0}; \n".format(tech.spice["msflop_in_cap"]))
|
||||
min_pulse_width = ch.round_time(self.delay["min_period"])/2.0
|
||||
min_period = ch.round_time(self.delay["min_period"])
|
||||
self.lib.write(" timing(){ \n")
|
||||
|
|
@ -389,12 +432,12 @@ class lib:
|
|||
try:
|
||||
self.d
|
||||
except AttributeError:
|
||||
self.d = delay.delay(self.sram, self.sim_sp_file)
|
||||
self.d = delay.delay(self.sram, self.sim_sp_file, self.corner)
|
||||
if self.use_model:
|
||||
self.delay = self.d.analytical_model(self.sram,self.slews,self.loads)
|
||||
else:
|
||||
probe_address = "1" * self.addr_size
|
||||
probe_data = self.word_size - 1
|
||||
probe_address = "1" * self.sram.addr_size
|
||||
probe_data = self.sram.word_size - 1
|
||||
# We must trim based on a specific address and data bit
|
||||
if OPTS.trim_netlist:
|
||||
self.trimsp.trim(probe_address,probe_data)
|
||||
|
|
@ -406,7 +449,7 @@ class lib:
|
|||
try:
|
||||
self.sh
|
||||
except AttributeError:
|
||||
self.sh = setup_hold.setup_hold()
|
||||
self.sh = setup_hold.setup_hold(self.corner)
|
||||
if self.use_model:
|
||||
self.times = self.sh.analytical_model(self.slews,self.loads)
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -13,18 +13,23 @@ class setup_hold():
|
|||
(Bisection Methodology)
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
def __init__(self, corner):
|
||||
# This must match the spice model order
|
||||
self.pins = ["data", "dout", "dout_bar", "clk", "vdd", "gnd"]
|
||||
self.model_name = "ms_flop"
|
||||
self.model_location = OPTS.openram_tech + "sp_lib/ms_flop.sp"
|
||||
self.period = tech.spice["feasible_period"]
|
||||
self.vdd = tech.spice["supply_voltage"]
|
||||
self.gnd = tech.spice["gnd_voltage"]
|
||||
|
||||
debug.info(2,"Feasible period from technology file: {0} ".format(self.period))
|
||||
|
||||
self.set_corner(corner)
|
||||
|
||||
|
||||
def set_corner(self,corner):
|
||||
""" Set the corner values """
|
||||
self.corner = corner
|
||||
(self.process, self.vdd_voltage, self.temperature) = corner
|
||||
self.gnd_voltage = 0
|
||||
|
||||
|
||||
def write_stimulus(self, mode, target_time, correct_value):
|
||||
|
|
@ -33,14 +38,14 @@ class setup_hold():
|
|||
# creates and opens the stimulus file for writing
|
||||
temp_stim = OPTS.openram_temp + "stim.sp"
|
||||
self.sf = open(temp_stim, "w")
|
||||
self.stim = stimuli.stimuli(self.sf, self.corner)
|
||||
|
||||
self.write_header(correct_value)
|
||||
|
||||
# instantiate the master-slave d-flip-flop
|
||||
self.sf.write("* Instantiation of the Master-Slave D-flip-flop\n")
|
||||
stimuli.inst_model(stim_file=self.sf,
|
||||
pins=self.pins,
|
||||
model_name=self.model_name)
|
||||
self.sf.write("\n* Instantiation of the Master-Slave D-flip-flop\n")
|
||||
self.stim.inst_model(pins=self.pins,
|
||||
model_name=self.model_name)
|
||||
|
||||
self.write_data(mode=mode,
|
||||
target_time=target_time,
|
||||
|
|
@ -52,22 +57,20 @@ class setup_hold():
|
|||
correct_value=correct_value)
|
||||
|
||||
|
||||
stimuli.write_control(self.sf,4*self.period)
|
||||
self.stim.write_control(4*self.period)
|
||||
|
||||
self.sf.close()
|
||||
|
||||
def write_header(self, correct_value):
|
||||
""" Write the header file with all the models and the power supplies. """
|
||||
self.sf.write("* Stimulus for setup/hold: data {0} period {1}n\n".format(correct_value, self.period))
|
||||
self.sf.write("\n* Stimulus for setup/hold: data {0} period {1}n\n".format(correct_value, self.period))
|
||||
|
||||
# include files in stimulus file
|
||||
self.model_list = tech.spice["fet_models"] + [self.model_location]
|
||||
stimuli.write_include(stim_file=self.sf,
|
||||
models=self.model_list)
|
||||
self.stim.write_include(self.model_location)
|
||||
|
||||
# add vdd/gnd statements
|
||||
self.sf.write("* Global Power Supplies\n")
|
||||
stimuli.write_supply(self.sf)
|
||||
self.sf.write("\n* Global Power Supplies\n")
|
||||
self.stim.write_supply()
|
||||
|
||||
|
||||
def write_data(self, mode, target_time, correct_value):
|
||||
|
|
@ -76,8 +79,8 @@ class setup_hold():
|
|||
characterization.
|
||||
|
||||
"""
|
||||
self.sf.write("* Generation of the data and clk signals\n")
|
||||
incorrect_value = stimuli.get_inverse_value(correct_value)
|
||||
self.sf.write("\n* Generation of the data and clk signals\n")
|
||||
incorrect_value = self.stim.get_inverse_value(correct_value)
|
||||
if mode=="HOLD":
|
||||
init_value = incorrect_value
|
||||
start_value = correct_value
|
||||
|
|
@ -87,29 +90,27 @@ class setup_hold():
|
|||
start_value = incorrect_value
|
||||
end_value = correct_value
|
||||
|
||||
stimuli.gen_pwl(stim_file=self.sf,
|
||||
sig_name="data",
|
||||
clk_times=[self.period, target_time],
|
||||
data_values=[init_value, start_value, end_value],
|
||||
period=target_time,
|
||||
slew=self.constrained_input_slew,
|
||||
setup=0)
|
||||
self.stim.gen_pwl(sig_name="data",
|
||||
clk_times=[0, self.period, target_time],
|
||||
data_values=[init_value, start_value, end_value],
|
||||
period=target_time,
|
||||
slew=self.constrained_input_slew,
|
||||
setup=0)
|
||||
|
||||
def write_clock(self):
|
||||
""" Create the clock signal for setup/hold analysis. First period initializes the FF
|
||||
while the second is used for characterization."""
|
||||
|
||||
stimuli.gen_pwl(stim_file=self.sf,
|
||||
sig_name="clk",
|
||||
# initial clk edge is right after the 0 time to initialize a flop
|
||||
# without using .IC on an internal node.
|
||||
# Return input to value after one period.
|
||||
# The second pulse is the characterization one at 2*period
|
||||
clk_times=[0.1*self.period,self.period,2*self.period],
|
||||
data_values=[0, 1, 0, 1],
|
||||
period=2*self.period,
|
||||
slew=self.constrained_input_slew,
|
||||
setup=0)
|
||||
self.stim.gen_pwl(sig_name="clk",
|
||||
# initial clk edge is right after the 0 time to initialize a flop
|
||||
# without using .IC on an internal node.
|
||||
# Return input to value after one period.
|
||||
# The second pulse is the characterization one at 2*period
|
||||
clk_times=[0, 0.1*self.period,self.period,2*self.period],
|
||||
data_values=[0, 1, 0, 1],
|
||||
period=2*self.period,
|
||||
slew=self.constrained_input_slew,
|
||||
setup=0)
|
||||
|
||||
|
||||
|
||||
|
|
@ -132,33 +133,33 @@ class setup_hold():
|
|||
din_rise_or_fall = "RISE"
|
||||
|
||||
|
||||
self.sf.write("* Measure statements for pass/fail verification\n")
|
||||
self.sf.write("\n* Measure statements for pass/fail verification\n")
|
||||
trig_name = "clk"
|
||||
targ_name = "dout"
|
||||
trig_val = targ_val = 0.5 * self.vdd
|
||||
trig_val = targ_val = 0.5 * self.vdd_voltage
|
||||
# Start triggers right before the clock edge at 2*period
|
||||
stimuli.gen_meas_delay(stim_file=self.sf,
|
||||
meas_name="clk2q_delay",
|
||||
trig_name=trig_name,
|
||||
targ_name=targ_name,
|
||||
trig_val=trig_val,
|
||||
targ_val=targ_val,
|
||||
trig_dir="RISE",
|
||||
targ_dir=dout_rise_or_fall,
|
||||
td=1.9*self.period)
|
||||
|
||||
self.stim.gen_meas_delay(meas_name="clk2q_delay",
|
||||
trig_name=trig_name,
|
||||
targ_name=targ_name,
|
||||
trig_val=trig_val,
|
||||
targ_val=targ_val,
|
||||
trig_dir="RISE",
|
||||
targ_dir=dout_rise_or_fall,
|
||||
trig_td=1.9*self.period,
|
||||
targ_td=1.9*self.period)
|
||||
|
||||
targ_name = "data"
|
||||
# Start triggers right after initialize value is returned to normal
|
||||
# at one period
|
||||
stimuli.gen_meas_delay(stim_file=self.sf,
|
||||
meas_name="setup_hold_time",
|
||||
trig_name=trig_name,
|
||||
targ_name=targ_name,
|
||||
trig_val=trig_val,
|
||||
targ_val=targ_val,
|
||||
trig_dir="RISE",
|
||||
targ_dir=din_rise_or_fall,
|
||||
td=1.2*self.period)
|
||||
self.stim.gen_meas_delay(meas_name="setup_hold_time",
|
||||
trig_name=trig_name,
|
||||
targ_name=targ_name,
|
||||
trig_val=trig_val,
|
||||
targ_val=targ_val,
|
||||
trig_dir="RISE",
|
||||
targ_dir=din_rise_or_fall,
|
||||
trig_td=1.2*self.period,
|
||||
targ_td=1.2*self.period)
|
||||
|
||||
|
||||
|
||||
|
|
@ -184,7 +185,7 @@ class setup_hold():
|
|||
self.write_stimulus(mode=mode,
|
||||
target_time=feasible_bound,
|
||||
correct_value=correct_value)
|
||||
stimuli.run_sim()
|
||||
self.stim.run_sim()
|
||||
ideal_clk_to_q = ch.convert_to_float(ch.parse_output("timing", "clk2q_delay"))
|
||||
setuphold_time = ch.convert_to_float(ch.parse_output("timing", "setup_hold_time"))
|
||||
debug.info(2,"*** {0} CHECK: {1} Ideal Clk-to-Q: {2} Setup/Hold: {3}".format(mode, correct_value,ideal_clk_to_q,setuphold_time))
|
||||
|
|
@ -217,7 +218,7 @@ class setup_hold():
|
|||
feasible_bound))
|
||||
|
||||
|
||||
stimuli.run_sim()
|
||||
self.stim.run_sim()
|
||||
clk_to_q = ch.convert_to_float(ch.parse_output("timing", "clk2q_delay"))
|
||||
setuphold_time = ch.convert_to_float(ch.parse_output("timing", "setup_hold_time"))
|
||||
if type(clk_to_q)==float and (clk_to_q<1.1*ideal_clk_to_q) and type(setuphold_time)==float:
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
"""
|
||||
This file generates the test structure and stimulus for an sram
|
||||
simulation. There are various functions that can be be used to
|
||||
generate stimulus for other simulations as well.
|
||||
This file generates simple spice cards for simulation. There are
|
||||
various functions that can be be used to generate stimulus for other
|
||||
simulations as well.
|
||||
"""
|
||||
|
||||
import tech
|
||||
|
|
@ -12,316 +12,301 @@ import sys
|
|||
import numpy as np
|
||||
from globals import OPTS
|
||||
|
||||
vdd_voltage = tech.spice["supply_voltage"]
|
||||
gnd_voltage = tech.spice["gnd_voltage"]
|
||||
vdd_name = tech.spice["vdd_name"]
|
||||
gnd_name = tech.spice["gnd_name"]
|
||||
pmos_name = tech.spice["pmos_name"]
|
||||
nmos_name = tech.spice["nmos_name"]
|
||||
tx_width = tech.spice["minwidth_tx"]
|
||||
tx_length = tech.spice["channel"]
|
||||
|
||||
def inst_sram(stim_file, abits, dbits, sram_name):
|
||||
"""function to instatiate the sram subckt"""
|
||||
stim_file.write("Xsram ")
|
||||
for i in range(dbits):
|
||||
stim_file.write("D[{0}] ".format(i))
|
||||
for i in range(abits):
|
||||
stim_file.write("A[{0}] ".format(i))
|
||||
for i in tech.spice["control_signals"]:
|
||||
stim_file.write("{0} ".format(i))
|
||||
stim_file.write("{0} ".format(tech.spice["clk"]))
|
||||
stim_file.write("{0} {1} ".format(vdd_name, gnd_name))
|
||||
stim_file.write("{0}\n\n".format(sram_name))
|
||||
class stimuli():
|
||||
""" Class for providing stimuli functions """
|
||||
|
||||
def __init__(self, stim_file, corner):
|
||||
self.vdd_name = tech.spice["vdd_name"]
|
||||
self.gnd_name = tech.spice["gnd_name"]
|
||||
self.pmos_name = tech.spice["pmos"]
|
||||
self.nmos_name = tech.spice["nmos"]
|
||||
self.tx_width = tech.spice["minwidth_tx"]
|
||||
self.tx_length = tech.spice["channel"]
|
||||
|
||||
def inst_model(stim_file, pins, model_name):
|
||||
"""function to instantiate a model"""
|
||||
stim_file.write("X{0} ".format(model_name))
|
||||
for pin in pins:
|
||||
stim_file.write("{0} ".format(pin))
|
||||
stim_file.write("{0}\n".format(model_name))
|
||||
|
||||
|
||||
def create_inverter(stim_file, size=1, beta=2.5):
|
||||
"""Generates inverter for the top level signals (only for sim purposes)"""
|
||||
stim_file.write(".SUBCKT test_inv in out {0} {1}\n".format(vdd_name, gnd_name))
|
||||
stim_file.write("mpinv out in {0} {0} {1} w={2}u l={3}u\n".format(vdd_name,
|
||||
pmos_name,
|
||||
beta * size * tx_width,
|
||||
tx_length))
|
||||
stim_file.write("mninv out in {0} {0} {1} w={2}u l={3}u\n".format(gnd_name,
|
||||
nmos_name,
|
||||
size * tx_width,
|
||||
tx_length))
|
||||
stim_file.write(".ENDS test_inv\n")
|
||||
|
||||
|
||||
def create_buffer(stim_file, buffer_name, size=[1,3], beta=2.5):
|
||||
"""Generates buffer for top level signals (only for sim
|
||||
purposes). Size is pair for PMOS, NMOS width multiple. It includes
|
||||
a beta of 3."""
|
||||
|
||||
stim_file.write(".SUBCKT test_{2} in out {0} {1}\n".format(vdd_name,
|
||||
gnd_name,
|
||||
buffer_name))
|
||||
stim_file.write("mpinv1 out_inv in {0} {0} {1} w={2}u l={3}u\n".format(vdd_name,
|
||||
pmos_name,
|
||||
beta * size[0] * tx_width,
|
||||
tx_length))
|
||||
stim_file.write("mninv1 out_inv in {0} {0} {1} w={2}u l={3}u\n".format(gnd_name,
|
||||
nmos_name,
|
||||
size[0] * tx_width,
|
||||
tx_length))
|
||||
stim_file.write("mpinv2 out out_inv {0} {0} {1} w={2}u l={3}u\n".format(vdd_name,
|
||||
pmos_name,
|
||||
beta * size[1] * tx_width,
|
||||
tx_length))
|
||||
stim_file.write("mninv2 out out_inv {0} {0} {1} w={2}u l={3}u\n".format(gnd_name,
|
||||
nmos_name,
|
||||
size[1] * tx_width,
|
||||
tx_length))
|
||||
stim_file.write(".ENDS test_{0}\n\n".format(buffer_name))
|
||||
|
||||
|
||||
def inst_buffer(stim_file, buffer_name, signal_list):
|
||||
"""Adds buffers to each top level signal that is in signal_list (only for sim purposes)"""
|
||||
for signal in signal_list:
|
||||
stim_file.write("X{0}_buffer {0} {0}_buf {1} {2} test_{3}\n".format(signal,
|
||||
"test"+vdd_name,
|
||||
"test"+gnd_name,
|
||||
buffer_name))
|
||||
|
||||
|
||||
def inst_inverter(stim_file, signal_list):
|
||||
"""Adds inv for each signal that needs its inverted version (only for sim purposes)"""
|
||||
for signal in signal_list:
|
||||
stim_file.write("X{0}_inv {0} {0}_inv {1} {2} test_inv\n".format(signal,
|
||||
"test"+vdd_name,
|
||||
"test"+gnd_name))
|
||||
|
||||
|
||||
def inst_accesstx(stim_file, dbits):
|
||||
"""Adds transmission gate for inputs to data-bus (only for sim purposes)"""
|
||||
stim_file.write("* Tx Pin-list: Drain Gate Source Body\n")
|
||||
for i in range(dbits):
|
||||
pmos_access_string="mp{0} DATA[{0}] acc_en D[{0}] {1} {2} w={3}u l={4}u\n"
|
||||
stim_file.write(pmos_access_string.format(i,
|
||||
"test"+vdd_name,
|
||||
pmos_name,
|
||||
2 * tx_width,
|
||||
tx_length))
|
||||
nmos_access_string="mn{0} DATA[{0}] acc_en_inv D[{0}] {1} {2} w={3}u l={4}u\n"
|
||||
stim_file.write(nmos_access_string.format(i,
|
||||
"test"+gnd_name,
|
||||
nmos_name,
|
||||
2 * tx_width,
|
||||
tx_length))
|
||||
|
||||
def gen_pulse(stim_file, sig_name, v1=gnd_voltage, v2=vdd_voltage, offset=0, period=1, t_rise=0, t_fall=0):
|
||||
"""Generates a periodic signal with 50% duty cycle and slew rates. Period is measured
|
||||
from 50% to 50%."""
|
||||
pulse_string="V{0} {0} 0 PULSE ({1} {2} {3}n {4}n {5}n {6}n {7}n)\n"
|
||||
stim_file.write(pulse_string.format(sig_name,
|
||||
v1,
|
||||
v2,
|
||||
offset,
|
||||
t_rise,
|
||||
t_fall,
|
||||
0.5*period-0.5*t_rise-0.5*t_fall,
|
||||
period))
|
||||
|
||||
|
||||
def gen_pwl(stim_file, sig_name, clk_times, data_values, period, slew, setup):
|
||||
# the initial value is not a clock time
|
||||
debug.check(len(clk_times)+1==len(data_values),"Clock and data value lengths don't match.")
|
||||
# shift signal times earlier for setup time
|
||||
times = np.array(clk_times) - setup*period
|
||||
values = np.array(data_values) * vdd_voltage
|
||||
half_slew = 0.5 * slew
|
||||
stim_file.write("V{0} {0} 0 PWL (0n {1}v ".format(sig_name, values[0]))
|
||||
for i in range(len(times)):
|
||||
stim_file.write("{0}n {1}v {2}n {3}v ".format(times[i]-half_slew,
|
||||
values[i],
|
||||
times[i]+half_slew,
|
||||
values[i+1]))
|
||||
stim_file.write(")\n")
|
||||
|
||||
def gen_data(stim_file, clk_times, sig_name, period, slew):
|
||||
"""Generates the PWL data inputs for a simulation timing test."""
|
||||
# values for NOP, W1, W0, W1, R0, W1, W0, R1, NOP
|
||||
# we are asserting the opposite value on the other side of the tx gate during
|
||||
# the read to be "worst case". Otherwise, it can actually assist the read.
|
||||
values = [0, 1, 0, 1, 1, 1, 0, 0, 0 ]
|
||||
gen_pwl(stim_file, sig_name, clk_times, values, period, slew, 0.05)
|
||||
|
||||
|
||||
def gen_addr(stim_file, clk_times, addr, period, slew):
|
||||
"""Generates the address inputs for a simulation timing test.
|
||||
One cycle is different to clear the bus
|
||||
"""
|
||||
|
||||
zero_values = [0, 0, 0, 1, 0, 0, 1, 0, 0 ]
|
||||
ones_values = [1, 1, 1, 0, 1, 1, 0, 1, 1 ]
|
||||
|
||||
for i in range(len(addr)):
|
||||
sig_name = "A[{0}]".format(i)
|
||||
if addr[i]=="1":
|
||||
gen_pwl(stim_file, sig_name, clk_times, ones_values, period, slew, 0.05)
|
||||
else:
|
||||
gen_pwl(stim_file, sig_name, clk_times, zero_values, period, slew, 0.05)
|
||||
|
||||
def gen_constant(stim_file, sig_name, v_val):
|
||||
"""Generates a constant signal with reference voltage and the voltage value"""
|
||||
stim_file.write("V{0} {0} 0 DC {1}\n".format(sig_name, v_val))
|
||||
|
||||
def gen_csb(stim_file, clk_times, period, slew):
|
||||
""" Generates the PWL CSb signal"""
|
||||
# values for NOP, W1, W0, W1, R0, W1, W0, R1, NOP
|
||||
values = [1, 0, 0, 0, 0, 0, 0, 0, 1]
|
||||
gen_pwl(stim_file, "csb", clk_times, values, period, slew, 0.05)
|
||||
|
||||
def gen_web(stim_file, clk_times, period, slew):
|
||||
""" Generates the PWL WEb signal"""
|
||||
# values for NOP, W1, W0, W1, R0, W1, W0, R1, NOP
|
||||
values = [1, 0, 0, 0, 1, 0, 0, 1, 1]
|
||||
gen_pwl(stim_file, "web", clk_times, values, period, slew, 0.05)
|
||||
|
||||
values = [1, 0, 0, 0, 1, 0, 0, 1, 1]
|
||||
gen_pwl(stim_file, "acc_en", clk_times, values, period, slew, 0)
|
||||
values = [0, 1, 1, 1, 0, 1, 1, 0, 0]
|
||||
gen_pwl(stim_file, "acc_en_inv", clk_times, values, period, slew, 0)
|
||||
|
||||
def gen_oeb(stim_file, clk_times, period, slew):
|
||||
""" Generates the PWL WEb signal"""
|
||||
# values for NOP, W1, W0, W1, R0, W1, W0, R1, NOP
|
||||
values = [1, 1, 1, 1, 0, 1, 1, 0, 1]
|
||||
gen_pwl(stim_file, "oeb", clk_times, values, period, slew, 0.05)
|
||||
|
||||
|
||||
|
||||
|
||||
def get_inverse_voltage(value):
|
||||
if value > 0.5*vdd_voltage:
|
||||
return gnd_voltage
|
||||
elif value <= 0.5*vdd_voltage:
|
||||
return vdd_voltage
|
||||
else:
|
||||
debug.error("Invalid value to get an inverse of: {0}".format(value))
|
||||
|
||||
def get_inverse_value(value):
|
||||
if value > 0.5:
|
||||
return 0
|
||||
elif value <= 0.5:
|
||||
return 1
|
||||
else:
|
||||
debug.error("Invalid value to get an inverse of: {0}".format(value))
|
||||
self.sf = stim_file
|
||||
|
||||
(self.process, self.voltage, self.temperature) = corner
|
||||
self.device_models = tech.spice["fet_models"][self.process]
|
||||
|
||||
def gen_meas_delay(stim_file, meas_name, trig_name, targ_name, trig_val, targ_val, trig_dir, targ_dir, td):
|
||||
"""Creates the .meas statement for the measurement of delay"""
|
||||
measure_string=".meas tran {0} TRIG v({1}) VAL={2} {3}=1 TD={7}n TARG v({4}) VAL={5} {6}=1 TD={7}n\n\n"
|
||||
stim_file.write(measure_string.format(meas_name,
|
||||
trig_name,
|
||||
trig_val,
|
||||
trig_dir,
|
||||
targ_name,
|
||||
targ_val,
|
||||
targ_dir,
|
||||
td))
|
||||
|
||||
def gen_meas_power(stim_file, meas_name, t_initial, t_final):
|
||||
"""Creates the .meas statement for the measurement of avg power"""
|
||||
# power mea cmd is different in different spice:
|
||||
if OPTS.spice_name == "hspice":
|
||||
power_exp = "power"
|
||||
else:
|
||||
power_exp = "par('(-1*v(" + str(vdd_name) + ")*I(v" + str(vdd_name) + "))')"
|
||||
stim_file.write(".meas tran {0} avg {1} from={2}n to={3}n\n\n".format(meas_name,
|
||||
power_exp,
|
||||
t_initial,
|
||||
t_final))
|
||||
stim_file.write("\n")
|
||||
|
||||
def write_control(stim_file, end_time):
|
||||
# UIC is needed for ngspice to converge
|
||||
stim_file.write(".TRAN 5p {0}n UIC\n".format(end_time))
|
||||
stim_file.write(".OPTIONS POST=1 RUNLVL=4 PROBE\n")
|
||||
# create plots for all signals
|
||||
stim_file.write("* probe is used for hspice/xa, while plot is used in ngspice\n")
|
||||
if OPTS.debug_level>0:
|
||||
if OPTS.spice_name in ["hspice","xa"]:
|
||||
stim_file.write(".probe V(*)\n")
|
||||
else:
|
||||
stim_file.write(".plot V(*)\n")
|
||||
else:
|
||||
stim_file.write("*.probe V(*)\n")
|
||||
stim_file.write("*.plot V(*)\n")
|
||||
|
||||
# end the stimulus file
|
||||
stim_file.write(".end\n\n")
|
||||
def inst_sram(self, abits, dbits, sram_name):
|
||||
""" Function to instatiate an SRAM subckt. """
|
||||
self.sf.write("Xsram ")
|
||||
for i in range(dbits):
|
||||
self.sf.write("D[{0}] ".format(i))
|
||||
for i in range(abits):
|
||||
self.sf.write("A[{0}] ".format(i))
|
||||
for i in tech.spice["control_signals"]:
|
||||
self.sf.write("{0} ".format(i))
|
||||
self.sf.write("{0} ".format(tech.spice["clk"]))
|
||||
self.sf.write("{0} {1} ".format(self.vdd_name, self.gnd_name))
|
||||
self.sf.write("{0}\n".format(sram_name))
|
||||
|
||||
|
||||
def write_include(stim_file, models):
|
||||
"""Writes include statements, inputs are lists of model files"""
|
||||
for item in list(models):
|
||||
stim_file.write(".include \"{0}\"\n\n".format(item))
|
||||
def inst_model(self, pins, model_name):
|
||||
""" Function to instantiate a generic model with a set of pins """
|
||||
self.sf.write("X{0} ".format(model_name))
|
||||
for pin in pins:
|
||||
self.sf.write("{0} ".format(pin))
|
||||
self.sf.write("{0}\n".format(model_name))
|
||||
|
||||
|
||||
def write_supply(stim_file):
|
||||
"""Writes supply voltage statements"""
|
||||
stim_file.write("V{0} {0} 0.0 {1}\n".format(vdd_name, vdd_voltage))
|
||||
stim_file.write("V{0} {0} 0.0 {1}\n".format(gnd_name, gnd_voltage))
|
||||
# This is for the test power supply
|
||||
stim_file.write("V{0} {0} 0.0 {1}\n".format("test"+vdd_name, vdd_voltage))
|
||||
stim_file.write("V{0} {0} 0.0 {1}\n\n".format("test"+gnd_name, gnd_voltage))
|
||||
def create_inverter(self, size=1, beta=2.5):
|
||||
""" Generates inverter for the top level signals (only for sim purposes) """
|
||||
self.sf.write(".SUBCKT test_inv in out {0} {1}\n".format(self.vdd_name, self.gnd_name))
|
||||
self.sf.write("mpinv out in {0} {0} {1} w={2}u l={3}u\n".format(self.vdd_name,
|
||||
self.pmos_name,
|
||||
beta * size * self.tx_width,
|
||||
self.tx_length))
|
||||
self.sf.write("mninv out in {0} {0} {1} w={2}u l={3}u\n".format(self.gnd_name,
|
||||
self.nmos_name,
|
||||
size * self.tx_width,
|
||||
self.tx_length))
|
||||
self.sf.write(".ENDS test_inv\n")
|
||||
|
||||
|
||||
def run_sim():
|
||||
"""Run hspice in batch mode and output rawfile to parse."""
|
||||
temp_stim = "{0}stim.sp".format(OPTS.openram_temp)
|
||||
import datetime
|
||||
start_time = datetime.datetime.now()
|
||||
debug.check(OPTS.spice_exe!="","No spice simulator has been found.")
|
||||
|
||||
if OPTS.spice_name == "xa":
|
||||
# Output the xa configurations here. FIXME: Move this to write it once.
|
||||
xa_cfg = open("{}xa.cfg".format(OPTS.openram_temp), "w")
|
||||
xa_cfg.write("set_sim_level -level 7\n")
|
||||
xa_cfg.write("set_powernet_level 7 -node vdd\n")
|
||||
xa_cfg.close()
|
||||
cmd = "{0} {1} -c {2}xa.cfg -o {2}xa -mt 20".format(OPTS.spice_exe,
|
||||
temp_stim,
|
||||
OPTS.openram_temp)
|
||||
valid_retcode=0
|
||||
elif OPTS.spice_name == "hspice":
|
||||
# TODO: Should make multithreading parameter a configuration option
|
||||
cmd = "{0} -mt 2 -i {1} -o {2}timing".format(OPTS.spice_exe,
|
||||
temp_stim,
|
||||
OPTS.openram_temp)
|
||||
valid_retcode=0
|
||||
else:
|
||||
cmd = "{0} -b -o {2}timing.lis {1}".format(OPTS.spice_exe,
|
||||
temp_stim,
|
||||
OPTS.openram_temp)
|
||||
# for some reason, ngspice-25 returns 1 when it only has acceptable warnings
|
||||
valid_retcode=1
|
||||
def create_buffer(self, buffer_name, size=[1,3], beta=2.5):
|
||||
"""
|
||||
Generates buffer for top level signals (only for sim
|
||||
purposes). Size is pair for PMOS, NMOS width multiple.
|
||||
"""
|
||||
|
||||
self.sf.write(".SUBCKT test_{2} in out {0} {1}\n".format(self.vdd_name,
|
||||
self.gnd_name,
|
||||
buffer_name))
|
||||
self.sf.write("mpinv1 out_inv in {0} {0} {1} w={2}u l={3}u\n".format(self.vdd_name,
|
||||
self.pmos_name,
|
||||
beta * size[0] * self.tx_width,
|
||||
self.tx_length))
|
||||
self.sf.write("mninv1 out_inv in {0} {0} {1} w={2}u l={3}u\n".format(self.gnd_name,
|
||||
self.nmos_name,
|
||||
size[0] * self.tx_width,
|
||||
self.tx_length))
|
||||
self.sf.write("mpinv2 out out_inv {0} {0} {1} w={2}u l={3}u\n".format(self.vdd_name,
|
||||
self.pmos_name,
|
||||
beta * size[1] * self.tx_width,
|
||||
self.tx_length))
|
||||
self.sf.write("mninv2 out out_inv {0} {0} {1} w={2}u l={3}u\n".format(self.gnd_name,
|
||||
self.nmos_name,
|
||||
size[1] * self.tx_width,
|
||||
self.tx_length))
|
||||
self.sf.write(".ENDS test_{0}\n\n".format(buffer_name))
|
||||
|
||||
|
||||
def inst_buffer(self, buffer_name, signal_list):
|
||||
""" Adds buffers to each top level signal that is in signal_list (only for sim purposes) """
|
||||
for signal in signal_list:
|
||||
self.sf.write("X{0}_buffer {0} {0}_buf {1} {2} test_{3}\n".format(signal,
|
||||
"test"+self.vdd_name,
|
||||
"test"+self.gnd_name,
|
||||
buffer_name))
|
||||
|
||||
|
||||
def inst_inverter(self, signal_list):
|
||||
""" Adds inv for each signal that needs its inverted version (only for sim purposes) """
|
||||
for signal in signal_list:
|
||||
self.sf.write("X{0}_inv {0} {0}_inv {1} {2} test_inv\n".format(signal,
|
||||
"test"+self.vdd_name,
|
||||
"test"+self.gnd_name))
|
||||
|
||||
|
||||
spice_stdout = open("{0}spice_stdout.log".format(OPTS.openram_temp), 'w')
|
||||
spice_stderr = open("{0}spice_stderr.log".format(OPTS.openram_temp), 'w')
|
||||
def inst_accesstx(self, dbits):
|
||||
""" Adds transmission gate for inputs to data-bus (only for sim purposes) """
|
||||
self.sf.write("* Tx Pin-list: Drain Gate Source Body\n")
|
||||
for i in range(dbits):
|
||||
pmos_access_string="mp{0} DATA[{0}] acc_en D[{0}] {1} {2} w={3}u l={4}u\n"
|
||||
self.sf.write(pmos_access_string.format(i,
|
||||
"test"+self.vdd_name,
|
||||
self.pmos_name,
|
||||
2 * self.tx_width,
|
||||
self.tx_length))
|
||||
nmos_access_string="mn{0} DATA[{0}] acc_en_inv D[{0}] {1} {2} w={3}u l={4}u\n"
|
||||
self.sf.write(nmos_access_string.format(i,
|
||||
"test"+self.gnd_name,
|
||||
self.nmos_name,
|
||||
2 * self.tx_width,
|
||||
self.tx_length))
|
||||
|
||||
debug.info(3, cmd)
|
||||
retcode = subprocess.call(cmd, stdout=spice_stdout, stderr=spice_stderr, shell=True)
|
||||
def gen_pulse(self, sig_name, v1, v2, offset, period, t_rise, t_fall):
|
||||
"""
|
||||
Generates a periodic signal with 50% duty cycle and slew rates. Period is measured
|
||||
from 50% to 50%.
|
||||
"""
|
||||
self.sf.write("* PULSE: period={0}\n".format(period))
|
||||
pulse_string="V{0} {0} 0 PULSE ({1} {2} {3}n {4}n {5}n {6}n {7}n)\n"
|
||||
self.sf.write(pulse_string.format(sig_name,
|
||||
v1,
|
||||
v2,
|
||||
offset,
|
||||
t_rise,
|
||||
t_fall,
|
||||
0.5*period-0.5*t_rise-0.5*t_fall,
|
||||
period))
|
||||
|
||||
spice_stdout.close()
|
||||
spice_stderr.close()
|
||||
|
||||
def gen_pwl(self, sig_name, clk_times, data_values, period, slew, setup):
|
||||
"""
|
||||
Generate a PWL stimulus given a signal name and data values at each period.
|
||||
Automatically creates slews and ensures each data occurs a setup before the clock
|
||||
edge. The first clk_time should be 0 and is the initial time that corresponds
|
||||
to the initial value.
|
||||
"""
|
||||
# the initial value is not a clock time
|
||||
debug.check(len(clk_times)==len(data_values),"Clock and data value lengths don't match.")
|
||||
|
||||
if (retcode > valid_retcode):
|
||||
debug.error("Spice simulation error: " + cmd, -1)
|
||||
else:
|
||||
end_time = datetime.datetime.now()
|
||||
delta_time = round((end_time-start_time).total_seconds(),1)
|
||||
debug.info(2,"*** Spice: {} seconds".format(delta_time))
|
||||
# shift signal times earlier for setup time
|
||||
times = np.array(clk_times) - setup*period
|
||||
values = np.array(data_values) * self.voltage
|
||||
half_slew = 0.5 * slew
|
||||
self.sf.write("* (time, data): {}\n".format(zip(clk_times, data_values)))
|
||||
self.sf.write("V{0} {0} 0 PWL (0n {1}v ".format(sig_name, values[0]))
|
||||
for i in range(1,len(times)):
|
||||
self.sf.write("{0}n {1}v {2}n {3}v ".format(times[i]-half_slew,
|
||||
values[i-1],
|
||||
times[i]+half_slew,
|
||||
values[i]))
|
||||
self.sf.write(")\n")
|
||||
|
||||
def gen_constant(self, sig_name, v_val):
|
||||
""" Generates a constant signal with reference voltage and the voltage value """
|
||||
self.sf.write("V{0} {0} 0 DC {1}\n".format(sig_name, v_val))
|
||||
|
||||
def get_inverse_voltage(self, value):
|
||||
if value > 0.5*self.voltage:
|
||||
return 0
|
||||
elif value <= 0.5*self.voltage:
|
||||
return self.voltage
|
||||
else:
|
||||
debug.error("Invalid value to get an inverse of: {0}".format(value))
|
||||
|
||||
def get_inverse_value(self, value):
|
||||
if value > 0.5:
|
||||
return 0
|
||||
elif value <= 0.5:
|
||||
return 1
|
||||
else:
|
||||
debug.error("Invalid value to get an inverse of: {0}".format(value))
|
||||
|
||||
|
||||
def gen_meas_delay(self, meas_name, trig_name, targ_name, trig_val, targ_val, trig_dir, targ_dir, trig_td, targ_td):
|
||||
""" Creates the .meas statement for the measurement of delay """
|
||||
measure_string=".meas tran {0} TRIG v({1}) VAL={2} {3}=1 TD={4}n TARG v({5}) VAL={6} {7}=1 TD={8}n\n\n"
|
||||
self.sf.write(measure_string.format(meas_name,
|
||||
trig_name,
|
||||
trig_val,
|
||||
trig_dir,
|
||||
trig_td,
|
||||
targ_name,
|
||||
targ_val,
|
||||
targ_dir,
|
||||
targ_td))
|
||||
|
||||
def gen_meas_power(self, meas_name, t_initial, t_final):
|
||||
""" Creates the .meas statement for the measurement of avg power """
|
||||
# power mea cmd is different in different spice:
|
||||
if OPTS.spice_name == "hspice":
|
||||
power_exp = "power"
|
||||
else:
|
||||
power_exp = "par('(-1*v(" + str(self.vdd_name) + ")*I(v" + str(self.vdd_name) + "))')"
|
||||
self.sf.write(".meas tran {0} avg {1} from={2}n to={3}n\n\n".format(meas_name,
|
||||
power_exp,
|
||||
t_initial,
|
||||
t_final))
|
||||
|
||||
def write_control(self, end_time):
|
||||
""" Write the control cards to run and end the simulation """
|
||||
# UIC is needed for ngspice to converge
|
||||
self.sf.write(".TRAN 5p {0}n UIC\n".format(end_time))
|
||||
if OPTS.spice_name == "ngspice":
|
||||
# ngspice sometimes has convergence problems if not using gear method
|
||||
# which is more accurate, but slower than the default trapezoid method
|
||||
# Do not remove this or it may not converge due to some "pa_00" nodes
|
||||
# unless you figure out what these are.
|
||||
self.sf.write(".OPTIONS POST=1 RUNLVL=4 PROBE method=gear TEMP={}\n".format(self.temperature))
|
||||
else:
|
||||
self.sf.write(".OPTIONS POST=1 RUNLVL=4 PROBE TEMP={}\n".format(self.temperature))
|
||||
|
||||
# create plots for all signals
|
||||
self.sf.write("* probe is used for hspice/xa, while plot is used in ngspice\n")
|
||||
if OPTS.debug_level>0:
|
||||
if OPTS.spice_name in ["hspice","xa"]:
|
||||
self.sf.write(".probe V(*)\n")
|
||||
else:
|
||||
self.sf.write(".plot V(*)\n")
|
||||
else:
|
||||
self.sf.write("*.probe V(*)\n")
|
||||
self.sf.write("*.plot V(*)\n")
|
||||
|
||||
# end the stimulus file
|
||||
self.sf.write(".end\n\n")
|
||||
|
||||
|
||||
def write_include(self, circuit):
|
||||
"""Writes include statements, inputs are lists of model files"""
|
||||
includes = self.device_models + [circuit]
|
||||
self.sf.write("* {} process corner\n".format(self.process))
|
||||
for item in list(includes):
|
||||
if os.path.isfile(item):
|
||||
self.sf.write(".include \"{0}\"\n".format(item))
|
||||
else:
|
||||
debug.error("Could not find spice model: {0}\nSet SPICE_MODEL_DIR to over-ride path.\n".format(item))
|
||||
|
||||
|
||||
def write_supply(self):
|
||||
""" Writes supply voltage statements """
|
||||
self.sf.write("V{0} {0} 0.0 {1}\n".format(self.vdd_name, self.voltage))
|
||||
self.sf.write("V{0} {0} 0.0 {1}\n".format(self.gnd_name, 0))
|
||||
# This is for the test power supply
|
||||
self.sf.write("V{0} {0} 0.0 {1}\n".format("test"+self.vdd_name, self.voltage))
|
||||
self.sf.write("V{0} {0} 0.0 {1}\n".format("test"+self.gnd_name, 0))
|
||||
|
||||
|
||||
def run_sim(self):
|
||||
""" Run hspice in batch mode and output rawfile to parse. """
|
||||
temp_stim = "{0}stim.sp".format(OPTS.openram_temp)
|
||||
import datetime
|
||||
start_time = datetime.datetime.now()
|
||||
debug.check(OPTS.spice_exe!="","No spice simulator has been found.")
|
||||
|
||||
if OPTS.spice_name == "xa":
|
||||
# Output the xa configurations here. FIXME: Move this to write it once.
|
||||
xa_cfg = open("{}xa.cfg".format(OPTS.openram_temp), "w")
|
||||
xa_cfg.write("set_sim_level -level 7\n")
|
||||
xa_cfg.write("set_powernet_level 7 -node vdd\n")
|
||||
xa_cfg.close()
|
||||
cmd = "{0} {1} -c {2}xa.cfg -o {2}xa -mt 2".format(OPTS.spice_exe,
|
||||
temp_stim,
|
||||
OPTS.openram_temp)
|
||||
valid_retcode=0
|
||||
elif OPTS.spice_name == "hspice":
|
||||
# TODO: Should make multithreading parameter a configuration option
|
||||
cmd = "{0} -mt 2 -i {1} -o {2}timing".format(OPTS.spice_exe,
|
||||
temp_stim,
|
||||
OPTS.openram_temp)
|
||||
valid_retcode=0
|
||||
else:
|
||||
cmd = "{0} -b -o {2}timing.lis {1}".format(OPTS.spice_exe,
|
||||
temp_stim,
|
||||
OPTS.openram_temp)
|
||||
# for some reason, ngspice-25 returns 1 when it only has acceptable warnings
|
||||
valid_retcode=1
|
||||
|
||||
|
||||
spice_stdout = open("{0}spice_stdout.log".format(OPTS.openram_temp), 'w')
|
||||
spice_stderr = open("{0}spice_stderr.log".format(OPTS.openram_temp), 'w')
|
||||
|
||||
debug.info(3, cmd)
|
||||
retcode = subprocess.call(cmd, stdout=spice_stdout, stderr=spice_stderr, shell=True)
|
||||
|
||||
spice_stdout.close()
|
||||
spice_stderr.close()
|
||||
|
||||
if (retcode > valid_retcode):
|
||||
debug.error("Spice simulation error: " + cmd, -1)
|
||||
else:
|
||||
end_time = datetime.datetime.now()
|
||||
delta_time = round((end_time-start_time).total_seconds(),1)
|
||||
debug.info(2,"*** Spice: {} seconds".format(delta_time))
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -45,27 +45,38 @@ class trim_spice():
|
|||
|
||||
# Always start fresh if we do multiple reductions
|
||||
self.sp_buffer = self.spice
|
||||
|
||||
# Find the row and column indices for the removals
|
||||
# Convert address froms tring to int
|
||||
address = int(address,2)
|
||||
array_row = address >> self.col_addr_size
|
||||
# Which word in the array (0 if only one word)
|
||||
if self.col_addr_size>0:
|
||||
lower_mask = int(self.col_addr_size-1)
|
||||
lower_address = address & lower_mask
|
||||
else:
|
||||
lower_address=0
|
||||
# Which bit in the array
|
||||
array_bit = lower_address*self.word_size + data_bit
|
||||
|
||||
# Split up the address and convert to an int
|
||||
wl_address = int(address[self.col_addr_size:],2)
|
||||
if self.col_addr_size>1:
|
||||
col_address = int(address[0:self.col_addr_size],2)
|
||||
else:
|
||||
col_address = 0
|
||||
# 1. Keep cells in the bitcell array based on WL and BL
|
||||
wl_name = "wl[{}]".format(array_row)
|
||||
bl_name = "bl[{}]".format(array_bit)
|
||||
wl_name = "wl[{}]".format(wl_address)
|
||||
bl_name = "bl[{}]".format(self.words_per_row*data_bit + col_address)
|
||||
|
||||
# Prepend info about the trimming
|
||||
addr_msg = "Keeping {} address".format(address)
|
||||
self.sp_buffer.insert(0, "* "+addr_msg)
|
||||
debug.info(1,addr_msg)
|
||||
data_msg = "Keeping {} data bit".format(data_bit)
|
||||
self.sp_buffer.insert(0, "* "+data_msg)
|
||||
debug.info(1,data_msg)
|
||||
bl_msg = "Keeping {} (trimming other BLs)".format(bl_name)
|
||||
wl_msg = "Keeping {} (trimming other WLs)".format(wl_name)
|
||||
self.sp_buffer.insert(0, "* "+bl_msg)
|
||||
debug.info(1,bl_msg)
|
||||
self.sp_buffer.insert(0, "* "+wl_msg)
|
||||
debug.info(1,wl_msg)
|
||||
self.sp_buffer.insert(0, "* It should NOT be used for LVS!!")
|
||||
self.sp_buffer.insert(0, "* WARNING: This is a TRIMMED NETLIST.")
|
||||
|
||||
self.remove_insts("bitcell_array",[wl_name,bl_name])
|
||||
|
||||
# 2. Keep sense amps basd on BL
|
||||
self.remove_insts("sense_amp_array",[bl_name])
|
||||
# FIXME: The bit lines are not indexed the same in sense_amp_array
|
||||
#self.remove_insts("sense_amp_array",[bl_name])
|
||||
|
||||
# 3. Keep column muxes basd on BL
|
||||
self.remove_insts("column_mux_array",[bl_name])
|
||||
|
|
|
|||
|
|
@ -1,8 +1,11 @@
|
|||
word_size = 2
|
||||
num_words = 16
|
||||
num_words = 128
|
||||
num_banks = 1
|
||||
|
||||
tech_name = "freepdk45"
|
||||
process_corners = ["TT"]
|
||||
supply_voltages = [1.0]
|
||||
temperatures = [25]
|
||||
|
||||
output_path = "temp"
|
||||
output_name = "sram_2_16_1_freepdk45"
|
||||
|
|
|
|||
|
|
@ -3,6 +3,10 @@ num_words = 16
|
|||
num_banks = 1
|
||||
|
||||
tech_name = "scn3me_subm"
|
||||
process_corners = ["TT"]
|
||||
supply_voltages = [ 5.0 ]
|
||||
temperatures = [ 25 ]
|
||||
|
||||
|
||||
output_path = "temp"
|
||||
output_name = "sram_2_16_1_scn3me_subm"
|
||||
|
|
|
|||
|
|
@ -11,20 +11,11 @@ import sys
|
|||
import re
|
||||
import importlib
|
||||
|
||||
# Current version of OpenRAM.
|
||||
VERSION = "1.01"
|
||||
|
||||
USAGE = "Usage: openram.py [options] <config file>\nUse -h for help.\n"
|
||||
|
||||
# Anonymous object that will be the options
|
||||
OPTS = options.options()
|
||||
|
||||
# check that we are not using version 3 and at least 2.7
|
||||
major_python_version = sys.version_info.major
|
||||
minor_python_version = sys.version_info.minor
|
||||
if not (major_python_version == 2 and minor_python_version >= 7):
|
||||
debug.error("Python 2.7 is required.",-1)
|
||||
|
||||
def parse_args():
|
||||
""" Parse the optional arguments for OpenRAM """
|
||||
|
||||
|
|
@ -39,8 +30,6 @@ def parse_args():
|
|||
help="Output file(s) location"),
|
||||
optparse.make_option("-n", "--nocheck", action="store_false",
|
||||
help="Disable inline LVS/DRC checks", dest="check_lvsdrc"),
|
||||
optparse.make_option("-q", "--quiet", action="store_false", dest="print_banner",
|
||||
help="Don\'t display banner"),
|
||||
optparse.make_option("-v", "--verbose", action="count", dest="debug_level",
|
||||
help="Increase the verbosity level"),
|
||||
optparse.make_option("-t", "--tech", dest="tech_name",
|
||||
|
|
@ -50,14 +39,16 @@ def parse_args():
|
|||
optparse.make_option("-r", "--remove_netlist_trimming", action="store_false", dest="trim_netlist",
|
||||
help="Disable removal of noncritical memory cells during characterization"),
|
||||
optparse.make_option("-c", "--characterize", action="store_false", dest="analytical_delay",
|
||||
help="Perform characterization to calculate delays (default is analytical models)")
|
||||
help="Perform characterization to calculate delays (default is analytical models)"),
|
||||
optparse.make_option("-d", "--dontpurge", action="store_false", dest="purge_temp",
|
||||
help="Don't purge the contents of the temp directory after a successful run")
|
||||
# -h --help is implicit.
|
||||
}
|
||||
|
||||
parser = optparse.OptionParser(option_list=option_list,
|
||||
description="Compile and/or characterize an SRAM.",
|
||||
usage=USAGE,
|
||||
version="OpenRAM v" + VERSION)
|
||||
version="OpenRAM")
|
||||
|
||||
(options, args) = parser.parse_args(values=OPTS)
|
||||
# If we don't specify a tech, assume freepdk45.
|
||||
|
|
@ -67,17 +58,17 @@ def parse_args():
|
|||
# Alias SCMOS to AMI 0.5um
|
||||
if OPTS.tech_name == "scmos":
|
||||
OPTS.tech_name = "scn3me_subm"
|
||||
|
||||
|
||||
return (options, args)
|
||||
|
||||
def print_banner():
|
||||
""" Conditionally print the banner to stdout """
|
||||
global OPTS
|
||||
if not OPTS.print_banner:
|
||||
if OPTS.is_unit_test:
|
||||
return
|
||||
|
||||
print("|==============================================================================|")
|
||||
name = "OpenRAM Compiler v"+VERSION
|
||||
name = "OpenRAM Compiler"
|
||||
print("|=========" + name.center(60) + "=========|")
|
||||
print("|=========" + " ".center(60) + "=========|")
|
||||
print("|=========" + "VLSI Design and Automation Lab".center(60) + "=========|")
|
||||
|
|
@ -86,22 +77,41 @@ def print_banner():
|
|||
print("|=========" + "VLSI Computer Architecture Research Group".center(60) + "=========|")
|
||||
print("|=========" + "Oklahoma State University ECE Department".center(60) + "=========|")
|
||||
print("|=========" + " ".center(60) + "=========|")
|
||||
print("|=========" + OPTS.openram_temp.center(60) + "=========|")
|
||||
user_info = "Usage help: openram-user-group@ucsc.edu"
|
||||
print("|=========" + user_info.center(60) + "=========|")
|
||||
dev_info = "Development help: openram-dev-group@ucsc.edu"
|
||||
print("|=========" + dev_info.center(60) + "=========|")
|
||||
temp_info = "Temp dir: {}".format(OPTS.openram_temp)
|
||||
print("|=========" + temp_info.center(60) + "=========|")
|
||||
print("|==============================================================================|")
|
||||
|
||||
|
||||
def init_openram(config_file):
|
||||
def check_versions():
|
||||
""" Run some checks of required software versions. """
|
||||
|
||||
# check that we are not using version 3 and at least 2.7
|
||||
major_python_version = sys.version_info.major
|
||||
minor_python_version = sys.version_info.minor
|
||||
if not (major_python_version == 2 and minor_python_version >= 7):
|
||||
debug.error("Python 2.7 is required.",-1)
|
||||
|
||||
# FIXME: Check versions of other tools here??
|
||||
# or, this could be done in each module (e.g. verify, characterizer, etc.)
|
||||
|
||||
def init_openram(config_file, is_unit_test=True):
|
||||
"""Initialize the technology, paths, simulators, etc."""
|
||||
check_versions()
|
||||
|
||||
debug.info(1,"Initializing OpenRAM...")
|
||||
|
||||
setup_paths()
|
||||
|
||||
read_config(config_file)
|
||||
read_config(config_file, is_unit_test)
|
||||
|
||||
import_tech()
|
||||
|
||||
|
||||
|
||||
def get_tool(tool_type, preferences):
|
||||
"""
|
||||
Find which tool we have from a list of preferences and return the
|
||||
|
|
@ -121,7 +131,7 @@ def get_tool(tool_type, preferences):
|
|||
|
||||
|
||||
|
||||
def read_config(config_file):
|
||||
def read_config(config_file, is_unit_test=True):
|
||||
"""
|
||||
Read the configuration file that defines a few parameters. The
|
||||
config file is just a Python file that defines some config
|
||||
|
|
@ -159,6 +169,16 @@ def read_config(config_file):
|
|||
OPTS.output_path += "/"
|
||||
debug.info(1, "Output saved in " + OPTS.output_path)
|
||||
|
||||
OPTS.is_unit_test=is_unit_test
|
||||
|
||||
# If config didn't set output name, make a reasonable default.
|
||||
if (OPTS.output_name == ""):
|
||||
OPTS.output_name = "sram_{0}rw_{1}b_{2}w_{3}bank_{4}".format(OPTS.rw_ports,
|
||||
OPTS.word_size,
|
||||
OPTS.num_words,
|
||||
OPTS.num_banks,
|
||||
OPTS.tech_name)
|
||||
|
||||
# Don't delete the output dir, it may have other files!
|
||||
# make the directory if it doesn't exist
|
||||
try:
|
||||
|
|
@ -174,17 +194,17 @@ def read_config(config_file):
|
|||
def end_openram():
|
||||
""" Clean up openram for a proper exit """
|
||||
cleanup_paths()
|
||||
|
||||
|
||||
# Reset the static duplicate name checker for unit tests.
|
||||
# This is needed for running unit tests.
|
||||
import design
|
||||
design.design.name_map=[]
|
||||
|
||||
|
||||
def cleanup_paths():
|
||||
"""
|
||||
We should clean up the temp directory after execution.
|
||||
"""
|
||||
if not OPTS.purge_temp:
|
||||
debug.info(0,"Preserving temp directory: {}".format(OPTS.openram_temp))
|
||||
return
|
||||
if os.path.exists(OPTS.openram_temp):
|
||||
shutil.rmtree(OPTS.openram_temp, ignore_errors=True)
|
||||
|
||||
|
|
@ -199,16 +219,14 @@ def setup_paths():
|
|||
except:
|
||||
debug.error("$OPENRAM_HOME is not properly defined.",1)
|
||||
debug.check(os.path.isdir(OPENRAM_HOME),"$OPENRAM_HOME does not exist: {0}".format(OPENRAM_HOME))
|
||||
|
||||
debug.check(os.path.isdir(OPENRAM_HOME+"/gdsMill"),
|
||||
"$OPENRAM_HOME/gdsMill does not exist: {0}".format(OPENRAM_HOME+"/gdsMill"))
|
||||
sys.path.append("{0}/gdsMill".format(OPENRAM_HOME))
|
||||
debug.check(os.path.isdir(OPENRAM_HOME+"/tests"),
|
||||
"$OPENRAM_HOME/tests does not exist: {0}".format(OPENRAM_HOME+"/tests"))
|
||||
sys.path.append("{0}/tests".format(OPENRAM_HOME))
|
||||
debug.check(os.path.isdir(OPENRAM_HOME+"/router"),
|
||||
"$OPENRAM_HOME/router does not exist: {0}".format(OPENRAM_HOME+"/router"))
|
||||
sys.path.append("{0}/router".format(OPENRAM_HOME))
|
||||
|
||||
# Add all of the subdirs to the python path
|
||||
# These subdirs are modules and don't need to be added: characterizer, verify
|
||||
for subdir in ["gdsMill", "tests", "router", "modules", "base", "pgates"]:
|
||||
full_path = "{0}/{1}".format(OPENRAM_HOME,subdir)
|
||||
debug.check(os.path.isdir(full_path),
|
||||
"$OPENRAM_HOME/{0} does not exist: {1}".format(subdir,full_path))
|
||||
sys.path.append("{0}".format(full_path))
|
||||
|
||||
if not OPTS.openram_temp.endswith('/'):
|
||||
OPTS.openram_temp += "/"
|
||||
|
|
@ -246,9 +264,8 @@ def import_tech():
|
|||
|
||||
# Set the tech to the config file we read in instead of the command line value.
|
||||
OPTS.tech_name = OPTS.tech_name
|
||||
|
||||
|
||||
# environment variable should point to the technology dir
|
||||
|
||||
# environment variable should point to the technology dir
|
||||
try:
|
||||
OPENRAM_TECH = os.path.abspath(os.environ.get("OPENRAM_TECH"))
|
||||
except:
|
||||
|
|
@ -272,3 +289,43 @@ def import_tech():
|
|||
debug.error("Nonexistent technology_setup_file: {0}.py".format(filename))
|
||||
sys.exit(1)
|
||||
|
||||
import tech
|
||||
# Set some default options now based on the technology...
|
||||
if (OPTS.process_corners == ""):
|
||||
OPTS.process_corners = tech.spice["fet_models"].keys()
|
||||
if (OPTS.supply_voltages == ""):
|
||||
OPTS.supply_voltages = tech.spice["supply_voltages"]
|
||||
if (OPTS.temperatures == ""):
|
||||
OPTS.temperatures = tech.spice["temperatures"]
|
||||
|
||||
|
||||
def print_time(name, now_time, last_time=None):
|
||||
""" Print a statement about the time delta. """
|
||||
if last_time:
|
||||
time = round((now_time-last_time).total_seconds(),1)
|
||||
else:
|
||||
time = now_time
|
||||
print("** {0}: {1} seconds".format(name,time))
|
||||
|
||||
|
||||
def report_status():
|
||||
""" Check for valid arguments and report the info about the SRAM being generated """
|
||||
# Check if all arguments are integers for bits, size, banks
|
||||
if type(OPTS.word_size)!=int:
|
||||
debug.error("{0} is not an integer in config file.".format(OPTS.word_size))
|
||||
if type(OPTS.num_words)!=int:
|
||||
debug.error("{0} is not an integer in config file.".format(OPTS.sram_size))
|
||||
if type(OPTS.num_banks)!=int:
|
||||
debug.error("{0} is not an integer in config file.".format(OPTS.num_banks))
|
||||
|
||||
if not OPTS.tech_name:
|
||||
debug.error("Tech name must be specified in config file.")
|
||||
|
||||
print("Output files are " + OPTS.output_name + ".(sp|gds|v|lib|lef)")
|
||||
print("Technology: {0}".format(OPTS.tech_name))
|
||||
print("Word size: {0}\nWords: {1}\nBanks: {2}".format(OPTS.word_size,
|
||||
OPTS.num_words,
|
||||
OPTS.num_banks))
|
||||
if not OPTS.check_lvsdrc:
|
||||
print("DRC/LVS/PEX checking is disabled.")
|
||||
|
||||
|
|
|
|||
|
|
@ -99,8 +99,10 @@ class bank(design.design):
|
|||
self.add_precharge_array()
|
||||
|
||||
if self.col_addr_size > 0:
|
||||
# The m2 width is because the 6T cell may have vias on the boundary edge for
|
||||
# overlapping when making the array
|
||||
self.column_mux_height = self.column_mux_array.height + 0.5*self.m2_width
|
||||
self.add_column_mux_array()
|
||||
self.column_mux_height = self.column_mux_array.height
|
||||
else:
|
||||
self.column_mux_height = 0
|
||||
if self.col_addr_size > 1: # size 1 is from addr FF
|
||||
|
|
@ -249,7 +251,7 @@ class bank(design.design):
|
|||
def add_column_mux_array(self):
|
||||
""" Adding Column Mux when words_per_row > 1 . """
|
||||
|
||||
y_offset = self.column_mux_array.height
|
||||
y_offset = self.column_mux_height
|
||||
self.col_mux_array_inst=self.add_inst(name="column_mux_array",
|
||||
mod=self.column_mux_array,
|
||||
offset=vector(0,y_offset).scale(-1,-1))
|
||||
|
|
@ -434,7 +436,8 @@ class bank(design.design):
|
|||
|
||||
|
||||
# Place the col decoder just to the left of the control bus
|
||||
x_off = self.m2_pitch + self.overall_central_bus_width + self.col_decoder.width
|
||||
gap = max(drc["pwell_to_nwell"], 2*self.m2_pitch)
|
||||
x_off = gap + self.overall_central_bus_width + self.col_decoder.width
|
||||
# Place the col decoder below the the address flops which are below the row decoder (lave some space for wells)
|
||||
vertical_gap = max(drc["pwell_to_nwell"], 2*self.m2_pitch)
|
||||
y_off = self.decoder.predecoder_height + self.msf_address.width + self.col_decoder.height + 2*vertical_gap
|
||||
|
|
@ -68,7 +68,10 @@ class control_logic(design.design):
|
|||
|
||||
c = reload(__import__(OPTS.replica_bitline))
|
||||
replica_bitline = getattr(c, OPTS.replica_bitline)
|
||||
self.replica_bitline = replica_bitline(rows=int(math.ceil(self.num_rows / 10.0)))
|
||||
# FIXME: These should be tuned according to the size!
|
||||
FO4_stages = 8
|
||||
bitcell_loads = int(math.ceil(self.num_rows / 10.0))
|
||||
self.replica_bitline = replica_bitline(FO4_stages, bitcell_loads)
|
||||
self.add_mod(self.replica_bitline)
|
||||
|
||||
|
||||
|
|
@ -77,8 +80,6 @@ class control_logic(design.design):
|
|||
# These aren't for instantiating, but we use them to get the dimensions
|
||||
self.poly_contact_offset = vector(0.5*contact.poly.width,0.5*contact.poly.height)
|
||||
|
||||
# For different layer width vias
|
||||
self.m1m2_offset_fix = vector(0,0.5*(drc["minwidth_metal2"]-drc["minwidth_metal1"]))
|
||||
# M1/M2 routing pitch is based on contacted pitch
|
||||
self.m1_pitch = max(contact.m1m2.width,contact.m1m2.height) + max(drc["metal1_to_metal1"],drc["metal2_to_metal2"])
|
||||
self.m2_pitch = max(contact.m2m3.width,contact.m2m3.height) + max(drc["metal2_to_metal2"],drc["metal3_to_metal3"])
|
||||
|
|
@ -87,10 +88,6 @@ class control_logic(design.design):
|
|||
# Some cells may have pwell/nwell spacing problems too when the wells are different heights.
|
||||
self.cell_gap = max(self.m2_pitch,drc["pwell_to_nwell"])
|
||||
|
||||
# Amount to shift a 90 degree rotated via from center-line path routing to it's offset
|
||||
self.m1m2_via_offset = vector(contact.m1m2.first_layer_height,-0.5*drc["minwidth_metal2"])
|
||||
self.m2m3_via_offset = vector(contact.m2m3.first_layer_height,-0.5*drc["minwidth_metal3"])
|
||||
|
||||
# First RAIL Parameters: gnd, oe, oebar, cs, we, clk_buf, clk_bar
|
||||
self.rail_1_start_x = 0
|
||||
self.num_rails_1 = 8
|
||||
|
|
@ -326,6 +323,7 @@ class control_logic(design.design):
|
|||
x_off += self.inv1.width
|
||||
|
||||
# BUFFER INVERTERS FOR W_EN
|
||||
# FIXME: Can we remove these two invs and size the previous one?
|
||||
self.pre_w_en_bar_offset = vector(x_off, y_off)
|
||||
self.pre_w_en_bar=self.add_inst(name="inv_pre_w_en_bar",
|
||||
mod=self.inv1,
|
||||
|
|
@ -512,11 +510,25 @@ class control_logic(design.design):
|
|||
offset=clk_buf_rail_position,
|
||||
rotate=90)
|
||||
|
||||
# clk_bar
|
||||
self.connect_rail_from_left_m2m3(self.clk_bar,"Z","clk_bar")
|
||||
# clk_bar, routes over the clock buffer vdd rail
|
||||
clk_pin = self.clk_bar.get_pin("Z")
|
||||
vdd_pin = self.clk_bar.get_pin("vdd")
|
||||
# move the output pin up to metal2
|
||||
self.add_via_center(layers=("metal1","via1","metal2"),
|
||||
offset=self.clk_bar.get_pin("Z").rc(),
|
||||
offset=clk_pin.rc(),
|
||||
rotate=90)
|
||||
# route to a position over the supply rail
|
||||
in_pos = vector(clk_pin.rx(), vdd_pin.cy())
|
||||
self.add_path("metal2",[clk_pin.rc(), in_pos])
|
||||
# connect that position to the control bus
|
||||
rail_pos = vector(self.rail_1_x_offsets["clk_bar"], in_pos.y)
|
||||
self.add_wire(("metal3","via2","metal2"),[in_pos, rail_pos])
|
||||
self.add_via_center(layers=("metal2","via2","metal3"),
|
||||
offset=in_pos,
|
||||
rotate=90)
|
||||
self.add_via_center(layers=("metal2","via2","metal3"),
|
||||
offset=rail_pos,
|
||||
rotate=90)
|
||||
|
||||
# clk_buf to msf control flops
|
||||
msf_clk_pos = self.msf_inst.get_pin("clk").bc()
|
||||
|
|
@ -8,7 +8,8 @@ from globals import OPTS
|
|||
|
||||
class delay_chain(design.design):
|
||||
"""
|
||||
Generate a logic effort based delay chain.
|
||||
Generate a delay chain with the given number of stages and fanout.
|
||||
This automatically adds an extra inverter with no load on the input.
|
||||
Input is a list contains the electrical effort of each stage.
|
||||
"""
|
||||
|
||||
|
|
@ -250,9 +250,9 @@ class hierarchical_predecode(design.design):
|
|||
index_lst= nand_input_line_combination[k]
|
||||
|
||||
if self.number_of_inputs == 2:
|
||||
gate_lst = ["B","A"]
|
||||
gate_lst = ["A","B"]
|
||||
else:
|
||||
gate_lst = ["C","B","A"]
|
||||
gate_lst = ["A","B","C"]
|
||||
|
||||
# this will connect pins A,B or A,B,C
|
||||
for rail_pin,gate_pin in zip(index_lst,gate_lst):
|
||||
|
|
@ -27,10 +27,10 @@ class hierarchical_predecode2x4(hierarchical_predecode):
|
|||
self.create_rails()
|
||||
self.add_input_inverters()
|
||||
self.add_output_inverters()
|
||||
connections =[["in[0]", "in[1]", "Z[3]", "vdd", "gnd"],
|
||||
["inbar[0]", "in[1]", "Z[2]", "vdd", "gnd"],
|
||||
connections =[["inbar[0]", "inbar[1]", "Z[0]", "vdd", "gnd"],
|
||||
["in[0]", "inbar[1]", "Z[1]", "vdd", "gnd"],
|
||||
["inbar[0]", "inbar[1]", "Z[0]", "vdd", "gnd"]]
|
||||
["inbar[0]", "in[1]", "Z[2]", "vdd", "gnd"],
|
||||
["in[0]", "in[1]", "Z[3]", "vdd", "gnd"]]
|
||||
self.add_nand(connections)
|
||||
self.route()
|
||||
|
||||
|
|
@ -29,13 +29,13 @@ class precharge(pgate.pgate):
|
|||
self.DRC_LVS()
|
||||
|
||||
def add_pins(self):
|
||||
self.add_pin_list(["bl", "br", "clk", "vdd"])
|
||||
self.add_pin_list(["bl", "br", "en", "vdd"])
|
||||
|
||||
def create_layout(self):
|
||||
self.create_ptx()
|
||||
self.add_ptx()
|
||||
self.connect_poly()
|
||||
self.add_pclk()
|
||||
self.add_en()
|
||||
self.add_nwell_and_contact()
|
||||
self.add_vdd_rail()
|
||||
self.add_bitlines()
|
||||
|
|
@ -74,7 +74,7 @@ class precharge(pgate.pgate):
|
|||
self.lower_pmos_inst=self.add_inst(name="lower_pmos",
|
||||
mod=self.pmos,
|
||||
offset=self.lower_pmos_position)
|
||||
self.connect_inst(["bl", "clk", "BR", "vdd"])
|
||||
self.connect_inst(["bl", "en", "BR", "vdd"])
|
||||
|
||||
# adds the upper pmos(s) to layout
|
||||
ydiff = self.pmos.height + 2*self.m1_space + contact.poly.width
|
||||
|
|
@ -82,13 +82,13 @@ class precharge(pgate.pgate):
|
|||
self.upper_pmos1_inst=self.add_inst(name="upper_pmos1",
|
||||
mod=self.pmos,
|
||||
offset=self.upper_pmos1_pos)
|
||||
self.connect_inst(["bl", "clk", "vdd", "vdd"])
|
||||
self.connect_inst(["bl", "en", "vdd", "vdd"])
|
||||
|
||||
upper_pmos2_pos = self.upper_pmos1_pos + self.overlap_offset
|
||||
self.upper_pmos2_inst=self.add_inst(name="upper_pmos2",
|
||||
mod=self.pmos,
|
||||
offset=upper_pmos2_pos)
|
||||
self.connect_inst(["br", "clk", "vdd", "vdd"])
|
||||
self.connect_inst(["br", "en", "vdd", "vdd"])
|
||||
|
||||
def connect_poly(self):
|
||||
"""Connects the upper and lower pmos together"""
|
||||
|
|
@ -109,16 +109,16 @@ class precharge(pgate.pgate):
|
|||
width=xlength,
|
||||
height=self.poly_width)
|
||||
|
||||
def add_pclk(self):
|
||||
"""Adds the pclk input rail, pclk contact/vias, and connects to the pmos"""
|
||||
# adds the pclk contact to connect the gates to the pclk rail on metal1
|
||||
def add_en(self):
|
||||
"""Adds the en input rail, en contact/vias, and connects to the pmos"""
|
||||
# adds the en contact to connect the gates to the en rail on metal1
|
||||
offset = self.lower_pmos_inst.get_pin("G").ul() + vector(0,0.5*self.poly_space)
|
||||
self.add_contact_center(layers=("poly", "contact", "metal1"),
|
||||
offset=offset,
|
||||
rotate=90)
|
||||
|
||||
# adds the pclk rail on metal1
|
||||
self.add_layout_pin_center_segment(text="clk",
|
||||
# adds the en rail on metal1
|
||||
self.add_layout_pin_center_segment(text="en",
|
||||
layer="metal1",
|
||||
start=offset.scale(0,1),
|
||||
end=offset.scale(0,1)+vector(self.width,0))
|
||||
|
|
@ -46,7 +46,7 @@ class precharge_array(design.design):
|
|||
|
||||
self.add_layout_pin(text="en",
|
||||
layer="metal1",
|
||||
offset=self.pc_cell.get_pin("clk").ll(),
|
||||
offset=self.pc_cell.get_pin("en").ll(),
|
||||
width=self.width,
|
||||
height=drc["minwidth_metal1"])
|
||||
|
||||
|
|
@ -10,12 +10,12 @@ from globals import OPTS
|
|||
|
||||
class replica_bitline(design.design):
|
||||
"""
|
||||
Generate a module that simulate the delay of control logic
|
||||
and bit line charging.
|
||||
Used for memory timing control
|
||||
Generate a module that simulates the delay of control logic
|
||||
and bit line charging. Stages is the depth of the FO4 delay
|
||||
line and rows is the height of the replica bit loads.
|
||||
"""
|
||||
|
||||
def __init__(self, rows, name="replica_bitline"):
|
||||
def __init__(self, FO4_stages, bitcell_loads, name="replica_bitline"):
|
||||
design.design.__init__(self, name)
|
||||
|
||||
g = reload(__import__(OPTS.delay_chain))
|
||||
|
|
@ -29,7 +29,8 @@ class replica_bitline(design.design):
|
|||
|
||||
for pin in ["en", "out", "vdd", "gnd"]:
|
||||
self.add_pin(pin)
|
||||
self.rows = rows
|
||||
self.bitcell_loads = bitcell_loads
|
||||
self.FO4_stages = FO4_stages
|
||||
|
||||
self.create_modules()
|
||||
self.calculate_module_offsets()
|
||||
|
|
@ -78,10 +79,11 @@ class replica_bitline(design.design):
|
|||
self.add_mod(self.bitcell)
|
||||
|
||||
# This is the replica bitline load column that is the height of our array
|
||||
self.rbl = bitcell_array(name="bitline_load", cols=1, rows=self.rows)
|
||||
self.rbl = bitcell_array(name="bitline_load", cols=1, rows=self.bitcell_loads)
|
||||
self.add_mod(self.rbl)
|
||||
|
||||
self.delay_chain = self.mod_delay_chain([1, 1, 1])
|
||||
|
||||
# FIXME: The FO and depth of this should be tuned
|
||||
self.delay_chain = self.mod_delay_chain([4]*self.FO4_stages)
|
||||
self.add_mod(self.delay_chain)
|
||||
|
||||
self.inv = pinv()
|
||||
|
|
@ -123,7 +125,7 @@ class replica_bitline(design.design):
|
|||
self.rbl_inst=self.add_inst(name="load",
|
||||
mod=self.rbl,
|
||||
offset=self.rbl_offset)
|
||||
self.connect_inst(["bl[0]", "br[0]"] + ["gnd"]*self.rows + ["vdd", "gnd"])
|
||||
self.connect_inst(["bl[0]", "br[0]"] + ["gnd"]*self.bitcell_loads + ["vdd", "gnd"])
|
||||
|
||||
|
||||
|
||||
|
|
@ -239,56 +241,61 @@ class replica_bitline(design.design):
|
|||
def route_gnd(self):
|
||||
""" Route all signals connected to gnd """
|
||||
|
||||
# Add a rail in M1 from bottom to two along delay chain
|
||||
gnd_start = self.rbl_inv_inst.get_pin("gnd").ll() - self.offset_fix
|
||||
gnd_start = self.rbl_inv_inst.get_pin("gnd").bc()
|
||||
gnd_end = vector(gnd_start.x, self.rbl_inst.uy()+2*self.m2_pitch)
|
||||
|
||||
# It is the height of the entire RBL and bitcell
|
||||
self.add_rect(layer="metal2",
|
||||
offset=gnd_start,
|
||||
width=self.m2_width,
|
||||
height=self.rbl.height+self.bitcell.height+self.inv.width+self.m2_pitch)
|
||||
self.add_layout_pin(text="gnd",
|
||||
layer="metal1",
|
||||
offset=gnd_start.scale(1,0),
|
||||
width=self.m2_width,
|
||||
height=2*self.inv.width)
|
||||
# Add a rail in M1 from bottom of delay chain to two above the RBL
|
||||
# This prevents DRC errors with vias for the WL
|
||||
dc_top = self.dc_inst.ur()
|
||||
self.add_segment_center(layer="metal1",
|
||||
start=vector(gnd_start.x, dc_top.y),
|
||||
end=gnd_end)
|
||||
|
||||
# Add a rail in M2 from RBL inverter to two above the RBL
|
||||
self.add_segment_center(layer="metal2",
|
||||
start=gnd_start,
|
||||
end=gnd_end)
|
||||
|
||||
# Add pin from bottom to RBL inverter
|
||||
self.add_layout_pin_center_segment(text="gnd",
|
||||
layer="metal1",
|
||||
start=gnd_start.scale(1,0),
|
||||
end=gnd_start)
|
||||
|
||||
# Connect the WL pins directly to gnd
|
||||
for row in range(self.rows):
|
||||
gnd_pin = self.get_pin("gnd").rc()
|
||||
for row in range(self.bitcell_loads):
|
||||
wl = "wl[{}]".format(row)
|
||||
pin = self.rbl_inst.get_pin(wl)
|
||||
offset = vector(gnd_start.x,pin.by())
|
||||
self.add_rect(layer="metal1",
|
||||
offset=offset,
|
||||
width=self.rbl_offset.x-gnd_start.x,
|
||||
height=self.m1_width)
|
||||
self.add_via(layers=("metal1", "via1", "metal2"),
|
||||
offset=offset)
|
||||
start = vector(gnd_pin.x,pin.cy())
|
||||
self.add_segment_center(layer="metal1",
|
||||
start=start,
|
||||
end=pin.lc())
|
||||
self.add_via_center(layers=("metal1", "via1", "metal2"),
|
||||
offset=start)
|
||||
|
||||
# Add via for the delay chain
|
||||
offset = self.delay_chain_offset - vector(0.5*self.m1_width,0) - self.offset_fix
|
||||
self.add_via(layers=("metal1", "via1", "metal2"),
|
||||
offset=offset)
|
||||
offset = self.dc_inst.get_pins("gnd")[0].bc() + vector(0.5*contact.m1m2.width,0.5*contact.m1m2.height)
|
||||
self.add_via_center(layers=("metal1", "via1", "metal2"),
|
||||
offset=offset)
|
||||
|
||||
# Add via for the inverter
|
||||
offset = self.rbl_inv_offset - vector(0.5*self.m1_width,contact.m1m2.height) - self.offset_fix
|
||||
self.add_via(layers=("metal1", "via1", "metal2"),
|
||||
offset=offset)
|
||||
offset = self.rbl_inv_inst.get_pin("gnd").bc() - vector(0,0.5*contact.m1m2.height)
|
||||
self.add_via_center(layers=("metal1", "via1", "metal2"),
|
||||
offset=offset)
|
||||
|
||||
# Connect the bitcell gnd pin to the rail
|
||||
# Connect the bitcell gnd pins to the rail
|
||||
gnd_pins = self.get_pins("gnd")
|
||||
gnd_start = gnd_pins[0].uc()
|
||||
gnd_start = gnd_pins[0].ul()
|
||||
rbl_gnd_pins = self.rbl_inst.get_pins("gnd")
|
||||
# Find the left most rail on M2
|
||||
gnd_pin = None
|
||||
# Add L shapes to each vertical gnd rail
|
||||
for pin in rbl_gnd_pins:
|
||||
if gnd_pin == None or (pin.layer=="metal2" and pin.lx()<gnd_pin.lx()):
|
||||
gnd_pin = pin
|
||||
gnd_end = gnd_pin.uc()
|
||||
# Add a couple midpoints so that the wire will drop a via and then route horizontal on M1
|
||||
gnd_mid1 = gnd_start + vector(0,self.m2_pitch)
|
||||
gnd_mid2 = gnd_end + vector(0,self.m2_pitch)
|
||||
self.add_wire(("metal1","via1","metal2"), [gnd_start, gnd_mid1, gnd_mid2, gnd_end])
|
||||
if pin.layer != "metal2":
|
||||
continue
|
||||
gnd_end = pin.uc()
|
||||
gnd_mid = vector(gnd_end.x, gnd_start.y)
|
||||
self.add_wire(("metal1","via1","metal2"), [gnd_start, gnd_mid, gnd_end])
|
||||
gnd_start = gnd_mid
|
||||
|
||||
|
||||
# Add a second gnd pin to the second delay chain rail. No need for full length.
|
||||
|
|
@ -12,9 +12,10 @@ class single_level_column_mux(design.design):
|
|||
Creates a single columnmux cell.
|
||||
"""
|
||||
|
||||
def __init__(self, name, tx_size):
|
||||
def __init__(self, tx_size):
|
||||
name="single_level_column_mux_{}".format(tx_size)
|
||||
design.design.__init__(self, name)
|
||||
debug.info(2, "create single columnmux cell: {0}".format(name))
|
||||
debug.info(2, "create single column mux cell: {0}".format(name))
|
||||
|
||||
c = reload(__import__(OPTS.bitcell))
|
||||
self.mod_bitcell = getattr(c, OPTS.bitcell)
|
||||
|
|
@ -27,9 +28,9 @@ class single_level_column_mux(design.design):
|
|||
def create_layout(self):
|
||||
|
||||
self.add_ptx()
|
||||
|
||||
self.pin_height = 2*self.m2_width
|
||||
self.width = self.bitcell.width
|
||||
self.height = self.nmos2.uy()
|
||||
self.height = self.nmos2.uy() + self.pin_height
|
||||
self.connect_poly()
|
||||
self.add_gnd_rail()
|
||||
self.add_bitline_pins()
|
||||
|
|
@ -42,26 +43,25 @@ class single_level_column_mux(design.design):
|
|||
bl_pos = vector(self.bitcell.get_pin("BL").lx(), 0)
|
||||
br_pos = vector(self.bitcell.get_pin("BR").lx(), 0)
|
||||
|
||||
pin_height = 2*self.m2_width
|
||||
# bl and br
|
||||
self.add_layout_pin(text="bl",
|
||||
layer="metal2",
|
||||
offset=bl_pos + vector(0,self.height - pin_height),
|
||||
height=pin_height)
|
||||
offset=bl_pos + vector(0,self.height - self.pin_height),
|
||||
height=self.pin_height)
|
||||
self.add_layout_pin(text="br",
|
||||
layer="metal2",
|
||||
offset=br_pos + vector(0,self.height - pin_height),
|
||||
height=pin_height)
|
||||
offset=br_pos + vector(0,self.height - self.pin_height),
|
||||
height=self.pin_height)
|
||||
|
||||
# bl_out and br_out
|
||||
self.add_layout_pin(text="bl_out",
|
||||
layer="metal2",
|
||||
offset=bl_pos,
|
||||
height=pin_height)
|
||||
height=self.pin_height)
|
||||
self.add_layout_pin(text="br_out",
|
||||
layer="metal2",
|
||||
offset=br_pos,
|
||||
height=pin_height)
|
||||
height=self.pin_height)
|
||||
|
||||
|
||||
def add_ptx(self):
|
||||
|
|
@ -40,26 +40,28 @@ class single_level_column_mux_array(design.design):
|
|||
self.setup_layout_constants()
|
||||
self.create_array()
|
||||
self.add_routing()
|
||||
# Find the highest shapes to determine height before adding well
|
||||
highest = self.find_highest_coords()
|
||||
self.height = highest.y
|
||||
self.add_layout_pins()
|
||||
self.add_enclosure(self.mux_inst, "pwell")
|
||||
|
||||
|
||||
|
||||
def add_modules(self):
|
||||
self.mux = single_level_column_mux(name="single_level_column_mux",
|
||||
tx_size=8)
|
||||
# FIXME: Why is this 8x?
|
||||
self.mux = single_level_column_mux(tx_size=8)
|
||||
self.add_mod(self.mux)
|
||||
|
||||
|
||||
def setup_layout_constants(self):
|
||||
self.column_addr_size = num_of_inputs = int(self.words_per_row / 2)
|
||||
self.width = self.columns * self.mux.width
|
||||
|
||||
self.m1_pitch = contact.m1m2.width + max(drc["metal1_to_metal1"],drc["metal2_to_metal2"])
|
||||
# To correct the offset between M1 and M2 via enclosures
|
||||
self.offset_fix = vector(0,0.5*(drc["minwidth_metal2"]-drc["minwidth_metal1"]))
|
||||
# one set of metal1 routes for select signals and a pair to interconnect the mux outputs bl/br
|
||||
# one extra route pitch is to space from the sense amp
|
||||
self.route_height = (self.words_per_row + 3)*self.m1_pitch
|
||||
# mux height plus routing signal height plus well spacing at the top
|
||||
self.height = self.mux.height + self.route_height + drc["pwell_to_nwell"]
|
||||
|
||||
|
||||
|
||||
def create_array(self):
|
||||
|
|
@ -72,28 +74,6 @@ class single_level_column_mux_array(design.design):
|
|||
self.mux_inst.append(self.add_inst(name=name,
|
||||
mod=self.mux,
|
||||
offset=x_off))
|
||||
|
||||
offset = self.mux_inst[-1].get_pin("bl").ll()
|
||||
self.add_layout_pin(text="bl[{}]".format(col_num),
|
||||
layer="metal2",
|
||||
offset=offset,
|
||||
height=self.height-offset.y)
|
||||
|
||||
offset = self.mux_inst[-1].get_pin("br").ll()
|
||||
self.add_layout_pin(text="br[{}]".format(col_num),
|
||||
layer="metal2",
|
||||
offset=offset,
|
||||
height=self.height-offset.y)
|
||||
|
||||
gnd_pins = self.mux_inst[-1].get_pins("gnd")
|
||||
for gnd_pin in gnd_pins:
|
||||
# only do even colums to avoid duplicates
|
||||
offset = gnd_pin.ll()
|
||||
if col_num % 2 == 0:
|
||||
self.add_layout_pin(text="gnd",
|
||||
layer="metal2",
|
||||
offset=offset.scale(1,0),
|
||||
height=self.height)
|
||||
|
||||
self.connect_inst(["bl[{}]".format(col_num),
|
||||
"br[{}]".format(col_num),
|
||||
|
|
@ -102,7 +82,34 @@ class single_level_column_mux_array(design.design):
|
|||
"sel[{}]".format(col_num % self.words_per_row),
|
||||
"gnd"])
|
||||
|
||||
|
||||
|
||||
def add_layout_pins(self):
|
||||
""" Add the pins after we determine the height. """
|
||||
# For every column, add a pass gate
|
||||
for col_num in range(self.columns):
|
||||
mux_inst = self.mux_inst[col_num]
|
||||
offset = mux_inst.get_pin("bl").ll()
|
||||
self.add_layout_pin(text="bl[{}]".format(col_num),
|
||||
layer="metal2",
|
||||
offset=offset,
|
||||
height=self.height-offset.y)
|
||||
|
||||
offset = mux_inst.get_pin("br").ll()
|
||||
self.add_layout_pin(text="br[{}]".format(col_num),
|
||||
layer="metal2",
|
||||
offset=offset,
|
||||
height=self.height-offset.y)
|
||||
|
||||
gnd_pins = mux_inst.get_pins("gnd")
|
||||
for gnd_pin in gnd_pins:
|
||||
# only do even colums to avoid duplicates
|
||||
offset = gnd_pin.ll()
|
||||
if col_num % 2 == 0:
|
||||
self.add_layout_pin(text="gnd",
|
||||
layer="metal2",
|
||||
offset=offset.scale(1,0),
|
||||
height=self.height)
|
||||
|
||||
|
||||
def add_routing(self):
|
||||
self.add_horizontal_input_rail()
|
||||
|
|
@ -14,116 +14,47 @@ import sys,os
|
|||
import datetime
|
||||
import re
|
||||
import importlib
|
||||
import globals
|
||||
from globals import *
|
||||
|
||||
(OPTS, args) = globals.parse_args()
|
||||
(OPTS, args) = parse_args()
|
||||
|
||||
# Check that we are left with a single configuration file as argument.
|
||||
if len(args) != 1:
|
||||
print(USAGE)
|
||||
sys.exit(2)
|
||||
|
||||
def print_time(name, now_time, last_time=None):
|
||||
if last_time:
|
||||
time = round((now_time-last_time).total_seconds(),1)
|
||||
else:
|
||||
time = now_time
|
||||
print("** {0}: {1} seconds".format(name,time))
|
||||
return now_time
|
||||
|
||||
# These depend on arguments, so don't load them until now.
|
||||
import debug
|
||||
|
||||
# required positional args for using openram main exe
|
||||
if len(args) < 1:
|
||||
print(globals.USAGE)
|
||||
sys.exit(2)
|
||||
|
||||
globals.print_banner()
|
||||
init_openram(config_file=args[0], is_unit_test=False)
|
||||
|
||||
globals.init_openram(args[0])
|
||||
# Only print banner here so it's not in unit tests
|
||||
print_banner()
|
||||
|
||||
# Check if all arguments are integers for bits, size, banks
|
||||
if type(OPTS.word_size)!=int:
|
||||
debug.error("{0} is not an integer in config file.".format(OPTS.word_size))
|
||||
if type(OPTS.num_words)!=int:
|
||||
debug.error("{0} is not an integer in config file.".format(OPTS.sram_size))
|
||||
if type(OPTS.num_banks)!=int:
|
||||
debug.error("{0} is not an integer in config file.".format(OPTS.num_banks))
|
||||
# Output info about this run
|
||||
report_status()
|
||||
|
||||
if not OPTS.tech_name:
|
||||
debug.error("Tech name must be specified in config file.")
|
||||
|
||||
word_size = OPTS.word_size
|
||||
num_words = OPTS.num_words
|
||||
num_banks = OPTS.num_banks
|
||||
|
||||
if (OPTS.output_name == ""):
|
||||
OPTS.output_name = "sram_{0}_{1}_{2}_{3}".format(word_size,
|
||||
num_words,
|
||||
num_banks,
|
||||
OPTS.tech_name)
|
||||
|
||||
print("Output files are " + OPTS.output_name + ".(sp|gds|v|lib|lef)")
|
||||
|
||||
print("Technology: {0}".format(OPTS.tech_name))
|
||||
print("Word size: {0}\nWords: {1}\nBanks: {2}".format(word_size,num_words,num_banks))
|
||||
|
||||
# only start importing modules after we have the config file
|
||||
# Start importing design modules after we have the config file
|
||||
import verify
|
||||
import sram
|
||||
|
||||
# Keep track of running stats
|
||||
start_time = datetime.datetime.now()
|
||||
last_time = start_time
|
||||
print_time("Start",datetime.datetime.now())
|
||||
if not OPTS.check_lvsdrc:
|
||||
print("DRC/LVS/PEX checking is disabled.")
|
||||
print_time("Start",start_time)
|
||||
|
||||
# import SRAM test generation
|
||||
s = sram.sram(word_size=word_size,
|
||||
num_words=num_words,
|
||||
num_banks=num_banks,
|
||||
s = sram.sram(word_size=OPTS.word_size,
|
||||
num_words=OPTS.num_words,
|
||||
num_banks=OPTS.num_banks,
|
||||
name=OPTS.output_name)
|
||||
last_time=print_time("SRAM creation", datetime.datetime.now(), last_time)
|
||||
|
||||
# Output the files for the resulting SRAM
|
||||
s.save_output()
|
||||
|
||||
spname = OPTS.output_path + s.name + ".sp"
|
||||
print("SP: Writing to {0}".format(spname))
|
||||
s.sp_write(spname)
|
||||
last_time=print_time("Spice writing", datetime.datetime.now(), last_time)
|
||||
|
||||
# Output the extracted design
|
||||
sram_file = spname
|
||||
if OPTS.use_pex:
|
||||
sram_file = OPTS.output_path + "temp_pex.sp"
|
||||
verify.run_pex(s.name, gdsname, spname, output=sram_file)
|
||||
|
||||
# Characterize the design
|
||||
from characterizer import lib
|
||||
libname = OPTS.output_path + s.name + ".lib"
|
||||
print("LIB: Writing to {0}".format(libname))
|
||||
if OPTS.analytical_delay:
|
||||
print("Using analytical delay models (no characterization)")
|
||||
else:
|
||||
if OPTS.spice_name!="":
|
||||
print("Performing simulation-based characterization with {}".format(OPTS.spice_name))
|
||||
if OPTS.trim_netlist:
|
||||
print("Trimming netlist to speed up characterization.")
|
||||
lib.lib(libname,s,sram_file)
|
||||
last_time=print_time("Characterization", datetime.datetime.now(), last_time)
|
||||
|
||||
# Write the layout
|
||||
gdsname = OPTS.output_path + s.name + ".gds"
|
||||
print("GDS: Writing to {0}".format(gdsname))
|
||||
s.gds_write(gdsname)
|
||||
last_time=print_time("GDS", datetime.datetime.now(), last_time)
|
||||
|
||||
# Create a LEF physical model
|
||||
lefname = OPTS.output_path + s.name + ".lef"
|
||||
print("LEF: Writing to {0}".format(lefname))
|
||||
s.lef_write(lefname)
|
||||
last_time=print_time("LEF", datetime.datetime.now(), last_time)
|
||||
|
||||
# Write a verilog model
|
||||
vname = OPTS.output_path + s.name + ".v"
|
||||
print("Verilog: Writing to {0}".format(vname))
|
||||
s.verilog_write(vname)
|
||||
last_time=print_time("Verilog", datetime.datetime.now(), last_time)
|
||||
|
||||
globals.end_openram()
|
||||
# Delete temp files etc.
|
||||
end_openram()
|
||||
print_time("End",datetime.datetime.now(), start_time)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -39,9 +39,20 @@ class options(optparse.Values):
|
|||
# Define the output file paths
|
||||
output_path = "."
|
||||
# Define the output file base name
|
||||
output_name = "sram"
|
||||
output_name = ""
|
||||
# Use analytical delay models by default rather than (slow) characterization
|
||||
analytical_delay = True
|
||||
# Purge the temp directory after a successful run (doesn't purge on errors, anyhow)
|
||||
purge_temp = True
|
||||
|
||||
# These are the configuration parameters
|
||||
rw_ports = 1
|
||||
r_ports = 0
|
||||
# These will get initialized by the the file
|
||||
supply_voltages = ""
|
||||
temperatures = ""
|
||||
process_corners = ""
|
||||
|
||||
|
||||
# These are the default modules that can be over-riden
|
||||
decoder = "hierarchical_decoder"
|
||||
|
|
|
|||
|
|
@ -63,10 +63,15 @@ class ptx(design.design):
|
|||
|
||||
# self.spice.append("\n.SUBCKT {0} {1}".format(self.name,
|
||||
# " ".join(self.pins)))
|
||||
self.spice_device="M{{0}} {{1}} {0} m={1} w={2}u l={3}u".format(spice[self.tx_type],
|
||||
self.mults,
|
||||
self.tx_width,
|
||||
drc["minwidth_poly"])
|
||||
# Just make a guess since these will actually be decided in the layout later.
|
||||
area_sd = 2.5*drc["minwidth_poly"]*self.tx_width
|
||||
perimeter_sd = 2*drc["minwidth_poly"] + 2*self.tx_width
|
||||
self.spice_device="M{{0}} {{1}} {0} m={1} w={2}u l={3}u pd={4}u ps={4}u as={5}p ad={5}p".format(spice[self.tx_type],
|
||||
self.mults,
|
||||
self.tx_width,
|
||||
drc["minwidth_poly"],
|
||||
perimeter_sd,
|
||||
area_sd)
|
||||
self.spice.append("\n* ptx " + self.spice_device)
|
||||
# self.spice.append(".ENDS {0}".format(self.name))
|
||||
|
||||
|
|
@ -8,7 +8,7 @@ from bank import bank
|
|||
import datetime
|
||||
import getpass
|
||||
from vector import vector
|
||||
from globals import OPTS
|
||||
from globals import OPTS, print_time
|
||||
|
||||
|
||||
class sram(design.design):
|
||||
|
|
@ -45,6 +45,7 @@ class sram(design.design):
|
|||
|
||||
debug.info(2, "create sram of size {0} with {1} num of words".format(self.word_size,
|
||||
self.num_words))
|
||||
start_time = datetime.datetime.now()
|
||||
|
||||
design.design.__init__(self, name)
|
||||
|
||||
|
|
@ -72,7 +73,11 @@ class sram(design.design):
|
|||
self.width = sizes[0]
|
||||
self.height = sizes[1]
|
||||
|
||||
self.DRC_LVS()
|
||||
self.DRC_LVS(final_verification=True)
|
||||
|
||||
if not OPTS.is_unit_test:
|
||||
print_time("SRAM creation", datetime.datetime.now(), start_time)
|
||||
|
||||
|
||||
def compute_sizes(self):
|
||||
""" Computes the organization of the memory using bitcell size by trying to make it square."""
|
||||
|
|
@ -650,7 +655,7 @@ class sram(design.design):
|
|||
# Connect the output bar to select 0
|
||||
msb_out_pin = self.msb_address_inst.get_pin("dout_bar[0]")
|
||||
msb_out_pos = msb_out_pin.rc()
|
||||
out_extend_right_pos = msb_out_pos + vector(self.m2_pitch,0)
|
||||
out_extend_right_pos = msb_out_pos + vector(2*self.m2_pitch,0)
|
||||
out_extend_up_pos = out_extend_right_pos + vector(0,self.m2_width)
|
||||
rail_pos = vector(self.vert_control_bus_positions["bank_sel[0]"].x,out_extend_up_pos.y)
|
||||
self.add_path("metal2",[msb_out_pos,out_extend_right_pos,out_extend_up_pos])
|
||||
|
|
@ -660,7 +665,7 @@ class sram(design.design):
|
|||
# Connect the output to select 1
|
||||
msb_out_pin = self.msb_address_inst.get_pin("dout[0]")
|
||||
msb_out_pos = msb_out_pin.rc()
|
||||
out_extend_right_pos = msb_out_pos + vector(self.m2_pitch,0)
|
||||
out_extend_right_pos = msb_out_pos + vector(2*self.m2_pitch,0)
|
||||
out_extend_down_pos = out_extend_right_pos - vector(0,2*self.m1_pitch)
|
||||
rail_pos = vector(self.vert_control_bus_positions["bank_sel[1]"].x,out_extend_down_pos.y)
|
||||
self.add_path("metal2",[msb_out_pos,out_extend_right_pos,out_extend_down_pos])
|
||||
|
|
@ -989,7 +994,13 @@ class sram(design.design):
|
|||
############################################################
|
||||
sp = open(sp_name, 'w')
|
||||
|
||||
sp.write("**************************************************\n")
|
||||
sp.write("* OpenRAM generated memory.\n")
|
||||
sp.write("* Words: {}\n".format(self.num_words))
|
||||
sp.write("* Data bits: {}\n".format(self.word_size))
|
||||
sp.write("* Banks: {}\n".format(self.num_banks))
|
||||
sp.write("* Column mux: {}:1\n".format(self.words_per_row))
|
||||
sp.write("**************************************************\n")
|
||||
# This causes unit test mismatch
|
||||
# sp.write("* Created: {0}\n".format(datetime.datetime.now()))
|
||||
# sp.write("* User: {0}\n".format(getpass.getuser()))
|
||||
|
|
@ -1007,3 +1018,59 @@ class sram(design.design):
|
|||
def analytical_power(self,slew,load):
|
||||
""" Just a test function for the power."""
|
||||
return self.bank.analytical_power(slew,load)
|
||||
|
||||
def save_output(self):
|
||||
""" Save all the output files while reporting time to do it as well. """
|
||||
|
||||
# Save the spice file
|
||||
start_time = datetime.datetime.now()
|
||||
spname = OPTS.output_path + self.name + ".sp"
|
||||
print("SP: Writing to {0}".format(spname))
|
||||
self.sp_write(spname)
|
||||
print_time("Spice writing", datetime.datetime.now(), start_time)
|
||||
|
||||
# Save the extracted spice file
|
||||
if OPTS.use_pex:
|
||||
start_time = datetime.datetime.now()
|
||||
# Output the extracted design if requested
|
||||
sp_file = OPTS.output_path + "temp_pex.sp"
|
||||
verify.run_pex(self.name, gdsname, spname, output=sp_file)
|
||||
print_time("Extraction", datetime.datetime.now(), start_time)
|
||||
else:
|
||||
# Use generated spice file for characterization
|
||||
sp_file = spname
|
||||
|
||||
# Characterize the design
|
||||
start_time = datetime.datetime.now()
|
||||
from characterizer import lib
|
||||
print("LIB: Characterizing... ")
|
||||
if OPTS.analytical_delay:
|
||||
print("Using analytical delay models (no characterization)")
|
||||
else:
|
||||
if OPTS.spice_name!="":
|
||||
print("Performing simulation-based characterization with {}".format(OPTS.spice_name))
|
||||
if OPTS.trim_netlist:
|
||||
print("Trimming netlist to speed up characterization.")
|
||||
lib.lib(out_dir=OPTS.output_path, sram=self, sp_file=sp_file)
|
||||
print_time("Characterization", datetime.datetime.now(), start_time)
|
||||
|
||||
# Write the layout
|
||||
start_time = datetime.datetime.now()
|
||||
gdsname = OPTS.output_path + self.name + ".gds"
|
||||
print("GDS: Writing to {0}".format(gdsname))
|
||||
self.gds_write(gdsname)
|
||||
print_time("GDS", datetime.datetime.now(), start_time)
|
||||
|
||||
# Create a LEF physical model
|
||||
start_time = datetime.datetime.now()
|
||||
lefname = OPTS.output_path + self.name + ".lef"
|
||||
print("LEF: Writing to {0}".format(lefname))
|
||||
self.lef_write(lefname)
|
||||
print_time("LEF", datetime.datetime.now(), start_time)
|
||||
|
||||
# Write a verilog model
|
||||
start_time = datetime.datetime.now()
|
||||
vname = OPTS.output_path + self.name + ".v"
|
||||
print("Verilog: Writing to {0}".format(vname))
|
||||
self.verilog_write(vname)
|
||||
print_time("Verilog", datetime.datetime.now(), start_time)
|
||||
|
|
|
|||
|
|
@ -32,6 +32,10 @@ class hierarchical_decoder_test(openram_test):
|
|||
# a = hierarchical_decoder.hierarchical_decoder(rows=8)
|
||||
# self.local_check(a)
|
||||
|
||||
debug.info(1, "Testing 16 row sample for hierarchical_decoder")
|
||||
a = hierarchical_decoder.hierarchical_decoder(rows=16)
|
||||
self.local_check(a)
|
||||
|
||||
debug.info(1, "Testing 32 row sample for hierarchical_decoder")
|
||||
a = hierarchical_decoder.hierarchical_decoder(rows=32)
|
||||
self.local_check(a)
|
||||
|
|
|
|||
|
|
@ -21,10 +21,18 @@ class replica_bitline_test(openram_test):
|
|||
|
||||
import replica_bitline
|
||||
|
||||
debug.info(2, "Testing RBL")
|
||||
a = replica_bitline.replica_bitline(13)
|
||||
stages=4
|
||||
rows=13
|
||||
debug.info(2, "Testing RBL with {0} FO4 stages, {1} rows".format(stages,rows))
|
||||
a = replica_bitline.replica_bitline(stages,rows)
|
||||
self.local_check(a)
|
||||
|
||||
stages=8
|
||||
rows=100
|
||||
debug.info(2, "Testing RBL with {0} FO4 stages, {1} rows".format(stages,rows))
|
||||
a = replica_bitline.replica_bitline(stages,rows)
|
||||
self.local_check(a)
|
||||
|
||||
OPTS.check_lvsdrc = True
|
||||
globals.end_openram()
|
||||
|
||||
|
|
|
|||
|
|
@ -23,19 +23,19 @@ class sram_1bank_test(openram_test):
|
|||
|
||||
debug.info(1, "Single bank, no column mux with control logic")
|
||||
a = sram.sram(word_size=4, num_words=16, num_banks=1, name="sram1")
|
||||
self.local_check(a)
|
||||
self.local_check(a, final_verification=True)
|
||||
|
||||
debug.info(1, "Single bank two way column mux with control logic")
|
||||
a = sram.sram(word_size=4, num_words=32, num_banks=1, name="sram2")
|
||||
self.local_check(a)
|
||||
self.local_check(a, final_verification=True)
|
||||
|
||||
debug.info(1, "Single bank, four way column mux with control logic")
|
||||
a = sram.sram(word_size=4, num_words=64, num_banks=1, name="sram3")
|
||||
self.local_check(a)
|
||||
self.local_check(a, final_verification=True)
|
||||
|
||||
# debug.info(1, "Single bank, eight way column mux with control logic")
|
||||
# a = sram.sram(word_size=2, num_words=128, num_banks=1, name="sram4")
|
||||
# self.local_check(a)
|
||||
# self.local_check(a, final_verification=True)
|
||||
|
||||
OPTS.check_lvsdrc = True
|
||||
globals.end_openram()
|
||||
|
|
|
|||
|
|
@ -23,19 +23,19 @@ class sram_2bank_test(openram_test):
|
|||
|
||||
debug.info(1, "Two bank, no column mux with control logic")
|
||||
a = sram.sram(word_size=16, num_words=32, num_banks=2, name="sram1")
|
||||
self.local_check(a)
|
||||
self.local_check(a, final_verification=True)
|
||||
|
||||
debug.info(1, "Two bank two way column mux with control logic")
|
||||
a = sram.sram(word_size=16, num_words=64, num_banks=2, name="sram2")
|
||||
self.local_check(a)
|
||||
self.local_check(a, final_verification=True)
|
||||
|
||||
debug.info(1, "Two bank, four way column mux with control logic")
|
||||
a = sram.sram(word_size=16, num_words=128, num_banks=2, name="sram3")
|
||||
self.local_check(a)
|
||||
self.local_check(a, final_verification=True)
|
||||
|
||||
# debug.info(1, "Two bank, eight way column mux with control logic")
|
||||
# a = sram.sram(word_size=2, num_words=256 num_banks=2, name="sram4")
|
||||
# self.local_check(a)
|
||||
# self.local_check(a, final_verification=True)
|
||||
|
||||
OPTS.check_lvsdrc = True
|
||||
globals.end_openram()
|
||||
|
|
|
|||
|
|
@ -23,19 +23,19 @@ class sram_4bank_test(openram_test):
|
|||
|
||||
debug.info(1, "Four bank, no column mux with control logic")
|
||||
a = sram.sram(word_size=16, num_words=64, num_banks=4, name="sram1")
|
||||
self.local_check(a)
|
||||
self.local_check(a, final_verification=True)
|
||||
|
||||
debug.info(1, "Four bank two way column mux with control logic")
|
||||
a = sram.sram(word_size=16, num_words=128, num_banks=4, name="sram2")
|
||||
self.local_check(a)
|
||||
self.local_check(a, final_verification=True)
|
||||
|
||||
debug.info(1, "Four bank, four way column mux with control logic")
|
||||
a = sram.sram(word_size=16, num_words=256, num_banks=4, name="sram3")
|
||||
self.local_check(a)
|
||||
self.local_check(a, final_verification=True)
|
||||
|
||||
# debug.info(1, "Four bank, eight way column mux with control logic")
|
||||
# a = sram.sram(word_size=2, num_words=256, num_banks=4, name="sram4")
|
||||
# self.local_check(a)
|
||||
# self.local_check(a, final_verification=True)
|
||||
|
||||
OPTS.check_lvsdrc = True
|
||||
globals.end_openram()
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ class timing_sram_test(openram_test):
|
|||
debug.error("Could not find {} simulator.".format(OPTS.spice_name),-1)
|
||||
|
||||
import sram
|
||||
|
||||
import tech
|
||||
debug.info(1, "Testing timing for sample 1bit, 16words SRAM with 1 bank")
|
||||
s = sram.sram(word_size=OPTS.word_size,
|
||||
num_words=OPTS.num_words,
|
||||
|
|
@ -43,31 +43,33 @@ class timing_sram_test(openram_test):
|
|||
probe_data = s.word_size - 1
|
||||
debug.info(1, "Probe address {0} probe data {1}".format(probe_address, probe_data))
|
||||
|
||||
d = delay.delay(s,tempspice)
|
||||
corner = (OPTS.process_corners[0], OPTS.supply_voltages[0], OPTS.temperatures[0])
|
||||
d = delay.delay(s,tempspice,corner)
|
||||
import tech
|
||||
loads = [tech.spice["FF_in_cap"]*4]
|
||||
loads = [tech.spice["msflop_in_cap"]*4]
|
||||
slews = [tech.spice["rise_time"]*2]
|
||||
data = d.analyze(probe_address, probe_data,slews,loads)
|
||||
#print data
|
||||
if OPTS.tech_name == "freepdk45":
|
||||
golden_data = {'read1_power': 0.0296933,
|
||||
'read0_power': 0.029897899999999998,
|
||||
'write0_power': 0.0258029,
|
||||
'delay1': [0.049100700000000004],
|
||||
'delay0': [0.13766139999999996],
|
||||
'min_period': 0.322,
|
||||
'write1_power': 0.0260398,
|
||||
'slew0': [0.0265264],
|
||||
'slew1': [0.0195507]}
|
||||
golden_data = {'read1_power': 0.0356004,
|
||||
'read0_power': 0.0364339,
|
||||
'write0_power': 0.0262249,
|
||||
'delay1': [0.0572987],
|
||||
'delay0': [0.0705677],
|
||||
'min_period': 0.41,
|
||||
'write1_power': 0.038824700000000004,
|
||||
'slew0': [0.028478],
|
||||
'slew1': [0.0190058]}
|
||||
elif OPTS.tech_name == "scn3me_subm":
|
||||
golden_data = {'read1_power': 4.443,
|
||||
'read0_power': 4.4712,
|
||||
'write0_power': 3.0032,
|
||||
'delay1': [0.8596608],
|
||||
'delay0': [1.9534000000000002],
|
||||
'min_period': 5.625,
|
||||
'write1_power': 2.8086,
|
||||
'slew0': [1.2982],
|
||||
'slew1': [0.9909933]}
|
||||
golden_data = {'read1_power': 10.3442,
|
||||
'read0_power': 10.5159,
|
||||
'write0_power': 6.9292,
|
||||
'delay1': [0.6536728],
|
||||
'delay0': [0.9019465999999999],
|
||||
'min_period': 4.531,
|
||||
'write1_power': 11.3108,
|
||||
'slew0': [0.8320245],
|
||||
'slew1': [0.5897582]}
|
||||
else:
|
||||
self.assertTrue(False) # other techs fail
|
||||
# Check if no too many or too few results
|
||||
|
|
|
|||
|
|
@ -31,19 +31,20 @@ class timing_setup_test(openram_test):
|
|||
import tech
|
||||
slews = [tech.spice["rise_time"]*2]
|
||||
|
||||
sh = setup_hold.setup_hold()
|
||||
corner = (OPTS.process_corners[0], OPTS.supply_voltages[0], OPTS.temperatures[0])
|
||||
sh = setup_hold.setup_hold(corner)
|
||||
data = sh.analyze(slews,slews)
|
||||
|
||||
#print data
|
||||
if OPTS.tech_name == "freepdk45":
|
||||
golden_data = {'setup_times_LH': [0.014648399999999999],
|
||||
'hold_times_LH': [0.0024414],
|
||||
'hold_times_HL': [-0.0036620999999999997],
|
||||
'setup_times_HL': [0.0085449]}
|
||||
elif OPTS.tech_name == "scn3me_subm":
|
||||
golden_data = {'setup_times_LH': [0.1000977],
|
||||
'hold_times_LH': [0.020751999999999996],
|
||||
'hold_times_HL': [-0.0830078],
|
||||
'setup_times_HL': [0.020751999999999996]}
|
||||
golden_data = {'setup_times_LH': [0.08178709999999999],
|
||||
'hold_times_LH': [0.0024414],
|
||||
'hold_times_HL': [-0.0646973],
|
||||
'setup_times_HL': [0.0390625]}
|
||||
else:
|
||||
self.assertTrue(False) # other techs fail
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ class timing_sram_test(openram_test):
|
|||
debug.error("Could not find {} simulator.".format(OPTS.spice_name),-1)
|
||||
|
||||
import sram
|
||||
|
||||
import tech
|
||||
debug.info(1, "Testing timing for sample 1bit, 16words SRAM with 1 bank")
|
||||
s = sram.sram(word_size=OPTS.word_size,
|
||||
num_words=OPTS.num_words,
|
||||
|
|
@ -41,31 +41,33 @@ class timing_sram_test(openram_test):
|
|||
probe_data = s.word_size - 1
|
||||
debug.info(1, "Probe address {0} probe data {1}".format(probe_address, probe_data))
|
||||
|
||||
d = delay.delay(s,tempspice)
|
||||
corner = (OPTS.process_corners[0], OPTS.supply_voltages[0], OPTS.temperatures[0])
|
||||
d = delay.delay(s,tempspice,corner)
|
||||
import tech
|
||||
loads = [tech.spice["FF_in_cap"]*4]
|
||||
loads = [tech.spice["msflop_in_cap"]*4]
|
||||
slews = [tech.spice["rise_time"]*2]
|
||||
data = d.analyze(probe_address, probe_data,slews,loads)
|
||||
#print data
|
||||
if OPTS.tech_name == "freepdk45":
|
||||
golden_data = {'read1_power': 0.026660760000000002,
|
||||
'read0_power': 0.02711731,
|
||||
'write0_power': 0.02501428,
|
||||
'delay1': [0.04867702],
|
||||
'delay0': [0.1423633],
|
||||
'min_period': 0.332,
|
||||
'write1_power': 0.024162890000000003,
|
||||
'slew0': [0.02733451],
|
||||
'slew1': [0.02121624]}
|
||||
golden_data = {'read1_power': 0.03308298,
|
||||
'read0_power': 0.03866541,
|
||||
'write0_power': 0.02695139,
|
||||
'delay1': [0.05840294000000001],
|
||||
'delay0': [0.40787249999999997],
|
||||
'min_period': 0.781,
|
||||
'write1_power': 0.037257830000000006,
|
||||
'slew0': [0.035826199999999996],
|
||||
'slew1': [0.02059459]}
|
||||
elif OPTS.tech_name == "scn3me_subm":
|
||||
golden_data = {'read1_power': 4.250786000000001,
|
||||
'read0_power': 4.093461,
|
||||
'write0_power': 2.762675,
|
||||
'delay1': [0.920068],
|
||||
'delay0': [2.051821],
|
||||
'min_period': 6.563,
|
||||
'write1_power': 2.4545719999999998,
|
||||
'slew0': [1.342015],
|
||||
'slew1': [1.040868]}
|
||||
golden_data = {'read1_power': 10.31395,
|
||||
'read0_power': 10.0321,
|
||||
'write0_power': 6.072756,
|
||||
'delay1': [1.042564],
|
||||
'delay0': [1.412224],
|
||||
'min_period': 4.688,
|
||||
'write1_power': 10.53758,
|
||||
'slew0': [1.355812],
|
||||
'slew1': [1.03401]}
|
||||
else:
|
||||
self.assertTrue(False) # other techs fail
|
||||
|
||||
|
|
|
|||
|
|
@ -30,19 +30,20 @@ class timing_setup_test(openram_test):
|
|||
import tech
|
||||
slews = [tech.spice["rise_time"]*2]
|
||||
|
||||
sh = setup_hold.setup_hold()
|
||||
corner = (OPTS.process_corners[0], OPTS.supply_voltages[0], OPTS.temperatures[0])
|
||||
sh = setup_hold.setup_hold(corner)
|
||||
data = sh.analyze(slews,slews)
|
||||
|
||||
#print data
|
||||
if OPTS.tech_name == "freepdk45":
|
||||
golden_data = {'setup_times_LH': [0.01464844],
|
||||
'hold_times_LH': [0.0024414059999999997],
|
||||
'hold_times_HL': [-0.003662109],
|
||||
'setup_times_HL': [0.008544922]}
|
||||
elif OPTS.tech_name == "scn3me_subm":
|
||||
golden_data = {'setup_times_LH': [0.1000977],
|
||||
'hold_times_LH': [0.02075195],
|
||||
'hold_times_HL': [-0.08300781],
|
||||
'setup_times_HL': [0.02075195]}
|
||||
golden_data = {'setup_times_LH': [0.1855469],
|
||||
'hold_times_LH': [-0.009765625],
|
||||
'hold_times_HL': [-0.15625],
|
||||
'setup_times_HL': [0.12451169999999999]}
|
||||
else:
|
||||
self.assertTrue(False) # other techs fail
|
||||
|
||||
|
|
|
|||
|
|
@ -43,12 +43,13 @@ class sram_func_test(openram_test):
|
|||
probe_data = s.word_size - 1
|
||||
debug.info(1, "Probe address {0} probe data {1}".format(probe_address, probe_data))
|
||||
|
||||
d = delay.delay(s,tempspice)
|
||||
corner = (OPTS.process_corners[0], OPTS.supply_voltages[0], OPTS.temperatures[0])
|
||||
d = delay.delay(s,tempspice,corner)
|
||||
d.set_probe(probe_address,probe_data)
|
||||
|
||||
# This will exit if it doesn't find a feasible period
|
||||
import tech
|
||||
load = tech.spice["FF_in_cap"]*4
|
||||
load = tech.spice["msflop_in_cap"]*4
|
||||
slew = tech.spice["rise_time"]*2
|
||||
feasible_period = d.find_feasible_period(load,slew)
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ Check the .lib file for an SRAM
|
|||
|
||||
import unittest
|
||||
from testutils import header,openram_test
|
||||
import sys,os
|
||||
import sys,os,re
|
||||
sys.path.append(os.path.join(sys.path[0],".."))
|
||||
import globals
|
||||
from globals import OPTS
|
||||
|
|
@ -22,22 +22,28 @@ class lib_test(openram_test):
|
|||
|
||||
debug.info(1, "Testing timing for sample 2 bit, 16 words SRAM with 1 bank")
|
||||
s = sram.sram(word_size=2,
|
||||
num_words=OPTS.num_words,
|
||||
num_banks=OPTS.num_banks,
|
||||
num_words=16,
|
||||
num_banks=1,
|
||||
name="sram_2_16_1_{0}".format(OPTS.tech_name))
|
||||
OPTS.check_lvsdrc = True
|
||||
|
||||
tempspice = OPTS.openram_temp + "temp.sp"
|
||||
s.sp_write(tempspice)
|
||||
|
||||
filename = s.name + "_analytical.lib"
|
||||
libname = OPTS.openram_temp + filename
|
||||
lib.lib(libname=libname,sram=s,spfile=tempspice,use_model=True)
|
||||
lib.lib(out_dir=OPTS.openram_temp, sram=s, sp_file=tempspice, use_model=True)
|
||||
|
||||
# let's diff the result with a golden model
|
||||
golden = "{0}/golden/{1}".format(os.path.dirname(os.path.realpath(__file__)),filename)
|
||||
self.isapproxdiff(libname,golden,0.15)
|
||||
# get all of the .lib files generated
|
||||
files = os.listdir(OPTS.openram_temp)
|
||||
nametest = re.compile("\.lib$", re.IGNORECASE)
|
||||
lib_files = filter(nametest.search, files)
|
||||
|
||||
# and compare them with the golden model
|
||||
for filename in lib_files:
|
||||
newname = filename.replace(".lib","_analytical.lib")
|
||||
libname = "{0}/{1}".format(OPTS.openram_temp,filename)
|
||||
golden = "{0}/golden/{1}".format(os.path.dirname(os.path.realpath(__file__)),newname)
|
||||
self.isapproxdiff(libname,golden,0.15)
|
||||
|
||||
globals.end_openram()
|
||||
|
||||
# instantiate a copdsay of the class to actually run the test
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ Check the .lib file for an SRAM with pruning
|
|||
|
||||
import unittest
|
||||
from testutils import header,openram_test
|
||||
import sys,os
|
||||
import sys,os,re
|
||||
sys.path.append(os.path.join(sys.path[0],".."))
|
||||
import globals
|
||||
from globals import OPTS
|
||||
|
|
@ -31,21 +31,27 @@ class lib_test(openram_test):
|
|||
|
||||
debug.info(1, "Testing timing for sample 2 bit, 16 words SRAM with 1 bank")
|
||||
s = sram.sram(word_size=2,
|
||||
num_words=OPTS.num_words,
|
||||
num_banks=OPTS.num_banks,
|
||||
num_words=16,
|
||||
num_banks=1,
|
||||
name="sram_2_16_1_{0}".format(OPTS.tech_name))
|
||||
OPTS.check_lvsdrc = True
|
||||
|
||||
tempspice = OPTS.openram_temp + "temp.sp"
|
||||
s.sp_write(tempspice)
|
||||
|
||||
filename = s.name + "_pruned.lib"
|
||||
libname = OPTS.openram_temp + filename
|
||||
lib.lib(libname=libname,sram=s,spfile=tempspice,use_model=False)
|
||||
|
||||
# let's diff the result with a golden model
|
||||
golden = "{0}/golden/{1}".format(os.path.dirname(os.path.realpath(__file__)),filename)
|
||||
self.isapproxdiff(libname,golden,0.30)
|
||||
lib.lib(out_dir=OPTS.openram_temp, sram=s, sp_file=tempspice, use_model=False)
|
||||
|
||||
# get all of the .lib files generated
|
||||
files = os.listdir(OPTS.openram_temp)
|
||||
nametest = re.compile("\.lib$", re.IGNORECASE)
|
||||
lib_files = filter(nametest.search, files)
|
||||
|
||||
# and compare them with the golden model
|
||||
for filename in lib_files:
|
||||
newname = filename.replace(".lib","_pruned.lib")
|
||||
libname = "{0}/{1}".format(OPTS.openram_temp,filename)
|
||||
golden = "{0}/golden/{1}".format(os.path.dirname(os.path.realpath(__file__)),newname)
|
||||
self.isapproxdiff(libname,golden,0.15)
|
||||
|
||||
OPTS.analytical_delay = True
|
||||
reload(characterizer)
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ Check the .lib file for an SRAM
|
|||
|
||||
import unittest
|
||||
from testutils import header,openram_test
|
||||
import sys,os
|
||||
import sys,os,re
|
||||
sys.path.append(os.path.join(sys.path[0],".."))
|
||||
import globals
|
||||
from globals import OPTS
|
||||
|
|
@ -31,21 +31,26 @@ class lib_test(openram_test):
|
|||
|
||||
debug.info(1, "Testing timing for sample 2 bit, 16 words SRAM with 1 bank")
|
||||
s = sram.sram(word_size=2,
|
||||
num_words=OPTS.num_words,
|
||||
num_banks=OPTS.num_banks,
|
||||
num_words=16,
|
||||
num_banks=1,
|
||||
name="sram_2_16_1_{0}".format(OPTS.tech_name))
|
||||
OPTS.check_lvsdrc = True
|
||||
|
||||
tempspice = OPTS.openram_temp + "temp.sp"
|
||||
s.sp_write(tempspice)
|
||||
|
||||
filename = s.name + ".lib"
|
||||
libname = OPTS.openram_temp + filename
|
||||
lib.lib(libname=libname,sram=s,spfile=tempspice,use_model=False)
|
||||
|
||||
# let's diff the result with a golden model
|
||||
golden = "{0}/golden/{1}".format(os.path.dirname(os.path.realpath(__file__)),filename)
|
||||
self.isapproxdiff(libname,golden,0.15)
|
||||
lib.lib(out_dir=OPTS.openram_temp, sram=s, sp_file=tempspice, use_model=False)
|
||||
|
||||
# get all of the .lib files generated
|
||||
files = os.listdir(OPTS.openram_temp)
|
||||
nametest = re.compile("\.lib$", re.IGNORECASE)
|
||||
lib_files = filter(nametest.search, files)
|
||||
|
||||
# and compare them with the golden model
|
||||
for filename in lib_files:
|
||||
libname = "{0}/{1}".format(OPTS.openram_temp,filename)
|
||||
golden = "{0}/golden/{1}".format(os.path.dirname(os.path.realpath(__file__)),filename)
|
||||
self.isapproxdiff(libname,golden,0.15)
|
||||
|
||||
OPTS.analytical_delay = True
|
||||
OPTS.trim_netlist = True
|
||||
|
|
|
|||
|
|
@ -20,8 +20,8 @@ class openram_test(openram_test):
|
|||
|
||||
debug.info(1, "Testing top-level openram.py with 2-bit, 16 word SRAM.")
|
||||
out_file = "testsram"
|
||||
# make a temp directory for output
|
||||
out_path = "/tmp/testsram"
|
||||
# make a temp directory for output
|
||||
out_path = "/tmp/testsram_{0}".format(OPTS.tech_name)
|
||||
|
||||
# make sure we start without the files existing
|
||||
if os.path.exists(out_path):
|
||||
|
|
@ -52,11 +52,16 @@ class openram_test(openram_test):
|
|||
os.system(cmd)
|
||||
|
||||
# assert an error until we actually check a resul
|
||||
for extension in ["gds", "v", "lef", "lib", "sp"]:
|
||||
for extension in ["gds", "v", "lef", "sp"]:
|
||||
filename = "{0}/{1}.{2}".format(out_path,out_file,extension)
|
||||
debug.info(1,"Checking for file: " + filename)
|
||||
self.assertEqual(os.path.exists(filename),True)
|
||||
|
||||
# Make sure there is any .lib file
|
||||
import glob
|
||||
files = glob.glob('{0}/*.lib'.format(out_path))
|
||||
self.assertTrue(len(files)>0)
|
||||
|
||||
# grep any errors from the output
|
||||
output = open("{0}/output.log".format(out_path),"r").read()
|
||||
self.assertEqual(len(re.findall('ERROR',output)),0)
|
||||
|
|
|
|||
|
|
@ -3,5 +3,8 @@ num_words = 16
|
|||
num_banks = 1
|
||||
|
||||
tech_name = "freepdk45"
|
||||
process_corners = ["TT"]
|
||||
supply_voltages = [1.0]
|
||||
temperatures = [25]
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -3,4 +3,7 @@ num_words = 16
|
|||
num_banks = 1
|
||||
|
||||
tech_name = "scn3me_subm"
|
||||
process_corners = ["TT"]
|
||||
supply_voltages = [5.0]
|
||||
temperatures = [25]
|
||||
|
||||
|
|
|
|||
|
|
@ -7,11 +7,11 @@ UNITS
|
|||
END UNITS
|
||||
SITE MacroSite
|
||||
CLASS Core ;
|
||||
SIZE 175.0 by 135.0 ;
|
||||
SIZE 21695.0 by 42337.5 ;
|
||||
END MacroSite
|
||||
MACRO sram_2_16_1_freepdk45
|
||||
CLASS BLOCK ;
|
||||
SIZE 175.0 BY 135.0 ;
|
||||
SIZE 21695.0 BY 42337.5 ;
|
||||
SYMMETRY X Y R90 ;
|
||||
SITE MacroSite ;
|
||||
PIN DATA[0]
|
||||
|
|
@ -606,14 +606,14 @@ MACRO sram_2_16_1_freepdk45
|
|||
RECT 10785.0 10360.0 10420.0 10425.0 ;
|
||||
RECT 11060.0 11122.5 9125.0 11187.5 ;
|
||||
RECT 10785.0 12467.5 8850.0 12532.5 ;
|
||||
RECT 9675.0 8722.5 8292.5 8787.5 ;
|
||||
RECT 9400.0 8937.5 8550.0 9002.5 ;
|
||||
RECT 9125.0 10562.5 8292.5 10627.5 ;
|
||||
RECT 9400.0 10347.5 8550.0 10412.5 ;
|
||||
RECT 9675.0 11412.5 8292.5 11477.5 ;
|
||||
RECT 8850.0 11627.5 8550.0 11692.5 ;
|
||||
RECT 9125.0 13252.5 8292.5 13317.5 ;
|
||||
RECT 8850.0 13037.5 8550.0 13102.5 ;
|
||||
RECT 9675.0 8937.5 8550.0 9002.5 ;
|
||||
RECT 9400.0 8722.5 8292.5 8787.5 ;
|
||||
RECT 9125.0 10347.5 8550.0 10412.5 ;
|
||||
RECT 9400.0 10562.5 8292.5 10627.5 ;
|
||||
RECT 9675.0 11627.5 8550.0 11692.5 ;
|
||||
RECT 8850.0 11412.5 8292.5 11477.5 ;
|
||||
RECT 9125.0 13037.5 8550.0 13102.5 ;
|
||||
RECT 8850.0 13252.5 8292.5 13317.5 ;
|
||||
RECT 7845.0 8937.5 7780.0 9002.5 ;
|
||||
RECT 7845.0 8925.0 7780.0 8990.0 ;
|
||||
RECT 8062.5 8937.5 7812.5 9002.5 ;
|
||||
|
|
@ -894,14 +894,14 @@ MACRO sram_2_16_1_freepdk45
|
|||
RECT 9057.5 11122.5 9192.5 11187.5 ;
|
||||
RECT 10717.5 12467.5 10852.5 12532.5 ;
|
||||
RECT 8782.5 12467.5 8917.5 12532.5 ;
|
||||
RECT 9607.5 8722.5 9742.5 8787.5 ;
|
||||
RECT 9332.5 8937.5 9467.5 9002.5 ;
|
||||
RECT 9057.5 10562.5 9192.5 10627.5 ;
|
||||
RECT 9332.5 10347.5 9467.5 10412.5 ;
|
||||
RECT 9607.5 11412.5 9742.5 11477.5 ;
|
||||
RECT 8782.5 11627.5 8917.5 11692.5 ;
|
||||
RECT 9057.5 13252.5 9192.5 13317.5 ;
|
||||
RECT 8782.5 13037.5 8917.5 13102.5 ;
|
||||
RECT 9607.5 8937.5 9742.5 9002.5 ;
|
||||
RECT 9332.5 8722.5 9467.5 8787.5 ;
|
||||
RECT 9057.5 10347.5 9192.5 10412.5 ;
|
||||
RECT 9332.5 10562.5 9467.5 10627.5 ;
|
||||
RECT 9607.5 11627.5 9742.5 11692.5 ;
|
||||
RECT 8782.5 11412.5 8917.5 11477.5 ;
|
||||
RECT 9057.5 13037.5 9192.5 13102.5 ;
|
||||
RECT 8782.5 13252.5 8917.5 13317.5 ;
|
||||
RECT 7335.0 8925.0 7130.0 8990.0 ;
|
||||
RECT 7335.0 10360.0 7130.0 10425.0 ;
|
||||
RECT 7335.0 11615.0 7130.0 11680.0 ;
|
||||
|
|
@ -925,14 +925,14 @@ MACRO sram_2_16_1_freepdk45
|
|||
RECT 10785.0 15740.0 10420.0 15805.0 ;
|
||||
RECT 11060.0 16502.5 9125.0 16567.5 ;
|
||||
RECT 10785.0 17847.5 8850.0 17912.5 ;
|
||||
RECT 9675.0 14102.5 8292.5 14167.5 ;
|
||||
RECT 9400.0 14317.5 8550.0 14382.5 ;
|
||||
RECT 9125.0 15942.5 8292.5 16007.5 ;
|
||||
RECT 9400.0 15727.5 8550.0 15792.5 ;
|
||||
RECT 9675.0 16792.5 8292.5 16857.5 ;
|
||||
RECT 8850.0 17007.5 8550.0 17072.5 ;
|
||||
RECT 9125.0 18632.5 8292.5 18697.5 ;
|
||||
RECT 8850.0 18417.5 8550.0 18482.5 ;
|
||||
RECT 9675.0 14317.5 8550.0 14382.5 ;
|
||||
RECT 9400.0 14102.5 8292.5 14167.5 ;
|
||||
RECT 9125.0 15727.5 8550.0 15792.5 ;
|
||||
RECT 9400.0 15942.5 8292.5 16007.5 ;
|
||||
RECT 9675.0 17007.5 8550.0 17072.5 ;
|
||||
RECT 8850.0 16792.5 8292.5 16857.5 ;
|
||||
RECT 9125.0 18417.5 8550.0 18482.5 ;
|
||||
RECT 8850.0 18632.5 8292.5 18697.5 ;
|
||||
RECT 7845.0 14317.5 7780.0 14382.5 ;
|
||||
RECT 7845.0 14305.0 7780.0 14370.0 ;
|
||||
RECT 8062.5 14317.5 7812.5 14382.5 ;
|
||||
|
|
@ -1213,14 +1213,14 @@ MACRO sram_2_16_1_freepdk45
|
|||
RECT 9057.5 16502.5 9192.5 16567.5 ;
|
||||
RECT 10717.5 17847.5 10852.5 17912.5 ;
|
||||
RECT 8782.5 17847.5 8917.5 17912.5 ;
|
||||
RECT 9607.5 14102.5 9742.5 14167.5 ;
|
||||
RECT 9332.5 14317.5 9467.5 14382.5 ;
|
||||
RECT 9057.5 15942.5 9192.5 16007.5 ;
|
||||
RECT 9332.5 15727.5 9467.5 15792.5 ;
|
||||
RECT 9607.5 16792.5 9742.5 16857.5 ;
|
||||
RECT 8782.5 17007.5 8917.5 17072.5 ;
|
||||
RECT 9057.5 18632.5 9192.5 18697.5 ;
|
||||
RECT 8782.5 18417.5 8917.5 18482.5 ;
|
||||
RECT 9607.5 14317.5 9742.5 14382.5 ;
|
||||
RECT 9332.5 14102.5 9467.5 14167.5 ;
|
||||
RECT 9057.5 15727.5 9192.5 15792.5 ;
|
||||
RECT 9332.5 15942.5 9467.5 16007.5 ;
|
||||
RECT 9607.5 17007.5 9742.5 17072.5 ;
|
||||
RECT 8782.5 16792.5 8917.5 16857.5 ;
|
||||
RECT 9057.5 18417.5 9192.5 18482.5 ;
|
||||
RECT 8782.5 18632.5 8917.5 18697.5 ;
|
||||
RECT 7335.0 14305.0 7130.0 14370.0 ;
|
||||
RECT 7335.0 15740.0 7130.0 15805.0 ;
|
||||
RECT 7335.0 16995.0 7130.0 17060.0 ;
|
||||
|
|
@ -4165,9 +4165,11 @@ MACRO sram_2_16_1_freepdk45
|
|||
RECT 750.0 30905.0 685.0 30970.0 ;
|
||||
RECT 32.5 30615.0 -32.5 31175.0 ;
|
||||
RECT 1377.5 30615.0 1312.5 31175.0 ;
|
||||
RECT 1380.0 33907.5 935.0 33972.5 ;
|
||||
RECT 1380.0 36317.5 935.0 36382.5 ;
|
||||
RECT 1345.0 36817.5 935.0 36882.5 ;
|
||||
RECT 1377.5 39337.5 1312.5 36955.0 ;
|
||||
RECT 1312.5 33907.5 1025.0 33972.5 ;
|
||||
RECT 1312.5 36317.5 1025.0 36382.5 ;
|
||||
RECT 1377.5 31862.5 935.0 31927.5 ;
|
||||
RECT 935.0 31862.5 230.0 31927.5 ;
|
||||
RECT 20.0 35112.5 935.0 35177.5 ;
|
||||
RECT 20.0 32422.5 935.0 32487.5 ;
|
||||
RECT 2005.0 33435.0 1940.0 34135.0 ;
|
||||
|
|
@ -4208,11 +4210,11 @@ MACRO sram_2_16_1_freepdk45
|
|||
RECT 2330.0 33497.5 2465.0 33562.5 ;
|
||||
RECT 2330.0 33497.5 2465.0 33562.5 ;
|
||||
RECT 2330.0 33307.5 2465.0 33372.5 ;
|
||||
RECT 1312.5 35352.5 1377.5 35417.5 ;
|
||||
RECT 4002.5 35352.5 4067.5 35417.5 ;
|
||||
RECT 1312.5 35255.0 1377.5 35385.0 ;
|
||||
RECT 1345.0 35352.5 4035.0 35417.5 ;
|
||||
RECT 4002.5 35255.0 4067.5 35385.0 ;
|
||||
RECT 1312.5 39272.5 1377.5 39337.5 ;
|
||||
RECT 4002.5 39272.5 4067.5 39337.5 ;
|
||||
RECT 1312.5 39175.0 1377.5 39305.0 ;
|
||||
RECT 1345.0 39272.5 4035.0 39337.5 ;
|
||||
RECT 4002.5 39175.0 4067.5 39305.0 ;
|
||||
RECT 2875.0 34562.5 2690.0 34627.5 ;
|
||||
RECT 4035.0 34562.5 3850.0 34627.5 ;
|
||||
RECT 3917.5 34202.5 4067.5 34267.5 ;
|
||||
|
|
@ -4254,6 +4256,279 @@ MACRO sram_2_16_1_freepdk45
|
|||
RECT 2722.5 34695.0 2657.5 35255.0 ;
|
||||
RECT 4067.5 34695.0 4002.5 35255.0 ;
|
||||
RECT 3340.0 34820.0 3475.0 34885.0 ;
|
||||
RECT 2875.0 35682.5 2690.0 35747.5 ;
|
||||
RECT 4035.0 35682.5 3850.0 35747.5 ;
|
||||
RECT 3917.5 35322.5 4067.5 35387.5 ;
|
||||
RECT 3032.5 35322.5 2657.5 35387.5 ;
|
||||
RECT 3917.5 35512.5 3032.5 35577.5 ;
|
||||
RECT 3032.5 35322.5 2897.5 35387.5 ;
|
||||
RECT 3032.5 35512.5 2897.5 35577.5 ;
|
||||
RECT 3032.5 35512.5 2897.5 35577.5 ;
|
||||
RECT 3032.5 35322.5 2897.5 35387.5 ;
|
||||
RECT 3917.5 35322.5 3782.5 35387.5 ;
|
||||
RECT 3917.5 35512.5 3782.5 35577.5 ;
|
||||
RECT 3917.5 35512.5 3782.5 35577.5 ;
|
||||
RECT 3917.5 35322.5 3782.5 35387.5 ;
|
||||
RECT 2942.5 35682.5 2807.5 35747.5 ;
|
||||
RECT 3917.5 35682.5 3782.5 35747.5 ;
|
||||
RECT 3475.0 35380.0 3340.0 35445.0 ;
|
||||
RECT 3475.0 35380.0 3340.0 35445.0 ;
|
||||
RECT 3440.0 35545.0 3375.0 35610.0 ;
|
||||
RECT 2722.5 35255.0 2657.5 35815.0 ;
|
||||
RECT 4067.5 35255.0 4002.5 35815.0 ;
|
||||
RECT 3340.0 35380.0 3475.0 35445.0 ;
|
||||
RECT 2875.0 36242.5 2690.0 36307.5 ;
|
||||
RECT 4035.0 36242.5 3850.0 36307.5 ;
|
||||
RECT 3917.5 35882.5 4067.5 35947.5 ;
|
||||
RECT 3032.5 35882.5 2657.5 35947.5 ;
|
||||
RECT 3917.5 36072.5 3032.5 36137.5 ;
|
||||
RECT 3032.5 35882.5 2897.5 35947.5 ;
|
||||
RECT 3032.5 36072.5 2897.5 36137.5 ;
|
||||
RECT 3032.5 36072.5 2897.5 36137.5 ;
|
||||
RECT 3032.5 35882.5 2897.5 35947.5 ;
|
||||
RECT 3917.5 35882.5 3782.5 35947.5 ;
|
||||
RECT 3917.5 36072.5 3782.5 36137.5 ;
|
||||
RECT 3917.5 36072.5 3782.5 36137.5 ;
|
||||
RECT 3917.5 35882.5 3782.5 35947.5 ;
|
||||
RECT 2942.5 36242.5 2807.5 36307.5 ;
|
||||
RECT 3917.5 36242.5 3782.5 36307.5 ;
|
||||
RECT 3475.0 35940.0 3340.0 36005.0 ;
|
||||
RECT 3475.0 35940.0 3340.0 36005.0 ;
|
||||
RECT 3440.0 36105.0 3375.0 36170.0 ;
|
||||
RECT 2722.5 35815.0 2657.5 36375.0 ;
|
||||
RECT 4067.5 35815.0 4002.5 36375.0 ;
|
||||
RECT 3340.0 35940.0 3475.0 36005.0 ;
|
||||
RECT 2875.0 36802.5 2690.0 36867.5 ;
|
||||
RECT 4035.0 36802.5 3850.0 36867.5 ;
|
||||
RECT 3917.5 36442.5 4067.5 36507.5 ;
|
||||
RECT 3032.5 36442.5 2657.5 36507.5 ;
|
||||
RECT 3917.5 36632.5 3032.5 36697.5 ;
|
||||
RECT 3032.5 36442.5 2897.5 36507.5 ;
|
||||
RECT 3032.5 36632.5 2897.5 36697.5 ;
|
||||
RECT 3032.5 36632.5 2897.5 36697.5 ;
|
||||
RECT 3032.5 36442.5 2897.5 36507.5 ;
|
||||
RECT 3917.5 36442.5 3782.5 36507.5 ;
|
||||
RECT 3917.5 36632.5 3782.5 36697.5 ;
|
||||
RECT 3917.5 36632.5 3782.5 36697.5 ;
|
||||
RECT 3917.5 36442.5 3782.5 36507.5 ;
|
||||
RECT 2942.5 36802.5 2807.5 36867.5 ;
|
||||
RECT 3917.5 36802.5 3782.5 36867.5 ;
|
||||
RECT 3475.0 36500.0 3340.0 36565.0 ;
|
||||
RECT 3475.0 36500.0 3340.0 36565.0 ;
|
||||
RECT 3440.0 36665.0 3375.0 36730.0 ;
|
||||
RECT 2722.5 36375.0 2657.5 36935.0 ;
|
||||
RECT 4067.5 36375.0 4002.5 36935.0 ;
|
||||
RECT 3340.0 36500.0 3475.0 36565.0 ;
|
||||
RECT 2875.0 37362.5 2690.0 37427.5 ;
|
||||
RECT 4035.0 37362.5 3850.0 37427.5 ;
|
||||
RECT 3917.5 37002.5 4067.5 37067.5 ;
|
||||
RECT 3032.5 37002.5 2657.5 37067.5 ;
|
||||
RECT 3917.5 37192.5 3032.5 37257.5 ;
|
||||
RECT 3032.5 37002.5 2897.5 37067.5 ;
|
||||
RECT 3032.5 37192.5 2897.5 37257.5 ;
|
||||
RECT 3032.5 37192.5 2897.5 37257.5 ;
|
||||
RECT 3032.5 37002.5 2897.5 37067.5 ;
|
||||
RECT 3917.5 37002.5 3782.5 37067.5 ;
|
||||
RECT 3917.5 37192.5 3782.5 37257.5 ;
|
||||
RECT 3917.5 37192.5 3782.5 37257.5 ;
|
||||
RECT 3917.5 37002.5 3782.5 37067.5 ;
|
||||
RECT 2942.5 37362.5 2807.5 37427.5 ;
|
||||
RECT 3917.5 37362.5 3782.5 37427.5 ;
|
||||
RECT 3475.0 37060.0 3340.0 37125.0 ;
|
||||
RECT 3475.0 37060.0 3340.0 37125.0 ;
|
||||
RECT 3440.0 37225.0 3375.0 37290.0 ;
|
||||
RECT 2722.5 36935.0 2657.5 37495.0 ;
|
||||
RECT 4067.5 36935.0 4002.5 37495.0 ;
|
||||
RECT 3340.0 37060.0 3475.0 37125.0 ;
|
||||
RECT 2875.0 37922.5 2690.0 37987.5 ;
|
||||
RECT 4035.0 37922.5 3850.0 37987.5 ;
|
||||
RECT 3917.5 37562.5 4067.5 37627.5 ;
|
||||
RECT 3032.5 37562.5 2657.5 37627.5 ;
|
||||
RECT 3917.5 37752.5 3032.5 37817.5 ;
|
||||
RECT 3032.5 37562.5 2897.5 37627.5 ;
|
||||
RECT 3032.5 37752.5 2897.5 37817.5 ;
|
||||
RECT 3032.5 37752.5 2897.5 37817.5 ;
|
||||
RECT 3032.5 37562.5 2897.5 37627.5 ;
|
||||
RECT 3917.5 37562.5 3782.5 37627.5 ;
|
||||
RECT 3917.5 37752.5 3782.5 37817.5 ;
|
||||
RECT 3917.5 37752.5 3782.5 37817.5 ;
|
||||
RECT 3917.5 37562.5 3782.5 37627.5 ;
|
||||
RECT 2942.5 37922.5 2807.5 37987.5 ;
|
||||
RECT 3917.5 37922.5 3782.5 37987.5 ;
|
||||
RECT 3475.0 37620.0 3340.0 37685.0 ;
|
||||
RECT 3475.0 37620.0 3340.0 37685.0 ;
|
||||
RECT 3440.0 37785.0 3375.0 37850.0 ;
|
||||
RECT 2722.5 37495.0 2657.5 38055.0 ;
|
||||
RECT 4067.5 37495.0 4002.5 38055.0 ;
|
||||
RECT 3340.0 37620.0 3475.0 37685.0 ;
|
||||
RECT 2875.0 38482.5 2690.0 38547.5 ;
|
||||
RECT 4035.0 38482.5 3850.0 38547.5 ;
|
||||
RECT 3917.5 38122.5 4067.5 38187.5 ;
|
||||
RECT 3032.5 38122.5 2657.5 38187.5 ;
|
||||
RECT 3917.5 38312.5 3032.5 38377.5 ;
|
||||
RECT 3032.5 38122.5 2897.5 38187.5 ;
|
||||
RECT 3032.5 38312.5 2897.5 38377.5 ;
|
||||
RECT 3032.5 38312.5 2897.5 38377.5 ;
|
||||
RECT 3032.5 38122.5 2897.5 38187.5 ;
|
||||
RECT 3917.5 38122.5 3782.5 38187.5 ;
|
||||
RECT 3917.5 38312.5 3782.5 38377.5 ;
|
||||
RECT 3917.5 38312.5 3782.5 38377.5 ;
|
||||
RECT 3917.5 38122.5 3782.5 38187.5 ;
|
||||
RECT 2942.5 38482.5 2807.5 38547.5 ;
|
||||
RECT 3917.5 38482.5 3782.5 38547.5 ;
|
||||
RECT 3475.0 38180.0 3340.0 38245.0 ;
|
||||
RECT 3475.0 38180.0 3340.0 38245.0 ;
|
||||
RECT 3440.0 38345.0 3375.0 38410.0 ;
|
||||
RECT 2722.5 38055.0 2657.5 38615.0 ;
|
||||
RECT 4067.5 38055.0 4002.5 38615.0 ;
|
||||
RECT 3340.0 38180.0 3475.0 38245.0 ;
|
||||
RECT 2875.0 39042.5 2690.0 39107.5 ;
|
||||
RECT 4035.0 39042.5 3850.0 39107.5 ;
|
||||
RECT 3917.5 38682.5 4067.5 38747.5 ;
|
||||
RECT 3032.5 38682.5 2657.5 38747.5 ;
|
||||
RECT 3917.5 38872.5 3032.5 38937.5 ;
|
||||
RECT 3032.5 38682.5 2897.5 38747.5 ;
|
||||
RECT 3032.5 38872.5 2897.5 38937.5 ;
|
||||
RECT 3032.5 38872.5 2897.5 38937.5 ;
|
||||
RECT 3032.5 38682.5 2897.5 38747.5 ;
|
||||
RECT 3917.5 38682.5 3782.5 38747.5 ;
|
||||
RECT 3917.5 38872.5 3782.5 38937.5 ;
|
||||
RECT 3917.5 38872.5 3782.5 38937.5 ;
|
||||
RECT 3917.5 38682.5 3782.5 38747.5 ;
|
||||
RECT 2942.5 39042.5 2807.5 39107.5 ;
|
||||
RECT 3917.5 39042.5 3782.5 39107.5 ;
|
||||
RECT 3475.0 38740.0 3340.0 38805.0 ;
|
||||
RECT 3475.0 38740.0 3340.0 38805.0 ;
|
||||
RECT 3440.0 38905.0 3375.0 38970.0 ;
|
||||
RECT 2722.5 38615.0 2657.5 39175.0 ;
|
||||
RECT 4067.5 38615.0 4002.5 39175.0 ;
|
||||
RECT 3340.0 38740.0 3475.0 38805.0 ;
|
||||
RECT 2505.0 38187.5 2690.0 38122.5 ;
|
||||
RECT 1345.0 38187.5 1530.0 38122.5 ;
|
||||
RECT 1462.5 38547.5 1312.5 38482.5 ;
|
||||
RECT 2347.5 38547.5 2722.5 38482.5 ;
|
||||
RECT 1462.5 38357.5 2347.5 38292.5 ;
|
||||
RECT 2347.5 38547.5 2482.5 38482.5 ;
|
||||
RECT 2347.5 38357.5 2482.5 38292.5 ;
|
||||
RECT 2347.5 38357.5 2482.5 38292.5 ;
|
||||
RECT 2347.5 38547.5 2482.5 38482.5 ;
|
||||
RECT 1462.5 38547.5 1597.5 38482.5 ;
|
||||
RECT 1462.5 38357.5 1597.5 38292.5 ;
|
||||
RECT 1462.5 38357.5 1597.5 38292.5 ;
|
||||
RECT 1462.5 38547.5 1597.5 38482.5 ;
|
||||
RECT 2437.5 38187.5 2572.5 38122.5 ;
|
||||
RECT 1462.5 38187.5 1597.5 38122.5 ;
|
||||
RECT 1905.0 38490.0 2040.0 38425.0 ;
|
||||
RECT 1905.0 38490.0 2040.0 38425.0 ;
|
||||
RECT 1940.0 38325.0 2005.0 38260.0 ;
|
||||
RECT 2657.5 38615.0 2722.5 38055.0 ;
|
||||
RECT 1312.5 38615.0 1377.5 38055.0 ;
|
||||
RECT 1905.0 38425.0 2040.0 38490.0 ;
|
||||
RECT 2505.0 37627.5 2690.0 37562.5 ;
|
||||
RECT 1345.0 37627.5 1530.0 37562.5 ;
|
||||
RECT 1462.5 37987.5 1312.5 37922.5 ;
|
||||
RECT 2347.5 37987.5 2722.5 37922.5 ;
|
||||
RECT 1462.5 37797.5 2347.5 37732.5 ;
|
||||
RECT 2347.5 37987.5 2482.5 37922.5 ;
|
||||
RECT 2347.5 37797.5 2482.5 37732.5 ;
|
||||
RECT 2347.5 37797.5 2482.5 37732.5 ;
|
||||
RECT 2347.5 37987.5 2482.5 37922.5 ;
|
||||
RECT 1462.5 37987.5 1597.5 37922.5 ;
|
||||
RECT 1462.5 37797.5 1597.5 37732.5 ;
|
||||
RECT 1462.5 37797.5 1597.5 37732.5 ;
|
||||
RECT 1462.5 37987.5 1597.5 37922.5 ;
|
||||
RECT 2437.5 37627.5 2572.5 37562.5 ;
|
||||
RECT 1462.5 37627.5 1597.5 37562.5 ;
|
||||
RECT 1905.0 37930.0 2040.0 37865.0 ;
|
||||
RECT 1905.0 37930.0 2040.0 37865.0 ;
|
||||
RECT 1940.0 37765.0 2005.0 37700.0 ;
|
||||
RECT 2657.5 38055.0 2722.5 37495.0 ;
|
||||
RECT 1312.5 38055.0 1377.5 37495.0 ;
|
||||
RECT 1905.0 37865.0 2040.0 37930.0 ;
|
||||
RECT 2505.0 37067.5 2690.0 37002.5 ;
|
||||
RECT 1345.0 37067.5 1530.0 37002.5 ;
|
||||
RECT 1462.5 37427.5 1312.5 37362.5 ;
|
||||
RECT 2347.5 37427.5 2722.5 37362.5 ;
|
||||
RECT 1462.5 37237.5 2347.5 37172.5 ;
|
||||
RECT 2347.5 37427.5 2482.5 37362.5 ;
|
||||
RECT 2347.5 37237.5 2482.5 37172.5 ;
|
||||
RECT 2347.5 37237.5 2482.5 37172.5 ;
|
||||
RECT 2347.5 37427.5 2482.5 37362.5 ;
|
||||
RECT 1462.5 37427.5 1597.5 37362.5 ;
|
||||
RECT 1462.5 37237.5 1597.5 37172.5 ;
|
||||
RECT 1462.5 37237.5 1597.5 37172.5 ;
|
||||
RECT 1462.5 37427.5 1597.5 37362.5 ;
|
||||
RECT 2437.5 37067.5 2572.5 37002.5 ;
|
||||
RECT 1462.5 37067.5 1597.5 37002.5 ;
|
||||
RECT 1905.0 37370.0 2040.0 37305.0 ;
|
||||
RECT 1905.0 37370.0 2040.0 37305.0 ;
|
||||
RECT 1940.0 37205.0 2005.0 37140.0 ;
|
||||
RECT 2657.5 37495.0 2722.5 36935.0 ;
|
||||
RECT 1312.5 37495.0 1377.5 36935.0 ;
|
||||
RECT 1905.0 37305.0 2040.0 37370.0 ;
|
||||
RECT 2505.0 36507.5 2690.0 36442.5 ;
|
||||
RECT 1345.0 36507.5 1530.0 36442.5 ;
|
||||
RECT 1462.5 36867.5 1312.5 36802.5 ;
|
||||
RECT 2347.5 36867.5 2722.5 36802.5 ;
|
||||
RECT 1462.5 36677.5 2347.5 36612.5 ;
|
||||
RECT 2347.5 36867.5 2482.5 36802.5 ;
|
||||
RECT 2347.5 36677.5 2482.5 36612.5 ;
|
||||
RECT 2347.5 36677.5 2482.5 36612.5 ;
|
||||
RECT 2347.5 36867.5 2482.5 36802.5 ;
|
||||
RECT 1462.5 36867.5 1597.5 36802.5 ;
|
||||
RECT 1462.5 36677.5 1597.5 36612.5 ;
|
||||
RECT 1462.5 36677.5 1597.5 36612.5 ;
|
||||
RECT 1462.5 36867.5 1597.5 36802.5 ;
|
||||
RECT 2437.5 36507.5 2572.5 36442.5 ;
|
||||
RECT 1462.5 36507.5 1597.5 36442.5 ;
|
||||
RECT 1905.0 36810.0 2040.0 36745.0 ;
|
||||
RECT 1905.0 36810.0 2040.0 36745.0 ;
|
||||
RECT 1940.0 36645.0 2005.0 36580.0 ;
|
||||
RECT 2657.5 36935.0 2722.5 36375.0 ;
|
||||
RECT 1312.5 36935.0 1377.5 36375.0 ;
|
||||
RECT 1905.0 36745.0 2040.0 36810.0 ;
|
||||
RECT 2505.0 35947.5 2690.0 35882.5 ;
|
||||
RECT 1345.0 35947.5 1530.0 35882.5 ;
|
||||
RECT 1462.5 36307.5 1312.5 36242.5 ;
|
||||
RECT 2347.5 36307.5 2722.5 36242.5 ;
|
||||
RECT 1462.5 36117.5 2347.5 36052.5 ;
|
||||
RECT 2347.5 36307.5 2482.5 36242.5 ;
|
||||
RECT 2347.5 36117.5 2482.5 36052.5 ;
|
||||
RECT 2347.5 36117.5 2482.5 36052.5 ;
|
||||
RECT 2347.5 36307.5 2482.5 36242.5 ;
|
||||
RECT 1462.5 36307.5 1597.5 36242.5 ;
|
||||
RECT 1462.5 36117.5 1597.5 36052.5 ;
|
||||
RECT 1462.5 36117.5 1597.5 36052.5 ;
|
||||
RECT 1462.5 36307.5 1597.5 36242.5 ;
|
||||
RECT 2437.5 35947.5 2572.5 35882.5 ;
|
||||
RECT 1462.5 35947.5 1597.5 35882.5 ;
|
||||
RECT 1905.0 36250.0 2040.0 36185.0 ;
|
||||
RECT 1905.0 36250.0 2040.0 36185.0 ;
|
||||
RECT 1940.0 36085.0 2005.0 36020.0 ;
|
||||
RECT 2657.5 36375.0 2722.5 35815.0 ;
|
||||
RECT 1312.5 36375.0 1377.5 35815.0 ;
|
||||
RECT 1905.0 36185.0 2040.0 36250.0 ;
|
||||
RECT 2505.0 35387.5 2690.0 35322.5 ;
|
||||
RECT 1345.0 35387.5 1530.0 35322.5 ;
|
||||
RECT 1462.5 35747.5 1312.5 35682.5 ;
|
||||
RECT 2347.5 35747.5 2722.5 35682.5 ;
|
||||
RECT 1462.5 35557.5 2347.5 35492.5 ;
|
||||
RECT 2347.5 35747.5 2482.5 35682.5 ;
|
||||
RECT 2347.5 35557.5 2482.5 35492.5 ;
|
||||
RECT 2347.5 35557.5 2482.5 35492.5 ;
|
||||
RECT 2347.5 35747.5 2482.5 35682.5 ;
|
||||
RECT 1462.5 35747.5 1597.5 35682.5 ;
|
||||
RECT 1462.5 35557.5 1597.5 35492.5 ;
|
||||
RECT 1462.5 35557.5 1597.5 35492.5 ;
|
||||
RECT 1462.5 35747.5 1597.5 35682.5 ;
|
||||
RECT 2437.5 35387.5 2572.5 35322.5 ;
|
||||
RECT 1462.5 35387.5 1597.5 35322.5 ;
|
||||
RECT 1905.0 35690.0 2040.0 35625.0 ;
|
||||
RECT 1905.0 35690.0 2040.0 35625.0 ;
|
||||
RECT 1940.0 35525.0 2005.0 35460.0 ;
|
||||
RECT 2657.5 35815.0 2722.5 35255.0 ;
|
||||
RECT 1312.5 35815.0 1377.5 35255.0 ;
|
||||
RECT 1905.0 35625.0 2040.0 35690.0 ;
|
||||
RECT 2505.0 34827.5 2690.0 34762.5 ;
|
||||
RECT 1345.0 34827.5 1530.0 34762.5 ;
|
||||
RECT 1462.5 35187.5 1312.5 35122.5 ;
|
||||
|
|
@ -4297,13 +4572,14 @@ MACRO sram_2_16_1_freepdk45
|
|||
RECT 1312.5 34695.0 1377.5 34135.0 ;
|
||||
RECT 1905.0 34505.0 2040.0 34570.0 ;
|
||||
RECT 3340.0 34425.0 3475.0 34490.0 ;
|
||||
RECT 3340.0 34985.0 3475.0 35050.0 ;
|
||||
RECT 1905.0 34900.0 2040.0 34965.0 ;
|
||||
RECT 3340.0 36665.0 3475.0 36730.0 ;
|
||||
RECT 3340.0 38905.0 3475.0 38970.0 ;
|
||||
RECT 1905.0 36580.0 2040.0 36645.0 ;
|
||||
RECT 3340.0 34260.0 3475.0 34325.0 ;
|
||||
RECT 1940.0 34135.0 2005.0 34340.0 ;
|
||||
RECT 2657.5 34135.0 2722.5 35255.0 ;
|
||||
RECT 1312.5 34135.0 1377.5 35255.0 ;
|
||||
RECT 4002.5 34135.0 4067.5 35255.0 ;
|
||||
RECT 2657.5 34135.0 2722.5 39175.0 ;
|
||||
RECT 1312.5 34135.0 1377.5 39175.0 ;
|
||||
RECT 4002.5 34135.0 4067.5 39175.0 ;
|
||||
RECT 935.0 33800.0 225.0 32455.0 ;
|
||||
RECT 935.0 33800.0 230.0 35145.0 ;
|
||||
RECT 935.0 36490.0 230.0 35145.0 ;
|
||||
|
|
@ -4312,12 +4588,12 @@ MACRO sram_2_16_1_freepdk45
|
|||
RECT 1025.0 35112.5 140.0 35177.5 ;
|
||||
RECT 1025.0 33767.5 140.0 33832.5 ;
|
||||
RECT 1025.0 36457.5 140.0 36522.5 ;
|
||||
RECT 1377.5 33907.5 1312.5 34042.5 ;
|
||||
RECT 1377.5 36317.5 1312.5 36452.5 ;
|
||||
RECT 1377.5 34135.0 1312.5 34270.0 ;
|
||||
RECT 1345.0 33872.5 1280.0 34007.5 ;
|
||||
RECT 1345.0 36282.5 1280.0 36417.5 ;
|
||||
RECT 1342.5 34135.0 1277.5 34270.0 ;
|
||||
RECT 1377.5 31760.0 1312.5 31895.0 ;
|
||||
RECT 1277.5 36817.5 1412.5 36882.5 ;
|
||||
RECT 867.5 36817.5 1002.5 36882.5 ;
|
||||
RECT 867.5 31862.5 1002.5 31927.5 ;
|
||||
RECT 162.5 31862.5 297.5 31927.5 ;
|
||||
RECT 2005.0 33367.5 1940.0 33502.5 ;
|
||||
RECT 1105.0 32627.5 1240.0 32692.5 ;
|
||||
RECT 1105.0 32030.0 1240.0 32095.0 ;
|
||||
|
|
@ -4326,7 +4602,7 @@ MACRO sram_2_16_1_freepdk45
|
|||
RECT 2005.0 31335.0 1940.0 32100.0 ;
|
||||
RECT 20.0 31335.0 -45.0 36577.5 ;
|
||||
RECT 2722.5 31335.0 2657.5 34135.0 ;
|
||||
RECT 1380.0 31335.0 1310.0 32455.0 ;
|
||||
RECT 1377.5 31335.0 1312.5 31895.0 ;
|
||||
RECT 4067.5 31335.0 4002.5 34135.0 ;
|
||||
RECT 3455.0 26182.5 3390.0 26047.5 ;
|
||||
RECT 3455.0 22102.5 3390.0 21967.5 ;
|
||||
|
|
@ -4529,14 +4805,14 @@ MACRO sram_2_16_1_freepdk45
|
|||
RECT 9057.5 11120.0 9192.5 11190.0 ;
|
||||
RECT 10717.5 12465.0 10852.5 12535.0 ;
|
||||
RECT 8782.5 12465.0 8917.5 12535.0 ;
|
||||
RECT 9607.5 8720.0 9742.5 8790.0 ;
|
||||
RECT 9332.5 8935.0 9467.5 9005.0 ;
|
||||
RECT 9057.5 10560.0 9192.5 10630.0 ;
|
||||
RECT 9332.5 10345.0 9467.5 10415.0 ;
|
||||
RECT 9607.5 11410.0 9742.5 11480.0 ;
|
||||
RECT 8782.5 11625.0 8917.5 11695.0 ;
|
||||
RECT 9057.5 13250.0 9192.5 13320.0 ;
|
||||
RECT 8782.5 13035.0 8917.5 13105.0 ;
|
||||
RECT 9607.5 8935.0 9742.5 9005.0 ;
|
||||
RECT 9332.5 8720.0 9467.5 8790.0 ;
|
||||
RECT 9057.5 10345.0 9192.5 10415.0 ;
|
||||
RECT 9332.5 10560.0 9467.5 10630.0 ;
|
||||
RECT 9607.5 11625.0 9742.5 11695.0 ;
|
||||
RECT 8782.5 11410.0 8917.5 11480.0 ;
|
||||
RECT 9057.5 13035.0 9192.5 13105.0 ;
|
||||
RECT 8782.5 13250.0 8917.5 13320.0 ;
|
||||
RECT 11095.0 8330.0 11025.0 13570.0 ;
|
||||
RECT 10820.0 8330.0 10750.0 13570.0 ;
|
||||
RECT 9160.0 13710.0 9090.0 18950.0 ;
|
||||
|
|
@ -4583,14 +4859,14 @@ MACRO sram_2_16_1_freepdk45
|
|||
RECT 9057.5 16500.0 9192.5 16570.0 ;
|
||||
RECT 10717.5 17845.0 10852.5 17915.0 ;
|
||||
RECT 8782.5 17845.0 8917.5 17915.0 ;
|
||||
RECT 9607.5 14100.0 9742.5 14170.0 ;
|
||||
RECT 9332.5 14315.0 9467.5 14385.0 ;
|
||||
RECT 9057.5 15940.0 9192.5 16010.0 ;
|
||||
RECT 9332.5 15725.0 9467.5 15795.0 ;
|
||||
RECT 9607.5 16790.0 9742.5 16860.0 ;
|
||||
RECT 8782.5 17005.0 8917.5 17075.0 ;
|
||||
RECT 9057.5 18630.0 9192.5 18700.0 ;
|
||||
RECT 8782.5 18415.0 8917.5 18485.0 ;
|
||||
RECT 9607.5 14315.0 9742.5 14385.0 ;
|
||||
RECT 9332.5 14100.0 9467.5 14170.0 ;
|
||||
RECT 9057.5 15725.0 9192.5 15795.0 ;
|
||||
RECT 9332.5 15940.0 9467.5 16010.0 ;
|
||||
RECT 9607.5 17005.0 9742.5 17075.0 ;
|
||||
RECT 8782.5 16790.0 8917.5 16860.0 ;
|
||||
RECT 9057.5 18415.0 9192.5 18485.0 ;
|
||||
RECT 8782.5 18630.0 8917.5 18700.0 ;
|
||||
RECT 11095.0 13710.0 11025.0 18950.0 ;
|
||||
RECT 10820.0 13710.0 10750.0 18950.0 ;
|
||||
RECT 7385.0 19695.0 7455.0 19765.0 ;
|
||||
|
|
@ -5088,6 +5364,7 @@ MACRO sram_2_16_1_freepdk45
|
|||
RECT 4035.0 26695.0 8.881784197e-13 26765.0 ;
|
||||
RECT 4035.0 26900.0 8.881784197e-13 26970.0 ;
|
||||
RECT 4035.0 27310.0 8.881784197e-13 27380.0 ;
|
||||
RECT 3422.5 22000.0 2690.0 22070.0 ;
|
||||
RECT 2520.0 19467.5 2450.0 26115.0 ;
|
||||
RECT 4035.0 26285.0 3830.0 26355.0 ;
|
||||
RECT 2895.0 27105.0 2690.0 27175.0 ;
|
||||
|
|
@ -5162,25 +5439,51 @@ MACRO sram_2_16_1_freepdk45
|
|||
RECT 1610.0 26387.5 1540.0 26252.5 ;
|
||||
RECT 2315.0 25737.5 2245.0 25602.5 ;
|
||||
RECT 2315.0 26387.5 2245.0 26252.5 ;
|
||||
RECT 1380.0 31895.0 1310.0 36750.0 ;
|
||||
RECT 1380.0 32455.0 1310.0 32660.0 ;
|
||||
RECT 1380.0 32660.0 1310.0 36850.0 ;
|
||||
RECT 970.0 36645.0 900.0 36850.0 ;
|
||||
RECT 1380.0 31895.0 1310.0 36955.0 ;
|
||||
RECT 970.0 31895.0 900.0 36645.0 ;
|
||||
RECT 265.0 31895.0 195.0 36645.0 ;
|
||||
RECT 1207.5 32062.5 1137.5 32660.0 ;
|
||||
RECT 785.0 32062.5 715.0 32342.5 ;
|
||||
RECT 3372.5 34457.5 3442.5 34852.5 ;
|
||||
RECT 2655.0 34982.5 2725.0 35052.5 ;
|
||||
RECT 2655.0 35062.5 2725.0 35132.5 ;
|
||||
RECT 2690.0 34982.5 3407.5 35052.5 ;
|
||||
RECT 2655.0 35017.5 2725.0 35097.5 ;
|
||||
RECT 1972.5 35062.5 2690.0 35132.5 ;
|
||||
RECT 1937.5 34537.5 2007.5 34932.5 ;
|
||||
RECT 3372.5 34852.5 3442.5 35412.5 ;
|
||||
RECT 3372.5 35412.5 3442.5 35972.5 ;
|
||||
RECT 3372.5 35972.5 3442.5 36532.5 ;
|
||||
RECT 3372.5 36697.5 3442.5 37092.5 ;
|
||||
RECT 3372.5 37092.5 3442.5 37652.5 ;
|
||||
RECT 3372.5 37652.5 3442.5 38212.5 ;
|
||||
RECT 3372.5 38212.5 3442.5 38772.5 ;
|
||||
RECT 2655.0 38902.5 2725.0 38972.5 ;
|
||||
RECT 2655.0 38422.5 2725.0 38492.5 ;
|
||||
RECT 2690.0 38902.5 3407.5 38972.5 ;
|
||||
RECT 2655.0 38457.5 2725.0 38937.5 ;
|
||||
RECT 1972.5 38422.5 2690.0 38492.5 ;
|
||||
RECT 1937.5 37897.5 2007.5 38457.5 ;
|
||||
RECT 1937.5 37337.5 2007.5 37897.5 ;
|
||||
RECT 1937.5 36777.5 2007.5 37337.5 ;
|
||||
RECT 1937.5 36217.5 2007.5 36612.5 ;
|
||||
RECT 1937.5 35657.5 2007.5 36217.5 ;
|
||||
RECT 1937.5 35097.5 2007.5 35657.5 ;
|
||||
RECT 1937.5 34537.5 2007.5 35097.5 ;
|
||||
RECT 3340.0 34817.5 3475.0 34887.5 ;
|
||||
RECT 3340.0 35377.5 3475.0 35447.5 ;
|
||||
RECT 3340.0 35937.5 3475.0 36007.5 ;
|
||||
RECT 3340.0 36497.5 3475.0 36567.5 ;
|
||||
RECT 3340.0 37057.5 3475.0 37127.5 ;
|
||||
RECT 3340.0 37617.5 3475.0 37687.5 ;
|
||||
RECT 3340.0 38177.5 3475.0 38247.5 ;
|
||||
RECT 3340.0 38737.5 3475.0 38807.5 ;
|
||||
RECT 1905.0 38422.5 2040.0 38492.5 ;
|
||||
RECT 1905.0 37862.5 2040.0 37932.5 ;
|
||||
RECT 1905.0 37302.5 2040.0 37372.5 ;
|
||||
RECT 1905.0 36742.5 2040.0 36812.5 ;
|
||||
RECT 1905.0 36182.5 2040.0 36252.5 ;
|
||||
RECT 1905.0 35622.5 2040.0 35692.5 ;
|
||||
RECT 1905.0 35062.5 2040.0 35132.5 ;
|
||||
RECT 1905.0 34502.5 2040.0 34572.5 ;
|
||||
RECT 3340.0 34422.5 3475.0 34492.5 ;
|
||||
RECT 3340.0 34982.5 3475.0 35052.5 ;
|
||||
RECT 1905.0 34897.5 2040.0 34967.5 ;
|
||||
RECT 3340.0 36662.5 3475.0 36732.5 ;
|
||||
RECT 3340.0 38902.5 3475.0 38972.5 ;
|
||||
RECT 1905.0 36577.5 2040.0 36647.5 ;
|
||||
RECT 935.0 33800.0 225.0 32455.0 ;
|
||||
RECT 935.0 33800.0 230.0 35145.0 ;
|
||||
RECT 935.0 36490.0 230.0 35145.0 ;
|
||||
|
|
@ -5188,19 +5491,19 @@ MACRO sram_2_16_1_freepdk45
|
|||
RECT 450.0 33700.0 380.0 36645.0 ;
|
||||
RECT 970.0 33700.0 900.0 36645.0 ;
|
||||
RECT 265.0 33700.0 195.0 36645.0 ;
|
||||
RECT 1380.0 33907.5 1310.0 34042.5 ;
|
||||
RECT 1380.0 36317.5 1310.0 36452.5 ;
|
||||
RECT 1380.0 34135.0 1310.0 34270.0 ;
|
||||
RECT 1347.5 33872.5 1277.5 34007.5 ;
|
||||
RECT 1347.5 36282.5 1277.5 36417.5 ;
|
||||
RECT 1345.0 34135.0 1275.0 34270.0 ;
|
||||
RECT 1380.0 31760.0 1310.0 31895.0 ;
|
||||
RECT 1277.5 36815.0 1412.5 36885.0 ;
|
||||
RECT 867.5 36815.0 1002.5 36885.0 ;
|
||||
RECT 867.5 31860.0 1002.5 31930.0 ;
|
||||
RECT 162.5 31860.0 297.5 31930.0 ;
|
||||
RECT 1105.0 32625.0 1240.0 32695.0 ;
|
||||
RECT 1105.0 32027.5 1240.0 32097.5 ;
|
||||
RECT 682.5 32027.5 817.5 32097.5 ;
|
||||
RECT 3457.5 26182.5 3387.5 26047.5 ;
|
||||
RECT 3457.5 22102.5 3387.5 21967.5 ;
|
||||
RECT 3457.5 27617.5 3387.5 27482.5 ;
|
||||
RECT 3457.5 22102.5 3387.5 21967.5 ;
|
||||
RECT 2725.0 22102.5 2655.0 21967.5 ;
|
||||
RECT 2725.0 27617.5 2655.0 27482.5 ;
|
||||
RECT 2520.0 19535.0 2450.0 19400.0 ;
|
||||
RECT 1965.0 26182.5 1895.0 26047.5 ;
|
||||
RECT 1750.0 26592.5 1680.0 26457.5 ;
|
||||
|
|
@ -5299,7 +5602,7 @@ MACRO sram_2_16_1_freepdk45
|
|||
RECT 905.0 25670.0 835.0 26320.0 ;
|
||||
RECT 1610.0 25670.0 1540.0 26320.0 ;
|
||||
RECT 2315.0 25670.0 2245.0 26320.0 ;
|
||||
RECT 3457.5 22035.0 3387.5 27550.0 ;
|
||||
RECT 2725.0 22035.0 2655.0 27550.0 ;
|
||||
RECT 2020.0 27550.0 1950.0 29062.5 ;
|
||||
RECT 1805.0 27345.0 1735.0 29320.0 ;
|
||||
RECT 482.5 19230.0 552.5 19370.0 ;
|
||||
|
|
@ -5321,8 +5624,8 @@ MACRO sram_2_16_1_freepdk45
|
|||
RECT 1610.0 26387.5 1540.0 26252.5 ;
|
||||
RECT 2315.0 25737.5 2245.0 25602.5 ;
|
||||
RECT 2315.0 26387.5 2245.0 26252.5 ;
|
||||
RECT 3457.5 22102.5 3387.5 21967.5 ;
|
||||
RECT 3457.5 27617.5 3387.5 27482.5 ;
|
||||
RECT 2725.0 22102.5 2655.0 21967.5 ;
|
||||
RECT 2725.0 27617.5 2655.0 27482.5 ;
|
||||
RECT 2020.0 29130.0 1950.0 28995.0 ;
|
||||
RECT 2020.0 27617.5 1950.0 27482.5 ;
|
||||
RECT 1805.0 29387.5 1735.0 29252.5 ;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
library (sram_2_16_1_scn3me_subm_lib){
|
||||
library (sram_2_16_1_freepdk45_TT_10V_25C_lib){
|
||||
delay_model : "table_lookup";
|
||||
time_unit : "1ns" ;
|
||||
voltage_unit : "1v" ;
|
||||
|
|
@ -8,8 +8,8 @@ library (sram_2_16_1_scn3me_subm_lib){
|
|||
leakage_power_unit : "1mW" ;
|
||||
pulling_resistance_unit :"1kohm" ;
|
||||
operating_conditions(TT){
|
||||
voltage : 5.0 ;
|
||||
temperature : 25.000 ;
|
||||
voltage : 1.0 ;
|
||||
temperature : 25;
|
||||
}
|
||||
|
||||
input_threshold_pct_fall : 50.0 ;
|
||||
|
|
@ -34,15 +34,15 @@ library (sram_2_16_1_scn3me_subm_lib){
|
|||
lu_table_template(CELL_TABLE){
|
||||
variable_1 : input_net_transition;
|
||||
variable_2 : total_output_net_capacitance;
|
||||
index_1("0.0125, 0.05, 0.4");
|
||||
index_2("2.45605, 9.8242, 78.5936");
|
||||
index_1("0.00125, 0.005, 0.04");
|
||||
index_2("0.052275, 0.2091, 1.6728");
|
||||
}
|
||||
|
||||
lu_table_template(CONSTRAINT_TABLE){
|
||||
variable_1 : related_pin_transition;
|
||||
variable_2 : constrained_pin_transition;
|
||||
index_1("0.0125, 0.05, 0.4");
|
||||
index_2("0.0125, 0.05, 0.4");
|
||||
index_1("0.00125, 0.005, 0.04");
|
||||
index_2("0.00125, 0.005, 0.04");
|
||||
}
|
||||
|
||||
default_operating_conditions : TT;
|
||||
|
|
@ -64,7 +64,7 @@ library (sram_2_16_1_scn3me_subm_lib){
|
|||
bit_to : 3;
|
||||
}
|
||||
|
||||
cell (sram_2_16_1_scn3me_subm){
|
||||
cell (sram_2_16_1_freepdk45){
|
||||
memory(){
|
||||
type : ram;
|
||||
address_width : 4;
|
||||
|
|
@ -74,12 +74,12 @@ cell (sram_2_16_1_scn3me_subm){
|
|||
dont_use : true;
|
||||
map_only : true;
|
||||
dont_touch : true;
|
||||
area : 2.7;
|
||||
area : 918.5120625;
|
||||
|
||||
bus(DATA){
|
||||
bus_type : DATA;
|
||||
direction : inout;
|
||||
max_capacitance : 78.5936;
|
||||
max_capacitance : 1.6728;
|
||||
three_state : "!OEb & !clk";
|
||||
memory_write(){
|
||||
address : ADDR;
|
||||
|
|
@ -92,47 +92,47 @@ cell (sram_2_16_1_scn3me_subm){
|
|||
internal_power(){
|
||||
when : "OEb & !clk";
|
||||
rise_power(scalar){
|
||||
values("2.8745");
|
||||
values("0.042347092");
|
||||
}
|
||||
fall_power(scalar){
|
||||
values("3.0265");
|
||||
values("0.029908723");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
timing_type : setup_rising;
|
||||
related_pin : "clk";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.082, 0.088, 0.186",\
|
||||
"0.082, 0.088, 0.186",\
|
||||
"0.082, 0.088, 0.186");
|
||||
values("0.009, 0.015, 0.021",\
|
||||
"0.009, 0.015, 0.021",\
|
||||
"0.009, 0.015, 0.021");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.021, 0.021, 0.027",\
|
||||
"0.021, 0.021, 0.027",\
|
||||
"0.021, 0.021, 0.027");
|
||||
values("0.009, 0.009, 0.015",\
|
||||
"0.009, 0.009, 0.015",\
|
||||
"0.009, 0.009, 0.015");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
timing_type : hold_rising;
|
||||
related_pin : "clk";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.015, 0.021",\
|
||||
"0.009, 0.015, 0.021",\
|
||||
"0.009, 0.015, 0.021");
|
||||
values("0.002, 0.002, -0.004",\
|
||||
"0.002, 0.002, -0.004",\
|
||||
"0.002, 0.002, -0.004");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("-0.065, -0.071, -0.175",\
|
||||
"-0.065, -0.071, -0.175",\
|
||||
"-0.065, -0.071, -0.175");
|
||||
values("-0.004, -0.004, -0.016",\
|
||||
"-0.004, -0.004, -0.016",\
|
||||
"-0.004, -0.004, -0.016");
|
||||
}
|
||||
}
|
||||
internal_power(){
|
||||
when : "!OEb & !clk";
|
||||
rise_power(scalar){
|
||||
values("4.4921");
|
||||
values("0.054779642");
|
||||
}
|
||||
fall_power(scalar){
|
||||
values("4.5139");
|
||||
values("0.060081573");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
|
|
@ -140,24 +140,24 @@ cell (sram_2_16_1_scn3me_subm){
|
|||
related_pin : "clk";
|
||||
timing_type : falling_edge;
|
||||
cell_rise(CELL_TABLE) {
|
||||
values("0.496, 0.579, 1.253",\
|
||||
"0.499, 0.581, 1.258",\
|
||||
"0.547, 0.627, 1.305");
|
||||
values("0.055, 0.056, 0.063",\
|
||||
"0.056, 0.057, 0.063",\
|
||||
"0.061, 0.062, 0.069");
|
||||
}
|
||||
cell_fall(CELL_TABLE) {
|
||||
values("1.429, 1.539, 2.523",\
|
||||
"1.433, 1.544, 2.526",\
|
||||
"1.485, 1.595, 2.578");
|
||||
values("0.522, 0.523, 0.533",\
|
||||
"0.523, 0.524, 0.533",\
|
||||
"0.528, 0.529, 0.539");
|
||||
}
|
||||
rise_transition(CELL_TABLE) {
|
||||
values("0.189, 0.335, 1.879",\
|
||||
"0.19, 0.336, 1.879",\
|
||||
"0.192, 0.337, 1.879");
|
||||
values("0.013, 0.015, 0.026",\
|
||||
"0.013, 0.015, 0.026",\
|
||||
"0.013, 0.015, 0.026");
|
||||
}
|
||||
fall_transition(CELL_TABLE) {
|
||||
values("0.224, 0.437, 2.462",\
|
||||
"0.225, 0.437, 2.472",\
|
||||
"0.225, 0.436, 2.458");
|
||||
values("0.029, 0.031, 0.044",\
|
||||
"0.029, 0.031, 0.044",\
|
||||
"0.029, 0.031, 0.044");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -166,36 +166,36 @@ cell (sram_2_16_1_scn3me_subm){
|
|||
bus(ADDR){
|
||||
bus_type : ADDR;
|
||||
direction : input;
|
||||
capacitance : 9.8242;
|
||||
max_transition : 0.4;
|
||||
capacitance : 0.2091;
|
||||
max_transition : 0.04;
|
||||
fanout_load : 1.000000;
|
||||
pin(ADDR[3:0]){
|
||||
timing(){
|
||||
timing_type : setup_rising;
|
||||
related_pin : "clk";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.082, 0.088, 0.186",\
|
||||
"0.082, 0.088, 0.186",\
|
||||
"0.082, 0.088, 0.186");
|
||||
values("0.009, 0.015, 0.021",\
|
||||
"0.009, 0.015, 0.021",\
|
||||
"0.009, 0.015, 0.021");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.021, 0.021, 0.027",\
|
||||
"0.021, 0.021, 0.027",\
|
||||
"0.021, 0.021, 0.027");
|
||||
values("0.009, 0.009, 0.015",\
|
||||
"0.009, 0.009, 0.015",\
|
||||
"0.009, 0.009, 0.015");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
timing_type : hold_rising;
|
||||
related_pin : "clk";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.015, 0.021",\
|
||||
"0.009, 0.015, 0.021",\
|
||||
"0.009, 0.015, 0.021");
|
||||
values("0.002, 0.002, -0.004",\
|
||||
"0.002, 0.002, -0.004",\
|
||||
"0.002, 0.002, -0.004");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("-0.065, -0.071, -0.175",\
|
||||
"-0.065, -0.071, -0.175",\
|
||||
"-0.065, -0.071, -0.175");
|
||||
values("-0.004, -0.004, -0.016",\
|
||||
"-0.004, -0.004, -0.016",\
|
||||
"-0.004, -0.004, -0.016");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -203,99 +203,99 @@ cell (sram_2_16_1_scn3me_subm){
|
|||
|
||||
pin(CSb){
|
||||
direction : input;
|
||||
capacitance : 9.8242;
|
||||
capacitance : 0.2091;
|
||||
timing(){
|
||||
timing_type : setup_rising;
|
||||
related_pin : "clk";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.082, 0.088, 0.186",\
|
||||
"0.082, 0.088, 0.186",\
|
||||
"0.082, 0.088, 0.186");
|
||||
values("0.009, 0.015, 0.021",\
|
||||
"0.009, 0.015, 0.021",\
|
||||
"0.009, 0.015, 0.021");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.021, 0.021, 0.027",\
|
||||
"0.021, 0.021, 0.027",\
|
||||
"0.021, 0.021, 0.027");
|
||||
values("0.009, 0.009, 0.015",\
|
||||
"0.009, 0.009, 0.015",\
|
||||
"0.009, 0.009, 0.015");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
timing_type : hold_rising;
|
||||
related_pin : "clk";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.015, 0.021",\
|
||||
"0.009, 0.015, 0.021",\
|
||||
"0.009, 0.015, 0.021");
|
||||
values("0.002, 0.002, -0.004",\
|
||||
"0.002, 0.002, -0.004",\
|
||||
"0.002, 0.002, -0.004");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("-0.065, -0.071, -0.175",\
|
||||
"-0.065, -0.071, -0.175",\
|
||||
"-0.065, -0.071, -0.175");
|
||||
values("-0.004, -0.004, -0.016",\
|
||||
"-0.004, -0.004, -0.016",\
|
||||
"-0.004, -0.004, -0.016");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pin(OEb){
|
||||
direction : input;
|
||||
capacitance : 9.8242;
|
||||
capacitance : 0.2091;
|
||||
timing(){
|
||||
timing_type : setup_rising;
|
||||
related_pin : "clk";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.082, 0.088, 0.186",\
|
||||
"0.082, 0.088, 0.186",\
|
||||
"0.082, 0.088, 0.186");
|
||||
values("0.009, 0.015, 0.021",\
|
||||
"0.009, 0.015, 0.021",\
|
||||
"0.009, 0.015, 0.021");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.021, 0.021, 0.027",\
|
||||
"0.021, 0.021, 0.027",\
|
||||
"0.021, 0.021, 0.027");
|
||||
values("0.009, 0.009, 0.015",\
|
||||
"0.009, 0.009, 0.015",\
|
||||
"0.009, 0.009, 0.015");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
timing_type : hold_rising;
|
||||
related_pin : "clk";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.015, 0.021",\
|
||||
"0.009, 0.015, 0.021",\
|
||||
"0.009, 0.015, 0.021");
|
||||
values("0.002, 0.002, -0.004",\
|
||||
"0.002, 0.002, -0.004",\
|
||||
"0.002, 0.002, -0.004");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("-0.065, -0.071, -0.175",\
|
||||
"-0.065, -0.071, -0.175",\
|
||||
"-0.065, -0.071, -0.175");
|
||||
values("-0.004, -0.004, -0.016",\
|
||||
"-0.004, -0.004, -0.016",\
|
||||
"-0.004, -0.004, -0.016");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pin(WEb){
|
||||
direction : input;
|
||||
capacitance : 9.8242;
|
||||
capacitance : 0.2091;
|
||||
timing(){
|
||||
timing_type : setup_rising;
|
||||
related_pin : "clk";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.082, 0.088, 0.186",\
|
||||
"0.082, 0.088, 0.186",\
|
||||
"0.082, 0.088, 0.186");
|
||||
values("0.009, 0.015, 0.021",\
|
||||
"0.009, 0.015, 0.021",\
|
||||
"0.009, 0.015, 0.021");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.021, 0.021, 0.027",\
|
||||
"0.021, 0.021, 0.027",\
|
||||
"0.021, 0.021, 0.027");
|
||||
values("0.009, 0.009, 0.015",\
|
||||
"0.009, 0.009, 0.015",\
|
||||
"0.009, 0.009, 0.015");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
timing_type : hold_rising;
|
||||
related_pin : "clk";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.015, 0.021",\
|
||||
"0.009, 0.015, 0.021",\
|
||||
"0.009, 0.015, 0.021");
|
||||
values("0.002, 0.002, -0.004",\
|
||||
"0.002, 0.002, -0.004",\
|
||||
"0.002, 0.002, -0.004");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("-0.065, -0.071, -0.175",\
|
||||
"-0.065, -0.071, -0.175",\
|
||||
"-0.065, -0.071, -0.175");
|
||||
values("-0.004, -0.004, -0.016",\
|
||||
"-0.004, -0.004, -0.016",\
|
||||
"-0.004, -0.004, -0.016");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -303,25 +303,25 @@ cell (sram_2_16_1_scn3me_subm){
|
|||
pin(clk){
|
||||
clock : true;
|
||||
direction : input;
|
||||
capacitance : 9.8242;
|
||||
capacitance : 0.2091;
|
||||
timing(){
|
||||
timing_type :"min_pulse_width";
|
||||
related_pin : clk;
|
||||
rise_constraint(scalar) {
|
||||
values("4.375");
|
||||
values("0.5275");
|
||||
}
|
||||
fall_constraint(scalar) {
|
||||
values("4.375");
|
||||
values("0.5275");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
timing_type :"minimum_period";
|
||||
related_pin : clk;
|
||||
rise_constraint(scalar) {
|
||||
values("8.75");
|
||||
values("1.055");
|
||||
}
|
||||
fall_constraint(scalar) {
|
||||
values("8.75");
|
||||
values("1.055");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
library (sram_2_16_1_freepdk45_lib){
|
||||
library (sram_2_16_1_freepdk45_TT_10V_25C_lib){
|
||||
delay_model : "table_lookup";
|
||||
time_unit : "1ns" ;
|
||||
voltage_unit : "1v" ;
|
||||
|
|
@ -9,7 +9,7 @@ library (sram_2_16_1_freepdk45_lib){
|
|||
pulling_resistance_unit :"1kohm" ;
|
||||
operating_conditions(TT){
|
||||
voltage : 1.0 ;
|
||||
temperature : 25.000 ;
|
||||
temperature : 25;
|
||||
}
|
||||
|
||||
input_threshold_pct_fall : 50.0 ;
|
||||
|
|
@ -74,7 +74,7 @@ cell (sram_2_16_1_freepdk45){
|
|||
dont_use : true;
|
||||
map_only : true;
|
||||
dont_touch : true;
|
||||
area : 0.023625;
|
||||
area : 918.5120625;
|
||||
|
||||
bus(DATA){
|
||||
bus_type : DATA;
|
||||
|
|
@ -92,19 +92,19 @@ cell (sram_2_16_1_freepdk45){
|
|||
internal_power(){
|
||||
when : "OEb & !clk";
|
||||
rise_power(scalar){
|
||||
values("0.027781");
|
||||
values("0.039115101");
|
||||
}
|
||||
fall_power(scalar){
|
||||
values("0.026752");
|
||||
values("0.026662611");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
timing_type : setup_rising;
|
||||
related_pin : "clk";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.015, 0.027",\
|
||||
"0.009, 0.015, 0.027",\
|
||||
"0.009, 0.015, 0.027");
|
||||
values("0.009, 0.015, 0.021",\
|
||||
"0.009, 0.015, 0.021",\
|
||||
"0.009, 0.015, 0.021");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.009, 0.015",\
|
||||
|
|
@ -129,10 +129,10 @@ cell (sram_2_16_1_freepdk45){
|
|||
internal_power(){
|
||||
when : "!OEb & !clk";
|
||||
rise_power(scalar){
|
||||
values("0.031198");
|
||||
values("0.036300681");
|
||||
}
|
||||
fall_power(scalar){
|
||||
values("0.031252");
|
||||
values("0.041472985");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
|
|
@ -140,24 +140,24 @@ cell (sram_2_16_1_freepdk45){
|
|||
related_pin : "clk";
|
||||
timing_type : falling_edge;
|
||||
cell_rise(CELL_TABLE) {
|
||||
values("0.046, 0.047, 0.054",\
|
||||
"0.047, 0.047, 0.054",\
|
||||
"0.052, 0.052, 0.059");
|
||||
values("0.054, 0.055, 0.061",\
|
||||
"0.055, 0.055, 0.062",\
|
||||
"0.06, 0.061, 0.067");
|
||||
}
|
||||
cell_fall(CELL_TABLE) {
|
||||
values("0.132, 0.133, 0.142",\
|
||||
"0.133, 0.134, 0.142",\
|
||||
"0.138, 0.139, 0.147");
|
||||
values("0.519, 0.52, 0.529",\
|
||||
"0.519, 0.52, 0.53",\
|
||||
"0.525, 0.526, 0.535");
|
||||
}
|
||||
rise_transition(CELL_TABLE) {
|
||||
values("0.014, 0.015, 0.027",\
|
||||
"0.014, 0.015, 0.027",\
|
||||
"0.014, 0.015, 0.027");
|
||||
values("0.013, 0.014, 0.026",\
|
||||
"0.013, 0.014, 0.026",\
|
||||
"0.013, 0.015, 0.026");
|
||||
}
|
||||
fall_transition(CELL_TABLE) {
|
||||
values("0.018, 0.02, 0.036",\
|
||||
"0.019, 0.02, 0.036",\
|
||||
"0.019, 0.02, 0.036");
|
||||
values("0.027, 0.029, 0.043",\
|
||||
"0.027, 0.029, 0.043",\
|
||||
"0.027, 0.029, 0.043");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -174,9 +174,9 @@ cell (sram_2_16_1_freepdk45){
|
|||
timing_type : setup_rising;
|
||||
related_pin : "clk";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.015, 0.027",\
|
||||
"0.009, 0.015, 0.027",\
|
||||
"0.009, 0.015, 0.027");
|
||||
values("0.009, 0.015, 0.021",\
|
||||
"0.009, 0.015, 0.021",\
|
||||
"0.009, 0.015, 0.021");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.009, 0.015",\
|
||||
|
|
@ -208,9 +208,9 @@ cell (sram_2_16_1_freepdk45){
|
|||
timing_type : setup_rising;
|
||||
related_pin : "clk";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.015, 0.027",\
|
||||
"0.009, 0.015, 0.027",\
|
||||
"0.009, 0.015, 0.027");
|
||||
values("0.009, 0.015, 0.021",\
|
||||
"0.009, 0.015, 0.021",\
|
||||
"0.009, 0.015, 0.021");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.009, 0.015",\
|
||||
|
|
@ -241,9 +241,9 @@ cell (sram_2_16_1_freepdk45){
|
|||
timing_type : setup_rising;
|
||||
related_pin : "clk";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.015, 0.027",\
|
||||
"0.009, 0.015, 0.027",\
|
||||
"0.009, 0.015, 0.027");
|
||||
values("0.009, 0.015, 0.021",\
|
||||
"0.009, 0.015, 0.021",\
|
||||
"0.009, 0.015, 0.021");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.009, 0.015",\
|
||||
|
|
@ -274,9 +274,9 @@ cell (sram_2_16_1_freepdk45){
|
|||
timing_type : setup_rising;
|
||||
related_pin : "clk";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.015, 0.027",\
|
||||
"0.009, 0.015, 0.027",\
|
||||
"0.009, 0.015, 0.027");
|
||||
values("0.009, 0.015, 0.021",\
|
||||
"0.009, 0.015, 0.021",\
|
||||
"0.009, 0.015, 0.021");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.009, 0.015",\
|
||||
|
|
@ -308,20 +308,20 @@ cell (sram_2_16_1_freepdk45){
|
|||
timing_type :"min_pulse_width";
|
||||
related_pin : clk;
|
||||
rise_constraint(scalar) {
|
||||
values("0.1955");
|
||||
values("0.5275");
|
||||
}
|
||||
fall_constraint(scalar) {
|
||||
values("0.1955");
|
||||
values("0.5275");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
timing_type :"minimum_period";
|
||||
related_pin : clk;
|
||||
rise_constraint(scalar) {
|
||||
values("0.391");
|
||||
values("1.055");
|
||||
}
|
||||
fall_constraint(scalar) {
|
||||
values("0.391");
|
||||
values("1.055");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
library (sram_2_16_1_freepdk45_lib){
|
||||
library (sram_2_16_1_freepdk45_TT_10V_25C_lib){
|
||||
delay_model : "table_lookup";
|
||||
time_unit : "1ns" ;
|
||||
voltage_unit : "1v" ;
|
||||
|
|
@ -9,7 +9,7 @@ library (sram_2_16_1_freepdk45_lib){
|
|||
pulling_resistance_unit :"1kohm" ;
|
||||
operating_conditions(TT){
|
||||
voltage : 1.0 ;
|
||||
temperature : 25.000 ;
|
||||
temperature : 25;
|
||||
}
|
||||
|
||||
input_threshold_pct_fall : 50.0 ;
|
||||
|
|
@ -74,7 +74,7 @@ cell (sram_2_16_1_freepdk45){
|
|||
dont_use : true;
|
||||
map_only : true;
|
||||
dont_touch : true;
|
||||
area : 0.023625;
|
||||
area : 918.5120625;
|
||||
|
||||
bus(DATA){
|
||||
bus_type : DATA;
|
||||
|
|
@ -92,19 +92,19 @@ cell (sram_2_16_1_freepdk45){
|
|||
internal_power(){
|
||||
when : "OEb & !clk";
|
||||
rise_power(scalar){
|
||||
values("0.027781");
|
||||
values("0.039115101");
|
||||
}
|
||||
fall_power(scalar){
|
||||
values("0.026752");
|
||||
values("0.026662611");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
timing_type : setup_rising;
|
||||
related_pin : "clk";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.015, 0.027",\
|
||||
"0.009, 0.015, 0.027",\
|
||||
"0.009, 0.015, 0.027");
|
||||
values("0.009, 0.015, 0.021",\
|
||||
"0.009, 0.015, 0.021",\
|
||||
"0.009, 0.015, 0.021");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.009, 0.015",\
|
||||
|
|
@ -129,10 +129,10 @@ cell (sram_2_16_1_freepdk45){
|
|||
internal_power(){
|
||||
when : "!OEb & !clk";
|
||||
rise_power(scalar){
|
||||
values("0.031198");
|
||||
values("0.036300681");
|
||||
}
|
||||
fall_power(scalar){
|
||||
values("0.031252");
|
||||
values("0.041472985");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
|
|
@ -140,24 +140,24 @@ cell (sram_2_16_1_freepdk45){
|
|||
related_pin : "clk";
|
||||
timing_type : falling_edge;
|
||||
cell_rise(CELL_TABLE) {
|
||||
values("0.046, 0.047, 0.054",\
|
||||
"0.047, 0.047, 0.054",\
|
||||
"0.052, 0.052, 0.059");
|
||||
values("0.054, 0.055, 0.061",\
|
||||
"0.055, 0.055, 0.062",\
|
||||
"0.06, 0.061, 0.067");
|
||||
}
|
||||
cell_fall(CELL_TABLE) {
|
||||
values("0.132, 0.133, 0.142",\
|
||||
"0.133, 0.134, 0.142",\
|
||||
"0.138, 0.139, 0.147");
|
||||
values("0.519, 0.52, 0.529",\
|
||||
"0.519, 0.52, 0.53",\
|
||||
"0.525, 0.526, 0.535");
|
||||
}
|
||||
rise_transition(CELL_TABLE) {
|
||||
values("0.014, 0.015, 0.027",\
|
||||
"0.014, 0.015, 0.027",\
|
||||
"0.014, 0.015, 0.027");
|
||||
values("0.013, 0.014, 0.026",\
|
||||
"0.013, 0.014, 0.026",\
|
||||
"0.013, 0.015, 0.026");
|
||||
}
|
||||
fall_transition(CELL_TABLE) {
|
||||
values("0.018, 0.02, 0.036",\
|
||||
"0.019, 0.02, 0.036",\
|
||||
"0.019, 0.02, 0.036");
|
||||
values("0.027, 0.029, 0.043",\
|
||||
"0.027, 0.029, 0.043",\
|
||||
"0.027, 0.029, 0.043");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -174,9 +174,9 @@ cell (sram_2_16_1_freepdk45){
|
|||
timing_type : setup_rising;
|
||||
related_pin : "clk";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.015, 0.027",\
|
||||
"0.009, 0.015, 0.027",\
|
||||
"0.009, 0.015, 0.027");
|
||||
values("0.009, 0.015, 0.021",\
|
||||
"0.009, 0.015, 0.021",\
|
||||
"0.009, 0.015, 0.021");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.009, 0.015",\
|
||||
|
|
@ -208,9 +208,9 @@ cell (sram_2_16_1_freepdk45){
|
|||
timing_type : setup_rising;
|
||||
related_pin : "clk";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.015, 0.027",\
|
||||
"0.009, 0.015, 0.027",\
|
||||
"0.009, 0.015, 0.027");
|
||||
values("0.009, 0.015, 0.021",\
|
||||
"0.009, 0.015, 0.021",\
|
||||
"0.009, 0.015, 0.021");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.009, 0.015",\
|
||||
|
|
@ -241,9 +241,9 @@ cell (sram_2_16_1_freepdk45){
|
|||
timing_type : setup_rising;
|
||||
related_pin : "clk";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.015, 0.027",\
|
||||
"0.009, 0.015, 0.027",\
|
||||
"0.009, 0.015, 0.027");
|
||||
values("0.009, 0.015, 0.021",\
|
||||
"0.009, 0.015, 0.021",\
|
||||
"0.009, 0.015, 0.021");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.009, 0.015",\
|
||||
|
|
@ -274,9 +274,9 @@ cell (sram_2_16_1_freepdk45){
|
|||
timing_type : setup_rising;
|
||||
related_pin : "clk";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.015, 0.027",\
|
||||
"0.009, 0.015, 0.027",\
|
||||
"0.009, 0.015, 0.027");
|
||||
values("0.009, 0.015, 0.021",\
|
||||
"0.009, 0.015, 0.021",\
|
||||
"0.009, 0.015, 0.021");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.009, 0.015",\
|
||||
|
|
@ -308,20 +308,20 @@ cell (sram_2_16_1_freepdk45){
|
|||
timing_type :"min_pulse_width";
|
||||
related_pin : clk;
|
||||
rise_constraint(scalar) {
|
||||
values("0.1955");
|
||||
values("0.5275");
|
||||
}
|
||||
fall_constraint(scalar) {
|
||||
values("0.1955");
|
||||
values("0.5275");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
timing_type :"minimum_period";
|
||||
related_pin : clk;
|
||||
rise_constraint(scalar) {
|
||||
values("0.391");
|
||||
values("1.055");
|
||||
}
|
||||
fall_constraint(scalar) {
|
||||
values("0.391");
|
||||
values("1.055");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,329 +0,0 @@
|
|||
library (sram_2_16_1_freepdk45_lib){
|
||||
delay_model : "table_lookup";
|
||||
time_unit : "1ns" ;
|
||||
voltage_unit : "1v" ;
|
||||
current_unit : "1mA" ;
|
||||
resistance_unit : "1kohm" ;
|
||||
capacitive_load_unit(1 ,fF) ;
|
||||
leakage_power_unit : "1mW" ;
|
||||
pulling_resistance_unit :"1kohm" ;
|
||||
operating_conditions(TT){
|
||||
voltage : 1.0 ;
|
||||
temperature : 25.000 ;
|
||||
}
|
||||
|
||||
input_threshold_pct_fall : 50.0 ;
|
||||
output_threshold_pct_fall : 50.0 ;
|
||||
input_threshold_pct_rise : 50.0 ;
|
||||
output_threshold_pct_rise : 50.0 ;
|
||||
slew_lower_threshold_pct_fall : 10.0 ;
|
||||
slew_upper_threshold_pct_fall : 90.0 ;
|
||||
slew_lower_threshold_pct_rise : 10.0 ;
|
||||
slew_upper_threshold_pct_rise : 90.0 ;
|
||||
|
||||
default_cell_leakage_power : 0.0 ;
|
||||
default_leakage_power_density : 0.0 ;
|
||||
default_input_pin_cap : 1.0 ;
|
||||
default_inout_pin_cap : 1.0 ;
|
||||
default_output_pin_cap : 0.0 ;
|
||||
default_max_transition : 0.5 ;
|
||||
default_fanout_load : 1.0 ;
|
||||
default_max_fanout : 4.0 ;
|
||||
default_connection_class : universal ;
|
||||
|
||||
lu_table_template(CELL_TABLE){
|
||||
variable_1 : input_net_transition;
|
||||
variable_2 : total_output_net_capacitance;
|
||||
index_1("0.00125, 0.005, 0.04");
|
||||
index_2("0.052275, 0.2091, 1.6728");
|
||||
}
|
||||
|
||||
lu_table_template(CONSTRAINT_TABLE){
|
||||
variable_1 : related_pin_transition;
|
||||
variable_2 : constrained_pin_transition;
|
||||
index_1("0.00125, 0.005, 0.04");
|
||||
index_2("0.00125, 0.005, 0.04");
|
||||
}
|
||||
|
||||
default_operating_conditions : TT;
|
||||
|
||||
|
||||
type (DATA){
|
||||
base_type : array;
|
||||
data_type : bit;
|
||||
bit_width : 2;
|
||||
bit_from : 0;
|
||||
bit_to : 1;
|
||||
}
|
||||
|
||||
type (ADDR){
|
||||
base_type : array;
|
||||
data_type : bit;
|
||||
bit_width : 4;
|
||||
bit_from : 0;
|
||||
bit_to : 3;
|
||||
}
|
||||
|
||||
cell (sram_2_16_1_freepdk45){
|
||||
memory(){
|
||||
type : ram;
|
||||
address_width : 4;
|
||||
word_width : 2;
|
||||
}
|
||||
interface_timing : true;
|
||||
dont_use : true;
|
||||
map_only : true;
|
||||
dont_touch : true;
|
||||
area : 0.023625;
|
||||
|
||||
bus(DATA){
|
||||
bus_type : DATA;
|
||||
direction : inout;
|
||||
max_capacitance : 1.6728;
|
||||
three_state : "!OEb & !clk";
|
||||
memory_write(){
|
||||
address : ADDR;
|
||||
clocked_on : clk;
|
||||
}
|
||||
memory_read(){
|
||||
address : ADDR;
|
||||
}
|
||||
pin(DATA[1:0]){
|
||||
internal_power(){
|
||||
when : "OEb & !clk";
|
||||
rise_power(scalar){
|
||||
values("0");
|
||||
}
|
||||
fall_power(scalar){
|
||||
values("0");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
timing_type : setup_rising;
|
||||
related_pin : "clk";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
timing_type : hold_rising;
|
||||
related_pin : "clk";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001");
|
||||
}
|
||||
}
|
||||
internal_power(){
|
||||
when : "!OEb & !clk";
|
||||
rise_power(scalar){
|
||||
values("0");
|
||||
}
|
||||
fall_power(scalar){
|
||||
values("0");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
timing_sense : non_unate;
|
||||
related_pin : "clk";
|
||||
timing_type : falling_edge;
|
||||
cell_rise(CELL_TABLE) {
|
||||
values("0.123, 0.124, 0.133",\
|
||||
"0.123, 0.124, 0.133",\
|
||||
"0.123, 0.124, 0.133");
|
||||
}
|
||||
cell_fall(CELL_TABLE) {
|
||||
values("0.123, 0.124, 0.133",\
|
||||
"0.123, 0.124, 0.133",\
|
||||
"0.123, 0.124, 0.133");
|
||||
}
|
||||
rise_transition(CELL_TABLE) {
|
||||
values("0.006, 0.007, 0.018",\
|
||||
"0.006, 0.007, 0.018",\
|
||||
"0.006, 0.007, 0.018");
|
||||
}
|
||||
fall_transition(CELL_TABLE) {
|
||||
values("0.006, 0.007, 0.018",\
|
||||
"0.006, 0.007, 0.018",\
|
||||
"0.006, 0.007, 0.018");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bus(ADDR){
|
||||
bus_type : ADDR;
|
||||
direction : input;
|
||||
capacitance : 0.2091;
|
||||
max_transition : 0.04;
|
||||
fanout_load : 1.000000;
|
||||
pin(ADDR[3:0]){
|
||||
timing(){
|
||||
timing_type : setup_rising;
|
||||
related_pin : "clk";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
timing_type : hold_rising;
|
||||
related_pin : "clk";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pin(CSb){
|
||||
direction : input;
|
||||
capacitance : 0.2091;
|
||||
timing(){
|
||||
timing_type : setup_rising;
|
||||
related_pin : "clk";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
timing_type : hold_rising;
|
||||
related_pin : "clk";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pin(OEb){
|
||||
direction : input;
|
||||
capacitance : 0.2091;
|
||||
timing(){
|
||||
timing_type : setup_rising;
|
||||
related_pin : "clk";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
timing_type : hold_rising;
|
||||
related_pin : "clk";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pin(WEb){
|
||||
direction : input;
|
||||
capacitance : 0.2091;
|
||||
timing(){
|
||||
timing_type : setup_rising;
|
||||
related_pin : "clk";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
timing_type : hold_rising;
|
||||
related_pin : "clk";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pin(clk){
|
||||
clock : true;
|
||||
direction : input;
|
||||
capacitance : 0.2091;
|
||||
timing(){
|
||||
timing_type :"min_pulse_width";
|
||||
related_pin : clk;
|
||||
rise_constraint(scalar) {
|
||||
values("0.0");
|
||||
}
|
||||
fall_constraint(scalar) {
|
||||
values("0.0");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
timing_type :"minimum_period";
|
||||
related_pin : clk;
|
||||
rise_constraint(scalar) {
|
||||
values("0.0");
|
||||
}
|
||||
fall_constraint(scalar) {
|
||||
values("0.0");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -7,11 +7,11 @@ UNITS
|
|||
END UNITS
|
||||
SITE MacroSite
|
||||
CLASS Core ;
|
||||
SIZE 2250.0 by 1200.0 ;
|
||||
SIZE 277800.0 by 440700.0 ;
|
||||
END MacroSite
|
||||
MACRO sram_2_16_1_scn3me_subm
|
||||
CLASS BLOCK ;
|
||||
SIZE 2250.0 BY 1200.0 ;
|
||||
SIZE 277800.0 BY 440700.0 ;
|
||||
SYMMETRY X Y R90 ;
|
||||
SITE MacroSite ;
|
||||
PIN DATA[0]
|
||||
|
|
@ -577,14 +577,14 @@ MACRO sram_2_16_1_scn3me_subm
|
|||
RECT 127050.0 109650.0 122100.0 110550.0 ;
|
||||
RECT 130050.0 118350.0 105450.0 119250.0 ;
|
||||
RECT 127050.0 132150.0 102450.0 133050.0 ;
|
||||
RECT 111450.0 93750.0 94500.0 94650.0 ;
|
||||
RECT 108450.0 96450.0 97500.0 97350.0 ;
|
||||
RECT 105450.0 111150.0 94500.0 112050.0 ;
|
||||
RECT 108450.0 108450.0 97500.0 109350.0 ;
|
||||
RECT 111450.0 121350.0 94500.0 122250.0 ;
|
||||
RECT 102450.0 124050.0 97500.0 124950.0 ;
|
||||
RECT 105450.0 138750.0 94500.0 139650.0 ;
|
||||
RECT 102450.0 136050.0 97500.0 136950.0 ;
|
||||
RECT 111450.0 96450.0 97500.0 97350.0 ;
|
||||
RECT 108450.0 93750.0 94500.0 94650.0 ;
|
||||
RECT 105450.0 108450.0 97500.0 109350.0 ;
|
||||
RECT 108450.0 111150.0 94500.0 112050.0 ;
|
||||
RECT 111450.0 124050.0 97500.0 124950.0 ;
|
||||
RECT 102450.0 121350.0 94500.0 122250.0 ;
|
||||
RECT 105450.0 136050.0 97500.0 136950.0 ;
|
||||
RECT 102450.0 138750.0 94500.0 139650.0 ;
|
||||
RECT 88050.0 96450.0 87150.0 97350.0 ;
|
||||
RECT 88050.0 95250.0 87150.0 96150.0 ;
|
||||
RECT 92100.0 96450.0 87600.0 97350.0 ;
|
||||
|
|
@ -865,14 +865,14 @@ MACRO sram_2_16_1_scn3me_subm
|
|||
RECT 104850.0 118200.0 106050.0 119400.0 ;
|
||||
RECT 126450.0 132000.0 127650.0 133200.0 ;
|
||||
RECT 101850.0 132000.0 103050.0 133200.0 ;
|
||||
RECT 110850.0 93600.0 112050.0 94800.0 ;
|
||||
RECT 107850.0 96300.0 109050.0 97500.0 ;
|
||||
RECT 104850.0 111000.0 106050.0 112200.0 ;
|
||||
RECT 107850.0 108300.0 109050.0 109500.0 ;
|
||||
RECT 110850.0 121200.0 112050.0 122400.0 ;
|
||||
RECT 101850.0 123900.0 103050.0 125100.0 ;
|
||||
RECT 104850.0 138600.0 106050.0 139800.0 ;
|
||||
RECT 101850.0 135900.0 103050.0 137100.0 ;
|
||||
RECT 110850.0 96300.0 112050.0 97500.0 ;
|
||||
RECT 107850.0 93600.0 109050.0 94800.0 ;
|
||||
RECT 104850.0 108300.0 106050.0 109500.0 ;
|
||||
RECT 107850.0 111000.0 109050.0 112200.0 ;
|
||||
RECT 110850.0 123900.0 112050.0 125100.0 ;
|
||||
RECT 101850.0 121200.0 103050.0 122400.0 ;
|
||||
RECT 104850.0 135900.0 106050.0 137100.0 ;
|
||||
RECT 101850.0 138600.0 103050.0 139800.0 ;
|
||||
RECT 79650.0 95250.0 75900.0 96150.0 ;
|
||||
RECT 79650.0 109650.0 75900.0 110550.0 ;
|
||||
RECT 79650.0 122850.0 75900.0 123750.0 ;
|
||||
|
|
@ -896,14 +896,14 @@ MACRO sram_2_16_1_scn3me_subm
|
|||
RECT 127050.0 164850.0 122100.0 165750.0 ;
|
||||
RECT 130050.0 173550.0 105450.0 174450.0 ;
|
||||
RECT 127050.0 187350.0 102450.0 188250.0 ;
|
||||
RECT 111450.0 148950.0 94500.0 149850.0 ;
|
||||
RECT 108450.0 151650.0 97500.0 152550.0 ;
|
||||
RECT 105450.0 166350.0 94500.0 167250.0 ;
|
||||
RECT 108450.0 163650.0 97500.0 164550.0 ;
|
||||
RECT 111450.0 176550.0 94500.0 177450.0 ;
|
||||
RECT 102450.0 179250.0 97500.0 180150.0 ;
|
||||
RECT 105450.0 193950.0 94500.0 194850.0 ;
|
||||
RECT 102450.0 191250.0 97500.0 192150.0 ;
|
||||
RECT 111450.0 151650.0 97500.0 152550.0 ;
|
||||
RECT 108450.0 148950.0 94500.0 149850.0 ;
|
||||
RECT 105450.0 163650.0 97500.0 164550.0 ;
|
||||
RECT 108450.0 166350.0 94500.0 167250.0 ;
|
||||
RECT 111450.0 179250.0 97500.0 180150.0 ;
|
||||
RECT 102450.0 176550.0 94500.0 177450.0 ;
|
||||
RECT 105450.0 191250.0 97500.0 192150.0 ;
|
||||
RECT 102450.0 193950.0 94500.0 194850.0 ;
|
||||
RECT 88050.0 151650.0 87150.0 152550.0 ;
|
||||
RECT 88050.0 150450.0 87150.0 151350.0 ;
|
||||
RECT 92100.0 151650.0 87600.0 152550.0 ;
|
||||
|
|
@ -1184,14 +1184,14 @@ MACRO sram_2_16_1_scn3me_subm
|
|||
RECT 104850.0 173400.0 106050.0 174600.0 ;
|
||||
RECT 126450.0 187200.0 127650.0 188400.0 ;
|
||||
RECT 101850.0 187200.0 103050.0 188400.0 ;
|
||||
RECT 110850.0 148800.0 112050.0 150000.0 ;
|
||||
RECT 107850.0 151500.0 109050.0 152700.0 ;
|
||||
RECT 104850.0 166200.0 106050.0 167400.0 ;
|
||||
RECT 107850.0 163500.0 109050.0 164700.0 ;
|
||||
RECT 110850.0 176400.0 112050.0 177600.0 ;
|
||||
RECT 101850.0 179100.0 103050.0 180300.0 ;
|
||||
RECT 104850.0 193800.0 106050.0 195000.0 ;
|
||||
RECT 101850.0 191100.0 103050.0 192300.0 ;
|
||||
RECT 110850.0 151500.0 112050.0 152700.0 ;
|
||||
RECT 107850.0 148800.0 109050.0 150000.0 ;
|
||||
RECT 104850.0 163500.0 106050.0 164700.0 ;
|
||||
RECT 107850.0 166200.0 109050.0 167400.0 ;
|
||||
RECT 110850.0 179100.0 112050.0 180300.0 ;
|
||||
RECT 101850.0 176400.0 103050.0 177600.0 ;
|
||||
RECT 104850.0 191100.0 106050.0 192300.0 ;
|
||||
RECT 101850.0 193800.0 103050.0 195000.0 ;
|
||||
RECT 79650.0 150450.0 75900.0 151350.0 ;
|
||||
RECT 79650.0 164850.0 75900.0 165750.0 ;
|
||||
RECT 79650.0 178050.0 75900.0 178950.0 ;
|
||||
|
|
@ -4105,9 +4105,11 @@ MACRO sram_2_16_1_scn3me_subm
|
|||
RECT 16050.0 358350.0 15150.0 359250.0 ;
|
||||
RECT 8850.0 353400.0 7950.0 363000.0 ;
|
||||
RECT 22650.0 353400.0 21750.0 363000.0 ;
|
||||
RECT 22650.0 396900.0 16800.0 397800.0 ;
|
||||
RECT 22650.0 420300.0 16800.0 421200.0 ;
|
||||
RECT 22200.0 427650.0 16800.0 428550.0 ;
|
||||
RECT 22650.0 499050.0 21750.0 430200.0 ;
|
||||
RECT 21750.0 397050.0 17400.0 397950.0 ;
|
||||
RECT 21750.0 420450.0 17400.0 421350.0 ;
|
||||
RECT 22650.0 371550.0 16800.0 372450.0 ;
|
||||
RECT 16800.0 371550.0 6600.0 372450.0 ;
|
||||
RECT 4500.0 408600.0 16800.0 409500.0 ;
|
||||
RECT 4500.0 381000.0 16800.0 381900.0 ;
|
||||
RECT 29250.0 397800.0 28350.0 410400.0 ;
|
||||
|
|
@ -4148,11 +4150,11 @@ MACRO sram_2_16_1_scn3me_subm
|
|||
RECT 32550.0 398400.0 33750.0 399600.0 ;
|
||||
RECT 32550.0 398400.0 33750.0 399600.0 ;
|
||||
RECT 32550.0 396000.0 33750.0 397200.0 ;
|
||||
RECT 21750.0 430950.0 22650.0 431850.0 ;
|
||||
RECT 49350.0 430950.0 50250.0 431850.0 ;
|
||||
RECT 21750.0 429600.0 22650.0 431400.0 ;
|
||||
RECT 22200.0 430950.0 49800.0 431850.0 ;
|
||||
RECT 49350.0 429600.0 50250.0 431400.0 ;
|
||||
RECT 21750.0 498150.0 22650.0 499050.0 ;
|
||||
RECT 49350.0 498150.0 50250.0 499050.0 ;
|
||||
RECT 21750.0 496800.0 22650.0 498600.0 ;
|
||||
RECT 22200.0 498150.0 49800.0 499050.0 ;
|
||||
RECT 49350.0 496800.0 50250.0 498600.0 ;
|
||||
RECT 37950.0 417000.0 36000.0 418200.0 ;
|
||||
RECT 49800.0 417000.0 47850.0 418200.0 ;
|
||||
RECT 48450.0 412200.0 50250.0 413400.0 ;
|
||||
|
|
@ -4194,6 +4196,279 @@ MACRO sram_2_16_1_scn3me_subm
|
|||
RECT 36450.0 420000.0 35550.0 429600.0 ;
|
||||
RECT 50250.0 420000.0 49350.0 429600.0 ;
|
||||
RECT 42600.0 422400.0 43800.0 423600.0 ;
|
||||
RECT 37950.0 436200.0 36000.0 437400.0 ;
|
||||
RECT 49800.0 436200.0 47850.0 437400.0 ;
|
||||
RECT 48450.0 431400.0 50250.0 432600.0 ;
|
||||
RECT 39150.0 431400.0 35550.0 432600.0 ;
|
||||
RECT 48450.0 434100.0 39150.0 435000.0 ;
|
||||
RECT 39150.0 431400.0 37950.0 432600.0 ;
|
||||
RECT 39150.0 433800.0 37950.0 435000.0 ;
|
||||
RECT 39150.0 433800.0 37950.0 435000.0 ;
|
||||
RECT 39150.0 431400.0 37950.0 432600.0 ;
|
||||
RECT 48450.0 431400.0 47250.0 432600.0 ;
|
||||
RECT 48450.0 433800.0 47250.0 435000.0 ;
|
||||
RECT 48450.0 433800.0 47250.0 435000.0 ;
|
||||
RECT 48450.0 431400.0 47250.0 432600.0 ;
|
||||
RECT 38550.0 436200.0 37350.0 437400.0 ;
|
||||
RECT 48450.0 436200.0 47250.0 437400.0 ;
|
||||
RECT 43800.0 432000.0 42600.0 433200.0 ;
|
||||
RECT 43800.0 432000.0 42600.0 433200.0 ;
|
||||
RECT 43650.0 434550.0 42750.0 435450.0 ;
|
||||
RECT 36450.0 429600.0 35550.0 439200.0 ;
|
||||
RECT 50250.0 429600.0 49350.0 439200.0 ;
|
||||
RECT 42600.0 432000.0 43800.0 433200.0 ;
|
||||
RECT 37950.0 445800.0 36000.0 447000.0 ;
|
||||
RECT 49800.0 445800.0 47850.0 447000.0 ;
|
||||
RECT 48450.0 441000.0 50250.0 442200.0 ;
|
||||
RECT 39150.0 441000.0 35550.0 442200.0 ;
|
||||
RECT 48450.0 443700.0 39150.0 444600.0 ;
|
||||
RECT 39150.0 441000.0 37950.0 442200.0 ;
|
||||
RECT 39150.0 443400.0 37950.0 444600.0 ;
|
||||
RECT 39150.0 443400.0 37950.0 444600.0 ;
|
||||
RECT 39150.0 441000.0 37950.0 442200.0 ;
|
||||
RECT 48450.0 441000.0 47250.0 442200.0 ;
|
||||
RECT 48450.0 443400.0 47250.0 444600.0 ;
|
||||
RECT 48450.0 443400.0 47250.0 444600.0 ;
|
||||
RECT 48450.0 441000.0 47250.0 442200.0 ;
|
||||
RECT 38550.0 445800.0 37350.0 447000.0 ;
|
||||
RECT 48450.0 445800.0 47250.0 447000.0 ;
|
||||
RECT 43800.0 441600.0 42600.0 442800.0 ;
|
||||
RECT 43800.0 441600.0 42600.0 442800.0 ;
|
||||
RECT 43650.0 444150.0 42750.0 445050.0 ;
|
||||
RECT 36450.0 439200.0 35550.0 448800.0 ;
|
||||
RECT 50250.0 439200.0 49350.0 448800.0 ;
|
||||
RECT 42600.0 441600.0 43800.0 442800.0 ;
|
||||
RECT 37950.0 455400.0 36000.0 456600.0 ;
|
||||
RECT 49800.0 455400.0 47850.0 456600.0 ;
|
||||
RECT 48450.0 450600.0 50250.0 451800.0 ;
|
||||
RECT 39150.0 450600.0 35550.0 451800.0 ;
|
||||
RECT 48450.0 453300.0 39150.0 454200.0 ;
|
||||
RECT 39150.0 450600.0 37950.0 451800.0 ;
|
||||
RECT 39150.0 453000.0 37950.0 454200.0 ;
|
||||
RECT 39150.0 453000.0 37950.0 454200.0 ;
|
||||
RECT 39150.0 450600.0 37950.0 451800.0 ;
|
||||
RECT 48450.0 450600.0 47250.0 451800.0 ;
|
||||
RECT 48450.0 453000.0 47250.0 454200.0 ;
|
||||
RECT 48450.0 453000.0 47250.0 454200.0 ;
|
||||
RECT 48450.0 450600.0 47250.0 451800.0 ;
|
||||
RECT 38550.0 455400.0 37350.0 456600.0 ;
|
||||
RECT 48450.0 455400.0 47250.0 456600.0 ;
|
||||
RECT 43800.0 451200.0 42600.0 452400.0 ;
|
||||
RECT 43800.0 451200.0 42600.0 452400.0 ;
|
||||
RECT 43650.0 453750.0 42750.0 454650.0 ;
|
||||
RECT 36450.0 448800.0 35550.0 458400.0 ;
|
||||
RECT 50250.0 448800.0 49350.0 458400.0 ;
|
||||
RECT 42600.0 451200.0 43800.0 452400.0 ;
|
||||
RECT 37950.0 465000.0 36000.0 466200.0 ;
|
||||
RECT 49800.0 465000.0 47850.0 466200.0 ;
|
||||
RECT 48450.0 460200.0 50250.0 461400.0 ;
|
||||
RECT 39150.0 460200.0 35550.0 461400.0 ;
|
||||
RECT 48450.0 462900.0 39150.0 463800.0 ;
|
||||
RECT 39150.0 460200.0 37950.0 461400.0 ;
|
||||
RECT 39150.0 462600.0 37950.0 463800.0 ;
|
||||
RECT 39150.0 462600.0 37950.0 463800.0 ;
|
||||
RECT 39150.0 460200.0 37950.0 461400.0 ;
|
||||
RECT 48450.0 460200.0 47250.0 461400.0 ;
|
||||
RECT 48450.0 462600.0 47250.0 463800.0 ;
|
||||
RECT 48450.0 462600.0 47250.0 463800.0 ;
|
||||
RECT 48450.0 460200.0 47250.0 461400.0 ;
|
||||
RECT 38550.0 465000.0 37350.0 466200.0 ;
|
||||
RECT 48450.0 465000.0 47250.0 466200.0 ;
|
||||
RECT 43800.0 460800.0 42600.0 462000.0 ;
|
||||
RECT 43800.0 460800.0 42600.0 462000.0 ;
|
||||
RECT 43650.0 463350.0 42750.0 464250.0 ;
|
||||
RECT 36450.0 458400.0 35550.0 468000.0 ;
|
||||
RECT 50250.0 458400.0 49350.0 468000.0 ;
|
||||
RECT 42600.0 460800.0 43800.0 462000.0 ;
|
||||
RECT 37950.0 474600.0 36000.0 475800.0 ;
|
||||
RECT 49800.0 474600.0 47850.0 475800.0 ;
|
||||
RECT 48450.0 469800.0 50250.0 471000.0 ;
|
||||
RECT 39150.0 469800.0 35550.0 471000.0 ;
|
||||
RECT 48450.0 472500.0 39150.0 473400.0 ;
|
||||
RECT 39150.0 469800.0 37950.0 471000.0 ;
|
||||
RECT 39150.0 472200.0 37950.0 473400.0 ;
|
||||
RECT 39150.0 472200.0 37950.0 473400.0 ;
|
||||
RECT 39150.0 469800.0 37950.0 471000.0 ;
|
||||
RECT 48450.0 469800.0 47250.0 471000.0 ;
|
||||
RECT 48450.0 472200.0 47250.0 473400.0 ;
|
||||
RECT 48450.0 472200.0 47250.0 473400.0 ;
|
||||
RECT 48450.0 469800.0 47250.0 471000.0 ;
|
||||
RECT 38550.0 474600.0 37350.0 475800.0 ;
|
||||
RECT 48450.0 474600.0 47250.0 475800.0 ;
|
||||
RECT 43800.0 470400.0 42600.0 471600.0 ;
|
||||
RECT 43800.0 470400.0 42600.0 471600.0 ;
|
||||
RECT 43650.0 472950.0 42750.0 473850.0 ;
|
||||
RECT 36450.0 468000.0 35550.0 477600.0 ;
|
||||
RECT 50250.0 468000.0 49350.0 477600.0 ;
|
||||
RECT 42600.0 470400.0 43800.0 471600.0 ;
|
||||
RECT 37950.0 484200.0 36000.0 485400.0 ;
|
||||
RECT 49800.0 484200.0 47850.0 485400.0 ;
|
||||
RECT 48450.0 479400.0 50250.0 480600.0 ;
|
||||
RECT 39150.0 479400.0 35550.0 480600.0 ;
|
||||
RECT 48450.0 482100.0 39150.0 483000.0 ;
|
||||
RECT 39150.0 479400.0 37950.0 480600.0 ;
|
||||
RECT 39150.0 481800.0 37950.0 483000.0 ;
|
||||
RECT 39150.0 481800.0 37950.0 483000.0 ;
|
||||
RECT 39150.0 479400.0 37950.0 480600.0 ;
|
||||
RECT 48450.0 479400.0 47250.0 480600.0 ;
|
||||
RECT 48450.0 481800.0 47250.0 483000.0 ;
|
||||
RECT 48450.0 481800.0 47250.0 483000.0 ;
|
||||
RECT 48450.0 479400.0 47250.0 480600.0 ;
|
||||
RECT 38550.0 484200.0 37350.0 485400.0 ;
|
||||
RECT 48450.0 484200.0 47250.0 485400.0 ;
|
||||
RECT 43800.0 480000.0 42600.0 481200.0 ;
|
||||
RECT 43800.0 480000.0 42600.0 481200.0 ;
|
||||
RECT 43650.0 482550.0 42750.0 483450.0 ;
|
||||
RECT 36450.0 477600.0 35550.0 487200.0 ;
|
||||
RECT 50250.0 477600.0 49350.0 487200.0 ;
|
||||
RECT 42600.0 480000.0 43800.0 481200.0 ;
|
||||
RECT 37950.0 493800.0 36000.0 495000.0 ;
|
||||
RECT 49800.0 493800.0 47850.0 495000.0 ;
|
||||
RECT 48450.0 489000.0 50250.0 490200.0 ;
|
||||
RECT 39150.0 489000.0 35550.0 490200.0 ;
|
||||
RECT 48450.0 491700.0 39150.0 492600.0 ;
|
||||
RECT 39150.0 489000.0 37950.0 490200.0 ;
|
||||
RECT 39150.0 491400.0 37950.0 492600.0 ;
|
||||
RECT 39150.0 491400.0 37950.0 492600.0 ;
|
||||
RECT 39150.0 489000.0 37950.0 490200.0 ;
|
||||
RECT 48450.0 489000.0 47250.0 490200.0 ;
|
||||
RECT 48450.0 491400.0 47250.0 492600.0 ;
|
||||
RECT 48450.0 491400.0 47250.0 492600.0 ;
|
||||
RECT 48450.0 489000.0 47250.0 490200.0 ;
|
||||
RECT 38550.0 493800.0 37350.0 495000.0 ;
|
||||
RECT 48450.0 493800.0 47250.0 495000.0 ;
|
||||
RECT 43800.0 489600.0 42600.0 490800.0 ;
|
||||
RECT 43800.0 489600.0 42600.0 490800.0 ;
|
||||
RECT 43650.0 492150.0 42750.0 493050.0 ;
|
||||
RECT 36450.0 487200.0 35550.0 496800.0 ;
|
||||
RECT 50250.0 487200.0 49350.0 496800.0 ;
|
||||
RECT 42600.0 489600.0 43800.0 490800.0 ;
|
||||
RECT 34050.0 480600.0 36000.0 479400.0 ;
|
||||
RECT 22200.0 480600.0 24150.0 479400.0 ;
|
||||
RECT 23550.0 485400.0 21750.0 484200.0 ;
|
||||
RECT 32850.0 485400.0 36450.0 484200.0 ;
|
||||
RECT 23550.0 482700.0 32850.0 481800.0 ;
|
||||
RECT 32850.0 485400.0 34050.0 484200.0 ;
|
||||
RECT 32850.0 483000.0 34050.0 481800.0 ;
|
||||
RECT 32850.0 483000.0 34050.0 481800.0 ;
|
||||
RECT 32850.0 485400.0 34050.0 484200.0 ;
|
||||
RECT 23550.0 485400.0 24750.0 484200.0 ;
|
||||
RECT 23550.0 483000.0 24750.0 481800.0 ;
|
||||
RECT 23550.0 483000.0 24750.0 481800.0 ;
|
||||
RECT 23550.0 485400.0 24750.0 484200.0 ;
|
||||
RECT 33450.0 480600.0 34650.0 479400.0 ;
|
||||
RECT 23550.0 480600.0 24750.0 479400.0 ;
|
||||
RECT 28200.0 484800.0 29400.0 483600.0 ;
|
||||
RECT 28200.0 484800.0 29400.0 483600.0 ;
|
||||
RECT 28350.0 482250.0 29250.0 481350.0 ;
|
||||
RECT 35550.0 487200.0 36450.0 477600.0 ;
|
||||
RECT 21750.0 487200.0 22650.0 477600.0 ;
|
||||
RECT 28200.0 483600.0 29400.0 484800.0 ;
|
||||
RECT 34050.0 471000.0 36000.0 469800.0 ;
|
||||
RECT 22200.0 471000.0 24150.0 469800.0 ;
|
||||
RECT 23550.0 475800.0 21750.0 474600.0 ;
|
||||
RECT 32850.0 475800.0 36450.0 474600.0 ;
|
||||
RECT 23550.0 473100.0 32850.0 472200.0 ;
|
||||
RECT 32850.0 475800.0 34050.0 474600.0 ;
|
||||
RECT 32850.0 473400.0 34050.0 472200.0 ;
|
||||
RECT 32850.0 473400.0 34050.0 472200.0 ;
|
||||
RECT 32850.0 475800.0 34050.0 474600.0 ;
|
||||
RECT 23550.0 475800.0 24750.0 474600.0 ;
|
||||
RECT 23550.0 473400.0 24750.0 472200.0 ;
|
||||
RECT 23550.0 473400.0 24750.0 472200.0 ;
|
||||
RECT 23550.0 475800.0 24750.0 474600.0 ;
|
||||
RECT 33450.0 471000.0 34650.0 469800.0 ;
|
||||
RECT 23550.0 471000.0 24750.0 469800.0 ;
|
||||
RECT 28200.0 475200.0 29400.0 474000.0 ;
|
||||
RECT 28200.0 475200.0 29400.0 474000.0 ;
|
||||
RECT 28350.0 472650.0 29250.0 471750.0 ;
|
||||
RECT 35550.0 477600.0 36450.0 468000.0 ;
|
||||
RECT 21750.0 477600.0 22650.0 468000.0 ;
|
||||
RECT 28200.0 474000.0 29400.0 475200.0 ;
|
||||
RECT 34050.0 461400.0 36000.0 460200.0 ;
|
||||
RECT 22200.0 461400.0 24150.0 460200.0 ;
|
||||
RECT 23550.0 466200.0 21750.0 465000.0 ;
|
||||
RECT 32850.0 466200.0 36450.0 465000.0 ;
|
||||
RECT 23550.0 463500.0 32850.0 462600.0 ;
|
||||
RECT 32850.0 466200.0 34050.0 465000.0 ;
|
||||
RECT 32850.0 463800.0 34050.0 462600.0 ;
|
||||
RECT 32850.0 463800.0 34050.0 462600.0 ;
|
||||
RECT 32850.0 466200.0 34050.0 465000.0 ;
|
||||
RECT 23550.0 466200.0 24750.0 465000.0 ;
|
||||
RECT 23550.0 463800.0 24750.0 462600.0 ;
|
||||
RECT 23550.0 463800.0 24750.0 462600.0 ;
|
||||
RECT 23550.0 466200.0 24750.0 465000.0 ;
|
||||
RECT 33450.0 461400.0 34650.0 460200.0 ;
|
||||
RECT 23550.0 461400.0 24750.0 460200.0 ;
|
||||
RECT 28200.0 465600.0 29400.0 464400.0 ;
|
||||
RECT 28200.0 465600.0 29400.0 464400.0 ;
|
||||
RECT 28350.0 463050.0 29250.0 462150.0 ;
|
||||
RECT 35550.0 468000.0 36450.0 458400.0 ;
|
||||
RECT 21750.0 468000.0 22650.0 458400.0 ;
|
||||
RECT 28200.0 464400.0 29400.0 465600.0 ;
|
||||
RECT 34050.0 451800.0 36000.0 450600.0 ;
|
||||
RECT 22200.0 451800.0 24150.0 450600.0 ;
|
||||
RECT 23550.0 456600.0 21750.0 455400.0 ;
|
||||
RECT 32850.0 456600.0 36450.0 455400.0 ;
|
||||
RECT 23550.0 453900.0 32850.0 453000.0 ;
|
||||
RECT 32850.0 456600.0 34050.0 455400.0 ;
|
||||
RECT 32850.0 454200.0 34050.0 453000.0 ;
|
||||
RECT 32850.0 454200.0 34050.0 453000.0 ;
|
||||
RECT 32850.0 456600.0 34050.0 455400.0 ;
|
||||
RECT 23550.0 456600.0 24750.0 455400.0 ;
|
||||
RECT 23550.0 454200.0 24750.0 453000.0 ;
|
||||
RECT 23550.0 454200.0 24750.0 453000.0 ;
|
||||
RECT 23550.0 456600.0 24750.0 455400.0 ;
|
||||
RECT 33450.0 451800.0 34650.0 450600.0 ;
|
||||
RECT 23550.0 451800.0 24750.0 450600.0 ;
|
||||
RECT 28200.0 456000.0 29400.0 454800.0 ;
|
||||
RECT 28200.0 456000.0 29400.0 454800.0 ;
|
||||
RECT 28350.0 453450.0 29250.0 452550.0 ;
|
||||
RECT 35550.0 458400.0 36450.0 448800.0 ;
|
||||
RECT 21750.0 458400.0 22650.0 448800.0 ;
|
||||
RECT 28200.0 454800.0 29400.0 456000.0 ;
|
||||
RECT 34050.0 442200.0 36000.0 441000.0 ;
|
||||
RECT 22200.0 442200.0 24150.0 441000.0 ;
|
||||
RECT 23550.0 447000.0 21750.0 445800.0 ;
|
||||
RECT 32850.0 447000.0 36450.0 445800.0 ;
|
||||
RECT 23550.0 444300.0 32850.0 443400.0 ;
|
||||
RECT 32850.0 447000.0 34050.0 445800.0 ;
|
||||
RECT 32850.0 444600.0 34050.0 443400.0 ;
|
||||
RECT 32850.0 444600.0 34050.0 443400.0 ;
|
||||
RECT 32850.0 447000.0 34050.0 445800.0 ;
|
||||
RECT 23550.0 447000.0 24750.0 445800.0 ;
|
||||
RECT 23550.0 444600.0 24750.0 443400.0 ;
|
||||
RECT 23550.0 444600.0 24750.0 443400.0 ;
|
||||
RECT 23550.0 447000.0 24750.0 445800.0 ;
|
||||
RECT 33450.0 442200.0 34650.0 441000.0 ;
|
||||
RECT 23550.0 442200.0 24750.0 441000.0 ;
|
||||
RECT 28200.0 446400.0 29400.0 445200.0 ;
|
||||
RECT 28200.0 446400.0 29400.0 445200.0 ;
|
||||
RECT 28350.0 443850.0 29250.0 442950.0 ;
|
||||
RECT 35550.0 448800.0 36450.0 439200.0 ;
|
||||
RECT 21750.0 448800.0 22650.0 439200.0 ;
|
||||
RECT 28200.0 445200.0 29400.0 446400.0 ;
|
||||
RECT 34050.0 432600.0 36000.0 431400.0 ;
|
||||
RECT 22200.0 432600.0 24150.0 431400.0 ;
|
||||
RECT 23550.0 437400.0 21750.0 436200.0 ;
|
||||
RECT 32850.0 437400.0 36450.0 436200.0 ;
|
||||
RECT 23550.0 434700.0 32850.0 433800.0 ;
|
||||
RECT 32850.0 437400.0 34050.0 436200.0 ;
|
||||
RECT 32850.0 435000.0 34050.0 433800.0 ;
|
||||
RECT 32850.0 435000.0 34050.0 433800.0 ;
|
||||
RECT 32850.0 437400.0 34050.0 436200.0 ;
|
||||
RECT 23550.0 437400.0 24750.0 436200.0 ;
|
||||
RECT 23550.0 435000.0 24750.0 433800.0 ;
|
||||
RECT 23550.0 435000.0 24750.0 433800.0 ;
|
||||
RECT 23550.0 437400.0 24750.0 436200.0 ;
|
||||
RECT 33450.0 432600.0 34650.0 431400.0 ;
|
||||
RECT 23550.0 432600.0 24750.0 431400.0 ;
|
||||
RECT 28200.0 436800.0 29400.0 435600.0 ;
|
||||
RECT 28200.0 436800.0 29400.0 435600.0 ;
|
||||
RECT 28350.0 434250.0 29250.0 433350.0 ;
|
||||
RECT 35550.0 439200.0 36450.0 429600.0 ;
|
||||
RECT 21750.0 439200.0 22650.0 429600.0 ;
|
||||
RECT 28200.0 435600.0 29400.0 436800.0 ;
|
||||
RECT 34050.0 423000.0 36000.0 421800.0 ;
|
||||
RECT 22200.0 423000.0 24150.0 421800.0 ;
|
||||
RECT 23550.0 427800.0 21750.0 426600.0 ;
|
||||
|
|
@ -4237,25 +4512,26 @@ MACRO sram_2_16_1_scn3me_subm
|
|||
RECT 21750.0 420000.0 22650.0 410400.0 ;
|
||||
RECT 28200.0 416400.0 29400.0 417600.0 ;
|
||||
RECT 42600.0 415200.0 43800.0 416400.0 ;
|
||||
RECT 42600.0 424800.0 43800.0 426000.0 ;
|
||||
RECT 28200.0 423600.0 29400.0 424800.0 ;
|
||||
RECT 42600.0 453600.0 43800.0 454800.0 ;
|
||||
RECT 42600.0 492000.0 43800.0 493200.0 ;
|
||||
RECT 28200.0 452400.0 29400.0 453600.0 ;
|
||||
RECT 42600.0 412800.0 43800.0 414000.0 ;
|
||||
RECT 28350.0 410400.0 29250.0 414150.0 ;
|
||||
RECT 35550.0 410400.0 36450.0 429600.0 ;
|
||||
RECT 21750.0 410400.0 22650.0 429600.0 ;
|
||||
RECT 49350.0 410400.0 50250.0 429600.0 ;
|
||||
RECT 35550.0 410400.0 36450.0 496800.0 ;
|
||||
RECT 21750.0 410400.0 22650.0 496800.0 ;
|
||||
RECT 49350.0 410400.0 50250.0 496800.0 ;
|
||||
RECT 16800.0 395400.0 6600.0 381600.0 ;
|
||||
RECT 16800.0 395400.0 6600.0 409200.0 ;
|
||||
RECT 16800.0 423000.0 6600.0 409200.0 ;
|
||||
RECT 17400.0 396900.0 6000.0 398100.0 ;
|
||||
RECT 17400.0 420300.0 6000.0 421500.0 ;
|
||||
RECT 17400.0 408600.0 6000.0 409500.0 ;
|
||||
RECT 22650.0 396900.0 21450.0 398100.0 ;
|
||||
RECT 22650.0 420300.0 21450.0 421500.0 ;
|
||||
RECT 22650.0 410400.0 21450.0 411600.0 ;
|
||||
RECT 22650.0 370800.0 21450.0 372000.0 ;
|
||||
RECT 21600.0 427500.0 22800.0 428700.0 ;
|
||||
RECT 16200.0 427500.0 17400.0 428700.0 ;
|
||||
RECT 22350.0 396900.0 21150.0 398100.0 ;
|
||||
RECT 22350.0 420300.0 21150.0 421500.0 ;
|
||||
RECT 22200.0 410400.0 21000.0 411600.0 ;
|
||||
RECT 22800.0 370800.0 21600.0 372000.0 ;
|
||||
RECT 16200.0 371400.0 17400.0 372600.0 ;
|
||||
RECT 6000.0 371400.0 7200.0 372600.0 ;
|
||||
RECT 29400.0 397200.0 28200.0 398400.0 ;
|
||||
RECT 19350.0 383700.0 20550.0 384900.0 ;
|
||||
RECT 19350.0 375600.0 20550.0 376800.0 ;
|
||||
|
|
@ -4264,7 +4540,7 @@ MACRO sram_2_16_1_scn3me_subm
|
|||
RECT 29250.0 362400.0 28350.0 375750.0 ;
|
||||
RECT 4500.0 362400.0 3600.0 425250.0 ;
|
||||
RECT 36450.0 362400.0 35550.0 410400.0 ;
|
||||
RECT 22650.0 362400.0 21750.0 381600.0 ;
|
||||
RECT 22650.0 362400.0 21750.0 372000.0 ;
|
||||
RECT 50250.0 362400.0 49350.0 410400.0 ;
|
||||
RECT 43950.0 285750.0 42750.0 284550.0 ;
|
||||
RECT 43950.0 244800.0 42750.0 243600.0 ;
|
||||
|
|
@ -4461,14 +4737,14 @@ MACRO sram_2_16_1_scn3me_subm
|
|||
RECT 104850.0 118200.0 106050.0 119400.0 ;
|
||||
RECT 126450.0 132000.0 127650.0 133200.0 ;
|
||||
RECT 101850.0 132000.0 103050.0 133200.0 ;
|
||||
RECT 110850.0 93600.0 112050.0 94800.0 ;
|
||||
RECT 107850.0 96300.0 109050.0 97500.0 ;
|
||||
RECT 104850.0 111000.0 106050.0 112200.0 ;
|
||||
RECT 107850.0 108300.0 109050.0 109500.0 ;
|
||||
RECT 110850.0 121200.0 112050.0 122400.0 ;
|
||||
RECT 101850.0 123900.0 103050.0 125100.0 ;
|
||||
RECT 104850.0 138600.0 106050.0 139800.0 ;
|
||||
RECT 101850.0 135900.0 103050.0 137100.0 ;
|
||||
RECT 110850.0 96300.0 112050.0 97500.0 ;
|
||||
RECT 107850.0 93600.0 109050.0 94800.0 ;
|
||||
RECT 104850.0 108300.0 106050.0 109500.0 ;
|
||||
RECT 107850.0 111000.0 109050.0 112200.0 ;
|
||||
RECT 110850.0 123900.0 112050.0 125100.0 ;
|
||||
RECT 101850.0 121200.0 103050.0 122400.0 ;
|
||||
RECT 104850.0 135900.0 106050.0 137100.0 ;
|
||||
RECT 101850.0 138600.0 103050.0 139800.0 ;
|
||||
RECT 130500.0 89100.0 129600.0 142500.0 ;
|
||||
RECT 127500.0 89100.0 126600.0 142500.0 ;
|
||||
RECT 105900.0 144300.0 105000.0 197700.0 ;
|
||||
|
|
@ -4515,14 +4791,14 @@ MACRO sram_2_16_1_scn3me_subm
|
|||
RECT 104850.0 173400.0 106050.0 174600.0 ;
|
||||
RECT 126450.0 187200.0 127650.0 188400.0 ;
|
||||
RECT 101850.0 187200.0 103050.0 188400.0 ;
|
||||
RECT 110850.0 148800.0 112050.0 150000.0 ;
|
||||
RECT 107850.0 151500.0 109050.0 152700.0 ;
|
||||
RECT 104850.0 166200.0 106050.0 167400.0 ;
|
||||
RECT 107850.0 163500.0 109050.0 164700.0 ;
|
||||
RECT 110850.0 176400.0 112050.0 177600.0 ;
|
||||
RECT 101850.0 179100.0 103050.0 180300.0 ;
|
||||
RECT 104850.0 193800.0 106050.0 195000.0 ;
|
||||
RECT 101850.0 191100.0 103050.0 192300.0 ;
|
||||
RECT 110850.0 151500.0 112050.0 152700.0 ;
|
||||
RECT 107850.0 148800.0 109050.0 150000.0 ;
|
||||
RECT 104850.0 163500.0 106050.0 164700.0 ;
|
||||
RECT 107850.0 166200.0 109050.0 167400.0 ;
|
||||
RECT 110850.0 179100.0 112050.0 180300.0 ;
|
||||
RECT 101850.0 176400.0 103050.0 177600.0 ;
|
||||
RECT 104850.0 191100.0 106050.0 192300.0 ;
|
||||
RECT 101850.0 193800.0 103050.0 195000.0 ;
|
||||
RECT 130500.0 144300.0 129600.0 197700.0 ;
|
||||
RECT 127500.0 144300.0 126600.0 197700.0 ;
|
||||
RECT 80250.0 206850.0 81150.0 207750.0 ;
|
||||
|
|
@ -5006,6 +5282,7 @@ MACRO sram_2_16_1_scn3me_subm
|
|||
RECT 49800.0 292800.0 1.42108547152e-11 293700.0 ;
|
||||
RECT 49800.0 295500.0 1.42108547152e-11 296400.0 ;
|
||||
RECT 49800.0 300900.0 1.42108547152e-11 301800.0 ;
|
||||
RECT 43350.0 243750.0 36000.0 244650.0 ;
|
||||
RECT 33750.0 205350.0 32850.0 285150.0 ;
|
||||
RECT 49800.0 287400.0 47100.0 288300.0 ;
|
||||
RECT 38700.0 298200.0 36000.0 299100.0 ;
|
||||
|
|
@ -5071,25 +5348,51 @@ MACRO sram_2_16_1_scn3me_subm
|
|||
RECT 10800.0 288450.0 9600.0 287250.0 ;
|
||||
RECT 31200.0 263100.0 30000.0 261900.0 ;
|
||||
RECT 31200.0 288450.0 30000.0 287250.0 ;
|
||||
RECT 22650.0 372000.0 21750.0 427500.0 ;
|
||||
RECT 22650.0 381600.0 21750.0 384300.0 ;
|
||||
RECT 22650.0 384300.0 21750.0 428100.0 ;
|
||||
RECT 17250.0 425400.0 16350.0 428100.0 ;
|
||||
RECT 22650.0 372000.0 21750.0 430200.0 ;
|
||||
RECT 17250.0 372000.0 16350.0 425400.0 ;
|
||||
RECT 7050.0 372000.0 6150.0 425400.0 ;
|
||||
RECT 20400.0 376200.0 19500.0 384300.0 ;
|
||||
RECT 13650.0 376200.0 12750.0 381000.0 ;
|
||||
RECT 42750.0 415800.0 43650.0 423000.0 ;
|
||||
RECT 35550.0 424950.0 36450.0 425850.0 ;
|
||||
RECT 35550.0 426150.0 36450.0 427050.0 ;
|
||||
RECT 36000.0 424950.0 43200.0 425850.0 ;
|
||||
RECT 35550.0 425400.0 36450.0 426600.0 ;
|
||||
RECT 28800.0 426150.0 36000.0 427050.0 ;
|
||||
RECT 28350.0 417000.0 29250.0 424200.0 ;
|
||||
RECT 42750.0 423000.0 43650.0 432600.0 ;
|
||||
RECT 42750.0 432600.0 43650.0 442200.0 ;
|
||||
RECT 42750.0 442200.0 43650.0 451800.0 ;
|
||||
RECT 42750.0 454200.0 43650.0 461400.0 ;
|
||||
RECT 42750.0 461400.0 43650.0 471000.0 ;
|
||||
RECT 42750.0 471000.0 43650.0 480600.0 ;
|
||||
RECT 42750.0 480600.0 43650.0 490200.0 ;
|
||||
RECT 35550.0 492150.0 36450.0 493050.0 ;
|
||||
RECT 35550.0 483750.0 36450.0 484650.0 ;
|
||||
RECT 36000.0 492150.0 43200.0 493050.0 ;
|
||||
RECT 35550.0 484200.0 36450.0 492600.0 ;
|
||||
RECT 28800.0 483750.0 36000.0 484650.0 ;
|
||||
RECT 28350.0 474600.0 29250.0 484200.0 ;
|
||||
RECT 28350.0 465000.0 29250.0 474600.0 ;
|
||||
RECT 28350.0 455400.0 29250.0 465000.0 ;
|
||||
RECT 28350.0 445800.0 29250.0 453000.0 ;
|
||||
RECT 28350.0 436200.0 29250.0 445800.0 ;
|
||||
RECT 28350.0 426600.0 29250.0 436200.0 ;
|
||||
RECT 28350.0 417000.0 29250.0 426600.0 ;
|
||||
RECT 42600.0 422400.0 43800.0 423600.0 ;
|
||||
RECT 42600.0 432000.0 43800.0 433200.0 ;
|
||||
RECT 42600.0 441600.0 43800.0 442800.0 ;
|
||||
RECT 42600.0 451200.0 43800.0 452400.0 ;
|
||||
RECT 42600.0 460800.0 43800.0 462000.0 ;
|
||||
RECT 42600.0 470400.0 43800.0 471600.0 ;
|
||||
RECT 42600.0 480000.0 43800.0 481200.0 ;
|
||||
RECT 42600.0 489600.0 43800.0 490800.0 ;
|
||||
RECT 28200.0 483600.0 29400.0 484800.0 ;
|
||||
RECT 28200.0 474000.0 29400.0 475200.0 ;
|
||||
RECT 28200.0 464400.0 29400.0 465600.0 ;
|
||||
RECT 28200.0 454800.0 29400.0 456000.0 ;
|
||||
RECT 28200.0 445200.0 29400.0 446400.0 ;
|
||||
RECT 28200.0 435600.0 29400.0 436800.0 ;
|
||||
RECT 28200.0 426000.0 29400.0 427200.0 ;
|
||||
RECT 28200.0 416400.0 29400.0 417600.0 ;
|
||||
RECT 42600.0 415200.0 43800.0 416400.0 ;
|
||||
RECT 42600.0 424800.0 43800.0 426000.0 ;
|
||||
RECT 28200.0 423600.0 29400.0 424800.0 ;
|
||||
RECT 42600.0 453600.0 43800.0 454800.0 ;
|
||||
RECT 42600.0 492000.0 43800.0 493200.0 ;
|
||||
RECT 28200.0 452400.0 29400.0 453600.0 ;
|
||||
RECT 16800.0 395400.0 6600.0 381600.0 ;
|
||||
RECT 16800.0 395400.0 6600.0 409200.0 ;
|
||||
RECT 16800.0 423000.0 6600.0 409200.0 ;
|
||||
|
|
@ -5097,19 +5400,19 @@ MACRO sram_2_16_1_scn3me_subm
|
|||
RECT 10800.0 394800.0 9600.0 425400.0 ;
|
||||
RECT 17400.0 394800.0 16200.0 425400.0 ;
|
||||
RECT 7200.0 394800.0 6000.0 425400.0 ;
|
||||
RECT 22650.0 396900.0 21450.0 398100.0 ;
|
||||
RECT 22650.0 420300.0 21450.0 421500.0 ;
|
||||
RECT 22650.0 410400.0 21450.0 411600.0 ;
|
||||
RECT 22650.0 370800.0 21450.0 372000.0 ;
|
||||
RECT 21600.0 427500.0 22800.0 428700.0 ;
|
||||
RECT 16200.0 427500.0 17400.0 428700.0 ;
|
||||
RECT 22350.0 396900.0 21150.0 398100.0 ;
|
||||
RECT 22350.0 420300.0 21150.0 421500.0 ;
|
||||
RECT 22200.0 410400.0 21000.0 411600.0 ;
|
||||
RECT 22800.0 370800.0 21600.0 372000.0 ;
|
||||
RECT 16200.0 371400.0 17400.0 372600.0 ;
|
||||
RECT 6000.0 371400.0 7200.0 372600.0 ;
|
||||
RECT 19350.0 383700.0 20550.0 384900.0 ;
|
||||
RECT 19350.0 375600.0 20550.0 376800.0 ;
|
||||
RECT 12600.0 375600.0 13800.0 376800.0 ;
|
||||
RECT 43950.0 285750.0 42750.0 284550.0 ;
|
||||
RECT 43950.0 244800.0 42750.0 243600.0 ;
|
||||
RECT 43950.0 304650.0 42750.0 303450.0 ;
|
||||
RECT 43950.0 244800.0 42750.0 243600.0 ;
|
||||
RECT 36600.0 244800.0 35400.0 243600.0 ;
|
||||
RECT 36600.0 304650.0 35400.0 303450.0 ;
|
||||
RECT 33900.0 205950.0 32700.0 204750.0 ;
|
||||
RECT 29850.0 285750.0 28650.0 284550.0 ;
|
||||
RECT 27150.0 291150.0 25950.0 289950.0 ;
|
||||
|
|
@ -5202,7 +5505,7 @@ MACRO sram_2_16_1_scn3me_subm
|
|||
RECT 23550.0 262500.0 22050.0 295950.0 ;
|
||||
RECT 10950.0 262500.0 9450.0 287850.0 ;
|
||||
RECT 31350.0 262500.0 29850.0 287850.0 ;
|
||||
RECT 44100.0 244200.0 42600.0 304050.0 ;
|
||||
RECT 36750.0 244200.0 35250.0 304050.0 ;
|
||||
RECT 30750.0 304050.0 29250.0 327900.0 ;
|
||||
RECT 28050.0 301350.0 26550.0 330900.0 ;
|
||||
RECT 4200.0 203400.0 6000.0 205200.0 ;
|
||||
|
|
@ -5220,8 +5523,8 @@ MACRO sram_2_16_1_scn3me_subm
|
|||
RECT 11100.0 288750.0 9300.0 286950.0 ;
|
||||
RECT 31500.0 263400.0 29700.0 261600.0 ;
|
||||
RECT 31500.0 288750.0 29700.0 286950.0 ;
|
||||
RECT 44250.0 245100.0 42450.0 243300.0 ;
|
||||
RECT 44250.0 304950.0 42450.0 303150.0 ;
|
||||
RECT 36900.0 245100.0 35100.0 243300.0 ;
|
||||
RECT 36900.0 304950.0 35100.0 303150.0 ;
|
||||
RECT 30900.0 328800.0 29100.0 327000.0 ;
|
||||
RECT 30900.0 304950.0 29100.0 303150.0 ;
|
||||
RECT 28200.0 331800.0 26400.0 330000.0 ;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
library (sram_2_16_1_scn3me_subm_lib){
|
||||
library (sram_2_16_1_scn3me_subm_TT_50V_25C_lib){
|
||||
delay_model : "table_lookup";
|
||||
time_unit : "1ns" ;
|
||||
voltage_unit : "1v" ;
|
||||
|
|
@ -9,7 +9,7 @@ library (sram_2_16_1_scn3me_subm_lib){
|
|||
pulling_resistance_unit :"1kohm" ;
|
||||
operating_conditions(TT){
|
||||
voltage : 5.0 ;
|
||||
temperature : 25.000 ;
|
||||
temperature : 25;
|
||||
}
|
||||
|
||||
input_threshold_pct_fall : 50.0 ;
|
||||
|
|
@ -74,7 +74,7 @@ cell (sram_2_16_1_scn3me_subm){
|
|||
dont_use : true;
|
||||
map_only : true;
|
||||
dont_touch : true;
|
||||
area : 2.7;
|
||||
area : 122426.46;
|
||||
|
||||
bus(DATA){
|
||||
bus_type : DATA;
|
||||
|
|
@ -92,47 +92,47 @@ cell (sram_2_16_1_scn3me_subm){
|
|||
internal_power(){
|
||||
when : "OEb & !clk";
|
||||
rise_power(scalar){
|
||||
values("3.2612");
|
||||
values("11.756062");
|
||||
}
|
||||
fall_power(scalar){
|
||||
values("3.5985");
|
||||
values("7.1840422");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
timing_type : setup_rising;
|
||||
related_pin : "clk";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.082, 0.088, 0.186",\
|
||||
"0.082, 0.088, 0.186",\
|
||||
"0.082, 0.088, 0.186");
|
||||
values("0.076, 0.076, 0.149",\
|
||||
"0.076, 0.076, 0.149",\
|
||||
"0.076, 0.076, 0.149");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.021, 0.021, 0.027",\
|
||||
"0.021, 0.021, 0.027",\
|
||||
"0.021, 0.021, 0.027");
|
||||
values("0.039, 0.039, 0.027",\
|
||||
"0.039, 0.039, 0.027",\
|
||||
"0.039, 0.039, 0.027");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
timing_type : hold_rising;
|
||||
related_pin : "clk";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.015, 0.021",\
|
||||
"0.009, 0.015, 0.021",\
|
||||
"0.009, 0.015, 0.021");
|
||||
values("-0.004, -0.004, 0.009",\
|
||||
"-0.004, -0.004, 0.009",\
|
||||
"-0.004, -0.004, 0.009");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("-0.065, -0.071, -0.175",\
|
||||
"-0.065, -0.071, -0.175",\
|
||||
"-0.065, -0.071, -0.175");
|
||||
values("-0.052, -0.059, -0.132",\
|
||||
"-0.052, -0.059, -0.132",\
|
||||
"-0.052, -0.059, -0.132");
|
||||
}
|
||||
}
|
||||
internal_power(){
|
||||
when : "!OEb & !clk";
|
||||
rise_power(scalar){
|
||||
values("5.1597");
|
||||
values("10.730552");
|
||||
}
|
||||
fall_power(scalar){
|
||||
values("5.1863");
|
||||
values("10.584523");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
|
|
@ -140,24 +140,24 @@ cell (sram_2_16_1_scn3me_subm){
|
|||
related_pin : "clk";
|
||||
timing_type : falling_edge;
|
||||
cell_rise(CELL_TABLE) {
|
||||
values("0.509, 0.592, 1.265",\
|
||||
"0.512, 0.595, 1.271",\
|
||||
"0.561, 0.642, 1.317");
|
||||
values("0.458, 0.503, 0.87",\
|
||||
"0.461, 0.505, 0.873",\
|
||||
"0.5, 0.544, 0.911");
|
||||
}
|
||||
cell_fall(CELL_TABLE) {
|
||||
values("1.449, 1.549, 2.511",\
|
||||
"1.453, 1.555, 2.518",\
|
||||
"1.505, 1.607, 2.568");
|
||||
values("0.573, 0.649, 1.249",\
|
||||
"0.576, 0.651, 1.252",\
|
||||
"0.616, 0.69, 1.289");
|
||||
}
|
||||
rise_transition(CELL_TABLE) {
|
||||
values("0.19, 0.335, 1.887",\
|
||||
"0.192, 0.336, 1.886",\
|
||||
"0.194, 0.339, 1.886");
|
||||
values("0.153, 0.232, 1.084",\
|
||||
"0.153, 0.233, 1.084",\
|
||||
"0.156, 0.236, 1.084");
|
||||
}
|
||||
fall_transition(CELL_TABLE) {
|
||||
values("0.282, 0.465, 2.464",\
|
||||
"0.283, 0.466, 2.463",\
|
||||
"0.283, 0.465, 2.455");
|
||||
values("0.277, 0.355, 1.499",\
|
||||
"0.277, 0.357, 1.499",\
|
||||
"0.278, 0.362, 1.499");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -174,28 +174,28 @@ cell (sram_2_16_1_scn3me_subm){
|
|||
timing_type : setup_rising;
|
||||
related_pin : "clk";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.082, 0.088, 0.186",\
|
||||
"0.082, 0.088, 0.186",\
|
||||
"0.082, 0.088, 0.186");
|
||||
values("0.076, 0.076, 0.149",\
|
||||
"0.076, 0.076, 0.149",\
|
||||
"0.076, 0.076, 0.149");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.021, 0.021, 0.027",\
|
||||
"0.021, 0.021, 0.027",\
|
||||
"0.021, 0.021, 0.027");
|
||||
values("0.039, 0.039, 0.027",\
|
||||
"0.039, 0.039, 0.027",\
|
||||
"0.039, 0.039, 0.027");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
timing_type : hold_rising;
|
||||
related_pin : "clk";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.015, 0.021",\
|
||||
"0.009, 0.015, 0.021",\
|
||||
"0.009, 0.015, 0.021");
|
||||
values("-0.004, -0.004, 0.009",\
|
||||
"-0.004, -0.004, 0.009",\
|
||||
"-0.004, -0.004, 0.009");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("-0.065, -0.071, -0.175",\
|
||||
"-0.065, -0.071, -0.175",\
|
||||
"-0.065, -0.071, -0.175");
|
||||
values("-0.052, -0.059, -0.132",\
|
||||
"-0.052, -0.059, -0.132",\
|
||||
"-0.052, -0.059, -0.132");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -208,28 +208,28 @@ cell (sram_2_16_1_scn3me_subm){
|
|||
timing_type : setup_rising;
|
||||
related_pin : "clk";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.082, 0.088, 0.186",\
|
||||
"0.082, 0.088, 0.186",\
|
||||
"0.082, 0.088, 0.186");
|
||||
values("0.076, 0.076, 0.149",\
|
||||
"0.076, 0.076, 0.149",\
|
||||
"0.076, 0.076, 0.149");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.021, 0.021, 0.027",\
|
||||
"0.021, 0.021, 0.027",\
|
||||
"0.021, 0.021, 0.027");
|
||||
values("0.039, 0.039, 0.027",\
|
||||
"0.039, 0.039, 0.027",\
|
||||
"0.039, 0.039, 0.027");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
timing_type : hold_rising;
|
||||
related_pin : "clk";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.015, 0.021",\
|
||||
"0.009, 0.015, 0.021",\
|
||||
"0.009, 0.015, 0.021");
|
||||
values("-0.004, -0.004, 0.009",\
|
||||
"-0.004, -0.004, 0.009",\
|
||||
"-0.004, -0.004, 0.009");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("-0.065, -0.071, -0.175",\
|
||||
"-0.065, -0.071, -0.175",\
|
||||
"-0.065, -0.071, -0.175");
|
||||
values("-0.052, -0.059, -0.132",\
|
||||
"-0.052, -0.059, -0.132",\
|
||||
"-0.052, -0.059, -0.132");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -241,28 +241,28 @@ cell (sram_2_16_1_scn3me_subm){
|
|||
timing_type : setup_rising;
|
||||
related_pin : "clk";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.082, 0.088, 0.186",\
|
||||
"0.082, 0.088, 0.186",\
|
||||
"0.082, 0.088, 0.186");
|
||||
values("0.076, 0.076, 0.149",\
|
||||
"0.076, 0.076, 0.149",\
|
||||
"0.076, 0.076, 0.149");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.021, 0.021, 0.027",\
|
||||
"0.021, 0.021, 0.027",\
|
||||
"0.021, 0.021, 0.027");
|
||||
values("0.039, 0.039, 0.027",\
|
||||
"0.039, 0.039, 0.027",\
|
||||
"0.039, 0.039, 0.027");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
timing_type : hold_rising;
|
||||
related_pin : "clk";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.015, 0.021",\
|
||||
"0.009, 0.015, 0.021",\
|
||||
"0.009, 0.015, 0.021");
|
||||
values("-0.004, -0.004, 0.009",\
|
||||
"-0.004, -0.004, 0.009",\
|
||||
"-0.004, -0.004, 0.009");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("-0.065, -0.071, -0.175",\
|
||||
"-0.065, -0.071, -0.175",\
|
||||
"-0.065, -0.071, -0.175");
|
||||
values("-0.052, -0.059, -0.132",\
|
||||
"-0.052, -0.059, -0.132",\
|
||||
"-0.052, -0.059, -0.132");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -274,28 +274,28 @@ cell (sram_2_16_1_scn3me_subm){
|
|||
timing_type : setup_rising;
|
||||
related_pin : "clk";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.082, 0.088, 0.186",\
|
||||
"0.082, 0.088, 0.186",\
|
||||
"0.082, 0.088, 0.186");
|
||||
values("0.076, 0.076, 0.149",\
|
||||
"0.076, 0.076, 0.149",\
|
||||
"0.076, 0.076, 0.149");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.021, 0.021, 0.027",\
|
||||
"0.021, 0.021, 0.027",\
|
||||
"0.021, 0.021, 0.027");
|
||||
values("0.039, 0.039, 0.027",\
|
||||
"0.039, 0.039, 0.027",\
|
||||
"0.039, 0.039, 0.027");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
timing_type : hold_rising;
|
||||
related_pin : "clk";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.015, 0.021",\
|
||||
"0.009, 0.015, 0.021",\
|
||||
"0.009, 0.015, 0.021");
|
||||
values("-0.004, -0.004, 0.009",\
|
||||
"-0.004, -0.004, 0.009",\
|
||||
"-0.004, -0.004, 0.009");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("-0.065, -0.071, -0.175",\
|
||||
"-0.065, -0.071, -0.175",\
|
||||
"-0.065, -0.071, -0.175");
|
||||
values("-0.052, -0.059, -0.132",\
|
||||
"-0.052, -0.059, -0.132",\
|
||||
"-0.052, -0.059, -0.132");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -308,20 +308,20 @@ cell (sram_2_16_1_scn3me_subm){
|
|||
timing_type :"min_pulse_width";
|
||||
related_pin : clk;
|
||||
rise_constraint(scalar) {
|
||||
values("4.375");
|
||||
values("2.344");
|
||||
}
|
||||
fall_constraint(scalar) {
|
||||
values("4.375");
|
||||
values("2.344");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
timing_type :"minimum_period";
|
||||
related_pin : clk;
|
||||
rise_constraint(scalar) {
|
||||
values("8.75");
|
||||
values("4.688");
|
||||
}
|
||||
fall_constraint(scalar) {
|
||||
values("8.75");
|
||||
values("4.688");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
library (sram_2_16_1_scn3me_subm_lib){
|
||||
library (sram_2_16_1_scn3me_subm_TT_50V_25C_lib){
|
||||
delay_model : "table_lookup";
|
||||
time_unit : "1ns" ;
|
||||
voltage_unit : "1v" ;
|
||||
|
|
@ -9,7 +9,7 @@ library (sram_2_16_1_scn3me_subm_lib){
|
|||
pulling_resistance_unit :"1kohm" ;
|
||||
operating_conditions(TT){
|
||||
voltage : 5.0 ;
|
||||
temperature : 25.000 ;
|
||||
temperature : 25;
|
||||
}
|
||||
|
||||
input_threshold_pct_fall : 50.0 ;
|
||||
|
|
@ -74,7 +74,7 @@ cell (sram_2_16_1_scn3me_subm){
|
|||
dont_use : true;
|
||||
map_only : true;
|
||||
dont_touch : true;
|
||||
area : 2.7;
|
||||
area : 122426.46;
|
||||
|
||||
bus(DATA){
|
||||
bus_type : DATA;
|
||||
|
|
@ -140,14 +140,14 @@ cell (sram_2_16_1_scn3me_subm){
|
|||
related_pin : "clk";
|
||||
timing_type : falling_edge;
|
||||
cell_rise(CELL_TABLE) {
|
||||
values("0.561, 0.608, 1.049",\
|
||||
"0.561, 0.608, 1.049",\
|
||||
"0.561, 0.608, 1.049");
|
||||
values("0.556, 0.603, 1.044",\
|
||||
"0.556, 0.603, 1.044",\
|
||||
"0.556, 0.603, 1.044");
|
||||
}
|
||||
cell_fall(CELL_TABLE) {
|
||||
values("0.561, 0.608, 1.049",\
|
||||
"0.561, 0.608, 1.049",\
|
||||
"0.561, 0.608, 1.049");
|
||||
values("0.556, 0.603, 1.044",\
|
||||
"0.556, 0.603, 1.044",\
|
||||
"0.556, 0.603, 1.044");
|
||||
}
|
||||
rise_transition(CELL_TABLE) {
|
||||
values("0.024, 0.081, 0.61",\
|
||||
|
|
@ -0,0 +1,329 @@
|
|||
library (sram_2_16_1_scn3me_subm_TT_50V_25C_lib){
|
||||
delay_model : "table_lookup";
|
||||
time_unit : "1ns" ;
|
||||
voltage_unit : "1v" ;
|
||||
current_unit : "1mA" ;
|
||||
resistance_unit : "1kohm" ;
|
||||
capacitive_load_unit(1 ,fF) ;
|
||||
leakage_power_unit : "1mW" ;
|
||||
pulling_resistance_unit :"1kohm" ;
|
||||
operating_conditions(TT){
|
||||
voltage : 5.0 ;
|
||||
temperature : 25;
|
||||
}
|
||||
|
||||
input_threshold_pct_fall : 50.0 ;
|
||||
output_threshold_pct_fall : 50.0 ;
|
||||
input_threshold_pct_rise : 50.0 ;
|
||||
output_threshold_pct_rise : 50.0 ;
|
||||
slew_lower_threshold_pct_fall : 10.0 ;
|
||||
slew_upper_threshold_pct_fall : 90.0 ;
|
||||
slew_lower_threshold_pct_rise : 10.0 ;
|
||||
slew_upper_threshold_pct_rise : 90.0 ;
|
||||
|
||||
default_cell_leakage_power : 0.0 ;
|
||||
default_leakage_power_density : 0.0 ;
|
||||
default_input_pin_cap : 1.0 ;
|
||||
default_inout_pin_cap : 1.0 ;
|
||||
default_output_pin_cap : 0.0 ;
|
||||
default_max_transition : 0.5 ;
|
||||
default_fanout_load : 1.0 ;
|
||||
default_max_fanout : 4.0 ;
|
||||
default_connection_class : universal ;
|
||||
|
||||
lu_table_template(CELL_TABLE){
|
||||
variable_1 : input_net_transition;
|
||||
variable_2 : total_output_net_capacitance;
|
||||
index_1("0.0125, 0.05, 0.4");
|
||||
index_2("2.45605, 9.8242, 78.5936");
|
||||
}
|
||||
|
||||
lu_table_template(CONSTRAINT_TABLE){
|
||||
variable_1 : related_pin_transition;
|
||||
variable_2 : constrained_pin_transition;
|
||||
index_1("0.0125, 0.05, 0.4");
|
||||
index_2("0.0125, 0.05, 0.4");
|
||||
}
|
||||
|
||||
default_operating_conditions : TT;
|
||||
|
||||
|
||||
type (DATA){
|
||||
base_type : array;
|
||||
data_type : bit;
|
||||
bit_width : 2;
|
||||
bit_from : 0;
|
||||
bit_to : 1;
|
||||
}
|
||||
|
||||
type (ADDR){
|
||||
base_type : array;
|
||||
data_type : bit;
|
||||
bit_width : 4;
|
||||
bit_from : 0;
|
||||
bit_to : 3;
|
||||
}
|
||||
|
||||
cell (sram_2_16_1_scn3me_subm){
|
||||
memory(){
|
||||
type : ram;
|
||||
address_width : 4;
|
||||
word_width : 2;
|
||||
}
|
||||
interface_timing : true;
|
||||
dont_use : true;
|
||||
map_only : true;
|
||||
dont_touch : true;
|
||||
area : 122426.46;
|
||||
|
||||
bus(DATA){
|
||||
bus_type : DATA;
|
||||
direction : inout;
|
||||
max_capacitance : 78.5936;
|
||||
three_state : "!OEb & !clk";
|
||||
memory_write(){
|
||||
address : ADDR;
|
||||
clocked_on : clk;
|
||||
}
|
||||
memory_read(){
|
||||
address : ADDR;
|
||||
}
|
||||
pin(DATA[1:0]){
|
||||
internal_power(){
|
||||
when : "OEb & !clk";
|
||||
rise_power(scalar){
|
||||
values("11.756062");
|
||||
}
|
||||
fall_power(scalar){
|
||||
values("7.1840422");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
timing_type : setup_rising;
|
||||
related_pin : "clk";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.076, 0.076, 0.149",\
|
||||
"0.076, 0.076, 0.149",\
|
||||
"0.076, 0.076, 0.149");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.039, 0.039, 0.027",\
|
||||
"0.039, 0.039, 0.027",\
|
||||
"0.039, 0.039, 0.027");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
timing_type : hold_rising;
|
||||
related_pin : "clk";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("-0.004, -0.004, 0.009",\
|
||||
"-0.004, -0.004, 0.009",\
|
||||
"-0.004, -0.004, 0.009");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("-0.052, -0.059, -0.132",\
|
||||
"-0.052, -0.059, -0.132",\
|
||||
"-0.052, -0.059, -0.132");
|
||||
}
|
||||
}
|
||||
internal_power(){
|
||||
when : "!OEb & !clk";
|
||||
rise_power(scalar){
|
||||
values("10.730552");
|
||||
}
|
||||
fall_power(scalar){
|
||||
values("10.584523");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
timing_sense : non_unate;
|
||||
related_pin : "clk";
|
||||
timing_type : falling_edge;
|
||||
cell_rise(CELL_TABLE) {
|
||||
values("0.458, 0.503, 0.87",\
|
||||
"0.461, 0.505, 0.873",\
|
||||
"0.5, 0.544, 0.911");
|
||||
}
|
||||
cell_fall(CELL_TABLE) {
|
||||
values("0.573, 0.649, 1.249",\
|
||||
"0.576, 0.651, 1.252",\
|
||||
"0.616, 0.69, 1.289");
|
||||
}
|
||||
rise_transition(CELL_TABLE) {
|
||||
values("0.153, 0.232, 1.084",\
|
||||
"0.153, 0.233, 1.084",\
|
||||
"0.156, 0.236, 1.084");
|
||||
}
|
||||
fall_transition(CELL_TABLE) {
|
||||
values("0.277, 0.355, 1.499",\
|
||||
"0.277, 0.357, 1.499",\
|
||||
"0.278, 0.362, 1.499");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bus(ADDR){
|
||||
bus_type : ADDR;
|
||||
direction : input;
|
||||
capacitance : 9.8242;
|
||||
max_transition : 0.4;
|
||||
fanout_load : 1.000000;
|
||||
pin(ADDR[3:0]){
|
||||
timing(){
|
||||
timing_type : setup_rising;
|
||||
related_pin : "clk";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.076, 0.076, 0.149",\
|
||||
"0.076, 0.076, 0.149",\
|
||||
"0.076, 0.076, 0.149");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.039, 0.039, 0.027",\
|
||||
"0.039, 0.039, 0.027",\
|
||||
"0.039, 0.039, 0.027");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
timing_type : hold_rising;
|
||||
related_pin : "clk";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("-0.004, -0.004, 0.009",\
|
||||
"-0.004, -0.004, 0.009",\
|
||||
"-0.004, -0.004, 0.009");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("-0.052, -0.059, -0.132",\
|
||||
"-0.052, -0.059, -0.132",\
|
||||
"-0.052, -0.059, -0.132");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pin(CSb){
|
||||
direction : input;
|
||||
capacitance : 9.8242;
|
||||
timing(){
|
||||
timing_type : setup_rising;
|
||||
related_pin : "clk";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.076, 0.076, 0.149",\
|
||||
"0.076, 0.076, 0.149",\
|
||||
"0.076, 0.076, 0.149");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.039, 0.039, 0.027",\
|
||||
"0.039, 0.039, 0.027",\
|
||||
"0.039, 0.039, 0.027");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
timing_type : hold_rising;
|
||||
related_pin : "clk";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("-0.004, -0.004, 0.009",\
|
||||
"-0.004, -0.004, 0.009",\
|
||||
"-0.004, -0.004, 0.009");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("-0.052, -0.059, -0.132",\
|
||||
"-0.052, -0.059, -0.132",\
|
||||
"-0.052, -0.059, -0.132");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pin(OEb){
|
||||
direction : input;
|
||||
capacitance : 9.8242;
|
||||
timing(){
|
||||
timing_type : setup_rising;
|
||||
related_pin : "clk";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.076, 0.076, 0.149",\
|
||||
"0.076, 0.076, 0.149",\
|
||||
"0.076, 0.076, 0.149");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.039, 0.039, 0.027",\
|
||||
"0.039, 0.039, 0.027",\
|
||||
"0.039, 0.039, 0.027");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
timing_type : hold_rising;
|
||||
related_pin : "clk";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("-0.004, -0.004, 0.009",\
|
||||
"-0.004, -0.004, 0.009",\
|
||||
"-0.004, -0.004, 0.009");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("-0.052, -0.059, -0.132",\
|
||||
"-0.052, -0.059, -0.132",\
|
||||
"-0.052, -0.059, -0.132");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pin(WEb){
|
||||
direction : input;
|
||||
capacitance : 9.8242;
|
||||
timing(){
|
||||
timing_type : setup_rising;
|
||||
related_pin : "clk";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.076, 0.076, 0.149",\
|
||||
"0.076, 0.076, 0.149",\
|
||||
"0.076, 0.076, 0.149");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.039, 0.039, 0.027",\
|
||||
"0.039, 0.039, 0.027",\
|
||||
"0.039, 0.039, 0.027");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
timing_type : hold_rising;
|
||||
related_pin : "clk";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("-0.004, -0.004, 0.009",\
|
||||
"-0.004, -0.004, 0.009",\
|
||||
"-0.004, -0.004, 0.009");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("-0.052, -0.059, -0.132",\
|
||||
"-0.052, -0.059, -0.132",\
|
||||
"-0.052, -0.059, -0.132");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pin(clk){
|
||||
clock : true;
|
||||
direction : input;
|
||||
capacitance : 9.8242;
|
||||
timing(){
|
||||
timing_type :"min_pulse_width";
|
||||
related_pin : clk;
|
||||
rise_constraint(scalar) {
|
||||
values("2.344");
|
||||
}
|
||||
fall_constraint(scalar) {
|
||||
values("2.344");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
timing_type :"minimum_period";
|
||||
related_pin : clk;
|
||||
rise_constraint(scalar) {
|
||||
values("4.688");
|
||||
}
|
||||
fall_constraint(scalar) {
|
||||
values("4.688");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,8 +1,9 @@
|
|||
import unittest
|
||||
import unittest,warnings
|
||||
import sys,os,glob
|
||||
sys.path.append(os.path.join(sys.path[0],".."))
|
||||
import globals
|
||||
from globals import OPTS
|
||||
import debug
|
||||
|
||||
class openram_test(unittest.TestCase):
|
||||
""" Base unit test that we have some shared classes in. """
|
||||
|
|
@ -17,8 +18,8 @@ class openram_test(unittest.TestCase):
|
|||
for f in files:
|
||||
os.remove(f)
|
||||
|
||||
def local_check(self, a):
|
||||
|
||||
def local_check(self, a, final_verification=False):
|
||||
|
||||
tempspice = OPTS.openram_temp + "temp.sp"
|
||||
tempgds = OPTS.openram_temp + "temp.gds"
|
||||
|
||||
|
|
@ -34,17 +35,17 @@ class openram_test(unittest.TestCase):
|
|||
|
||||
|
||||
try:
|
||||
self.assertTrue(verify.run_lvs(a.name, tempgds, tempspice)==0)
|
||||
self.assertTrue(verify.run_lvs(a.name, tempgds, tempspice, final_verification)==0)
|
||||
except:
|
||||
self.reset()
|
||||
self.fail("LVS mismatch: {}".format(a.name))
|
||||
|
||||
self.cleanup()
|
||||
self.reset()
|
||||
if OPTS.purge_temp:
|
||||
self.cleanup()
|
||||
|
||||
def cleanup(self):
|
||||
""" Reset the duplicate checker and cleanup files. """
|
||||
self.reset()
|
||||
|
||||
files = glob.glob(OPTS.openram_temp + '*')
|
||||
for f in files:
|
||||
# Only remove the files
|
||||
|
|
|
|||
|
|
@ -137,9 +137,11 @@ def run_drc(cell_name, gds_name):
|
|||
return errors
|
||||
|
||||
|
||||
def run_lvs(cell_name, gds_name, sp_name):
|
||||
def run_lvs(cell_name, gds_name, sp_name, final_verification=False):
|
||||
"""Run LVS check on a given top-level name which is
|
||||
implemented in gds_name and sp_name. """
|
||||
implemented in gds_name and sp_name. Final verification will
|
||||
ensure that there are no remaining virtual conections. """
|
||||
|
||||
from tech import drc
|
||||
lvs_rules = drc["lvs_rules"]
|
||||
lvs_runset = {
|
||||
|
|
@ -154,7 +156,6 @@ def run_lvs(cell_name, gds_name, sp_name):
|
|||
'lvsPowerNames': 'vdd',
|
||||
'lvsGroundNames': 'gnd',
|
||||
'lvsIncludeSVRFCmds': 1,
|
||||
'lvsSVRFCmds': '{VIRTUAL CONNECT NAME VDD? GND? ?}',
|
||||
'lvsIgnorePorts': 1,
|
||||
'lvsERCDatabase': OPTS.openram_temp + cell_name + ".erc.results",
|
||||
'lvsERCSummaryFile': OPTS.openram_temp + cell_name + ".erc.summary",
|
||||
|
|
@ -162,10 +163,18 @@ def run_lvs(cell_name, gds_name, sp_name):
|
|||
'lvsMaskDBFile': OPTS.openram_temp + cell_name + ".maskdb",
|
||||
'cmnFDILayerMapFile': drc["layer_map"],
|
||||
'cmnFDIUseLayerMap': 1,
|
||||
'cmnVConnectNames': 'vdd, gnd',
|
||||
'lvsRecognizeGates': 'NONE'
|
||||
#'cmnVConnectNamesState' : 'ALL', #connects all nets with the same name
|
||||
}
|
||||
|
||||
# This should be removed for final verification
|
||||
if not final_verification:
|
||||
lvs_runset['cmnVConnectReport']=1
|
||||
lvs_runset['cmnVConnectNamesState']='SOME'
|
||||
lvs_runset['cmnVConnectNames']='vdd gnd'
|
||||
|
||||
|
||||
|
||||
# write the runset file
|
||||
f = open(OPTS.openram_temp + "lvs_runset", "w")
|
||||
for k in sorted(lvs_runset.iterkeys()):
|
||||
|
|
|
|||
|
|
@ -44,8 +44,8 @@ EOF
|
|||
3. netgen can perform LVS with:
|
||||
#!/bin/sh
|
||||
netgen -noconsole <<EOF
|
||||
readnet $1.spice
|
||||
readnet $1.sp
|
||||
readnet spice $1.spice
|
||||
readnet spice $1.sp
|
||||
ignore class c
|
||||
equate class {$1.spice nfet} {$2.sp n}
|
||||
equate class {$1.spice pfet} {$2.sp p}
|
||||
|
|
@ -86,7 +86,7 @@ def write_magic_script(cell_name, gds_name, extract=False):
|
|||
f.write("drc count total\n")
|
||||
f.write("drc count\n")
|
||||
if extract:
|
||||
f.write("extract\n")
|
||||
f.write("extract all\n")
|
||||
f.write("ext2spice hierarchy on\n")
|
||||
f.write("ext2spice scale off\n")
|
||||
# Can choose hspice, ngspice, or spice3,
|
||||
|
|
@ -113,21 +113,26 @@ def write_netgen_script(cell_name, sp_name):
|
|||
f = open(run_file, "w")
|
||||
f.write("#!/bin/sh\n")
|
||||
f.write("{} -noconsole << EOF\n".format(OPTS.lvs_exe[1]))
|
||||
f.write("readnet {}.spice\n".format(cell_name))
|
||||
f.write("readnet {}\n".format(sp_name))
|
||||
f.write("readnet spice {}.spice\n".format(cell_name))
|
||||
f.write("readnet spice {}\n".format(sp_name))
|
||||
f.write("ignore class c\n")
|
||||
f.write("permute transistors\n")
|
||||
f.write("equate class {{{0}.spice nfet}} {{{1} n}}\n".format(cell_name, sp_name))
|
||||
f.write("equate class {{{0}.spice pfet}} {{{1} p}}\n".format(cell_name, sp_name))
|
||||
# This circuit has symmetries and needs to be flattened to resolve them or the banks won't pass
|
||||
# Is there a more elegant way to add this when needed?
|
||||
f.write("flatten class {{{0}.spice precharge_array}}\n".format(cell_name))
|
||||
f.write("property {{{0}.spice nfet}} remove as ad ps pd\n".format(cell_name))
|
||||
f.write("property {{{0}.spice pfet}} remove as ad ps pd\n".format(cell_name))
|
||||
f.write("property {{{0} n}} remove as ad ps pd\n".format(sp_name))
|
||||
f.write("property {{{0} p}} remove as ad ps pd\n".format(sp_name))
|
||||
# Allow some flexibility in W size because magic will snap to a lambda grid
|
||||
# This can also cause disconnects unfortunately!
|
||||
# f.write("property {{{0}{1}.spice nfet}} tolerance {{w 0.1}}\n".format(OPTS.openram_temp,
|
||||
# cell_name))
|
||||
# f.write("property {{{0}{1}.spice pfet}} tolerance {{w 0.1}}\n".format(OPTS.openram_temp,
|
||||
# cell_name))
|
||||
f.write("lvs {0}.spice {{{1} {0}}} setup.tcl lvs.results\n".format(cell_name, sp_name))
|
||||
f.write("lvs {0}.spice {{{1} {0}}} setup.tcl {0}.lvs.report\n".format(cell_name, sp_name))
|
||||
f.write("quit\n")
|
||||
f.write("EOF\n")
|
||||
f.close()
|
||||
|
|
@ -142,7 +147,7 @@ def run_drc(cell_name, gds_name, extract=False):
|
|||
cwd = os.getcwd()
|
||||
os.chdir(OPTS.openram_temp)
|
||||
errfile = "{0}{1}.drc.err".format(OPTS.openram_temp, cell_name)
|
||||
outfile = "{0}{1}.drc.out".format(OPTS.openram_temp, cell_name)
|
||||
outfile = "{0}{1}.drc.summary".format(OPTS.openram_temp, cell_name)
|
||||
|
||||
cmd = "{0}run_drc.sh 2> {1} 1> {2}".format(OPTS.openram_temp,
|
||||
errfile,
|
||||
|
|
@ -181,9 +186,10 @@ def run_drc(cell_name, gds_name, extract=False):
|
|||
return errors
|
||||
|
||||
|
||||
def run_lvs(cell_name, gds_name, sp_name):
|
||||
def run_lvs(cell_name, gds_name, sp_name, final_verification=False):
|
||||
"""Run LVS check on a given top-level name which is
|
||||
implemented in gds_name and sp_name. """
|
||||
implemented in gds_name and sp_name. Final verification will
|
||||
ensure that there are no remaining virtual conections. """
|
||||
|
||||
run_drc(cell_name, gds_name, extract=True)
|
||||
write_netgen_script(cell_name, sp_name)
|
||||
|
|
@ -193,7 +199,7 @@ def run_lvs(cell_name, gds_name, sp_name):
|
|||
os.chdir(OPTS.openram_temp)
|
||||
errfile = "{0}{1}.lvs.err".format(OPTS.openram_temp, cell_name)
|
||||
outfile = "{0}{1}.lvs.out".format(OPTS.openram_temp, cell_name)
|
||||
resultsfile = "{0}lvs.results".format(OPTS.openram_temp, cell_name)
|
||||
resultsfile = "{0}{1}.lvs.report".format(OPTS.openram_temp, cell_name)
|
||||
|
||||
cmd = "{0}run_lvs.sh lvs 2> {1} 1> {2}".format(OPTS.openram_temp,
|
||||
errfile,
|
||||
|
|
@ -216,10 +222,12 @@ def run_lvs(cell_name, gds_name, sp_name):
|
|||
propertyerrors = filter(test.search, results)
|
||||
# Require pins to match?
|
||||
# Cell pin lists for pnand2_1.spice and pnand2_1 altered to match.
|
||||
test = re.compile(".*altered to match.")
|
||||
pinerrors = filter(test.search, results)
|
||||
|
||||
total_errors = len(propertyerrors) + len(incorrect) + len(pinerrors)
|
||||
# test = re.compile(".*altered to match.")
|
||||
# pinerrors = filter(test.search, results)
|
||||
# if len(pinerrors)>0:
|
||||
# debug.warning("Pins altered to match in {}.".format(cell_name))
|
||||
|
||||
total_errors = len(propertyerrors) + len(incorrect)
|
||||
# If we want to ignore property errors
|
||||
#total_errors = len(incorrect)
|
||||
#if len(propertyerrors)>0:
|
||||
|
|
@ -236,7 +244,7 @@ def run_lvs(cell_name, gds_name, sp_name):
|
|||
# Just print out the whole file, it is short.
|
||||
for e in results:
|
||||
debug.info(1,e.strip("\n"))
|
||||
debug.error("LVS mismatch (results in {}lvs.results)".format(OPTS.openram_temp))
|
||||
debug.error("LVS mismatch (results in {})".format(resultsfile))
|
||||
|
||||
return total_errors
|
||||
|
||||
|
|
|
|||
1475
docs/figs/Array.svg
|
Before Width: | Height: | Size: 51 KiB |
|
Before Width: | Height: | Size: 7.4 KiB |
|
Before Width: | Height: | Size: 8.7 KiB |
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 31 KiB |
|
|
@ -1,409 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="744.09448819"
|
||||
height="1052.3622047"
|
||||
id="svg2"
|
||||
sodipodi:version="0.32"
|
||||
inkscape:version="0.46"
|
||||
sodipodi:docname="decoder_to _array.svg"
|
||||
inkscape:output_extension="org.inkscape.output.svg.inkscape">
|
||||
<defs
|
||||
id="defs4">
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Lend"
|
||||
orient="auto"
|
||||
refY="0.0"
|
||||
refX="0.0"
|
||||
id="Arrow1Lend"
|
||||
style="overflow:visible;">
|
||||
<path
|
||||
id="path3229"
|
||||
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
|
||||
transform="scale(0.8) rotate(180) translate(12.5,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Lstart"
|
||||
orient="auto"
|
||||
refY="0.0"
|
||||
refX="0.0"
|
||||
id="Arrow1Lstart"
|
||||
style="overflow:visible">
|
||||
<path
|
||||
id="path3226"
|
||||
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none"
|
||||
transform="scale(0.8) translate(12.5,0)" />
|
||||
</marker>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient2461">
|
||||
<stop
|
||||
style="stop-color:#b3b3b3;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop2463" />
|
||||
<stop
|
||||
style="stop-color:#b3b3b3;stop-opacity:0;"
|
||||
offset="1"
|
||||
id="stop2465" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient2451">
|
||||
<stop
|
||||
style="stop-color:#b3b3b3;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop2453" />
|
||||
<stop
|
||||
style="stop-color:#b3b3b3;stop-opacity:0;"
|
||||
offset="1"
|
||||
id="stop2455" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient2445">
|
||||
<stop
|
||||
style="stop-color:#b3b3b3;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop2447" />
|
||||
<stop
|
||||
style="stop-color:#b3b3b3;stop-opacity:0;"
|
||||
offset="1"
|
||||
id="stop2449" />
|
||||
</linearGradient>
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 526.18109 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="744.09448 : 526.18109 : 1"
|
||||
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
|
||||
id="perspective10" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient2445"
|
||||
id="linearGradient2443"
|
||||
x1="370.17203"
|
||||
y1="408.19574"
|
||||
x2="372.40872"
|
||||
y2="517.79352"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.7710419,0,0,0.8337292,8.1937292,7.8098171)" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient2451"
|
||||
id="linearGradient2457"
|
||||
x1="371.29037"
|
||||
y1="409.31409"
|
||||
x2="367.72989"
|
||||
y2="523.38525"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.7712785,0,0,0.8337292,8.0871771,7.8098171)" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient2461"
|
||||
id="linearGradient2467"
|
||||
x1="551.34387"
|
||||
y1="456.28641"
|
||||
x2="551.34387"
|
||||
y2="619.56287"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1,0,0,0.5308865,0,114.74779)" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
gridtolerance="10000"
|
||||
guidetolerance="10"
|
||||
objecttolerance="10"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="2.1448286"
|
||||
inkscape:cx="309.70169"
|
||||
inkscape:cy="808.88914"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
showguides="true"
|
||||
inkscape:guide-bbox="true"
|
||||
inkscape:window-width="1600"
|
||||
inkscape:window-height="1132"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<rect
|
||||
style="fill:url(#linearGradient2467);fill-opacity:1"
|
||||
id="rect2459"
|
||||
width="354.07697"
|
||||
height="193.31812"
|
||||
x="391.42059"
|
||||
y="246.19127" />
|
||||
<rect
|
||||
style="fill:url(#linearGradient2457);fill-opacity:1"
|
||||
id="rect2433"
|
||||
width="127.34832"
|
||||
height="191.49203"
|
||||
x="228.03519"
|
||||
y="248.01219" />
|
||||
<rect
|
||||
style="fill:#ff6600"
|
||||
id="rect2549"
|
||||
width="518.00879"
|
||||
height="37.828362"
|
||||
x="227.68326"
|
||||
y="302.75879" />
|
||||
<rect
|
||||
style="fill:#00ff00"
|
||||
id="rect2547"
|
||||
width="544.10468"
|
||||
height="38.307152"
|
||||
x="201.76241"
|
||||
y="243.43471" />
|
||||
<rect
|
||||
style="fill:url(#linearGradient2443);fill-opacity:1"
|
||||
id="rect2383"
|
||||
width="192.29077"
|
||||
height="392.53891"
|
||||
x="35.787025"
|
||||
y="46.97047" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:19.24255753px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
|
||||
x="94.222366"
|
||||
y="-121.21298"
|
||||
id="text2387"
|
||||
transform="matrix(-6.8463303e-3,1.0398304,-0.9616465,-7.4029511e-3,0,0)"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan2389"
|
||||
x="94.222366"
|
||||
y="-121.21298">Address Decoder</tspan><tspan
|
||||
sodipodi:role="line"
|
||||
x="94.222366"
|
||||
y="-97.15979"
|
||||
id="tspan2391" /></text>
|
||||
<rect
|
||||
style="fill:#ff0000"
|
||||
id="rect2393"
|
||||
width="159.23743"
|
||||
height="17.715534"
|
||||
x="202.95409"
|
||||
y="254.21713" />
|
||||
<rect
|
||||
style="fill:#0000ff"
|
||||
id="rect2399"
|
||||
width="159.23741"
|
||||
height="17.715534"
|
||||
x="202.9501"
|
||||
y="280.85464" />
|
||||
<rect
|
||||
style="fill:#008000"
|
||||
id="rect2401"
|
||||
width="159.40862"
|
||||
height="17.715534"
|
||||
x="202.94533"
|
||||
y="310.23676" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:14.67683983000000048px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
|
||||
x="254.6263"
|
||||
y="281.54678"
|
||||
id="text2403"
|
||||
transform="scale(1.0494184,0.9529088)"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan2405"
|
||||
x="254.6263"
|
||||
y="281.54678">Vdd </tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:14.9124279px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
|
||||
x="278.65591"
|
||||
y="268.46613"
|
||||
id="text2407"
|
||||
transform="scale(0.9095598,1.0994329)"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan2409"
|
||||
x="278.65591"
|
||||
y="268.46613">Word Line</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:15.81832218px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
|
||||
x="277.87473"
|
||||
y="316.27682"
|
||||
id="text2411"
|
||||
transform="scale(0.9736983,1.0270121)"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan2413"
|
||||
x="277.87473"
|
||||
y="316.27682">Vss</tspan></text>
|
||||
<rect
|
||||
style="fill:#ff0000"
|
||||
id="rect2469"
|
||||
width="362.56842"
|
||||
height="17.715534"
|
||||
x="382.1893"
|
||||
y="254.20079" />
|
||||
<rect
|
||||
style="fill:#0000ff"
|
||||
id="rect2471"
|
||||
width="363.03949"
|
||||
height="17.715534"
|
||||
x="382.1853"
|
||||
y="280.83832" />
|
||||
<rect
|
||||
style="fill:#008000"
|
||||
id="rect2473"
|
||||
width="361.6424"
|
||||
height="17.715534"
|
||||
x="383.1106"
|
||||
y="310.22043" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:14.67683983px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
|
||||
x="445.56149"
|
||||
y="281.52963"
|
||||
id="text2475"
|
||||
transform="scale(1.0494184,0.9529088)"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan2477"
|
||||
x="445.56149"
|
||||
y="281.52963">Vdd </tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:14.9124279px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
|
||||
x="498.65213"
|
||||
y="268.45126"
|
||||
id="text2479"
|
||||
transform="scale(0.9095598,1.0994329)"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan2481"
|
||||
x="498.65213"
|
||||
y="268.45126">Word Line</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:15.81830978px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
|
||||
x="485.32767"
|
||||
y="315.46939"
|
||||
id="text2483"
|
||||
transform="scale(0.9736983,1.0270121)"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan2485"
|
||||
x="485.32767"
|
||||
y="315.46939">Vss</tspan></text>
|
||||
<rect
|
||||
style="fill:#ffffff"
|
||||
id="rect2551"
|
||||
width="16.346491"
|
||||
height="152.72293"
|
||||
x="364.29324"
|
||||
y="215.42181" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.4;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:18.10000038;stroke-dasharray:none;marker-start:url(#Arrow1Lstart);marker-end:url(#Arrow1Lend)"
|
||||
d="M 382.1893,263.0691 L 362.19151,263.07027"
|
||||
id="path2487"
|
||||
inkscape:connector-type="polyline"
|
||||
inkscape:connection-start="#rect2469"
|
||||
inkscape:connection-end="#rect2393" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.4;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:18.10000038;stroke-dasharray:none;marker-start:url(#Arrow1Lstart);marker-end:url(#Arrow1Lend)"
|
||||
d="M 362.35394,319.0899 L 383.1106,319.08869"
|
||||
id="path2491"
|
||||
inkscape:connector-type="polyline"
|
||||
inkscape:connection-start="#rect2401"
|
||||
inkscape:connection-end="#rect2473" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.4;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:18.10000038;stroke-dasharray:none;marker-start:url(#Arrow1Lstart);marker-end:url(#Arrow1Lend)"
|
||||
d="M 382.1853,289.70663 L 362.18752,289.70779"
|
||||
id="path2493"
|
||||
inkscape:connector-type="polyline"
|
||||
inkscape:connection-start="#rect2471"
|
||||
inkscape:connection-end="#rect2399" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:24px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
|
||||
x="533.82971"
|
||||
y="239.70804"
|
||||
id="text2543"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan2545"
|
||||
x="533.82971"
|
||||
y="239.70804">Array</tspan></text>
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.4;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:18.10000038;stroke-dasharray:none;marker-start:url(#Arrow1Lstart);marker-end:url(#Arrow1Lend)"
|
||||
d="M 380.28173,247.63341 L 363.69741,247.63484"
|
||||
id="path2553"
|
||||
inkscape:connector-type="polyline" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.4;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:18.10000038;stroke-dasharray:none;marker-start:url(#Arrow1Lstart);marker-end:url(#Arrow1Lend)"
|
||||
d="M 380.8161,335.38958 L 364.23178,335.39101"
|
||||
id="path2563"
|
||||
inkscape:connector-type="polyline" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:24px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
|
||||
x="-238.96878"
|
||||
y="379.59302"
|
||||
id="text2583"
|
||||
transform="matrix(0,-1,1,0,0,0)"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan2585"
|
||||
x="-238.96878"
|
||||
y="379.59302">}</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:24px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
|
||||
x="345.11981"
|
||||
y="380.30951"
|
||||
id="text2587"
|
||||
transform="matrix(0,1,1,0,0,0)"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan2589"
|
||||
x="345.11981"
|
||||
y="380.30951">}</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:16.78106117px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
|
||||
x="331.69421"
|
||||
y="231.48781"
|
||||
id="text2591"
|
||||
transform="scale(1.0378936,0.9634899)"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan2593"
|
||||
x="331.69421"
|
||||
y="231.48781">N-Well</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:16.01638031px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
|
||||
x="354.27347"
|
||||
y="370.5802"
|
||||
id="text2595"
|
||||
transform="scale(0.9905987,1.0094905)"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan2597"
|
||||
x="354.27347"
|
||||
y="370.5802">P-Well</tspan></text>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 21 KiB |
|
|
@ -25,13 +25,13 @@
|
|||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="1"
|
||||
inkscape:cx="161.5"
|
||||
inkscape:cx="20"
|
||||
inkscape:cy="520"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
inkscape:window-width="1280"
|
||||
inkscape:window-height="752"
|
||||
inkscape:window-width="3440"
|
||||
inkscape:window-height="1392"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1">
|
||||
|
|
@ -185,7 +185,7 @@
|
|||
id="tspan4519"
|
||||
x="184"
|
||||
y="577.36218"
|
||||
style="font-size:16px;line-height:1.25;font-family:sans-serif">BL</tspan></text>
|
||||
style="font-size:16px;line-height:1.25;font-family:sans-serif">bl</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
|
||||
|
|
@ -196,7 +196,7 @@
|
|||
id="tspan4523"
|
||||
x="336"
|
||||
y="577.36218"
|
||||
style="font-size:16px;line-height:1.25;font-family:sans-serif">BL_bar</tspan></text>
|
||||
style="font-size:16px;line-height:1.25;font-family:sans-serif">br</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
|
||||
|
|
@ -207,7 +207,7 @@
|
|||
id="tspan4527"
|
||||
x="287"
|
||||
y="217.36218"
|
||||
style="font-size:16px;line-height:1.25;font-family:sans-serif">VDD</tspan></text>
|
||||
style="font-size:16px;line-height:1.25;font-family:sans-serif">vdd</tspan></text>
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
d="m 237,346.36218 77,0"
|
||||
|
|
@ -263,7 +263,7 @@
|
|||
id="tspan4793"
|
||||
x="271"
|
||||
y="334.36218"
|
||||
style="font-size:16px;line-height:1.25;font-family:sans-serif">CLK</tspan></text>
|
||||
style="font-size:16px;line-height:1.25;font-family:sans-serif">en</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
|
|
@ -13,8 +13,8 @@
|
|||
height="1052.3622047"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.48.3.1 r9886"
|
||||
sodipodi:docname="sense_amp.svg">
|
||||
inkscape:version="0.92.2 5c3e80d, 2017-08-06"
|
||||
sodipodi:docname="sense_amp_schem.svg">
|
||||
<defs
|
||||
id="defs4" />
|
||||
<sodipodi:namedview
|
||||
|
|
@ -24,16 +24,16 @@
|
|||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="1"
|
||||
inkscape:cx="199"
|
||||
inkscape:cy="520"
|
||||
inkscape:zoom="1.4142136"
|
||||
inkscape:cx="78.947962"
|
||||
inkscape:cy="503.38478"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
inkscape:window-width="1855"
|
||||
inkscape:window-height="1056"
|
||||
inkscape:window-x="65"
|
||||
inkscape:window-y="24"
|
||||
inkscape:window-width="3440"
|
||||
inkscape:window-height="1392"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
|
|
@ -47,7 +47,7 @@
|
|||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
|
|
@ -55,37 +55,6 @@
|
|||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<g
|
||||
id="g3496"
|
||||
transform="translate(-148.99875,80.014073)">
|
||||
<g
|
||||
transform="matrix(1.25,0,0,1.25,240,223.19311)"
|
||||
id="g3011">
|
||||
<path
|
||||
id="path3013"
|
||||
style="fill:none;stroke:#000000;stroke-width:1.60000002;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m 31.199,119.324 29.539,0 0,-14.66 36.922,0 0,14.66 29.539,0"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(1.25,0,0,1.25,240,223.19311)"
|
||||
id="g3015">
|
||||
<path
|
||||
id="path3017"
|
||||
style="fill:none;stroke:#000000;stroke-width:1.60000002;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m 61.09,100.621 36.57,0"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(1.25,0,0,1.25,240,223.19311)"
|
||||
id="g3019">
|
||||
<path
|
||||
id="path3021"
|
||||
style="fill:none;stroke:#000000;stroke-width:1.60000002;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m 58.523,104.664 40.614,0"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
id="g3496-2"
|
||||
transform="matrix(0,-1,1,0,-62.34811,791.36093)">
|
||||
|
|
@ -148,37 +117,6 @@
|
|||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
id="g3496-7"
|
||||
transform="translate(211.00125,80.014073)">
|
||||
<g
|
||||
transform="matrix(1.25,0,0,1.25,240,223.19311)"
|
||||
id="g3011-9">
|
||||
<path
|
||||
id="path3013-2"
|
||||
style="fill:none;stroke:#000000;stroke-width:1.60000002;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m 31.199,119.324 29.539,0 0,-14.66 36.922,0 0,14.66 29.539,0"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(1.25,0,0,1.25,240,223.19311)"
|
||||
id="g3015-8">
|
||||
<path
|
||||
id="path3017-9"
|
||||
style="fill:none;stroke:#000000;stroke-width:1.60000002;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m 61.09,100.621 36.57,0"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(1.25,0,0,1.25,240,223.19311)"
|
||||
id="g3019-4">
|
||||
<path
|
||||
id="path3021-9"
|
||||
style="fill:none;stroke:#000000;stroke-width:1.60000002;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m 58.523,104.664 40.614,0"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
id="g3496-8"
|
||||
transform="matrix(0,-1,1,0,-2.34811,920.37376)">
|
||||
|
|
@ -357,18 +295,18 @@
|
|||
id="path4592"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m 610,452.36218 30,0 0,-120 0,230"
|
||||
style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 604,452.36218 h 30 v -120 230"
|
||||
id="path4594"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
d="m 190,432.36218 0,-20 0,-10"
|
||||
style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 184,416.36218 v -20 -10"
|
||||
id="path4598"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
d="m 550,432.36218 0,-30"
|
||||
style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 544,416.36218 v -30"
|
||||
id="path4600"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
|
|
@ -406,11 +344,11 @@
|
|||
</g>
|
||||
<g
|
||||
id="g3319-3"
|
||||
transform="matrix(1.25,0,0,1,129,112.20718)">
|
||||
transform="matrix(1.25,0,0,1,125,112.20718)">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 409.934,339.155 c 0,1.338 -0.864,2.417 -1.934,2.417 -1.07,0 -1.934,-1.079 -1.934,-2.417 0,-1.333 0.864,-2.417 1.934,-2.417 1.07,0 1.934,1.084 1.934,2.417 z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.93475199;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.93475199;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path3321-5" />
|
||||
</g>
|
||||
<g
|
||||
|
|
@ -466,85 +404,165 @@
|
|||
</g>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:16px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
|
||||
style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
|
||||
x="390"
|
||||
y="172.36218"
|
||||
id="text4691"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
id="text4691"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4693"
|
||||
x="390"
|
||||
y="172.36218">VDD</tspan></text>
|
||||
y="172.36218"
|
||||
style="font-size:16px;line-height:1.25;font-family:sans-serif">vdd</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:16px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
|
||||
style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
|
||||
x="488"
|
||||
y="297.36218"
|
||||
id="text4695"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
id="text4695"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4697"
|
||||
x="488"
|
||||
y="297.36218">DATA</tspan></text>
|
||||
y="297.36218"
|
||||
style="font-size:16px;line-height:1.25;font-family:sans-serif">DATA</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:16px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
|
||||
x="615"
|
||||
style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
|
||||
x="621"
|
||||
y="577.36218"
|
||||
id="text4699"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
id="text4699"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4701"
|
||||
x="615"
|
||||
y="577.36218">BL_bar</tspan></text>
|
||||
x="621"
|
||||
y="577.36218"
|
||||
style="font-size:16px;line-height:1.25;font-family:sans-serif">br</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:16px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
|
||||
style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
|
||||
x="89"
|
||||
y="580.36218"
|
||||
id="text4703"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
id="text4703"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4705"
|
||||
x="89"
|
||||
y="580.36218">BL</tspan></text>
|
||||
y="580.36218"
|
||||
style="font-size:16px;line-height:1.25;font-family:sans-serif">bl</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:16px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
|
||||
style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
|
||||
x="295"
|
||||
y="588.36218"
|
||||
id="text4707"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
id="text4707"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4709"
|
||||
x="295"
|
||||
y="588.36218">EN</tspan></text>
|
||||
y="588.36218"
|
||||
style="font-size:16px;line-height:1.25;font-family:sans-serif">en</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:16px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
|
||||
x="540"
|
||||
y="398.36218"
|
||||
id="text4711"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
|
||||
x="538"
|
||||
y="382.36218"
|
||||
id="text4711"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4713"
|
||||
x="540"
|
||||
y="398.36218">EN</tspan></text>
|
||||
x="538"
|
||||
y="382.36218"
|
||||
style="font-size:16px;line-height:1.25;font-family:sans-serif">en</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:16px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
|
||||
x="180"
|
||||
y="399.36218"
|
||||
id="text4715"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
|
||||
x="177.87868"
|
||||
y="376.02765"
|
||||
id="text4715"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4717"
|
||||
x="180"
|
||||
y="399.36218">EN</tspan></text>
|
||||
x="177.87868"
|
||||
y="376.02765"
|
||||
style="font-size:16px;line-height:1.25;font-family:sans-serif">en</tspan></text>
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:0"
|
||||
d="m 680,572.36218 0,-440 -620,0 0,610 620,0 z"
|
||||
id="path4738"
|
||||
inkscape:connector-curvature="0" />
|
||||
<g
|
||||
transform="rotate(-90,322.13078,437.55515)"
|
||||
id="g161">
|
||||
<g
|
||||
id="g147"
|
||||
transform="matrix(1.25,0,0,1.25,-200,23.193113)">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 434.398,221.727 c 0,2.207 -1.789,4 -4,4 -2.207,0 -4,-1.793 -4,-4 0,-2.211 1.793,-4 4,-4 2.211,0 4,1.789 4,4 z"
|
||||
style="fill:none;stroke:#000000;stroke-width:1.30079997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path145" />
|
||||
</g>
|
||||
<g
|
||||
id="g151"
|
||||
transform="matrix(0,1.25,-1.25,0,-200,23.193113)">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 175.324,-407.199 h 29.539 v -14.66 h 36.922 v 14.66 h 29.539"
|
||||
style="fill:none;stroke:#000000;stroke-width:1.60000002;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path149" />
|
||||
</g>
|
||||
<g
|
||||
id="g155"
|
||||
transform="matrix(0,1.25,-1.25,0,-200,23.193113)">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 205.215,-425.902 h 36.57"
|
||||
style="fill:none;stroke:#000000;stroke-width:1.60000002;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path153" />
|
||||
</g>
|
||||
<g
|
||||
id="g159"
|
||||
transform="matrix(0,1.25,-1.25,0,-200,23.193113)">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 202.648,-421.859 h 40.614"
|
||||
style="fill:none;stroke:#000000;stroke-width:1.60000002;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path157" />
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
id="g179"
|
||||
transform="rotate(-90,502.65766,258.08202)">
|
||||
<g
|
||||
transform="matrix(1.25,0,0,1.25,-200,23.193113)"
|
||||
id="g165">
|
||||
<path
|
||||
id="path163"
|
||||
style="fill:none;stroke:#000000;stroke-width:1.30079997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 434.398,221.727 c 0,2.207 -1.789,4 -4,4 -2.207,0 -4,-1.793 -4,-4 0,-2.211 1.793,-4 4,-4 2.211,0 4,1.789 4,4 z"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(0,1.25,-1.25,0,-200,23.193113)"
|
||||
id="g169">
|
||||
<path
|
||||
id="path167"
|
||||
style="fill:none;stroke:#000000;stroke-width:1.60000002;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 175.324,-407.199 h 29.539 v -14.66 h 36.922 v 14.66 h 29.539"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(0,1.25,-1.25,0,-200,23.193113)"
|
||||
id="g173">
|
||||
<path
|
||||
id="path171"
|
||||
style="fill:none;stroke:#000000;stroke-width:1.60000002;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 205.215,-425.902 h 36.57"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(0,1.25,-1.25,0,-200,23.193113)"
|
||||
id="g177">
|
||||
<path
|
||||
id="path175"
|
||||
style="fill:none;stroke:#000000;stroke-width:1.60000002;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 202.648,-421.859 h 40.614"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 60 KiB |