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
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.
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!
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.
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 !!!!
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 :
1 | if rising_edge (clk_in) then |
2 | -- bei steigender Flanke der clk, also immer nach 12.5 ns
|
3 | for i in 1 to 8 loop |
4 | case bitstream_in is |
5 | -- momentanen Wert des Bitstream beachten
|
6 | when ‘0’ => counter0 := counter0 + 1; |
7 | when ‘1’ => counter1 := counter1 + 1; |
8 | end case; |
9 | 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" ?
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?
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.
1 | entity Bit_Sampling is |
2 | port ( |
3 | bitstream_in : in std_logic; |
4 | clk_in : in std_logic; |
5 | bitstream_sampled : out std_logic ) ; |
6 | end entity Bit_Sampling; |
7 | |
8 | |
9 | architecture behave of Bit_Sampling is |
10 | |
11 | signal counter0 : std_logic_vector (2 downto 0) := "000"; |
12 | signal counter1 : std_logic_vector (2 downto 0) := "000"; |
13 | signal counter2 : std_logic_vector (2 downto 0) := "000"; |
14 | signal sampled_puffer : std_logic := '0'; |
15 | |
16 | begin
|
17 | |
18 | |
19 | sampling: PROCESS (clk_in) |
20 | begin
|
21 | if rising_edge(clk_in) then |
22 | |
23 | if counter2="000" then |
24 | -- solange in status 0 bleiben bis 1 erkannt wurde, dann automatisch in status 1 wechseln
|
25 | counter2(0) <= bitstream_in; |
26 | counter0 <= "000"; |
27 | counter1 <= "001"; -- da erstes Bit immer 1 |
28 | else
|
29 | |
30 | if counter2="111" then |
31 | |
32 | -- Auswertung nach 8 Takten
|
33 | if counter0 > counter1 then |
34 | sampled_puffer <= '0'; |
35 | end if; |
36 | |
37 | if counter1 > counter0 then |
38 | sampled_puffer <= '1'; |
39 | end if; |
40 | |
41 | if counter1 = counter0 then |
42 | sampled_puffer <= 'X'; |
43 | end if; |
44 | |
45 | else
|
46 | |
47 | case bitstream_in is |
48 | when '0' => counter0 <= counter0 + '1'; |
49 | when '1' => counter1 <= counter1 + '1'; |
50 | end case; |
51 | |
52 | end if; |
53 | |
54 | -- zähler für aktuellen Taktschritt erhöhen
|
55 | counter2 <= counter2 + '1'; |
56 | |
57 | end if; |
58 | |
59 | end if; |
60 | end process sampling; |
61 | |
62 | bitstream_sampled <= sampled_puffer; |
63 | |
64 | |
65 | end architecture behave; |
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?
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.
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.
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.
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.