Vivado VHDL锁存器去除

huangapple go评论84阅读模式
英文:

Vivado VHDL latch removal

问题

在综合项目时,Vivado指出除了W_FILTER进程使用的internal_regChannelinternal_memAddress外,所有信号上都存在6个隐含的锁存器。这可能是由于逻辑不完整或条件不明确导致的。要解决这个问题,你需要确保在所有可能情况下,信号都有明确定义的值。

另外,确保在所有条件分支中,所有的信号都有被赋值。根据你提供的代码,你可能需要在适当的条件下为这些信号提供默认值,以避免综合工具推断锁存器。最好的方式是在每个条件下都明确地赋值,确保所有的分支都被覆盖。

希望这能帮到你解决问题!

英文:

I'm using VHDL and Vivado for a sort of clocked filter that reads one bit at a time from an i_w channel when an input i_start is given and stays active, converting it into a memory address from which it then reads, and finally it loads the value inside of the address in one of four different registers, also depending on the first two bits read of the i_w signal, and outputs a "done" signal to notify that it has finished.

I've created an internal counter that keeps track of how many clock cycles have elapsed from the reading start.

  1. architecture rtl of project is
  2. --Counter
  3. signal internal_counter: std_logic_vector(4 downto 0);
  4. signal internal_done: std_logic := '0';
  5. --Addresses
  6. signal internal_regChannel: std_logic_vector(1 downto 0);
  7. signal internal_memAddress: std_logic_vector(15 downto 0);
  8. --Registry Bank
  9. signal internal_regValue0: std_logic_vector(7 downto 0);
  10. signal internal_regValue1: std_logic_vector(7 downto 0);
  11. signal internal_regValue2: std_logic_vector(7 downto 0);
  12. signal internal_regValue3: std_logic_vector(7 downto 0);
  13. begin
  14. COUNTER: process(i_clk)
  15. begin
  16. if i_rst ='1' then
  17. --reset the counter
  18. internal_counter <= (others => '0');
  19. internal_done <= '0';
  20. else
  21. if i_clk = '1' and i_start = '1' then
  22. --start counting
  23. internal_counter <= internal_counter + 1;
  24. internal_done <= '0';
  25. else
  26. internal_counter <= internal_counter;
  27. end if;
  28. if i_clk = '1' and internal_counter /= "00000" then
  29. --keep counting
  30. internal_counter <= internal_counter + 1;
  31. internal_done <= '0';
  32. end if;
  33. if i_clk = '1' and internal_counter = "10100" then
  34. --the counter has finished
  35. --count for one more cycle so then the done signal can be put back to 0
  36. internal_counter<= internal_counter + 1;
  37. internal_done <= '1';
  38. end if;
  39. if i_clk = '1' and internal_counter = "10101" then
  40. internal_counter <= "00000";
  41. internal_done <= '0';
  42. end if;
  43. end if;
  44. end process;
  45. W_FILTER: process(i_clk)
  46. begin
  47. if i_rst ='1' then
  48. internal_memAddress <= (others => '0');
  49. internal_regChannel <= (others => '0');
  50. else
  51. if i_clk = '1' and i_clk'event then
  52. if i_start = '1' and internal_counter < "00010" then
  53. --generate the registry Flag
  54. internal_regChannel <= internal_regChannel(0) & i_w;
  55. else if i_start = '1' and internal_counter >= "00010" then
  56. --generate the memory Address
  57. internal_memAddress <= internal_memAddress(14 downto 0) & i_w;
  58. end if;
  59. end if;
  60. if i_start = '0' and internal_counter > "00000" then
  61. --memory address is safe to output
  62. o_mem_addr <= internal_memAddress;
  63. end if;
  64. if internal_done = '1' then
  65. internal_memAddress <= (others => '0');
  66. internal_regChannel <= (others => '0');
  67. end if;
  68. end if;
  69. end if;
  70. end process;
  71. REG_BANK: process(i_clk)
  72. begin
  73. if i_rst = '1' then
  74. internal_regValue0 <= (others => '0');
  75. internal_regValue1 <= (others => '0');
  76. internal_regValue2 <= (others => '0');
  77. internal_regValue3 <= (others => '0');
  78. else
  79. if internal_counter = "10100" then
  80. case internal_regChannel is
  81. when "00" =>
  82. internal_regValue0 <= i_mem_data;
  83. when "01" =>
  84. internal_regValue1 <= i_mem_data;
  85. when "10" =>
  86. internal_regValue2 <= i_mem_data;
  87. when "11" =>
  88. internal_regValue3 <= i_mem_data;
  89. when others =>
  90. --placeholder; others condition can never occur
  91. internal_regValue0 <= i_mem_data;
  92. end case;
  93. end if;
  94. end if;
  95. end process;
  96. o_done <= internal_done;
  97. end rtl;

However, when synthesizing the project, Vivado signals 6 inferred latches on all the signals, except for the one used by the W_FILTER process, internal_regChannel and internal_memAddress.

  1. WARNING: [Synth 8-327] inferring latch for variable 'internal_done_reg' [C:/.../project.vhd:57]
  2. WARNING: [Synth 8-327] inferring latch for variable 'internal_regValue0_reg' [C:/.../project.vhd:114]
  3. WARNING: [Synth 8-327] inferring latch for variable 'internal_regValue1_reg' [C:/.../project.vhd:115]
  4. WARNING: [Synth 8-327] inferring latch for variable 'internal_regValue2_reg' [C:/.../project.vhd:116]
  5. WARNING: [Synth 8-327] inferring latch for variable 'internal_regValue3_reg' [C:/.../project.vhd:117]
  6. WARNING: [Synth 8-327] inferring latch for variable 'internal_counter_reg' [C:/.../project.vhd:56]

I tried looking at the lines of code listed in the warnings, and I tried to follow what little guidance I could find online, but I still fail to understand what I should be doing to fix this issue.

答案1

得分: 2

To properly synthesize clocked registers, make the process sensitive to the rising clock edge. You don't have this issue for the second process because there you use i_clk = '1' and i_clk'event.

But in the first process you use:

  1. else
  2. if i_clk = '1' and i_start = '1' then

Change it to

  1. elsif i_clk = '1' and i_clk'event then
  2. if i_start = '1' then

or better

  1. elsif rising_edge(i_clk) then
  2. if i_start = '1' then

(see: https://stackoverflow.com/questions/15205202/clkevent-vs-rising-edge)

英文:

To properly synthesize clocked registers, make the process sensitive to the rising clock edge. You don't have this issue for the second process because there you use i_clk = '1' and i_clk'event.

But in the first process you use:

> else
> if i_clk = '1' and i_start = '1' then

Change it to

  1. elsif i_clk = '1' and i_clk'event then
  2. if i_start = '1' then

or better

  1. elsif rising_edge(i_clk) then
  2. if i_start = '1' then

(see: https://stackoverflow.com/questions/15205202/clkevent-vs-rising-edge)

huangapple
  • 本文由 发表于 2023年5月10日 20:04:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/76218187.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定