Hallo an alle! Ich bin Neuling was VHDL-Programmierung betrifft und bräuchte bitte einen Rat eurerseits. Ich möchte gerne einen 2:8 Multiplexer erstellen bei dem die Richtung eines Pins umschaltbar ist. Der Eingang SEL legt fest, wie die Pins A und B auf Y gelegt werden. Wenn DIR auf 1 liegt, soll B ein Eingang sein (Signalfluss B -> Y) und sonst ein Ausgang (Signal also vom jeweiligen Y-Pin zurück nach B). Kann man das mit einem temporären Signal erledigen? Was mir vorschwebt ist in etwa folgendes: entity MYMUX is port ( SEL : in STD_LOGIC_VECTOR(2 downto 0); DIR : in STD_LOGIC; -- Richtung der Uebertragung B <-> Y A : in STD_LOGIC; B : inout STD_LOGIC; Y : inout STD_LOGIC_VECTOR(8 downto 0)); end MYMUX; architecture BEHAVORIAL of MYMUX is signal B_TEMP : STD_LOGIC; begin MUX_PROCESS : process(SEL, READ, A, B, Y) begin -- kann man das so loesen? -- if DIR = '1' -- DIR = 1: B -> Y B <= 'Z'; B_TEMP <= B; else -- DIR = 0: Y -> B B_TEMP <= 'Z'; B <= B_TEMP; end if; -- kann man das so loesen? -- -- 2:8 Multiplexer case SEL is when "000" => Y <= (0 => A, 1 => B_TEMP, others => 'Z'); when "001" => Y <= (1 => A, 3 => B_TEMP, others => 'Z'); when "010" => Y <= (5 => A, 6 => B_TEMP, others => 'Z'); ... when others => Y <= (others => 'Z'); end case; end process MUX_PROCESS; end Bin für alle Anregungen dankbar! Beste Grüße, Manuel
Hallo, ohne jetzt die richtige Funktionalität Deines Multiplexers genau zu beachten sehe ich bei Deiner Beschreibung ein kleines Problem: B_TEMP sollte ín Deinem Code eine Variable sein, wenn B oder Y im selben Simulationszyklus darauf zugreifen wollen. Irgendwie erscheint mir dein Multiplezer etwas kompliziert gedacht. Überlege, ob die Bidirektionalität wirklich notwendig ist. Meist handelt man sich damit mehr Probleme ein, als man auf den ersten Blick sieht. Der Besucher
Nachtrag: auch fehlt irgendwie die Zuweisung von Y nach B in deinem Code. Und das READ Signal in den Sensitivity Liste benötigst Du in Deinem Beispiel auch nicht. Aber ausprobieren und Fragen sind schonmal der beste Weg zum Erfolg! Der Besucher
> Und das READ Signal in den Sensitivity Liste benötigst Du in Deinem > Beispiel auch nicht. Richtig, zuviel vom Falschen drin: unvollständige Sensitivity-Liste
1 | MUX_PROCESS : process(SEL, READ, A, B, Y) |
2 | begin
|
3 | if DIR = '1' |
4 | :
|
5 | :
|
DIR fehlt --> Simulation falsch :(
Jo, stimmt. Sicherlich wurde READ irgendwann in DIR umbenannt. Nur sollte der Compiler eigentlich meckern, da er READ nun nicht kennt. Vielleicht eine VHDL-Trockenübung ohne Simulation? Der Besucher
Nochmal angeschaut: > B_TEMP sollte ín Deinem Code eine Variable sein, wenn B oder Y im selben > Simulationszyklus darauf zugreifen wollen. Nein, eine Variable muß das nicht sein, aber B_TEMP sollte in die Sensitivity-List, denn wenn sich B_TEMP ändert, kann sich auch der Ausgang ändern. ;-) Wieso behandelt du diese Signalpfade A und B nicht getrennt? 1) A ist unidirektinal, also ein ordinärer Multiplexer 2) B ist bidirektonal und braucht ein wenig Sonderbehandlung... > when "000" => Y <= (0 => A, 1 => B_TEMP, others => 'Z'); Das geht nicht, denn es wird zwar B_TEMP auf Y(1) zugewiesen, aber nicht automatisch auch Y(1) auf B_TEMP. In deiner Beschreibung fehlt der "Rückwärtsgang" von Y nach B :-/
Hallo! READ sollte eigentlich DIR heißen, richtig. Ich hab den Code gerade erst geschrieben und noch gar keine Simulation gemacht. @Lothar: Danke fuer die Anregung mit der Aufteilung! Wenn ich es richtig verstanden habe, meinst du so etwas in der Art: -- praeventiv alles auf Z setzen B <= 'Z'; Y <= (others => 'Z'); -- Mux fuer A case SEL is when "000" => Y(0) <= A; when "001" => Y(1) <= A; when "010" => Y(5) <= A; ... when others => null; end case; if DIR = '1' -- Mux B -> Y case SEL is when "000" => Y(1) <= B; when "001" => Y(3) <= B; when "010" => Y(6) <= B; ... when others => null; end case; else -- Mux B -> Y case SEL is when "000" => B <= Y(1); when "001" => B <= Y(3); when "010" => B <= Y(6); ... when others => null; end case; end if; Grüße, Manuel
> meinst du so etwas in der Art...
Der Ansatz scheint mir nicht ganz falsch ;-)
BTW:
Wenn du deine case komplett auscodierst
1 | when "000" => Y(0) <= A; |
2 | when "001" => Y(1) <= A; |
3 | when "010" => Y(5) <= A; |
4 | ...
|
5 | when "111" => Y(3) <= A; |
dann ist der
1 | when others => null; |
unnötig, denn er wird nicht synthetisiert.
1 | -- praeventiv alles auf Z setzen
|
2 | Y <= (others => 'Z'); |
Der Kommentar leitet etwas in die Irre, denn damit wird nicht vorsorglich was gesetzt, sondern durch diese Zeile erhältst du Kombinatorik. Ohne diese Zeile bekämst du u.U. Latches :-/
Super! Vielen Dank für die Hilfe. Ich werd heut abend mal probieren, ob ich es jetzt hinbekomme. Der Code ist jetzt zwar 3x so lang, wie ursprünglich geplant, aber hauptsache er läuft ;-) Danke nochmal für den ganzen Input! /Manuel
Wenn dir der Code zu lang wird kann man den bestimmt auch kürzer schreiben. Nur ist dann fraglich, ob der dann noch auf die schnelle verständlich bleibt. Wenn du den kompletten MUX fertig hast kann man ja mal schauen wo man optimieren kann. Ich denke mal, das man z.B. auf die cases verzichten kann (aber und nicht durch elsif). Hängt aber von der gewünschten Kodierung ab. Der Besucher
> Der Code ist jetzt zwar 3x so lang... Langer Code bedeutet nicht unbedingt auch großes Design. BTW: > ...dann ist der
1 | when others => null; |
> unnötig, denn er wird nicht synthetisiert.
Ich korrigiere mich, lass den besser drin ;-)
ich bin auch dafür ihn drin zu lassen, da es eine case-anweisung ist, die von einem std_logic_vector abhängig ist. alles "auszucodieren" dürfte schwer/langweilig werden, wenn man die restlichen zustände außer "0" und "1" auch noch berücksichtigt ;)
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.