Merge branch 'dev' into add_wmask

This commit is contained in:
jsowash 2019-08-29 12:56:11 -07:00
commit af3d2af0ec
38 changed files with 4673 additions and 377 deletions

View File

@ -22,7 +22,7 @@ class verilog:
self.vf.write("// OpenRAM SRAM model\n")
self.vf.write("// Words: {0}\n".format(self.num_words))
self.vf.write("// Word size: {0}\n".format(self.word_size))
if self.write_size is not None:
if self.write_size:
self.vf.write("// Write size: {0}\n\n".format(self.write_size))
else:
self.vf.write("\n")
@ -37,22 +37,22 @@ class verilog:
self.vf.write("// Port {0}: W\n".format(port))
if port in self.readwrite_ports:
self.vf.write(" clk{0},csb{0},web{0},".format(port))
if self.write_size is not None:
if self.write_size:
self.vf.write("wmask{},".format(port))
self.vf.write("ADDR{0},DIN{0},DOUT{0}".format(port))
self.vf.write("addr{0},din{0},dout{0}".format(port))
elif port in self.write_ports:
self.vf.write(" clk{0},csb{0},".format(port))
if self.write_size is not None:
if self.write_size:
self.vf.write("wmask{},".format(port))
self.vf.write("ADDR{0},DIN{0}".format(port))
self.vf.write("addr{0},din{0}".format(port))
elif port in self.read_ports:
self.vf.write(" clk{0},csb{0},ADDR{0},DOUT{0}".format(port))
self.vf.write(" clk{0},csb{0},addr{0},dout{0}".format(port))
# Continue for every port on a new line
if port != self.all_ports[-1]:
self.vf.write(",\n")
self.vf.write("\n );\n\n")
if self.write_size is not None:
if self.write_size:
self.num_wmasks = int(self.word_size/self.write_size)
self.vf.write(" parameter NUM_WMASKS = {0} ;\n".format(self.num_wmasks))
self.vf.write(" parameter DATA_WIDTH = {0} ;\n".format(self.word_size))
@ -99,13 +99,13 @@ class verilog:
if port in self.readwrite_ports:
self.vf.write(" reg web{0}_reg;\n".format(port))
if port in self.write_ports:
if self.write_size is not None:
if self.write_size:
self.vf.write(" reg [NUM_WMASKS-1:0] wmask{0}_reg;\n".format(port))
self.vf.write(" reg [ADDR_WIDTH-1:0] ADDR{0}_reg;\n".format(port))
self.vf.write(" reg [ADDR_WIDTH-1:0] addr{0}_reg;\n".format(port))
if port in self.write_ports:
self.vf.write(" reg [DATA_WIDTH-1:0] DIN{0}_reg;\n".format(port))
self.vf.write(" reg [DATA_WIDTH-1:0] din{0}_reg;\n".format(port))
if port in self.read_ports:
self.vf.write(" reg [DATA_WIDTH-1:0] DOUT{0};\n".format(port))
self.vf.write(" reg [DATA_WIDTH-1:0] dout{0};\n".format(port))
def add_flops(self, port):
"""
@ -119,31 +119,31 @@ class verilog:
if port in self.readwrite_ports:
self.vf.write(" web{0}_reg = web{0};\n".format(port))
if port in self.write_ports:
if self.write_size is not None:
if self.write_size:
self.vf.write(" wmask{0}_reg = wmask{0};\n".format(port))
self.vf.write(" ADDR{0}_reg = ADDR{0};\n".format(port))
self.vf.write(" addr{0}_reg = addr{0};\n".format(port))
if port in self.write_ports:
self.vf.write(" DIN{0}_reg = DIN{0};\n".format(port))
self.vf.write(" din{0}_reg = din{0};\n".format(port))
if port in self.read_ports:
self.vf.write(" DOUT{0} = {1}'bx;\n".format(port,self.word_size))
self.vf.write(" dout{0} = {1}'bx;\n".format(port,self.word_size))
if port in self.readwrite_ports:
self.vf.write(" if ( !csb{0}_reg && web{0}_reg ) \n".format(port))
self.vf.write(" $display($time,\" Reading %m ADDR{0}=%b DOUT{0}=%b\",ADDR{0}_reg,mem[ADDR{0}_reg]);\n".format(port))
self.vf.write(" $display($time,\" Reading %m addr{0}=%b dout{0}=%b\",addr{0}_reg,mem[addr{0}_reg]);\n".format(port))
elif port in self.read_ports:
self.vf.write(" if ( !csb{0}_reg ) \n".format(port))
self.vf.write(" $display($time,\" Reading %m ADDR{0}=%b DOUT{0}=%b\",ADDR{0}_reg,mem[ADDR{0}_reg]);\n".format(port))
self.vf.write(" $display($time,\" Reading %m addr{0}=%b dout{0}=%b\",addr{0}_reg,mem[addr{0}_reg]);\n".format(port))
if port in self.readwrite_ports:
self.vf.write(" if ( !csb{0}_reg && !web{0}_reg )\n".format(port))
if self.write_size is not None:
self.vf.write(" $display($time,\" Writing %m ADDR{0}=%b DIN{0}=%b wmask{0}=%b\",ADDR{0}_reg,DIN{0}_reg,wmask{0}_reg);\n".format(port))
if self.write_size:
self.vf.write(" $display($time,\" Writing %m addr{0}=%b din{0}=%b wmask{0}=%b\",addr{0}_reg,din{0}_reg,wmask{0}_reg);\n".format(port))
else:
self.vf.write(" $display($time,\" Writing %m ADDR{0}=%b DIN{0}=%b\",ADDR{0}_reg,DIN{0}_reg);\n".format(port))
self.vf.write(" $display($time,\" Writing %m addr{0}=%b din{0}=%b\",addr{0}_reg,din{0}_reg);\n".format(port))
elif port in self.write_ports:
self.vf.write(" if ( !csb{0}_reg )\n".format(port))
if self.write_size is not None:
self.vf.write(" $display($time,\" Writing %m ADDR{0}=%b DIN{0}=%b wmask{0}=%b\",ADDR{0}_reg,DIN{0}_reg,wmask{0}_reg);\n".format(port))
if self.write_size:
self.vf.write(" $display($time,\" Writing %m addr{0}=%b din{0}=%b wmask{0}=%b\",addr{0}_reg,din{0}_reg,wmask{0}_reg);\n".format(port))
else:
self.vf.write(" $display($time,\" Writing %m ADDR{0}=%b DIN{0}=%b\",ADDR{0}_reg,DIN{0}_reg);\n".format(port))
self.vf.write(" $display($time,\" Writing %m addr{0}=%b din{0}=%b\",addr{0}_reg,din{0}_reg);\n".format(port))
self.vf.write(" end\n\n")
@ -156,13 +156,13 @@ class verilog:
self.vf.write(" input csb{0}; // active low chip select\n".format(port))
if port in self.readwrite_ports:
self.vf.write(" input web{0}; // active low write control\n".format(port))
if self.write_size is not None:
if self.write_size:
self.vf.write(" input [NUM_WMASKS-1:0] wmask{0}; // write mask\n".format(port))
self.vf.write(" input [ADDR_WIDTH-1:0] ADDR{0};\n".format(port))
self.vf.write(" input [ADDR_WIDTH-1:0] addr{0};\n".format(port))
if port in self.write_ports:
self.vf.write(" input [DATA_WIDTH-1:0] DIN{0};\n".format(port))
self.vf.write(" input [DATA_WIDTH-1:0] din{0};\n".format(port))
if port in self.read_ports:
self.vf.write(" output [DATA_WIDTH-1:0] DOUT{0};\n".format(port))
self.vf.write(" output [DATA_WIDTH-1:0] dout{0};\n".format(port))
def add_write_block(self, port):
"""
@ -175,25 +175,25 @@ class verilog:
self.vf.write(" always @ (negedge clk{0})\n".format(port))
self.vf.write(" begin : MEM_WRITE{0}\n".format(port))
if port in self.readwrite_ports:
if self.write_size is not None:
if self.write_size:
self.vf.write(" if ( !csb{0}_reg && !web{0}_reg ) begin\n".format(port))
else:
self.vf.write(" if ( !csb{0}_reg && !web{0}_reg )\n".format(port))
else:
if self.write_size is not None:
if self.write_size:
self.vf.write(" if (!csb{0}_reg) begin\n".format(port))
else:
self.vf.write(" if (!csb{0}_reg)\n".format(port))
if self.write_size is not None:
if self.write_size:
for mask in range(0,self.num_wmasks):
lower = mask * self.write_size
upper = lower + self.write_size-1
self.vf.write(" if (wmask{0}_reg[{1}])\n".format(port,mask))
self.vf.write(" mem[ADDR{0}_reg][{1}:{2}] = DIN{0}_reg[{1}:{2}];\n".format(port,upper,lower))
self.vf.write(" mem[addr{0}_reg][{1}:{2}] = din{0}_reg[{1}:{2}];\n".format(port,upper,lower))
self.vf.write(" end\n")
else:
self.vf.write(" mem[ADDR{0}_reg] = DIN{0}_reg;\n".format(port))
self.vf.write(" mem[addr{0}_reg] = din{0}_reg;\n".format(port))
self.vf.write(" end\n")
def add_read_block(self, port):
@ -209,6 +209,6 @@ class verilog:
self.vf.write(" if (!csb{0}_reg && web{0}_reg)\n".format(port))
else:
self.vf.write(" if (!csb{0}_reg)\n".format(port))
self.vf.write(" DOUT{0} <= #(DELAY) mem[ADDR{0}_reg];\n".format(port))
self.vf.write(" dout{0} <= #(DELAY) mem[addr{0}_reg];\n".format(port))
self.vf.write(" end\n")

View File

@ -46,7 +46,7 @@ class delay(simulation):
self.targ_read_ports = []
self.targ_write_ports = []
self.period = 0
if self.write_size is not None:
if self.write_size:
self.num_wmasks = int(self.word_size / self.write_size)
else:
self.num_wmasks = 0
@ -1191,7 +1191,7 @@ class delay(simulation):
self.measure_cycles[write_port][sram_op.WRITE_ZERO] = len(self.cycle_times)-1
# This also ensures we will have a H->L transition on the next read
self.add_read("R data 1 address {} to set DOUT caps".format(inverse_address),
self.add_read("R data 1 address {} to set dout caps".format(inverse_address),
inverse_address,data_zeros,wmask_ones,read_port)
self.add_read("R data 0 address {} to check W0 worked".format(self.probe_address),
@ -1205,11 +1205,11 @@ class delay(simulation):
self.probe_address,data_ones,wmask_ones,write_port)
self.measure_cycles[write_port][sram_op.WRITE_ONE] = len(self.cycle_times)-1
self.add_write("W data 0 address {} to clear DIN caps".format(inverse_address),
self.add_write("W data 0 address {} to clear din caps".format(inverse_address),
inverse_address,data_zeros,wmask_ones,write_port)
# This also ensures we will have a L->H transition on the next read
self.add_read("R data 0 address {} to clear DOUT caps".format(inverse_address),
self.add_read("R data 0 address {} to clear dout caps".format(inverse_address),
inverse_address,data_zeros,wmask_ones,read_port)
self.add_read("R data 1 address {} to check W1 worked".format(self.probe_address),

View File

@ -34,7 +34,7 @@ class functional(simulation):
if OPTS.is_unit_test:
random.seed(12345)
if self.write_size is not None:
if self.write_size:
self.num_wmasks = int(self.word_size / self.write_size)
else:
self.num_wmasks = 0
@ -61,7 +61,7 @@ class functional(simulation):
def initialize_wmask(self):
self.wmask = ""
if self.write_size is not None:
if self.write_size:
# initialize all wmask bits to 1
for bit in range(self.num_wmasks):
self.wmask += "1"
@ -76,7 +76,7 @@ class functional(simulation):
self.write_functional_stimulus()
self.stim.run_sim()
# read DOUT values from SPICE simulation. If the values do not fall within the noise margins, return the error.
# read dout values from SPICE simulation. If the values do not fall within the noise margins, return the error.
(success, error) = self.read_stim_results()
if not success:
return (0, error)
@ -85,7 +85,7 @@ class functional(simulation):
return self.check_stim_results()
def write_random_memory_sequence(self):
if self.write_size is not None:
if self.write_size:
rw_ops = ["noop", "write", "partial_write", "read"]
w_ops = ["noop", "write", "partial_write"]
else:
@ -187,7 +187,7 @@ class functional(simulation):
self.add_noop_all_ports(comment, "0"*self.addr_size, "0"*self.word_size, "0"*self.num_wmasks)
def read_stim_results(self):
# Extrat DOUT values from spice timing.lis
# Extrat dout values from spice timing.lis
for (word, dout_port, eo_period, check) in self.write_check:
sp_read_value = ""
for bit in range(self.word_size):
@ -338,7 +338,7 @@ class functional(simulation):
# Generate wmask bits
for port in self.write_ports:
if self.write_size is not None:
if self.write_size:
self.sf.write("\n* Generation of wmask signals\n")
for bit in range(self.num_wmasks):
sig_name = "WMASK{0}_{1} ".format(port, bit)
@ -357,7 +357,7 @@ class functional(simulation):
t_rise=self.slew,
t_fall=self.slew)
# Generate DOUT value measurements
# Generate dout value measurements
self.sf.write("\n * Generation of dout measurements\n")
for (word, dout_port, eo_period, check) in self.write_check:
t_intital = eo_period - 0.01*self.period

View File

@ -278,10 +278,10 @@ class lib:
# self.lib.write(" }\n\n")
def write_bus(self):
""" Adds format of DATA and ADDR bus."""
""" Adds format of data and addr bus."""
self.lib.write("\n\n")
self.lib.write(" type (DATA){\n")
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.sram.word_size))
@ -289,7 +289,7 @@ class lib:
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(" 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.sram.addr_size))
@ -329,18 +329,18 @@ class lib:
def write_data_bus_output(self, read_port):
""" Adds data bus timing results."""
self.lib.write(" bus(DOUT{0}){{\n".format(read_port))
self.lib.write(" bus_type : DATA; \n")
self.lib.write(" bus(dout{0}){{\n".format(read_port))
self.lib.write(" bus_type : data; \n")
self.lib.write(" direction : output; \n")
# This is conservative, but limit to range that we characterized.
self.lib.write(" max_capacitance : {0}; \n".format(max(self.loads)/1000))
self.lib.write(" min_capacitance : {0}; \n".format(min(self.loads)/1000))
self.lib.write(" memory_read(){ \n")
self.lib.write(" address : ADDR{0}; \n".format(read_port))
self.lib.write(" address : addr{0}; \n".format(read_port))
self.lib.write(" }\n")
self.lib.write(" pin(DOUT{0}[{1}:0]){{\n".format(read_port,self.sram.word_size-1))
self.lib.write(" pin(dout{0}[{1}:0]){{\n".format(read_port,self.sram.word_size-1))
self.lib.write(" timing(){ \n")
self.lib.write(" timing_sense : non_unate; \n")
self.lib.write(" related_pin : \"clk{0}\"; \n".format(read_port))
@ -362,18 +362,18 @@ class lib:
self.lib.write(" }\n\n") # bus
def write_data_bus_input(self, write_port):
""" Adds DIN data bus timing results."""
""" Adds din data bus timing results."""
self.lib.write(" bus(DIN{0}){{\n".format(write_port))
self.lib.write(" bus_type : DATA; \n")
self.lib.write(" bus(din{0}){{\n".format(write_port))
self.lib.write(" bus_type : data; \n")
self.lib.write(" direction : input; \n")
# This is conservative, but limit to range that we characterized.
self.lib.write(" capacitance : {0}; \n".format(tech.spice["dff_in_cap"]/1000))
self.lib.write(" memory_write(){ \n")
self.lib.write(" address : ADDR{0}; \n".format(write_port))
self.lib.write(" address : addr{0}; \n".format(write_port))
self.lib.write(" clocked_on : clk{0}; \n".format(write_port))
self.lib.write(" }\n")
self.lib.write(" pin(DIN{0}[{1}:0]){{\n".format(write_port,self.sram.word_size-1))
self.lib.write(" pin(din{0}[{1}:0]){{\n".format(write_port,self.sram.word_size-1))
self.write_FF_setuphold(write_port)
self.lib.write(" }\n") # pin
self.lib.write(" }\n") #bus
@ -388,12 +388,12 @@ class lib:
def write_addr_bus(self, port):
""" Adds addr bus timing results."""
self.lib.write(" bus(ADDR{0}){{\n".format(port))
self.lib.write(" bus_type : ADDR; \n")
self.lib.write(" bus(addr{0}){{\n".format(port))
self.lib.write(" bus_type : addr; \n")
self.lib.write(" direction : input; \n")
self.lib.write(" capacitance : {0}; \n".format(tech.spice["dff_in_cap"]/1000))
self.lib.write(" max_transition : {0};\n".format(self.slews[-1]))
self.lib.write(" pin(ADDR{0}[{1}:0])".format(port,self.sram.addr_size-1))
self.lib.write(" pin(addr{0}[{1}:0])".format(port,self.sram.addr_size-1))
self.lib.write("{\n")
self.write_FF_setuphold(port)
@ -577,10 +577,10 @@ class lib:
datasheet.write(str(self.sram.width * self.sram.height)+',')
# write timing information for all ports
for port in self.all_ports:
#DIN timings
#din timings
if port in self.write_ports:
datasheet.write("{0},{1},{2},{3},{4},{5},{6},{7},{8},".format(
"DIN{1}[{0}:0]".format(self.sram.word_size - 1, port),
"din{1}[{0}:0]".format(self.sram.word_size - 1, port),
min(list(map(round_time,self.times["setup_times_LH"]))),
max(list(map(round_time,self.times["setup_times_LH"]))),
@ -596,10 +596,10 @@ class lib:
))
for port in self.all_ports:
#DOUT timing
#dout timing
if port in self.read_ports:
datasheet.write("{0},{1},{2},{3},{4},{5},{6},{7},{8},".format(
"DOUT{1}[{0}:0]".format(self.sram.word_size - 1, port),
"dout{1}[{0}:0]".format(self.sram.word_size - 1, port),
min(list(map(round_time,self.char_port_results[port]["delay_lh"]))),
max(list(map(round_time,self.char_port_results[port]["delay_lh"]))),
@ -634,9 +634,9 @@ class lib:
))
for port in self.all_ports:
#ADDR timings
#addr timings
datasheet.write("{0},{1},{2},{3},{4},{5},{6},{7},{8},".format(
"ADDR{1}[{0}:0]".format(self.sram.addr_size - 1, port),
"addr{1}[{0}:0]".format(self.sram.addr_size - 1, port),
min(list(map(round_time,self.times["setup_times_LH"]))),
max(list(map(round_time,self.times["setup_times_LH"]))),

View File

@ -31,7 +31,7 @@ class simulation():
self.readwrite_ports = self.sram.readwrite_ports
self.read_ports = self.sram.read_ports
self.write_ports = self.sram.write_ports
if self.write_size is not None:
if self.write_size:
self.num_wmasks = int(self.word_size/self.write_size)
else:
self.num_wmasks = 0
@ -53,9 +53,9 @@ class simulation():
self.gnd_voltage = 0
def create_signal_names(self):
self.addr_name = "A"
self.din_name = "DIN"
self.dout_name = "DOUT"
self.addr_name = "a"
self.din_name = "din"
self.dout_name = "dout"
self.pins = self.gen_pin_names(port_signal_names=(self.addr_name,self.din_name,self.dout_name),
port_info=(len(self.all_ports),self.write_ports,self.read_ports),
abits=self.addr_size,
@ -303,7 +303,7 @@ class simulation():
for port in range(total_ports):
pin_names.append("{0}{1}".format(tech.spice["clk"], port))
if self.write_size is not None:
if self.write_size:
for port in write_index:
for bit in range(self.num_wmasks):
pin_names.append("WMASK{0}_{1}".format(port,bit))

View File

@ -161,7 +161,7 @@ def parse_characterizer_csv(f, pages):
# check current .lib file produces the slowest timing results
while(True):
col_start = col
if(row[col].startswith('DIN')):
if(row[col].startswith('din')):
start = col
for item in sheet.timing_table.rows:
if item[0].startswith(row[col]):
@ -200,7 +200,7 @@ def parse_characterizer_csv(f, pages):
col += 1
elif(row[col].startswith('DOUT')):
elif(row[col].startswith('dout')):
start = col
for item in sheet.timing_table.rows:
if item[0].startswith(row[col]):
@ -239,7 +239,7 @@ def parse_characterizer_csv(f, pages):
col += 1
elif(row[col].startswith('CSb')):
elif(row[col].startswith('csb')):
start = col
for item in sheet.timing_table.rows:
if item[0].startswith(row[col]):
@ -278,7 +278,7 @@ def parse_characterizer_csv(f, pages):
col += 1
elif(row[col].startswith('WEb')):
elif(row[col].startswith('web')):
start = col
for item in sheet.timing_table.rows:
if item[0].startswith(row[col]):
@ -317,7 +317,7 @@ def parse_characterizer_csv(f, pages):
col += 1
elif(row[col].startswith('ADDR')):
elif(row[col].startswith('addr')):
start = col
for item in sheet.timing_table.rows:
if item[0].startswith(row[col]):
@ -441,7 +441,7 @@ def parse_characterizer_csv(f, pages):
# parse initial timing information
while(True):
col_start = col
if(row[col].startswith('DIN')):
if(row[col].startswith('din')):
start = col
new_sheet.timing_table.add_row(
@ -465,7 +465,7 @@ def parse_characterizer_csv(f, pages):
col += 1
elif(row[col].startswith('DOUT')):
elif(row[col].startswith('dout')):
start = col
new_sheet.timing_table.add_row(
@ -489,7 +489,7 @@ def parse_characterizer_csv(f, pages):
col += 1
elif(row[col].startswith('CSb')):
elif(row[col].startswith('csb')):
start = col
new_sheet.timing_table.add_row(
@ -513,7 +513,7 @@ def parse_characterizer_csv(f, pages):
col += 1
elif(row[col].startswith('WEb')):
elif(row[col].startswith('web')):
start = col
new_sheet.timing_table.add_row(
@ -537,7 +537,7 @@ def parse_characterizer_csv(f, pages):
col += 1
elif(row[col].startswith('ADDR')):
elif(row[col].startswith('addr')):
start = col
new_sheet.timing_table.add_row(

View File

@ -19,8 +19,9 @@ import re
import copy
import importlib
USAGE = "Usage: openram.py [options] <config file>\nUse -h for help.\n"
# Anonymous object that will be the options
VERSION = "1.1.0"
NAME = "OpenRAM v{}".format(VERSION)
USAGE = "openram.py [options] <config file>\nUse -h for help.\n"
OPTS = options.options()
CHECKPOINT_OPTS=None
@ -57,9 +58,9 @@ def parse_args():
}
parser = optparse.OptionParser(option_list=option_list,
description="Compile and/or characterize an SRAM.",
description=NAME,
usage=USAGE,
version="OpenRAM")
version=VERSION)
(options, args) = parser.parse_args(values=OPTS)
# If we don't specify a tech, assume scmos.
@ -79,8 +80,7 @@ def print_banner():
return
debug.print_raw("|==============================================================================|")
name = "OpenRAM Compiler"
debug.print_raw("|=========" + name.center(60) + "=========|")
debug.print_raw("|=========" + NAME.center(60) + "=========|")
debug.print_raw("|=========" + " ".center(60) + "=========|")
debug.print_raw("|=========" + "VLSI Design and Automation Lab".center(60) + "=========|")
debug.print_raw("|=========" + "Computer Science and Engineering Department".center(60) + "=========|")

View File

@ -30,7 +30,7 @@ class bank(design.design):
self.sram_config = sram_config
sram_config.set_local_config(self)
if self.write_size is not None:
if self.write_size:
self.num_wmasks = int(self.word_size/self.write_size)
else:
self.num_wmasks = 0
@ -722,7 +722,7 @@ class bank(design.design):
din_name = "din{0}_{1}".format(port,row)
self.copy_layout_pin(self.port_data_inst[port], data_name, din_name)
if self.word_size is not None:
if self.word_size:
for row in range(self.num_wmasks):
wmask_name = "bank_wmask_{}".format(row)
bank_wmask_name = "bank_wmask{0}_{1}".format(port, row)

View File

@ -65,11 +65,11 @@ class multibank(design.design):
def add_pins(self):
""" Adding pins for Bank module"""
for i in range(self.word_size):
self.add_pin("DOUT_{0}".format(i),"OUT")
self.add_pin("dout_{0}".format(i),"OUT")
for i in range(self.word_size):
self.add_pin("BANK_DIN_{0}".format(i),"IN")
self.add_pin("bank_din_{0}".format(i),"IN")
for i in range(self.addr_size):
self.add_pin("A_{0}".format(i),"INPUT")
self.add_pin("a_{0}".format(i),"INPUT")
# For more than one bank, we have a bank select and name
# the signals gated_*.
@ -187,7 +187,7 @@ class multibank(design.design):
words_per_row=self.words_per_row)
self.add_mod(self.sense_amp_array)
if self.write_size is not None:
if self.write_size:
self.write_mask_driver_array = self.mod_write_mask_driver_array(columns=self.num_cols,
word_size=self.word_size,
write_size=self.write_size)
@ -302,7 +302,7 @@ class multibank(design.design):
temp = []
for i in range(self.word_size):
temp.append("BANK_DIN_{0}".format(i))
temp.append("bank_din_{0}".format(i))
for i in range(self.word_size):
if (self.words_per_row == 1):
temp.append("bl_{0}".format(i))
@ -325,7 +325,7 @@ class multibank(design.design):
for i in range(self.word_size):
temp.append("sa_out_{0}".format(i))
for i in range(self.word_size):
temp.append("DOUT_{0}".format(i))
temp.append("dout_{0}".format(i))
temp.extend([self.prefix+"tri_en", self.prefix+"tri_en_bar", "vdd", "gnd"])
self.connect_inst(temp)
@ -596,7 +596,7 @@ class multibank(design.design):
""" Add pins for the sense amp output """
for i in range(self.word_size):
data_pin = self.sense_amp_array_inst.get_pin("data_{}".format(i))
self.add_layout_pin_rect_center(text="DOUT_{}".format(i),
self.add_layout_pin_rect_center(text="dout_{}".format(i),
layer=data_pin.layer,
offset=data_pin.center(),
height=data_pin.height(),
@ -606,7 +606,7 @@ class multibank(design.design):
""" Metal 3 routing of tri_gate output data """
for i in range(self.word_size):
data_pin = self.tri_gate_array_inst.get_pin("out_{}".format(i))
self.add_layout_pin_rect_center(text="DOUT_{}".format(i),
self.add_layout_pin_rect_center(text="dout_{}".format(i),
layer=data_pin.layer,
offset=data_pin.center(),
height=data_pin.height(),
@ -619,8 +619,8 @@ class multibank(design.design):
# Create inputs for the row address lines
for i in range(self.row_addr_size):
addr_idx = i + self.col_addr_size
decoder_name = "A_{}".format(i)
addr_name = "A_{}".format(addr_idx)
decoder_name = "a_{}".format(i)
addr_name = "a_{}".format(addr_idx)
self.copy_layout_pin(self.row_decoder_inst, decoder_name, addr_name)
@ -629,7 +629,7 @@ class multibank(design.design):
for i in range(self.word_size):
data_name = "data_{}".format(i)
din_name = "BANK_DIN_{}".format(i)
din_name = "bank_din_{}".format(i)
self.copy_layout_pin(self.write_driver_array_inst, data_name, din_name)
@ -668,7 +668,7 @@ class multibank(design.design):
decode_names = ["Zb", "Z"]
# The Address LSB
self.copy_layout_pin(self.col_decoder_inst, "A", "A[0]")
self.copy_layout_pin(self.col_decoder_inst, "A", "a[0]")
elif self.col_addr_size > 1:
decode_names = []
@ -677,7 +677,7 @@ class multibank(design.design):
for i in range(self.col_addr_size):
decoder_name = "in_{}".format(i)
addr_name = "A_{}".format(i)
addr_name = "a_{}".format(i)
self.copy_layout_pin(self.col_decoder_inst, decoder_name, addr_name)
@ -827,4 +827,4 @@ class multibank(design.design):
rotate=90)
self.add_via(layers=("metal2","via2","metal3"),
offset=in_pin + self.m2m3_via_offset,
rotate=90)
rotate=90)

View File

@ -22,7 +22,7 @@ class port_data(design.design):
sram_config.set_local_config(self)
self.port = port
if self.write_size is not None:
if self.write_size:
self.num_wmasks = int(self.word_size/self.write_size)
else:
self.num_wmasks = 0
@ -58,7 +58,7 @@ class port_data(design.design):
if self.write_driver_array:
self.create_write_driver_array()
if self.write_size is not None:
if self.write_size:
self.create_write_mask_and_array()
else:
self.write_mask_and_array_inst = None
@ -187,7 +187,7 @@ class port_data(design.design):
word_size=self.word_size,
write_size=self.write_size)
self.add_mod(self.write_driver_array)
if self.write_size is not None:
if self.write_size:
self.write_mask_and_array = factory.create(module_type="write_mask_and_array",
columns=self.num_cols,
word_size=self.word_size,
@ -320,7 +320,7 @@ class port_data(design.design):
temp.append(self.bl_names[self.port] + "_out_{0}".format(bit))
temp.append(self.br_names[self.port] + "_out_{0}".format(bit))
if self.write_size is not None:
if self.write_size:
for i in range(self.num_wmasks):
temp.append("wdriver_sel_{}".format(i))
else:

View File

@ -30,7 +30,7 @@ class write_driver_array(design.design):
self.write_size = write_size
self.words_per_row = int(columns / word_size)
if self.write_size is not None:
if self.write_size:
self.num_wmasks = int(self.word_size/self.write_size)
self.create_netlist()
@ -62,7 +62,7 @@ class write_driver_array(design.design):
for i in range(self.word_size):
self.add_pin("bl_{0}".format(i), "OUTPUT")
self.add_pin("br_{0}".format(i), "OUTPUT")
if self.write_size is not None:
if self.write_size:
for i in range(self.num_wmasks):
self.add_pin("en_{0}".format(i), "INPUT")
else:
@ -88,7 +88,7 @@ class write_driver_array(design.design):
self.driver_insts[index]=self.add_inst(name=name,
mod=self.driver)
if self.write_size is not None:
if self.write_size:
self.connect_inst(["data_{0}".format(index),
"bl_{0}".format(index),
"br_{0}".format(index),
@ -148,7 +148,7 @@ class write_driver_array(design.design):
self.add_layout_pin_rect_center(text=n,
layer="metal3",
offset=pin_pos)
if self.write_size is not None:
if self.write_size:
for bit in range(self.num_wmasks):
en_pin = self.driver_insts[bit*self.write_size].get_pin("en")
# Determine width of wmask modified en_pin with/without col mux

View File

@ -44,7 +44,7 @@ class sram_1bank(sram_base):
if self.col_addr_dff:
self.col_addr_dff_insts = self.create_col_addr_dff()
if self.write_size is not None:
if self.write_size:
self.wmask_dff_insts = self.create_wmask_dff()
self.data_dff_insts = self.create_data_dff()
else:
@ -77,7 +77,7 @@ class sram_1bank(sram_base):
# Port 0
port = 0
if self.write_size is not None:
if self.write_size:
if port in self.write_ports:
# Add the write mask flops below the write mask AND array.
wmask_pos[port] = vector(self.bank.bank_array_ll.x,
@ -135,7 +135,7 @@ class sram_1bank(sram_base):
port = 1
if port in self.write_ports:
if self.write_size is not None:
if self.write_size:
# Add the write mask flops below the write mask AND array.
wmask_pos[port] = vector(self.bank.bank_array_ur.x - self.data_dff_insts[port].width,
self.bank.height + 0.5*max_gap_size + self.dff.height)
@ -195,19 +195,20 @@ class sram_1bank(sram_base):
if port in self.read_ports:
for bit in range(self.word_size):
self.copy_layout_pin(self.bank_inst, "dout{0}_{1}".format(port,bit), "DOUT{0}[{1}]".format(port,bit))
self.copy_layout_pin(self.bank_inst, "dout{0}_{1}".format(port,bit), "dout{0}[{1}]".format(port,bit))
# Lower address bits
for bit in range(self.col_addr_size):
self.copy_layout_pin(self.col_addr_dff_insts[port], "din_{}".format(bit),"ADDR{0}[{1}]".format(port,bit))
self.copy_layout_pin(self.col_addr_dff_insts[port], "din_{}".format(bit),"addr{0}[{1}]".format(port,bit))
# Upper address bits
for bit in range(self.row_addr_size):
self.copy_layout_pin(self.row_addr_dff_insts[port], "din_{}".format(bit),"ADDR{0}[{1}]".format(port,bit+self.col_addr_size))
self.copy_layout_pin(self.row_addr_dff_insts[port], "din_{}".format(bit),"addr{0}[{1}]".format(port,bit+self.col_addr_size))
if port in self.write_ports:
for bit in range(self.word_size):
self.copy_layout_pin(self.data_dff_insts[port], "din_{}".format(bit), "DIN{0}[{1}]".format(port,bit))
if self.write_size is not None:
self.copy_layout_pin(self.data_dff_insts[port], "din_{}".format(bit), "din{0}[{1}]".format(port,bit))
if self.write_size:
for bit in range(self.num_wmasks):
self.copy_layout_pin(self.wmask_dff_insts[port], "din_{}".format(bit), "wmask{0}[{1}]".format(port,bit))
@ -228,7 +229,7 @@ class sram_1bank(sram_base):
self.route_data_dff()
if self.write_size is not None:
if self.write_size:
self.route_wmask_dff()
def route_clk(self):
@ -282,7 +283,7 @@ class sram_1bank(sram_base):
self.add_path("metal2",[mid_pos, clk_steiner_pos], width=max(m2m3.width,m2m3.height))
self.add_wire(("metal3","via2","metal2"),[data_dff_clk_pos, mid_pos, clk_steiner_pos])
if self.write_size is not None:
if self.write_size:
wmask_dff_clk_pin = self.wmask_dff_insts[port].get_pin("clk")
wmask_dff_clk_pos = wmask_dff_clk_pin.center()
mid_pos = vector(clk_steiner_pos.x, wmask_dff_clk_pos.y)
@ -362,7 +363,7 @@ class sram_1bank(sram_base):
dff_names = ["dout_{}".format(x) for x in range(self.word_size)]
dff_pins = [self.data_dff_insts[port].get_pin(x) for x in dff_names]
if self.write_size is not None:
if self.write_size:
for x in dff_names:
pin_offset = self.data_dff_insts[port].get_pin(x).center()
self.add_via_center(layers=("metal1", "via1", "metal2"),
@ -375,7 +376,7 @@ class sram_1bank(sram_base):
bank_names = ["din{0}_{1}".format(port,x) for x in range(self.word_size)]
bank_pins = [self.bank_inst.get_pin(x) for x in bank_names]
if self.write_size is not None:
if self.write_size:
for x in bank_names:
pin_offset = self.bank_inst.get_pin(x).bc()
self.add_via_center(layers=("metal1", "via1", "metal2"),
@ -386,7 +387,7 @@ class sram_1bank(sram_base):
offset=pin_offset)
route_map = list(zip(bank_pins, dff_pins))
if self.write_size is not None:
if self.write_size:
self.create_horizontal_channel_route(netlist=route_map,
offset=offset,
layer_stack=("metal3", "via3", "metal4"))
@ -440,7 +441,7 @@ class sram_1bank(sram_base):
#Data dffs and wmask dffs are only for writing so are not useful for evaluating read delay.
for inst in self.data_dff_insts:
self.graph_inst_exclude.add(inst)
if self.write_size is not None:
if self.write_size:
for inst in self.wmask_dff_insts:
self.graph_inst_exclude.add(inst)

View File

@ -88,7 +88,7 @@ class sram_2bank(sram_base):
mod=self.msb_address,
offset=self.msb_address_position,
rotate=270)
self.msb_bank_sel_addr = "ADDR[{}]".format(self.addr_size-1)
self.msb_bank_sel_addr = "addr[{}]".format(self.addr_size-1)
self.connect_inst([self.msb_bank_sel_addr,"bank_sel[1]","bank_sel[0]","clk_buf", "vdd", "gnd"])

View File

@ -35,7 +35,7 @@ class sram_base(design, verilog, lef):
self.bank_insts = []
if self.write_size is not None:
if self.write_size:
self.num_wmasks = int(self.word_size/self.write_size)
else:
self.num_wmasks = 0
@ -48,11 +48,11 @@ class sram_base(design, verilog, lef):
for port in self.write_ports:
for bit in range(self.word_size):
self.add_pin("DIN{0}[{1}]".format(port,bit),"INPUT")
self.add_pin("din{0}[{1}]".format(port,bit),"INPUT")
for port in self.all_ports:
for bit in range(self.addr_size):
self.add_pin("ADDR{0}[{1}]".format(port,bit),"INPUT")
self.add_pin("addr{0}[{1}]".format(port,bit),"INPUT")
# These are used to create the physical pins
self.control_logic_inputs = []
@ -80,7 +80,7 @@ class sram_base(design, verilog, lef):
self.add_pin("wmask{0}[{1}]".format(port,bit),"INPUT")
for port in self.read_ports:
for bit in range(self.word_size):
self.add_pin("DOUT{0}[{1}]".format(port,bit),"OUTPUT")
self.add_pin("dout{0}[{1}]".format(port,bit),"OUTPUT")
self.add_pin("vdd","POWER")
self.add_pin("gnd","GROUND")
@ -284,7 +284,7 @@ class sram_base(design, verilog, lef):
self.data_dff = dff_array(name="data_dff", rows=1, columns=self.word_size)
self.add_mod(self.data_dff)
if self.write_size is not None:
if self.write_size:
self.wmask_dff = dff_array(name="wmask_dff", rows=1, columns=self.num_wmasks)
self.add_mod(self.wmask_dff)
@ -338,15 +338,15 @@ class sram_base(design, verilog, lef):
temp = []
for port in self.read_ports:
for bit in range(self.word_size):
temp.append("DOUT{0}[{1}]".format(port,bit))
temp.append("dout{0}[{1}]".format(port,bit))
for port in self.all_ports:
temp.append("rbl_bl{0}".format(port))
for port in self.write_ports:
for bit in range(self.word_size):
temp.append("BANK_DIN{0}[{1}]".format(port,bit))
temp.append("bank_din{0}[{1}]".format(port,bit))
for port in self.all_ports:
for bit in range(self.bank_addr_size):
temp.append("A{0}[{1}]".format(port,bit))
temp.append("a{0}[{1}]".format(port,bit))
if(self.num_banks > 1):
for port in self.all_ports:
temp.append("bank_sel{0}[{1}]".format(port,bank_num))
@ -408,8 +408,8 @@ class sram_base(design, verilog, lef):
inputs = []
outputs = []
for bit in range(self.row_addr_size):
inputs.append("ADDR{}[{}]".format(port,bit+self.col_addr_size))
outputs.append("A{}[{}]".format(port,bit+self.col_addr_size))
inputs.append("addr{}[{}]".format(port,bit+self.col_addr_size))
outputs.append("a{}[{}]".format(port,bit+self.col_addr_size))
self.connect_inst(inputs + outputs + ["clk_buf{}".format(port), "vdd", "gnd"])
@ -427,8 +427,8 @@ class sram_base(design, verilog, lef):
inputs = []
outputs = []
for bit in range(self.col_addr_size):
inputs.append("ADDR{}[{}]".format(port,bit))
outputs.append("A{}[{}]".format(port,bit))
inputs.append("addr{}[{}]".format(port,bit))
outputs.append("a{}[{}]".format(port,bit))
self.connect_inst(inputs + outputs + ["clk_buf{}".format(port), "vdd", "gnd"])
@ -450,8 +450,8 @@ class sram_base(design, verilog, lef):
inputs = []
outputs = []
for bit in range(self.word_size):
inputs.append("DIN{}[{}]".format(port,bit))
outputs.append("BANK_DIN{}[{}]".format(port,bit))
inputs.append("din{}[{}]".format(port,bit))
outputs.append("bank_din{}[{}]".format(port,bit))
self.connect_inst(inputs + outputs + ["clk_buf{}".format(port), "vdd", "gnd"])

View File

@ -3,7 +3,7 @@ NAMESCASESENSITIVE ON ;
BUSBITCHARS "[]" ;
DIVIDERCHAR "/" ;
UNITS
DATABASE MICRONS 1000 ;
dataBASE MICRONS 1000 ;
END UNITS
SITE MacroSite
CLASS Core ;
@ -14,48 +14,48 @@ MACRO sram_2_16_1_freepdk45
SIZE 12145.0 BY 43967.5 ;
SYMMETRY X Y R90 ;
SITE MacroSite ;
PIN DATA[0]
PIN data[0]
DIRECTION INOUT ;
PORT
LAYER metal2 ;
RECT 10260.0 67.5 10330.0 207.5 ;
END
END DATA[0]
PIN DATA[1]
END data[0]
PIN data[1]
DIRECTION INOUT ;
PORT
LAYER metal2 ;
RECT 10965.0 67.5 11035.0 207.5 ;
END
END DATA[1]
PIN ADDR[0]
END data[1]
PIN addr[0]
DIRECTION INPUT ;
PORT
LAYER metal3 ;
RECT 67.5 8370.0 837.5 8440.0 ;
END
END ADDR[0]
PIN ADDR[1]
END addr[0]
PIN addr[1]
DIRECTION INPUT ;
PORT
LAYER metal3 ;
RECT 67.5 7665.0 837.5 7735.0 ;
END
END ADDR[1]
PIN ADDR[2]
END addr[1]
PIN addr[2]
DIRECTION INPUT ;
PORT
LAYER metal3 ;
RECT 67.5 6960.0 837.5 7030.0 ;
END
END ADDR[2]
PIN ADDR[3]
END addr[2]
PIN addr[3]
DIRECTION INPUT ;
PORT
LAYER metal3 ;
RECT 67.5 6255.0 837.5 6325.0 ;
END
END ADDR[3]
END addr[3]
PIN CSb
DIRECTION INPUT ;
PORT

View File

@ -136,10 +136,10 @@ Xpmos1 vdd A net1 vdd nor_2_pmos121
Xpmos2 net1 B Z vdd nor_2_pmos222
.ENDS nor2
.SUBCKT msf_control DATA[0] DATA[1] DATA[2] data_in[0] data_in_bar[0] data_in[1] data_in_bar[1] data_in[2] data_in_bar[2] clk vdd gnd
XXdff0 DATA[0] data_in[0] data_in_bar[0] clk vdd gnd ms_flop
XXdff1 DATA[1] data_in[1] data_in_bar[1] clk vdd gnd ms_flop
XXdff2 DATA[2] data_in[2] data_in_bar[2] clk vdd gnd ms_flop
.SUBCKT msf_control data[0] data[1] data[2] data_in[0] data_in_bar[0] data_in[1] data_in_bar[1] data_in[2] data_in_bar[2] clk vdd gnd
XXdff0 data[0] data_in[0] data_in_bar[0] clk vdd gnd ms_flop
XXdff1 data[1] data_in[1] data_in_bar[1] clk vdd gnd ms_flop
XXdff2 data[2] data_in[2] data_in_bar[2] clk vdd gnd ms_flop
.ENDS msf_control
.SUBCKT replica_cell_6t bl br wl vdd gnd
@ -524,16 +524,16 @@ XINVERTER_[14] Z[14] decode_out[14] vdd gnd INVERTER
XINVERTER_[15] Z[15] decode_out[15] vdd gnd INVERTER
.ENDS hierarchical_decoder
.SUBCKT msf_address ADDR[0] ADDR[1] ADDR[2] ADDR[3] A[0] A_bar[0] A[1] A_bar[1] A[2] A_bar[2] A[3] A_bar[3] addr_clk vdd gnd
XXdff0 ADDR[0] A[0] A_bar[0] addr_clk vdd gnd ms_flop
XXdff1 ADDR[1] A[1] A_bar[1] addr_clk vdd gnd ms_flop
XXdff2 ADDR[2] A[2] A_bar[2] addr_clk vdd gnd ms_flop
XXdff3 ADDR[3] A[3] A_bar[3] addr_clk vdd gnd ms_flop
.SUBCKT msf_address addr[0] addr[1] addr[2] addr[3] A[0] A_bar[0] A[1] A_bar[1] A[2] A_bar[2] A[3] A_bar[3] addr_clk vdd gnd
XXdff0 addr[0] A[0] A_bar[0] addr_clk vdd gnd ms_flop
XXdff1 addr[1] A[1] A_bar[1] addr_clk vdd gnd ms_flop
XXdff2 addr[2] A[2] A_bar[2] addr_clk vdd gnd ms_flop
XXdff3 addr[3] A[3] A_bar[3] addr_clk vdd gnd ms_flop
.ENDS msf_address
.SUBCKT msf_data_in DATA[0] DATA[1] data_in[0] data_in_bar[0] data_in[1] data_in_bar[1] clk vdd gnd
XXdff0 DATA[0] data_in[0] data_in_bar[0] clk vdd gnd ms_flop
XXdff1 DATA[1] data_in[1] data_in_bar[1] clk vdd gnd ms_flop
.SUBCKT msf_data_in data[0] data[1] data_in[0] data_in_bar[0] data_in[1] data_in_bar[1] clk vdd gnd
XXdff0 data[0] data_in[0] data_in_bar[0] clk vdd gnd ms_flop
XXdff1 data[1] data_in[1] data_in_bar[1] clk vdd gnd ms_flop
.ENDS msf_data_in
.SUBCKT msf_data_out data_out[0] data_out[1] tri_in[0] tri_in_bar[0] tri_in[1] tri_in_bar[1] sclk vdd gnd
@ -551,9 +551,9 @@ M_6 in_inv in gnd gnd NMOS_VTG W=90.000000n L=50.000000n
.ENDS
.SUBCKT tri_gate_array tri_in[0] tri_in[1] DATA[0] DATA[1] en en_bar vdd gnd
XXtri_gate0 tri_in[0] DATA[0] en en_bar vdd gnd tri_gate
XXtri_gate1 tri_in[1] DATA[1] en en_bar vdd gnd tri_gate
.SUBCKT tri_gate_array tri_in[0] tri_in[1] data[0] data[1] en en_bar vdd gnd
XXtri_gate0 tri_in[0] data[0] en en_bar vdd gnd tri_gate
XXtri_gate1 tri_in[1] data[1] en en_bar vdd gnd tri_gate
.ENDS tri_gate_array
.SUBCKT wordline_driver decode_out[0] decode_out[1] decode_out[2] decode_out[3] decode_out[4] decode_out[5] decode_out[6] decode_out[7] decode_out[8] decode_out[9] decode_out[10] decode_out[11] decode_out[12] decode_out[13] decode_out[14] decode_out[15] wl[0] wl[1] wl[2] wl[3] wl[4] wl[5] wl[6] wl[7] wl[8] wl[9] wl[10] wl[11] wl[12] wl[13] wl[14] wl[15] clk vdd gnd
@ -643,19 +643,19 @@ Xpmos1 vdd A net1 vdd nor_2_pmos185
Xpmos2 net1 B Z vdd nor_2_pmos286
.ENDS NOR2
.SUBCKT test_bank1 DATA[0] DATA[1] ADDR[0] ADDR[1] ADDR[2] ADDR[3] s_en w_en tri_en_bar tri_en clk_bar clk vdd gnd
.SUBCKT test_bank1 data[0] data[1] addr[0] addr[1] addr[2] addr[3] s_en w_en tri_en_bar tri_en clk_bar clk vdd gnd
Xbitcell_array bl[0] br[0] bl[1] br[1] wl[0] wl[1] wl[2] wl[3] wl[4] wl[5] wl[6] wl[7] wl[8] wl[9] wl[10] wl[11] wl[12] wl[13] wl[14] wl[15] vdd gnd bitcell_array
Xprecharge_array bl[0] br[0] bl[1] br[1] clk_bar vdd precharge_array
Xsense_amp_array bl[0] br[0] bl[1] br[1] data_out[0] data_out[1] s_en vdd gnd sense_amp_array
Xwrite_driver_array data_in[0] data_in[1] bl[0] br[0] bl[1] br[1] w_en vdd gnd write_driver_array
Xdata_in_flop_array DATA[0] DATA[1] data_in[0] data_in_bar[0] data_in[1] data_in_bar[1] clk_bar vdd gnd msf_data_in
Xtrigate_data_array data_out[0] data_out[1] DATA[0] DATA[1] tri_en tri_en_bar vdd gnd tri_gate_array
Xdata_in_flop_array data[0] data[1] data_in[0] data_in_bar[0] data_in[1] data_in_bar[1] clk_bar vdd gnd msf_data_in
Xtrigate_data_array data_out[0] data_out[1] data[0] data[1] tri_en tri_en_bar vdd gnd tri_gate_array
Xaddress_decoder A[0] A[1] A[2] A[3] decode_out[0] decode_out[1] decode_out[2] decode_out[3] decode_out[4] decode_out[5] decode_out[6] decode_out[7] decode_out[8] decode_out[9] decode_out[10] decode_out[11] decode_out[12] decode_out[13] decode_out[14] decode_out[15] vdd gnd hierarchical_decoder
Xwordline_driver decode_out[0] decode_out[1] decode_out[2] decode_out[3] decode_out[4] decode_out[5] decode_out[6] decode_out[7] decode_out[8] decode_out[9] decode_out[10] decode_out[11] decode_out[12] decode_out[13] decode_out[14] decode_out[15] wl[0] wl[1] wl[2] wl[3] wl[4] wl[5] wl[6] wl[7] wl[8] wl[9] wl[10] wl[11] wl[12] wl[13] wl[14] wl[15] clk vdd gnd wordline_driver
Xaddress_flop_array ADDR[0] ADDR[1] ADDR[2] ADDR[3] A[0] A_bar[0] A[1] A_bar[1] A[2] A_bar[2] A[3] A_bar[3] clk vdd gnd msf_address
Xaddress_flop_array addr[0] addr[1] addr[2] addr[3] A[0] A_bar[0] A[1] A_bar[1] A[2] A_bar[2] A[3] A_bar[3] clk vdd gnd msf_address
.ENDS test_bank1
.SUBCKT testsram DATA[0] DATA[1] ADDR[0] ADDR[1] ADDR[2] ADDR[3] CSb WEb OEb clk vdd gnd
Xbank0 DATA[0] DATA[1] ADDR[0] ADDR[1] ADDR[2] ADDR[3] s_en w_en tri_en_bar tri_en clk_bar clk vdd gnd test_bank1
.SUBCKT testsram data[0] data[1] addr[0] addr[1] addr[2] addr[3] CSb WEb OEb clk vdd gnd
Xbank0 data[0] data[1] addr[0] addr[1] addr[2] addr[3] s_en w_en tri_en_bar tri_en clk_bar clk vdd gnd test_bank1
Xcontrol CSb WEb OEb s_en w_en tri_en tri_en_bar clk_bar clk vdd gnd control_logic
.ENDS testsram

View File

@ -4,7 +4,7 @@
module sram_2_16_1_freepdk45(
// Port 0: RW
clk0,csb0,web0,ADDR0,DIN0,DOUT0
clk0,csb0,web0,addr0,din0,dout0
);
parameter DATA_WIDTH = 2 ;
@ -16,28 +16,28 @@ module sram_2_16_1_freepdk45(
input clk0; // clock
input csb0; // active low chip select
input web0; // active low write control
input [ADDR_WIDTH-1:0] ADDR0;
input [DATA_WIDTH-1:0] DIN0;
output [DATA_WIDTH-1:0] DOUT0;
input [ADDR_WIDTH-1:0] addr0;
input [DATA_WIDTH-1:0] din0;
output [DATA_WIDTH-1:0] dout0;
reg csb0_reg;
reg web0_reg;
reg [ADDR_WIDTH-1:0] ADDR0_reg;
reg [DATA_WIDTH-1:0] DIN0_reg;
reg [DATA_WIDTH-1:0] DOUT0;
reg [ADDR_WIDTH-1:0] addr0_reg;
reg [DATA_WIDTH-1:0] din0_reg;
reg [DATA_WIDTH-1:0] dout0;
// All inputs are registers
always @(posedge clk0)
begin
csb0_reg = csb0;
web0_reg = web0;
ADDR0_reg = ADDR0;
DIN0_reg = DIN0;
DOUT0 = 2'bx;
addr0_reg = addr0;
din0_reg = din0;
dout0 = 2'bx;
if ( !csb0_reg && web0_reg )
$display($time," Reading %m ADDR0=%b DOUT0=%b",ADDR0_reg,mem[ADDR0_reg]);
$display($time," Reading %m addr0=%b dout0=%b",addr0_reg,mem[addr0_reg]);
if ( !csb0_reg && !web0_reg )
$display($time," Writing %m ADDR0=%b DIN0=%b",ADDR0_reg,DIN0_reg);
$display($time," Writing %m addr0=%b din0=%b",addr0_reg,din0_reg);
end
reg [DATA_WIDTH-1:0] mem [0:RAM_DEPTH-1];
@ -47,7 +47,7 @@ reg [DATA_WIDTH-1:0] mem [0:RAM_DEPTH-1];
always @ (negedge clk0)
begin : MEM_WRITE0
if ( !csb0_reg && !web0_reg )
mem[ADDR0_reg] = DIN0_reg;
mem[addr0_reg] = din0_reg;
end
// Memory Read Block Port 0
@ -55,7 +55,7 @@ reg [DATA_WIDTH-1:0] mem [0:RAM_DEPTH-1];
always @ (negedge clk0)
begin : MEM_READ0
if (!csb0_reg && web0_reg)
DOUT0 <= #(DELAY) mem[ADDR0_reg];
dout0 <= #(DELAY) mem[addr0_reg];
end
endmodule

View File

@ -52,7 +52,7 @@ library (sram_2_16_1_freepdk45_FF_1p0V_25C_lib){
default_operating_conditions : OC;
type (DATA){
type (data){
base_type : array;
data_type : bit;
bit_width : 2;
@ -60,7 +60,7 @@ library (sram_2_16_1_freepdk45_FF_1p0V_25C_lib){
bit_to : 1;
}
type (ADDR){
type (addr){
base_type : array;
data_type : bit;
bit_width : 4;
@ -85,15 +85,15 @@ cell (sram_2_16_1_freepdk45){
value : 0.000167;
}
cell_leakage_power : 0;
bus(DIN0){
bus_type : DATA;
bus(din0){
bus_type : data;
direction : input;
capacitance : 0.2091;
memory_write(){
address : ADDR0;
address : addr0;
clocked_on : clk0;
}
pin(DIN0[1:0]){
pin(din0[1:0]){
timing(){
timing_type : setup_rising;
related_pin : "clk0";
@ -124,15 +124,15 @@ cell (sram_2_16_1_freepdk45){
}
}
}
bus(DOUT0){
bus_type : DATA;
bus(dout0){
bus_type : data;
direction : output;
max_capacitance : 1.6728;
min_capacitance : 0.052275;
memory_read(){
address : ADDR0;
address : addr0;
}
pin(DOUT0[1:0]){
pin(dout0[1:0]){
timing(){
timing_sense : non_unate;
related_pin : "clk0";
@ -161,12 +161,12 @@ cell (sram_2_16_1_freepdk45){
}
}
bus(ADDR0){
bus_type : ADDR;
bus(addr0){
bus_type : addr;
direction : input;
capacitance : 0.2091;
max_transition : 0.04;
pin(ADDR0[3:0]){
pin(addr0[3:0]){
timing(){
timing_type : setup_rising;
related_pin : "clk0";

View File

@ -52,7 +52,7 @@ library (sram_2_16_1_freepdk45_SS_1p0V_25C_lib){
default_operating_conditions : OC;
type (DATA){
type (data){
base_type : array;
data_type : bit;
bit_width : 2;
@ -60,7 +60,7 @@ library (sram_2_16_1_freepdk45_SS_1p0V_25C_lib){
bit_to : 1;
}
type (ADDR){
type (addr){
base_type : array;
data_type : bit;
bit_width : 4;
@ -85,15 +85,15 @@ cell (sram_2_16_1_freepdk45){
value : 0.000167;
}
cell_leakage_power : 0;
bus(DIN0){
bus_type : DATA;
bus(din0){
bus_type : data;
direction : input;
capacitance : 0.2091;
memory_write(){
address : ADDR0;
address : addr0;
clocked_on : clk0;
}
pin(DIN0[1:0]){
pin(din0[1:0]){
timing(){
timing_type : setup_rising;
related_pin : "clk0";
@ -124,15 +124,15 @@ cell (sram_2_16_1_freepdk45){
}
}
}
bus(DOUT0){
bus_type : DATA;
bus(dout0){
bus_type : data;
direction : output;
max_capacitance : 1.6728;
min_capacitance : 0.052275;
memory_read(){
address : ADDR0;
address : addr0;
}
pin(DOUT0[1:0]){
pin(dout0[1:0]){
timing(){
timing_sense : non_unate;
related_pin : "clk0";
@ -161,12 +161,12 @@ cell (sram_2_16_1_freepdk45){
}
}
bus(ADDR0){
bus_type : ADDR;
bus(addr0){
bus_type : addr;
direction : input;
capacitance : 0.2091;
max_transition : 0.04;
pin(ADDR0[3:0]){
pin(addr0[3:0]){
timing(){
timing_type : setup_rising;
related_pin : "clk0";

View File

@ -52,7 +52,7 @@ library (sram_2_16_1_freepdk45_TT_1p0V_25C_lib){
default_operating_conditions : OC;
type (DATA){
type (data){
base_type : array;
data_type : bit;
bit_width : 2;
@ -60,7 +60,7 @@ library (sram_2_16_1_freepdk45_TT_1p0V_25C_lib){
bit_to : 1;
}
type (ADDR){
type (addr){
base_type : array;
data_type : bit;
bit_width : 4;
@ -85,15 +85,15 @@ cell (sram_2_16_1_freepdk45){
value : 0.0011164579999999999;
}
cell_leakage_power : 0;
bus(DIN0){
bus_type : DATA;
bus(din0){
bus_type : data;
direction : input;
capacitance : 0.2091;
memory_write(){
address : ADDR0;
address : addr0;
clocked_on : clk0;
}
pin(DIN0[1:0]){
pin(din0[1:0]){
timing(){
timing_type : setup_rising;
related_pin : "clk0";
@ -124,15 +124,15 @@ cell (sram_2_16_1_freepdk45){
}
}
}
bus(DOUT0){
bus_type : DATA;
bus(dout0){
bus_type : data;
direction : output;
max_capacitance : 1.6728;
min_capacitance : 0.052275;
memory_read(){
address : ADDR0;
address : addr0;
}
pin(DOUT0[1:0]){
pin(dout0[1:0]){
timing(){
timing_sense : non_unate;
related_pin : "clk0";
@ -161,12 +161,12 @@ cell (sram_2_16_1_freepdk45){
}
}
bus(ADDR0){
bus_type : ADDR;
bus(addr0){
bus_type : addr;
direction : input;
capacitance : 0.2091;
max_transition : 0.04;
pin(ADDR0[3:0]){
pin(addr0[3:0]){
timing(){
timing_type : setup_rising;
related_pin : "clk0";

View File

@ -52,7 +52,7 @@ library (sram_2_16_1_freepdk45_TT_1p0V_25C_lib){
default_operating_conditions : OC;
type (DATA){
type (data){
base_type : array;
data_type : bit;
bit_width : 2;
@ -60,7 +60,7 @@ library (sram_2_16_1_freepdk45_TT_1p0V_25C_lib){
bit_to : 1;
}
type (ADDR){
type (addr){
base_type : array;
data_type : bit;
bit_width : 4;
@ -85,15 +85,15 @@ cell (sram_2_16_1_freepdk45){
value : 0.000179;
}
cell_leakage_power : 0;
bus(DIN0){
bus_type : DATA;
bus(din0){
bus_type : data;
direction : input;
capacitance : 0.2091;
memory_write(){
address : ADDR0;
address : addr0;
clocked_on : clk0;
}
pin(DIN0[1:0]){
pin(din0[1:0]){
timing(){
timing_type : setup_rising;
related_pin : "clk0";
@ -124,15 +124,15 @@ cell (sram_2_16_1_freepdk45){
}
}
}
bus(DOUT0){
bus_type : DATA;
bus(dout0){
bus_type : data;
direction : output;
max_capacitance : 1.6728;
min_capacitance : 0.052275;
memory_read(){
address : ADDR0;
address : addr0;
}
pin(DOUT0[1:0]){
pin(dout0[1:0]){
timing(){
timing_sense : non_unate;
related_pin : "clk0";
@ -161,12 +161,12 @@ cell (sram_2_16_1_freepdk45){
}
}
bus(ADDR0){
bus_type : ADDR;
bus(addr0){
bus_type : addr;
direction : input;
capacitance : 0.2091;
max_transition : 0.04;
pin(ADDR0[3:0]){
pin(addr0[3:0]){
timing(){
timing_type : setup_rising;
related_pin : "clk0";

View File

@ -52,7 +52,7 @@ library (sram_2_16_1_freepdk45_TT_1p0V_25C_lib){
default_operating_conditions : OC;
type (DATA){
type (data){
base_type : array;
data_type : bit;
bit_width : 2;
@ -60,7 +60,7 @@ library (sram_2_16_1_freepdk45_TT_1p0V_25C_lib){
bit_to : 1;
}
type (ADDR){
type (addr){
base_type : array;
data_type : bit;
bit_width : 4;
@ -85,15 +85,15 @@ cell (sram_2_16_1_freepdk45){
value : 0.0011164579999999999;
}
cell_leakage_power : 0;
bus(DIN0){
bus_type : DATA;
bus(din0){
bus_type : data;
direction : input;
capacitance : 0.2091;
memory_write(){
address : ADDR0;
address : addr0;
clocked_on : clk0;
}
pin(DIN0[1:0]){
pin(din0[1:0]){
timing(){
timing_type : setup_rising;
related_pin : "clk0";
@ -124,15 +124,15 @@ cell (sram_2_16_1_freepdk45){
}
}
}
bus(DOUT0){
bus_type : DATA;
bus(dout0){
bus_type : data;
direction : output;
max_capacitance : 1.6728;
min_capacitance : 0.052275;
memory_read(){
address : ADDR0;
address : addr0;
}
pin(DOUT0[1:0]){
pin(dout0[1:0]){
timing(){
timing_sense : non_unate;
related_pin : "clk0";
@ -161,12 +161,12 @@ cell (sram_2_16_1_freepdk45){
}
}
bus(ADDR0){
bus_type : ADDR;
bus(addr0){
bus_type : addr;
direction : input;
capacitance : 0.2091;
max_transition : 0.04;
pin(ADDR0[3:0]){
pin(addr0[3:0]){
timing(){
timing_type : setup_rising;
related_pin : "clk0";

View File

@ -3,7 +3,7 @@ NAMESCASESENSITIVE ON ;
BUSBITCHARS "[]" ;
DIVIDERCHAR "/" ;
UNITS
DATABASE MICRONS 1000 ;
dataBASE MICRONS 1000 ;
END UNITS
SITE MacroSite
CLASS Core ;
@ -14,48 +14,48 @@ MACRO sram_2_16_1_scn3me_subm
SIZE 148050.0 BY 461850.0 ;
SYMMETRY X Y R90 ;
SITE MacroSite ;
PIN DATA[0]
PIN data[0]
DIRECTION INOUT ;
PORT
LAYER metal2 ;
RECT 120900.0 0.0 121800.0 1800.0 ;
END
END DATA[0]
PIN DATA[1]
END data[0]
PIN data[1]
DIRECTION INOUT ;
PORT
LAYER metal2 ;
RECT 131100.0 0.0 132000.0 1800.0 ;
END
END DATA[1]
PIN ADDR[0]
END data[1]
PIN addr[0]
DIRECTION INPUT ;
PORT
LAYER metal3 ;
RECT 0.0 87600.0 10800.0 89100.0 ;
END
END ADDR[0]
PIN ADDR[1]
END addr[0]
PIN addr[1]
DIRECTION INPUT ;
PORT
LAYER metal3 ;
RECT 0.0 77400.0 10800.0 78900.0 ;
END
END ADDR[1]
PIN ADDR[2]
END addr[1]
PIN addr[2]
DIRECTION INPUT ;
PORT
LAYER metal3 ;
RECT 0.0 67200.0 10800.0 68700.0 ;
END
END ADDR[2]
PIN ADDR[3]
END addr[2]
PIN addr[3]
DIRECTION INPUT ;
PORT
LAYER metal3 ;
RECT 0.0 57000.0 10800.0 58500.0 ;
END
END ADDR[3]
END addr[3]
PIN CSb
DIRECTION INPUT ;
PORT

View File

@ -136,10 +136,10 @@ Xpmos1 vdd A net1 vdd nor_2_pmos125
Xpmos2 net1 B Z vdd nor_2_pmos226
.ENDS nor2
.SUBCKT msf_control DATA[0] DATA[1] DATA[2] data_in[0] data_in_bar[0] data_in[1] data_in_bar[1] data_in[2] data_in_bar[2] clk vdd gnd
XXdff0 DATA[0] data_in[0] data_in_bar[0] clk vdd gnd ms_flop
XXdff1 DATA[1] data_in[1] data_in_bar[1] clk vdd gnd ms_flop
XXdff2 DATA[2] data_in[2] data_in_bar[2] clk vdd gnd ms_flop
.SUBCKT msf_control data[0] data[1] data[2] data_in[0] data_in_bar[0] data_in[1] data_in_bar[1] data_in[2] data_in_bar[2] clk vdd gnd
XXdff0 data[0] data_in[0] data_in_bar[0] clk vdd gnd ms_flop
XXdff1 data[1] data_in[1] data_in_bar[1] clk vdd gnd ms_flop
XXdff2 data[2] data_in[2] data_in_bar[2] clk vdd gnd ms_flop
.ENDS msf_control
*********************** "cell_6t" ******************************
@ -541,16 +541,16 @@ XINVERTER_[14] Z[14] decode_out[14] vdd gnd INVERTER
XINVERTER_[15] Z[15] decode_out[15] vdd gnd INVERTER
.ENDS hierarchical_decoder
.SUBCKT msf_address ADDR[0] ADDR[1] ADDR[2] ADDR[3] A[0] A_bar[0] A[1] A_bar[1] A[2] A_bar[2] A[3] A_bar[3] addr_clk vdd gnd
XXdff0 ADDR[0] A[0] A_bar[0] addr_clk vdd gnd ms_flop
XXdff1 ADDR[1] A[1] A_bar[1] addr_clk vdd gnd ms_flop
XXdff2 ADDR[2] A[2] A_bar[2] addr_clk vdd gnd ms_flop
XXdff3 ADDR[3] A[3] A_bar[3] addr_clk vdd gnd ms_flop
.SUBCKT msf_address addr[0] addr[1] addr[2] addr[3] A[0] A_bar[0] A[1] A_bar[1] A[2] A_bar[2] A[3] A_bar[3] addr_clk vdd gnd
XXdff0 addr[0] A[0] A_bar[0] addr_clk vdd gnd ms_flop
XXdff1 addr[1] A[1] A_bar[1] addr_clk vdd gnd ms_flop
XXdff2 addr[2] A[2] A_bar[2] addr_clk vdd gnd ms_flop
XXdff3 addr[3] A[3] A_bar[3] addr_clk vdd gnd ms_flop
.ENDS msf_address
.SUBCKT msf_data_in DATA[0] DATA[1] data_in[0] data_in_bar[0] data_in[1] data_in_bar[1] clk vdd gnd
XXdff0 DATA[0] data_in[0] data_in_bar[0] clk vdd gnd ms_flop
XXdff1 DATA[1] data_in[1] data_in_bar[1] clk vdd gnd ms_flop
.SUBCKT msf_data_in data[0] data[1] data_in[0] data_in_bar[0] data_in[1] data_in_bar[1] clk vdd gnd
XXdff0 data[0] data_in[0] data_in_bar[0] clk vdd gnd ms_flop
XXdff1 data[1] data_in[1] data_in_bar[1] clk vdd gnd ms_flop
.ENDS msf_data_in
.SUBCKT msf_data_out data_out[0] data_out[1] tri_in[0] tri_in_bar[0] tri_in[1] tri_in_bar[1] sclk vdd gnd
@ -571,9 +571,9 @@ M_6 in_inv in gnd gnd n W='1.2*1u' L=0.6u
.ENDS
.SUBCKT tri_gate_array tri_in[0] tri_in[1] DATA[0] DATA[1] en en_bar vdd gnd
XXtri_gate0 tri_in[0] DATA[0] en en_bar vdd gnd tri_gate
XXtri_gate1 tri_in[1] DATA[1] en en_bar vdd gnd tri_gate
.SUBCKT tri_gate_array tri_in[0] tri_in[1] data[0] data[1] en en_bar vdd gnd
XXtri_gate0 tri_in[0] data[0] en en_bar vdd gnd tri_gate
XXtri_gate1 tri_in[1] data[1] en en_bar vdd gnd tri_gate
.ENDS tri_gate_array
.SUBCKT wordline_driver decode_out[0] decode_out[1] decode_out[2] decode_out[3] decode_out[4] decode_out[5] decode_out[6] decode_out[7] decode_out[8] decode_out[9] decode_out[10] decode_out[11] decode_out[12] decode_out[13] decode_out[14] decode_out[15] wl[0] wl[1] wl[2] wl[3] wl[4] wl[5] wl[6] wl[7] wl[8] wl[9] wl[10] wl[11] wl[12] wl[13] wl[14] wl[15] clk vdd gnd
@ -663,19 +663,19 @@ Xpmos1 vdd A net1 vdd nor_2_pmos197
Xpmos2 net1 B Z vdd nor_2_pmos298
.ENDS NOR2
.SUBCKT test_bank1 DATA[0] DATA[1] ADDR[0] ADDR[1] ADDR[2] ADDR[3] s_en w_en tri_en_bar tri_en clk_bar clk vdd gnd
.SUBCKT test_bank1 data[0] data[1] addr[0] addr[1] addr[2] addr[3] s_en w_en tri_en_bar tri_en clk_bar clk vdd gnd
Xbitcell_array bl[0] br[0] bl[1] br[1] wl[0] wl[1] wl[2] wl[3] wl[4] wl[5] wl[6] wl[7] wl[8] wl[9] wl[10] wl[11] wl[12] wl[13] wl[14] wl[15] vdd gnd bitcell_array
Xprecharge_array bl[0] br[0] bl[1] br[1] clk_bar vdd precharge_array
Xsense_amp_array bl[0] br[0] bl[1] br[1] data_out[0] data_out[1] s_en vdd gnd sense_amp_array
Xwrite_driver_array data_in[0] data_in[1] bl[0] br[0] bl[1] br[1] w_en vdd gnd write_driver_array
Xdata_in_flop_array DATA[0] DATA[1] data_in[0] data_in_bar[0] data_in[1] data_in_bar[1] clk_bar vdd gnd msf_data_in
Xtrigate_data_array data_out[0] data_out[1] DATA[0] DATA[1] tri_en tri_en_bar vdd gnd tri_gate_array
Xdata_in_flop_array data[0] data[1] data_in[0] data_in_bar[0] data_in[1] data_in_bar[1] clk_bar vdd gnd msf_data_in
Xtrigate_data_array data_out[0] data_out[1] data[0] data[1] tri_en tri_en_bar vdd gnd tri_gate_array
Xaddress_decoder A[0] A[1] A[2] A[3] decode_out[0] decode_out[1] decode_out[2] decode_out[3] decode_out[4] decode_out[5] decode_out[6] decode_out[7] decode_out[8] decode_out[9] decode_out[10] decode_out[11] decode_out[12] decode_out[13] decode_out[14] decode_out[15] vdd gnd hierarchical_decoder
Xwordline_driver decode_out[0] decode_out[1] decode_out[2] decode_out[3] decode_out[4] decode_out[5] decode_out[6] decode_out[7] decode_out[8] decode_out[9] decode_out[10] decode_out[11] decode_out[12] decode_out[13] decode_out[14] decode_out[15] wl[0] wl[1] wl[2] wl[3] wl[4] wl[5] wl[6] wl[7] wl[8] wl[9] wl[10] wl[11] wl[12] wl[13] wl[14] wl[15] clk vdd gnd wordline_driver
Xaddress_flop_array ADDR[0] ADDR[1] ADDR[2] ADDR[3] A[0] A_bar[0] A[1] A_bar[1] A[2] A_bar[2] A[3] A_bar[3] clk vdd gnd msf_address
Xaddress_flop_array addr[0] addr[1] addr[2] addr[3] A[0] A_bar[0] A[1] A_bar[1] A[2] A_bar[2] A[3] A_bar[3] clk vdd gnd msf_address
.ENDS test_bank1
.SUBCKT testsram DATA[0] DATA[1] ADDR[0] ADDR[1] ADDR[2] ADDR[3] CSb WEb OEb clk vdd gnd
Xbank0 DATA[0] DATA[1] ADDR[0] ADDR[1] ADDR[2] ADDR[3] s_en w_en tri_en_bar tri_en clk_bar clk vdd gnd test_bank1
.SUBCKT testsram data[0] data[1] addr[0] addr[1] addr[2] addr[3] CSb WEb OEb clk vdd gnd
Xbank0 data[0] data[1] addr[0] addr[1] addr[2] addr[3] s_en w_en tri_en_bar tri_en clk_bar clk vdd gnd test_bank1
Xcontrol CSb WEb OEb s_en w_en tri_en tri_en_bar clk_bar clk vdd gnd control_logic
.ENDS testsram

View File

@ -4,7 +4,7 @@
module sram_2_16_1_scn4m_subm(
// Port 0: RW
clk0,csb0,web0,ADDR0,DIN0,DOUT0
clk0,csb0,web0,addr0,din0,dout0
);
parameter DATA_WIDTH = 2 ;
@ -16,28 +16,28 @@ module sram_2_16_1_scn4m_subm(
input clk0; // clock
input csb0; // active low chip select
input web0; // active low write control
input [ADDR_WIDTH-1:0] ADDR0;
input [DATA_WIDTH-1:0] DIN0;
output [DATA_WIDTH-1:0] DOUT0;
input [ADDR_WIDTH-1:0] addr0;
input [DATA_WIDTH-1:0] din0;
output [DATA_WIDTH-1:0] dout0;
reg csb0_reg;
reg web0_reg;
reg [ADDR_WIDTH-1:0] ADDR0_reg;
reg [DATA_WIDTH-1:0] DIN0_reg;
reg [DATA_WIDTH-1:0] DOUT0;
reg [ADDR_WIDTH-1:0] addr0_reg;
reg [DATA_WIDTH-1:0] din0_reg;
reg [DATA_WIDTH-1:0] dout0;
// All inputs are registers
always @(posedge clk0)
begin
csb0_reg = csb0;
web0_reg = web0;
ADDR0_reg = ADDR0;
DIN0_reg = DIN0;
DOUT0 = 2'bx;
addr0_reg = addr0;
din0_reg = din0;
dout0 = 2'bx;
if ( !csb0_reg && web0_reg )
$display($time," Reading %m ADDR0=%b DOUT0=%b",ADDR0_reg,mem[ADDR0_reg]);
$display($time," Reading %m addr0=%b dout0=%b",addr0_reg,mem[addr0_reg]);
if ( !csb0_reg && !web0_reg )
$display($time," Writing %m ADDR0=%b DIN0=%b",ADDR0_reg,DIN0_reg);
$display($time," Writing %m addr0=%b din0=%b",addr0_reg,din0_reg);
end
reg [DATA_WIDTH-1:0] mem [0:RAM_DEPTH-1];
@ -47,7 +47,7 @@ reg [DATA_WIDTH-1:0] mem [0:RAM_DEPTH-1];
always @ (negedge clk0)
begin : MEM_WRITE0
if ( !csb0_reg && !web0_reg )
mem[ADDR0_reg] = DIN0_reg;
mem[addr0_reg] = din0_reg;
end
// Memory Read Block Port 0
@ -55,7 +55,7 @@ reg [DATA_WIDTH-1:0] mem [0:RAM_DEPTH-1];
always @ (negedge clk0)
begin : MEM_READ0
if (!csb0_reg && web0_reg)
DOUT0 <= #(DELAY) mem[ADDR0_reg];
dout0 <= #(DELAY) mem[addr0_reg];
end
endmodule

View File

@ -52,7 +52,7 @@ library (sram_2_16_1_scn4m_subm_FF_5p0V_25C_lib){
default_operating_conditions : OC;
type (DATA){
type (data){
base_type : array;
data_type : bit;
bit_width : 2;
@ -60,7 +60,7 @@ library (sram_2_16_1_scn4m_subm_FF_5p0V_25C_lib){
bit_to : 1;
}
type (ADDR){
type (addr){
base_type : array;
data_type : bit;
bit_width : 4;
@ -85,15 +85,15 @@ cell (sram_2_16_1_scn4m_subm){
value : 0.000167;
}
cell_leakage_power : 0;
bus(DIN0){
bus_type : DATA;
bus(din0){
bus_type : data;
direction : input;
capacitance : 9.8242;
memory_write(){
address : ADDR0;
address : addr0;
clocked_on : clk0;
}
pin(DIN0[1:0]){
pin(din0[1:0]){
timing(){
timing_type : setup_rising;
related_pin : "clk0";
@ -124,15 +124,15 @@ cell (sram_2_16_1_scn4m_subm){
}
}
}
bus(DOUT0){
bus_type : DATA;
bus(dout0){
bus_type : data;
direction : output;
max_capacitance : 78.5936;
min_capacitance : 2.45605;
memory_read(){
address : ADDR0;
address : addr0;
}
pin(DOUT0[1:0]){
pin(dout0[1:0]){
timing(){
timing_sense : non_unate;
related_pin : "clk0";
@ -161,12 +161,12 @@ cell (sram_2_16_1_scn4m_subm){
}
}
bus(ADDR0){
bus_type : ADDR;
bus(addr0){
bus_type : addr;
direction : input;
capacitance : 9.8242;
max_transition : 0.4;
pin(ADDR0[3:0]){
pin(addr0[3:0]){
timing(){
timing_type : setup_rising;
related_pin : "clk0";

View File

@ -52,7 +52,7 @@ library (sram_2_16_1_scn4m_subm_SS_5p0V_25C_lib){
default_operating_conditions : OC;
type (DATA){
type (data){
base_type : array;
data_type : bit;
bit_width : 2;
@ -60,7 +60,7 @@ library (sram_2_16_1_scn4m_subm_SS_5p0V_25C_lib){
bit_to : 1;
}
type (ADDR){
type (addr){
base_type : array;
data_type : bit;
bit_width : 4;
@ -85,15 +85,15 @@ cell (sram_2_16_1_scn4m_subm){
value : 0.000167;
}
cell_leakage_power : 0;
bus(DIN0){
bus_type : DATA;
bus(din0){
bus_type : data;
direction : input;
capacitance : 9.8242;
memory_write(){
address : ADDR0;
address : addr0;
clocked_on : clk0;
}
pin(DIN0[1:0]){
pin(din0[1:0]){
timing(){
timing_type : setup_rising;
related_pin : "clk0";
@ -124,15 +124,15 @@ cell (sram_2_16_1_scn4m_subm){
}
}
}
bus(DOUT0){
bus_type : DATA;
bus(dout0){
bus_type : data;
direction : output;
max_capacitance : 78.5936;
min_capacitance : 2.45605;
memory_read(){
address : ADDR0;
address : addr0;
}
pin(DOUT0[1:0]){
pin(dout0[1:0]){
timing(){
timing_sense : non_unate;
related_pin : "clk0";
@ -161,12 +161,12 @@ cell (sram_2_16_1_scn4m_subm){
}
}
bus(ADDR0){
bus_type : ADDR;
bus(addr0){
bus_type : addr;
direction : input;
capacitance : 9.8242;
max_transition : 0.4;
pin(ADDR0[3:0]){
pin(addr0[3:0]){
timing(){
timing_type : setup_rising;
related_pin : "clk0";

View File

@ -52,7 +52,7 @@ library (sram_2_16_1_scn4m_subm_TT_5p0V_25C_lib){
default_operating_conditions : OC;
type (DATA){
type (data){
base_type : array;
data_type : bit;
bit_width : 2;
@ -60,7 +60,7 @@ library (sram_2_16_1_scn4m_subm_TT_5p0V_25C_lib){
bit_to : 1;
}
type (ADDR){
type (addr){
base_type : array;
data_type : bit;
bit_width : 4;
@ -85,15 +85,15 @@ cell (sram_2_16_1_scn4m_subm){
value : 0.0009813788999999999;
}
cell_leakage_power : 0;
bus(DIN0){
bus_type : DATA;
bus(din0){
bus_type : data;
direction : input;
capacitance : 9.8242;
memory_write(){
address : ADDR0;
address : addr0;
clocked_on : clk0;
}
pin(DIN0[1:0]){
pin(din0[1:0]){
timing(){
timing_type : setup_rising;
related_pin : "clk0";
@ -124,15 +124,15 @@ cell (sram_2_16_1_scn4m_subm){
}
}
}
bus(DOUT0){
bus_type : DATA;
bus(dout0){
bus_type : data;
direction : output;
max_capacitance : 78.5936;
min_capacitance : 2.45605;
memory_read(){
address : ADDR0;
address : addr0;
}
pin(DOUT0[1:0]){
pin(dout0[1:0]){
timing(){
timing_sense : non_unate;
related_pin : "clk0";
@ -161,12 +161,12 @@ cell (sram_2_16_1_scn4m_subm){
}
}
bus(ADDR0){
bus_type : ADDR;
bus(addr0){
bus_type : addr;
direction : input;
capacitance : 9.8242;
max_transition : 0.4;
pin(ADDR0[3:0]){
pin(addr0[3:0]){
timing(){
timing_type : setup_rising;
related_pin : "clk0";

View File

@ -52,7 +52,7 @@ library (sram_2_16_1_scn4m_subm_TT_5p0V_25C_lib){
default_operating_conditions : OC;
type (DATA){
type (data){
base_type : array;
data_type : bit;
bit_width : 2;
@ -60,7 +60,7 @@ library (sram_2_16_1_scn4m_subm_TT_5p0V_25C_lib){
bit_to : 1;
}
type (ADDR){
type (addr){
base_type : array;
data_type : bit;
bit_width : 4;
@ -85,15 +85,15 @@ cell (sram_2_16_1_scn4m_subm){
value : 0.000179;
}
cell_leakage_power : 0;
bus(DIN0){
bus_type : DATA;
bus(din0){
bus_type : data;
direction : input;
capacitance : 9.8242;
memory_write(){
address : ADDR0;
address : addr0;
clocked_on : clk0;
}
pin(DIN0[1:0]){
pin(din0[1:0]){
timing(){
timing_type : setup_rising;
related_pin : "clk0";
@ -124,15 +124,15 @@ cell (sram_2_16_1_scn4m_subm){
}
}
}
bus(DOUT0){
bus_type : DATA;
bus(dout0){
bus_type : data;
direction : output;
max_capacitance : 78.5936;
min_capacitance : 2.45605;
memory_read(){
address : ADDR0;
address : addr0;
}
pin(DOUT0[1:0]){
pin(dout0[1:0]){
timing(){
timing_sense : non_unate;
related_pin : "clk0";
@ -161,12 +161,12 @@ cell (sram_2_16_1_scn4m_subm){
}
}
bus(ADDR0){
bus_type : ADDR;
bus(addr0){
bus_type : addr;
direction : input;
capacitance : 9.8242;
max_transition : 0.4;
pin(ADDR0[3:0]){
pin(addr0[3:0]){
timing(){
timing_type : setup_rising;
related_pin : "clk0";

View File

@ -52,7 +52,7 @@ library (sram_2_16_1_scn4m_subm_TT_5p0V_25C_lib){
default_operating_conditions : OC;
type (DATA){
type (data){
base_type : array;
data_type : bit;
bit_width : 2;
@ -60,7 +60,7 @@ library (sram_2_16_1_scn4m_subm_TT_5p0V_25C_lib){
bit_to : 1;
}
type (ADDR){
type (addr){
base_type : array;
data_type : bit;
bit_width : 4;
@ -85,15 +85,15 @@ cell (sram_2_16_1_scn4m_subm){
value : 0.0009813788999999999;
}
cell_leakage_power : 0;
bus(DIN0){
bus_type : DATA;
bus(din0){
bus_type : data;
direction : input;
capacitance : 9.8242;
memory_write(){
address : ADDR0;
address : addr0;
clocked_on : clk0;
}
pin(DIN0[1:0]){
pin(din0[1:0]){
timing(){
timing_type : setup_rising;
related_pin : "clk0";
@ -124,15 +124,15 @@ cell (sram_2_16_1_scn4m_subm){
}
}
}
bus(DOUT0){
bus_type : DATA;
bus(dout0){
bus_type : data;
direction : output;
max_capacitance : 78.5936;
min_capacitance : 2.45605;
memory_read(){
address : ADDR0;
address : addr0;
}
pin(DOUT0[1:0]){
pin(dout0[1:0]){
timing(){
timing_sense : non_unate;
related_pin : "clk0";
@ -161,12 +161,12 @@ cell (sram_2_16_1_scn4m_subm){
}
}
bus(ADDR0){
bus_type : ADDR;
bus(addr0){
bus_type : addr;
direction : input;
capacitance : 9.8242;
max_transition : 0.4;
pin(ADDR0[3:0]){
pin(addr0[3:0]){
timing(){
timing_type : setup_rising;
related_pin : "clk0";

View File

@ -19,14 +19,14 @@ module sram_1rw_1r_tb;
reg csb1;
wire [1:0] dout1;
sram_1rw_1r_2_16_scn4m_subm U0 (.DIN0(din0),
.DOUT0(dout0),
.ADDR0(addr0),
sram_1rw_1r_2_16_scn4m_subm U0 (.din0(din0),
.dout0(dout0),
.addr0(addr0),
.csb0(csb0),
.web0(web0),
.clk0(clk),
.DOUT1(dout1),
.ADDR1(addr1),
.dout1(dout1),
.addr1(addr1),
.csb1(csb1),
.clk1(clk)
);

View File

@ -13,9 +13,9 @@ module sram_1rw_tb;
reg web0;
wire [1:0] dout0;
sram_2_16_scn4m_subm U0 (.DIN0(din0),
.DOUT0(dout0),
.ADDR0(addr0),
sram_2_16_scn4m_subm U0 (.din0(din0),
.dout0(dout0),
.addr0(addr0),
.csb0(csb0),
.web0(web0),
.clk0(clk)

View File

@ -14,9 +14,9 @@ module sram_1rw_wmask_tb;
reg [1:0] wmask0;
wire [1:0] dout0;
sram_2b_16_1rw_freepdk45 U0 (.DIN0(din0),
.DOUT0(dout0),
.ADDR0(addr0),
sram_2b_16_1rw_freepdk45 U0 (.din0(din0),
.dout0(dout0),
.addr0(addr0),
.csb0(csb0),
.web0(web0),
.wmask0(wmask0),

File diff suppressed because it is too large Load Diff

View File

@ -44,4 +44,14 @@ Contributions and modifications to this kit are welcomed and encouraged.
ncsu_basekit/ Base kit for custom design
osu_soc/ Standard-cell kit for synthesis, place, & route
FreePDK45.lyp is converted automatically from the .tf using:
https://github.com/klayoutmatthias/tf_import
Command line:
klayout -z -rd tf_file=FreePDK45.tf -rd lyp_file=FreePDK45.lyp
You can then view layouts with:
klayout file.gds -l mosis.lyp
glade_freepdk45.py is a script for Glade:
https://peardrop.co.uk/
to load the .tf using:
glade -script ~/openram/technology/freepdk45/tf/glade_freepdk45.py -gds file.gds

View File

@ -1223,6 +1223,7 @@ drDefinePacket(
( display prBoundary blank solid purple purple )
( display prBoundaryBnd blank solid cyan cyan )
( display prBoundaryLbl blank solid purple purple )
( display comment blank solid purple purple )
( display align blank solid tan tan )
( display hardFence blank solid red red )
( display softFence blank solid yellow yellow )

View File

@ -18,4 +18,16 @@ be found in the file cdb2oa/OA_Conversion.txt.
This kit is not yet fully supported. Please post problems and solutions at
http://www.chiptalk.org -> Forums -> NCSU CDK -> NCSU CDK 1.6.0.beta for Virtuoso 6.1
Modified 2018 by MRG to contain SCN4ME Via3/Metal4 layers.
Modified 2018 by MRG to contain SCN4ME Via3/Metal4 layers.
mosis.lyp is converted automatically from the .tf using:
https://github.com/klayoutmatthias/tf_import
Command line:
klayout -z -rd tf_file=FreePDK45.tf -rd lyp_file=FreePDK45.ly
You can then view layouts with:
klayout file.gds -l mosis.lyp
glade_scn4m_subm.py is a script for Glade:
https://peardrop.co.uk/
to load the .tf using:
glade -script ~/openram/technology/scn3me_subm/tf/glade_scn3me_subm.py -gds file.gds

File diff suppressed because it is too large Load Diff