Beispiel #1
0
 def __init__(self,**kwargs):
     VStruct.__init__(self,**kwargs)
     for entry in self.entries:
         csr = Wire(entry.bit_width,io='output' if entry.export else None)
         setattr(self,entry.name,csr)
         for start,end,width in entry.area_reserved:
             csr[start:end] = 0
         for start,end,width in entry.area_ignore:
             csr[start:end] = 0
         
         extend_start = 0                    
         if entry.mask_extend:
             start,end,width = entry.area_extend[0]
             if (entry.mask_extend>>1)&(entry.mask_reserved|entry.mask_ignore):
                 csr[start:end] = 0
             if start==0:csr[start:end] = 0
             extend_start = start
         for name,field in entry.bitfields.items():
             if field.rw=='r':
                 f = Reg (field.width,io='output' if field.export else None)
             elif field.rw=='rr':
                 f = Wire(field.width,io='output' if field.export else None)
             elif field.rw=='rc':
                 f = Wire(field.width,io='output' if field.export else None)
                 if field.value is None:raise ValueError('Marked as constant but not valued.')
                 else:f[:] = field.value
             elif field.rw=='rw':
                 f = Reg(field.width)
             f.field = field
             setattr(csr,name,f)
             csr[field.start:field.end] = f
             f.csr = csr
             if field.end == extend_start:csr[extend_start:] = f[-1]**(entry.bit_width-extend_start)
     self.lock = self.init_lock()
Beispiel #2
0
 def read_with(self,raddr,io=None):
     rdata = Wire(self.entries[0].bit_width,io=io)
     rdata.hit = VStruct()
     r = 0
     for entry in self.entries:
         hitcsr = Wire(raddr.equal_to(entry.id))
         setattr(rdata.hit,entry.name,hitcsr)
         r|=getattr(self,entry.name).validif(hitcsr)
     rdata[:] = r
     return rdata
Beispiel #3
0
 def decode_rtl(self,inst,op,pivots=None,corners=None,prepares=None,judgers=None,subset=None,remove_unused=True):
     subdec = {}
     inst.segs = []
     if not corners is None:
         inst.enable_ssa('corseg')
         for l,r in corners:
             inst.corseg = decode_raw(self,inst,l,r,subdec,remove_unused=remove_unused)
             inst.segs.append('decode inst[%d:%d] -> %s'%(r-1,l,str(inst.corseg)))
     if not pivots is None:
         w = len(inst)
         for i in range(1,len(pivots)):
             if pivots[i][-1] != pivots[0][-1]:pivots[i].append(pivots[0][-1])
             if pivots[i][ 0] != pivots[0][ 0]:pivots[i].insert(0,pivots[0][ 0])
         inst.enable_ssa('lv')
         inst.lv = VStruct()
         inst.lv.enable_ssa('seg')
         for i in range(len(pivots[0])-1):
             l = pivots[0][i]
             r = pivots[0][i+1]
             inst.lv.seg = decode_raw(self,inst,l,r,subdec,remove_unused=remove_unused)
             inst.segs.append('decode inst[%d:%d] -> %s'%(r-1,l,str(inst.lv.seg)))
         for i in range(1,len(pivots)):
             inst.lv = VStruct()
             inst.lv.enable_ssa('seg')
             u = 0
             for j in range(len(pivots[i])-1):
                 l = pivots[i][j]
                 r = pivots[i][j+1]
                 v = pivots[i-1].index(pivots[i][j+1])
                 inst.lv.seg = decode_buf(self,inst,l,r,subdec,u,v,pivots[i-1],remove_unused=remove_unused)
                 inst.segs.append('decode inst[%d:%d] -> %s'%(r-1,l,str(inst.lv.seg)))
                 u = v
     if not prepares is None:
         for name,expr in prepares.items():
             setattr(inst,name,Wire(expr(inst))) 
     masks = sorted([mask for mask in subdec],reverse=True)
     for entry in self.entries:
         if not subset is None and not subset(entry):continue
         expr = 1
         decoded = 0
         for mask in masks:
             if (mask&entry.mask)!=mask or (mask&decoded)!=0:continue
             l,r,dec = subdec[mask]
             expr&= dec[(entry.code&mask)>>l]
             decoded|=mask
         i = get_block(entry.mask,decoded,-1,1)
         while i < 32:
             j = get_block(entry.mask,decoded,i,0)
             expr&= inst[i:j]//((entry.code&get_mask(j,i))>>i)
             i = get_block(entry.mask,decoded,j,1)
         if not judgers is None:
             if entry.judge!='':expr &= judgers[entry.judge](inst)
         setattr(op,entry.name,Wire(expr))
Beispiel #4
0
 def write_with(self,reset,we,waddr,wdata,*args,**kwargs):
     self.reset = reset
     for entry in self.entries:
         csr = getattr(self,entry.name)
         if not hasattr(entry,'readonly') or not entry.readonly:
             mywe = we&waddr.equal_to(entry.id)
             if hasattr(entry,'lock'):
                 if isinstance(entry.lock,str):
                     if entry.lock!='':mywe&=getattr(self.lock,entry.lock)
                 elif isinstance(entry.lock,bool):
                     if entry.lock:mywe&=self.lock
                 else:raise TypeError(entry.lock)
             csr.write = Wire(mywe)
         csr.wdata = wdata
     for entry in self.entries:
         csr = getattr(self,entry.name)
         for name,field in entry.bitfields.items():
             f = getattr(csr,name)
             if field.rw == 'rc':
                 continue
             custom_method = 'write_csr_%s_%s'%(entry.name,name)
             if field.rw == 'rr':
                 getattr(self,custom_method)(f,wdata[field.start:field.end],*args,**kwargs)
                 continue
             blk = ctrlblk
             if not field.value is None:
                 blk = blk.When(reset)[f:field.value]
             if field.rw == 'rw':
                 blk = blk.When(csr.write)[f:wdata[field.start:field.end]]
             f.blk = blk
             if hasattr(self,custom_method):
                 getattr(self,custom_method)(f,wdata[field.start:field.end],*args,**kwargs)
Beispiel #5
0
def decode_raw_remove_unused(doc,seg,l,r):
    mask = get_mask(r,l)
    using = set()
    for entry in doc.entries:
        if (mask & entry.mask) == mask:using.add(entry.code&mask)
    seg.dec = {}
    using = sorted([code>>l for code in using])
    for code in using:
        decx = Wire(seg.equal_to(code))
        setattr(seg,'dec%d'%code,decx)
        seg.dec[code] = decx
Beispiel #6
0
def decode_buf_remove_unused(doc,seg,l,r,u,v,subdec,pivots):
    mask = get_mask(r,l)
    using = set()
    for entry in doc.entries:
        if (mask & entry.mask) == mask:using.add(entry.code&mask)
    using = set(code>>l for code in using)
    dec1 = {0:1}
    for x in range(u,v):
        next = {}
        dec2 = subdec[get_mask(pivots[x+1],pivots[x])][2]
        shift = pivots[x] - l
        for code2 in dec2:
            for code1 in dec1:
                next[(code2<<shift)|code1] = dec1[code1] & dec2[code2]
        dec1 = next
    dec = dec1
    for code in dec:
        if code not in using:continue
        decx = Wire(dec[code])
        setattr(seg,'dec%d'%code,decx)
        dec[code] = decx
    seg.dec = dec
Beispiel #7
0
def decode_buf_keep_unused(doc,seg,l,r,u,v,subdec,pivots):
    dec = Wire(1<<(r-l))
    for p in range(len(dec)):
        dec[p] = reduce(lambda x,y:x&y,(subcode(subdec,pivots,p<<l,x) for x in range(u,v)),1)
    seg.dec = dec
Beispiel #8
0
def decode_raw(doc,inst,l,r,subdec,remove_unused=True):
    seg = Wire(inst[l:r])
    (decode_raw_remove_unused if remove_unused else decode_raw_keep_unused)(doc,seg,l,r)
    subdec[get_mask(r,l)]=(l,r,seg.dec)
    return seg
Beispiel #9
0
 def __init__(self,width=None,io=None,**kwargs):
     VStruct.__init__(self,**kwargs)
     for myname in self.mynames:
         setattr(self,myname,Wire(width=1,io=io))