I've to constraints an Lattice Semiconductor FPGA and I've some doubts about the multicycle constraint described here. I've the following RTL : Counter

Basically it is a counter that is driven by a rising edge detector. Each times that a signal rise from 0 to 1 an impulse is generated and the counter increases. This is also the VHDL code, just to be clear :

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);


    for i in 0 to capture_com_tx_data_reg'length-1 generate 

        process(clk_i, rst_i)
            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;    

            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;

I have several counter in my design. Now I want to relax the timing, so I'm wondering if I can use a "Multicycle constraint" between the source register ( capture_com_rx_start_byte_reg_edge ) and the destination register ( capture_com_rx_packet_counter ) because I don't need that the counter is updated after the rising of capture_com_tx_start_byte_reg.

My only concern is that the generated impulse could last more than a clock cycle that could be a problem because the counter could be increased more than 1 unit.

  • \$\begingroup\$ Maybe I get it how it should be done a multicycle. I think I have to use a clock enable to be sure that during the multicycle my process works only one clock time. Does it sound reasonable to you ? \$\endgroup\$ – haster8558 Jun 4 '15 at 8:52

When using multicycles, you must be careful that the path is indeed multicycle-safe. In your case, the lack of clock-enable on capture_com_rx_packet_counter would make it "unsafe". It should be possible to force the synthesis tool to use a flip-flop primitive with a clock-en, which would be the first step to multicycle.

However, while multicycle is very useful to relax timings, I would only recommend it if it's your last solution. Is that path really problematic? Does it fail timings? Is every other path significantly faster?

You can also cut the timings with VHDL code. An example which does the addition in 2 cycles (input must be stable 2 cycles, output is only valid on the second cycle):

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

    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);
| improve this answer | |
  • \$\begingroup\$ Actually the path isn't so problematic, it match the time without any problem at the moment. I'm designing only a module that will be added to a project. So I want to have a solution to a possible problem. I've never use a multicycle so I've tryed. My only concern was the clock enable, but I've understood and you have confirmed that it's mandatory to be safe. The mapper recognizes the multicycle paths and at the moment everythings works fine. Thank you. \$\endgroup\$ – haster8558 Jun 4 '15 at 15:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.