Multiciclo: ¿Es posible?

Tengo que restringir una FPGA de Lattice Semiconductor y tengo algunas dudas acerca de la restricción multiciclo descrita aquí . Tengo el siguiente RTL:Encimera

Básicamente se trata de un contador accionado por un detector de flanco ascendente. Cada vez que una señal sube de 0 a 1 se genera un impulso y el contador aumenta. Este es también el código VHDL, para que quede claro:

type COM_PACKETS_COUNTER is array ( 7 downto 0) of std_logic_vector(31 downto 0);
signal capture_com_tx_packet_counter : COM_PACKETS_COUNTER;
signal capture_com_rx_packet_counter : COM_PACKETS_COUNTER;
signal capture_com_tx_data_reg : std_logic_vector(7 downto 0);
signal capture_com_rx_data_reg : std_logic_vector(7 downto 0);

signal capture_com_tx_start_byte_reg : std_logic_vector(7 downto 0);
signal capture_com_rx_start_byte_reg : std_logic_vector(7 downto 0);    
signal capture_com_tx_start_byte_reg_delay : std_logic_vector(7 downto 0);
signal capture_com_rx_start_byte_reg_delay : std_logic_vector(7 downto 0);
signal capture_com_tx_start_byte_reg_edge : std_logic_vector(7 downto 0);
signal capture_com_rx_start_byte_reg_edge : std_logic_vector(7 downto 0);

..........................

COM_COUNTER_PROCESS : 
    for i in 0 to capture_com_tx_data_reg'length-1 generate 

        process(clk_i, rst_i)
        begin
            if rst_i = '1' then 
                capture_com_rx_start_byte_reg_delay(i) <= '0';
                capture_com_rx_start_byte_reg_edge(i) <= '0';
                capture_com_tx_start_byte_reg_delay(i) <= '0';
                capture_com_tx_start_byte_reg_edge(i) <= '0';
            elsif clk_i = '1' and clk_i'event then 
                capture_com_rx_start_byte_reg_delay(i) <= capture_com_rx_start_byte_reg(i);
                capture_com_rx_start_byte_reg_edge(i) <= not ( capture_com_rx_start_byte_reg_delay(i) ) and capture_com_rx_start_byte_reg(i) and CAPTURE_COM_RX_SELECTED_FILTER(i);
                capture_com_tx_start_byte_reg_delay(i) <= capture_com_tx_start_byte_reg(i);
                capture_com_tx_start_byte_reg_edge(i) <= not ( capture_com_tx_start_byte_reg_delay(i) ) and capture_com_tx_start_byte_reg(i) and CAPTURE_COM_TX_SELECTED_FILTER(i);
            end if;
        end process;    


        process(clk_i,rst_i)
        begin
            if rst_i = '0' then
                capture_com_tx_packet_counter(i) <= (others => '0');
            elsif clk_i'event and clk_i = '1' then
                if capture_com_tx_start_byte_reg_edge(i) = '1' then 
                    capture_com_tx_packet_counter(i) <= capture_com_tx_packet_counter(i) + 1;
                end if;
                if capture_com_rx_start_byte_reg_edge(i) = '1' then 
                    capture_com_rx_packet_counter(i) <= capture_com_rx_packet_counter(i) + 1;
                end if;
            end if;
        end process;
    end generate;

Tengo varios mostradores en mi diseño. Ahora quiero relajar el tiempo, así que me pregunto si puedo usar una "restricción de ciclo múltiple" entre el registro de origen ( capture_com_rx_start_byte_reg_edge ) y el registro de destino ( capture_com_rx_packet_counter ) porque no necesito que el contador se actualice después del aumento de capture_com_tx_start_byte_reg.

Mi única preocupación es que el impulso generado pueda durar más de un ciclo de reloj, eso podría ser un problema porque el contador podría aumentar más de 1 unidad.

Tal vez lo entiendo como se debe hacer un multiciclo. Creo que tengo que usar una habilitación de reloj para asegurarme de que durante el multiciclo mi proceso funcione solo una vez. ¿Te suena razonable?

Respuestas (1)

Cuando utilice multiciclos, debe tener cuidado de que la ruta sea segura para multiciclos. En su caso, la falta de activación del reloj capture_com_rx_packet_counterlo haría "inseguro". Debería ser posible obligar a la herramienta de síntesis a usar una primitiva de flip-flop con un reloj-en, que sería el primer paso para multiciclo.

Sin embargo, aunque el multiciclo es muy útil para relajar los tiempos, solo lo recomendaría si es tu última solución. ¿Es ese camino realmente problemático? ¿Falla los tiempos? ¿Todos los demás caminos son significativamente más rápidos?

También puede cortar los tiempos con código VHDL. Un ejemplo que hace la suma en 2 ciclos (la entrada debe ser estable 2 ciclos, la salida solo es válida en el segundo ciclo):

signal s_lo : unsigned(16 downto 0);
signal s_hi : unsigned(15 downto 0);

process(clk)
begin
    if rising_edge(clk) then
        s_lo <= '0' & a(15 downto 0) + b(15 downto 0);
        s_hi <= a(31 downto 16) + b(31 downto 16) + s_lo(16);
    end if;
end process;

s <= s_hi & s_lo(15 downto 0);
En realidad el camino no es tan problemático, coincide con la hora sin ningún problema por el momento. Estoy diseñando solo un módulo que se agregará a un proyecto. Así que quiero tener una solución a un posible problema. Nunca he usado un multiciclo, así que lo he intentado. Mi única preocupación era la habilitación del reloj, pero lo he entendido y me has confirmado que es obligatorio para estar seguro. El mapeador reconoce las rutas multiciclo y por el momento todo funciona bien. Gracias.