¿Cómo comparar un valor de 4 bits regrabable con una entrada de 4 bits dada en Verilog?

0

El objetivo de este proyecto es diseñar una alarma de bloqueo computacional en Verilog para que se ejecute en un tablero Altera (la nota en el tablero 0 está en realidad ACTIVADA y 1 en DESACTIVADA).

Basándome en los criterios de diseño, creé un diagrama de estado de todos los estados posibles y los contenía en una declaración de "casos" en mi código de registro de verificación.

Sin embargo, estoy teniendo problemas para comparar el código de combinación ingresado y la contraseña registrada y TAMBIÉN reescribiendo una nueva contraseña a la contraseña registrada cuando el diseño está en un estado particular.

Tenga en cuenta que he incluido muchos de mis problemas en los bloques / líneas de comentarios.

/* NOTES: FIX THE PASSWORD REGISTER AND INPUTS*/

module combinationalLock (clock, INPUTS, enter, change, reset, door, newPass, alarm);

    input enter, change, reset;
    input [4:1] INPUTS; // I don't know if I've defined this correctly

    output door, newPass, alarm;

    reg[3:1] y, Y;

    wire[4:1] passwordREG; // rewritable and comparable to INPUTS (I don't know if I've defined this correctly)
    parameter[3:1]

    // Binary state values

    START = 3'b000, 
    AGAIN = 3'b001, 
    ALARM = 3'b010, 
    CHANGE_OLD = 3'b011, 
    OPEN_DOOR = 3'b100, 
    CHANGE_OLD_AGAIN = 3'b101, 
    CHANGE_NEW = 3'b110;

    // Default password combo

   passwordREG = 4'b0110; // IM TRYING TO SET THE DEFAULT PASSWORD HERE

    // State conditions and changes

    always @(INPUTS, y, reset, change, enter)

        case(y)

            START: if((enter == 0) && (/*INPUTS ARE EQUAL TO REGISTRED PASSWORD*/)) Y = OPEN_DOOR;
                     else if ((enter == 0) && (/*INPUTS ARE NOT EQUAL TO REGISTRED PASSWORD*/)) Y = AGAIN;
                     else Y = START;

            AGAIN: if((enter == 0) && (/*INPUTS ARE EQUAL TO REGISTRED PASSWORD*/)) Y = OPEN_DOOR;
                     else if ((enter == 0) && (INPUTS != passwordREG)) Y = ALARM;
                     else Y = AGAIN;

            ALARM: if(reset == 0) Y = CHANGE;
                     else Y = ALARM;

            CHANGE_OLD: passwordREG = 4'b0110;
                            if((change == 0) && (/*INPUTS ARE EQUAL TO REGISTRED PASSWORD*/)) Y = CHANGE_NEW;
                          else if ((change == 0) && (/*INPUTS ARE NOT EQUAL TO REGISTRED PASSWORD*/)) Y = CHANGE_OLD_AGAIN;
                          else Y = CHANGE_OLD;

            OPEN_DOOR: if(enter == 0) Y = START;
                         else Y = OPEN_DOOR;

            CHANGE_OLD_AGAIN: if((change == 0) && (/*INPUTS ARE EQUAL TO REGISTRED PASSWORD*/)) Y = CHANGE_NEW;
                                else if ((change == 0) && (/*INPUTS ARE NOT EQUAL TO REGISTRED PASSWORD*/)) Y = ALARM;
                                else Y = CHANGE_OLD_AGAIN;

            CHANGE_NEW: passwordREG = INPUTS; // NOTE IN THIS LINE IM TRYING TO REWRITE THE REGISTERED PASSWORD
                            if((CHANGE == 0)||(ENTER == 0)) Y = START; 
                          else Y = CHANGE_NEW;

            default: Y = 3'bxxx;

        endcase

    // Clock pulse

    always @(posedge clock)
        y<=Y;

    // Output

    assign door = (y == OPEN_DOOR);
    assign newPass = (y == CHANGE_NEW);
    assign alarm = (y == ALARM);


endmodule 

Nota: También recibo algunos errores de sintaxis impares en las líneas 27, 47 y 59 donde esperan un "caso final".

    
pregunta Akila Kavisinghe

1 respuesta

1

Algunos puntos para hacer.

En primer lugar, para Verilog debería utilizar la indexación cero. p.ej. wire [3:0] imAFourBitWire .

En segundo lugar, si el cuerpo de una declaración case ocupa más de una línea, necesita envolverla en declaraciones begin-end (de hecho, el uso liberal de este es un buen hábito). Por ejemplo,

case(y)
   SOMETHING: begin
      aThing = bThing;
      cThing = anotherThing;
   end
   ...
endcase

Observe cómo la multilínea se ajusta en begin-end .

Lo mismo ocurre con las declaraciones if y if-else . Sí, puedes omitir begin-end , pero eso no significa que debas hacerlo, especialmente si estás empezando con el idioma. No toma mucho tiempo agregar 8 caracteres, pero hace que la estructura del código sea mucho más fácil de seguir.

En tercer lugar, esta línea:

passwordREG = 4'b0110; // IM TRYING TO SET THE DEFAULT PASSWORD HERE

Necesitas usar una declaración assign si quieres asignar un valor a un cable.

Esto conduce a:

passwordREG = INPUTS; // NOTE IN THIS LINE IM TRYING TO REWRITE THE REGISTERED PASSWORD

Pero usted declaró passwordREG como wire , no como reg . Estás violando dos reglas aquí:

  1. No puede asignar un valor a un wire con una asignación de procedimiento (por ejemplo, = en un bloque always ), solo usando la asignación continua ( assign enunciados)
  2. Solo puede asignar un wire con más de una asignación. Ya tienes passwordREG = 4'b0110; más arriba.

A continuación, usar parameter[3:1] no es diferente de parameter . Establecer el ancho de un parámetro como este no tiene efecto. En cambio, el ancho es el ancho del valor que esté configurando, por ejemplo, parameter something=3'b110 crearía un parámetro de 3 bits.

Finalmente, nuevamente desde un punto de vista estilístico, mientras que puedes declarar múltiples parámetros como lo has hecho, es decir,

parameter[3:1]

// Binary state values

START = 3'b000, 
AGAIN = 3'b001, 
ALARM = 3'b010, 
CHANGE_OLD = 3'b011, 
OPEN_DOOR = 3'b100, 
CHANGE_OLD_AGAIN = 3'b101, 
CHANGE_NEW = 3'b110;

Recomendaría que no lo hiciera, hace que el código sea más difícil de seguir y los errores pueden comenzar a aparecer. En lugar de eso, utilice:

// Binary state values

parameter START = 3'b000;
parameter AGAIN = 3'b001; 
parameter ALARM = 3'b010; 
parameter CHANGE_OLD = 3'b011;
parameter OPEN_DOOR = 3'b100; 
parameter CHANGE_OLD_AGAIN = 3'b101;
parameter CHANGE_NEW = 3'b110;

No agrega mucho más esfuerzo, pero algún día le ahorrará una gran cantidad de tiempo en la depuración del código.

    
respondido por el Tom Carpenter

Lea otras preguntas en las etiquetas