VHDL de 4 bits Shift-and-Add Multiplier Buffer y error de puerto de salida

Estoy trabajando en la creación de un multiplicador Shift-and-Add de 4 bits. Recibo este mensaje de advertencia: "ADVERTENCIA:HDLParsers:3555 - "//filer1.egr.msu.edu/samarar1/ece230/Project05/Project05.vhd" Línea 220. Advertencia por infracción de la sección 1.1.1.2 de LRM sobre las reglas de conectividad. El parámetro P del búfer de modo no debe asociarse con un puerto formal de salida de modo".

¿Cómo puedo solucionar esta advertencia? Aquí está mi código:

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

entity shiftlne is
generic(n:integer:= 4);
port (R     :in     STD_LOGIC_VECTOR(n-1 downto 0);
        L,E,w :in       STD_LOGIC;
        Clock   :in     STD_LOGIC;
        Q       :buffer STD_LOGIC_VECTOR(n-1 downto 0));
end shiftlne;

architecture Behavioral of shiftlne is
begin
process
begin
    wait until Clock'Event and Clock = '1';
    if L = '1' then
          Q <= R;
    elsif E = '1' then
        Q(0) <= w;
        Genbits: for i in 1 to n-1 loop
            Q(i) <= Q(i-1);
        End loop;
    End if;
End process;
end Behavioral;

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity shiftrne is
generic(n:integer:= 4);
port(R  :in     STD_LOGIC_VECTOR(n-1 downto 0);
     L,E,w:in       STD_LOGIC;
     Clock:in       STD_LOGIC;
     Q      :buffer  STD_LOGIC_VECTOR(n-1 downto 0));
end shiftrne;

architecture Behavioral of shiftrne is
begin
process
begin
    wait until Clock'Event and Clock = '1';
    if E = '1' then
        if L = '1' then
            Q <= R;
        else
            Genbits: for i in 0 to n-2 loop
                Q(i) <= Q(i+1);
            end loop;
            Q(n-1) <= w;
        end if;
    end if;
end process;
 end Behavioral;

 library IEEE;
 use IEEE.STD_LOGIC_1164.ALL;

 entity mux2to1 is
port (w0,w1,s :in   STD_LOGIC;
        f         :out  STD_LOGIC);
 end mux2to1;
 architecture Behavioral of mux2to1 is
 begin
with s select
f <= w0 when '0',
      w1 when others;
 end Behavioral;

 library IEEE;
 use IEEE.STD_LOGIC_1164.ALL;

 entity regne is
generic (n: integer:= 4);
port(R          :in STD_LOGIC_VECTOR(n-1 downto 0);
      Resetn        :in STD_LOGIC;
      E,Clock   :in STD_LOGIC;
      Q         :out STD_LOGIC_VECTOR(n-1 downto 0));
 end regne;

 architecture Behavioral of regne is
 begin
process(Resetn,Clock)
begin
    if Resetn = '0' then
        Q <= (others => '0');
    elsif Clock'event and Clock = '1' then
        if E = '1' then
            Q <= R;
        end if;
    end if;
end process;
 end Behavioral;

 library IEEE;
 use IEEE.STD_LOGIC_1164.ALL;
 use IEEE.STD_LOGIC_UNSIGNED.ALL;

 entity Multiplier is
generic (n:integer:=4; nn:integer:=8);
port (Clock     :in std_logic;
        Resetn  :in std_logic;
        LA,LB,s :in std_logic;
        DataA       :in std_logic_vector(n-1 downto 0);
        DataB       :in std_logic_vector(n-1 downto 0);
        P         :buffer std_logic_vector(nn-1   downto 0);
        Done        :out std_logic);
 end Multiplier;

 architecture Behavioral of Multiplier is
type state_type is (s1,s2,s3);
signal y: state_type;
signal Psel,z,EA,EB,EP,Zero: std_logic;
signal B,n_Zeros: std_logic_vector(n-1 downto 0);
signal A,Ain,DataP,Sum: std_logic_vector(nn-1 downto 0);

component mux2to1
    port(w0,w1  :in STD_LOGIC;
          s     :in STD_LOGIC;
          f     :out STD_LOGIC);
end component;

component regne
    generic(n:integer:= 4);
    port(R          :in STD_LOGIC_VECTOR(n-1 downto 0);
          Resetn    :in STD_LOGIC;
          E,Clock   :in STD_LOGIC;
          Q     :out    STD_LOGIC_VECTOR(n-1 downto 0));
end component;

component shiftlne
    generic(n:integer:= 4);
    port (R         :in STD_LOGIC_VECTOR(n-1 downto 0);
            L,E,w       :in     STD_LOGIC;
            Clock       :in STD_LOGIC;
            Q   :buffer STD_LOGIC_VECTOR(n-1 downto 0));
end component;

component shiftrne
    generic(n:integer:= 4);
    port (R         :in STD_LOGIC_VECTOR(n-1 downto 0);
            L,E,w       :in     STD_LOGIC;
            Clock       :in STD_LOGIC;
            Q   :buffer STD_LOGIC_VECTOR(n-1 downto 0));
end component;

 begin
FSM_transitions: process(Resetn,Clock)
begin
    if Resetn = '0' then
            y<=s1;
    elsif (Clock'event and Clock = '1') then
     case y is
          when s1=>
          if s = '0' then y <= s1; else y <= s2;                    
 end if;
        when s2=>
            if z = '0' then y <= s2; else y <= s3;      
 end if;
            when s3 =>
             if s = '1' then y <= s3; else y <= s1;      
 end if;
        end case;
    end if;
end process;

FSM_outputs: process(y,s,B(0))
begin
    EP <= '0'; EA <= '0'; EB <= '0'; Done <= '0'; Psel <= '0';
    case y is
        when s1 =>
            EP <= '1';
        when s2 =>
            EA <= '1'; EB <= '1'; Psel <= '1';
            if B(0) = '1' then EP <= '1'; else EP <= '0'; 
 end if;
        when s3 =>
            Done <= '1';
    end case;
end process;

Zero <= '0';
n_Zeros <= (others => '0');
Ain <= n_Zeros & DataA;
ShiftA:shiftlne generic map (n=>nn)
    port map(Ain,LA,EA,Zero,Clock,A);
ShiftB:shiftrne generic map (n=>n)
    port map(DataB,LB,EB,Zero,Clock,B);
z <= '1' when B = n_Zeros else '0';
Sum <= A + P;

GenMUX: for i in 0 to nn-1 generate
    Muxi: mux2to1 port map (Zero,Sum(i),Psel,DataP(i));
end generate;
RegP:regne generic map (n=>nn)
    port map (DataP,Resetn,EP,Clock,P);

 end Behavioral;
Para que no tengamos que contar 220 líneas, ¿tal vez podría señalar la línea a la que se refiere el error?
Copie y pegue su código en un editor de texto. No hay línea 220.

Respuestas (2)

Creo que aquí es donde sale mal:
RegP:regne generic map (n=>nn) port map (DataP,Resetn,EP,Clock,P);

El puerto del que proviene P es una salida, pero P es un búfer.

Recomendé nunca usar 'buffer' exactamente por este motivo. Use una variable local para leer y escribir y asígnela a una salida. Uso la convención de agregar _buf a ese tipo de señales locales en mi diseño: el puerto de salida es Q, la señal local es Q_buf, Q <= Q_buf.

Por ejemplo: tienes un diseño grande que casi funciona. Por alguna razón, descubre que tiene una señal de salida que necesita volver a leer. Por lo tanto, cambia el puerto a 'buffer' y... ¡su sistema VHDL se desmorona! Ahora quiere que cambie TODOS los puertos en la jerarquía de todos los módulos por donde pasa esa señal desde la salida al búfer.

Parece que nuestras respuestas se superpusieron, y resaltamos exactamente lo mismo. +1 por ganarme el golpe.
Esas cosas pasan.

Lo más probable es que tu problema esté aquí:

RegP:regne mapa genérico (n=>nn) mapa de puerto (DataP,Resetn,EP,Clock,P); — <—- aquí

donde está intentando asignar un puerto de salida Q :out STD_LOGIC_VECTOR(n-1 downto 0));a un búfer. Los búferes deben tener sus valores asignados internamente y, por lo general, no se pueden conectar a out.

Mi consejo es minimizar el uso de búferes. A menudo conducen a problemas, especialmente en síntesis.