Hallo ich will serielle Daten in parallen umwandeln. Jetzt ist mein Problem das wenn am seriellen Eingang eine Eins anliegt geht der Ausgang auf einen Undef Zustand. Aber wenn der Ausgang undef ist und eine Null anliegt geht er wieder auf Null. Also irgendwie rafft er das nicht die eins zu setzen. Was hab ich falsch gemacht. Das ganze hab ich unter Xilinx Webpack programmiert und mit Modelsim simuliert. Gruss Achim entity versuch1 is Port ( DIN : in std_logic; DOUT : out std_logic_vector(7 downto 0):="00000000"; .... end versuch1; architecture Behavioral of versuch1 is signal SIN : std_logic; signal POUT : std_logic_vector(7 downto 0):="00000000"; signal uebernahme : std_logic; begin --hier steht noch andere code mit Clock Behandlung usw. Daten: process(BCLK) subtype int70 is integer range 0 to 7; variable i: int70 :=0 ; begin if BCLK='1' and BCLK'event then POUT(i)<=DIN; i:=i+1; elsif i=7 then i:=0; end if; end process; Ausgabe: process(uebernahme) begin if uebernahme='1' then DOUT<=POUT; end if; end process; end Behavioral;
Daten: process(BCLK, Uebernahme) begin if Uebernahme = '1' then DOUT <= POUT; elsif BCLK = '1' and BCLK'Event then POUT <= POUT(5 downto 0) & PIN; end if; end process; einfaches Schieberegister. gruß hagen
Hallo Erstmal danke. Aber irgendwie ist das langweilig. ;o) So ein einfaches Schiebregister. Meine Lösung fand ich irgendwie so genial. ;o) Achim
Ich bin zwar auch nicht so erfahren aber das Schieberegister dürfte weit weniger Resourcen fressen als dein komplizierter Multiplexer. Egal, was zählt ist das es funktioniert ;) Gruß Hagen
Da kann ich nur die fertigen Templates die sogar im WebPack enthalten sind, empfehlen. Die sind schon sehr gut aufgebaut.
Was ich noch machen würde wäre ein zweites Schieberegister. Das ganze sieht denn so aus: process (CLR,CLK,S_REGA) begin if (CLR = '1') then S_REGA <= "000000001"; elsif (CLK'event and CLK = '0') then S_REGA <= S_REGA(7 downto 0) & S_REGA(8); -- schieben end if; end process; Das erste Schieberegister schiebst Du mit der abfallenden Flanke. Dadurch wird die '1' immer weiter nach links geschoben. Immer wenn die '1' ganz links angekommen ist, dann werden die Werte an den parallelen Ausgang übergeben. Somit brauchst Du keine Zähler zurücksetzen, den Zähler nicht abfragen und und und. process(CLR,CLK,POUT,PIN) begin if (CLR = '1') then DOUT <= (others => '0'); elsif (CLK'event and CLK = '1') then if(S_REGA(8) = 1) then DOUT <= POUT; else POUT <= POUT(5 downto 0) & PIN; end if; end process; Mit der ansteigenden Flanke fragst Du die Posisition des Schieberegisters ab, steht die '1' an der richtigen Stelle, dann übergibst Du die Werte, wenn nicht dann schiebst einen neuen Wert in das zweite Schieberegister. Wenn Du in diesem Prozess die ansteigende Flanke benutzt, dann kannst Du sicher sein das schon alles eingeschwungen ist. Diese Lösung ist sehr elegant und vor allem sehr übersichtlich.
Naja, dann könnte er auch POUT statt mit 6 Bits mit 7 Bit Breite definieren. Sobald Bit 6 == 1 wird müssen die Daten an den Ausgabeport und das POUT Schieberegister neu initialisiert werden. process(Clr, clk) begin if Clr = '1' then DOut <= (others => '0'); POut <= "0000001"; elsif Clk = '1' and Clk'Event then if POut(6) = 1 then DOut <= POut(5 downto 0); POut <= "000001" & Pin; else POut <= POut(5 downto 0) & Pin; end if; end process; Dies wäre dann aber eben keine asynchrone Ausgabe des internen Schieberegisters. Das Takten auf fallende Flanke einer Clock sollte man eher vermeiden. In meinen bisherigen Projekten hat dies immer zu schlechteren Fittings geführt. Gruß Hagen
oder mit 6 Bits (spart ein Register/FF), dann so process(Clr, clk) begin if Clr = '1' then DOut <= (others => '0'); POut <= "000001"; elsif Clk = '1' and Clk'Event then if POut(5) = 1 then DOut <= POut(4 downto 0) & Pin; POut <= "000001"; else POut <= POut(4 downto 0) & Pin; end if; end process;
Das ist aber keine schöne Lösung, denn Du schreibst die Daten von POut nach DOut wenn POut(5) = 1 ist. Bis dahin ist alles noch ok. Aber dann definierst Du POut neu. Und genau das kann Probleme machen. Wenn man sich das ganze in Logik vorstellt, dann übernimmt die Scahltung mit einer Taktflanke die Daten nach DOut aber setzt POut auch gleich wieder zurück. Wie willst Du mit der Lösung sicherstellen, dass es zu keinen undefinierten Zuständen kommt. Mit anderen Worten woher soll das System wissen, wann die Daten erfolgreich übergegeben wurden, denn erst dann darf das System zurückgesetzt werden. Ich denke mal das da meine Lösung deulich besser ist. Und warum sollte es Probleme geben wenn ich zwei Flanken benutze. Man muss bei seinem Design halt nur dabei bleiben, dann wird es sehr überschaubar und man kann sehr einfach programmieren. (kann ich zumindestens aus Erfahrungen meiner Projekte sagen) Gruss Michael
Hallo So ein zweitesmal irgendwie war geradeben nach einen falschen Tastendruck der ganze Text weg. grrrr ;o) So erstmal danke für eure Antworten. Meine nächstes Problem ist das die ganze Umwandlung erst starten darf wenn ein anderes Signal auf High geht. Ich hab dafür ein zweites Clocksignal LRCLK das alle 32 Takte von CLK einen Takt hat. Ich schaff zwar das zu programmieren kann das aber nicht synthesieren. @Michael Könnte sein das dein Entwurf ein Fehler hat? Nämlich immer wenn das Schieberegister ausgegeben wird übersieht er das Bit. ich hab das versucht zu kompensieren indem ich das Schieberegister auch bei der Ausgabe weiterschieb aber es hilft irgendwie nicht. Oder simuliere ich irgendwie falsch? Gruss Achim process(CLR,CLK,POUT,PIN) begin if (CLR = '1') then DOUT <= (others => '0'); elsif (CLK'event and CLK = '1') then if(S_REGA(8) = '1') then DOUT <= POUT; POUT <= POUT(6 downto 0) & PIN; WCLK<='1' else POUT <= POUT(6 downto 0) & PIN; WCLK<='1' end if; end if; end process;
Ich habe das ganze nicht getestet, sondern nur als Hilfe gepostet. Deshalb kann es sein, dass noch Fehler enthalten sind. was ich noch nicht geschrieben habe ist, dass das Signal noch deklariert werden muss. entity versuch1 is Port ( CLK : in std_logic; CLR : in std_logic; SIN : in std_logic; DOUT : out std_logic_vector(7 downto 0) ); end versuch1; architecture structure of versuch1 is signal S_REGA : std_logic_vector (9 downto 0); signal S_POUT : std_logic_vector (7 downto 0); signal S_OK : std_logic; begin process (CLR,CLK,S_REGA,S_OK) begin if (CLR = '1') then S_REGA <= "000000001"; S_OK <= '0'; elsif (CLK'event and CLK = '0') then S_REGA <= S_REGA(8 downto 0) & S_REGA(9); -- schieben S_OK <= '1' -- damit man sicher ist das zuerst die fallende Flanke kommt und das zählen nicht durcheinander gebracht wird end if; end process; process(CLR,CLK,S_POUT,SIN,S_OK) begin if (CLR = '1') then S_POUT <= (others => '0'); elsif (CLK'event and CLK = '1') then if(S_REGA(9) = 1 and S_OK = '1') then DOUT <= S_POUT; else S_POUT <= S_POUT(6 downto 0) & SIN; end if; end process; Ich denke mal das muss jetzt funktionieren. Das Signal S_OK ist notwendig, da man nie weiß ob zuerst die ansteigende oder abfallende Flanke erscheint, wenn man die Spannungsversorgung anschaltet. Deshalb verwende ich hier noch das Signal S_OK. Du solltest Dir dafür noch einen anderen Namen ausdenken. Das mit dem schnelleren Clock ist schon etwas komplizierter. Am besten Du setzt ein Signal, das z.b. "ENABLE" heist auf '1', wenn die Daten von parallel in seriell gewandelt werden sollen. Dann benötigst Du noch eine zweite Variable, damit die Wandlung nur einmal durchlaufen wird, denn Du kannst das Signal "ENABLE" nur in dem Prozess zurücksetzen, in dem Du es gesetzt hast. Gruss Michael
hallo Michael Das sollte auf keinen Fall eine Kritik an dir gewesen sein. Mir war das schon klar das du mir es nur als Hilfe gepostet hast. Auch die Signaldeklaration war mir klar. Ich fand nur deine Herangehsweise an das Problem interessant, deshalb nochmals die Nachfrage ob das Problem bei mir liegt indem ich die Simulation falsch fahr oder bei deinem Vorschlag. Mein Problem ist das ich noch immer zu sehr in C Programmierwesie denk und programmier. Was auch meistens bis zur Simulation klappt, aber dann bei der Synthese na klar überhaupt nicht mehr funktioniert. Vielen Dank nochmals für deine Hilfe. Gruss Achim
Ich habe es auch nicht als Kritik angesehen und ich fühlte mich auch nicht angegriffen. Ich denke mal es liegt an Deiner Simulation. Du must aufpassen dass Du mit der richtigen Clockflanke anfängst. Deshalb habe ich bei der zweiten Variante das Signal "S_OK" eingefügt. Somit müste es eigentlich funktionieren. Gruss Michael
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.