def handshake_signals(self) -> Iterator[Union[ast.Wire, ast.Reg]]: """All handshake signals used for this instance. Yields: Union[ast.Wire, ast.Reg] of signals. """ if self.is_autorun: yield ast.Reg(name=self.start.name, width=None) else: yield ast.Wire(name=self.start.name, width=None) yield ast.Reg(name=self.state.name, width=ast.make_width(2)) yield from (ast.Wire(name=rtl.wire_name(self.name, suffix), width=None) for suffix in rtl.HANDSHAKE_OUTPUT_PORTS)
def __init__(self, name: str, level: int, width: Optional[int] = None): self.level = level self._ids = tuple( ast.Identifier(f'{name}__q%d' % i) for i in range(level + 1)) self._width: Optional[ast.Width] = width and ast.make_width(width)
def _instantiate_global_fsm( self, task: Task, is_done_signals: List[rtl.Pipeline], ) -> None: # global state machine def is_state(state: ast.IntConst) -> ast.Eq: return ast.Eq(left=rtl.STATE, right=state) def set_state(state: ast.IntConst) -> ast.NonblockingSubstitution: return ast.NonblockingSubstitution(left=rtl.STATE, right=state) countdown = ast.Identifier('countdown') countdown_width = (self.register_level - 1).bit_length() task.module.add_signals([ ast.Reg(rtl.STATE.name, width=ast.make_width(2)), ast.Reg(countdown.name, width=ast.make_width(countdown_width)), ]) state01_action = set_state(STATE10) if is_done_signals: state01_action = ast.make_if_with_block( cond=ast.make_operation( operator=ast.Land, nodes=(x[-1] for x in reversed(is_done_signals)), ), true=state01_action, ) global_fsm = ast.make_case_with_block( comp=rtl.STATE, cases=[ ( STATE00, ast.make_if_with_block( cond=self.start_q[-1], true=set_state(STATE01), ), ), ( STATE01, state01_action, ), ( STATE10, [ set_state(STATE11 if self.register_level else STATE00), ast.NonblockingSubstitution( left=countdown, right=ast.make_int(max(0, self.register_level - 1)), ), ], ), ( STATE11, ast.make_if_with_block( cond=ast.Eq( left=countdown, right=ast.make_int(0, width=countdown_width), ), true=set_state(STATE00), false=ast.NonblockingSubstitution( left=countdown, right=ast.Minus( left=countdown, right=ast.make_int(1, width=countdown_width), ), ), ), ), ], ) task.module.add_logics([ ast.Always( sens_list=rtl.CLK_SENS_LIST, statement=ast.make_block( ast.make_if_with_block( cond=rtl.RST, true=set_state(STATE00), false=global_fsm, )), ), ast.Assign(left=rtl.IDLE, right=is_state(STATE00)), ast.Assign(left=rtl.DONE, right=self.done_q[-1]), ast.Assign(left=rtl.READY, right=self.done_q[0]), ]) task.module.add_pipeline(self.start_q, init=rtl.START) task.module.add_pipeline(self.done_q, init=is_state(STATE10))