mirror of https://github.com/VLSIDA/OpenRAM.git
Merge branch 'dev' into add_wmask
This commit is contained in:
commit
af3d2af0ec
|
|
@ -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")
|
||||
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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"]))),
|
||||
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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) + "=========|")
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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"])
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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"])
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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
Loading…
Reference in New Issue