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 log2(value, maxsize=32): if isinstance(value, (int, bool, float)): return int(math.ceil(math.log(value, 2))) patterns = [] for i in range(1, maxsize): patterns.append((value < 2**i, i)) return vtypes.PatternMux(patterns)
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 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()