Forum: FPGA, VHDL & Co. STD_LOGIC_VECTOR Änderung erfassen


von Alaatdin Özdemir (Gast)


Lesenswert?

Ich habe eine Signal(std_logic_vector) und jedesmal wenn dieses Signal 
sich ändert(egal welche Bit, Hauptsache anders als vorherige wert ist) 
ich muss durch eine andere Signal(std_logic) mit der Wert 1 
signalisieren.
1
   signal SIG           : std_logic_vector(15 downto 0);
2
   signal SIG_VERZOGERT : std_logic_vector(15 downto 0);
3
   signal SIG_CHANGED   : std_logic;
4
5
    PROCESS (SIG, CLK, rst) is
6
    BEGIN
7
  IF(rst='0') then
8
            SIG_VERZOGERT <= (OTHERS => '0');
9
  ELSIF rising_edge(CLK) then  
10
            SIG_VERZOGERT <= SIG;
11
        END IF;
12
    END PROCESS;
13
    SIG_CHANGED <= or_reduce(SIG_VERZOGERT xor SIG);

obwohl SIG sich ständig ändert bekomme ich auf SIG_CHANGED keine impuls, 
sondern immer 0;

kann jemand bitte helfen?

: Bearbeitet durch Moderator
von Tobias B. (Firma: www.elpra.de) (ttobsen) Benutzerseite


Lesenswert?

Ohne or_reduce waere:
1
SIG_CHANGED <= '1' when SIG_VERZOGERT /= SIG else '0';

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


Lesenswert?

Alaatdin Özdemir schrieb:
> obwohl SIG sich ständig ändert bekomme ich auf SIG_CHANGED keine impuls,
> sondern immer 0;
Wie stellst du das fest?

Mit welcher Testbench überprüfst du das? Lass doch mal einen Screenshot 
deiner Waveform sehen, wo dieses Verhalten erkennbar ist.

von Fpgakuechle K. (Gast)


Lesenswert?

> obwohl SIG sich ständig ändert bekomme ich auf SIG_CHANGED keine impuls,
> sondern immer 0;

Tja, vielleicht ändert clk nicht oder rst hockt auf '0' ...

von Vancouver (Gast)


Lesenswert?

Sieht eigentlich alles richtig aus, außer dass SIG nicht in die 
Sens-Liste gehört. Damit baust du dir ein übles Latch.
Ich würde auch einen Dauerreset vermuten.

von Dussel (Gast)


Lesenswert?

Vancouver schrieb:
> Sieht eigentlich alles richtig aus, außer dass SIG nicht in die
> Sens-Liste gehört. Damit baust du dir ein übles Latch.
Wie und warum? Hat die Sensitivity-List Auswirkungen auf die Synthese?

von Duke Scarring (Gast)


Lesenswert?

Dussel schrieb:
> Hat die Sensitivity-List Auswirkungen auf die Synthese?
Indirekt ja. Die Simulation reagiert drauf und die Hardware nicht.
Dann passen Simulation und Hardware nicht zusammen.

Duke

von Dussel (Gast)


Lesenswert?

Duke Scarring schrieb:
> Dussel schrieb:
>> Hat die Sensitivity-List Auswirkungen auf die Synthese?
> Indirekt ja. Die Simulation reagiert drauf und die Hardware nicht.
> Dann passen Simulation und Hardware nicht zusammen.
Sehr indirekt.
Aber hier ging es ja darum, dass ein Latch entstehen würde. Aber wo und 
wie?
Ich frage, weil ich es mir nicht erklären kann. Aber es kann ja auch 
sein, dass ich falsch liege.

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


Lesenswert?

Vancouver schrieb:
> Sieht eigentlich alles richtig aus, außer dass SIG nicht in die
> Sens-Liste gehört. Damit baust du dir ein übles Latch.
Eigentlich nicht, denn
1. dem Synthesizer ist die Sensitivliste egal
und
2. wenn im Simulator rst low ist, dann wird SIG gar nicht abgefragt, 
wenn es aber high ist, dann braucht es punktgenau eine Flanke vom Takt
und
3. wenn ein Takt beteiligt ist, dann gibts kein Latch, sondern 
Flipflops.

Dussel schrieb:
> Aber hier ging es ja darum, dass ein Latch entstehen würde. Aber wo
Nirgends. Der Simulator rechnet einfach den Prozess unnötigerweise mit 
jedem Wechsel von SIG durch. Sowas zeigt halt jedem: "Obacht, ein 
Anfänger!"

Duke Scarring schrieb:
> Dussel schrieb:
>> Hat die Sensitivity-List Auswirkungen auf die Synthese?
> Indirekt ja. Die Simulation reagiert drauf und die Hardware nicht.
> Dann passen Simulation und Hardware nicht zusammen.
Deshalb meine Frage, wie das Fehlverhalten festgestellt wird. Aber mich 
beschleicht der Verdacht, dass wir das nicht mehr erfahren werden...

: Bearbeitet durch Moderator
von Fpgakuechle K. (Gast)


Lesenswert?

Lothar M. schrieb:
> Vancouver schrieb:
>> Sieht eigentlich alles richtig aus, außer dass SIG nicht in die
>> Sens-Liste gehört. Damit baust du dir ein übles Latch.
> Eigentlich nicht, denn
> 1. dem Synthesizer ist die Sensitivliste egal

Das kann man so vermuten, es muß aber nicht so sein. Fakt ist, das 
VHDL-Synthese im Gegensatz zur Simulation nicht genormt ist und somit 
jedes Synthesetool seinen eigenen Synthesis Style Guide' mitbringt indem 
beschrieben wird, wie das VHDL-Schnipsel auszusehen hat, damit diese 
VHDL-Hochsprachenkonstrukt auf das reale Schaltelement (FF,Latch, 
[ruckgekoppelte Logik]) abgebildet wird.
Hinzukommt kommen die Einschränkungen, die der jeweilige FPGA/ASIC-Typ 
mitbringt, also ob sich darin überhaupt  Schaltungselemente finden mit 
denen ein Latch oder interner Tristate oder FF mit asynchronen und/oder 
synchreon Set/Reset odr ... realisieren lassen. Ein FPGA ohne die 
Möglichkeit an beliebiger Stelle ein Latch einzubauen, könnte eine 
'Latch-ähnliche Beschreibung ignorieren, ein anderes kann versucht sein, 
da unbedingt eins mit 'kruden' Verschaltungen einzubauen.

Deshalb sollte man IMHO nur die exakten Templates aus den jeweiligen 
Synthese-Style-Guides verwenden und auch nicht 'mischen'. Also bei FF 
mit synchronen Reset nur clk in der sensetivity list, bei FF mit 
asynchronen reset ist clock und reset (aber auch nicht mehr) in der 
sense.- Liste zu finden. Solch 'sauberer' Code macht dann auch die 
Qualifikation desselben für höhere Sicherheitsanforderungen (bspw. 
Flugzeug) einfacher.
Und sauberer Code verlangt, das sich der Code-schreiber selbst überlegt, 
ob er hier ein (störanfalliges) Latch haben will und nicht ein FF. Aber 
gerade daran scheitern manche FPGA-Einsteiger, weil sie 'aus der 
Software-Ecke' kommen und wenig bis kein Grundwissen über Hardwaredesign 
und Schaltungstechnik haben.


Und nicht zuletzt haben auch Synthesetools Bugs, in die man mit allzu 
frei geschriebenen Code stolpert:
https://johnwickerson.github.io/papers/verismith_fpga20.pdf

Die Style guides für Xilinx, Altera, Lattice:
https://wiki.electroniciens.cnrs.fr/images/Xilinx_HDL_Coding_style.pdf

https://www.intel.com/content/dam/www/programmable/us/en/pdfs/literature/hb/qts/qts_qii51007.pdf

https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=&cad=rja&uact=8&ved=2ahUKEwi71cjBgvf1AhWJQ_EDHQNvBR0QFnoECA4QAQ&url=http%3A%2F%2Fwww.latticesemi.com%2F-%2Fmedia%2FLatticeSemi%2FDocuments%2FApplicationNotes%2FEH%2FHDLSynthesisCodingGuidelinesforLatticeFPGAs.ashx%3Fdocument_id%3D4815&usg=AOvVaw3AwQfSJDWHqL-wuyM1xyMQ

von Markus F. (mfro)


Lesenswert?

VHDL 2008 erlaubt "all" in der Sensitivliste.

Und ich sehe keinerlei Grund, da (in 2022) noch irgendwas anderes 
hinzuschreiben.

von Fpgakuechle K. (Gast)


Angehängte Dateien:

Lesenswert?

Markus F. schrieb:
> VHDL 2008 erlaubt "all" in der Sensitivliste.
>
> Und ich sehe keinerlei Grund, da (in 2022) noch irgendwas anderes
> hinzuschreiben.

Naja, selbst 2022 gibt es Simulatoren die VHDL'93 und nicht 2008 
komplett unterstützen. Oder die alten Coden anmaulen, wenn 2008 
aktiviert ist. Und Synthesetools kochen ohnehin ihr eigens Süppchen.

Persönlich finde ich hinsichtlich der Les-/ und Wartbarkeit besser, wenn 
man mit kurzen Blick auf die sensetivity List erfassen kann, ob es sich 
um einen kombinatorischen oder sequentiellen 'Block' handelt, ob 
asynchron oder synchron Rest und in welcher Taktdomain sich der Block 
befindet. Eine sensetivity list "(all)" verrät das alles nicht, da muß 
man u.U. durch den ganzen Block lesen um das wait until zu vinden.

Also meines Erachtens gibt es schon gute Gründe eine exakte 
sensitivitylist zu verwenden. Manche editoren wie emacs im VHDL-mode 
bieten auch gleich das passende template zum Implementierungswunsch an 
(siehe Anhang)

von Markus F. (mfro)


Lesenswert?

Ich soll mir C-c C-tps merken?

Da such' ich lieber nach dem rising_edge() ;)

(aber jeder wie er mag)

von Fpgakuechle K. (Gast)


Lesenswert?

Markus F. schrieb:
> Ich soll mir C-c C-tps merken?
>
> Da such' ich lieber nach dem rising_edge() ;)
me too ;-) - Dem Alter von Stützrädern am Radl und Templates im Editor 
bin ich entwachsen.

Und ich würd eher nach dem clk_i suchen, nicht das es grad die 
'Design-ecke' auf fallende Flanke ist.

> (aber jeder wie er mag)
oder als blutiger Anfänger braucht.

von New C. (wunderlampe)


Lesenswert?

Statt, den Signal verzögern und neue mit alte abgleichen, kann ich nicht 
einfach eine process machen in der sensitivliste nur SIG aufnehmen und 
drinen einfach  SIG_CHANGED <= toggle schreiben?

    PROCESS (SIG) is
    BEGIN
            SIG_CHANGED <= impuls;
    END PROCESS;

SIG ist eine graycode, da kann bei jeder Änderung nur ein Bit ändern, es 
ist für mich unwichtig welche Bit geändert ist Hauptsache man hat eine 
neue SIG.

ich lerne VHDL erst. Nach meine Verständnis, wenn SIG ändert sollte 
prozess aktiv werden.

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


Lesenswert?

New C. schrieb:
> wenn SIG ändert sollte prozess aktiv werden.
Wie ich schon schrieb:
> dem Synthesizer ist die Sensitivliste egal
Oder anders: die Sensitivliste ist nur für die Simulation relevant.

Dein Ansatz funktioniert also nur im Simulator. Wenn das reicht, dann 
nur zu.

New C. schrieb:
> ich lerne VHDL erst. Nach meine Verständnis, wenn SIG ändert sollte
> prozess aktiv werden.
So ein Prozess wird in Hardware realisiert. Diese Hardware ist immer 
aktiv. Und in der Hardware gibt es keinen "Sensitivlistenparser" der auf 
irgendeine Änderung wartet.

Mach dir klar, was das D in VHDL heißt und was es bedeutet: du nimmst 
eine HardwareBESCHREIBUNGssprache dafür, eine Hardware in Textform zu 
beschreiben. Du musst also erst mal einen "Schaltplan" (wenigstens in 
Funktionsblöcken) im Kopf oder auf dem Papier haben, den du dann mit 
VHDL beschreiben kannst.
Natürlich könntest du diesen Schaltplan auch in Vivado oder Quartus 
zeichnen, aber eine solche grafische Darstellung ist eben viel 
umständlicher zu managen, schlecht vergleichbar und nicht portierbar. 
Deshalb nimmt man VHDL.

: Bearbeitet durch Moderator
von Fpgakuechle K. (Gast)


Lesenswert?

New C. schrieb:

> SIG ist eine graycode, da kann bei jeder Änderung nur ein Bit ändern, es
> ist für mich unwichtig welche Bit geändert ist Hauptsache man hat eine
> neue SIG.
>
> ich lerne VHDL erst. Nach meine Verständnis, wenn SIG ändert sollte
> prozess aktiv werden.

Dein Verständnis und code  ist an meherenen Stellen falsch.
Die signale in der sensetivity list steuern den process nicht durch 
bit-änderung, sondern wenn an diesen ein Event (Ereignis) passiert. 
Genaugenommen ist auch die Zuweisung mit dm selben Wert ein Ereignis. 
Und da der verwendetet vector aus std_logic und nicht aus bit aufgebaut 
ist, könnte man auch Werterhaltenen Änderungen wie 'H' auf '1' oder 'L' 
auf '0' aussortieren.

Und din deinem Process gibt es auch keine wirklich Impulsformung.

Besorg dir ein gutes Buch über VHDL oder gleich das LRM und arbeitet das 
durch. Insbesonders die Definition von Ereignis und das zugehörige 
Attribur 'event. https://edg.uchicago.edu/~tang/VHDLref.pdf

von New C. (wunderlampe)


Lesenswert?

PROCESS (CLK_200MHz) is
    BEGIN
    IF rising_edge(CLK_200MHz) then
            SIG_VERZOGERT <= SIG;
       END IF;
    END PROCESS;
   SIG_CHANGED <= '0' when
         (SIG_VERZOGERT(0)=SIG(0)  AND
         SIG_VERZOGERT(1)=SIG(1) AND
         SIG_VERZOGERT(2)=SIG(2) AND
         SIG_VERZOGERT(3)=SIG(3) AND
         SIG_VERZOGERT(4)=SIG(4) AND
         SIG_VERZOGERT(5)=SIG(5) AND
         SIG_VERZOGERT(6)=SIG(6) AND
         SIG_VERZOGERT(7)=SIG(7) AND
         SIG_VERZOGERT(8)=SIG(8) AND
         SIG_VERZOGERT(9)=SIG(9))
      else '1';

Ich habe meine Code so geändert(auch reset weggetan). Und immernoch 
Ausgang bleibt LOW.

Zum überprüfen ob Signal wirklich auf dem Ausgang richtig kommt habe ich 
auch
'0' when ... else '1'; mit else '1' when ... else '0';
und gesehen Ausgang ist jetzt immer HIGH.

noch einfache kann man den code nicht mehr gestalten denke ich.
kann das Clock welches 200MhZ ist eine rolle spielen?

von Fpgakuechle K. (Gast)


Lesenswert?

Der gezeigte Code scheint zu passen, also wird das Problem im nicht 
gezeigten sein. Bitte mal auf die Rückfragen in: 
Beitrag "Re: STD_LOGIC_VECTOR Änderung erfassen"

eingehen.

von New C. (wunderlampe)


Angehängte Dateien:

Lesenswert?

1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use ieee.std_logic_misc.all;  --or_reduce
4
use IEEE.NUMERIC_STD.ALL;
5
library UNISIM;
6
use UNISIM.VComponents.all;
7
8
entity Yazboz_main is
9
    Port ( 
10
    sys_clk_p : in  STD_LOGIC;
11
    sys_clk_n : in  STD_LOGIC;        
12
        rst           : in std_logic;
13
        -- ==================================================
14
        LED_0        : out std_logic;
15
         -- ==================================================
16
        SIG          : in std_logic_vector(9 downto 0);
17
        SIG_CHANGED  : out STD_LOGIC := '0'
18
    );
19
end Yazboz_main;
20
21
architecture Behavioral of Yazboz_main is
22
23
    signal sys_clk: std_logic;
24
    signal clk:     std_logic; --200.000MHz 
25
  -- ==================================================
26
  signal SIG_VERZOGERT        : std_logic_vector(9 downto 0);
27
   signal SIG_CHANGED_REG      : std_logic; 
28
       
29
begin
30
31
IBUFDS_inst : IBUFDS
32
   generic map ( DIFF_TERM => FALSE, IBUF_LOW_PWR => TRUE, IOSTANDARD => "DEFAULT")
33
   port map ( O => sys_clk, I => sys_clk_p, IB => sys_clk_n  );
34
BUFG_inst : BUFG
35
   port map ( O => clk, I => sys_clk );
36
37
          
38
PROCESS (clk) is
39
    BEGIN
40
    IF rising_edge(clk) then
41
            SIG_VERZOGERT <= SIG;
42
       END IF;
43
    END PROCESS;
44
   SIG_CHANGED_REG <= '0' when
45
         (SIG_VERZOGERT(0)=SIG(0)  AND
46
         SIG_VERZOGERT(1)=SIG(1) AND
47
         SIG_VERZOGERT(2)=SIG(2) AND
48
         SIG_VERZOGERT(3)=SIG(3) AND
49
         SIG_VERZOGERT(4)=SIG(4) AND
50
         SIG_VERZOGERT(5)=SIG(5) AND
51
         SIG_VERZOGERT(6)=SIG(6) AND
52
         SIG_VERZOGERT(7)=SIG(7) AND
53
         SIG_VERZOGERT(8)=SIG(8) AND
54
         SIG_VERZOGERT(9)=SIG(9))
55
      else '1';
56
     
57
    LED_0  <= SIG_CHANGED_REG;  
58
    SIG_CHANGED <= SIG_CHANGED_REG;     
59
60
61
end Behavioral

Das ist mein gesamtes code. Ich verwende KC705 Xilinx Kintex7.
mit Modelsim soviel ich verstehen kann, funktioniert. Auf Hardware keine 
Änderung auf Signal&LED.

von Achim S. (Gast)


Lesenswert?

New C. schrieb:
> Modelsim soviel ich verstehen kann, funktioniert.

Ja, funktioniert...

New C. schrieb:
> Auf Hardware keine
> Änderung auf Signal&LED.

dann hast du vielleicht deine Signale sig_changed und LED mit anderen 
Ausgängen verbunden, als du eigentlich meinst. D.h. irgendein Pin geht 
vielleicht im richtigen Moment auf 1, aber nicht der Pin, den du 
beobachtest.

Und zur Sicherheit: was meinst du egnau mit "keine Änderung auf Signal". 
Hoffentlich den Ausgang sig_changed.

Falls du stattdessen vom Signal sig sprechen solltest: das ist ein 
Eingang. Damit dort eine Änderung auftaucht, musst du extern die 
Eingänge auf geänderte Werte treiben.

Und auch die Eingänge müssen natürlich mit den richtigen input-Pins 
verbunden sein. Welche das sind, siehst du in den reports. Und 
üblicherweise musst du selbst entpsprechende constraints vorgeben, die 
festlegen, mit welchen pins deine Signale verbunden sind.

Und noch als allerletzten Hinweis: bei jedem Wechsel von sig gehen deine 
Ausgänge nur einen Taktzyklus lang auf 1. In deiner Simu sind das nur 
5ns. Die Zeit ist zu kurz, um sie mit einem Multimeter (oder bei der LED 
mit dem Auge) erkennen zu kennen. Um zu messen, ob die Pulse da sind, 
brauchst du ein Oszi.

von New C. (wunderlampe)


Lesenswert?

Ja ich beobachte immer den Ausgangspin(von SIG_CHANGED) und LED.
Ich habe einen Oszi mit 200MHz der zeigt auch keine erkennbare Signal

meine Contrains sind richtig, das habe ich ausprobiert mit eine einfache 
code.

wenn ich diese Signaländerungscode mit eine null Überprüfung Code wie 
unten ersetze , es funktioniert und ich sehe immer wenn der Signal null 
ist am Led
1
  PROCESS (clk) is
2
  BEGIN
3
  IF rising_edge(clk) then  
4
     if SIG= '0000000000'then SIG_CHANGED_REG   <= '1';     else      SIG_CHANGED_REG   <= '0';  end if;
5
  END IF;
6
  END PROCESS;  
7
  SIG_CHANGED <= SIG_CHANGED_REG;
8
        LED_0  <= SIG_CHANGED_REG;

aber selbstverständlich der SIG signal bleibt sehr sehr lange auf null 
(ca 1 sekunde) deshalb auch auf dem Led sichtbar.

wenn wir bei diese Sache sind, wie kann ich eine Signal ausgeben, der 
statt 1 mehrere Taktzyklen lang ist? FPGA clock ist 200Mhz , signal 
Änderung aber höstenst 1 Mhz schnell

: Bearbeitet durch User
von Achim S. (Gast)


Lesenswert?

New C. schrieb:
> wenn ich diese Signaländerungscode mit eine null Überprüfung Code wie
> unten ersetze , es funktioniert und ich sehe immer wenn der Signal null
> ist am Led

Also zusammengefasst:
- der VHDL-Code ist richtig (wie im Simulator zu sehen)
- die constraints sind richtig
- der alternative Code
   "  if SIG= '0000000000'then SIG_CHANGED_REG   <= '1';
      else      SIG_CHANGED_REG   <= '0';
      end if;"
   funktioniert wie erwartet

Wenn das alles stimmt, dann fällt mir nur noch ein, dass du das Oszi 
nicht richtig triggerst und deswegen den Puls nicht siehst (obwohl er 
tatsächlich auftritt).

von Fpgakuechle K. (Gast)


Angehängte Dateien:

Lesenswert?

Achim S. schrieb:

> Wenn das alles stimmt, dann fällt mir nur noch ein, dass du das Oszi
> nicht richtig triggerst und deswegen den Puls nicht siehst (obwohl er
> tatsächlich auftritt).

Falls der verwendete FPGA in der Lage ist, einen Puls von 5 ns Breite 
sicht- resp. triggerbar rauszuballern ... insbesonders, wenn an diesem 
Pin auch noch eine LED mit Serienwiderstand hängt ...

Die ganze Nachweis-Idee ist murks, besser ein T-FF am Ausgang verwenden.

von Achim S. (Gast)


Lesenswert?

Fpgakuechle K. schrieb:
> insbesonders, wenn an diesem
> Pin auch noch eine LED mit Serienwiderstand hängt ...

wenn ich richtig interpretiere hängt am Ausgang SIG_CHANGED keine Last 
(außer dem Oszi). Kann schon sein, dass es nicht für einen hübschen 5ns 
Rechteckpuls reicht (zumal auch nicht klar ist, womit das Oszi 
angeschlossen wurde und wie stark es den FPGA-Treiber kapazitiv 
belastet). Aber dass es nicht für ein trigger- und erkannbares Signal 
reicht, wäre schon seltsam.

Als kleiner Test mal die Bitte an New C: sei so nett, lade nochmal den 
funktionierenden, alternativen Code
   "  if SIG= '0000000000'then SIG_CHANGED_REG   <= '1';
      else      SIG_CHANGED_REG   <= '0';
      end if;"
und triggere das Oszi auf eine Flanke. Stelle die Zeitablenkung des 
Oszis dabei in den ns-Bereich. Und dann zeig uns hier einen Screenshot 
deiner Oszi-Messung. Damit sollten wir auch einem möglichen Messproblem 
auf den Grund gehen können.

von New C. (wunderlampe)


Lesenswert?

Der Grund war zu kurze impulsdauer(5 ns). Nachdem ich statt Impuls eine 
toggle gebaut habe und clock verringert habe war der Signal richtig 
erfassbar und auch optisch sichtbar.
Tolle Forum Tolle Unterstüzung. Ich bedanke mich an allen die 
geantwortet haben.

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.