def Elif(self, *cond): if len(self.last_cond) == 0: raise ValueError("No previous condition for Else.") cond = make_condition(*cond) old = self.last_cond.pop() self.last_cond.append(vtypes.Not(old)) self.last_cond.append(cond) # if the true-statement has delay attributes, Else statement is # separated. if 'delay' in self.last_kwargs and self.last_kwargs['delay'] > 0: prev_cond = self.last_cond ret = self.Then() self.last_cond = prev_cond return ret if not isinstance(self.last_if_statement, vtypes.If): raise ValueError("Last if-statement is not If") self.elif_cond = cond cond = self._make_cond(self.last_cond) self.next_kwargs['cond'] = cond return self
def done(self, fsm): done = None for flag in self.done_flags: done = make_condition(done, flag) return done
def join(self, fsm): done = None for flag in self.done_flags: done = make_condition(done, flag) fsm.If(done).goto_next() return 0
def _add_statement(self, statement, index=None, keep=None, delay=None, cond=None, lazy_cond=False, eager_val=False, no_delay_cond=False): cond = make_condition(cond) index = self._to_index(index) if index is not None else self.current if keep is not None: for i in range(keep): new_delay = i if delay is None else delay + i self._add_statement(statement, index=index, keep=None, delay=new_delay, cond=cond, lazy_cond=lazy_cond, eager_val=eager_val, no_delay_cond=no_delay_cond) return self if delay is not None and delay > 0: self._add_delayed_state(delay) if eager_val: statement = [self._add_delayed_subst(s, index, delay) for s in statement] if not no_delay_cond: if cond is None: cond = 1 if not lazy_cond: cond = self._add_delayed_cond(cond, index, delay) else: # lazy condition t = self._add_delayed_cond(1, index, delay) if isinstance(cond, int) and cond == 1: cond = t else: cond = vtypes.Ands(t, cond) statement = [vtypes.If(cond)(*statement)] self.delayed_body[delay][index].extend(statement) self._add_dst_var(statement) return self if cond is not None: statement = [vtypes.If(cond)(*statement)] self.last_if_statement = statement[0] self.body[index].extend(statement) self._add_dst_var(statement) return self
def If(self, *cond): self._clear_elif_cond() cond = make_condition(*cond) if cond is None: return self if 'cond' not in self.next_kwargs: self.next_kwargs['cond'] = cond else: self.next_kwargs['cond'] = vtypes.Ands(self.next_kwargs['cond'], cond) self.last_cond = [self.next_kwargs['cond']] return self
def If(self, *cond): self._clear_elif_cond() cond = make_condition(*cond) if cond is None: return self if 'cond' not in self.next_kwargs: self.next_kwargs['cond'] = cond else: self.next_kwargs['cond'] = vtypes.Ands( self.next_kwargs['cond'], cond) self.last_cond = [self.next_kwargs['cond']] return self
def deq_rtl(self, cond=None): """ Deque """ if self._deq_disabled: raise TypeError('Deq disabled.') cond = make_condition(cond) ready = vtypes.Not(self.rif.empty) if cond is not None: deq_cond = vtypes.Ands(cond, ready) else: deq_cond = ready util.add_enable_cond(self.rif.deq, deq_cond, 1) data = self.rif.rdata valid = self.seq.Prev(deq_cond, 1) return data, valid, ready
def enq_rtl(self, wdata, cond=None): """ Enque """ if self._enq_disabled: raise TypeError('Enq disabled.') cond = make_condition(cond) ready = vtypes.Not(self.wif.almost_full) if cond is not None: enq_cond = vtypes.Ands(cond, ready) enable = cond else: enq_cond = ready enable = vtypes.Int(1, 1) util.add_mux(self.wif.wdata, enable, wdata) util.add_enable_cond(self.wif.enq, enable, enq_cond) ack = self.seq.Prev(ready, 1) return ack, ready
def _synthesize_set_sink_pattern(self, var, name): if var.sink_pat_fsm is not None: return sink_start = vtypes.Ands(self.start, var.sink_mode == 1) for sink_pat_size in var.sink_pat_sizes: sink_start = vtypes.Ands(sink_start, sink_pat_size > 0) fsm_id = self.fsm_id_count self.fsm_id_count += 1 prefix = self._prefix(name) fsm_name = '_%s_sink_pat_fsm_%d' % (prefix, fsm_id) var.sink_pat_fsm = FSM(self.module, fsm_name, self.clock, self.reset, as_module=self.fsm_as_module) self.seq.If(var.sink_pat_fsm.here)( var.sink_ram_wenable(0) ) var.sink_pat_fsm.If(sink_start).goto_next() self.seq.If(var.sink_pat_fsm.here)( var.sink_ram_waddr(var.sink_offset - var.sink_stride) ) for sink_pat_offset in var.sink_pat_offsets: self.seq.If(var.sink_pat_fsm.here)( sink_pat_offset(0) ) for (sink_pat_size, sink_pat_count) in zip( var.sink_pat_sizes, var.sink_pat_counts): self.seq.If(var.sink_pat_fsm.here)( sink_pat_count(sink_pat_size - 1) ) num_wdelay = self._write_delay() for _ in range(num_wdelay): var.sink_pat_fsm.goto_next() if name in self.sink_when_map: when = self.sink_when_map[name] wcond = when.read() else: wcond = None sink_all_offset = self.module.Wire('_%s_sink_pat_all_offset' % prefix, self.addrwidth) sink_all_offset_val = var.sink_offset for sink_pat_offset in var.sink_pat_offsets: sink_all_offset_val += sink_pat_offset sink_all_offset.assign(sink_all_offset_val) if name in self.sink_when_map: when = self.sink_when_map[name] wcond = when.read() else: wcond = None rdata = var.read() self.seq.If(var.sink_pat_fsm.here)( var.sink_ram_wenable(0) ) self.seq.If(var.sink_pat_fsm.here, wcond)( var.sink_ram_waddr(sink_all_offset), var.sink_ram_wdata(rdata), var.sink_ram_wenable(1) ) upcond = None for (sink_pat_offset, sink_pat_size, sink_pat_stride, sink_pat_count) in zip( var.sink_pat_offsets, var.sink_pat_sizes, var.sink_pat_strides, var.sink_pat_counts): self.seq.If(var.sink_pat_fsm.here, upcond)( sink_pat_offset.add(sink_pat_stride), sink_pat_count.dec() ) reset_cond = sink_pat_count == 0 self.seq.If(var.sink_pat_fsm.here, upcond, reset_cond)( sink_pat_offset(0), sink_pat_count(sink_pat_size - 1) ) upcond = make_condition(upcond, reset_cond) fin_cond = upcond var.sink_pat_fsm.If(fin_cond).goto_init()
def _synthesize_set_source_pattern(self, var, name): if var.source_pat_fsm is not None: return wdata = var.source_ram_rdata wenable = var.source_ram_rvalid var.write(wdata, wenable) source_start = vtypes.Ands(self.start, var.source_mode == 1) for source_pat_size in var.source_pat_sizes: source_start = vtypes.Ands(source_start, source_pat_size > 0) self.seq.If(source_start)( var.source_idle(0) ) for source_pat_offset in var.source_pat_offsets: self.seq.If(source_start)( source_pat_offset(0) ) for (source_pat_size, source_pat_count) in zip( var.source_pat_sizes, var.source_pat_counts): self.seq.If(source_start)( source_pat_count(source_pat_size - 1) ) fsm_id = self.fsm_id_count self.fsm_id_count += 1 prefix = self._prefix(name) fsm_name = '_%s_source_pat_fsm_%d' % (prefix, fsm_id) var.source_pat_fsm = FSM(self.module, fsm_name, self.clock, self.reset, as_module=self.fsm_as_module) var.source_pat_fsm.If(source_start).goto_next() source_all_offset = self.module.Wire('_%s_source_pat_all_offset' % prefix, self.addrwidth) source_all_offset_val = var.source_offset for source_pat_offset in var.source_pat_offsets: source_all_offset_val += source_pat_offset source_all_offset.assign(source_all_offset_val) self.seq.If(var.source_pat_fsm.here)( var.source_ram_raddr(source_all_offset), var.source_ram_renable(1) ) upcond = None for (source_pat_offset, source_pat_size, source_pat_stride, source_pat_count) in zip( var.source_pat_offsets, var.source_pat_sizes, var.source_pat_strides, var.source_pat_counts): self.seq.If(var.source_pat_fsm.here, upcond)( source_pat_offset.add(source_pat_stride), source_pat_count.dec() ) reset_cond = source_pat_count == 0 self.seq.If(var.source_pat_fsm.here, upcond, reset_cond)( source_pat_offset(0), source_pat_count(source_pat_size - 1) ) upcond = make_condition(upcond, reset_cond) fin_cond = upcond var.source_pat_fsm.If(fin_cond).goto_next() self.seq.If(var.source_pat_fsm.here)( var.source_ram_renable(0), var.source_idle(1) ) var.source_pat_fsm.goto_init()
def run(self, fsm): # entry point self.fsm._set_index(0) #cond = fsm.here cond = self._set_flag(fsm) add_mux(self.start_flag, cond, 1) # after started if self.fsm_synthesized: fsm.goto_next() fsm.goto_next() return self.fsm_synthesized = True num_wdelay = self._write_delay() self.fsm.If(self.start_flag)( self.start(1), self.busy(1) ) if self.reduce_reset is not None: self.fsm.seq.If(self.seq.Prev(self.start_flag, self.ram_delay + 1))( self.reduce_reset(0) ) substreams = self._collect_substreams() for sub in substreams: reset_delay = self.ram_delay + 1 + sub.start_stage + sub.reset_delay sub_fsm = sub.substrm.fsm sub_fsm._set_index(0) if sub.substrm.reduce_reset is not None: sub_fsm.seq.If(self.seq.Prev(self.start_flag, reset_delay))( sub.substrm.reduce_reset(0) ) for cond in sub.conds.values(): sub_fsm.If(self.start_flag)( cond(1) ) self.fsm.If(self.start_flag).goto_next() self.fsm( self.start(0) ) self.fsm.goto_next() done_cond = None for key, source_idle in sorted(self.source_idle_map.items(), key=lambda x: x[0]): done_cond = make_condition(done_cond, source_idle) done = self.module.Wire('_%s_done' % self.name) done.assign(done_cond) self.fsm.If(done).goto_next() depth = self.pipeline_depth() for _ in range(depth): self.fsm.goto_next() self.fsm.goto_next() # reset accumulate pipelines if self.reduce_reset is not None: self.fsm( self.reduce_reset(1) ) end_flag = self.fsm.here for sub in substreams: sub_fsm = sub.substrm.fsm sub_fsm._set_index(0) if sub.substrm.reduce_reset is not None: sub_fsm.If(end_flag)( sub.substrm.reduce_reset(1) ) for cond in sub.conds.values(): sub_fsm.If(end_flag)( cond(0) ) self.fsm.goto_next() self.fsm( self.busy(0) ) self.fsm.goto_init() fsm.goto_next() fsm.goto_next() return 0
def run(self, fsm): # entry point self.fsm._set_index(0) start_flag = (fsm.state == fsm.current) self.fsm.If(start_flag)( self.start(1), self.busy(1) ) self.fsm.If(start_flag).Delay(1)( self.start(0) ) if self.reduce_reset is not None: self.fsm.If(start_flag).Delay(self.ram_delay + 1)( self.reduce_reset(0) ) substreams = self._collect_substreams() for sub in substreams: reset_delay = self.ram_delay + 1 + sub.start_stage if sub.substrm.reduce_reset is not None: self.fsm.If(start_flag).Delay(reset_delay)( sub.substrm.reduce_reset(0) ) for cond in sub.conds.values(): self.fsm.If(start_flag)( cond(1) ) self.fsm.If(start_flag).goto_next() # after started if self.fsm_synthesized: fsm.goto_next() return self.fsm_synthesized = True self.fsm.goto_next() done_cond = None for key, source_idle in sorted(self.source_idle_map.items(), key=lambda x: x[0]): done_cond = make_condition(done_cond, source_idle) done = self.module.Wire('_%s_done' % self.name) done.assign(done_cond) self.fsm.If(done).goto_next() depth = self.pipeline_depth() num_wdelay = self._write_delay() # pipeline delay for i in range(depth): self.fsm.goto_next() self.fsm.goto_next() # reset accumulate pipelines if self.reduce_reset is not None: self.fsm( self.reduce_reset(1) ) for sub in substreams: reset_delay = sub.start_stage if sub.substrm.reduce_reset is not None: self.fsm( sub.substrm.reduce_reset(1) ) for cond in sub.conds.values(): self.fsm( cond(0) ) for i in range(num_wdelay - depth - 1): self.fsm.goto_next() # finish self.fsm( self.busy(0) ) self.fsm.goto_init() fsm.goto_next() return 0
def set_sink_pattern(self, fsm, name, ram, offset, pattern, port=0): """ intrinsic method to assign RAM property to a sink stream """ if not self.stream_synthesized: self._implement_stream() if isinstance(name, str): var = self.var_name_map[name] elif isinstance(name, vtypes.Str): name = name.value var = self.var_name_map[name] elif isinstance(name, int): var = self.var_id_map[name] elif isinstance(name, vtypes.Int): name = name.value var = self.var_id_map[name] else: raise TypeError('Unsupported index name') if name not in self.sinks: raise NameError("No such stream '%s'" % name) if not isinstance(pattern, (tuple, list)): raise TypeError('pattern must be list or tuple.') if not pattern: raise ValueError( 'pattern must have one (size, stride) pair at least.') if not isinstance(pattern[0], (tuple, list)): pattern = (pattern,) prefix = self._prefix(name) fsm_id = self.fsm_id_count fsm_name = '_%s_fsm_%d' % (prefix, fsm_id) sink_fsm = FSM(self.module, fsm_name, self.clock, self.reset) self.fsm_id_map[fsm_id] = sink_fsm self.fsm_id_count += 1 sink_offset = self.module.Reg('_%s_offset_%d' % (prefix, fsm_id), ram.addrwidth, initval=0) sink_pat_offsets = [self.module.Reg('_%s_pat_offset_%d_%d' % (prefix, fsm_id, i), ram.addrwidth, initval=0) for i, _ in enumerate(pattern)] sink_pat_sizes = [self.module.Reg('_%s_pat_size_%d_%d' % (prefix, fsm_id, i), ram.addrwidth + 1, initval=0) for i, _ in enumerate(pattern)] sink_pat_strides = [self.module.Reg('_%s_pat_stride_%d_%d' % (prefix, fsm_id, i), ram.addrwidth, initval=0) for i, _ in enumerate(pattern)] sink_pat_counts = [self.module.Reg('_%s_pat_count_%d_%d' % (prefix, fsm_id, i), ram.addrwidth + 1, initval=0) for i, _ in enumerate(pattern)] var_id = self.var_name_id_map[name] fsm_sel = self.var_id_fsm_sel_map[var_id] set_cond = (fsm.state == fsm.current) sink_fsm.If(set_cond)( sink_offset(offset) ) self.seq.If(set_cond)( fsm_sel(fsm_id) ) for sink_pat_offset in sink_pat_offsets: sink_fsm.If(set_cond)( sink_pat_offset(0) ) for (sink_pat_size, sink_pat_stride, (size, stride)) in zip( sink_pat_sizes, sink_pat_strides, pattern): sink_fsm.If(set_cond)( sink_pat_size(size), sink_pat_stride(stride) ) sink_start = vtypes.Ands(self.start, fsm_sel == fsm_id) for sink_pat_size in sink_pat_sizes: sink_start = vtypes.Ands(sink_start, sink_pat_size > 0) for (sink_pat_size, sink_pat_count) in zip( sink_pat_sizes, sink_pat_counts): sink_fsm.If(sink_start)( sink_pat_count(sink_pat_size - 1) ) sink_fsm.If(sink_start).goto_next() num_wdelay = self._write_delay() for i in range(num_wdelay): sink_fsm.goto_next() sink_all_offset = self.module.Wire('_%s_all_offset_%d' % (prefix, fsm_id), ram.addrwidth) sink_all_offset_val = sink_offset for sink_pat_offset in sink_pat_offsets: sink_all_offset_val += sink_pat_offset sink_all_offset.assign(sink_all_offset_val) waddr = self.module.Reg('_%s_waddr_%d' % (prefix, fsm_id), ram.addrwidth, initval=0) wenable = self.module.Reg('_%s_wenable_%d' % (prefix, fsm_id), initval=0) wdata = self.module.Reg('_%s_wdata_%d' % (prefix, fsm_id), ram.datawidth, initval=0, signed=True) rdata = var.read() ram.write_rtl(waddr, wdata, port=port, cond=wenable) if name in self.sink_when_map: when = self.sink_when_map[name] wcond = when.read() else: wcond = None sink_fsm.If(wcond)( waddr(sink_all_offset), wdata(rdata), wenable(1) ) sink_fsm.Delay(1)( wenable(0) ) upcond = None for (sink_pat_offset, sink_pat_size, sink_pat_stride, sink_pat_count) in zip( sink_pat_offsets, sink_pat_sizes, sink_pat_strides, sink_pat_counts): sink_fsm.If(upcond)( sink_pat_offset.add(sink_pat_stride), sink_pat_count.dec() ) reset_cond = sink_pat_count == 0 sink_fsm.If(upcond, reset_cond)( sink_pat_offset(0), sink_pat_count(sink_pat_size - 1) ) upcond = make_condition(upcond, reset_cond) fin_cond = upcond sink_fsm.If(fin_cond).goto_init() sink_fsm._set_index(0) fsm.goto_next()