Conducción de una pantalla de 7 segmentos con un registro vs cable

4

Hace unos días, cuando obtuve mi FPGA, creé un módulo para manejar mi pantalla de 7 segmentos. Usé solo asignaciones continuas para conducir los leds.

module set_number(input [3:0] x, output [6:0] seg);
    assign seg = x == 0 ? 7'b1000000 :
                 x == 1 ? 7'b1111001 :
                 x == 2 ? 7'b0100100 :
                 x == 3 ? 7'b0110000 :
                 x == 4 ? 7'b0011001 :
                 x == 5 ? 7'b0010010 :
                 x == 6 ? 7'b0000010 :
                 x == 7 ? 7'b1111000 :
                 x == 8 ? 7'b0000000 :
                 x == 9 ? 7'b0010000 : 
                          7'b1111111;
endmodule

Estaba leyendo un libro y tienen una pantalla de 7 Seg. escrita de esta manera, utilizando registros y un bloque combinado de combinación.

module hex_to_sseg
(
 input  wire  [3:0]  hex,
 input  wire  dp,
 output  reg  [7:0]  sseg   // output active low
);

always @*
begin
   case(hex)
      4'h0:  sseg[6:0]  = 7'b0000001;
      4'h1:  sseg[6:0]  = 7'b1001111;
      4'h2:  sseg[6:0]  = 7'b0010010;
      4'h3:  sseg[6:0]  = 7'b0000110;
      4'h4:  sseg[6:0]  = 7'b1001100;
      4'h5:  sseg[6:0]  = 7'b0100100;
      4'h6:  sseg[6:0]  = 7'b0100000;
      4'h7:  sseg[6:0]  = 7'b0001111;
      4'h8:  sseg[6:0]  = 7'b0000000;
      4'h9:  sseg[6:0]  = 7'b0000100;
      4'ha:  sseg[6:0]  = 7'b0001000;
      4'hb:  sseg[6:0]  = 7'b1100000;
      4'hc:  sseg[6:0]  = 7'b0110001;
      4'hd:  sseg[6:0]  = 7'b1000010;
      4'he:  sseg[6:0]  = 7'b0110000;
      default:  sseg[6:0]  = 7'b0111000;   //4'hf
  endcase
  sseg[7] = dp;

¿Hay alguna diferencia práctica entre mi enfoque con el cable y el enfoque del libro con el registro y la lógica combinatoria?

    
pregunta chasep255

4 respuestas

4

Como el transistor menciona en su respuesta, la lógica representada por las dos piezas de código que publicaste no es la misma; tiene diferencias en el orden de los bits y la última muestra mostrará los caracteres hexadecimales A-F.

Pero está preguntando sobre la diferencia entre usar una variable de conexión y una declaración de asignación frente a una variable de registro y una construcción siempre @ *.

Una cosa confusa acerca de verilog es que el uso de un tipo de datos reg en su código no siempre implica que se implementará un registro en la lógica sintetizada.

En los casos que publicaste, ambas soluciones se implementarían usando lógica combinatoria sin registros físicos. Es muy común utilizar la construcción always @ * para modelar la lógica combinatoria.

Los circuitos secuenciales, que incluirán registros físicos (flip-flops), también se modelan usando la construcción siempre, pero estos circuitos tendrán una señal de posición y / o señalización especificada en la lista de sensibilidad.

De los casos que publicaste, personalmente preferiría usar la versión always @ * del código ya que creo que muestra más claramente la intención del código; es fácil ver que representa una tabla de decodificación.

    
respondido por el B Pete
3

Hay varias formas diferentes de expresar la misma descripción en Verilog. La declaración continua assign es buena para escribir una ecuación para una sola señal, pero en realidad no es RTL. Si desea asignar varias señales basadas en el mismo conjunto de entradas, entonces el bloque always le permite mostrar el flujo de decisiones tomadas en un bloque de código de procedimiento. Esta es una forma mucho mejor de mostrar su intención mediante el uso de un conjunto de declaraciones RTL más legibles por humanos.

    
respondido por el dave_59
2

Si su preocupación es con respecto a los valores binarios, entonces se ve bien. El código de ejemplo tiene dos diferencias.

  • El orden de los bits se invierte. Esto se puede reorganizar para adaptarse al diseño de PCB.
  • La versión del libro mostrará el conjunto de caracteres hexadecimales completos mientras que el suyo solo maneja dígitos decimales.
  • El libro parece estar utilizando un registro de salida diferente.
respondido por el Transistor
2

Muchos sintetizadores usan el operador condicional ( ?: ) como mux explícito 2: 1. Operadores condicionales anidados con sintetizar como se escribe el diseño. En tu caso, será una cadena de diez musas 2: 1. Aquí hay un diagrama de su código sintetizado con Yosys 0.3.0 en edaplayground

Alconvertirsucódigoenunadeclaracióndecaso,sesintetizarácomolasiguiente(tambiénsesintetizaconYosys0.3.0en edaplayground ). En este caso, Yosys usó un mux de prioridad, pero podría haber escogido de forma sencilla un

Funcionalmente los dos son idénticos. La versión de la declaración de caso tendrá típicamente una sincronización mejor y más uniforme. Con los operadores condicionales anidados, cuando x==0 el retardo de prórroga es de 2 puertas lógicas, cuando x>=9 son 11 puertas lógicas. La versión de la declaración de caso también le da al sintetizador más flexibilidad, lo que permite que el sintetizador elija las mejores opciones para la situación teniendo en cuenta los recursos disponibles, los recursos necesarios para otras lógicas y los requisitos de tiempo.

En general, es mejor usar una declaración de caso y dejar que el sintetizador elija los muxes apropiados.

    
respondido por el Greg

Lea otras preguntas en las etiquetas