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()
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
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))
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)
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
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
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
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
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))