Verilog lecturas asíncronas de registros - y pregunta de diseño

2

Estoy tratando de entender en qué parte del siguiente código de comportamiento, en qué tipo de hardware se convierte:

reg [7:0] k0, k1, k2, k3;
reg [7:0] data1_tmp, data2_tmp;

// Asynchronously read data from two registers
always @(*)
begin
    case (reg1)
        0: data1_tmp = k0;
        1: data1_tmp = k1;
        2: data1_tmp = k2;
        3: data1_tmp = k3;
    endcase
    case (reg2)
        0: data2_tmp = k0;
        1: data2_tmp = k1;
        2: data2_tmp = k2;
        3: data2_tmp = k3;
    endcase
end

Lógicamente entiendo lo que está haciendo. Pero me gustaría saber de qué se haría este archivo de mini registro en hardware. En particular, la matriz de 4x8 bits que consiste en k0, k1, k2, k3. Pensé que cuando se trataba de registros y matrices como esta, ¿necesitas un reloj para leer datos, como RAM?

Vea Tengo un problema conceptual al diseñar un módulo simple de caché verilog. Tengo una matriz de datos que contiene todas mis etiquetas como:

reg [NUM_TAG_BITS-1:0] tag_array[NUM_BLOCKS-1:0] 

Y tengo un cable "line_select" (de mi PC de entrada). Lo que quiero hacer es recuperar tag_array [line_select] y luego colocarlo en un comparador con la etiqueta de mi PC para ver si tengo un hit.

Pero pensé que cada vez que accedía a tag_array, tenía que estar dentro del código "always @ (posedge clk)". Luego me quedé atascado: ¿cómo leo este tag_array y hago la comparación dentro del mismo ciclo de reloj? Así que encontré el código anterior en línea diciendo que se puede leer de los registros de forma asíncrona, luego me confundí porque, francamente, no sé lo suficiente sobre el hardware de memoria y cómo es posible.

Muchas gracias por cualquier ayuda!

    
pregunta JDS

2 respuestas

5

Tu código simula dos multiplexores. Estos son en realidad componentes asíncronos. El hecho de que Verilog requiera que data1_temp y data2_temp se declaren como reg 's es una peculiaridad de la sintaxis de Verilog y su estilo de codificación, y no significa que estas señales sean las salidas de los elementos de almacenamiento Implementación física.

Si desea capturar estos valores en registros reales, debe agregarlos explícitamente:

reg [7:0] data1, data2;
always @(posedge someclock) begin
    data1 <= data1_tmp;
    data2 <= data2_tmp;
end
  

Pero me gustaría saber de qué se haría este archivo de mini registro en hardware. En particular, la matriz de 4x8 bits que consiste en k0, k1, k2, k3.

No ha mostrado cómo se asignan estas variables, por lo que no es posible decir cómo se implementan. Como mostró su código, simplemente declararlos como reg no garantiza que se implementen con elementos de almacenamiento reales. Si los asigna dentro de un bloque que comienza always @(posedge clk) entonces es muy probable que sean flip-flops, pero hay formas en que podría codificarlos que los harían sintetizar de manera diferente.

  

Pensé que cuando se trataba de registros y matrices como esta, ¿necesitas un reloj para leer datos, como RAM?

Necesita un reloj para actualizar un registro (físico). Puedes leerlo en cualquier momento. Por ejemplo:

wire [8:0] sum;
assign sum = k0 + k1; 

es un código perfectamente válido. sum cambiará siempre que cambie alguna de sus entradas. Si k0 y k1 son las salidas de los flip-flops, sus valores solo cambiarán cuando haya un borde del reloj.

Para otro ejemplo, también podría describir sus multiplexores con un código como este:

reg [7:0] k0, k1, k2, k3;
wire [7:0] data1_tmp;
reg [1:0] reg1;
// k<n> and reg1 are assigned elsewhere.
assign data1_tmp = (reg1 == 0) ? k0 :
                   (reg1 == 1) ? k1 :
                   (reg1 == 2) ? k2 : k3;
  

¿Cómo leo de este tag_array y hago la comparación dentro del mismo ciclo de reloj?

Permítame repetir un punto clave para enfatizar: necesita usar un reloj para asignar un nuevo valor a un registro (un registro de hardware real o un grupo de flip-flops). Su salida está disponible en cualquier momento.

Las RAM son diferentes y la forma en que acceda al contenido de una RAM dependerá de los detalles del tipo de RAM que utilice.

  

Me confundí porque, francamente, no sé lo suficiente sobre el hardware de memoria y cómo es posible.

Otra estrategia clave: cuando estás aprendiendo lógica digital, te recomiendo que primero aprendas sobre el hardware físico, y luego trabajes o estudies cómo simularlo en HDL. Entonces, primero, aprenda qué es un flip-flop físico, luego aprenda los métodos estándar de Verilog para describir un flip-flop. Especialmente si está intentando escribir HDL para síntesis, tratar de escribir buen código antes de aprender las capacidades del hardware subyacente lo llevará por muchos caminos sin salida.

    
respondido por el The Photon
4

Si un Verilog reg se convierte en un flip-flop de hardware depende de cómo se actualice. En general, si se actualiza dentro de un bloque always @(posedge <signal>) , se convertirá en un DFF.

Su código de muestra no muestra cómo se actualizan k0, k1, k2 y k3, por lo que en lo que respecta a este bloque, solo son 32 cables que vienen de otro lugar. Cada declaración case es un multiplexor asíncrono simple que selecciona 8 bits a la vez entre esos 32 cables.

El hecho de que sus variables k<n> puedan ser asignadas colectivamente a una estructura RAM de hardware (suponiendo que tal cosa esté disponible en su tecnología objetivo) depende de cómo se actualicen y de cómo se lean ... Las herramientas de síntesis están en inferir RAM del código de comportamiento.

    
respondido por el Dave Tweed

Lea otras preguntas en las etiquetas