mikrocontroller.net

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


Autor: Andreas Weschenfelder (Firma: andreas-weschenfelder.de.vu) (rupplyn) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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;

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Klaus Falser (kfalser)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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.
   if rising_edge( MainCLK ) then
      MyPortB <= "ZZZZZZZZ"; -- DEFAULT, so wird Kombinatorik erzeugt
      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;

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.