Estoy tratando de entender cuál es el 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é estaría hecho este mini archivo de registro en hardware. En particular, la matriz de 4x8 bits que consta de k0,k1,k2,k3. Pensé que cuando se trataba de registros y matrices como esta, ¿necesita un reloj para leer datos, como RAM?
Mire, tengo un problema conceptual al diseñar un módulo de caché verilog simple. Tengo una matriz de datos que contiene todas mis etiquetas así:
reg [NUM_TAG_BITS-1:0] tag_array[NUM_BLOCKS-1:0]
Y tengo un cable "line_select" (desde mi PC de entrada). Lo que quiero hacer es recuperar tag_array[line_select] y luego ponerlo en un comparador con la etiqueta de mi PC para ver si tengo un acierto.
Pero pensé que cada vez que accedo a tag_array, necesito estar dentro del código "always @ (posedge clk)". Luego me quedé atascado: ¿cómo leo de este tag_array y hago la comparación dentro del mismo ciclo de reloj? Así que encontré el código anterior en línea que dice que puede leer los registros de forma asincrónica, luego me confundí porque, francamente, no sé lo suficiente sobre el hardware de memoria y cómo es posible.
¡Muchas gracias por cualquier ayuda!
Su código simula dos multiplexores. Estos son en realidad componentes asincrónicos. El hecho de que Verilog requiera data1_temp
y data2_temp
se declare como reg
's es una peculiaridad de la sintaxis de Verilog y su elección de estilo de codificación, y no significa que estas señales sean las salidas de los elementos de almacenamiento en una 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é estaría hecho este mini archivo de registro en hardware. En particular, la matriz de 4x8 bits que consta de 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)
, es muy probable que sean flip-flops, pero hay formas de codificarlos que los sintetizarían de manera diferente.
Pensé que cuando se trataba de registros y matrices como esta, ¿necesita 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á cada vez 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 de reloj.
Para otro ejemplo, igualmente 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ítanme 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 de acceder al contenido de una RAM dependerá de los detalles del tipo de RAM que utilice.
Me confundí porque, francamente, no sé lo suficiente sobre hardware de memoria y cómo es posible.
Otra estrategia clave: cuando esté aprendiendo lógica digital, le recomiendo que primero aprenda sobre el hardware físico y luego trabaje o estudie cómo simularlo en HDL en segundo lugar. 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á tratando de escribir HDL para síntesis, tratar de escribir un buen código antes de aprender las capacidades del hardware subyacente lo llevará por muchos caminos sin salida.
Si un Verilog se convierte o no reg
en un flip-flop de hardware depende de cómo se actualice. En general, si se actualiza dentro de un always @(posedge <signal>)
bloque, 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, son solo 32 cables que provienen de otro lugar. Cada case
declaración es un multiplexor asíncrono simple que selecciona 8 bits a la vez de entre esos 32 cables.
k<n>
Si sus variables se pueden mapear colectivamente o no en una estructura de RAM de hardware (suponiendo que tal cosa esté disponible en su tecnología de destino) depende de cómo se actualizan y cómo se leen ... y qué tan buenas son las herramientas de síntesis para inferir RAM del código de comportamiento.
JDS
Let me repeat a key point for emphasis: You need to use a clock to assign a new value to a register (an actual hardware register or group of flip-flops). It's output is available at any time.
dibujé en papel un montón de DFF y me di cuenta de esto... Por supuesto, las salidas están disponibles en cualquier momento y las escrituras deben estar sincronizadas con un reloj. Como usted sugiere, estoy tratando de aprender los conceptos de hardware más que la codificación. Gracias de nuevo.el fotón
david tweed
el fotón