3

As part of adaptations to an existing large design on Artix-7 FPGA, I implemented a simple counting mechanism, something similar to "Archticture with 'constant' ", so that in the future, I can just change the value of the constant and not worry too much about where it is used.

However, it led to several timing failures and I went back to the normal way to increment a counter, by adding a 1, which resolved the timing failures. Here are the entity and the 2 architectures that I tried synthesizing in Vivado 2016.4 tool. But the Project Summary tab in Vivado shows no resources except IO was used.! So my question is, does declaring constants in VHDL result in more hardware than usual? What is the difference between the 2 implementations?

Entity

entity counter is
Port(
      i_clk : in std_logic;
      i_rst : in std_logic;
      o_cnt : out std_logic_vector(7 downto 0)
    );
end counter;

Architecture with 'constant'

architecture Behavioral of counter is
signal s_cnt : unsigned(7 downto 0) := (others => '0');
signal s_max : unsigned(7 downto 0) := (others => '1');

constant c_INCR : unsigned(3 downto 0) := x"1";
begin
process (i_clk) begin
    if rising_edge(i_clk) then
        if i_rst = '1' then
            s_cnt <= (others => '0');
        else
            o_cnt <= std_logic_vector(s_cnt);
            if s_cnt = s_max then
                s_cnt <= (others => '0');
            else
                s_cnt <= s_cnt + c_INCR;
            end if;
        end if;
    end if;
end process;

end Behavioral;

Architecture with '+1'

architecture Behavioral of counter is
signal s_cnt : unsigned(7 downto 0) := (others => '0');
signal s_max : unsigned(7 downto 0) := (others => '1');

begin
process (i_clk) begin
    if rising_edge(i_clk) then
        if i_rst = '1' then
            s_cnt <= (others => '0');
        else
            o_cnt <= std_logic_vector(s_cnt);
            if s_cnt = s_max then
                s_cnt <= (others => '0');
            else
                s_cnt <= s_cnt + 1;
            end if;
        end if;
    end if;
end process;

end Behavioral;
Vinay Madapura
  • 327
  • 5
  • 17
  • 1
    Both implementations should produce the same synthesis result. However, the placement and routing on the FPGA could be very different (depending on how the vendor IDE controls its placement and routing process). So this could cause timing issues in one implementation. But you cannot say that using constants is generally worse. – Juergen Sep 06 '17 at 11:55
  • 2
    I tried your code in Vivado 2017.1 and the post-synthesis result was identical. – scary_jeff Sep 06 '17 at 12:06
  • (between the two architectures) – scary_jeff Sep 06 '17 at 12:19
  • In my experience a small change in the code can have a large impact on the implementation by synthesis tools. I think that is because the tools generate a random seed based on the hash of the code, which is used as a base for initial logic placement. The optimization of the synthesis tools is never perfect, thus a different start state will have a different end state. – JHBonarius Sep 06 '17 at 14:07
  • Could be due to the fact that your constant is 4 bits while your '+1' can be interpreted by your synthesizer as a simpler incrementer. But if this is the reason, it proves that your synthesizer is not really the best for constants propagation... You could check this by redefining your constant as the `1` integer and/or the `'1'` `std_ulogic`. – Renaud Pacalet Sep 06 '17 at 15:55

0 Answers0