LIBRARY ieee; USE ieee.std_logic_1164.ALL; USE ieee.std_logic_arith.ALL; USE ieee.std_logic_unsigned.ALL; ENTITY stg IS PORT ( clk : IN std_logic; reset : IN std_logic; aktpos : IN std_logic_vector(11 DOWNTO 0); NotAus : IN std_logic; Betrieb : IN std_logic; ESL : IN std_logic; -- endschalter oben ESR : IN std_logic; -- endschalter unten cnt_clr : OUT std_logic; m_li : OUT std_logic; m_re : OUT std_logic; m_an : OUT std_logic; LEDR : OUT std_logic; state: out integer range 0 to 10 --test ); END stg; ARCHITECTURE behv OF stg IS BEGIN Process (reset, clk, aktpos, NotAus, Betrieb, ESL, ESR) IS Type STATE IS (Start, Motor_links, Motor_weiter_links, Motor_rechts, Motor_weiter_rechts, Notschalter); Variable zustandsvektor: STATE; Begin if reset = '1' then zustandsvektor := Start; Elsif (clk'event AND clk ='1') Then CASE zustandsvektor IS When Start => IF NotAus ='1' Then zustandsvektor := Notschalter; Elsif ESR ='1' Then zustandsvektor := Motor_links; Elsif ESL ='1' Then zustandsvektor := Motor_rechts; END IF; When Motor_links => IF NotAus ='1' Then zustandsvektor := Notschalter; Elsif aktpos < 624 Then zustandsvektor := Start; Elsif ESR ='1' Then zustandsvektor := Motor_weiter_links; END IF; When Motor_weiter_links => IF NotAus ='1' Then zustandsvektor := Notschalter; Elsif aktpos < 624 Then zustandsvektor := Start; Elsif ESR='1' Then zustandsvektor := Motor_links; END IF; When Motor_rechts => IF NotAus ='1' Then zustandsvektor := Notschalter; Elsif aktpos > 1324 Then zustandsvektor := Start; Elsif ESL ='1' Then zustandsvektor := Motor_weiter_rechts; END IF; When Motor_weiter_rechts => IF NotAus ='1' Then zustandsvektor := Notschalter; Elsif aktpos > 1424 Then zustandsvektor := Start; Elsif ESL ='1' Then zustandsvektor := Motor_rechts; END IF; When Notschalter => IF Betrieb ='1' Then zustandsvektor := Start; END IF; End Case; End if; CASE zustandsvektor IS WHEN Start => state <= 0; m_an <= '1'; m_li <= '0'; m_re <= '0'; cnt_clr <= '1'; LEDR <= '0'; WHEN Motor_links => state <= 2; m_an <= '1'; m_li <= '1'; m_re <= '0'; cnt_clr <= '0'; LEDR <= '0'; WHEN Motor_weiter_links => state <= 3; m_an <= '1'; m_li <= '1'; m_re <= '0'; cnt_clr <= '1'; LEDR <= '0'; WHEN Motor_rechts => state <= 4; m_an <= '1'; m_li <= '0'; m_re <= '1'; cnt_clr <= '0'; LEDR <= '0'; WHEN Motor_weiter_rechts => state <= 5; m_an <= '1'; m_li <= '0'; m_re <= '1'; cnt_clr <= '1'; LEDR <= '0'; WHEN Notschalter => state <= 8; m_an <= '0'; m_li <= '0'; m_re <= '0'; cnt_clr <= '0'; LEDR <= '1'; END CASE; END PROCESS; END behv; -- kann mir einer sagen was genau der error bedeute, bzw warum ist state kein signal. Error (10477): VHDL error at stg.vhd(79): name "STATE" must represent signal Error (10517): VHDL type mismatch error at stg.vhd(79): STATE type does not match integer literal
Polo schrieb: > state: out integer range 0 to 10 --test dang :-) In VHDL kann man nicht den gleichen Namen für verschiedene Dinge, in diesem Fall, einen Port und einen Typ, verwenden.
CASE zustandsvektor IS WHEN Start => state <= 0; zeile 79 --> state <= 0; ab da fängt er an
Übrigens hast noch einige weitere Fehler und unschönheiten in deinem
Design.
1) Mixe keine kombinatorische und getaktete Logik in einem Prozess. Wenn
du beides trennen möchtest, nimm 2 Prozesse.
2) Benutze keine Variable als speicherndes Element! Das geht schief. Mal
im Forum suchen nach "signal vs variable". Kurz: eigentlich müsste deine
Variable "zustandsvektor" in die Prozessensitivity List. Das geht jedoch
nicht, da Signale keine events haben, und damit auch keine Processe
triggern können. Folge: Deine Simulation wird falsche Ergebnisse
anzeigen!
3)
> if (clk'event AND clk ='1')
Schöner (und richtiger!) ist rising_edge(clk). Alles andere kann
Probleme bei der Simulation machen.
4) Deine Sensitivity List: Für einen getakteten Process schreib man
ausschließlich den Takt (und evtl. Reset) rein. Denn alle anderen
Signale ändern die Ausgänge nicht.
Hab ich was vergessen? :)
argh, wenn ich euch richtig verstehe, geht es nur darum dass der integer port state heißt und der TYPE auch STATE heißt. Ncch eine andere frage, der name des TYPE, kann beliebig gewählt werden, der wird doch nur für "interne" zwecke genutzt werden, den könnte ich auch TYPE Furz nennen oder?
Polo schrieb: > den könnte ich > auch TYPE Furz nennen oder? Könntest du, ja. Aber du ja Code schreiben willst, denn man in 2 Wochen noch lesen kann, wirst du das niemals tun ;-) Eine häufig benutzte Konvention ist z. B. an den Typ ein _t an den Signalnamen anzuhängen. Also das signal state und den typ state_t zu nennen. Wie auch immer du es machst, aussagekräftige und korrekte Namen verwenden!
@klaus, zu deinem letzten post, ist mir schon bewusst dass man aussagekräftige namen wählen sollte. :D IF NotAus ='1' Then zustandsvektor := Notschalter; Ich hatte zu erst IF NotAus ='1' Then := Notschalter; meintest du das damit, man soll keine variabeln als speichernde elemente nehmen? Man sagte mir nämlich ich müsse eine variable einbauen, jedenfalls wird es in den vorlesungen so praktiziert. Bezüglich dem CLK event, dass benutze ich immer aus meiner angefertigten Schablone , die ich ebenfalls aus den vorlesungen habe. Auf dein rising_edge(clk) wurde ich, jedenfalls erinnere ich mich nicht daran, nie hingewiesen. Punkt 4, ich weiss nicht was eine Sensitivity List ist. bzw. wo kommt die in meinen code vor? Aber danke erstmal dass du so ausführlich drauf eingehst :-)
Polo schrieb: > Man sagte mir nämlich ich müsse eine variable einbauen, jedenfalls wird > es in den vorlesungen so praktiziert. Ohje, hab ich befürchtet. Ist nicht dein Fehler Polo, das Problem ist: Dein Prof ist ne Pfeife und hat absolut keine Ahnung von VHDL! :-/ Warum ist diese Unfähigkeit von Profs bei Hardwarebeschreibung eigentlich so verbreitet? Hat jemand der alten Hasen, die länger im Geschäft sind als ich dafür ne Erklärung? Ok, zurück zum Thema. Anstelle der Variable solltest du ein Signal nehmen. Das musst du dann natürlich außerhalb des Prozesses deklarieren. Polo schrieb: > Auf dein rising_edge(clk) wurde ich, jedenfalls erinnere ich mich nicht > daran, nie hingewiesen. Gewöhn dich dran, dass es rising_edge() heißt um eine Flanke auf einem Takt abzufragen ;-) Das ist erstens deutlich besser lesbar, zweitens hat es auch handfeste Gründe: Wenn nämlich (zum Beispiel nach Simulationsstart oder warum auch immer) ein Signal den Zustand von 'U' nach '1' ändert, ist clk = '1' and clk'event auch true! Das selbe gilt für beliebige andere Kombinationen von Zuständen, die eigentlich keine Flanke sind. Polo schrieb: > Process (reset, clk, aktpos, NotAus, Betrieb, ESL, ESR) IS Dies hier am Prozessanfang ist die Sensitivity List. In der stehen alle Signale, die sofort den "Ausgang" des Prozesses verändern würden. Das bedeutet: 1) Alle Signale die ungetaktet gelesen werden gehören da rein. 2) Alle Signale die getaktet (= innerhalb von if rising_edge()) gehören nicht darein. Denn erst mit dem Takt ändern sich die Ausgangssignale. 3) Und hier kommt das Problem mit Variablen: Eine Änderung von "zustandsvektor" würde die Ausgänge des Prozesses verändern. Es wäre also notwendig, dass der Process auf diese Variable "sensitiv" ist. Genau das ist aber nicht möglich. Folge: der Simulator hat keine Chance, die Simulation richtig zu machen.
Wieder danke für deine Mühen. Ich muss mir dein text erstmal ein paar mal durchlesen und sacken lassen, alles verstehen tu ich noch nicht. Wir beschäftigen uns seit 4 monaten erst mit Vhdl bzw. digitaltechnik, nächstes semester geht es dann über zu C#. Ob mein Prof wirklich eine pflaume ist, kann ich schlecht beurteilen, er erklärt jedenfalls sehr verständlich und die vorlagen in den scripten, haben fast alle diese variablen eingebaut wenn es um "simple" automaten geht. Vielleicht macht er das auch um uns den einstieg etwas zu vereinfachen!? Mich würde folgendes noch interessieren wie sähe denn ahnand eines einfachen bsp. die deklaration von Signalen außerhalb des Prozess. Meinst du meine ein- und ausgänge die im PORT (...); beschrieben werden? Eine andere frage aus einem anderen post von dir, 1) Mixe keine kombinatorische und getaktete Logik in einem Prozess. Wenn du beides trennen möchtest, nimm 2 Prozesse. Wie sähe das genau aus, bzw. wo mache ich das in meinem Code. Bitte entschuldige wenn ich nicht konkret etwas mit den zwei begriffen kombinatorische und getaktete Logik anfangen kann :-(
Polo schrieb: > Wir > beschäftigen uns seit 4 monaten erst mit Vhdl bzw. digitaltechnik, > nächstes semester geht es dann über zu C#. Beim gleichen Prof? Wenn ja würde es einiges erklären... Die (ungelogen) allerwichtigste Regel bei Hardwarebeschreibungssprachen: Verbinde sie gedanklich nie mit einer Programmiersprache! Nenne beides nicht mal im gleichen Satz! ;-) Beides ist einfach grundverschieden. Bei Hardwarebeschreibungssprachen geht es einzig darum, zu beschreiben, wie einzelne Gatter und Flipflops miteinander verschaltet werden. Eine gute Grundregel ist immer: Man versucht sich vorzustellen, wie man ein gegebenes Problem mit Gattern und Flipflops lösen würde. Dabei kommt es nicht drauf an, sämtliche Logikgleichungen aufzustellen, aber die grundsätzliche Struktur sollte klar sein. Dann erst fängst du an, das Verhalten deiner ausgedachten Schaltung in einer HDL zu beschreiben. Wenn man sich stattdessen von der Softwaresichtweise nähert, macht man es sich unnötig schwer. Weil man dann nicht sieht, worum es wirklich geht (nämlich FF miteinander verdraten!). Also vergiss alles, was du über Programmiersprachen weißt, und stell dir vor, du würdest mit einen riesen Sack von digitalen Bausteinen rumhantieren. Polo schrieb: > Vielleicht macht er das auch um uns den einstieg etwas zu > vereinfachen!? Ich glaube das Gegenteil ist der Fall. Er macht euch den Einstieg schwerer. Er macht nur sich den Umstieg von der Softwarewelt leichter, indem er vermeidet, VHDL zu lernen ;-) Polo schrieb: > Wie sähe das genau aus, bzw. wo mache ich das in meinem Code.
1 | architecture x of y is |
2 | |
3 | signal state: state_t; |
4 | |
5 | begin
|
6 | |
7 | process(clk, reset) |
8 | begin
|
9 | if reset = '1' then |
10 | ...
|
11 | elsif rising_edge(clk) then |
12 | case state is |
13 | ...
|
14 | -- alles hier drin ist "getaktete Logik". Weil sich der Ausgang nur ändert, wenn eine taktflanke auftritt. In einem Prozess mit getakteter Logik steht nie weitere Logik. Also nach dem end if ist schluss!
|
15 | end if; |
16 | end process; |
17 | |
18 | |
19 | process(state) |
20 | begin
|
21 | case state is |
22 | ...
|
23 | -- hier drin ist nur "kombinatorische Logik". Das heiß, die Ausgänge sind zu jedem Zeitpunkt einfach bestimmt, durch die Kombination der Eingangssignale. In diesem Prozess steht kein rising_edge().
|
24 | end process; |
25 | end architecture x; |
Die Stichworte um sich das genauer anzugucken sind 1 Prozess Schreibweise, bzw. 2 oder 3 Prozessschreibweise. So nennt man die verschiedenen Stiele einen Zustandsautomaten zu beschreiben. Aber das ist erstmal noch nicht so wichtig. Deine Beschreibung von oben kommt der 2 Prozessschreibweise am nächsten. Lassen wir das erstmal auch so. Du schreibst dann also ein ersten case Statement in den ersten Prozess, und das zweite in den zweiten Prozess. Der erste Prozess beschreibt also nur die (getakteten) Veränderungen deines Zustandssignals. Und der zweite Prozess ist dafür Zuständig auf dem aktuellen Zustand (ungetaktet) die Ausgänge zu bestimmen. Fertig :) Bzw. ich sollte mal auswendig lernen, welche Artikel Lothar schon geschrieben hat. Würde mir viel arbeit ersparen, und spitzenmäßig erklären tun die Artikel auch :D http://www.lothar-miller.de/s9y/archives/43-Ein-oder-Zwei-Prozess-Schreibweise-fuer-FSM.html
Also, um nochmal das wort zu ergreifen für meinen Prof :D Er macht ein Semester lang Digitaltechnik, darin behandeln wir moore und mealy, hauptaugenmerk aber auf moore-automaten. Jetzt am schluss kommt ein bisschen der aufbau eines "von neumann rechners". In unseren Hausarbeiten müssen wir dann ,in der regel, die aufgaben mit VHDL "beschreiben", dafür benutzen wir quartus 2. Im nächsten semester, beschäftigen wir uns dann mit c#, das modul nennt sich "rechner hardwarenahe programmierung". Was genau dort gemacht wird im detail , weiß ich noch nicht aber c# ist bestandteil. Um vielleicht meinen prof in schutz zu nehmen, kann es natürlich gut sein dass ich gewisse sachen anders/falsch verstanden habe und das hier nun widergebe und du daraus das vernichtende urteil bildest :D Ich hatte die aufgabe erstmal ein zustandsüberführungsdiagramm zu zeichnen anhand moore. Dies habe ich gemacht. Dann bin ich übergegangen das umzusetzen, in den vorlesungen selber hieß es, dass wir unbedingt drauf achten sollen das ganze in zwei schritten zu gliedern. Das heisst alle zustände und deren verhalten anhand der eingabevektoren zu beschreiben(evtl auch die zustände ohne Bedingungen bzw. eingabevektoren) und dann das verhalten der zustände anhand der ausgabevektoren zu beschreiben. Begriffe wie ein-oder Zwei-Prozess schreibweise sind bisher noch nie gefallen, aber vielleicht wird in späteren semestern noch drauf eingegangen.
Nein, nein, ich gebe doch kein vernichtendes Urteil über deinen Prof ab ;-) In C# oder auch anderen Programmiersprachen mag er ein Genie sein, das weiß ich nicht. Ich weiß nur, dass er in VHDL nie eine reale größere Aufgabe gelöst hat. Glaub mir, das ist leider ein ständig wiederkehrendes Muster in der VHDL Welt: Softwerker kommt an und meint mal ebend schnell ne Hardwarebeschreibung machen zu können, weil er kann ja schließlich schon programmieren. Ist ja nur ne andere Sprache... Da ist dein Prof leider bei weitem nicht die Ausnahme... :-/
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.