Ejemplo n.º 1
0
def fusion_lut_with_mux( lut, counter ):
    '''将lut和mux进行逻辑混合, 插入扫描逻辑.
        In = scan_in+str(counter)
        I(n+1) = scan_en
        计算新的init_value
    '''
    assert isinstance(lut, cc.circut_module) and lut.m_type=="LUT"
    input_num = lut.input_count()
    assert input_num == int( lut.cellref[3] )
    scan_in = cc.port("I"+str(input_num),'input',cc.signal(name="scan_in"+str(counter)))            
    scan_en = cc.port('I'+str(input_num+1),'input',cc.signal(name="scan_en"))            
    lut.port_list.insert(-1,scan_in)
    lut.port_list.insert(-1,scan_en)
    assert (not lut.param_list==None) and len(lut.param_list)==1
    old_init = lut.param_list[0].value
    init_legal = re.match('(\d+)\'[hb]([0-9A-F]+)',old_init)
    assert (init_legal is not None)
    assert int(init_legal.groups()[0])==2**input_num
    if input_num == 1:
        assert  (init_legal.groups()[0] == '2' and init_legal.groups()[1] == "1"),\
        "Error:find LUT1 .INIT !=2'h1 %s, is %s" % (lut.name,lut.param_list[0].value)
        NEW_INIT = "8'hC5"
    else:
        NEW_INIT = str(2**(input_num+2))+'\'h'+'F'*int(2**(input_num-2)) \
        +'0'*int(2**(input_num-2))+(init_legal.groups()[1])*2
    lut.param_list[0].edit_param('INIT',NEW_INIT)
    lut.cellref = re.sub('LUT[1-4]', ( 'LUT'+str(input_num+2) ), lut.cellref )
    assert lut.input_count() == (input_num + 2)
    return None
Ejemplo n.º 2
0
def p_signal_decl(p):
    ''' signal_decl    : WIRE VECTOR IDENTIFIER ';'
                       | WIRE IDENTIFIER ';'
    '''
    if len(p)==5:
        p[0]=cc.signal(name=p[3],vector=p[2])
    else:
        p[0]=cc.signal(name=p[2],vector=None)
Ejemplo n.º 3
0
def p_signal_decl(p):
    ''' signal_decl    : WIRE VECTOR IDENTIFIER ';'
                       | WIRE IDENTIFIER ';'
    '''
    if len(p) == 5:
        p[0] = cc.signal(name=p[3], vector=p[2])
    else:
        p[0] = cc.signal(name=p[2], vector=None)
Ejemplo n.º 4
0
def replace_fd_with_scan_fd(fd, counter):
    '''将FD*替换为 SCAN_FD*, 并且增加三个和扫描有关的端口.
    '''
    assert isinstance(fd, cc.circut_module) and fd.m_type == "FD"
    fd.cellref = "SCAN_"+fd.cellref
    SCAN_IN = cc.port( 'SCAN_IN', 'input', cc.signal(name="scan_in"+str(counter)) )
    SCAN_EN = cc.port( 'SCAN_EN', 'input', cc.signal(name="scan_en"))
    SCAN_OUT = cc.port( 'SCAN_OUT', 'output', cc.signal(name='scan_out'+str(counter)) )
    fd.port_list.insert(0, SCAN_OUT)
    fd.port_list.insert(0, SCAN_EN)
    fd.port_list.insert(0, SCAN_IN)
    return None
Ejemplo n.º 5
0
def add_scan_ports_top(top_module):
    '''在顶层模块增加三个端口
    '''
    #assert isinstance(top_module, cc.circut_module)
    _scan_in = cc.signal('input', 'scan_in', None)
    _scan_en = cc.signal('input', 'scan_en', None)
    _scan_out = cc.signal('output', 'scan_out', None)
    port_scan_in = _scan_in.signal_2_port()
    port_scan_en = _scan_en.signal_2_port()
    port_scan_out = _scan_out.signal_2_port()
    top_module.port_list.insert(0,port_scan_in)
    top_module.port_list.insert(0,port_scan_out)
    top_module.port_list.insert(0,port_scan_en)
    return None
Ejemplo n.º 6
0
def p_port_decl(p):
    '''port_decl     : INPUT  IDENTIFIER ';'
                     | INPUT  VECTOR IDENTIFIER ';'
                     | OUTPUT IDENTIFIER ';'
                     | OUTPUT VECTOR IDENTIFIER ';'
                     | INOUT  IDENTIFIER ';'
                     | INOUT  VECTOR IDENTIFIER ';'
    '''
    if len(p)==5:
        tmp=cc.signal(s_type=p[1],name=p[3],vector=p[2])
        p[0]=tmp.signal_2_port()

    else:
        tmp=cc.signal(s_type=p[1],name=p[2],vector=None)    
        p[0]=tmp.signal_2_port()
Ejemplo n.º 7
0
def p_port_decl(p):
    '''port_decl     : INPUT  IDENTIFIER ';'
                     | INPUT  VECTOR IDENTIFIER ';'
                     | OUTPUT IDENTIFIER ';'
                     | OUTPUT VECTOR IDENTIFIER ';'
                     | INOUT  IDENTIFIER ';'
                     | INOUT  VECTOR IDENTIFIER ';'
    '''
    if len(p) == 5:
        tmp = cc.signal(s_type=p[1], name=p[3], vector=p[2])
        p[0] = tmp.signal_2_port()

    else:
        tmp = cc.signal(s_type=p[1], name=p[2], vector=None)
        p[0] = tmp.signal_2_port()
Ejemplo n.º 8
0
def p_signal_element(p):
    '''signal_element : IDENTIFIER BIT
                      | IDENTIFIER VECTOR
                      | IDENTIFIER
    '''
    if len(p)==3:
        p[0]=cc.signal(name=p[1],vector=p[2])
    else:
        # 匹配,使得连在一起的 ID-VEC:ID[\d+]等够将ID VEC分开
        linked_id_vec = re.match("(.+)(\[\d+\])$",p[1])
        if linked_id_vec is not None:
            iden = linked_id_vec.groups()[0]
            vec = linked_id_vec.groups()[1]
            p[0] = cc.signal( name = iden ,vector = vec)
        else:
            p[0]=cc.signal(name=p[1])
Ejemplo n.º 9
0
def p_signal_element(p):
    '''signal_element : IDENTIFIER BIT
                      | IDENTIFIER VECTOR
                      | IDENTIFIER
    '''
    if len(p) == 3:
        p[0] = cc.signal(name=p[1], vector=p[2])
    else:
        # 匹配,使得连在一起的 ID-VEC:ID[\d+]等够将ID VEC分开
        linked_id_vec = re.match("(.+)(\[\d+\])$", p[1])
        if linked_id_vec is not None:
            iden = linked_id_vec.groups()[0]
            vec = linked_id_vec.groups()[1]
            p[0] = cc.signal(name=iden, vector=vec)
        else:
            p[0] = cc.signal(name=p[1])
Ejemplo n.º 10
0
def p_assign_stm(p):
    ''' assign_stm      : ASSIGN signal_element '=' signal_element ';'
                        | ASSIGN signal_element '=' BIN_NUMBER ';'    
    '''
    if isinstance(p[4],cc.signal):
        p[0]=cc.assign("assign",p[2],p[4])
    else:
        p[0]=cc.assign("assign",p[2],cc.signal(name=p[4]))
Ejemplo n.º 11
0
def p_assign_stm(p):
    ''' assign_stm      : ASSIGN signal_element '=' signal_element ';'
                        | ASSIGN signal_element '=' BIN_NUMBER ';'    
    '''
    if isinstance(p[4], cc.signal):
        p[0] = cc.assign("assign", p[2], p[4])
    else:
        p[0] = cc.assign("assign", p[2], cc.signal(name=p[4]))
Ejemplo n.º 12
0
 def insert_wire(self, signal):
     '''@param: signal, 一个signal对象,
                 或者是一个可以转化为signal的字符串.空格分隔,长度为2个词,后一个是向量.或者单个词
        @return:如果成功插入则返回一个signal对象,如果失败,则返回None
     '''
     if isinstance(signal, cc.signal):
         s = signal
     elif isinstance(signal, str):
         ss = signal.split()
         if len(ss) == 2:
             assert re.match("\[\d+\]|\[\d+:\d+\]", ss[1])
             s = cc.signal(name = ss[0], vector = ss[1])
         else:
             s = cc.signal(name = ss[0])
     else:
         raise FormatError,"param type error: not a signal or a string."
     try:
         self.__insert_type('wires', s) 
     except RedeclarationError,e:
         # 已经插入过的线网,如果再次插入,直接保持原模原样不动就好了
         print e, "|| so no wire get changed."
         return None
Ejemplo n.º 13
0
 def insert_wire(self, signal):
     '''@param: signal, 一个signal对象,
                 或者是一个可以转化为signal的字符串.空格分隔,长度为2个词,后一个是向量.或者单个词
        @return:如果成功插入则返回一个signal对象,如果失败,则返回None
     '''
     if isinstance(signal, cc.signal):
         s = signal
     elif isinstance(signal, str):
         ss = signal.split()
         if len(ss) == 2:
             assert re.match("\[\d+\]|\[\d+:\d+\]", ss[1])
             s = cc.signal(name=ss[0], vector=ss[1])
         else:
             s = cc.signal(name=ss[0])
     else:
         raise FormatError, "param type error: not a signal or a string."
     try:
         self.__insert_type('wires', s)
     except RedeclarationError, e:
         # 已经插入过的线网,如果再次插入,直接保持原模原样不动就好了
         print e, "|| so no wire get changed."
         return None
Ejemplo n.º 14
0
def fusion_lut_with_or(lut):
    '''将LUT和 or门逻辑混合.功能是: O' = (In == 1'b1) ? 1'b1: O ;
    '''
    input_num = int(lut.cellref[3])
    scan_en = cc.port('I'+str(input_num),'input',cc.signal(name="scan_en"))
    lut.port_list.insert(-1,scan_en)
    assert (not lut.param_list==None)
    assert len(lut.param_list)==1
    old_init=lut.param_list[0].value
    init_legal=re.match('(\d+)\'[hb]([0-9A-F]+)',old_init)
    assert (init_legal is not None)
    assert int(init_legal.groups()[0])==2**input_num
    if input_num==1:
        NEW_INIT="4'hD"
    else:
        NEW_INIT=str(2**(input_num+1))+'\'h'+'F'*int(2**(input_num-2))\
                    +init_legal.groups()[1]
    lut.param_list[0].edit_param('INIT',NEW_INIT)
    lut.cellref = re.sub('LUT[1-5]', ('LUT' + str(input_num+1)), lut.cellref)
    return None
Ejemplo n.º 15
0
            replace_fd_with_scan_fd(eachPrimitive, counter)
            scan_out_list.append('scan_out' + str(counter))
            fd_replace_cnt+=1
        #CE时钟使能控制信号的优化. 改LUT,进行时钟使能的插入,就是插入一个或门
        elif(eachPrimitive.m_type=='LUT') and (eachPrimitive.name in lut_cnt2_ce):
            fusion_lut_with_or(eachPrimitive)

    #--------------------------------------------------------------------------
    # 未使用LUT混合来gate 的 ce信号名称应该修改, 和之后assign部分的相同
    #--------------------------------------------------------------------------
    for eachPrimitive in m_list[1:]:
        if (eachPrimitive.m_type=='FD') and (eachPrimitive.name in fd_has_ce_list):
            current_ce = all_fd_dict[eachPrimitive.name]['CE'].string 
            if current_ce in un_opt_ce_list:
                gatedCE = gate_ce( current_ce )
                new_ce_signal = cc.signal('wire', gatedCE)
                eachPrimitive.edit_spec_port('CE', new_ce_signal)
                #因为多个FD可能连接到相同的CE, signal_decl_list里面有重复的声明.
                if not gatedCE in gatedce_list:
                    gatedce_list.append(gatedCE)
                    signal_decl_list.append(new_ce_signal)

    #--------------------------------------------------------------------------
    #扫描链顺序的确定,在结尾处进行assign
    #--------------------------------------------------------------------------
    assign_stm_list.append( cc.assign('assign', cc.signal(name = "scan_in1"),
                                                cc.signal(name = "scan_in")) )
    for i in range(2,counter+1):
        tmp_assign = cc.assign('assign',cc.signal(name = "scan_in"+str(i) ),
                                        cc.signal( name = scan_out_list[i-2] )) 
        assign_stm_list.append( tmp_assign )