错误 (10028):无法解析 I2C_com.vhd 处净"sda"的多个常量驱动程序 (185)



我正在尝试进行自己的 I2C 通信,但我在乘法驱动程序方面遇到了问题,这并不是说我不理解它们,我只是看不到它们(我对 VHDL 仍然很新鲜(,所以请看看我的代码并告诉我为什么会有这样的错误。

我尝试在标志上操作以在总线上有多个信号驱动器,但有些地方不对劲。多个驱动程序位于 scl、sda、start_clk 和 stop_clk 上。例如,是因为这些标志在两个不同的进程中吗?

        library ieee;
    use ieee.std_logic_1164.all;
    use ieee.numeric_std.all;
    entity I2C_com is

    port (
    reset_en: in std_logic;  
    clk: in std_logic;  
    sda: inout std_logic;   
    scl: out std_logic;    
    RD:in std_logic;       
    WR: in std_logic;       
    addr: buffer std_logic_vector(7 downto 0) 

    );
    end I2C_com;

    architecture MAIN of I2C_com  is
    signal data :std_logic_vector (12 downto 0):="0000000000010"; 
    signal i2c_clk: std_logic ;  
    signal clk_count : unsigned(19 downto 0):="00000000000000000100"; 
    type program_state is (start,init,error_rd_wr,slave,ack);
    signal state: program_state;
    signal write_data: std_logic_vector (7 downto 0):=(others => '0'); 
   signal read_data: std_logic_vector (7 downto 0):=(others => '0'); 
    signal clk_enable: std_logic; 
    signal reset: std_logic:='1'; 
    signal start_clk: std_logic:= 'Z'; 
    signal stop_clk: std_logic:= 'Z';   
    signal strech: std_logic := '0';
    signal cnt_addr: integer := 0; 
    signal ack_error: std_logic; 
    signal sda_data: std_logic; 
    signal start_data: std_logic:= 'Z'; 
    begin

    i2c_clock: process(clk,reset_en,reset)
    begin

    if reset_en = '1' or reset = '1' then 

    elsif falling_edge(clk) then
    if clk_count < unsigned(data) then  
    clk_count <= clk_count + 1;
    clk_enable <= '1';
    else
    clk_count <= x"00000";
    clk_enable <= '0';
    end if;
    i2c_clk <= clk_enable;
    if start_clk = '1'  then
    sda <= '0';
    scl <= '0';
    start_clk <= '0';
    end if;
    if stop_clk = '1'  then
    sda <= '0';
    scl <= '0';
    stop_clk <= '0';
    end if;
    end if; 
    end process i2c_clock;
    --
    process(i2c_clk,reset_en,reset)

    begin

    if reset_en = '1' or reset = '1' then
    reset <= '0';       
    cnt_addr <= 0;
    state <= init;  

    elsif rising_edge(i2c_clk) then

    case state is

    when init =>                                    
    if RD = '1' or WR = '1' then      
    state <= start;
    else
    state <= error_rd_wr;
    end if;
    when start =>                   
    start_clk <= '1';
    state <= slave;

    when slave =>                               
    start_data <= '1';
    if cnt_addr < 8 then
    sda_data <= addr(cnt_addr);
    cnt_addr <= cnt_addr + 1;
    else
    cnt_addr <= 0;
    state <= ack;
    end if;
    when error_rd_wr =>             
    reset <= '1';
    when ack =>
    start_data <= '0';
    ack_error <= sda;
    if ack_error = '1' then         
    stop_clk <= '1';
    reset <= '1';
    else
    end if;
    if RD = '1' then                    

    elsif WR = '1' then             

    else                                    
    stop_clk <= '1';
    reset <= '1';
    end if;
    end case;
    end if;
    end process;

    sda <= sda_data when start_data = '1' else 'Z';
    scl <= i2c_clk when start_clk = '0' and stop_clk = '0' else 'Z';



    end MAIN;

用于合成的信号只能从一个过程或一个连续分配驱动;对于仿真,可以使用std_logic等解析信号来驱动多个驱动器。

sclsda都由i2c_clock过程和文件末尾的连续分配驱动。

start_clkstop_clk都由i2c_clock进程和其他未命名进程驱动。

sclsda的一种可能性是只从连续赋值中驱动它们,因为合成工具通常更喜欢三态输出

,如下所示:
q <= value when en = '1' else 'Z';

最新更新