Empaquetando pares de registros en el segmento FPGA de Lattice. ¿Cómo?

0

En mi diseño (Lattice MachXO2 FPGA) uso muchos registros establecidos por una señal y restablecidos por otro (ambos sincronizados con el reloj), como este:

process(Clk)
  if rising_edge(Clk) then
    if set_condition = '1' then
      flag <= '1';
    elsif reset_condition = '1' then
      flag <= '0';
    end if;
  end if;
end process

Esto se sintetiza en un registro (marca) con sus entradas CE y D controladas por una LUT cada una. También probé código como este:

process(Clk)
  if rising_edge(Clk) then
    o1 <= i1;
  end if;
end process;
i1 <= '1' when set_condition = '1' else
      '0' when reset_condition = '1' else o1;

Esto se sintetiza en un registro (indicador) con su LSR siendo controlado por la señal establecida y la entrada D controlada por una LUT como un mux de realimentación. Dado que el FPGA se asigna por segmentos y cada uno tiene dos LUT4 y dos registros, ambas implementaciones comparten un problema común (para mí) en el sentido de que utilizan las entradas de control de registro, que son comunes a ambos. Esto evita usar el segundo registro en un sector para otro propósito, desperdiciando esto y haciendo que mi diseño falle en el mapa por falta de segmentos (tengo alrededor del 80% de los registros utilizados, el 90% de LUT4s y el 103% de los sectores).

Para resolver esto, probé una solución mux de realimentación inspirada en componentes que utiliza una sola LUT para controlar la entrada del registro, sin utilizar las entradas CE o LSR. Para verificar la solución que he probado con dos registros (solo uno que se muestra a continuación), se debe empaquetar en una sola porción. Pero no lo son, cada registro usa su propia porción.

d1: FD1S3AX
  port map 
  (
    CK => Clk,
    D => i1,
    Q => o1
  );
l1: LUT4
  generic map
  (
    INIT => b"1111_0010_0011_0010"
  )
  port map
  (
    A => High,
    B => En1,
    C => Dis1,
    D => o1,
    Z => i1
  );

Desde entonces he encontrado una solución parcial, agregando comandos LOCATE al archivo LPF. Al hacerlo, puedo obtener dos registros en la misma porción, pero tengo que nombrar la porción, fijándola en el tejido FPGA.

LOCATE COMP "d1" SITE "R3C40A";
LOCATE COMP "d2" SITE "R3C40A";
LOCATE COMP "i1" SITE "R3C40A";
LOCATE COMP "i2" SITE "R3C40A";

Ya que no quiero hacer P & R, todo el diseño a mano, ¿hay una manera de agrupar pares de LUT y registros en la misma porción pero permitiéndoles flotar en todo el dispositivo?

    
pregunta Carlos Azevedo

1 respuesta

0

Si desea un reinicio asíncrono, separado para cada registro, es probable que sea imposible ya que ambos registros comparten una sola entrada LSR.

Si solo está buscando operaciones síncronas, como muestra su código, puede probar algunos de los primitivos de cierre de esta library . Eso haría que la síntesis fuera inequívoca y se asignara directamente a un cierre de hardware sin lógica ni restricciones adicionales.

Otra opción es crear un script que genere archivos de restricción de ubicación para usted. Lo hice para un circuito de tiempo con herramientas de microsemi, puede ser fácil si tienes estructuras repetitivas. Tenía un gran margen de recursos, por lo que no estoy seguro de si eso podría funcionar para usted.

    
respondido por el pserra

Lea otras preguntas en las etiquetas