6 votos

Problema con el reloj de la Spartan 6

Tengo un divisor de reloj implementado de la siguiente manera:

module sync_out(
  input clk,            // This is the FPGA system clock
  output reg sync       // This is the generated sync signal to be tested
);
  localparam
    SYNC_OUT_CLOCK_RATIO = 20;

  reg [10:0] counter;   // Clock counter reset when reaching CLOCK_RATIO

  initial begin
    counter <= 0;
    sync <= 0;
  end

  always @(posedge clk) begin
    counter <= counter + 1;

    if(counter == SYNC_OUT_CLOCK_RATIO) begin
      counter <= 0;
      sync <= ~sync;
    end
  end
endmodule

Aquí clk es el reloj principal, y sync es el reloj dividido que sale directamente de la placa. Ahora ISE me da el siguiente error:

Place:1136 - This design contains a global buffer instance,
   <clock_deskew_0/BUFG_inst>, driving the net, <clk>, that is driving the
   following (first 30) non-clock load pins.
   < PIN: sync_apbinterface_0/pclk_test_select[15]_AND_253_o4.A4; >
   This is not a recommended design practice in Spartan-6 due to limitations in
   the global routing that may cause excessive delay, skew or unroutable
   situations.  It is recommended to only use a BUFG resource to drive clock
   loads. If you wish to override this recommendation, you may use the
   CLOCK_DEDICATED_ROUTE constraint (given below) in the .ucf file to demote
   this message to a WARNING and allow your design to continue.
   < PIN "clock_deskew_0/BUFG_inst.O" CLOCK_DEDICATED_ROUTE = FALSE; >

¿Cuál es exactamente el problema y cómo puedo solucionarlo?

7voto

Mark Puntos 1998

En general, no deberías escribir los separadores así. Estás creando una señal de reloj a partir de la lógica, lo cual, como te dice el ISE, no es una práctica de diseño recomendada. No sólo estás consumiendo redes de enrutamiento de reloj (a menudo escasas), sino que también puedes terminar con relojes con interferencias, ya que los bloques lógicos se ondulan a través de su siguiente estado.

ejemplos (en VHDL, lo prefiero a Verilog, pero es un ejemplo bastante simple)

p. ej. 1: cómo NO para hacerlo (crear un reloj a partir de las salidas lógicas):

signal counter: integer range 0 to 999;
signal slowclk: std_logic;

gen_slowclk: process(clk, rst)
begin
    if rising_edge(clk) then
        if counter = 0 then
            slow_clk <= not slow_clk;
            counter <= counter'high
        else
            counter <= counter - 1;
        end if;
    end if;

    if rst = '1' then
        slow_clk <= '0';
        counter = counter'high;
    end if;
end process;

use_slow_clk: process(slow_clk, rst)
begin
    if rising_edge(slow_clk) then
        -- ...
    end if;

    if reset = '1' then
        -- ...
    end if;
end process;

Esto crea un slow_clk que es 1000 veces más lento que el reloj principal, y luego utiliza esa señal slow_clk como la entrada de reloj en otro proceso. Es un ejemplo de cómo no hacer las cosas. Si examinas tu RTL verás que la salida de la lógica va a las entradas de reloj de los FFs en el proceso use_slow_clk, lo cual es malo.

Lo que deberías hacer en su lugar es crear un reloj que te permita. Se conduce toda la lógica con el reloj original (rápido), y luego se crea una señal de habilitación de reloj. La mayoría de las FPGAs tienen primitivas de flip-flop que tienen entradas de habilitación de reloj, que es exactamente la razón por la que se diseñaría de esta manera.

Por ejemplo, 2: Utilizar la activación del reloj (la forma recomendada):

signal counter: integer range 0 to 999;
signal slow_ce: std_logic;

gen_slow_ce: process(clk, rst)
begin
    if rising_edge(clk) then
        if counter = 0 then
            slow_ce <= '1';
            counter <= counter'high
        else
            slow_ce <= '0';
            counter <= counter - 1;
        end if;
    end if;

    if rst = '1' then
        slow_ce <= '0';
        counter = counter'high;
    end if;
end process;

use_slow_ce: process(clk, rst)
begin
    if rising_edge(clk) then
        if slow_ce = '1' then
            -- ...
        end if;
    end if;

    if reset = '1' then
        -- ...
    end if;
end process;

Si examina la RTL de este tipo de construcción, verá que todos los FFs utilizan la misma señal de reloj, y que se proporciona en una red de reloj. El agregado @if slow_ce = '1'@ es reconocido por el sintetizador e instala un FF con una habilitación de reloj; esta es una señal que está diseñada para ser controlada con la lógica y para abrir limpiamente el FF.

En ambos ejemplos, la lógica en @use_slow_*@ se ejecuta a la misma frecuencia (1/1000 el reloj principal) pero en el segundo caso sólo tienes una red de reloj y estás haciendo uso de las habilitaciones de reloj presentes en tu FPGA, lo que lleva a una mejor síntesis, mejores relojes y un cierre de temporización más fácil. Esto lleva a diseños de FPGA más sanos que llevan a diseñadores de FPGA felices. :-)

5voto

Martin Thompson Puntos 6509

Su clk está manejando algunos pines que no son de reloj (entradas de LUT por lo que parece). Esto es casi siempre una mala idea.

Abra su diseño en el visor de tecnología y mire los "pines de carga no reloj" que aparecen en el archivo de registro ( < PIN: sync_apbinterface_0/pclk_test_select[15]_AND_253_o4.A4; > es el primero) y ver si puedes averiguar por qué una LUT está utilizando la entrada CLK.

Si resulta que todo está bien y realmente quieres hacer esto, por la razón que sea, y vas a ser feliz justificándolo ante una jauría de ingenieros si todo sale mal, puedes desactivar el error como se describe al final del mensaje de error.

3voto

MozenRath Puntos 118

Tal vez haya un problema con las dos asignaciones simultáneas a counter . Vea si al cambiar su always bloque a esto ayuda:

  always @(posedge clk) begin
    if(counter == SYNC_OUT_CLOCK_RATIO) begin
      counter <= 0;
      sync <= ~sync;
    end else begin
      counter <= counter + 1;
    end
  end

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X