示例#1
0
    def instantiate_single_port(self, banks_tall, banks_wide, macro_width,
                                macro_depth):
        '''
        Hook up the set of single port memories
        '''

        self._sub_addr = self.var("addr_macro", self.addr_width_macro)
        self.wire(self._sub_addr, self._addr[self.addr_width_macro - 1, 0])

        # Hook up the grid of SRAM banks
        for i in range(banks_tall):
            for j in range(banks_wide):
                self.add_child(f"sram_d{i}_w{j}",
                               SRAMStub(macro_width, macro_depth))

                self.wire(self[f"sram_d{i}_w{j}"].ports.i_clk, self._clk)
                self.wire(self[f"sram_d{i}_w{j}"].ports.i_rst_n, self._rst_n)

                self.wire(self[f"sram_d{i}_w{j}"].ports.i_addr, self._sub_addr)
                if (banks_tall > 1):
                    self.wire(
                        self[f"sram_d{i}_w{j}"].ports.i_wen,
                        self._wen & (self._addr[self.full_addr - 1,
                                                self.addr_width_macro] == i))
                    self.wire(self[f"sram_d{i}_w{j}"].ports.i_cen,
                              (self._ren | self._wen) &
                              (self._addr[self.full_addr - 1,
                                          self.addr_width_macro] == i))
                else:
                    self.wire(self[f"sram_d{i}_w{j}"].ports.i_wen, self._wen)
                    self.wire(self[f"sram_d{i}_w{j}"].ports.i_cen,
                              (self._ren | self._wen))

                # Send the data across horizontally based on j and the macro width
                self.wire(
                    self[f"sram_d{i}_w{j}"].ports.i_data,
                    self._wr_data[((j + 1) * macro_width) - 1,
                                  j * macro_width])

        for i in range(banks_tall):
            if (banks_wide > 1):
                self.wire(
                    self._memory_space[i],
                    concat(*[
                        self[f"sram_d{i}_w{j}"].ports.o_data
                        for j in range(banks_wide)
                    ]))
            else:
                self.wire(self._memory_space,
                          self[f"sram_d{i}_w{j}"].ports.o_data)

        if (banks_tall > 1):
            self.wire(self._rd_data, self._memory_space[self._bank_sel_reg])
        else:
            self.wire(self._rd_data, self._memory_space)

        return 0
示例#2
0
    def build_two_port(self, banks_tall, banks_wide, macro_width, macro_depth):
        '''
        Takes a single port memory and constructs a
        virtualized two port memory from a single port memory
        '''
        # We need one extra bank to create 1R1W
        logical_banks = banks_tall + 1

        # Create all logical banks as a bank array
        for i in range(logical_banks):
            for j in range(banks_wide):
                self.add_child(f"sram_d{i}_w{j}", SRAMStub(macro_width, macro_depth))

        return 5
示例#3
0
    def __init__(self, macro_width, logical_banks, macro_depth):
        super().__init__("virtual_remap_table")
        self._virt_addr = self.input("i_virt_addr", width)
        self._ren = self.input("i_ren", 1)
        self._out = self.output("o_data_out", width)
        self._in = self.input("i_data_in", width)
        self._clk = self.clock("i_clk")
        self._rst_n = self.reset("i_rst_n")

        # First wrap sram_stub
        sram_stub = SRAMStub(width, 1024)
        self.add_child_generator(f"u_sram_stub_0", sram_stub)
        self.wire(sram_stub.i_data, self._in)
        self.wire(self._out, sram_stub.o_data)

        self.wire(sram_stub.i_addr, 0)
        self.wire(sram_stub.i_cen, 0)
        self.wire(sram_stub.i_wen, 0)
        self.wire(sram_stub.i_clk, self._clk)
        self.wire(sram_stub.i_rst_n, self._rst_n)
示例#4
0
文件: sram.py 项目: StanfordAHA/lake
    def __init__(self, use_sram_stub, sram_name, data_width, fw_int, mem_depth,
                 mem_input_ports, mem_output_ports, address_width, bank_num,
                 num_tiles):
        super().__init__(f"{sram_name}_generator")

        self.use_sram_stub = use_sram_stub
        self.sram_name = sram_name
        self.data_width = data_width
        self.fw_int = fw_int
        self.mem_depth = mem_depth
        self.mem_input_ports = mem_input_ports
        self.mem_output_ports = mem_output_ports
        self.address_width = address_width
        self.bank_num = bank_num
        self.num_tiles = num_tiles

        self.chain_idx_bits = max(1, clog2(num_tiles))

        self._gclk = self.clock("clk")

        self._clk_en = self.input("clk_en", 1)

        if self.fw_int > 1:
            self._mem_data_in_bank = self.input("mem_data_in_bank",
                                                self.data_width,
                                                size=self.fw_int,
                                                packed=True,
                                                explicit_array=True)

            self._mem_data_out_bank = self.output("mem_data_out_bank",
                                                  self.data_width,
                                                  size=(self.mem_output_ports,
                                                        self.fw_int),
                                                  packed=True,
                                                  explicit_array=True)

            if not self.use_sram_stub:
                # flattened version of input data
                self._sram_mem_data_in_bank = self.var(
                    "sram_mem_data_in_bank",
                    self.data_width * self.fw_int * self.mem_input_ports)

                # flattened version of output data
                self._sram_mem_data_out_bank = self.var(
                    "sram_mem_data_out_bank",
                    self.data_width * self.fw_int * self.mem_output_ports)
        else:
            self._mem_data_in_bank = self.input("mem_data_in_bank",
                                                self.data_width,
                                                packed=True)

            self._mem_data_out_bank = self.output("mem_data_out_bank",
                                                  self.data_width,
                                                  packed=True)

        self._mem_addr_in_bank = self.input("mem_addr_in_bank",
                                            self.address_width)
        if num_tiles == 1:
            self._mem_addr_to_sram = self.var("mem_addr_to_sram",
                                              self.address_width)
        else:
            self._mem_addr_to_sram = self.var(
                "mem_addr_to_sram", self.address_width - self.chain_idx_bits)

        self._mem_cen_in_bank = self.input("mem_cen_in_bank",
                                           self.mem_output_ports)

        self._mem_wen_in_bank = self.input("mem_wen_in_bank",
                                           self.mem_input_ports)

        self._wtsel = self.input("wtsel", 2)
        self._rtsel = self.input("rtsel", 2)

        if self.use_sram_stub:
            mbank = SRAMStub(data_width=self.data_width,
                             width_mult=self.fw_int,
                             depth=self.mem_depth)

            self.add_child(f"mem_{self.bank_num}",
                           mbank,
                           clk=self._gclk,
                           data_in=self._mem_data_in_bank,
                           addr=self._mem_addr_to_sram,
                           cen=self._mem_cen_in_bank,
                           wen=self._mem_wen_in_bank,
                           data_out=self._mem_data_out_bank)

        # instantiante external provided sram macro and flatten input/output data
        # if fetch width is greater than 1
        else:
            mbank = SRAMStubGenerator(sram_name=self.sram_name,
                                      data_width=self.data_width,
                                      width_mult=self.fw_int,
                                      depth=self.mem_depth)

            compose_wide = True

            if self.fw_int > 1:
                flatten_data_in = FlattenND(self.data_width, self.fw_int,
                                            self.mem_input_ports)

                self.add_child(f"flatten_data_in_{self.bank_num}",
                               flatten_data_in,
                               input_array=self._mem_data_in_bank,
                               output_array=self._sram_mem_data_in_bank)

                if compose_wide:
                    for j in range(2):
                        mbank = SRAMStubGenerator(sram_name=self.sram_name,
                                                  data_width=self.data_width,
                                                  width_mult=self.fw_int // 2,
                                                  depth=self.mem_depth)

                        self.add_child(
                            f"mem_inst_{self.bank_num}_pt_{j}",
                            mbank,
                            sram_addr=self._mem_addr_to_sram,
                            sram_cen=~self._mem_cen_in_bank,
                            sram_clk=self._gclk,
                            sram_data_in=self._sram_mem_data_in_bank[j * 32 +
                                                                     32 - 1,
                                                                     j * 32],
                            sram_data_out=self._sram_mem_data_out_bank[j * 32 +
                                                                       32 - 1,
                                                                       j * 32],
                            sram_wen=~self._mem_wen_in_bank,
                            sram_wtsel=self._wtsel,
                            sram_rtsel=self._rtsel)

                else:
                    self.add_child(f"mem_inst_{self.bank_num}",
                                   mbank,
                                   sram_addr=self._mem_addr_to_sram,
                                   sram_cen=~self._mem_cen_in_bank,
                                   sram_clk=self._gclk,
                                   sram_data_in=self._sram_mem_data_in_bank,
                                   sram_data_out=self._sram_mem_data_out_bank,
                                   sram_wen=~self._mem_wen_in_bank,
                                   sram_wtsel=self._wtsel,
                                   sram_rtsel=self._rtsel)

                flatten_data_out = ReverseFlatten(self.data_width, self.fw_int,
                                                  self.mem_output_ports)

                self.add_child(f"flatten_data_out_{self.bank_num}",
                               flatten_data_out,
                               input_array=self._sram_mem_data_out_bank,
                               output_array=self._mem_data_out_bank)

            else:
                self.add_child(f"mem_inst_{self.bank_num}",
                               mbank,
                               sram_addr=self._mem_addr_to_sram,
                               sram_cen=~self._mem_cen_in_bank,
                               sram_clk=self._gclk,
                               sram_data_in=self._mem_data_in_bank,
                               sram_data_out=self._mem_data_out_bank,
                               sram_wen=~self._mem_wen_in_bank,
                               sram_wtsel=self._wtsel,
                               sram_rtsel=self._rtsel)

        self.add_code(self.set_mem_addr)
示例#5
0
    def __init__(self,
                 data_width=16,
                 fetch_width=1,
                 mem_depth=512,
                 config_width=16,
                 input_addr_iterator_support=6,
                 output_addr_iterator_support=6,
                 input_sched_iterator_support=6,
                 output_sched_iterator_support=6
                 ):

        super().__init__("lake_top_test")

        # generation parameters

        # inputs
        self._clk = self.clock("clk")
        self._rst_n = self.reset("rst_n")

        self._clk_en = self.input("clk_en", 1)
        self._flush = self.input("flush", 1)

        self._data_in = self.input("data_in", data_width, packed=True)

        # outputs
        self._data_out = self.output("data_out", data_width, packed=True)

        # local variables
        self._write = self.var("write", 1)
        self._read = self.var("read", 1)
        self._write_addr = self.var("write_addr", config_width)
        self._read_addr = self.var("read_addr", config_width)
        self._addr = self.var("addr", clog2(mem_depth))

        # memory module
        self.add_child(f"sram",
                       SRAMStub(data_width,
                                fetch_width,
                                mem_depth),
                       clk=self._clk,
                       wen=self._write,
                       cen=self._write | self._read,
                       addr=self._addr,
                       data_in=self._data_in,
                       data_out=self._data_out)

        # addressor modules
        self.add_child(f"input_addr_gen",
                       AddrGen(input_addr_iterator_support,
                               config_width),
                       clk=self._clk,
                       rst_n=self._rst_n,
                       step=self._write,
                       addr_out=self._write_addr,
                       clk_en=self._clk_en,
                       flush=self._flush)

        self.add_child(f"output_addr_gen",
                       AddrGen(output_addr_iterator_support,
                               config_width),
                       clk=self._clk,
                       rst_n=self._rst_n,
                       step=self._read,
                       addr_out=self._read_addr,
                       clk_en=self._clk_en,
                       flush=self._flush)

        # scheduler modules
        self.add_child(f"input_sched_gen",
                       SchedGen(input_sched_iterator_support,
                                config_width),
                       clk=self._clk,
                       rst_n=self._rst_n,
                       clk_en=self._clk_en,
                       flush=self._flush,
                       valid_output=self._write)

        self.add_child(f"output_sched_gen",
                       SchedGen(output_sched_iterator_support,
                                config_width),
                       clk=self._clk,
                       rst_n=self._rst_n,
                       clk_en=self._clk_en,
                       flush=self._flush,
                       valid_output=self._read)

        lift_config_reg(self.internal_generator)

        self.add_code(self.set_sram_addr)
示例#6
0
def test_sram_basic(data_width, depth, width_mult, num_tiles=1):

    # Set up model...
    model_sram = SRAMModel(data_width=data_width,
                           width_mult=width_mult,
                           depth=depth,
                           num_tiles=num_tiles)
    new_config = {}
    model_sram.set_config(new_config=new_config)
    ###

    # Set up dut...
    dut = SRAMStub(data_width=data_width, width_mult=width_mult, depth=depth)

    magma_dut = kts.util.to_magma(dut,
                                  flatten_array=True,
                                  check_flip_flop_always_ff=False)
    tester = fault.Tester(magma_dut, magma_dut.clk)
    ###

    for key, value in new_config.items():
        setattr(tester.circuit, key, value)

    rand.seed(0)

    data = [0 for i in range(width_mult)]

    for z in range(1000):
        # Generate new input
        wen = rand.randint(0, 1)
        cen = rand.randint(0, 1)
        addr = rand.randint(0, depth - 1)
        for i in range(width_mult):
            data[i] = rand.randint(0, 2**data_width - 1)

        tester.circuit.wen = wen
        tester.circuit.cen = cen
        tester.circuit.addr = addr

        if width_mult == 1:
            tester.circuit.data_in = data[0]
        else:
            for i in range(width_mult):
                setattr(tester.circuit, f"data_in_{i}", data[i])

        model_dat_out = model_sram.interact(wen, cen, addr, data)

        tester.eval()

        if width_mult == 1:
            tester.circuit.data_out.expect(model_dat_out[0])
        else:
            for i in range(width_mult):
                getattr(tester.circuit,
                        f"data_out_{i}").expect(model_dat_out[i])

        tester.step(2)

    with tempfile.TemporaryDirectory() as tempdir:
        tester.compile_and_run(target="verilator",
                               directory=tempdir,
                               magma_output="verilog",
                               flags=["-Wno-fatal"])
示例#7
0
    def __init__(self,
                 data_width=16,
                 fetch_width=4,
                 mem_depth=512,
                 config_width=9,
                 input_addr_iterator_support=6,
                 output_addr_iterator_support=6,
                 input_sched_iterator_support=6,
                 output_sched_iterator_support=6):

        super().__init__("lake_top_test")

        # generation parameters

        # inputs
        self._clk = self.clock("clk")
        self._rst_n = self.reset("rst_n")

        self._clk_en = self.input("clk_en", 1)
        self._flush = self.input("flush", 1)

        self._data_in = self.input("data_in", data_width, packed=True)

        # outputs
        self._data_out = self.output("data_out", data_width, packed=True)

        # local variables
        self._write = self.var("write", 1)
        self._read = self.var("read", 1)
        self._write_addr = self.var("write_addr", config_width)
        self._read_addr = self.var("read_addr", config_width)
        self._addr = self.var("addr", clog2(mem_depth))

        self._agg_write = self.var("agg_write", 1)
        self._agg_write_addr = self.var("agg_write_addr", 2)
        self._agg_read_addr = self.var("agg_read_addr", 2)

        self._tb_read = self.var("tb_read", 1)
        self._tb_write_addr = self.var("tb_write_addr", 2)
        self._tb_read_addr = self.var("tb_read_addr", 2)

        self._sram_write_data = self.var("sram_write_data",
                                         data_width,
                                         size=fetch_width,
                                         packed=True)
        self._sram_read_data = self.var("sram_read_data",
                                        data_width,
                                        size=fetch_width,
                                        packed=True)

        #        self._aggw_start_addr = self.input("aggw_start_addr", 2)
        #        self._aggw_start_addr.add_attribute(ConfigRegAttr("agg write start addr"))
        #        self._agg_start_addr = self.input("agg_start_addr", 2)
        #        self._agg_start_addr.add_attribute(ConfigRegAttr("agg read start addr"))

        self._agg_write_index = self.var("agg_write_index", 2, size=4)

        self._agg = self.var("agg",
                             width=data_width,
                             size=fetch_width,
                             packed=True)

        self.add_child(f"agg_write_addr_gen",
                       AddrGen(2, 2),
                       clk=self._clk,
                       rst_n=self._rst_n,
                       step=self._agg_write,
                       addr_out=self._agg_write_addr,
                       clk_en=self._clk_en,
                       flush=self._flush)

        self.add_child(f"agg_read_addr_gen",
                       AddrGen(2, 2),
                       clk=self._clk,
                       rst_n=self._rst_n,
                       step=self._write,
                       addr_out=self._agg_read_addr,
                       clk_en=self._clk_en,
                       flush=self._flush)

        self.add_child(f"agg_write_sched_gen",
                       SchedGen(2, 2),
                       clk=self._clk,
                       rst_n=self._rst_n,
                       clk_en=self._clk_en,
                       flush=self._flush,
                       valid_output=self._agg_write)

        self._tb = self.var("tb", width=data_width, size=fetch_width)

        self.add_child(f"tb_write_addr_gen",
                       AddrGen(2, 2),
                       clk=self._clk,
                       rst_n=self._rst_n,
                       step=self._read,
                       addr_out=self._tb_write_addr,
                       clk_en=self._clk_en,
                       flush=self._flush)

        self.add_child(f"tb_read_addr_gen",
                       AddrGen(2, 2),
                       clk=self._clk,
                       rst_n=self._rst_n,
                       step=self._tb_read,
                       addr_out=self._tb_read_addr,
                       clk_en=self._clk_en,
                       flush=self._flush)

        self.add_child(f"tb_read_sched_gen",
                       SchedGen(2, 2),
                       clk=self._clk,
                       rst_n=self._rst_n,
                       clk_en=self._clk_en,
                       flush=self._flush,
                       valid_output=self._tb_read)

        # memory module
        self.add_child(f"sram",
                       SRAMStub(data_width, fetch_width, mem_depth),
                       clk=self._clk,
                       wen=self._write,
                       cen=self._write | self._read,
                       addr=self._addr,
                       data_in=self._sram_write_data,
                       data_out=self._sram_read_data)

        # addressor modules
        self.add_child(f"input_addr_gen",
                       AddrGen(input_addr_iterator_support, config_width),
                       clk=self._clk,
                       rst_n=self._rst_n,
                       step=self._write,
                       addr_out=self._write_addr,
                       clk_en=self._clk_en,
                       flush=self._flush)

        self.add_child(f"output_addr_gen",
                       AddrGen(output_addr_iterator_support, config_width),
                       clk=self._clk,
                       rst_n=self._rst_n,
                       step=self._read,
                       addr_out=self._read_addr,
                       clk_en=self._clk_en,
                       flush=self._flush)

        # scheduler modules
        self.add_child(f"input_sched_gen",
                       SchedGen(input_sched_iterator_support, config_width),
                       clk=self._clk,
                       rst_n=self._rst_n,
                       clk_en=self._clk_en,
                       flush=self._flush,
                       valid_output=self._write)

        self.add_child(f"output_sched_gen",
                       SchedGen(output_sched_iterator_support, config_width),
                       clk=self._clk,
                       rst_n=self._rst_n,
                       clk_en=self._clk_en,
                       flush=self._flush,
                       valid_output=self._read)

        lift_config_reg(self.internal_generator)

        self.add_code(self.set_sram_addr)
        self.add_code(self.agg_ctrl)
        self.add_code(self.tb_ctrl)
        self.add_code(self.agg_to_sram)
        self.add_code(self.tb_to_out)