Forum: FPGA, VHDL & Co. Defaults bei CASE-Anweisungen


von Messi (Gast)


Lesenswert?

Ich habe eine Unsicherheit mit Defaults bei CASE-Anweisungen - ich bin 
nicht sicher, wo die hinkommen und ob das so geht:

Bei der Applikation soll EINER von 4 (demnächst 16) DMA-Kanälen 
beschickt werden. Es sind FIFOs, in die ADR+DAT+CNT eingeschrieben wird.
D.h. alle bis auf 1 Kanal müssen die ENA auf 0 haben.
Ich habe es IN das case geschrieben und da wollte er es nicht haben.
Dann habe ich es VOR den case geschrieben und es simuliert richtig.
Allerdings habe ich seltsame Effekte beim Testen: Manche Kanäle werden 
wegsynthetisiert und ich habe den Verdacht, dass die nicht aktiviert 
werden.

Ist das so in Ordnung?

Oder muss ich bei jedem ENA=1 auch die anderen mit 0 einsetzen?

Ich würde mir das gerne ersparen und verstehen, weil es auf 16 ch 
erweitert werden soll.


1
    
2
        if (high_out ='1') then
3
4
            trx_dma_ch1_ena <= '0';
5
            trx_dma_ch2_ena <= '0';
6
            trx_dma_ch3_ena <= '0';
7
            trx_dma_ch4_ena <= '0';
8
9
            case dma_channel_no is    
10
11
                when "00" =>
12
                    trx_dma_ch1_adr <= inp_dma_trx_adr;
13
                    trx_dma_ch1_dat <= inp_dma_trx_dat;
14
                    trx_dma_ch1_cnt <= trx_dma_ch1_cnt+1;
15
                    trx_dma_ch1_ena <= '1';
16
17
                when "01" =>
18
                    trx_dma_ch2_adr <= inp_dma_trx_adr;
19
                    trx_dma_ch2_dat <= inp_dma_trx_dat;
20
                    trx_dma_ch2_cnt <= trx_dma_ch2_cnt+1;
21
                    trx_dma_ch2_ena <= '1';
22
23
                when "10" =>
24
                    trx_dma_ch3_adr <= inp_dma_trx_adr;
25
                    trx_dma_ch3_dat <= inp_dma_trx_dat;
26
                    trx_dma_ch3_cnt <= trx_dma_ch3_cnt+1;
27
                    trx_dma_ch3_ena <= '1';
28
29
                when others =>
30
                    trx_dma_ch4_adr <= inp_dma_trx_adr;
31
                    trx_dma_ch4_dat <= inp_dma_trx_dat;
32
                    trx_dma_ch4_cnt <= trx_dma_ch4_cnt+1;
33
                    trx_dma_ch4_ean <= '1';

von Achim S. (Gast)


Lesenswert?

Messi schrieb:
> Dann habe ich es VOR den case geschrieben und es simuliert richtig.

geht in Ordnung. Das ganze steht ja innerhalb eines Prozesses. Und wenn 
du innerhalb des Prozesses einem Signal mehrmals nacheinander Werte 
zuweist, dann wird nur die letzte Zuweisung wirksam. Von deinen 
trx_dma_chx_ena Signalen wird also nur eins den Wert 1 haben, die 
anderen wie gewünscht 0.

Messi schrieb:
> Allerdings habe ich seltsame Effekte beim Testen: Manche Kanäle werden
> wegsynthetisiert und ich habe den Verdacht, dass die nicht aktiviert
> werden.

Vielleicht nimmt dma_channel_no nie den Wert des weg-optimierten Kanals 
an. Oder high_out wird nie 1. Oder irgendwas anderes, das man deinem 
Code-Schnippsel nicht ansehen kann.

von J. S. (engineer) Benutzerseite


Lesenswert?

Achim S. schrieb:
> Vielleicht nimmt dma_channel_no nie den Wert des weg-optimierten Kanals
> an.

Oder hinten dran hängt irgend etwas dran, was nicht richtig ist und 
Ursache für das Verschwinden ist.

@TE: Verwendest du Code Coverage? Damit lässt sich manch ein 
undefinierter Ast in den IFs auffinden.

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


Lesenswert?

Messi schrieb:
> Ist das so in Ordnung?
Eines vorneweg: ganz pfiffig wäre es, die DMA-Kanal-Namensgebung wie in 
der Software- und Hardwarewelt üblich bei 0 beginnen zu lassen. Denn 
wenn "00" den Kanal 1 auswählt und "11" den Kanal 4, dann ist das 
zumindest arg unglücklich.

> Oder muss ich bei jedem ENA=1 auch die anderen mit 0 einsetzen?
Das kommt darauf an, wie diene Hardware diese DMA-Anforderungen 
abhandelt.

> D.h. alle bis auf 1 Kanal müssen die ENA auf 0 haben.
Ich würde dann den gesamten Klimbim von der Datenstruktur her nicht auf 
dieses ausufernde Copy&Paste ausrichten, sondern mit Arrays und einem 
Index arbeiten.
Und vor Allem auch mit Datentypen, die Mehrdeutigkeiten ausschließen. 
Zuallerserst gehört der dma_channel_no vom std_logic_vector in einen 
Integer mit dem range 0 to 15 umgewandelt. Denn dann kannst du den 
aktiven DMA-Kanal eben auch als Integer abspeichern und hast in 4 Bits 
automatisch nur 1 einzigen aktiven "Kanal", statt einer one-hot 
codierten Kanalauswahl mit 15 Bits auf '0' und 1 Bit auf '1'.

> trx_dma_ch1_ena
Wenn du deine Signale umbenennen würdest, könntest du mit Indices 
arbeiten. Hier mal dein Copy-Paste-Ansatz:
1
:
2
signal std_logic trx_dma_ch1_ena, 
3
                 trx_dma_ch2_ena,
4
                 trx_dma_ch3_ena,
5
                 trx_dma_ch4_ena,
6
                 :
7
                 :
8
                 :
9
                 trx_dma_ch15_ena,
10
                 trx_dma_ch16_ena;
11
:
12
:
13
            trx_dma_ch1_ena <= '0';
14
            trx_dma_ch2_ena <= '0';
15
            trx_dma_ch3_ena <= '0';
16
            trx_dma_ch4_ena <= '0';
17
            trx_dma_ch5_ena <= '0';
18
            trx_dma_ch6_ena <= '0';
19
            trx_dma_ch7_ena <= '0';
20
            trx_dma_ch8_ena <= '0';
21
            trx_dma_ch9_ena <= '0';
22
            trx_dma_ch10_ena <= '0';
23
            trx_dma_ch11_ena <= '0';
24
            trx_dma_ch12_ena <= '0';
25
            trx_dma_ch13_ena <= '0';
26
            trx_dma_ch14_ena <= '0';
27
            trx_dma_ch15_ena <= '0';
28
            trx_dma_ch16_ena <= '0';
29
:
30
            case dma_channel_no is    
31
32
                when "0000" =>
33
                    trx_dma_ch1_ena <= '1';
34
:
35
                when "0001" =>
36
                    trx_dma_ch2_ena <= '1';
37
:
38
:
39
:
40
:
41
:
42
                    trx_dma_ch15_ena <= '1';
43
:
44
                when "1111" =>
45
                    trx_dma_ch16_ena <= '1';
46
:
Das zieht sich hin, braucht laufend viel Tipparbeit und wehe, da 
vergisst mal einer, eine Zahl anzupassen...

Das wäre eine kompaktere one-hot-Lösung:
1
:
2
signal trx_dma_ena : std_logic_vector (15 downto 0);
3
:
4
     trx_dma_ena <= (others=>'0');
5
:
6
     trx_dma_ena(to_integer(unsigned(dma_channel_no)) <= '1';
7
:

Und ich würde zusehen, dass ich es so machen kann:
1
:
2
signal trx_dma_ena : integer range 0 to 15 := 0;
3
:
4
:
5
:
6
     trx_dma_ena <= to_integer(unsigned(dma_channel_no));
7
:

: Bearbeitet durch Moderator
von Messi (Gast)


Lesenswert?

Die Idee der geschickten Zusammenfassung hatte ich auch bereits. Es ist 
aber leider so, dass der Code für die anderen Kanäle komplizierter ist 
und die Signale dort anders heißen und einige auch für Umsetzer in 
anderen Baugruppen laufen. Ich möchte das nicht alles ändern, weil 
Vieles aus Schaltplänen kommt, die mitgeändert werden müssten.

Mir kommt es einfach darauf an, zu wissen, ob das synthesemäßig i.O. 
ist.

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.