Forum: FPGA, VHDL & Co. Modelsim: Zählerausgang funktioniert nicht


von Markus (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,
ich versuche mich (wieder) in VHDL einzuarbeiten. Dazu versuche ich 
einen einfachen Zähler aus dem Netz mit Modelsim zu simulieren:
1
LIBRARY IEEE;
2
USE IEEE.STD_LOGIC_1164.ALL;
3
USE IEEE.NUMERIC_STD.ALL;
4
5
ENTITY three_bit_counter IS
6
  PORT (
7
    clk : IN STD_LOGIC;
8
    enable : IN STD_LOGIC;
9
    count : OUT UNSIGNED (2 DOWNTO 0)
10
  );
11
END ENTITY three_bit_counter;
12
13
ARCHITECTURE Behavioral OF three_bit_counter IS
14
15
  SIGNAL internal_count : UNSIGNED (2 DOWNTO 0) := "000";
16
17
  BEGIN
18
    counter: PROCESS (clk, enable)
19
    BEGIN
20
      IF rising_edge(clk) AND enable ='1' THEN
21
        internal_count <= internal_count + 1 AFTER 15 ns;
22
      END IF;
23
    END PROCESS counter;
24
25
    count <= internal_count;
26
27
END Behavioral;

Die Entwicklungsumgebung ist Libero 12.1 / Modelsim 10.7C.
Ich nutze (vorerst) keine Testbench sondern setze die Signale in 
Modelsim manuell (rechte Maustaste->Modifiy->force...)

Leider Zählt der Ausgang "count" nicht wie erwartet hoch, sondern bleibt 
"X"

Kann mir das Jemand erklären?
Vielen Dank,
Markus

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite



Lesenswert?

Markus schrieb:
> internal_count <= internal_count + 1 AFTER 15 ns;
Ein Tipp: lass gleich zu Beginn diese symbolischen Pseudo-Verzögerungen 
weg. Die sind eh' nicht synthetisierbar und du legst dir damit 
irgendwann selbst ein Ei.
Siehe dazu den Beitrag "Re: Einfaches Schieberegister in VHDL?"

Markus schrieb:
> Zählt der Ausgang "count" nicht wie erwartet hoch, sondern bleibt "X"
Er "bleibt" nicht 'X', sondern er kommt von 'U' und wird dann 'X'. Das 
kommt von 2 Treibern, die auf dieses Signal gehen und liegt offenbar an 
dieser murksigen manuellen Forcerei, denn mit einer simplen Testbench 
klappt das wunderbar wie erwartet.

Wobei dir hier schon diese symbolische Verzögerung von 15ns das Bild 
nahezu undurchschaubar macht. Wenn ich das weglasse, dann passiert immer 
nur genau bei oder besser wegen der steigenden Taktfklane was. Und so 
ein Bild habe ich im Kopf. Es macht die Sache einfach und überschaubar.

: Bearbeitet durch Moderator
von Markus (Gast)


Angehängte Dateien:

Lesenswert?

Wenn ich die Simulation mit der Testbench versuche kommt eine 
Fehlermeldung:


 ** Fatal: (vsim-3807) Types do not match between component and entity 
for port "count".
#    Time: 0 fs  Iteration: 0  Instance: /tb_counter/uut 
File:../synthesis/three_bit_counter.vhd Line: 12

Das sieht irgendwie so aus, als ob der "unsigned" nicht nach 
"std_logic_vector" gecastet wird (oder umgekehrt).

Fehlt da vlt irgendwo ein "use" oder könnte irgendwo eine Einstellung 
falsch sein?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Markus schrieb:
> oder könnte irgendwo eine Einstellung falsch sein?
Was steht denn in der Zeile 12?
Und was kommt raus, wenn du mal alle Deklarationen von "count" genauer 
anschaust?

Du selber hatttest das doch letzthin noch ganz anders deklariert,
denn Markus schrieb:
> count : OUT UNSIGNED (2 DOWNTO 0)
Und jetzt:
> count  : out   std_logic_vector(2 downto 0)
Und die Testbench:
> count : OUT  UNSIGNED(2 downto 0)
Merkst du was?

BTW: was ist denn das für ein unheimlich umständliches Herumgehampel mit 
smartfusion-Primitiven, das du da angehängt hast? Wo hast du dieses 
umständliche Gebastel gefunden?

: Bearbeitet durch Moderator
von Markus (Gast)


Lesenswert?

Lothar M. schrieb:

> BTW: was ist denn das für ein unheimlich umständliches Herumgehampel mit
> smartfusion-Primitiven, das du da angehängt hast? Wo hast du dieses
> umständliche Gebastel gefunden?

Das wird automatisch von Libero generiert, bevor dann Modelsim gestartet 
wird, welches die o.g. Fehlermeldung im Log hat.

In den Quellfiles steht nach wie vor nur die Deklaration als unsigned 
drin.

So wie ich dass verstehe, arbeitet die Bibliothek zum simulieren mit 
std_logic_vektor und nicht mit unsigned. Daher meine Vermutung, dass 
irgendwo noch eingestellt werden muss, dass und wie "unsigned" nach 
"std_logic_vektor" konvertiert werden soll.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Markus schrieb:
> dass irgendwo noch eingestellt werden muss, dass und wie "unsigned" nach
> "std_logic_vektor" konvertiert werden soll.
Da gibts nichts "einzustellen". Typkonvertierungen müssen in VHDL 
explizit gemacht werden, da geht nichts "automatisch" (*). Du musst also 
in der Testbench auch eine Komponente mit std_logic_vector definieren 
und die Komponente passend deklarieren.

(*) die "automatische" Addition des UNSIGNED zu einem Integer in 
"internal_count + 1" geht z.B. nur, weil der der Operator '+' so 
überladen ist, dass er diese Operation ausführen kann. Das findest du im 
Sourcecode der numeric_std.

: Bearbeitet durch Moderator
von Markus (Gast)


Lesenswert?

Ok,
ich habe jetzt die Deklaration des Ports von unsigned nach 
std_logic_vector geändert. Ich kann jetzt wieder simulieren, mit dem 
gleichen Ergebnis wie vom Eingangspost.

Allerdings bin ich jetzt auf eine Warnung gestossen:

User-specified initial value defined for instance internal_count[2:0] is 
being ignored due to limitations in architecture.

Ein nicht initialisiertes Signal "internal_count" erklärt das 
Simulationsergebnis.
Wenn jetzt bei enable='0' den internal_count auf 0 setze dann zählt der 
Zähler auch wie erwartet hoch:
1
ARCHITECTURE Behavioral OF three_bit_counter IS
2
3
  SIGNAL internal_count : UNSIGNED (2 DOWNTO 0) := "000";
4
5
  BEGIN
6
    counter: PROCESS (clk, enable)
7
   BEGIN
8
      IF rising_edge(clk) then
9
        if enable='0' then
10
          internal_count <= (others => '0'); 
11
        else
12
          internal_count <= internal_count + 1 ;
13
        end if;
14
      END IF;
15
    END PROCESS counter;
16
    count <= std_logic_vector(internal_count);
17
18
END Behavioral;

Was sind das für "limitations in architecture" bzw. wie kann ich diese 
eleganter umgehen, so dass obiges ":= "000";" funktioniert ?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Markus schrieb:
> Allerdings bin ich jetzt auf eine Warnung gestossen:
> User-specified initial value defined for instance internal_count[2:0] is
> being ignored due to limitations in architecture.
Das sagt aber mit ziemlicher Sicherheit der Sythesizer und nicht der 
Simulator.

> Was sind das für "limitations in architecture"
Dein flash-basierter Baustein von Microsemi kann keine Initialwerte 
verarbeiten. Nähere Informationen sind sicher im Datenblatt zu finden. 
Du musst einen expliziten Reset vorsehen.

> bzw. wie kann ich diese
> eleganter umgehen, so dass obiges ":= "000";" funktioniert ?
Du kannst sie nicht "umgehen", weil der Baustein sie nicht unterstützt. 
Im "Actel HDL Coding Style Guide" findet sich der klare Satz
"In the absence of a reset, there is no way of predicting the initial 
value of the state register flip-flops during the “power up” operation 
of an Actel FPGA."

: Bearbeitet durch Moderator
von Markus (Gast)


Lesenswert?

Lothar M. schrieb:
> Das sagt aber mit ziemlicher Sicherheit der Sythesizer und nicht der
> Simulator.

Ja, das ist richtig. Die Warnung kommt vom Synthesizer.

> Dein Baustein kann offenbar keine Initialwerte verarbeiten. Nähere
> Informationen sind sicher im Datenblatt zu finden.

Auf die Schnelle konnte ich da jetzt nichts zu finden (ist ein IGLOO2).
Ich lasse das also erstmal so, auch wenn das "unschön" ist.

Danke für deine Unterstützung.

Markus

von Christophz (Gast)


Lesenswert?

Markus schrieb:
>> BTW: was ist denn das für ein unheimlich umständliches Herumgehampel mit
>> smartfusion-Primitiven, das du da angehängt hast? Wo hast du dieses
>> umständliche Gebastel gefunden?
>
> Das wird automatisch von Libero generiert, bevor dann Modelsim gestartet
> wird, welches die o.g. Fehlermeldung im Log hat.
>
> In den Quellfiles steht nach wie vor nur die Deklaration als unsigned
> drin.

Sieht danach aus, als ob hier der TO eine post-map bzw. gate-level 
Simulation macht.

@Markus: Sieh mal in ein Libero Tutorial wie das mit der Simulation 
eigentlich vorgesehen ist. Da muss es noch andere Knöpfe geben um eine 
einfach VHDL Simulation zu machen ohne das vorher etwas Synthetisiert 
wird.

von Markus (Gast)


Angehängte Dateien:

Lesenswert?

Christophz schrieb:
> Sieh mal in ein Libero Tutorial wie das mit der Simulation
> eigentlich vorgesehen ist. Da muss es noch andere Knöpfe geben um eine
> einfach VHDL Simulation zu machen ohne das vorher etwas Synthetisiert
> wird.

Ja, Du hast Recht. Ganz oben unter "Verify Pre-Synthesized Design" gibts 
das. Das hatte ich irgendwie übersehen/ignoriert. Aber spätestens, wenn 
ich dann für den konkreten FPGA synthetisiere kommt ja das Problem mit 
den "limitations in architecture". Das wäre mir dann auf die Füsse 
gefallen.

Aber generell ist es wohl der richtige Weg, erstmal ohne synthetisieren 
zu simulieren. Danke für den Hinweis.

BTW: Ich habe noch ein Problem mit dem Workflow. Zur Zeit läuft der 
folgendermassen ab:

- VHDL schreiben/ändern
- in Libero im Designflow "simulieren" drücken
- es wird synthetisiert, anschliessend automatisch Modelsim aufgerufen
- in Modelsim ziehe ich mir die Signale, die mich interessieren in das 
Wave Fenster (die Signale die nach aussen (Testbench) geführt sind, sind 
schon drin)
- wenn das Ergebnis nicht so ist wie erwartet, beende ich Modelsim und 
fange wieder oben an


Das "reinholen" der Signale habe ich schon über ein do-File 
automatisiert, aber es kann doch nicht richtig sein, dass ich jedesmal 
den Modelsim beenden und über Libero neu starten muss.
Ich konnte im Netz keine brauchbare Lösung zu diesem "Problem" finden. 
In irgendeinem Tutorial stand, dass man über Modelsim synthetisieren 
soll, aber das scheiterte bei mir schon an der Auswahl der 
Quellfiles/Bibliotheken.

Markus

von Duke Scarring (Gast)


Lesenswert?

Markus schrieb:
> Das "reinholen" der Signale habe ich schon über ein do-File
> automatisiert, aber es kann doch nicht richtig sein, dass ich jedesmal
> den Modelsim beenden und über Libero neu starten muss.
Nein, muß man auch nicht.

1. Das Synthetisieren in Libero sollte für eine Simulation nicht nötig 
sein.
2. Modelsim muß alle geänderten (und davon abhängigen) Quelldateien neu 
compilieren: vcom *.vhd oder vmake
3. im noch geöffneten Modelsim: 'restart -f' und 'run -all' eintippen

Duke

P.S.: Pro-Tipp im .do-File eine Funktion für Tippfaule einbinden:
1
proc r {} {
2
    restart -f
3
    run -all
4
}
5
6
proc x {} {
7
    exit -force
8
}

von Markus (Gast)


Lesenswert?

Ah, ok.
Die Parameter für's compilieren kann ich mir aus dem File "run.do" 
rauskopieren, welches von Libero beim Aufruf von Modlesim erzeugt wird.

Vielen Dank.

Markus

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.