Esta máquina de estado no entra en un estado inicial en el inicio

0

Este es mi código de máquina de estado:

module DES_FSM (
    input CLK,
    input Start,
    input Reset,
    input [3:0] Input_Data,
    input [3:0] Next_Round_Data,
    output reg [3:0] Output_Data,
    output reg Complete
);
    reg c;
    //reg [3:0] out;
    reg [5:0] State;
    reg [5:0] Next_State;

    parameter Idle = 5'b00000;
    parameter R1    = 5'b00001;
    parameter R2    = 5'b00010;
    parameter R3    = 5'b00011;
    parameter R4    = 5'b00100;
    parameter R5    = 5'b00101;
    parameter R6    = 5'b00110;
    parameter R7    = 5'b00111;
    parameter R8    = 5'b01000;
    parameter R9    = 5'b01001;
    parameter R10   = 5'b01010;
    parameter R11   = 5'b01011;
    parameter R12   = 5'b01100;
    parameter R13   = 5'b01101;
    parameter R14   = 5'b01110;
    parameter R15   = 5'b01111;
    parameter R16   = 5'b10000;
    parameter Done = 5'b11111;

    //assign Output_Data = out;
    //assign Complete    = c;

    always @(posedge CLK or posedge Reset) begin
        if(Reset)
            State = Idle;
        else
            case (State)
                Idle: if(Start) State = R1;
                R1:     State = R2;
                R2:     State = R3;
                R3:     State = R4;
                R4:     State = R5;
                R5:     State = R6;
                R6:     State = R7;
                R7:     State = R8;
                R8:     State = R9;
                R9:     State = R10;
                R10:        State = R11;
                R11:        State = R12;
                R12:        State = R13;
                R13:        State = R14;
                R14:        State = R15;
                R15:        State = R16;
                R16:        State = Done;
                Done:       State = Idle;
                default: State = 5'bxxxxx;
            endcase
    end

    always @(State) begin
        case (State)
            Idle:   Output_Data = R1;
            R1:     Output_Data = Input_Data;
            R2:     Output_Data = Next_Round_Data;
            R3:     Output_Data = Next_Round_Data;
            R4:     Output_Data = Next_Round_Data;
            R5:     Output_Data = Next_Round_Data;
            R6:     Output_Data = Next_Round_Data;
            R7:     Output_Data = Next_Round_Data;
            R8:     Output_Data = Next_Round_Data;
            R9:     Output_Data = Next_Round_Data;
            R10:        Output_Data = Next_Round_Data;
            R11:        Output_Data = Next_Round_Data;
            R12:        Output_Data = Next_Round_Data;
            R13:        Output_Data = Next_Round_Data;
            R14:        Output_Data = Next_Round_Data;
            R15:        Output_Data = Next_Round_Data;
            R16:        Output_Data = Next_Round_Data;
            Done:       Complete        = 1'b1;
            default: Output_Data = 5'bxxxxx;
        endcase
    end

endmodule

Y este es el banco de pruebas:

module FSM_Test;
  reg clk, start, reset;
  reg [3:0] in, next_in;
  wire [3:0] out;
  wire complete;

  DES_FSM FSM (clk, start, reset, in, next_in, out, complete);

  initial begin
    clk = 1;
    start = 1;
    reset = 0;
    //#20 reset <= 0;
    in = 4'b0011;
    next_in = 4'b1100;
  end

  always @(clk) begin
    #10 clk <=~ clk;
  end

  initial #200 $stop;
endmodule

Estoy usando esta máquina de estado para contar cuántas rondas han pasado en un módulo de cifrado DES. Sinteticé mi diseño utilizando el software Altera Quartus II y la simulación utilizando ModelSim Altera.

Cuando paso los valores en mi banco de pruebas al diseño, la salida en todas las rondas es x . Claramente, como el diseño establece en la primera ronda, debe hacer Input_Data como salida y en las otras rondas Next_Round_Data es la salida.

Lo resolví un poco, ya sea proporcionando un pulso bajo-alto en el Reset o usando default: State = Idle; en lugar de default: State = 5'bxxxxx; ya que de alguna manera se desconoce State al inicio, que se inicializará en el segundo ciclo de reloj. / p>

¿Puedo obtener la salida deseada en el inicio? Me refiero a poner la máquina de estados en un estado inicial en el primer ciclo de reloj en lugar de esperar ciclos de reloj para la inicialización.

EDITAR: tuve mi diseño basado en este ejemplo .

    
pregunta 3bdalla

3 respuestas

4

Esto es exactamente por lo que se agrega una señal Reset al sistema. Para llevarlo a un estado inicial conocido. No hay forma de evitarlo cuando se trabaja con hardware real. En cuanto a la simulación, puede agregar un bloque initial al diseño e inicializar el estado a lo que desee, pero no es sintetizable.

    
respondido por el Eugene Sh.
2
  1. No estás usando Next_State, así que no tengo claro por qué te molestas en tenerlo. El enfoque (recomendado) sería realizar una asignación de bloqueo a Next_State en su bloque de combinación combinada, y una asignación de no bloqueo de Next_State a State en su bloque de sincronización síncrona.
  2. Está sobre-asignando las variables State y Next_State; solo necesitan 5 bits, no 6.
  3. Al asignar 5'bxxxx a Estado como el caso predeterminado, se asegura de que si el Estado está siempre fuera de rango siempre se mantenga de esa manera. Asigne un valor útil en el caso predeterminado, presumiblemente ya sea Inactivo o R1.
  4. Puede asignar un valor inicial cuando define las variables State y Next_State, por ejemplo. reg [4:0] State = Idle; Para hacerlo, (probablemente) tendrá que definir los parámetros primero.
respondido por el markt
2

Ha omitido la operación de restablecimiento en su banco de pruebas, Reset debería ir alto y algún tiempo después irá bajo. Si está apuntando a FPGA, también podría poner initial State = Idle; en su diseño. Tenga en cuenta que initial solo funciona para simulación y síntesis de FPGA, no síntesis de IC.

Otras cuestiones: Faltan Input_Data y Next_Round_Data en la lista de sensibilidad que asigna Output_Data . Esto es inferir la lógica de bloqueo compleja en la simulación . La mayoría de los sintetizadores tratarán es como combinación de lógica. Para asegurar un comportamiento de coincidencia, cambie always @(State) a always @* .

También puede hacer always @(State or Input_Data or Next_Round_Data) , sin embargo, solo debe enumerar explícitamente las redes en la lista de sensibilidad para lógica combinacional si está limitado al estilo de codificación IEEE Std 1364-1995. IEEE Std 1364-2001 y * -2005 recomiendan always @* . @* (o equivalente @(*) ) administra la lista sensible para el bloque por usted.

Además, cuando asigne State use asignaciones no bloqueantes ( <= ). Use la asignación de bloqueo ( = ) en su controlador de reloj en el banco de pruebas.

    
respondido por el Greg

Lea otras preguntas en las etiquetas