Tiene problemas para implementar una luz parpadeante de 1Hz en un Spartan 6 FPGA

1

Actualmente tengo un Spartan-6 FPGA en una placa Digilent Nexus 3. Estoy usando Xilinx 14.6 Project Navigator para escribir el código y programar el FPGA.

Mi código para el módulo superior (y único) es el siguiente:

21 module blinker(
22 input clk,
23 output reg led_state
24 );
25   
26 reg [31:0] count;
27 wire count_max = 32'd50000000;
28
29 assign count_next = (count_next > count_max) ? 32'd00000000 : count + 32'd00000001;
30 assign led_next = (count == count_max) ? ~led_state : led_state;
31
32 always @(posedge clk)
33 begin
34    count <= count_next;
35    led_state <= led_next;
36 end
37
38 endmodule

De acuerdo con el manual de referencia de Nexus 3, la placa tiene un oscilador de 100 MHz en el pin V10, por lo que en mi archivo de restricciones de usuario, asigné el pin V10 a la señal de entrada de clk de mi módulo.

Dado que el oscilador está a 100MHz, configuré count_max en 50,000,000, de modo que el led_state debería invertir cada 50 x 10 ^ 6 bordes de clk, o cada medio segundo, suponiendo 100MHz.

Cuando intenté la síntesis utilizando XST en el Project Navigator, recibo estos mensajes de advertencia:

WARNING:HDLCompiler:413 - "C:\Users\Public\Documents\Xilinx Projects\blinker\blinker.v" Line 29: Result of 32-bit expression is truncated to fit in 1-bit target.
WARNING:Xst:2404 -  FFs/Latches <count<31:1>> (without init value) have a constant value of 0 in block <blinker>.
WARNING:Xst:2170 - Unit blinker : the following signal(s) form a combinatorial loop: n0011<0>.

Sin embargo, todavía puedo seguir adelante y construir el archivo .bit y programar el Nexus 3. El resultado, sin embargo, es que el LED, al que designé por la salida, simplemente permaneció encendido todo el tiempo (a menos que está parpadeando tan rápido que no me doy cuenta de que parpadea).

Pensé que tal vez tenía que ver con la Advertencia donde el Sintetizador truncaba la expresión en la Línea 29, así que intenté declarar count_next como un vector de 32 bits [31: 0], tanto como un registro como un cable, y También inicializando su valor. Probé el sintetizador y obtengo errores en su lugar.

Declarar e inicializar el conteo, led_state, count_next, led_next tampoco funcionó.

Me preguntaba si alguien puede mirar esto y decirme qué problema tiene con el código. También hay un bucle combinatorio para la señal "n0011 < 0 >" que no reconozco.

    
pregunta user279043

3 respuestas

3

El problema que veo es que has declarado count_max como un cable de 1 bit de ancho y luego le asignas una constante de 32 bits. Esto esencialmente se truncará a 1 bit.

Esto significará que estás haciendo adiciones y comparaciones entre los valores de 32 bits y 1 bit en la línea 29, por lo que tienes el problema de que dice truncado de 32 bits a 1 bit.

Luego, por extensión, sus cálculos se optimizan a un solo valor de 1 bit (esencialmente se reduce a if >0, set to 0, else add 1 ), que solo será 0 o 1 y, por lo tanto, su count[31:1] (note que no es LSB, bit 0) sin cambios en la construcción siempre, porque los asigna a siempre 0.

También sería de ayuda declarar específicamente count_next : se asigna a un cable no existente, por lo que crea uno para ti. En algunas herramientas, por ejemplo. modelsim, esto sería un error, en otros al menos una advertencia. La forma más sencilla de hacerlo sería reemplazar assign count_next con wire [31:0] count_next .

Finalmente, como Brian señala bastante acertadamente en los comentarios, tu condicional está mal. Usted usa count_next como parte de su propia declaración de asignación que es claramente mala. Está bien hacer eso con los registros cronometrados , ya que no hay riesgo de crear un diseño que oscile a frecuencias muy altas y cause daños al FPGA. Creo que lo que quisiste decir es (count >= count_max) . Tenga en cuenta que también cambié a ser > =, esto se debe a que su conteo incluye cero; por ejemplo, count_max = 5, querría que su contador avance 0,1,2,3,4,0: observe cómo se toman 5 ciclos de reloj ¿contar de 0 a 4 y luego volver a 0?

    
respondido por el Tom Carpenter
2

Tu cuenta de cuenta se declara implícitamente. Eso significa que es un bit de ancho para el recuento [31: 1] nunca se asigna y nunca alcanzas tu recuento máximo, que también debe declararse como 32 bits en lugar de 1 bit como lo señaló Tom.

wire [31:0] count_next;
localparam count_max = 32'd50000000;  //you can use a wire but a parameter is a better description for a run time constant.

Hay otros problemas mencionados por otros.

  • count_max debe ser un parámetro (o, en este caso, un parámetro local).
  • use count no count_next en su asignación.
  • agregue un reinicio o para la síntesis de fpga solo inicialice sus registros.
  • Simular Simular Simular. Estos problemas se vuelven mucho más fáciles de depurar y mucho más evidentes en la simulación. Consulte enlace si necesita uno, pero Xilinx también incluye isim de forma gratuita en el paquete web, creo.
respondido por el davidd
0

Inicia el registro de conteo a cero y especifica el ancho correcto para el cable count_next. Debería funcionar bien una vez que realice esos cambios.

    
respondido por el alex.forencich

Lea otras preguntas en las etiquetas