Pregunta

Hice una simulación del comportamiento de mi código, y funciona perfectamente. Los resultados se predijo. Cuando sintetizo mi código y subirlo a una FPGA Spartan 3e y tratar de analizar el uso de ChipScope, los resultados no son ni siquiera cerca de lo que hubiera esperado. ¿Qué he hecho mal? http://pastebin.com/XWMekL7r

¿Fue útil?

Solución

Su problema es con las líneas 13-16, donde se define valores iniciales para los registros de estado:

 reg    [OUTPUT_WIDTH-1:0] previousstate = 0;              
 reg    [OUTPUT_WIDTH-1:0] presentstate = 1;
 reg    [6:0] fib_number_cnt = 1;  
 reg    [OUTPUT_WIDTH-1:0] nextstate = 1; 

Este es un equivalente a escribir una declaración "inicial" asignación de estos valores, que no es sintetizable - no hay tal cosa como un valor por defecto en el hardware. Cuando usted pone su diseño interior de un FPGA, todos estos registros se enfrentará a valores aleatorios.

En lugar de ello, es necesario inicializar los contadores / estados siempre dentro de su bloque, cuando se restablece es alto.

always @(posedge clk or posedge reset)
  if (reset) begin
     previousstate <= 0;
     presentstate <= 1;
     ... etc ...
  end

respuesta a las preguntas de seguimiento:

Al inicializar el código de esa manera, nada sucede en el hardware - que se ignora por completo, al igual que si has puesto en un comunicado pantalla $. La herramienta de síntesis salta sobre toda simulación se limita a construir, mientras que por lo general le da una especie de advertencia al respecto (que realmente depende de la herramienta).

Ahora, el bloqueo y sin bloqueo pregunta requiere una respuesta muy larga :). Voy a dirigir a este artículo de SNUG-2000, que es probablemente el mejor papel que se ha escrito sobre el tema. Responde a la pregunta, así como muchos otros en el tema. Después, se entiende por qué el uso de declaraciones de bloqueo en la lógica secuencial se considera una mala práctica, y por qué su código funciona bien con el bloqueo de las declaraciones de todos modos.

http://cs.haifa.ac.il /courses/verilog/cummings-nonblocking-snug99.pdf


Más respuestas:

El "patrón" habitual para la creación de la lógica como la suya es tener dos bloques, uno siempre que define la lógica, y uno que definen los fracasos. En el primer caso, se utilizan los estados de bloqueo para implementar la lógica, y en este último se enganche en (o reiniciar) el valor generado. Por lo tanto, algo como esto:

wire some_input;

// Main logic (use blocking statements)
reg state, next_state;
always @*
  if (reset) next_state = 1'b0;
  else begin
    // your state logic
    if (state) next_state = some_input;
    else next_state = 1'b0;
  end

// Flops (use non-blocking)
always @(posedge clock)
  if (reset) state <= 1'b0;
  else state <= next_state;

Tenga en cuenta que estoy usando un restablecimiento sincrónica, pero se puede usar asíncrono, si es necesario.

Otros consejos

Las líneas 13-16 son correctos. "Reg [6: 0] fib_number_cnt = 1;" No es lo mismo que usar la declaración "inicial". Leer Xilinx guía para la síntesis descripción más detallada de cómo inicializar los registros.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top