Utilizando a metodologia RTL, projete um sistema que funciona da seguinte maneira:
Após o término do processamento anterior, o sistema deve permitir que o processo seja reiniciado a qualquer momento através da entrada assíncrona rst, que reinicializa a operação do sistema ao seu estado inicial.
Após o término do processamento anterior, o sistema deve permitir que o processo seja reiniciado a qualquer momento através da entrada assíncrona rst, que reinicializa a operação do sistema ao seu estado inicial.
Passo 1
Beleza! O que a questão pede é: “Usando RTL (Register-Transfer Level), projete um sistema sequencial que, depois de terminar um processamento, pode ser reiniciado a qualquer hora por uma entrada assíncrona
Conteúdo: máquinas de estado finito (FSM) e reset assíncrono em lógica sequencial.
O que vamos precisar:
rst
, que leva o sistema de volta ao estado inicial.”Conteúdo: máquinas de estado finito (FSM) e reset assíncrono em lógica sequencial.
O que vamos precisar:
- Definir estados (por exemplo IDLE, RUN, DONE)
- Um registrador de estado com reset assíncrono
- Lógica de transição de estados em um bloco
always @(posedge clk or posedge rst)
Passo 2
Antes de codar, vamos entender a teoria:
- FSM (Finite State Machine) tem um conjunto finito de estados.
- Em cada borda de clock, o registrador de estado carrega o próximo estado, a menos que ocorra reset.
- Reset assíncrono significa que, ao ativar
rst
(nível alto), o circuito imediatamente (independente do clock) vai pro estado inicial.
Passo 3
Definindo estados e portas do módulo. Em Verilog (RTL) a gente normalmente faz assim:
module fsm_reinicia_async (
input wire clk,
input wire rst, // reset assíncrono, ativo em 1
input wire start, // sinal que inicia o processamento
output reg done // indica fim do processamento
);
// codificação dos estados em 2 bits
localparam IDLE = 2'b00,
RUN = 2'b01,
DONE = 2'b10;
reg [1:0] state, next_state;
Passo 4
Agora, a parte sequencial com reset assíncrono:
// always sensível ao clock e ao rst
always @(posedge clk or posedge rst) begin
if (rst) begin
state <= IDLE; // quando rst=1, volta pro IDLE imediatamente
end else begin
state <= next_state; // senão, carrega o próximo estado na borda de subida do clk
end
end
Explicação:
posedge rst
garante que, assim querst
sobe, o estado vai direto praIDLE
(sem esperar o clock).- Se
rst
estiver 0, a transição normal acontece na borda de clock.
Passo 5
Agora, descrevemos a lógica combinacional que gera
next_state
e done
: always @(*) begin
// defaults
next_state = state;
done = 1'b0;
case (state)
IDLE: begin
if (start) next_state = RUN;
end
RUN: begin
// aqui você coloca a lógica do seu processamento
// vamos supor que o processo acaba quando alguma condição `proc_done` vira 1
if (proc_done) next_state = DONE;
else next_state = RUN;
end
DONE: begin
done = 1'b1; // sinaliza fim do processamento
// o próprio rst que reinicia, mas se quiser recomeçar sem rst:
// if (!start) next_state = IDLE;
end
default: next_state = IDLE;
endcase
end
endmodule
Comentário da teoria aplicada:
- Bloco
always @(*)
faz a “função de próxima estado” e sinais de saída (done
). - Usamos
case
pra clareza, cada estado gera seu próprionext_state
. - Quando
rst=1
em qualquer momento, o bloco sequencial zera o estado paraIDLE
.
Resposta
Segue o módulo RTL completo que atende ao enunciado:
module fsm_reinicia_async (
input wire clk,
input wire rst, // reset assíncrono, ativo em 1
input wire start, // sinal que inicia o processamento
output reg done // indica fim do processamento
);
// estados codificados em 2 bits
localparam IDLE = 2'b00,
RUN = 2'b01,
DONE = 2'b10;
reg [1:0] state, next_state;
// Registrador de estado com reset assíncrono
always @(posedge clk or posedge rst) begin
if (rst)
state <= IDLE;
else
state <= next_state;
end
// Lógica de próximo estado e saída
always @(*) begin
next_state = state;
done = 1'b0;
case (state)
IDLE: if (start) next_state = RUN;
RUN: if (proc_done) next_state = DONE;
DONE: begin
done = 1'b1;
end
default: next_state = IDLE;
endcase
end
endmodule