Código Verilog. Se necesita ayuda en la declaración siempre
Frecuentes
Visto 2,581 equipos
1
El siguiente es el código: La intención del código es calcular el número de ceros a la izquierda de uno de los registros. Solo quiero calcular los ceros iniciales del registro significativo solo una vez. Tengo que usar un bloque siempre para esto. Ahora, inicialmente asigné a como 1'b1 y luego lo cambié a 1'b0, para que el bloque se ejecute una vez. Si trato de simular el código. El bloque always no se ejecuta. Sin embargo, si luego asigno a como 0'b1 (lo que no tiene ningún sentido). El código simula correctamente en el Simulador. Pero si sintetizo el código en el kit FPGA, da un resultado erróneo. por favor, ayúdame
integer count,index;
wire a;
assign a=1'b1;
always@(a)
begin
for(count=0;count<7;count=count+1) begin
index=4*count;
if((significand[index ]==1'b0) && (significand[index+1]==1'b0) &&
(significand[index+2]==1'b0) && (significand[index+3]==1'b0))
lzero=lzero+1;
end
end
assign a=1'b0;
// If I use assign a=0'b1, it simulates properly,
// but 0'b1 doesn't make any sense, also If I keep 0'b1,
// I dont get proper result in actual synthesis onto the board.
En realidad, mi intención de hacer la pregunta era cómo debería poder usar un bloque "siempre". Como solo quería ejecutar este bloque solo una vez, entonces no necesita establezca "posge clk" o "negege clock" con siempre. Entonces qué debo hacer ?? Por favor ayuda porque mi proyecto me demanda Alto uso de para loops si más bucles
3 Respuestas
5
Pareces un ingeniero de software tratando de escribir un programa y no tratando de describir el hardware.
Tienes que pensar mucho en paralelo cuando estás codificando.
Su código dice "continuamente y siempre asigne el valor de uno a a" y luego dice "continuamente y siempre asigne el valor de 0 a a". Esto obviamente no es lo que quieres. Esas declaraciones de asignación NO son temporales como usted quiere que sean.
Así que quieres algo como esto (en pseudocódigo): 1) Lee el registro de entrada 2) Cuenta el número de 0 3) Muestra el número de 0
En el software, harías el paso 2 así:
for i=msb to lsb loop
if (input[i] == 1) then break;
end loop
return i;
For loops en HW significa escribir una máquina de estado (piense en cómo hace for loops en un lenguaje funcional con recursividad y una de las entradas es el índice que está haciendo). O podemos desenrollar el bucle nosotros mismos.
if (msb == 1 ) then return 0
else if (msb-1 == 1) then return 1
...
else if (msb-31 == 1) then return 31
else return 32
end if
Respondido el 30 de junio de 12 a las 04:06
1
Lo que puede hacer es crear una bandera, establecer la bandera en 0 al inicio y en su bloque siempre, verifique el valor de su bandera, si la bandera es igual a 0 significa que esta es la primera vez que su bandera, realice su operación y dentro de allí, establezca su bandera en 1.
De esta manera, garantiza que solo realizará esas operaciones una vez al inicio.
Respondido el 30 de junio de 12 a las 19:06
1
Hay algunas cosas aquí que parecen ser un uso incorrecto del lenguaje verilog para describir el hardware.
Si se trataba de un componente de banco de pruebas que necesitaba inicializarse, entonces initial begin .. end
sería la manera de hacer esto.
Si esto está destinado a la síntesis y solo para ejecutarse una vez, entonces un always
block no me parece la forma correcta de diseñarlo. Si se va a ejecutar una vez en el encendido, entonces podría calcularse previamente (parámetro) y, por lo tanto, fijarse en la compilación/síntesis.
Si se basa en una entrada, que puede cambiar, no debería haber una habilitación para ejecutar el cálculo. Como esta entrada podría no establecerse en el tiempo 0, dependiendo de la secuencia de encendido del hardware.
Si esto es para síntesis, lo siguiente sería más adecuado:
module count_lzero(
input clk,
input rst_n,
input enable, // Toggle high 1 Clk to calc new lzero
output reg [31:0] lzero
);
always @(posedge clk or negedge rst_n) begin
if (~rst_n) begin
lzero <= 'b0;
end
else if ( enable ) begin
for(count=0;count<7;count=count+1) begin
index=4*count;
if((significand[index ]==1'b0) && (significand[index+1]==1'b0) &&
(significand[index+2]==1'b0) && (significand[index+3]==1'b0))
lzero<=lzero+1;
end
end
end
Respondido el 24 de enero de 13 a las 12:01
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas verilog or haz tu propia pregunta.
@ FarhadA: Señor, al usar su sugerencia, pude obtener el resultado de simulación correcto pero no pude obtener el resultado de síntesis correcto en el tablero. Estoy comprobando el resultado en la placa encendiendo los LED. Enlace a mi código: dl.dropbox.com/u/86119115/liderando_ceros.PNG - user1491918
Te falta una parte importante, olvidaste verificar la bandera antes de entrar en el bucle. Agregue eso, y estoy seguro de que verá un resultado diferente. - FarhadA