Forum: FPGA, VHDL & Co. represent signal & type does not match integer literal


von Polo (Gast)


Lesenswert?

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

von Klaus (Gast)


Lesenswert?

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.

von Sven P. (Gast)


Lesenswert?

Was steht denn in Zeile 79?

von Polo (Gast)


Lesenswert?

CASE zustandsvektor IS
        WHEN Start =>
            state <= 0;


zeile 79 -->  state <= 0;

ab da fängt er an

von Klaus (Gast)


Lesenswert?

Ü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? :)

von Polo (Gast)


Lesenswert?

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?

von Klaus (Gast)


Lesenswert?

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!

von Polo (Gast)


Lesenswert?

@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 :-)

von Klaus (Gast)


Lesenswert?

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.

von Polo (Gast)


Lesenswert?

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 :-(

von Klaus (Gast)


Lesenswert?

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

von Polo (Gast)


Lesenswert?

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.

von Klaus (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.