Forum: FPGA, VHDL & Co. VHDL - Lookuptable indizieren


von Tabelle (Gast)


Lesenswert?

Hallo Leute

ich versuche im Moment ein DDS zum implementieren, habe aber Probleme 
damit mein Array von Funktionswerten zu indizieren, als Meldung kommt
1
..\ieee\numeric_std-body.v93:2098:7:@5ns:(assertion warning): NUMERIC_STD.TO_INTEGER: metavalue detected, returning 0

mein Code soweit:
1
entity dds is
2
  port(clk : in std_logic;
3
     incr : in unsigned(31 downto 0);
4
     res : out unsigned(7 downto 0));
5
end dds;
6
7
architecture rtl of dds is
8
9
type tableentry is array (0 to 1023) of unsigned(7 downto 0);
10
constant lookuptable : tableentry := (
11
"10000000",
12
"10000000",
13
"10000001",
14
.. // viele einträge
15
16
signal acc : unsigned(31 downto 0); -- phase accumulator
17
18
begin
19
  process(clk)
20
  begin
21
    if (rising_edge(clk))
22
    then
23
      acc <= acc + incr;
24
      res <= lookuptable(to_integer(unsigned(acc(31 downto 24))));
25
    end if;
26
  end process;
27
end rtl;

Ich möchte die obersten 10 Bits als Index nutzen. Durch suchen habe ich 
herausgefunden dass ein Index immer ein Integer sein muss, nur wie 
bekomme ich einen Integer daraus?

MfG
Tabelle

von Dr. Schnaggels (Gast)


Lesenswert?

Es ist doch nur ein Warning oder?
Was siehst Du auf res?

>unsigned(acc(31 downto 24)

acc ist schon 'unsigned', daher unnötig

von Dr. Schnaggels (Gast)


Lesenswert?

10bit:

res <= lookuptable(to_integer(acc(31 downto 22)));

von fisch (Gast)


Lesenswert?

Hallo,

du musst das Signal acc initialisieren. Entweder in einem 
asynchronen/synchronen Resetzweig oder bei der Signaldeklaration.

Gruß
fisch

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


Lesenswert?

Tabelle schrieb:
> NUMERIC_STD.TO_INTEGER: metavalue detected, returning 0
Ich würde mal sowas probieren:
1
   signal acc : unsigned(31 downto 0) := (others=>'0'); -- phase accumulator
Zum Nachdenken: welchen Wert hat acc ohne Initialisierung?
Wie könnte dieser Wert in einen Integer umgewandelt werden?

von Tabelle (Gast)


Lesenswert?

Dr. Schnaggels schrieb:
> res <= lookuptable(to_integer(acc(31 downto 22)));

Habe ich jetzt mal so übernommen (peinlich nichtmehr bis 10 zählen zu 
können). Trotzdem kommt pro Clocktakt die selbe Warnung.

Lothar Miller schrieb:
> Ich würde mal sowas probieren:
hab es jetzt so gemacht.

Lothar Miller schrieb:
> Zum Nachdenken: welchen Wert hat acc ohne Initialisierung?
> Wie könnte dieser Wert in einen Integer umgewandelt werden?

Wäre es ein std_logic_vector vermutlich "unknown", aber da es ein 
unsigned
ist wohl einen beliebigen Wert? Es wäre also wahrscheinlich dass das zu
einem integer gecastet negativ wäre?

In der Simulation bekomme ich nur den ersten Wert der Tabelle, als ob
er nicht incrementieren würde. Ich poste mal die Testbench dazu:
1
entity dds_test is
2
end entity dds_test;
3
4
architecture test of dds_test is
5
6
component dds is
7
  port(clk : in std_logic;
8
     incr : in unsigned(31 downto 0);
9
     res : out unsigned(7 downto 0));
10
end component;
11
12
signal incr : unsigned(31 downto 0);
13
signal incrvec : std_logic_vector(31 downto 0);
14
signal res : unsigned(7 downto 0);
15
16
constant num_cycles : integer := 3200;
17
signal clock : std_ulogic := '1';
18
  
19
begin
20
  dds1 : dds port map(clock, incr, res);
21
22
  process
23
  begin
24
    report "start!";
25
    incrvec <= x"02000000";
26
    incr <= unsigned(incrvec);
27
    for i in 1 to num_cycles loop
28
      report "run";
29
      clock <= not clock;
30
      wait for 5 ns;
31
      clock <= not clock;
32
      wait for 5 ns;
33
      -- clock period = 10 ns
34
    end loop;
35
    wait;  -- simulation stops here
36
  end process;
37
end test;

Seltsamerweise wird der Code in der Schleife nicht ausgeführt wenn ich
keinerlei Ausgabe mittels report mache. Stattdessen simuliert er endlos,
sobald ich das abbreche bekomme ich keine Ausgabe.

von Dr. Schnaggels (Gast)


Lesenswert?

incrvec <= x"02000000";

und somit "incr" werden auch nur einmal gesetzt.


Was Du willst ist eher:

1
use ieee.numeric_std.all;
2
3
...
4
signal incr : unsigned(...) := (others => '0');
5
6
clock <= not clock after 5 ns;
7
8
incr <= incr + 1 when rising_edge(clock);

von Tabelle (Gast)


Lesenswert?

Dr. Schnaggels schrieb:
> incrvec <= x"02000000";
>
> und somit "incr" werden auch nur einmal gesetzt.
>
>
> Was Du willst ist eher:

Das ist beabsichtigt, "incr" ist der Wert um den der Akkumulator 
incrementiert wird, incr ist damit Proportional zur Frequenz.

von Dr. Schnaggels (Gast)


Lesenswert?

OK, verstehe.


Aber folgende Zuweisung ist meines Erachtens problematisch:
1
incrvec <= x"02000000";
2
incr <= unsigned(incrvec);

Da es sich um Signale handelt, wird "incr" nicht den Wert von "incrvec" 
bekommen. Oder siehst Du in der Simulation incr=x"02000000" ?

1
incrvec <= x"02000000";
2
wait for 10 ps;
3
incr <= unsigned(incrvec);

von Tabelle (Gast)


Lesenswert?

Stimmt das habe ich nicht bedacht. Wäre es hierfür sinnvoll eine 
Variable zu nutzen um das warten zu umgehen? Schließlich ist incrvec nur 
zur initialisierung von incr gedacht.

Wenn ich incr durch eine Konstante ersetze, also z.b. acc <= acc + 1; 
schreibe, wird die Simulation ausgeführt und "acc" auch jedes mal um 
eins erhöht. "incr" hat dabei den korrekten Wert den ich in der 
testbench setze.

Wenn ich jetzt aber wieder incr einfüge statt +1 habe ich wieder das 
problem dass er nichts simuliert, Fehlermeldungen gibt es keine aber es 
tut sich einfach nichts

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


Lesenswert?

Tabelle schrieb:
> Wäre es ein std_logic_vector vermutlich "unknown", aber da es ein
> unsigned ist wohl einen beliebigen Wert?
Ratestunde, oder wie?
sieh einfach mal nach, was ein unsigend ist. In der numeric_std findest 
du dann das:
1
  --============================================================================
2
  -- Numeric array type definitions
3
  --============================================================================
4
5
  type UNSIGNED is array (NATURAL range <>) of STD_LOGIC;
6
  type SIGNED is array (NATURAL range <>) of STD_LOGIC;
Und wie wird ein std_logic initialisiert?
Wie alle VHDL Typen mit dem "linkesten" Element, und der ist 'U'.

BTW:
Ein std_logic_vector wird genau gleich definiert. Ist aber trotzdem ein 
anderer Typ und muss daher konvertiert werden...

Tabelle schrieb:
> Wenn ich jetzt aber wieder incr einfüge statt +1 habe ich wieder das
> problem dass er nichts simuliert,
Definiere "nichts". Siehst du wenigstens einen Takt?
> Fehlermeldungen gibt es keine aber es tut sich einfach nichts
Du könntest die beiden relevanten Dateien einfach mal hier anhängen...

von Tabelle (Gast)


Angehängte Dateien:

Lesenswert?

Hier mal die beiden Dateien. Ich habe einen Takt aber die 
incrementierung funktioniert nicht.

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


Angehängte Dateien:

Lesenswert?

Tabelle schrieb:
> Ich habe einen Takt aber die incrementierung funktioniert nicht.
Bei mir geht das. Bei dir auch, du musst nur die Simulation WESENTLICH 
länger laufen lassen, denn ein Sinusdurchlauf braucht da ja mehr als 
10ms...

von Tabelle (Gast)


Angehängte Dateien:

Lesenswert?

Das bekomme ich wenn ich acc um 1 incrementiere.

Wenn ich aber wieder um incr incrementiere terminiert die Simulation 
nicht mehr. Auch die Testausgaben kommen nicht mehr, nach dem "-r" 
Befehl tut sich nichts.

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


Lesenswert?

Tabelle schrieb:
> Das bekomme ich wenn ich acc um 1 incrementiere.
Das ist doch gar nicht interessant. Was bekommst du, wenn du genau 
deine Testbench mit deinem DDS-Modul laufen lässt? Wie gesagt: dein 
Design läuft (wenn man auch eine Sinustabelle in einer Zeile einfach vom 
Synthesizer berechnen lassen könnte, siehe [*]). Das, was du hier als 
Anhang sehen kannst, sind genau deine beiden Dateien.

Ich vermute sehr, du simulierst nicht die Testbench, sondern die DDS. 
Wie erzeugst du dienen Takt? Musstest du da noch "zusätzlich" was 
einstellen oder machen?

Zeig mal einen Screenshot von deinem ganzen Projekt incl. Projektbaum.


BTW: es wäre sinnvoll, nicht mit jedem Takt die Meldung "run" 
auszugeben...

[*] http://www.lothar-miller.de/s9y/categories/31-DDFS

von Tabelle (Gast)


Angehängte Dateien:

Lesenswert?

Lothar Miller schrieb:
> Was bekommst du, wenn du genau
> deine Testbench mit deinem DDS-Modul laufen lässt?

Dann bekomme ich ein Konsolenfenster was nicht reagiert. Dass 
analysieren geht aber er bleibt dann beim Befehl
1
>ghdl -r --ieee=synopsys -fexplicit dds_test --vcd=dds.vcd

hängen. Es tut sich absolut garnichts, bis ich es irgentwann abbreche.

Habe im Anhang mal alle Dateien die ich benutze hochgeladen, zum 
simulieren starte ich einfach die .bat und bekomme, wenn alles gut geht, 
die waveform im gtk angezeigt. Soweit kommt er aber nicht.

Das mit den Meldungen liegt daran dass ich bei ersten tests mit 
logikgattern das selbe Verhalten bekommen habe, sprich einen endlos 
laufenden Simulator. Sobald ich nur eine einzige Zeile die eine Ausgabe 
erzeugt hinzugefügt habe ging es dann. Bei der ersten testschleife das 
selbe spielchen, durch die Ausgabe jeden Durchlauf kam die Simulation 
dann zu einem Ende.

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


Lesenswert?

Tabelle schrieb:
> ghdl
Ach so. Ich bin raus...

von Tabelle (Gast)


Angehängte Dateien:

Lesenswert?

Ich hab es mal mit dem ISE Webpack versucht, aber anscheinend kann das 
Programm keine analogen Werte darstellen. Wie hast du diese Wellenform 
so schön hinbekommen, bzw wie simulierst du das?

Wenigstens geht schonmal die Simulation

MfG
Tabelle

von berndl (Gast)


Lesenswert?

Lothar Miller schrieb:
> Tabelle schrieb:
>> ghdl
> Ach so. Ich bin raus...

also ich arbeite hier auch mit GHDL. Wie rufst du denn das ganze auf?
Bei mir hier so:
1
ghdl -i --workdir=work ../*.vhd
2
ghdl -m --workdir=work -P/<xilinx_lib_files>/unisim --ieee=synopsys -fexplicit tb_<design>
3
ghdl -r tb_<design> --vcd=tb_<design>.vcd
Mir war es jetzt zu bloed, dein .zip-file runterzuladen. Aber so 
funktioniert bei mir GHDL prima (unter Linux), das -P/<xilinx_lib_files> 
ist der Pfad zu den compilierten Xilinx Primitives (PLL, ...) falls man 
da was braucht.
Und ich musste auch noch nie was mit 'report' ausgeben, damit das ganze 
laeuft...

von berndl (Gast)


Lesenswert?

Tabelle schrieb:
> Ich hab es mal mit dem ISE Webpack versucht, aber anscheinend kann das
> Programm keine analogen Werte darstellen.
Richtig, ISIM kann das nicht

> Wie hast du diese Wellenform
> so schön hinbekommen, bzw wie simulierst du das?
Mit z.B. Modelsim wenn's Geld kosten darf, oder halt eben mit GHDL und 
GTKWAVE

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


Lesenswert?

Tabelle schrieb:
> wie simulierst du das?
Das ist die kostenlose Version des Aldec Simulators Active-HDL, der bei 
Lattice dabei ist.

> Wie hast du diese Wellenform so schön hinbekommen
Man kann da einfach angeben, wie das Bitmuster des Vektors interpretiert 
werden soll...

ModelSim kann das auch, der ist in der kostenlosen Version bei Altera 
mit drin. Und hoffentlich bekommt X auch mal den ISIM dazu, das 
darzustellen (sooooooo schwer ist das ja nun auch wieder nicht, die 
müssten nur mal einen Praktikanten ein halbes Jahr dransetzen...)

von Dude (Gast)


Lesenswert?

Lothar Miller schrieb:
> Und hoffentlich bekommt X auch mal den ISIM dazu, das
> darzustellen

wird nicht passieren: ISE (und damit ISIM) aist Auslaufmodell!

XSIM (bei Vivado dabei) kanns bereits

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


Lesenswert?

Dude schrieb:
> wird nicht passieren: ISE (und damit ISIM) ist Auslaufmodell!
Na gut. Die ISE war mit PlanAhead (kennt das noch jemand?) auch schon 
mal ein Auslaufmodell, aber diesmal wirds augenscheinlich ernst...

> XSIM (bei Vivado dabei) kanns bereits
Das wäre jetzt mal ein Grund umzustellen, allerdings hatte ich mich 
davon abschrecken lassen:
1
Vivado Design Suite WebPACK Edition supports the Artix™-7 (7A100T, 7A200T),
2
Kintex™-7 (7K70T, 7K160T) and Zynq™-7000 All Programmable SoC Devices 
3
(early access: XC7Z7010, XC7Z7020, XC7Z7030) devices
Und erst mit berappen barer Münze geht es auf zu alten Ufern:
1
Comprehensive Device Support
2
Kintex™-7, Virtex®-7, Zynq™-7000, Virtex-6, Virtex-5, Virtex-4,
3
Virtex-II Pro, Virtex-II, Spartan®-6, Spartan-3
http://www.xilinx.com/support/answers/51081.htm

Aber den Simulator sollte das ja nicht stören...

von Dude (Gast)


Lesenswert?

Lothar Miller schrieb:
> Das wäre jetzt mal ein Grund umzustellen

wir machen (um ggf. schnell wieder auf den alten 'bewährten' Pfad 
zurückschwenken zu können) beides parallel: XSim und ISim:
Scripte sind fast gleich - nur die tool-Optionen beim Aufruf sind 
anders.
aus 'fuse' wird 'xelab' / aus 'isim.exe' wird 'xsim.exe'

Aufpassen: 2 aktuelle 'Nachteile'
1) bei manchen Rechnern (nicht bei allen, obwohl Installation zu 99% 
gleich) versteht sich das generierte .exe nicht mit F-Secure:laut Xilinx 
liegt's am Viren-Scanner - sie sind mit dem Hersteller in Kontakt.

2) im (non-project mode) und den willst Du verwenden, wenn Du NICHT auf 
die 7er Serie zielst, geht der "relaunch button" nicht. Xilinx arbeitet 
aber dran

Ansonsten gefällt mir XSim besser
- bei 'langen' Simulationen (also nicht ein paar FFs für 10 us) geht die 
Simuation schneller - zumindest subjektiv: Stoppuhr noch nicht verwendet
- Analoge Waveforms !!!  ENDLICH
- verschiedene 'optimierungs-level' für 'compile': Unterscheidung 
zwischen 'Debugging' (-> alles sichtbar im GUI-mode) und 
'Regression-Testing' (schnelle Simulation in Batch-Runs) möglich

'Stabilität' ist aktuell kein Thema - aber 'zur' Not könnten wir sofort 
wieder auf ISim umschwenken

von Tabelle (Gast)


Lesenswert?

Ich hab es jetzt mal genauso aufgerufen wie in deinem Beispiel berndl.
1
ghdl -i --workdir=work *.vhdl
2
ghdl -m --workdir=work --ieee=synopsys -fexplicit dds_test
3
ghdl -r dds_test --vcd=dds.vcd
4
5
pause
6
gtkwave -r gtkwaverc dds.vcd

Ergebnis ist wieder gleich: ghdl "hängt" beim -r Befehl und es tut sich 
wieder nichts. Habe auch mal eine halbe Stunde gewartet, bringt auch 
nichts.

Die Auslastung ist auf maximum, ghdl nimmt sich einen kompletten Kern.

von Duke Scarring (Gast)


Lesenswert?

Tabelle schrieb:
> Ergebnis ist wieder gleich: ghdl "hängt" beim -r Befehl und es tut sich
> wieder nichts. Habe auch mal eine halbe Stunde gewartet, bringt auch
> nichts.
>
> Die Auslastung ist auf maximum, ghdl nimmt sich einen kompletten Kern.
Ja, der rechnet und simuliert. Wenn Du die Simulation stoppen willst, 
gibt es mindestens  drei Möglichkeiten:

1. Ctrl-C - ich weiß aber nicht, ob dann das vcd-File richtig 
geschlossen wird.

2. der Kommandozeilenparameter: --stop-time=TIME

3. alle Prozesse stoppen, so das keine Evnets mehr erzeugt werden. Ich 
nutze dafür in meinen Testbenchen folgendes Konstrukt um vor allem den 
Takt anzuhalten:
1
architecture testbench of dut_tb is
2
3
  signal simulation_stop : boolean := false;
4
5
  signal tb_clk : std_ulogic := '0';
6
7
begin
8
9
  tb_clk <= not tb_clk after 10 ns when not(simulation_stop);
10
11
  dut: ...
12
13
  process
14
  begin
15
    wait for 10 ms;
16
    simulation_stop <= true;
17
    wait; -- forever
18
  end process;
19
20
end architecture testbench;

Duke

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.