mikrocontroller.net

Forum: FPGA, VHDL & Co. Ausgang geht auf Undef Zustand


Autor: Achim B (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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;

Autor: Hagen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Achim B (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo
Erstmal danke.
Aber irgendwie ist das langweilig. ;o)
So ein einfaches Schiebregister.
Meine Lösung fand ich irgendwie so genial. ;o)

Achim

Autor: Hagen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Axel Meineke (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Da kann ich nur die fertigen Templates die sogar im WebPack enthalten
sind, empfehlen. Die sind schon sehr gut aufgebaut.

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Hagen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Hagen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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;

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Achim B (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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;

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Achim B (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.