def _setup_register_lite_fsm(self): fsm = FSM(self.m, '_'.join(['', self.name, 'register_fsm']), self.clk, self.rst) # request addr, readvalid, writevalid = self.pull_request(cond=fsm) maskaddr = self.m.TmpReg(self.maskwidth) fsm.If(vtypes.Ors(readvalid, writevalid))(maskaddr((addr >> self.shift) & self.mask), ) init_state = fsm.current # read read_state = fsm.current + 1 fsm.If(readvalid).goto_from(init_state, read_state) fsm.set_index(read_state) rdata = self.m.TmpWire(self.datawidth) pat = [(maskaddr == i, r) for i, r in enumerate(self.register)] pat.append((None, vtypes.IntX())) rval = vtypes.PatternMux(pat) rdata.assign(rval) flag = self.m.TmpWire() pat = [(maskaddr == i, r) for i, r in enumerate(self.flag)] pat.append((None, vtypes.IntX())) rval = vtypes.PatternMux(pat) flag.assign(rval) resetval = self.m.TmpWire(self.datawidth) pat = [(maskaddr == i, r) for i, r in enumerate(self.resetval)] pat.append((None, vtypes.IntX())) rval = vtypes.PatternMux(pat) resetval.assign(rval) ack = self.push_read_data(rdata, cond=fsm) # flag reset state_cond = fsm.state == fsm.current for i, r in enumerate(self.register): self.seq.If(state_cond, ack, flag, maskaddr == i)(self.register[i](resetval), self.flag[i](0)) fsm.If(ack).goto_init() # write write_state = fsm.current + 1 fsm.If(writevalid).goto_from(init_state, write_state) fsm.set_index(write_state) data, mask, valid = self.pull_write_data(cond=fsm) state_cond = fsm.state == fsm.current for i, r in enumerate(self.register): self.seq.If(state_cond, valid, maskaddr == i)(self.register[i](data)) fsm.goto_init()
def _for_list(self, node): target = self.visit(node.target) iterobj = self.visit(node.iter) begin_node = vtypes.Int(0) end_node = vtypes.Int(len(iterobj)) step_node = vtypes.Int(1) iter_node = self.getTmpVariable() cond_node = vtypes.LessThan(iter_node, end_node) update_node = vtypes.Plus(iter_node, step_node) node_body = node.body patterns = [] for i, obj in enumerate(iterobj): if not isinstance(obj, vtypes.numerical_types): raise TypeError("unsupported type for for-statement") patterns.append((iter_node == i, obj)) patterns.append((None, vtypes.IntX())) target_update = (target, vtypes.PatternMux(*patterns)) return self._for_range_fsm(begin_node, end_node, step_node, iter_node, cond_node, update_node, node_body, target_update)
def add_mux(targ, cond, value): prev_assign = targ._get_assign() if not prev_assign: targ.assign(vtypes.Mux(cond, value, vtypes.IntX())) else: prev_value = prev_assign.statement.right prev_assign.overwrite_right(vtypes.Mux(cond, value, prev_value)) targ.module.remove(prev_assign) targ.module.append(prev_assign)
def visit_Cat(self, node): left = [] right = [] for v in node.vars: val = self.visit(v) right = vtypes.IntX() if val is None else val.right left.append(v) right.append(right) return vtypes.Subst(vtypes.Cat(tuple(left)), vtypes.Cat(tuple(right)))
def read(self, fsm, addr): if isinstance(addr, int): rval = self.register[addr] elif isinstance(addr, vtypes.Int): rval = self.register[addr.value] else: pat = [(addr == i, r) for i, r in enumerate(self.register)] pat.append((None, vtypes.IntX())) rval = vtypes.PatternMux(pat) return rval
def ret(self, fsm, tid): """ return value """ patterns = [] for thread in self.threads: if thread.end_state is None: raise ValueError('thread %d not started' % thread.tid) patterns.append(((tid == thread.tid), thread.return_value)) patterns.append((None, vtypes.IntX())) ret = vtypes.PatternMux(*patterns) return ret
def done(self, fsm, tid): """ check whethe the thread is running """ patterns = [] for thread in self.threads: if thread.end_state is None: raise ValueError('thread %d not started' % thread.tid) end_flag = (thread.fsm.state == thread.end_state) patterns.append(((tid == thread.tid), end_flag)) patterns.append((None, vtypes.IntX())) cond = vtypes.PatternMux(*patterns) return cond
def join(self, fsm, tid): """ wait for the completion """ patterns = [] for thread in self.threads: if thread.end_state is None: raise ValueError('thread %d not started' % thread.tid) end_flag = (thread.fsm.state == thread.end_state) patterns.append(((tid == thread.tid), end_flag)) patterns.append((None, vtypes.IntX())) cond = vtypes.PatternMux(*patterns) fsm.If(cond).goto_next() return 0
def wait(self, fsm, addr, value, polarity=True): if isinstance(addr, int): rval = self.register[addr] elif isinstance(addr, vtypes.Int): rval = self.register[addr.value] else: pat = [(addr == i, r) for i, r in enumerate(self.register)] pat.append((None, vtypes.IntX())) rval = vtypes.PatternMux(pat) if polarity: wait_cond = (rval == value) else: wait_cond = (rval != value) fsm.If(wait_cond).goto_next()
def makeASTTree(node): if isinstance(node, DFBranch): return Cond(makeASTTree(node.condnode), makeASTTree(node.truenode), makeASTTree(node.falsenode)) if isinstance(node, DFIntConst): return vtypes.Int(int(node.value)) if isinstance(node, DFFloatConst): return vtypes.Float(float(node.value)) if isinstance(node, DFStringConst): return vtypes.Str(node.value) if isinstance(node, DFEvalValue): if isinstance(node.value, int): return vtypes.Int(node.value) if isinstance(node.value, float): return vtypes.Float(node.value) if isinstance(node.value, DFStringConst): return vtypes.Str(node.value) raise TypeError('Unknown constant') if isinstance(node, DFTerminal): return node.original if isinstance(node, DFUndefined): return vtypes.IntX() if isinstance(node, DFHighImpedance): return vtypes.IntZ() if isinstance(node, DFOperator): if len(node.nextnodes) == 1: return getOp(node.operator)(makeASTTree(node.nextnodes[0])) return getOp(node.operator)(makeASTTree(node.nextnodes[0]), makeASTTree(node.nextnodes[1])) if isinstance(node, DFSyscall): return vtypes.SystemTask( node.syscall, tuple([makeASTTree(n) for n in node.nextnodes])) raise TypeError("Unsupported DFNode %s" % type(node))
def wait_flag(self, fsm, addr, value, resetvalue=0, polarity=True): if isinstance(addr, int): rval = self.register[addr] elif isinstance(addr, vtypes.Int): rval = self.register[addr.value] else: pat = [(addr == i, r) for i, r in enumerate(self.register)] pat.append((None, vtypes.IntX())) rval = vtypes.PatternMux(pat) if polarity: wait_cond = (rval == value) else: wait_cond = (rval != value) state_cond = fsm.state == fsm.current # flag reset for i, r in enumerate(self.register): self.seq.If(wait_cond, state_cond, addr == i)(self.register[i](resetvalue)) fsm.If(wait_cond).goto_next()
def visit_Cat(self, node): left_values = [] right_values = [] for v in node.vars: val = self.visit(v) width = v.bit_length() if width is None: width = 1 if val is None: right = vtypes.IntX(width) elif isinstance(val.right, int): right = vtypes.Int(val.right, width) elif isinstance(val.right, vtypes._Constant): right = copy.deepcopy(val.right) right.width = width else: right = v._get_module().TmpLocalparam(val.right, width) left_values.append(v) right_values.append(right) return vtypes.Subst(vtypes.Cat(*left_values), vtypes.Cat(*right_values))