Forum: FPGA, VHDL & Co. Verilog Nachhilfe.


von Olaf (Gast)


Lesenswert?

Ich bin gerade dabei Verilog zu lernen. Leider scheine ich dafuer
wohl zu doof zu sein. Jedenfalls popel ich hier bereits seit einer
Woche damit rum einen SPI-Bus zu implementieren, etwas das ich in
C vermutlich in 1-2min runterschreiben koennte.

Eniviroment: Xilinx Webpack8.2, Demoboard mit XC3S100E, mehrere 
Taste(entprellt), LEDs, diverse IO-Ports...
SPI_CLK gewinne ich ueber einen Teiler aus einem 33Mhz Quarz und
betraegt momentan 1Hz.

Waer nett wenn da mal einer drueber schauen koennte und mir sagt wo der
Fehler liegt.

  reg           [3:0]  state, next_state;
  parameter S_0 = 4'b0000, S_1 = 4'b0001, S_2 = 4'b0010, S_3 = 4'b0011,
            S_4 = 4'b0100, S_5 = 4'b0101, S_6 = 4'b0110, S_7 = 4'b0111;

  reg    [7:0] tmp;
  integer bitcounter;


   //Ausgabe eines Datenbit und generierung des notwendigen Clocks
   //Ausserdem bei Reset das Datenregister initialisieren
      always@(state)
        begin
           case (state)
             S_0 : begin
                tmp <= {tmp[6:0],MAX_DOUT};
                next_state <= S_1;
             end
             S_1 : begin
                clockout <= 1'b1;       //Clock auf HighPegel
                next_state <= S_7;
             end
             S_2 : begin
                clockout <= 1'b0;               //Clock auf Low
                bitcounter = bitcounter +1;
                  if (bitcounter == 7) next_state <= S_7;
                    else               next_state <= S_0;
             end
             S_6 : begin
                tmp <= 8'b10101010;        //Bei Reset Kommandowort 
laden
                bitcounter = 0;
                next_state <= S_0;         //Statemachine starten
            end
             S_7 : begin                        //Wir sind fertig
                next_state <= S_7;
             end
           endcase
       end

   assign Led1 = tmp[7];
   assign Led2 = !clockout;

   //Haelt unser Statemachine in Schwung
   always @(posedge SPI_CLK)
     begin
        if (Taste1 == 1'b1)  //Das ist erstmal unsere Resettaste
          begin
             state <= S_6;
             //  tmp <= 8'b10101010;
          end
        else
          begin
             state <= next_state; //Statemachine triggern
          end
     end

Meine Vorstellung ist das das Programm beim druecken von 'Taste1' die
Statemachine bei S6 startet, den Vorgabewert ins Register laedt,
die einzelnen Bits ausgibt und dazu jeweils einen Clock generiert.
Danach sollte die UEbertragung anhalten.

Passieren tut folgendes:

Nach dem reinladen des Programms in den FPGA werden unendlich viele
Clockimpulse ausgeben, aber kein Registerinhalt.
Druecke ich Taste1 stoppt die Ausgabe der Clockimpulse, laesst
man los werden sie wieder erzeugt. Aber sie hoeren halt nicht auf.
Dabei sollte die Statemachine doch irgendwann mal anhalten.
Ausserdem wird entweder mein Vorgabewerte nicht uebernommen, oder es 
wird
nicht geshiftet.
Es sieht so aus als wenn nur S1 und S2 in einer Endlosschleife 
abgearbeitet werden. Warum ist das so? Irgendwie muss ich da was 
entscheidendes in der
Logic von Verilog nicht verstanden haben.

Olaf

von Günter -. (guenter)


Lesenswert?

Mach doch erst mal eine Testbench und schau ob da alles funktioniert wie 
du willst.

Du hast mit parameter 8 states spezifiziert aber nutzt nur 5 in der case 
Anweisung. Gibt dir die Synthese diesbezüglich eine Warnung?

Dein state S_2 wird nie angesprungen. Ist das beabsichtigt?

von Olaf (Gast)


Lesenswert?

> Mach doch erst mal eine Testbench und schau ob da alles funktioniert wie
> du willst.

Ich hab mir gerade Ikarus installiert. (Hat den Vorteil das ich nicht 
immer
fuer Windows booten muss, und laeuft 10^499mal schneller als der 
Compiler
von Xilinx.

http://iverilog.wikia.com/wiki/User_Guide

Dann hab ich mir dafuer ein Testbench geschrieben und laufen gelassen.

Die Ausgabe sieht genauso aus wie ich das erwarte. Ich versteh jetzt
leider ueberhaubt nicht wieso das im FPGA nicht laeuft, seufz.

> Du hast mit parameter 8 states spezifiziert aber nutzt nur 5 in der case
> Anweisung. Gibt dir die Synthese diesbezüglich eine Warnung?

Ja. Ich hab einige Parameter und IOs spezifiziert die ich momentan noch 
nicht nutze und bekomme da Warnungen. Ich denke aber mal das kann ich
einfach ignorieren?

> Dein state S_2 wird nie angesprungen. Ist das beabsichtigt?

Das war ein kleiner Fehler in meinem geposteten Programm. Ich hatte das 
vorher mal zu testzwecken geaendert und vergessen es rueckgaengig zu 
machen.
Ich probier mal die aktuelle Version anzuhaengen wie ich sie gerade mit 
Ikarus erfolgreich getestet habe. Ausser den "display" Zeilen 
unterscheidet die sich nur im Clock des letzten always. Im Testbench 
generiere ich direkt einen passenden Clock damit ich nicht ewig warten 
muss. Im Xilinx benutze ich einen anderen Clock den ich vorher durch 
runterteilen eines angeschlossenen Oszillator gewinne. Das funktioniert 
aber. Wenn ich mir
eine LED an meine Teile route kann ich die im Sekundenrythmus blinken 
sehen.


Olaf

von Olaf (Gast)


Angehängte Dateien:

Lesenswert?

Zweiter Versuch...mit Dateianhang..

von Olaf (Gast)


Angehängte Dateien:

Lesenswert?

Hier noch die Testbench falls es einer mal selber probieren will.
Aber wie gesagt, die Simulation sieht gut aus. Probleme habe
ich erst im FPGA.

Olaf

von lkmiller (Gast)


Lesenswert?

Nicht, dass ich auch nur den Hauch einer Ahnung von Verilog hätte,
aber in VHDL müssten in der sensitivity-list des Prozesses alle 
verwendeten Variablen stehen.

Siehe O-Text von

http://www.doulos.com/knowhow/verilog_designers_guide/rtl_verilog/
:
:
The statements inside the always block describe the functionality of the 
design (or a part of it). Let's reconsider the AND-OR-INVERTER gate:

always @(sensitivity-list)
begin
  F = ~((a & b) | (c & d));
end

Instead of a continuous assignment, we now have a procedural assignment 
to describe the functionality of the AOI gate. Perhaps a better question 
is what do we need to do in order to have F change value. Answer: F can 
only change when at least one of a, b, c or d changes. After all, these 
are the four inputs to the AOI gate. That's our sensitivity list:

always @(a or b or c or d)
begin
  F = ~((a & b) | (c & d));
end
:
:

Bezogen auf deinen Code müsste da also eher stehen

:
:
      always@(state or tmp or bitcounter)
        begin
           case (state)
             S_0 : begin
                tmp <= {tmp[6:0],MAX_DOUT};
                next_state <= S_1;
             end
             S_1 : begin
:
:

Insgesamt kann ich mir keine Hardware vorstellen, die das ausführen 
kann.
Wenn da steht
   always @(posedge SPI_CLK)
dann ist das getaktet --> FlipFlops --> ok

Wenn da aber steht
   always@(state or tmp or bitcounter)
dann gibt das Kombinatorik, und kombinatorische Schieberegister sind 
genau wie kombinatorische Counter nur Rauschgeneratoren.

Fazit:
Geschoben und Gezählt wird nur getaktet.

BTW:
Warum lernst du Verilog? Willst du auswandern?
Über den Daumen gepeilt gilt: Europa = VHDL

von Olaf (Gast)


Lesenswert?

> Bezogen auf deinen Code müsste da also eher stehen

Nein, ich will ja nur das dieser Block ausgefuehrt wird
wenn sich an state etwas aendert. Die anderen Variablen werden
zwar geaendert, sollen aber nicht selbst eine Aenderung ausloesen.

Ich weiss jetzt aber wo mein Problem lag. Man muss zu jederzeit
, also bei case in jeder der Moeglichkeiten, festlegen welchen
Zustand jede Variable haben soll. Man kann nicht davon ausgehen das
sie einfach ihren Vorzustand beibehaelt wenn man sie nicht aendert.

Macht man das nicht wandelt der Compiler die Variable in ein Latch um. 
(und gibt auch eine Warnung dazu aus) Die habe ich zwar gesehen, aber 
ignoriert weil eine Warnung erstmal noch kein Fehler ist, und zum 
zweiten nicht so unmittelbar einzusehen ist was an einem Latch 
fehlerhaft ist.

Aber anscheinend kann der FPGA an dieser Stelle kein Latch benutzen und 
deshalb laeuft es dann in der Hardware nicht, obwohl die Simulation kein 
Problem sieht.

> Warum lernst du Verilog? Willst du auswandern?

Die Beispiele bei meinem Kit waren bereits alle in Verilog und ausserdem 
sieht die Sprache IMHO schoener aus als VHDL.

> Über den Daumen gepeilt gilt: Europa = VHDL

Ich bin kosmopolitisch orientiert. Ausserdem waere es doch langweilig 
immer das zu machen was alle anderen auch machen. .-)

Olaf

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.