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.