Mux mit One-Hot Eingang

Persönliche Seite #3418841
Lesenswert?

slv_sel ist ein std_logic_vector welcher die Ergebnisse von vier 
Komparatoren zusammen fasst. Im Normalfall darf nur einer anschlagen 
(hoffentlich :)) und je nachdem welcher anschlägt soll aus dem 
record-Array rec_arr ein Record auf den Record rec_out gegeben werden.
1
WITH slv_sel SELECT
2
rec_out <= rec_arr(0) WHEN "0001",
3
           rec_arr(1) WHEN "0010",
4
           rec_arr(2) WHEN "0100",
5
           rec_arr(3) WHEN "1000",
6
           rec_arr(0) WHEN others;

Wie kann man das ganze schöner schreiben? Die Größe von rec_arr und die 
Länge von slv_sel soll über eine Generic anpassbar sein. Die Größe von 
rec_arr und die Länge von slv_sel stimmt immer überein.

Ich denke über eine FOR-Loop mit GENERATE-Anweisung könnte das klappen, 
oder? Nur wie genau?
Gast #3419273
Lesenswert?

>Ich denke über eine FOR-Loop mit GENERATE-Anweisung könnte das klappen,
>oder? Nur wie genau?


Genau genohmen ist eine for -schleife was komplett anderes als eine 
generate schleife.

sowas wie
1
for i in 0 to 9 loop   
2
--.....
3
end loop;


passt nur in prozessen,
während
1
Generate_loop: for i in 0 to 9 generate 
2
--..
3

4
end generate Generate_loop;

 nur außerhalb von prozessen erlaubt ist. Eine foor loop mit generate 
ist nich.

IMHO möchtest du für deine Anwendung eine for - loop und kein generate.

MfG;
Moderator (Firma: Titel) Persönliche Seite #3419307
Lesenswert?

Das "when others" ist mir nicht ganz klar. Ist das nötig oder nur ein 
kleiner Hilfeschrei? Wäre es schlimm oder was würde passieren, wenn du 
sowas schreiben würdest:
1
WITH slv_sel SELECT
2
rec_out <= rec_arr(0) WHEN "0001",
3
           rec_arr(1) WHEN "0010",
4
           rec_arr(2) WHEN "0100",
5
           rec_arr(3) WHEN others;


Wenn du deine Beschreibung umschreibst, dann kommst du schnell auf 
sowas:
1
 rec_out <= rec_arr(0) WHEN slv_sel(0)='1' ELSE
2
            rec_arr(1) WHEN slv_sel(1)='1' ELSE
3
            rec_arr(2) WHEN slv_sel(2)='1' ELSE
4
            rec_arr(3) WHEN slv_sel(3)='1' ELSE
5
            rec_arr(0);
Und das erinnert mich irgendwie an die Sache mit dem or_reduce() von 
letzter Woche im Beitrag "Über Conditions loopen (VHDL)"...
Persönliche Seite #3419358
Lesenswert?

Leonard Lebewohl schrieb:
> Genau genohmen ist eine for -schleife was komplett anderes als eine
> generate schleife.

Also soweit ich weiss verwendet man For-Schleifen in Prozessen und 
Generate-Schleifen in der Architektur.

Meine Beschreibung steht in der Architektur und soll nebenläufig sein, 
daher die Idee mit der Generate-Schleife.

Lothar Miller schrieb:
> Wenn du deine Beschreibung umschreibst, dann kommst du schnell auf
> sowas: rec_out <= rec_arr(0) WHEN slv_sel(0)='1' ELSE
>             rec_arr(1) WHEN slv_sel(1)='1' ELSE
>             rec_arr(2) WHEN slv_sel(2)='1' ELSE
>             rec_arr(3) WHEN slv_sel(3)='1' ELSE
>             rec_arr(0);
> Und das erinnert mich irgendwie an die Sache mit dem or_reduce() von
> letzter Woche im Beitrag "Über Conditions loopen (VHDL)"...

Ja, kann man auch gerne so schreiben. Nur wie bringe ich das jetzt in 
eine Form, dass ich die Länge von slv_sel und die Göße von rec_arr 
parametrieren kann?

Mir ist im grunde egal ob das über Generate-Loop oder eine Funktion 
geht, ich will nur eine Lösung :-P

Was das mit dem erwähnten Beitrag zu tun hat sehe ich noch nicht, werde 
ihn mir mal etwas genauer durchlesen.
#3419768
Lesenswert?

Mal ein Vorschlag als kombinatorischer Prozess:
1
onehotmux: process (slv_sel) is
2
begin  -- process onehotmux
3
    variable i : natural;
4
  begin
5
    assert rec_arr'length = slv_sel'length report "One-Hot Mux: Selection range" &
6
      " doesn't fit with range of input array" severity error;
7
    
8
    i := 0;
9

10
    -- convert one-hot encoding to integer
11
    for k in slv_sel'range loop
12
      if slv_sel(k) = '1' then
13
        i := k;
14
      end if;
15
    end loop;
16
    
17
    rec_out := rec_arr(i);
18

19
end process onehotmux;

Das ganze kann man auch komplett generisch beschreiben mit Hilfe einer 
Funktion und eigenen Datentypdefinitionen (die man praktischerweise in 
einem Package zusammen hat).
#3420953
Lesenswert?

Danke. War gestern ein bisschen voreilig. Dachte ich könnte das schnell 
beschreiben und dann zu meiner Sammlung von Funktionen hinzufügen. 
Realisierte dann aber, dass für den Fragesteller mein Code nicht so 
hilfreich wäre (Müsste dann das ganze Package veröffentlichen mit 
Beispiel). Also habe ich dann den Schnellschuss produziert.
1
onehotmux: process (slv_sel, rec_arr) is
2
begin  -- process onehotmux
3
    variable i : natural;
4
  begin
5
    assert rec_arr'length = slv_sel'length report "One-Hot Mux: Selection range" &
6
      " doesn't fit with range of input array" severity error;
7
    
8
    i := 0;
9

10
    -- convert one-hot encoding to integer
11
    for k in slv_sel'range loop
12
      if slv_sel(k) = '1' then
13
        i := k;
14
      end if;
15
    end loop;
16
    
17
    rec_out := rec_arr(i);
18

19
end process onehotmux;
Gast #3420980
Lesenswert?

Lothar Miller schlug vor:
1
WITH slv_sel SELECT
2
rec_out <= rec_arr(0) WHEN "0001",
3
           rec_arr(1) WHEN "0010",
4
           rec_arr(2) WHEN "0100",
5
           rec_arr(3) WHEN others;

1
Wenn du deine Beschreibung umschreibst, dann kommst du schnell auf 
2
sowas: rec_out <= rec_arr(0) WHEN slv_sel(0)='1' ELSE
3
            rec_arr(1) WHEN slv_sel(1)='1' ELSE
4
            rec_arr(2) WHEN slv_sel(2)='1' ELSE
5
            rec_arr(3) WHEN slv_sel(3)='1' ELSE
6
            rec_arr(0);


--

Nein das ist nicht identisch bspw. für slv_sel "0110". Oberes selektiert
(3), der zweite code dagegen  (1).

MfG,
#3421068
Lesenswert?

Leonard Lebewohl schrieb:
> Das others wird nicht identisch umgesetzt.

Korrekt. Da ist auch noch die Frage offen, ob das others genau so sein 
muss oder nicht.

Dieses Verhalten kann nach Wunsch mit dem Initalwert von "i" angepasst 
werden.

Leonard Lebewohl schrieb:
> Sind unerwarteterweise zwei bits '1' wird nicht (0) selektiert sondern der Kanal 
der der höherwertigen '1' zugeordnet ist.

Kommt darauf an ob slv_sel auf- oder absteigend ist. Man kann auch 
dieses Verhalten explizit beeinflussen.
1
for k in slv_sel'range loop

ersetzen durch:
1
for k in slv_sel'high downto slv_sel'low loop

Dann wird bei mehreren gesetzten '1' immer der niedrigste bevorzugt. 
(Letzte zuweisung gewinnt).
Moderator (Firma: Titel) Persönliche Seite #3421190
Lesenswert?

Leonard Lebewohl schrieb:
> Nein das ist nicht identisch ...
Der others-Fall ist offenbar nicht so wichtig, denn ich hatte da schon 
nachgefragt, und
Marius S. schrieb:
> Lothar Miller schrieb:
>> Wenn du deine Beschreibung umschreibst, dann ...
> Ja, kann man auch gerne so schreiben.
Also muss im Konfliktfall nicht unbedingt das erste Element selektiert 
werden.
Moderator (Firma: Titel) Persönliche Seite #3422095
Lesenswert?

Marius S. schrieb:
> Macht es denn vom resourcenverbrauch her einen Unterschied ob ich nur
> ein Bit oder alle auswerte? Ich glaube nicht, da er beides als eine LUT
> kodiert, oder?
Ob das alles in eine LUT passt, hängt davon ab, wie groß dein Record 
ist. Aber in 1 einzige LUT passt ein Decoder mit 4 Eingängen bestenfalls 
dann, wenn es eine 6er LUT ist...

> Macht es denn vom resourcenverbrauch her einen Unterschied ob ich nur
> ein Bit oder alle auswerte?
Ich würde das ausprobieren, wenn es mich interessieren würde und ichdas 
Ergbniss nicht wüsste. Dabei lernt man am meisten... ;-)

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren