Forum: FPGA, VHDL & Co. AX8 - PINB - Multi-source-Error (Spartan 3E/VHDL)


von Andreas W. (Firma: andreas-weschenfelder.de.vu) (rupplyn) Benutzerseite


Lesenswert?

Hallo zusammen,

ich habe den AX8 in mein Projekt eingefuegt und erfolgreich bauen können 
(UART-Echo funktioniert beispielsweise).
Allerdings habe ich Probleme beim Schreiben auf die Port-Wert, um diese 
dann mit PinX einlesen zu koennen: bei der LowLevel Synthese erhalte ich 
einen Multi-source-Error:
ERROR:Xst:528 - Multi-source in Unit <MainTop> on signal <MyPortB<7>>

Wie kann ich das denn anderst machen (ohne das AX8-Modul zu verändern)?

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


entity MainTop is
    Port (
        MainCLK  :  in std_logic;
        SW     : in  STD_LOGIC_VECTOR (3 downto 0);
        LED     : out  STD_LOGIC_VECTOR (7 downto 0);
        RXD    : in std_logic;
        TXD    : out std_logic

      );
end MainTop;

architecture Behavioral of MainTop is

 component A90S2313
  port(
    Clk    : in std_logic;
    Reset_n  : in std_logic;
    INT0    : in std_logic;
    INT1    : in std_logic;
    T0      : in std_logic;
    T1      : in std_logic;
    ICP    : in std_logic;
    RXD    : in std_logic;
    TXD    : out std_logic;
    OC      : out std_logic;
    Port_A  : inout std_logic_vector(7 downto 0);
    Port_B  : inout std_logic_vector(7 downto 0);
    Port_C  : inout std_logic_vector(7 downto 0);
    Port_D  : inout std_logic_vector(7 downto 0)
  );
  end component;


  signal MyPortA : std_logic_vector(7 downto 0);
  signal MyPortB : std_logic_vector(7 downto 0);
  signal MyPortC : std_logic_vector(7 downto 0);
  signal MyPortD : std_logic_vector(7 downto 0);


  signal tmp_adr : std_logic_vector(7 downto 0);
begin



 MyA90S2313 : A90S2313
  Port map(
    Clk    => MainCLK,
    Reset_n  => '1',--SW(0),
    INT0    => '1',
    INT1    => '1',
    T0      => '1',
    T1      => '1',
    ICP    => '1',
    RXD    => RXD,
    TXD    => TXD,
    OC      => open,
    Port_A  => MyPortA,
    Port_B  => MyPortB,
    Port_C  => MyPortC,
    Port_D  => MyPortD
  );



  Main_Pro:process( MainCLK )
  begin
    if rising_edge( MainCLK ) then


      if MyPortA = x"00" then


        case tmp_adr is
          when x"00"  =>
            -- belegt ;-)

          when x"01" =>           LED <= MyPortC;
          when x"02" =>          MyPortB <= "0000000" & SW(0);

          when others =>
            --ignorieren
        end case;

        tmp_adr <= x"00";

      else

        tmp_adr <= MyPortA;

      end if;


    end if;
  end process Main_Pro;

end Behavioral;

von Falk B. (falk)


Lesenswert?

@Andreas Weschenfelder (rupplyn)

>ERROR:Xst:528 - Multi-source in Unit <MainTop> on signal <MyPortB<7>>

Zwei Prozesse schreiben auf das Signal. Deine Komponente AX-8 und dein 
Prozess Main_Pro.

>Wie kann ich das denn anderst machen (ohne das AX8-Modul zu verändern)?

Du brauchst einen Multiplexer.

MFG
Falk

P.S. Und längere Quelltexte besser als Anhang. Siehe Netiquette

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Ist das der ganze Quelltext?
Warum hast du die Multisource nur auf
> MyPortB<7>
Du beschreibst doch den ganzen Port mit
> MyPortB <= "0000000" & SW(0);

Greift da irgendwer noch von woanders auf MyPortB(7) zu?

Zur Fehlersuche probier mal das
>  when x"02" =>          MyPortB(0) <= SW(0);
Die anderen Bits sind sowieso uninteressant und reichlich undefiniert.

von Klaus F. (kfalser)


Lesenswert?

Ohne jetzt die Detail genau zu kennen, denke ich dass Du am Konzept oder 
am A90S2313 Modell etwas ändern mußt.
Der A90S2313 (AT90S2313) ist wahrscheinlich das Modell eines Prozessors 
und stellt an den Ports bidirektionale Pins zur Verfügung. Bei Schreiben 
von außen in den Prozessor wird der Pin auf hochohmig geschalten, damit 
das Signal von Außen getrieben werden kann.
Das geht jedoch innerhalb eines FPGAs nicht, weil ein FPGA heutzutage 
keine internen Tri-State Leitungen, die das Prozessor-Modul hochohmig 
schalten kann hat.
Abhilfe :
- In deine Applikation ist PortB immer ein Eingang. Du änderst das 
Prozessor Modul und machst aus inout PortB ein "in PortB"
- Du legst PortB an einen Ausgangspin (der kann hochohmig geschalten 
werden) und verbindest das Signal außerhalb vom FPGA.
- Du verwendest "Multiple Source" Signale und stellst die Auflösung 
dafür auf "OR" (ver-oderung). Dabei wird intern aus den 2 Signalen ein 
neues generiert. Wenn jetzt der Prozessor sein PortB Signal mit "0" 
beschreibt, dann ist das "resolved" Signal (=Bus Signal) mit dem Wert 
von Prozess Main_Pro identisch.

Klaus

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Angehängte Dateien:

Lesenswert?

Das würde gehen, wenn du dem Signal MyPortB die Möglichkeit geben 
könntest, auch mal hochohmig zu werden. Durch die Beschreibung
>          when x"02" =>          MyPortB <= "0000000" & SW(0);
wird MyPortB zu Registern synthetisiert. Und so ein Register kann eben 
nur einen Zustand annehmen und nur von einer Flanke gesteuert werden. 
Also nicht nebenbei auch noch von
> MyA90S2313 : A90S2313
>  Port map(
>    :
>    Port_B  => MyPortB,
>    :
>  );


Mit einer Beschreibung wie z.B. im Anhang kannst du durchaus auch 
innerhalb eines FPGAs einen "Pseudo"-Tristate-Bus beschreiben. Dieser 
Bus wird bei der Synthese dann zwar in Logik (Mux) umgewandelt:
> WARNING:Xst:2040 - Unit TopIO: 4 multi-source signals
>                                    are replaced by logic (pull-up yes)
Aber prinzipiell geht das gut.
Natürlich musst du dafür sorgen, dass keine Buskollisionen auftreten. 
Aber durch die Auflösung in Logik werden dann in der Realität keine 2 
Treiber aufeinander losgelassen. Es kommt nur etwas Falsches dabei 
heraus.


Füg doch mal einen Defaultwert in für MyPortB in deinen Porzess ein. 
Dann wird Kombinatorik erzeugt, und die Synthese müsste durchgehen.
1
   if rising_edge( MainCLK ) then
2
      MyPortB <= "ZZZZZZZZ"; -- DEFAULT, so wird Kombinatorik erzeugt
3
      if MyPortA = x"00" then
4
5
        case tmp_adr is
6
          when x"00"  =>
7
            -- belegt ;-)
8
9
          when x"01" =>           LED <= MyPortC;
10
          when x"02" =>          MyPortB <= "0000000" & SW(0);
11
12
          when others =>
13
            --ignorieren
14
        end case;

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.