输出 IOBUF 上的多个驱动网。

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

Multiple Driver Nets on output of IOBUF

问题

我编写了以下模块,它将充当标准4线SPI和AD9637 ADC的3线SPI之间的开关。

因此,我实例化了一个IOBUF,在第16个时钟周期之后,计算时钟边缘的数量,并将IOBUF从输出切换到输入,ADC开始在共享线上输出数据的地方。

然而,我在尝试在Vivado 2019.1中实现设计时遇到了“多个驱动器网络”错误,我无法理解为什么会发生这种情况,因为在我的描述中,受影响的信号io_SDIO只受到实例化的IOBUF的IO引脚的驱动。

完整的错误如下:

  1. [DRC MDRV-1] 多个驱动器网络:网络zsys_i/SPI_3wire_adapter_AD_0/U0/o_MISO有多个驱动器:zsys_i/SPI_3wire_adapter_AD_0/U0/IOBUF_inst/IBUF/Ozsys_i/SPI_3wire_adapter_AD_0/U0/o_MISO_reg/Q

完整的设计如下:

  1. library IEEE;
  2. use IEEE.STD_LOGIC_1164.ALL;
  3. use IEEE.NUMERIC_STD.ALL;
  4. Library UNISIM;
  5. use UNISIM.vcomponents.all;
  6. entity SPI_3wire_adapter_AD9637 is
  7. port (
  8. o_count : out std_logic_vector(4 downto 0);
  9. o_enable : out std_logic;
  10. i_SCLK : in STD_LOGIC; --PS side clock on which the module operates syncronously
  11. i_MOSI : in STD_LOGIC; --MOSI PS side (input)
  12. o_MISO : out STD_LOGIC; --MISO PS side (output)
  13. i_CS : in STD_LOGIC; --CS PS side (input)
  14. o_SCLK : out std_logic; --SPI clock (output)
  15. o_CS : out std_logic; --SPI CS (output)
  16. io_SDIO : inout STD_LOGIC --SPI SDIO - shared MOSI/MISO for 3-wire SPI (output/input)
  17. );
  18. end SPI_3wire_adapter_AD9637;
  19. architecture behavioral of SPI_3wire_adapter_AD9637 is
  20. signal s_CLK_count: integer range 0 to 23 := 0;
  21. signal s_N_enable_output : STD_LOGIC := '0';
  22. begin
  23. IOBUF_inst : IOBUF
  24. generic map (
  25. DRIVE => 12,
  26. IOSTANDARD => "DEFAULT",
  27. SLEW => "SLOW")
  28. port map (
  29. O => o_MISO, -- Buffer output
  30. IO => io_SDIO, -- Buffer inout port (connect directly to top-level port)
  31. I => i_MOSI, -- Buffer input
  32. T => s_N_enable_output -- 3-state enable input, high=input, low=output
  33. );
  34. o_CS <= i_CS;
  35. o_SCLK <= i_SCLK;
  36. o_count <= std_logic_vector(to_unsigned(s_CLK_count, 5));
  37. o_enable <= s_N_enable_output;
  38. process(i_SCLK, i_CS)
  39. begin
  40. if falling_edge(i_CS) then
  41. -- 重置CLK_count并将IOBUF切换到输出模式
  42. s_CLK_count <= 0;
  43. s_N_enable_output <= '0'; -- IOBUF设置为输出模式
  44. end if;
  45. if falling_edge(i_SCLK) then
  46. if s_CLK_count = 16 then
  47. -- 在第16个时钟边沿上切换到输入模式
  48. s_N_enable_output <= '1'; -- IOBUF设置为输入模式
  49. end if;
  50. -- 在所有下降的时钟边沿上,如果处于活动状态,则增加CLK_count
  51. if i_CS = '0' then
  52. s_CLK_count <= s_CLK_count + 1;
  53. end if;
  54. if i_CS = '1' then
  55. -- 使用下降的时钟边沿重置系统,如果处于非活动状态,即CS == 1
  56. s_N_enable_output <= '1'; -- IOBUF设置为输入模式
  57. end if;
  58. end if;
  59. end process;
  60. end behavioral;

我对设计的方法是创建一个信号s_N_enable_output,表示IOBUF的期望输入/输出模式,并仅使用这个信号驱动IOBUF的T引脚。通过仅将共享数据线映射到inout端口,而不在进程中直接驱动它,我希望避免出现这种“多个驱动器网络”的错误。

编辑:我忽略了o_MISO引脚上的另一个“多个驱动器网络”错误:

  1. [DRC MDRV-1] 多个驱动器网络:网络zsys_i/SPI_3wire_adapter_AD_0/U0/o_MISO有多个驱动器:zsys_i/SPI_3wire_adapter_AD_0/U0/IOBUF_inst/IBUF/Ozsys_i/SPI_3wire_adapter_AD_0/U0/o_MISO_reg/Q
英文:

I wrote the following module which shall act as a switch between a standard 4-wire SPI and the 3-wire SPI of an AD9637 ADC.
Therefore I instantiated an IOBUF, count clock edges and switch the IOBUF from output to input after the 16th clock cycle, where the ADC starts to put out data on the shared line.
However, I get e Multiple Driver Nets error, trying to implement the design in Vivado 2019.1 and I cannot wrap my head around why this happens, as in my description, the affected signal io_SDIO is only driven by the IO pin of the instantiated IOBUF.
The full error is

  1. [DRC MDRV-1] Multiple Driver Nets: Net zsys_i/SPI_3wire_adapter_AD_0/U0/o_MISO has multiple drivers: zsys_i/SPI_3wire_adapter_AD_0/U0/IOBUF_inst/IBUF/O, and zsys_i/SPI_3wire_adapter_AD_0/U0/o_MISO_reg/Q.

The full design is

  1. library IEEE;
  2. use IEEE.STD_LOGIC_1164.ALL;
  3. use IEEE.NUMERIC_STD.ALL;
  4. Library UNISIM;
  5. use UNISIM.vcomponents.all;
  6. entity SPI_3wire_adapter_AD9637 is
  7. port (
  8. o_count : out std_logic_vector(4 downto 0);
  9. o_enable : out std_logic;
  10. i_SCLK : in STD_LOGIC; --PS side clock on which the module operates syncronously
  11. i_MOSI : in STD_LOGIC; --MOSI PS side (input)
  12. o_MISO : out STD_LOGIC; --MISO PS side (output)
  13. i_CS : in STD_LOGIC; --CS PS side (input)
  14. o_SCLK : out STD_LOGIC; --SPI clock (output)
  15. o_CS : out STD_LOGIC; --SPI CS (output)
  16. io_SDIO : inout STD_LOGIC --SPI SDIO - shared MOSI/MISO for 3-wire SPI (output/input)
  17. );
  18. end SPI_3wire_adapter_AD9637;
  19. architecture behavioral of SPI_3wire_adapter_AD9637 is
  20. signal s_CLK_count: integer range 0 to 23 := 0;
  21. signal s_N_enable_output : STD_LOGIC := &#39;0&#39;;
  22. begin
  23. IOBUF_inst : IOBUF
  24. generic map (
  25. DRIVE =&gt; 12,
  26. IOSTANDARD =&gt; &quot;DEFAULT&quot;,
  27. SLEW =&gt; &quot;SLOW&quot;)
  28. port map (
  29. O =&gt; o_MISO, -- Buffer output
  30. IO =&gt; io_SDIO, -- Buffer inout port (connect directly to top-level port)
  31. I =&gt; i_MOSI, -- Buffer input
  32. T =&gt; s_N_enable_output -- 3-state enable input, high=input, low=output
  33. );
  34. o_CS &lt;= i_CS;
  35. o_SCLK &lt;= i_SCLK;
  36. o_count &lt;= std_logic_vector(to_unsigned(s_CLK_count, 5));
  37. o_enable &lt;= s_N_enable_output;
  38. process(i_SCLK, i_CS)
  39. begin
  40. if falling_edge(i_CS) then
  41. -- Reset CLK_count and turn IOBUF into output mode
  42. s_CLK_count &lt;= 0;
  43. s_N_enable_output &lt;= &#39;0&#39;; -- set IOBUF to output mode
  44. end if;
  45. if falling_edge(i_SCLK) then
  46. if s_CLK_count = 16 then
  47. -- on the 16th clk edge switch to input mode
  48. s_N_enable_output &lt;= &#39;1&#39;; -- set IOBUF to input mode
  49. end if;
  50. -- on all falling clk edges increment the CLK_count if active
  51. if i_CS = &#39;0&#39; then
  52. s_CLK_count &lt;= s_CLK_count + 1;
  53. end if;
  54. if i_CS = &#39;1&#39; then
  55. -- use the falling clk edges to reset the system if inactive, i.e., CS == 1
  56. s_N_enable_output &lt;= &#39;1&#39;; -- set IOBUF to input modde
  57. end if;
  58. end if;
  59. end process;
  60. end behavioral;

My approach to the design was to create a signal s_N_enable_output which represents the desired input/output mode of the IOBUF and drive the T pin of the IOBUF with this signal only. By onyl mapping the shared data line to the inout port and not driving it directly in the process I was hoping to avoid such Multiple Driver Nets errors.

EDIT: I have overlooked that there is another Multiple Driver Nets error on the o_MISO pin:

  1. [DRC MDRV-1] Multiple Driver Nets: Net zsys_i/SPI_3wire_adapter_AD_0/U0/o_MISO has multiple drivers: zsys_i/SPI_3wire_adapter_AD_0/U0/IOBUF_inst/IBUF/O, and zsys_i/SPI_3wire_adapter_AD_0/U0/o_MISO_reg/Q.

答案1

得分: 0

我通过引入中间信号 s_CLK_count_greater_15 并在一个进程中处理所有的 "状态变化",使设计适用于综合和实现:

  1. library IEEE;
  2. use IEEE.STD_LOGIC_1164.ALL;
  3. use IEEE.NUMERIC_STD.ALL;
  4. Library UNISIM;
  5. use UNISIM.vcomponents.all;
  6. entity SPI_3wire_adapter_AD9637 is
  7. port (
  8. o_count : out std_logic_vector(4 downto 0);
  9. o_enable : out std_logic;
  10. i_SCLK : in STD_LOGIC; --PS side clock on which the module operates synchronously
  11. i_MOSI : in STD_LOGIC; --MOSI PS side (input)
  12. o_MISO : out STD_LOGIC; --MISO PS side (output)
  13. i_CS : in STD_LOGIC; --CS PS side (input)
  14. o_SCLK : out STD_LOGIC; --SPI clock (output)
  15. o_CS : out std_logic; --SPI CS (output)
  16. io_SDIO : inout STD_LOGIC --SPI SDIO - shared MOSI/MISO for 3-wire SPI (output/input)
  17. );
  18. end SPI_3wire_adapter_AD9637;
  19. architecture behavioral of SPI_3wire_adapter_AD9637 is
  20. signal s_CLK_count: integer range 0 to 23 := 0;
  21. signal s_IN_notOUT : STD_LOGIC;
  22. signal s_CLK_count_greater_15 : STD_LOGIC;
  23. begin
  24. IOBUF_inst : IOBUF
  25. generic map (
  26. DRIVE => 12,
  27. IOSTANDARD => "DEFAULT",
  28. SLEW => "SLOW")
  29. port map (
  30. O => o_MISO, -- Buffer output
  31. IO => io_SDIO, -- Buffer inout port (connect directly to top-level port)
  32. I => i_MOSI, -- Buffer input
  33. T => s_IN_notOUT -- 3-state enable input, high=input, low=output
  34. );
  35. o_CS <= i_CS;
  36. o_SCLK <= i_SCLK;
  37. o_count <= std_logic_vector(to_unsigned(s_CLK_count, 5));
  38. s_IN_notOUT <= not i_CS and s_CLK_count_greater_15;
  39. o_enable <= s_IN_notOUT;
  40. process(i_SCLK)
  41. begin
  42. if falling_edge(i_SCLK) then
  43. if i_CS = '1' then
  44. s_CLK_count <= 0;
  45. else
  46. s_CLK_count <= s_CLK_count + 1; -- on all falling clk edges increment the CLK_count if CS is low
  47. end if;
  48. if s_CLK_count > 15 then
  49. s_CLK_count_greater_15 <= '1';
  50. else
  51. s_CLK_count_greater_15 <= '0';
  52. end if;
  53. end if;
  54. end process;
  55. end behavioral;
英文:

I made the design suitable for synthesis and implementation by introducing an intermidiate signal s_CLK_count_greater_15 and handling all the "state changes" in one process:

  1. library IEEE;
  2. use IEEE.STD_LOGIC_1164.ALL;
  3. use IEEE.NUMERIC_STD.ALL;
  4. Library UNISIM;
  5. use UNISIM.vcomponents.all;
  6. entity SPI_3wire_adapter_AD9637 is
  7. port (
  8. o_count : out std_logic_vector(4 downto 0);
  9. o_enable : out std_logic;
  10. i_SCLK : in STD_LOGIC; --PS side clock on which the module operates syncronously
  11. i_MOSI : in STD_LOGIC; --MOSI PS side (input)
  12. o_MISO : out STD_LOGIC; --MISO PS side (output)
  13. i_CS : in STD_LOGIC; --CS PS side (input)
  14. o_SCLK : out STD_LOGIC; --SPI clock (output)
  15. o_CS : out STD_LOGIC; --SPI CS (output)
  16. io_SDIO : inout STD_LOGIC --SPI SDIO - shared MOSI/MISO for 3-wire SPI (output/input)
  17. );
  18. end SPI_3wire_adapter_AD9637;
  19. architecture behavioral of SPI_3wire_adapter_AD9637 is
  20. signal s_CLK_count: integer range 0 to 23 := 0;
  21. signal s_IN_notOUT : STD_LOGIC;
  22. signal s_CLK_count_greater_15 : STD_LOGIC;
  23. begin
  24. IOBUF_inst : IOBUF
  25. generic map (
  26. DRIVE =&gt; 12,
  27. IOSTANDARD =&gt; &quot;DEFAULT&quot;,
  28. SLEW =&gt; &quot;SLOW&quot;)
  29. port map (
  30. O =&gt; o_MISO, -- Buffer output
  31. IO =&gt; io_SDIO, -- Buffer inout port (connect directly to top-level port)
  32. I =&gt; i_MOSI, -- Buffer input
  33. T =&gt; s_IN_notOUT -- 3-state enable input, high=input, low=output
  34. );
  35. o_CS &lt;= i_CS;
  36. o_SCLK &lt;= i_SCLK;
  37. o_count &lt;= std_logic_vector(to_unsigned(s_CLK_count, 5));
  38. s_IN_notOUT &lt;= not i_CS and s_CLK_count_greater_15;
  39. o_enable &lt;= s_IN_notOUT;
  40. process(i_SCLK)
  41. begin
  42. if falling_edge(i_SCLK) then
  43. if i_CS = &#39;1&#39; then
  44. s_CLK_count &lt;= 0;
  45. else
  46. s_CLK_count &lt;= s_CLK_count + 1; -- on all falling clk edges increment the CLK_count if CS is low
  47. end if;
  48. if s_CLK_count &gt; 15 then
  49. s_CLK_count_greater_15 &lt;= &#39;1&#39;;
  50. else
  51. s_CLK_count_greater_15 &lt;= &#39;0&#39;;
  52. end if;
  53. end if;
  54. end process;
  55. end behavioral;

huangapple
  • 本文由 发表于 2023年6月14日 23:55:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/76475452.html
匿名

发表评论

匿名网友

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

确定