www.mikrocontroller.net

Forum: FPGA, VHDL & Co. Bitsampling mit VHDL-AMS


Autor: Sunny (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich muss ein Bitsampling mit VHDL-AMS realisieren.
Ziel ist es einen eingehenden Bitstream auf Richtigkeit zu 
kontrollieren. Um das zu machen ist es erst einmal notwendig den 
eingehenden Bitstream zu detektiern. Die Kontrolle bekomm ich dann schon 
hin.

Als Beispiel: Sagen wir mal es kommt ein Bitstream mit 8 Bits an, zB 
00110101. Dauer eines Bit sind 100ns. 1 Bit soll 8 mal abgetastet 
werden, also alle 12,5ns. Die Abtastung soll mit der ersten steigenden 
Flanke beginnen. Es sollen also für jedes Bit 8 Werte gespeichert 
werden. Dann soll eine Mehrheitsentscheidung durchgeführt werden. Das 
heist wenn mind 5 von 8 Abtastwerte den gleichen Wert haben wird dieser 
als Wert des Bit gespeichert. Somit sollen Glitches nicht beachtet 
werden. Bei 4x 1 und 4x 0 soll das als Fehler gespeichert werden.
Wenn hier zB das 4.Bit fehlerhaft ist und alle anderen so erkannt werden 
wie sie ankommen, soll am Ende im Speicher stehen: 1F0101.

Ich muss also erst mal die Abtastung realisieren.
Startbedingung soll die erste steigende Flanke sein. Der Wert ist 
gleichzeitig der erste Abtastwert. Dann wird im Abstand von 12,5ns noch 
7 mal abgestastet. Alle 8 werte sollen praktisch in einen 
Zwischenpeicher gelagert werden.
Ich hab keine Ahnung wie ich diese Abtastung realisieren soll. Die 
meisten FlipFlops reagieren nur auf 1. Ich will aber ständig die Werte 
auslesen, egal ob da was steigt, fällt oder sich gar nix ändert.

Danach folgt dann die Mehrheitsentscheidung. Aber soweit will ich im 
Moment noch gar nicht denken.

Es wäre echt super, wenn mir irgendwer helfen könnte!
Danke schon mal im Voraus für alle Antworten!

Sunny

Autor: Iulius (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sind die 12,5ns denn ein Takt im System, also arbeitest du mit 80mhz ?

Falls ja ists doch garnicht so schwer...

- rising_edge...

- 3*3 bit zähler
- bei erkannter 0 (inputpin = 0 ?) wird zähler1 um 1 erhöht, sonst 
zähler 2.
- zähler 3 wird immer erhöht

Du brauchst also garnicht die Werte zwischenspeichern, es ist nur 
interessant wie oft sie vorkamen.

- wenn zähler3 = 111 (oder 1000, falls das sonst mit dem timing nix 
wird)
-> prüfe ob z1 > z2 -> als 0 erkannt
-> prüfe ob z2 > z1 -> als 1 erkannt
-> sonst fehler(wobei mir noch unklar ist wie du das weiter behandeln 
willst, aber gut)

Das jetzt in vhdl alles auszuklamüsern sollte nicht so kompliziert sein.

Autor: Sunny (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Iulius,

erst mal danke für die Tips!
Mein Problem ist, dass ich noch nie vorher was von VHDL-AMS gehört hab. 
Und nun damit aber meine Diplomarbeit machen muss.

Ich hab echt keine Ahnung von den Timern und Countern in VHDL. Aber werd 
mit deinen Tipps mal was versuchen.

So wie das klingt brauch ich wohl tatsächlich keine spätere Auswertung 
eines Zwischenspeichers. Das ist ja schon mal spitze!
Es soll am Ende einfach ein Protokoll mit Übertragung ok oder nicht ok 
ausgegeben werden.

Wenn es dir nicht zu viel Umstände macht, wer ich echt dankbar, wenn du 
da noch ein paar Anregungen für mich hättest!

Autor: Iulius (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hmm, ich hatte gehofft du kennst dich da schon ein wenig aus, vor allem 
bei dem AMS-Part...

Das mit den Countern ist das kleinste Problem, glaub mir, und das Timing 
ist auch nicht so kritisch, der Systemtakt muss nichtmal zwingend ein 
genaues Vielfaches der Abtastrate sein, solange er signifikant höher 
ist.


Viel entscheidender wäre wohl die Frage wie die Erkennung ob 1 oder 0 
nun in deinem Fall funktioniert.

Denn wenn du von AMS schreibst gehe ich mal davon aus das jenes 
Eingangssignal analog vor liegt.

Wenn du dir darüber Gedanken machst und eine erkannte 0 oder 1 sowie den 
Systemtakt "bereitstellst", dann helf ich dir gerne bei dem Rest, das 
ist eine Sache von 5 Minuten.

Ein simples "input : in std_logic;" wirds wohl in dem Fall nicht tun.

Autor: Sunny (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also ich bekomme ein digitales Signal rein. Kann also für diesen Teil 
nur mit VHDL arbeiten.
Ich muss dann allerdings noch einen Physikal Layer bauen. Dafür brauch 
ich dann AMS. Aber dafür hab ich noch keine Unterlagen.

Ziel am Ende: Eine Bitfolge läuft durch den Physikal Layer. Und ich kann 
diese Erkennen und halt als 1 0 oder Fehler ausgeben.
Zum Test brauch ich da nun erst mal den Generator, damit ich weiß was 
ich rein geschickt hab.

Hab mir mal n Kopf gemacht. Wär nett wenn du mal deine Meinung dazu 
schreiben könntest:



Bitstream_Generator:


library IEEE;
use IEEE.std_logic_1164.all;

entity Bitstream_Generator is
  generic ( number_of_bits : integer := 10;
                 bit_time : time := 100ns);
        port ( bitstream_out : out bit );
end entity Bitstream_Generator;

architecture behav of Bitstream_Generator is
-- Bitstream: 0111000100
        constant bitstream : bit_vector (1 to number_of_bits) :=
                                ( 2 to4 │ 8  =>‘1’ │ others => ‘0’);
        signal a : bit <= ‘0’;
        variable bitstream_index : integer := 0;
-- Bitstream startet dann nach 500ns
        variable time : time := 400 ns;
begin
  for i in 1 to number_of_bits loop
                 bitstream_index := bitstream_index + 1;
                 time := time + bit_time;
                 a <= bitstream(bitstream_index) after time;
           bitstream_out <= a;
       end loop;
end architecture behav;




Clock_Generator


library IEEE;
use IEEE.std_logic_1164.all;

entity Clock_Generator is
  generic ( number_of_bits : integer := 10;
-- 1 Bit 8 mal abtasten: 100 / 8 = 12.5
                  bit_time : time := 100ns;
                  period_clock : time := 12.5ns );
  port ( clk_out : out std_logic );
end endity Clock_Generator;

architecture behav of Clock_Generator is
  variable a, b : integer;
  variable c : time;
begin
  a :=  bit_time / period_clock;
  b := a * number_of_bits;
  c := period_clock / 2;
  for i in 1 to b loop
    clk_out <= ‘1’;
    wait for c;
    clk_out <= ‘0’;
    wait for c;
  end loop;
end architecture behave;




clk_out und bitstream_out sollen jetz in das Bit_Sampling rein.




Bit_Sampling



library IEEE;
use IEEE.std_logic_1164.all;

entity Bit_Sampling is
  port (   bitstream_in : in bit;
    clk_in : in std_logic;
    bitstream_sampled : out std_logic ) ;
end entity Bit_Sampling;


architecture behav of Bit_Sampling is
  variable counter0 : integer := 0;
  variable counter1 : integer := 0;
begin
-- bis zur ersten steigenden Flanke im Bitstream warten
  wait until bitstream_in’event and bitstream_in = ‘1’;
  if rising_edge (clk_in) then
-- bei steigender Flanke der clk, also immer nach 12.5 ns
    for i in 1 to 8 loop
      case bitstream_in is
-- momentanen Wert des Bitstream beachten
        when ‘0’ => counter0 := counter0 + 1;
        when ‘1’ => counter1 := counter1 + 1;
      end case;
    end loop;
-- Mehrheitsentscheidung
    if counter0 > counter1 then
      bitstream_sampled <= ‘0’;
    elseif counter1 > counter0 then
      bitstream_sampled <= ‘1’;
    else
-- undefinierte Wert bei Anz 0 = Anz 1
      bitstream_sampled <= ‘X‘;
    end if;
  end if;
end architecture behave;



Tja, das wars. Keine Ahnung ob das so geht. Und dann hab ich noch kein 
Plan wie ich die 3 Teile zusammen gebastelt bekomm. Aber eins nach dem 
anderen.

Danke, Danke, Danke !!!!

Autor: Iulius (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bevor ich groß was dazu schreibe, mal eine wichtige Frage : soll das 
synthetisierbar sein(also in Hardware ausführbar) oder nur simuliert 
werden ?

Wenn ersteres der Fall ist, so wird wohl keine der 3 Funktionen 
überhaupt funktionieren.

after time... wait....for schleife von 1 bis 8 innerhalb der 
rising_clock Abfrage...


Letzteres verstehe ich gerade garnicht :
if rising_edge (clk_in) then
-- bei steigender Flanke der clk, also immer nach 12.5 ns
    for i in 1 to 8 loop
      case bitstream_in is
-- momentanen Wert des Bitstream beachten
        when 0 => counter0 := counter0 + 1;
        when 1 => counter1 := counter1 + 1;
      end case;
    end loop;

hier fragst du doch 8 mal hintereinander den gleichen Wert ab.

Du darfst jedoch nur einmal pro rising_edge einen der zähler erhöhen, 
sonst liest du gleich 8 mal den gleichen Wert aus.

Deswegen brauchst du auch einen dritten Zähler, der praktisch nochmal 
als Taktteiler fungiert und alle 8 clk_in-Takte die Auswertung vornimmt.


Die anderen Funktionen scheinen mir auf den ersten Blick zumindest 
simulierbar, auch wenn der Taktgenerator wohl ziemlich merkwürdig 
beschrieben wurde.

Wo ist das Problem wenn der durchgehend läuft anstatt umständlich nur 10 
mal zu "takten" ?

Autor: Sunny (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, also...
Ja, das ganze soll am Ende in Hardware umgesetzt werden!

Zu der Sache mit der 8-mal Abfrage: Also Ziel ist es ja, dass 1 Bit was 
über eine Dauer von 100ns steht 8 mal im Abstand von 12,5ns abgetastet 
wird.
Es ist ja möglich, dass bei der Bitübertragung Glitches auftreten, also 
kurze Einbrüche oder Anstiege. Wenn diese Glitches aber klein genug 
sind, also nur 3/8 ausmachen, können sie nicht beachtet werden. Darum im 
Abstand von 12,5ns immer wieder den Wert des Bit kontrollieren.
(Sorry, ich kann sowas immer so schlecht erklären. Hoffe man kann es 
verstehen.)

Ich will also nicht nur bei einer Flankenänderung den Wert abtasten, 
sondern auch wenn sich nix ändert.

Das warten bis zum rising_egde des bitstream_in hat den Zweck, dass erst 
bei der ersten steigenden Flanke, also Bit=1, mit der Abtastung begonnen 
werden soll. Danach spielt das aber keine Rolle mehr, dann soll ständig 
abgetastet werden.

Wegen dem Taktgenerator: Es gibt kein Problem wenn der ständig läuft. 
Hatte nur grad keine bessere Idee.

Zu den Zählern: Das hatte ich so verstanden: Wenn der Wert vom Bitstream 
an der Stelle grad 0 ist, wird der Wert des Nullzähler erhöht. Und wenn 
der Wert des Bit grad 1 ist, wird der Wert des Einszählers erhöht. Am 
Ende guck ich welcher Zähler den höheren Wert hat und das ist dann der 
Wert des Bit ohne Beachtung der Glitches. Wenn beide den gleichen Wert 
haben, ist das Bit nicht korrekt übertragen worden.

Sorry wenn ich mich doof anstelle, aber wozu brauch ich jetz nochmal den 
dritten Zähler. Versteh das mit der Taktteilung nicht.

Wenn man bei der Synchronisation die ganzen Schleifen nich verwenden 
kann, wie kann man das denn noch realisieren?

Autor: Iulius (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Die Schleife funktioniert deshalb nicht, weil nicht ein Schleifenzyklus 
pro Takt ausgeführt wird, sondern die komplette Schleife jeden Takt.

Aber du willst ja nicht 8 mal den gleichen Wert abtasten sondern alle 
12,5ns einen neuen Wert.


Mal ein Beispiel wie ich das Sampling in vhdl machen würde. Das erhebt 
keinen Anspruch auf die bestmögliche Lösung, aber wäre synthetisierbar 
und sollte verständlich sein.

Dazu ein Bild der Simulation. Wie man sieht zählt counter2 von 0 bis 7 
hoch, tastet also 7 mal ab und entscheidet dann anhand zähler0 und 1 die 
Ausgabe.

Diese Ausgabe des erkannten Bits wird jeweils bis zum nächsten erkannten 
Bit aufrecht erhalten, aber das kann man auch noch ändern.


entity Bit_Sampling is
  port (   
      bitstream_in : in std_logic;
      clk_in : in std_logic;
      bitstream_sampled : out std_logic ) ;
end entity Bit_Sampling;


architecture behave of Bit_Sampling is
  
  signal counter0 : std_logic_vector (2 downto 0) := "000";
  signal counter1 : std_logic_vector (2 downto 0) := "000";
  signal counter2 : std_logic_vector (2 downto 0) := "000";
  signal sampled_puffer : std_logic := '0';
  
begin


  sampling: PROCESS (clk_in)
  begin
    if rising_edge(clk_in) then
      
      if counter2="000" then
        -- solange in status 0 bleiben bis 1 erkannt wurde, dann automatisch in status 1 wechseln
        counter2(0) <= bitstream_in;
        counter0 <= "000";
        counter1 <= "001"; -- da erstes Bit immer 1
      else
    
        if counter2="111" then 
          
        -- Auswertung nach 8 Takten
          if counter0 > counter1 then
            sampled_puffer <= '0';
          end if;
        
          if counter1 > counter0 then
            sampled_puffer <= '1';
          end if;
          
          if counter1 = counter0 then
            sampled_puffer <= 'X';
          end if;
        
        else
        
          case bitstream_in is
            when '0' => counter0 <= counter0 + '1';
            when '1' => counter1 <= counter1 + '1';
          end case;
      
        end if;
        
        -- zähler für aktuellen Taktschritt erhöhen
        counter2 <= counter2 + '1';
    
      end if;
    
    end if;
  end process sampling;
  
  bitstream_sampled <= sampled_puffer;
  
  
end architecture behave;




Autor: Sunny (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hmmm... also jetz bin ich mir nich mal mehr sicher ob ich meine Aufgabe 
verstanden hab.

Ich dachte das Bitmuster was abgestastet raus kommt muss genau so 
aussehen wie das was rein geschickt worden ist?

Autor: Iulius (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn das so sein soll, warum willst du es dann überhaupt abtasten ?
Da könntest du ja gleich out <= in setzen.

Nach meiner Lösung wird der Eingang "geglättet", also kurze Fehler 
entfernt und dann verzögert das Signal sauber weitergegeben.

Wenn du weas anderes vor hast, dann musst das nochmal genau beschreiben.

Ein beispielhafter Waveform Verlauf(ähnlich der simulation) wie es 
aussehen soll wäre dann praktisch.


Achja, im Bild ist ein kleiner Fehler, ein Zyklus geht 160ns statt 80, 
aber das ist ja für die Funktion nicht wichtig.

Autor: Sunny (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Bitstream der jetzt rein kommt, soll wirklich genau so abgetastet 
werden und dann genau so wieder raus geschickt werden. Das klingt 
vielleicht jetz sinnlos, aber später macht das mal Sinn.
Man hat irgendwann mal einen technischen Übertrager. Und um den zu 
kontrollieren schickt man eine bekannte Bitfolge los. Die wird über den 
Übertrager weitergeleitet. Und dann soll diese übertragene Bitfolge als 
bitstream_in in dem Bitsamplingprogramm genau abgetastet werden. Über 
den Vergleich der Bitfolge vor dem Übertrager und der Abgetasteten kann 
man dann sehen, ob der Übertrager so arbeitet wie er soll oder bei der 
Übertragung Fehler macht.

Autor: Iulius (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dann musst du dich aber mal entscheiden was du nun willst :

- den eingangsvektor weiterleiten ( out <= in und fertig)

- den eingangsvektor abtasten und eine Mehrheitsentscheidung abliefern 
(lösung siehe oben)

- was ganz anderes.

Falls letzteres, dann bitte mal eine beispielhafte waveform, 
wahrheitstabelle, bild, etc

Hab mir alle deine Texte nochmal durchgelesen und werde da leider nicht 
schlau was das nun wird.

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.