diseñando una máquina de estados para detectar un bit determinado

0

Por lo tanto, necesito crear una máquina de estado (máquina harinosa) para detectar el bit 1010 y también debo codificarlo en verilog. Aquí hay una foto de mi máquina de estado:

Entonces,creélamáquinadeestadoyahoranecesitocodificarlaenverilog:

modulesm(clock,x,y);inputclk,x;outputy;regy;reg[1:0]s=0;always@(posedgeclk)case(s)0:if(x)s<=1;1:if(!x)s<=2;2:if(x)s<=3;elses<=0;3:if(x)s<=2;elses<=1;endcasealways@(*)case(s)3:if(x)y=1;elsey=0;default:y=0;endcaseendmodule

Apenasaprendoestohoy.Entonces,mepreguntabasimicódigoverilogescorrecto.Cualquierayuda/sugerenciaesapreciada.Gracias:)

resultadosdelasimulación:[![ingreseladescripcióndelaimagenaquí][2]][2]

nuevosim:

    
pregunta cmelo

1 respuesta

1

Antes de llegar a si es funcional o no, tengo algunas sugerencias. Pueden parecer triviales en este momento, pero si aprendes a hacerlas correctamente ahora, te será mucho más fácil más adelante.

  1. Sangra tu código correctamente. Puede parecer una tarea, pero vale la pena
  2. Utilice las palabras clave begin y end . Son tus amigos, y solo 8 caracteres.
  3. Dale a las redes nombres propios. Hace que la depuración de las cosas sea mucho más fácil a medida que el código comienza a leerse en inglés en lugar de gibberish.
  4. Da una longitud a las constantes. Hará que los errores sean más evidentes cuando sintetice, en lugar de simplemente ignorar las advertencias del compilador acerca de las constantes que se están truncando, podrá usarlas para detectar errores.
  5. ¡Añade comentarios! Cualquier cosa que no sea evidente en el código, escriba un comentario para explicar por qué está sucediendo.
  6. Dé los nombres de los estados de las máquinas de estados usando la palabra clave localparam . De nuevo, esto hace que sea más fácil de leer, y si necesita cambiar el valor que representa un estado, solo tiene que cambiarlo en un lugar.

Esto es un poco de tu código al que he aplicado lo anterior.

localparam IDLE_STATE = 2'd0;
localparam FINAL_STATE = 2'd3; //I'm not saying these are good names, just an example

reg [1:0] stateMachine = IDLE_STATE;
always @ (posedge clk) begin
    case(stateMachine)
    ...
    FINAL_STATE:
        //At this point we have the sequence 101
        if(bitIn) begin
            //A 1 does not make the sequence 1010
            stateMachine <= SOME_STATE; //Go back to ... state to start the sequence at 1xxx again.
        end else begin
            stateMachine <= SOME_OTHER_STATE; //Go to SOME_OTHER_STATE;. <-- This is a *bad* example of a comment as it doesn't tell us anything useful.
        end
    ...
    endcase
end

Una rápida mirada al diagrama de la máquina de estados, y parece tener sentido. De hecho, debería poder detectar flujos de 1010. Por ejemplo, 101010 se detectaría como dos secuencias 1010 válidas (que se superponen). Supongo que esto es lo que estás tratando de hacer.

La representación de la máquina de estado en Verilog (aparte de las sugerencias de codificación anteriores) parece ser una representación válida de su diagrama de la máquina de estado.

Lo que sí noté es que su máquina de estado no tiene una señal de reinicio. Se inicializa correctamente en el encendido, pero ¿qué sucede si usted, por ejemplo, restablece su flujo de datos entrantes, pero la máquina de estado todavía está en el estado final, puede detectar falsamente un patrón válido con solo 1,2 o 3 bits dependiendo de donde estaba su máquina de estado cuando comenzó el flujo de datos. Una señal de reinicio ayudaría a curar esto.

Además, no tiene un estado default: , que básicamente dice que si la máquina de estado no está en un estado válido, vaya a cualquier estado (por ejemplo, IDLE_STATE). Esto no es necesariamente necesario cuando tiene un caso completo (es decir, tiene una entrada para cada valor posible que puede tomar el registro) que es cierto para su código. Pero tenlo en cuenta.

Otra vez solo le eché un vistazo rápido. Debes ejecutar una simulación para asegurarte de que sea correcta.

Los resultados de tu simulación han revelado un problema: no detecté que en el bloque always que maneja y , tu sentencia if está invertida. Debería ser if(!x) .

Pero eso trae otro punto, por ese poco de código, haciendo:

if(!x) begin
    y = 1'b1;
end else begin
    y = 1'b0;
end

Es una manera muy larga de decir:

y = !x;
    
respondido por el Tom Carpenter

Lea otras preguntas en las etiquetas