0

I am attempting to write a simple VHDL Uart receiver and loop back. The baud clock is started at the beginning of the start bit and is stopped at the stop in an effort to keep the clock in sync with the data bits. This start and stop is done in the Bd_Clock process. The baud clock is stopped in the “stop” state by resetting the signal to ‘0’.

The assumption is that next 8 rising edge of the baud clock will be a readable bit from the receiving pin, rx_line.

Vivado is complaining about a 66 Multiple Driver errors: [DRC MDRV-1] Multiple Driver Nets: Net Baud_clock has multiple drivers: Baud_clock_reg/Q, Baud_clock_reg__0/Q, and Baud_clock_reg__1/Q.

Please, can anyone explain this error and its resolution?

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity Uart_rx_2 is
  Port ( 
        clk     : in  std_logic;
        reset   : in  std_logic;
        rx_line : in  std_logic;
        tx_line : out std_logic
  );
end Uart_rx_2;

architecture Behavioral of Uart_rx_2 is

signal  Bit_count   :  integer := 0; -- pointer to bin in R_data_buf
signal  R_data_buf  :  std_logic_vector(7 downto 0) := (others => '0');--rx byte

signal Baud_clock   :  std_logic  :='0'; -- the baud clock
-- signal Tmp_clock    :  std_logic  :='0'; -- Temp baud signal
signal Baud_count   :  integer    := 0; -- counts tick of the baud clock
signal Baud_max     :  integer    := 104; -- max ticks _12 Mhz at 115200 baud)
signal Baud_start   :  std_logic  := '0'; -- = 1 -> start baud clock

type   State_type is (idle, data, stop);
signal state_next : state_type;

begin

   Init   : process (reset)
      begin
         if(reset = '1') then
            State_next <= idle; 
            Bit_count <= 0; -- rx bit counter = 0
            R_data_buf <= "00000000"; -- intialize data buffer
            Baud_clock <= '0'; -- Baud clock starts at 0
            Baud_count <= 0; -- intial the clock counter
         end if;
   end process;

   State_Machine : process (State_next, Baud_clock, rx_line)
      begin

         case State_next is

         when idle =>

            if (rising_edge(Baud_clock)) then
               State_next <= data; -- start bit detected get rx_line data
            end if;
          -- end idle

          when data =>

             if( Bit_count = 8 ) then
                State_next <= stop;

             elsif (rising_edge(Baud_clock)) then
                R_data_buf(Bit_count) <= rx_line; -- put serial bit into buffer
                Bit_count <= Bit_count + 1; -- increment to the next bit
                tx_line <= rx_line; -- loop back to output

             end if;
             -- end data

           -- reset the bits and goto idle 
           when stop =>

             Baud_start <= '0'; -- stop the baud clock
             State_next <= idle; -- back to idle
             Baud_clock <= '0';  
             R_data_buf <= "00000000";
             Bit_count  <= 0;
             -- end stop

          end case;

   end process;

   Bd_Clock : process (rx_line, clk)

      begin

      if falling_edge(rx_line) and Baud_start = '0' then
         Baud_start <= '1'; -- Waits for the rx_line to go low signaling the start bit.
      end if;               -- Starts the baud clock.

      if Baud_start = '1' then
         if(Baud_count = Baud_max) then
            Baud_clock <= not Baud_clock;
            Baud_count <= 0;
         else
            Baud_count <= Baud_count + 1;
         end if;         
      end if;

   end process;

end Behavioral;   
user3822607
  • 69
  • 1
  • 9
  • 1
    You have Baud_clock assigned in more than one process: Init, State_Machine and Bd_Clock. Each process that contains an assignment to a signal will have a driver. The effective value for Baud_clock will be the resolved value of the three drivers (it's a std_logic, a resolve data type). Consolidate the processes into one or align them based on signals with assignments. (And you could simulate your design before synthesis.) –  Jan 19 '20 at 03:49
  • Thank-you for your comments. This solved the problem. – user3822607 Jan 19 '20 at 20:26

0 Answers0