Tach tach, ich möchte gern über die RS232 Schnittstelle Befehle von einem Terminalprogramm an die RS232 Schnittstelle senden und auswerten. So z.B. möchte ich Kanal 1 auf 200ns Zeitverzögerung setzen (Beispielbefehl: "ch1delay_200"). Meine Idee mithilfe einer State Machine sieht wie folgt aus: Ich dachte mir dass ich die Bitfolge bis "_" auswerte, zum entsprechenden case springe, dort die folgende Zahl auswerte und diese dann im FPGA auf Kanal 1 angewendet wird. Ist dies überhaupt im FPGA "on the fly" möglich, oder kann ich nicht so einfach wie ich mir das denke die Parameter für ein bereits im FPGA laufendes Programm ändern? Gibts von euch nen besseren Vorschlag wie man diese Sache implementieren könnte? Die Programmierung erfolgt in VHDL und zur verfügung steht ein Spartan 3AN. RS232 Daten kann ich bereits empfangen. Es geht nur um die Auswertung dieser Daten. Vielen Dank
Karnikel S. schrieb: > Gibts von euch nen besseren Vorschlag wie man diese Sache implementieren > könnte? Nicht einen langen Bitstrom auswerten, denn was machst du, wenn du mal eine kleine Pause in der Übertragung hast? Machs so, wie es alle Welt macht: Ein Zeichen nach dem anderen empfangen, und auswerten. Karnikel S. schrieb: > Ist dies überhaupt im FPGA "on the fly" möglich, oder kann ich nicht so > einfach wie ich mir das denke die Parameter für ein bereits im FPGA > laufendes Programm ändern? Du kannst in deinem FPGA machen, was du willst. Und natürlich lassen sich irgendwelche Zähler und Vergleichswerte zur Laufzeit ändern...
Ok, danke für die schnelle Antwort. Wie genau macht es denn "alle Welt"? Funktioniert es denn nur so: if erstes Byte = "c" then if zweites Byte = "h" then if drittes Byte = "1" then if usw. else "mach nix" oder gibt es da ne einfachere und kürzere Möglichkeit? Wie bekomme ich denn raus ob das Kommando vollständig ist...es ist zwar möglich ein Symbol am ende anzuhängen das mir das ende anzeigt, oder ich könnte auch den Befehl auf genau z.b. 8 Byte beschränken aber irgednwie hätt ich gern was variables. Wahrscheinlich macht es am meisten sinn, wenn ich am Ende abfrage ob das Byte "11111111" ist oder?
Eine Statemachine, die auf ein eingehendes Zeichen wartet, das dann z.B. in ein Schieberegister schiebt und auf das nächste wartet ist eine Variante. Damit vermeidet man lange if-else-Abfolgen. Dann eine Art "Ende-Zeichen", nach dem der ganze Befehl im Schieberegister ausgewertet werden kann, bei serieller Übertragung nimmt dafür meist das CR/LF- Symbol.
Karnikel S. schrieb: > Funktioniert es denn nur so: Ja, wie denn sonst? Uch wenn du z.B. in C einen schönen eleganten Funktionsaufruf wie strcmp() hinschreiben kannst, wird "ganz unten" nichts anderes gemacht...
Auch Tach! Ich bin ein großer Freund davon, Hardware-Aufgaben in Hardware (Verilog, VHDL) zu lösen und Software-Aufgaben in Software (C). Das, was Du da machen wills, ist die Interpretierung eines seriellen Byte-Protokolls und somit meines Erachtens eine Aufgabe für einen Prozessor. Der würde dann auch einen Timeout feststellen, oder ein nicht gültiges Zeichen etc. Ich finde, Du solltest darüber nachdenken, einen Prozessor ins FPGA zu holen.
Also je nach Anzahl der Befehle wäre eine Statemachine am einfachsten. Die Statemachine wird nur getriggert wenn ein neues Zeichen von der RS232 reinkommt und das nächste Zeichen verarbeitet. Wenn du die Befehle schön kurz hälst (2-3 Zeichen zum erkennen eines Befehls und) und statt Dezimal Hexadezimal verwendest sollte es auch nicht allzuviele Ressourcen verbrauchen. (Durch die Dezimale Schreibweise brauchst du evtl. einen Multiplizierer, bei Hexa schubst du einfach nur 4 Bit durch die gegend). Du könntest dir dann den erkannten Befehl und den dazugehörigen Parameter in einem Schattenregister speichern und wenn alles OK ist und Return gedrückt wird das Register dann zur Auswertung (bzw Befehlsausführung) in das Arbeitsregister kopiert. Einen Timeout sollte man ebenfalls vorsehen, der die aktuelle Eingabe vewirft und die Statemachin zurücksetzt. Ein Softcore-Prozessor ist da sicherlich auch eine denkbare Alternative, nur wenn es nur 2-3 Befehle sind die immer/annähernd gleich sind ist ein Softcore denke ich übertrieben. Oder wenn du wirklich eine richtige Eingabeaufforderung haben willst mit Zwischenspeicher, schöner Ausgabe usw., vielen Befehlen, Dezimale oder Hexa Schreibweise automatisch unterscheiden soll wäre ein Softcore geeignet. Kommt halt immer auf den Zweck bzw die Komplexität an.
Hi, vielen dank für die Anregungen. Ich hätte da aber noch ne allgemeine VHDL Frage: Bisher habe ich den time_delay-Wert fest eingestellt und mein Programm in der Top-entity wie folgt bekannt gemacht:
1 | architecture Behavioral of main is |
2 | :
|
3 | :
|
4 | component Delay_1 is |
5 | generic
|
6 | (
|
7 | system_speed : integer := 50000000; |
8 | bitrate : integer := 1000000; |
9 | time_delay : integer := 2000 |
10 | );
|
11 | port
|
12 | (
|
13 | RESET : in std_logic; |
14 | clk_i : in std_logic; |
15 | start_1 : in std_logic; |
16 | valid_bitwise_1 : in std_logic; |
17 | get_fifo_data_1 : out std_logic; |
18 | not_save_1 : out std_logic; |
19 | bitwise_delay_in_1: in std_logic_vector(21 downto 0); |
20 | dat_delay_in_1 : in std_logic_vector(21 downto 0); |
21 | dat_delay_out_1 : out std_logic_vector(21 downto 0) |
22 | );
|
23 | end component Delay_1; |
24 | :
|
25 | :
|
26 | begin
|
27 | :
|
28 | :
|
29 | Delay_1_inst : Delay_1 |
30 | generic map |
31 | (
|
32 | system_speed => 50000000, |
33 | bitrate => 1000000, |
34 | time_delay => 2000 |
35 | )
|
36 | port map |
37 | (
|
38 | RESET => RESET_i, |
39 | clk_i => CLK_50M_i, |
40 | start_1 => REC_1_TIMER_STARTxDELAY_1_START, |
41 | valid_bitwise_1 => REC_1_VALID_BITWISExDELAY_1_VALID_BITWISE, |
42 | get_fifo_data_1 => FIFO_1_RD_ENxDELAY_1_GET_FIFO_DATA, |
43 | not_save_1 => DELAY_1_NOT_SAVExRECEIVE_1_NOT_SAVE, |
44 | bitwise_delay_in_1 => REC_1_BW_DAT1xDELAY_1_BITWISE_IN, |
45 | dat_delay_in_1 => FIFO_1_DOUTxDELAY_1_DAT_DELAY_IN, |
46 | dat_delay_out_1 => DELAY_1_DATOUTxSEND_1_DAT_IN |
47 | );
|
Wenn ich nun "time_delay" variabel machen möchte, muss dann time_delay in "port / port map" mit rein?Oder reicht es, wenn ich die 2000 durch eine Variable ersetze und diese dann mit meinen Werten die ich per RS232 erhalte beschreibe?
Karnikel S. schrieb: > Oder reicht es, wenn ich die 2000 durch eine Variable ersetze Nein. Über Ports kommen veränderliche Werte/Signale. Über Generics nur Konstanten... > wenn ich die 2000 durch eine Variable ersetze Variablen sind sowieso nur innerhalb eines Prozesses gültig. Und fang mir bloß nicht mit den Shared Variables an. Das sind solche nachgebastelten Kostrukte für Softwareprogrammierer, die jetzt Hardware machen müssen/wollen/sollen... Karnikel S. schrieb: > Wenn ich nun "time_delay" variabel machen möchte, muss dann time_delay > in "port / port map" mit rein? Ja. Am besten (bzw. portabelsten) über einen Vektor, der danach wieder in einen integer konvertiert wird.
Vielen vielen Dank für eure Hilfe. Ich kann jetz jedem meiner 4 Kanäle einen Verzögerungswert per RS232 übergeben. Ich hätt aber noch ne weiterführende Frage: Ich kann ja mein Programm in den SPI Prom schreiben, so dass mein Programm geladen wird, sobald ich das Board einschalte. Jedoch lädt der FPGA jedes mal die Verzögerungszeiten mit den fest eingestellten Default-Werten. Wenn ich nun per RS232 diese Zeiten ändere übernimmt er diese zwar, "vergisst" diese aber wieder, sobald ich das Board ausschalte. Gibt es eine Möglichkeit, dass diese gespeichert werden? Wenn ja wie? Ich hab zwar mehrere ROMs auf dem Board, kann diese aber jweils nur ansteuern, wenn ich Jumper umstecke (soweit ich weiß). Also kann es anscheinend nur so gehen, dass ich die Werte im gleichen Speicher ablege wo das Prog gespeichert ist, oder das komplette Programm immer wieder neu in den ROM geschrieben wird, wenn ein neuer Verzögerungswert eingegeben wird. Oder gibt es da noch ne einfachere Möglichkeit? Es handelt sich dabei um 4 integer Werte, jeweils im Bereich von 100 bis 100000000. PS: ich hab das Spartan 3AN eval Board mit einem xc3s700an FPGA.
Karnikel S. schrieb: > Gibt es eine Möglichkeit, dass diese gespeichert werden? > Wenn ja wie? Du brauchst irgendeinen externen Speicher (EEPROM/Flash)...
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.