diff --git a/compiler/characterizer/functional.py b/compiler/characterizer/functional.py index 6e9f81d4..173feb6c 100644 --- a/compiler/characterizer/functional.py +++ b/compiler/characterizer/functional.py @@ -30,7 +30,7 @@ class functional(simulation): # Seed the characterizer with a constant seed for unit tests if OPTS.is_unit_test: - random.seed(12345) + random.seed(687234) if self.write_size is not None: self.num_wmasks = int(self.word_size / self.write_size) @@ -149,7 +149,7 @@ class functional(simulation): wmask = self.gen_wmask() new_word = word for bit in range(len(wmask)): - # Remove the bits of the word that's been written to + # AWhen the write mask's bits are 0, the old data values should appear in the new word if wmask[bit] == "0": lower = bit * self.write_size upper = lower + self.write_size - 1 @@ -170,7 +170,7 @@ class functional(simulation): if addr in w_addrs: self.add_noop_one_port("0"*self.addr_size, "0"*self.word_size, "0"*self.num_wmasks, port) else: - # comment = self.gen_cycle_comment("read", word, addr, self.wmask, port, self.t_current) + comment = self.gen_cycle_comment("read", word, addr, self.wmask, port, self.t_current) self.add_read_one_port(comment, addr, rw_read_din_data, "1"*self.num_wmasks, port) self.write_check.append([word, "{0}{1}".format(self.dout_name,port), self.t_current+self.period, check]) check += 1 diff --git a/compiler/characterizer/simulation.py b/compiler/characterizer/simulation.py index 52070a35..aea8f1cd 100644 --- a/compiler/characterizer/simulation.py +++ b/compiler/characterizer/simulation.py @@ -215,21 +215,6 @@ class simulation(): self.add_data(data,port) self.add_address(address,port) self.add_wmask(wmask,port) - - # - # def add_partial_write_one_port(self, comment, address, data, wmask, port): - # """ Add the control values for a write cycle (partial). Does not increment the period. """ - # debug.check(port in self.write_ports, - # "Cannot add write cycle to a read port. Port {0}, Write Ports {1}".format(port, - # self.write_ports)) - # debug.info(2, comment) - # self.fn_cycle_comments.append(comment) - # - # self.add_control_one_port(port, "write") - # self.add_data(data, port) - # self.add_address(address, port) - # self.add_wmask(wmask,port) - def add_read_one_port(self, comment, address, din_data, wmask, port): """ Add the control values for a read cycle. Does not increment the period. """ @@ -320,8 +305,9 @@ class simulation(): pin_names.append("{0}{1}".format(tech.spice["clk"], port)) if self.write_size is not None: - for bit in range(self.num_wmasks): - pin_names.append("WMASK{0}_{1}".format(port,bit)) + for port in write_index: + for bit in range(self.num_wmasks): + pin_names.append("WMASK{0}_{1}".format(port,bit)) for read_output in read_index: for i in range(dbits): diff --git a/compiler/modules/control_logic.py b/compiler/modules/control_logic.py index 45e1f643..bbd78a13 100644 --- a/compiler/modules/control_logic.py +++ b/compiler/modules/control_logic.py @@ -628,13 +628,6 @@ class control_logic(design.design): offset=out_pos) def create_pen_row(self): - # if self.port_type == "rw": - # # input: gated_clk_bar, we_bar, output: pre_p_en - # self.pre_p_en_inst=self.add_inst(name="and2_pre_p_en", - # mod=self.and2) - # self.connect_inst(["gated_clk_buf", "we_bar", "pre_p_en", "vdd", "gnd"]) - # input_name = "pre_p_en" - # else: input_name = "gated_clk_buf" # input: pre_p_en, output: p_en_bar @@ -646,29 +639,13 @@ class control_logic(design.design): def place_pen_row(self,row): x_off = self.control_x_offset (y_off,mirror)=self.get_offset(row) - - # if self.port_type == "rw": - # offset = vector(x_off, y_off) - # self.pre_p_en_inst.place(offset, mirror) - # - # x_off += self.and2.width - + offset = vector(x_off,y_off) self.p_en_bar_inst.place(offset, mirror) self.row_end_inst.append(self.p_en_bar_inst) def route_pen(self): - # if self.port_type == "rw": - # # Connect the NAND gate inputs to the bus - # pre_p_en_in_map = zip(["A", "B"], ["gated_clk_buf", "we_bar"]) - # self.connect_vertical_bus(pre_p_en_in_map, self.pre_p_en_inst, self.rail_offsets) - # - # out_pos = self.pre_p_en_inst.get_pin("Z").center() - # in_pos = self.p_en_bar_inst.get_pin("A").lc() - # mid1 = vector(out_pos.x,in_pos.y) - # self.add_wire(("metal1","via1","metal2"),[out_pos,mid1,in_pos]) - # else: in_map = zip(["A"], ["gated_clk_buf"]) self.connect_vertical_bus(in_map, self.p_en_bar_inst, self.rail_offsets) diff --git a/compiler/tests/22_psram_wmask_func_test.py b/compiler/tests/22_psram_wmask_func_test.py new file mode 100644 index 00000000..bbf28331 --- /dev/null +++ b/compiler/tests/22_psram_wmask_func_test.py @@ -0,0 +1,73 @@ +#!/usr/bin/env python3 +# See LICENSE for licensing information. +# +# Copyright (c) 2016-2019 Regents of the University of California and The Board +# of Regents for the Oklahoma Agricultural and Mechanical College +# (acting for and on behalf of Oklahoma State University) +# All rights reserved. +# +import unittest +from testutils import * +import sys, os + +sys.path.append(os.getenv("OPENRAM_HOME")) +import globals +from globals import OPTS +from sram_factory import factory +import debug + + +# @unittest.skip("SKIPPING psram_wmask_func_test") +class psram_wmask_func_test(openram_test): + + def runTest(self): + globals.init_openram("config_{0}".format(OPTS.tech_name)) + OPTS.analytical_delay = False + OPTS.netlist_only = True + OPTS.trim_netlist = False + OPTS.bitcell = "bitcell_1w_1r" + OPTS.replica_bitcell = "replica_bitcell_1w_1r" + + OPTS.num_rw_ports = 0 + OPTS.num_w_ports = 1 + OPTS.num_r_ports = 1 + + # This is a hack to reload the characterizer __init__ with the spice version + from importlib import reload + import characterizer + reload(characterizer) + from characterizer import functional, delay + from sram_config import sram_config + c = sram_config(word_size=8, + num_words=16, + write_size=2, + num_banks=1) + c.words_per_row = 1 + c.recompute_sizes() + debug.info(1, + "Functional test for sram with {} bit words, {} words, {} words per row, {} bit writes, {} banks".format( + c.word_size, + c.num_words, + c.words_per_row, + c.write_size, + c.num_banks)) + s = factory.create(module_type="sram", sram_config=c) + tempspice = OPTS.openram_temp + "temp.sp" + s.sp_write(tempspice) + + corner = (OPTS.process_corners[0], OPTS.supply_voltages[0], OPTS.temperatures[0]) + + f = functional(s.s, tempspice, corner) + f.num_cycles = 10 + (fail, error) = f.run() + self.assertTrue(fail, error) + + globals.end_openram() + + +# run the test from the command line +if __name__ == "__main__": + (OPTS, args) = globals.parse_args() + del sys.argv[1:] + header(__file__, OPTS.tech_name) + unittest.main(testRunner=debugTestRunner()) \ No newline at end of file