Forum: FPGA, VHDL & Co. Tipps zur Fehlersuche gesucht


von Hans-Werner (Gast)


Lesenswert?

Eine Frage zu folgenden Meldungen (ISE Webpack 10.1, Simulation):
Wie kann ich die Ursachen besser eingrenzen ?
Ich erhalte entweder nur einen Hinweis auf ein Signal welches 
anscheinend während der Synthese angelegt wurde oder einen Hinweis auf 
einen Zeitpunkt.
Falls gewünscht kann ich auch den Code posten.

:Xst:1426 - The value init of the FF/Latch state_FFd24 hinder the 
constant cleaning in the block make_key.
   You should achieve better results by setting this init to 0.

INFO:Xst:1767 - HDL ADVISOR - Resource sharing has identified that some 
arithmetic operations in this design can share the same physical 
resources for reduced device utilization. For improved clock frequency 
you may try to disable resource sharing.

at 500.000 ps(1), Instance /testbench/uut/ram_inkey/ : Warning: 
NUMERIC_STD.TO_INTEGER: metavalue detected, returning 0
at 500.000 ps(1), Instance /testbench/uut/ram_outkey/ : Warning: 
NUMERIC_STD.TO_INTEGER: metavalue detected, returning 0
at 256.500 ns(1), Instance /testbench/uut/ : Warning: 
NUMERIC_STD.TO_UNSIGNED: vector truncated
at 512.500 ns(1), Instance /testbench/uut/ : Warning: 
NUMERIC_STD.TO_UNSIGNED: vector truncated

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


Lesenswert?

> Falls gewünscht kann ich auch den Code posten.
Tu das ;-)

von Hans-Werner (Gast)


Angehängte Dateien:

Lesenswert?

Mach ich doch glatt.
Ist eine meiner vielen Übungen. C-Code siehe Datei.
Sinn des Ganzen ist es aus einem kurzen Passwort ein längeres Passwort 
zu generieren. Ja, es gibt auch Hash-Verfahren.
Hinweise zur Optimierung bzw. Verbesserung sind willkommen.
Sollte aber noch "leserlich" bleiben.
Testbench folgt nach.

librARY ieee;
use ieee.std_logic_1164.ALL;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.ALL;

entity testbench is
end testbench;

architecture behavior OF testbench IS

  component make_key
   port (
      --------------- Inputs
         clock         : in  std_logic;
      enable            : in  std_logic;
      length_of_inkey   : in  std_logic_vector(7 downto 0);
      inkey_byte       : in  std_logic_vector(7 downto 0);
      ---------------- Outputs
         ready             : out std_logic;
      done              : out std_logic;
         input             : out std_logic;
      output            : out std_logic;
      outkey_byte     : out std_logic_vector(7 downto 0)
        );
   end component;


   --Inputs
  signal enable         : std_logic;
   signal clock         : std_logic;
   signal inkey_byte      : std_logic_vector(7 downto 0) := (others => 
'0');
   signal length_of_inkey   : std_logic_vector(7 downto 0) := (others => 
'0');

   --Outputs
  signal ready         : std_logic;
  signal done             : std_logic;
  signal input          : std_logic;
  signal output      : std_logic;
   signal outkey_byte     : std_logic_vector(7 downto 0);

   -- Clock period definitions
   constant clock_period : time := 1ns;

  subtype byte is natural range 0 to 255;
  type byte_array is array(natural range <>) of byte;
  subtype byte_array_8 is byte_array (0 to 7);
  subtype byte_array_256 is byte_array (0 to 255);

  signal inkey         : byte_array_8 := (13, 74, 255, 45, 196, 21, 128, 
119);
  signal outkey         : byte_array_256;
BEGIN

  uut: make_key port map
  (
      -------------- Inputs
        clock         => clock,
        enable          => enable,
        length_of_inkey => length_of_inkey,
        inkey_byte     => inkey_byte,
      -------------- Outputs
        ready           => ready,
        done            => done,
        input        => input,
        output        => output,
           outkey_byte     => outkey_byte
   );

   -- Clock process definitions
   clock_process :process
   begin
    clock <= '0';
    wait for clock_period/2;
    clock <= '1';
    wait for clock_period/2;
   end process;


   -- Stimulus process
   stim_proc: process
   begin
     enable <= '0';
      length_of_inkey <= std_logic_vector(to_unsigned(inkey'length,8));
     -- Warte auf MakeKey
       wait until input = '1';
     for i in inkey'low to inkey'high loop
      -- Eingabe beginnt mit der nächsten Taktflanke
      inkey_byte <= std_logic_vector(to_unsigned(inkey(i),8));
      -- Warte jeweils einen Takt
      wait for clock_period;
     end loop;
     wait until ready = '1';
     enable <= '1';
     wait until output = '1';
     wait;
   end process;

END;

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


Lesenswert?

Btrifft nur die TB:
Entweder die
1
use ieee.std_logic_unsigned.all;
oder die
1
use ieee.numeric_std.ALL;
Aber nicht beide zusammen.

von Hans-Werner (Gast)


Lesenswert?

Danke, werde es nachprüfen.
Eine andere Frage:
Wo finde ich ein Beispiel für ein Shared RAM ?
Habe es schon versucht, aber noch nicht zum Laufen gebracht.

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


Lesenswert?

Hans-Werner wrote:
> Wo finde ich ein Beispiel für ein Shared RAM ?
Dual-Port oder Tri-Port RAMS kenne ich, aber unter einem Shared RAM kann 
ich mir (als Hardwarekomponente) nichts vorstellen? Was tut so ein 
Bauteil?

von Hans-Werner (Gast)


Angehängte Dateien:

Lesenswert?

Die Warnung mit dem Latch bezieht sich nicht auf die Testbench.
Die Warnungen "metavalue detected" und "vector truncated" erhalte ich 
auch wenn ich std_logic_unsigned ausklammere.
Leider wird in keinem VHDL-Buch beschrieben wie man systematisch Fehler 
sucht.
(Bezüglich Shared RAM sollte man ein neues Topic aufmachen)
Ein "Shared RAM" ist ein RAM auf das von mehreren Prozessen aus 
zugegriffen werden kann. Natürlich nicht gleichzeitig. Normalerweise 
unter VHDL nicht möglich. Hierfür existieren sogenannte "Shared 
Variablen". Mit der Deklaration einer Variablen als "Shared" ist es 
allein jedoch nicht getan.
Ich habe mich an einem Beispiel aus dem Buch von Peter Ashenden 
orientiert.
Siehe Anhang.
Leider funzt es nicht bzw. ich kriege Fehlermeldungen.
Dies wäre der letzte Schritt für die Umsetzung von Heapsort von C nach 
VHDL. Ich habe jede Prozedur bzw. Funktion von C in einen VHDL-Prozess 
umgesetzt. Dann nehme man einen Stack auf den der Name des aktuellen 
Prozesses abgelegt wird. Anhand des aktuellen Prozesses kann man dann 
die Signale der einzelnen Prozesse durchschalten. Was noch fehlt ist, 
wie gesagt, ein Shared RAM. Die Umsetzung mehrerer Funktionen bzw. 
Prozeduren in einen gemeinsamen Prozess mit einer einzigen 
Zustandsmaschine ergibt ein sehr unübersichtliches VHDL-Programm. Ich 
strebe eine 1-zu-1 Abbildung einer C-Prozedur bzw. Funktion auf einen 
Prozess an.

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


Lesenswert?

> Ein "Shared RAM" ist ein RAM auf das von mehreren Prozessen aus
> zugegriffen werden kann.
Ich bin mir nicht so sicher, ob du das ein wenig zu akademisch siehst 
:-/

Ein Shared RAM ist also in der realen Hardware ein RAM mit einem 
Multiplexer. Wenn du sowas meinst, dann beschreibe es am besten auch so. 
Mit derartigen VHDL-Kunstgriffen kommst du sehr sehr schnell an die 
Grenze des Synthetisierbaren!
>  type ... is protected
>    impure function ....;
>  end protected ...

Es ist schon klar: ich kann mit irgendwelchen Shared-Variablen irgendwas 
in VHDL beschreiben (und evtl. sogar noch simulieren). Aber ob der 
Synthesizer es noch in Hardware gebacken bekommt steht auf einem anderen 
Blatt (den Design Guides für die Synthese).
Ich kann ganz einfach einen VHDL-konformen Dreizeiler schreiben, der 
komplett ohne die neuen VHDL-Gimmicks auskommt, den mir aber kein 
Synthesizer in (FPGA-)Hardware umsetzen kann.

> Ich strebe eine 1-zu-1 Abbildung einer C-Prozedur bzw. Funktion
> auf einen Prozess an.
Naja, das geht mE. nicht   :-/
(weil u.a. schon die Denkweise dahinter eine ganz Andere ist)

> at 500.000 ps(1), Instance /testbench/uut/ram_inkey/ : Warning:
> NUMERIC_STD.TO_INTEGER: metavalue detected, returning 0
Das ist deine 1. steigende Flanke, da sind offenbar noch nicht alle 
Signale definiert.

von Hans-Werner (Gast)


Lesenswert?

Mit diesen Aussagen kann ich nichts anfangen.
Habe nur verstanden das du dich auch nicht mit Shared RAM auskennst und 
auch über kein synthetisierbares der simulierbares Beispiel verfügst.
Ich gehe weiter davon aus das sich Shared RAM synthetisieren lässt.
Bis jetzt habe ich keine eindeutige gegenteilige Aussage gefunden.
Die Beispiele in dem Buch von Ashenden beziehen sich zumeist auf die 
Simulation. Hier fehlt ebenfalls die Aussage welche Beispiele nur 
simulierbar sind und welche nicht. Leider beschränken sich die meisten 
VHDL-Bücher auf eine Einführung in die Sprache, das Programmieren wird 
jedoch nicht gelehrt.

von Klaus F. (kfalser)


Lesenswert?

Um es vorweg zu sagen, auch ich kenne mich mit Shared RAM nicht aus, ein 
Dual Port RAM gibt es jedoch.
Synthetisieren kann man nämlich immer nur das, was es im FPGA auch gibt, 
so könnte man nämlich nie ein Tripple-Port RAM synthetisieren, darunter 
verstehte sich wahrscheinlich ein shared RAM auf das 3 Prozesse 
gleichzeitig zugreifen können.

Das Dual Port RAM kann man entweder als vorgefertige Einheit mit den 
gewünschten Größe mit dem Xilinx Core generator definieren und als 
fertiges Modul einbinden, oder man beschreibt es in einer Weise, dass 
der Xilinx Compiler XST es als Dual Port erkennt. Zur 2. Methode bin ich 
aber nicht sicher, ob das geht, normale RAMs und ROMs kann man 
jedenfalls so erzeugen.

Dazu existiert eine Dokumentation (RTFM, na klar) zum XST, wo 
beschrieben ist, was synthesierbar ist und wie man es beschreiben muß, 
dass es entsprechend erkannt wird.

von Jan M. (mueschel)


Lesenswert?

>so könnte man nämlich nie ein Tripple-Port RAM synthetisieren, darunter
>versteht sich wahrscheinlich ein shared RAM auf das 3 Prozesse
>gleichzeitig zugreifen können.

Solange nur einer der drei (oder auch vier) schreiben kann geht das. 
Dazu gibt es auch eine Application Note von Xilinx.

von lkmiller (Gast)


Lesenswert?

> Mit diesen Aussagen kann ich nichts anfangen.
Hmmm.

> Habe nur verstanden das du dich auch nicht mit Shared RAM auskennst und
ACK
> auch über kein synthetisierbares der simulierbares Beispiel verfügst.
Full ACK


> Ich gehe weiter davon aus das sich Shared RAM synthetisieren lässt.
> Bis jetzt habe ich keine eindeutige gegenteilige Aussage gefunden.
Natürlich kannst du RAM im FPGA verwenden, auf das von mehreren 
Komponenten aus (zeitlich getrennt) zugegriffen wird. Nur brauchst du 
dafür eben einen Adress- und Daten-Multiplexer.
So ein Bauteil:
1
  process (clock)
2
  begin
3
    if rising_edge(clock)
4
    then
5
      if write_enable = '1'
6
      then
7
        ram(to_integer(unsigned(address))) <= data_in;
8
      else
9
        data_out <= ram(to_integer(unsigned(address)));
10
      end if;      
11
    end if;
12
  end process;
gibt es in einem FPGA nicht. Das ist kein reines BRAM, sondern hat ein 
nacheschaltetes Register.
Wie du das RAM beschreiben mußt, dass ein BRAM im FPGA verwendet wird, 
steht für Xilinx in den "General Coding Styles". Wenn du es nicht so 
machst, kannst du es evtl. simulieren (in der Simulation kannst du den 
gesamten Sprachumfang von VDHL verwenden) aber u.U nicht synthetisieren.
BTW:
Das gäbe ein lupenreines BRAM:
1
  process (clock)
2
  begin
3
    if rising_edge(clock)
4
    then
5
      if write_enable = '1'
6
      then
7
        ram(to_integer(unsigned(address))) <= data_in;
8
      end if;      
9
      data_out <= ram(to_integer(unsigned(address)));
10
    end if;
11
  end process;
Siehst du den Unterschied?

> Leider beschränken sich die meisten VHDL-Bücher auf eine Einführung
> in die Sprache, das Programmieren wird jedoch nicht gelehrt.
Lies dir mal das Buch VHDL-Synthese von Reichardt/Schwarz durch.
In diesem Buch deht es um VHDL für die Synthese.

Du kannst in einem FPGA nur das verdrahten/verwenden, was dort bereits 
eingebaut ist: Logik, FFs, Taktverwaltung, Taktverteilung, RAMs. Du 
kannst nichts neu implementieren.


> Solange nur einer der drei (oder auch vier) schreiben kann geht das.
Einfach ein paar BRAMs parallelschalten:
In alle wird das Selbe hineingeschrieben.
Es kann von jedem einzelnen BRAM (auf dem zweiten Port) gelesen werden.
--> 1 Read/Write-Port   und   3 (oder auch 4) Read-Ports

von Duke Scarring (Gast)


Lesenswert?

> Lies dir mal das Buch VHDL-Synthese von Reichardt/Schwarz durch.
> In diesem Buch deht es um VHDL für die Synthese.
Ich finde das Buch schon reichlich alt und an einigen Stellen überholt.

Wenn er wissen will, was wirklich zu synthetisieren geht, muss er in
xst.pdf (Xilinx) schauen. Da gibt es einen Abschnitt über die von XST 
unterstützten VHDL-Konstrukte und auch Codebeispiele, wie ein 
RAM/ROM/Dual-Port RAM etc. auszusehen haben.

BRAMs direkt zu instanzieren führt m.E. zu sehr unleserlichen, unnötig 
komplexen Code.

Duke

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


Lesenswert?

> Ich finde das Buch schon reichlich alt und an einigen Stellen überholt.
Ja, das schon...
Aber welches ist deines Erachtens aktueller, gleich gut lesbar und 
(mindestens) genauso Synthese-orientiert?

> Wenn er wissen will, was wirklich zu synthetisieren geht, muss er in
> xst.pdf (Xilinx) schauen.
Mit dem XST Design Guide anzufangen ist mE. schon starker Tobak.

> BRAMs direkt zu instanzieren führt m.E. zu sehr unleserlichen, unnötig
> komplexen Code.
Aber erst dann kann man so richtig schöne Tricks machen ;-)

von Klaus F. (kfalser)


Lesenswert?

> Mit dem XST Design Guide anzufangen ist mE. schon starker Tobak.
Naja, ein Heap Sort Algorithmus als VHDL Beginner ist auch nicht viel 
besser ...

von AngiBolyly (Gast)


Lesenswert?

As all we recognize, that now in the seventh heaven disaster and it is 
urgent to be more inexpensive, it would be winsome to understand your 
opinions how to prosper better.
remarkably I am am overwrought with cleaning of the big carpets.

von SuperWilly (Gast)


Lesenswert?

Habe mal in der aktuellen Dokumentation von SynplifyPro geschaut.
Es wird an keiner Stelle "shared variables" auch nur erwähnt.
Ergo: Shared Variablen werden für die Synthese nicht unterstützt.

Versuch es mal mit einer kleinen Post-Place&Route Timing-Simulation,
um zu schauen, ob deine synthetisierte Hardware das macht, was Du 
glaubst ;O)

SuperWilly

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.