def design(self, nand_params: Param, nor_params: Param, pupd_params: Param,
               export_pins: bool) -> None:
        self.instances['XNAND'].design(**nand_params)
        self.instances['XNOR'].design(**nor_params)
        self.instances['Xpupd'].design(**pupd_params.copy(append=dict(
            strong=True)))

        if export_pins:
            self.add_pin('nand_pu', TermType.output)
            self.add_pin('nor_pd', TermType.output)
Пример #2
0
    def _get_buf_lv_master(self, buf_params: Param, append: Mapping[str, Any]) -> InvChainCore:
        buf_params = buf_params.copy(append=dict(
            dual_output=True,
            vertical_output=True,
            **append
        ), remove=['sig_locs'])
        buf_master = self.new_template(InvChainCore, params=buf_params)

        vm_layer = self.conn_layer + 2
        out_tidx = buf_master.get_port('out').get_pins()[0].track_id.base_index
        prev_tidx = self.tr_manager.get_next_track(vm_layer, out_tidx, 'sig', 'sig', up=False)
        buf_master = buf_master.new_template_with(sig_locs=dict(outb=prev_tidx))
        return buf_master
Пример #3
0
    def design(self, dlycell_params: Param, num_insts: int, num_dum: int,
               flop: bool, flop_char: bool, output_sr_pins: bool) -> None:
        """To be overridden by subclasses to design this module.

        This method should fill in values for all parameters in
        self.parameters.  To design instances of this module, you can
        call their design() method or any other ways you coded.

        To modify schematic structure, call:

        rename_pin()
        delete_instance()
        replace_instance_master()
        reconnect_instance_terminal()
        restore_instance()
        array_instance()
        """
        if not flop:
            self.replace_instance_master('XCELL',
                                         'aib_ams',
                                         'aib_dlycell_no_flop',
                                         keep_connections=True)
            self.replace_instance_master('XDUM',
                                         'aib_ams',
                                         'aib_dlycell_no_flop',
                                         keep_connections=True)
            for name in ['RSTb', 'CLKIN', 'iSI', 'SOOUT', 'iSE']:
                self.remove_pin(name)

        self.instances['XCELL'].design(**dlycell_params)

        if num_insts > 2:

            if output_sr_pins:
                conn_list = [('in_p', f'a<{num_insts - 2}:0>,dlyin'),
                             ('bk', f'bk<{num_insts - 1}:0>'),
                             ('ci_p', f'b<{num_insts - 1}:0>'),
                             ('out_p', f'b<{num_insts-2}:0>,dlyout'),
                             ('co_p', f'a<{num_insts - 1}:0>'),
                             ('si', f'so<{num_insts-2}:0>,iSI'),
                             ('so', f'SOOUT,so<{num_insts-2}:0>'),
                             ('srqb', f'srqb<{num_insts - 1}:0>'),
                             ('srq', f'srq<{num_insts - 1}:0>')]
            else:
                conn_list = [
                    ('in_p', f'a<{num_insts - 2}:0>,dlyin'),
                    ('bk', f'bk<{num_insts - 1}:0>'),
                    ('ci_p', f'b{num_insts - 1},b<{num_insts - 2}:0>'),
                    ('out_p', f'b<{num_insts - 2}:0>,dlyout'),
                    ('co_p', f'a{num_insts - 1},a<{num_insts - 2}:0>'),
                    ('si', f'so<{num_insts - 2}:0>,iSI'),
                    ('so', f'SOOUT,so<{num_insts - 2}:0>'),
                ]

            if flop_char:
                conn_list.append(('bk1', f'flop_q<{num_insts - 1}:0>'))
                self.add_pin(f'flop_q<{num_insts - 1}:0>', TermType.output)
            self.rename_instance('XCELL', f'XCELL<{num_insts - 1}:0>',
                                 conn_list)
        elif num_insts == 2:
            conn_list = [
                ('in_p', f'a,dlyin'),
                ('bk', f'bk<{num_insts - 1}:0>'),
                ('ci_p', f'b{num_insts - 1},b'),
                ('out_p', 'b,dlyout'),
                ('co_p', f'a{num_insts - 1},a'),
                ('si', f'so,iSI'),
                ('so', f'SOOUT,so'),
            ]

            if output_sr_pins:
                conn_list += [('srqb', f'srqb<1:0>'), ('srq', f'srq<1:0>')]

            if flop_char:
                conn_list.append(('bk1', f'flop_q<{num_insts - 1}:0>'))
                self.add_pin(f'flop_q<{num_insts - 1}:0>', TermType.output)
            self.rename_instance('XCELL', f'XCELL<{num_insts - 1}:0>',
                                 conn_list)
        elif num_insts == 1:
            if flop_char:
                self.reconnect_instance_terminal('XCELL', 'bk1', 'flop_q<0>')
                self.add_pin('flop_q<0>', TermType.output)
            if output_sr_pins:
                self.reconnect_instance_terminal('XCELL', 'srq', 'srq')
                self.reconnect_instance_terminal('XCELL', 'srqb', 'srqb')

        else:
            raise ValueError(
                f'num_insts={num_insts} should be greater than 0.')

        if num_dum > 0:
            dc_core_params = dlycell_params['dc_core_params'].copy(
                remove=['output_sr_pins'])
            dum_params = dlycell_params.copy(
                remove=['flop_char', 'output_sr_pins'],
                append={
                    'is_dum': True,
                    'dc_core_params': dc_core_params
                })
            self.instances['XDUM'].design(**dum_params)
            if num_dum > 1:
                suffix = f'<{num_dum - 1}:0>'
                conn_list = [
                    ('out_p', 'NC_out' + suffix),
                    ('co_p', 'NC_co' + suffix),
                    ('so', 'NC_so' + suffix),
                ]
                self.rename_instance('XDUM', 'XDUM' + suffix, conn_list)
                if flop:
                    self.rename_instance('XNC_so', 'XNC_so' + suffix,
                                         [('noConn', 'NC_so' + suffix)])
                else:
                    self.remove_instance('XNC_so')
                self.rename_instance('XNC_co', 'XNC_co' + suffix,
                                     [('noConn', 'NC_co' + suffix)])
                self.rename_instance('XNC_out', 'XNC_out' + suffix,
                                     [('noConn', 'NC_out' + suffix)])
        else:
            for inst in ['XDUM', 'XNC_so', 'XNC_co', 'XNC_out']:
                self.remove_instance(inst)

        if output_sr_pins:
            if num_insts == 2:
                raise ValueError('oops not supported')
            pin_name_list = [
                ('bk', f'bk<{num_insts - 1}:0>'),
                ('b', f'b<{num_insts - 1}:0>'),
                ('a', f'a<{num_insts - 1}:0>'),
            ] if num_insts > 1 else []
            self.add_pin(f'srq<{num_insts-1}:0>', TermType.output)
            self.add_pin(f'srqb<{num_insts-1}:0>', TermType.output)
        else:
            pin_name_list = [
                ('bk', f'bk<{num_insts - 1}:0>'),
                ('b', f'b{num_insts - 1}'),
                ('a', f'a{num_insts - 1}'),
            ] if num_insts > 1 else []

        for old_name, new_name in pin_name_list:
            self.rename_pin(old_name, new_name)
    def _create_masters(
        self, pinfo: MOSBasePlaceInfo, ridx_p: int, ridx_n: int,
        is_guarded: bool, invp_params_list: Sequence[Param],
        invn_params_list: Sequence[Param], pg_params: Param,
        sig_locs: Mapping[str, Union[float, HalfInt]], vertical_out: bool,
        vertical_in: bool
    ) -> Tuple[Sequence[InvCore], Sequence[InvCore], PassGateCore]:
        # configure sig_locs dictionary so we can connect more signals on hm_layer
        nout_tid = get_adj_tidx_list(self, ridx_n, sig_locs, MOSWireType.DS,
                                     'nout', False)
        pout_tid = get_adj_tidx_list(self, ridx_p, sig_locs, MOSWireType.DS,
                                     'pout', True)
        nin_tid = get_adj_tidx_list(self, ridx_n, sig_locs, MOSWireType.G,
                                    'nin', True)
        pin_tid = get_adj_tidx_list(self, ridx_p, sig_locs, MOSWireType.G,
                                    'pin', False)
        # TODO: this gate index hack fixes cases where you cannot short adjacent hm_layer
        # TODO: tracks with vm_layer.  Need more rigorous checking later so we can reduce
        # TODO: gate resistance
        even_gate_index = int(is_guarded)
        # create masters
        append_dict = dict(
            pinfo=pinfo,
            ridx_p=ridx_p,
            ridx_n=ridx_n,
            is_guarded=is_guarded,
        )
        sig_locs0 = dict(
            nout=nout_tid[0],
            pout=pout_tid[0],
            nin=nin_tid[even_gate_index],
            pin=pin_tid[even_gate_index],
        )
        sig_locs1 = dict(
            nout=nout_tid[1],
            pout=pout_tid[1],
            nin=nin_tid[1],
            pin=pin_tid[1],
        )
        invp0 = self.new_template(InvCore,
                                  params=invp_params_list[0].copy(
                                      append=dict(sig_locs=sig_locs0,
                                                  vertical_out=not is_guarded,
                                                  vertical_in=vertical_in,
                                                  **append_dict)))
        pg = self.new_template(PassGateCore,
                               params=pg_params.copy(append=dict(
                                   sig_locs=dict(
                                       nd=nout_tid[0],
                                       pd=pout_tid[0],
                                       ns=nout_tid[1],
                                       ps=pout_tid[1],
                                       en=nin_tid[1],
                                       enb=pin_tid[1],
                                   ),
                                   pinfo=pinfo,
                                   ridx_p=ridx_p,
                                   ridx_n=ridx_n,
                                   is_guarded=is_guarded,
                                   vertical_out=False,
                                   vertical_in=False,
                               )))
        invp1 = self.new_template(
            InvCore,
            params=invp_params_list[1].copy(append=dict(
                sig_locs=sig_locs0, vertical_out=vertical_out, **append_dict)))

        invn0 = self.new_template(InvCore,
                                  params=invn_params_list[0].copy(
                                      append=dict(sig_locs=sig_locs0,
                                                  vertical_out=not is_guarded,
                                                  vertical_in=vertical_in,
                                                  **append_dict)))
        invn1 = self.new_template(
            InvCore,
            params=invn_params_list[1].copy(append=dict(
                sig_locs=sig_locs1, vertical_out=not is_guarded, **
                append_dict)))
        invn2 = self.new_template(
            InvCore,
            params=invn_params_list[2].copy(append=dict(
                sig_locs=sig_locs0, vertical_out=vertical_out, **append_dict)))

        if is_guarded:
            # make sure vm input pin are on the same track
            n0_in = invn0.get_port('in').get_pins()[0]
            p0_in = invp0.get_port('in').get_pins()[0]
            n0_tidx = n0_in.track_id.base_index
            p0_tidx = p0_in.track_id.base_index
            if n0_tidx < p0_tidx:
                sig_locs0['in'] = n0_tidx
                invp0 = invp0.new_template_with(sig_locs=sig_locs0)
            elif p0_tidx < n0_tidx:
                sig_locs0['in'] = p0_tidx
                invn0 = invn0.new_template_with(sig_locs=sig_locs0)

        return [invp0, invp1], [invn0, invn1, invn2], pg