Hi,
Ich probiere gerade folgendes in Verilog auf einem Lattice FPGA zu
realisieren.
Ich habe einen Eingang, sync_in, und wenn dieser von high auf low
wechselt, möchte ich einen Zähler starten. Der Zähler soll dann weiter
inkrementieren bis er einen maximalen Wert erreicht. Dann soll der
Zähler auf 0 zurück gesetzt werden und bis auf die nächste fallende
Flanke warten.
Ich habe bis jetzt mit VHDL zu tun gehabt und probiere in einem anderen
Projekt eine kleine Änderung durchzuführen: Der Zähler zuvor rannte
einfach von 0 auf max und fing dann wieder bei 0 an.
Mit folgendem Konstrukt erhalte ich fast das gewünschte Verhalten,
allerdings scheint cnt zwischen Wert 0 und StopValue-1 hin und her zu
wackeln, wenn keine Flanke von sync_in kommt. Ich komme mit Lattice
Diamond irgendwie noch nicht klar und bekomme keine Simulation dafür
hin. Gepaart mit meinem Verilog Verständnis komme ich derzeit nicht
weiter.
Hier der Code:
Ich kannte diese Formulierung mit # nicht, im verlinkten Wikiartikel
steht dazu:
"Vielleicht ist es ganz sinnvoll, an dieser Stelle nochmal zu erwähnen,
dass das Verzögerungszeichen nicht synthetisierbar ist."
Verzögerungen muss man schon explizit erstellen, einen Zähler und dann
die Verknüpfung damit.
Christoph K. schrieb:> Ich kannte diese Formulierung mit # nicht, im verlinkten> Wikiartikel> steht dazu:> "Vielleicht ist es ganz sinnvoll, an dieser Stelle nochmal zu erwähnen,> dass das Verzögerungszeichen nicht synthetisierbar ist."> Verzögerungen muss man schon explizit erstellen, einen Zähler und dann> die Verknüpfung damit.
Ohne zu wissen was sich der TO gedacht hat, ich kenne die Pounddelays
für die Simulation. Bei der Sythese werden diese dann ignoriert, muss
daher kein Problem sein. Das verzögert das Signal in der Simulation nur
um einen Tick.
Cle schrieb:> Das verzögert das Signal in der Simulation nur um einen Tick.
Eben das kann in der Simulation diesen seltsamen Effekt auslösen. Was
ist denn in der Verilog Simulation die kürzeste Verzögerung? Und was ist
der Simulationstakt? Hängen die irgendwie zusammen?
Kurz: in eine Verhaltensbeschreibung kommt keine Verzögerung.
T. F. schrieb:> Ich komme mit Lattice Diamond irgendwie noch nicht klar und bekomme> keine Simulation dafür hin.
Also doch keine Simulation...
Zum Simulieren verwendest du bei Lattice den Aldec Simulator. Der ist
eigenständig und du musst damit ein eigenes Simulationsprojekt
aufsetzen, das im Idealfall einfach die selben Sourcedateien wie Diamond
verwendet und denen eine Testbench hinzufügt.
habe mal ein paar mehr begin-end Paare eingebaut, nun tut der code etwas
anderes, wenn zweimal hindereinander "if" dann weiß ich nicht zu welchem
der "if"s das "else" dann gehört ... (aber so richtig 100% kann ich
verilog auch nicht!)
Simulieren kann man auch mit "http://iverilog.icarus.com/" + ansehen mit
http://gtkwave.sourceforge.net/
Hi,
Vielen Dank für die Kommentare. Teile des Codes stammen aus dem Projekt,
welches ich mit dieser Triggerung / Synchronisierung erweitern will.
Habe von dort die # Geschichten übernommen.
Danke Frank für deinen Code. Habe jetzt in der Zwischenzeit Xilinx ISE
wieder hochgefahren und verwende dieses zum Simulieren. Damit habe ich
schon gearbeitet.
@Frank: Wieso bist du den Weg über eine State-Maschine gegangen?
Folgendes erzeugt unter Xilinx ISE das gewünschte Verhalten:
1
`timescale 1ns / 1ns
2
3
module test(
4
input clk,
5
input sync,
6
input rst
7
);
8
9
10
reg reset_sw_n;
11
reg sync_r;
12
reg [12:0] cnt;
13
reg enable;
14
15
16
always @(posedge clk)
17
begin
18
reset_sw_n <= ~rst;
19
end
20
21
22
always @(posedge clk) begin
23
sync_r <= sync;
24
25
if (reset_sw_n) begin
26
cnt <= 13'b0 ;
27
enable <= 0;
28
end else if ((sync_r == 1) && (sync == 0) && (enable== 0)) begin
29
enable <= 1;
30
end else if (enable) begin
31
if (cnt == 13'd16) begin
32
cnt <= 0;
33
enable <= 0;
34
end else begin
35
cnt <= cnt + 1;
36
end
37
38
end
39
end
40
41
endmodule
Werde das jetzt mal auf der Hardware ausprobieren.
Danke an alle
Wo genau das Problem liegt, sehe ich Moment auch nicht (Ich bin
System-Verilog Novize), aber einen Fehler sehe ich: Du testest auf
sync_in_r1==0 und sync_in_r==1, damit hast Du aber eine steigende und
keine fallende Flanke (weil sync_in_r1 der ältere Wert ist).
Weiterhin könntest Du
1
else if(sync_in_r1 == 1'b0)
2
if (sync_in_r == 1'b1)
vereinfachen zu
1
else if(sync_in_r1 == 1'b0 && sync_in_r == 1'b1)
und die ersten beiden always-statements mergen. Das alles löst nicht das
Problem, aber der Code wird übersichtlicher, vllt findest Du dann
heraus, was schiefläuft. Hat cnt die gleiche Breite wie StopValue?
Verilog macht da manchmal seltsame Sachen ohne Vorwarnung. Ja, und lass
die Timing-Statements erst mal raus. Es geht jetzt nur um die funtionale
Simulation
Hi
T. F. schrieb:> @Frank: Wieso bist du den Weg über eine State-Maschine gegangen?
Weil Deine Aufgabenbeschreibung nach einer State-Machine geschriehen hat
;)
T. F. schrieb:> Ich habe einen Eingang, sync_in, und wenn dieser von high auf low> wechselt, möchte ich einen Zähler starten.
entpricht:
1
//state 0
2
if((startsig==0)&&(laststartsig==1))
3
begin
4
count<=count+1;
5
state<=1;
6
end
T. F. schrieb:> Der Zähler soll dann weiter> inkrementieren bis er einen maximalen Wert erreicht.
1
//state 1
2
if(count>=maxcount)
3
state<=2;
T. F. schrieb:> Dann soll der> Zähler auf 0 zurück gesetzt werden und bis auf die nächste fallende> Flanke warten.
Oh hier war ein Fehler:
1
// state 2
2
count<=0;//Hatte ich vergessen
3
if((startsig==0)&&(laststartsig==1))
4
begin
5
state<=0;//Wenn er sofort wieder zu zählen beginnen soll
6
//state <= 1;
7
end
...Ausserdem finde ich eine Statemachine deutlich übersichtlicher als
die ganzen verschachtelten ifs.
T. F. schrieb:>> Mit obigem Code funktionierts jetzt.>
Allerdings fehlt diesem das korrekte Einsynchroniseren des externen
Syncsignals. In der orginalen Version war das noch vorhanden. Ohne wird
es ab und zu auf der Hardware Fehler geben. Die Statemachine Version von
Frank kann sogar in einen illegalen Zustand springen.
Naja, wenn schon Erbsen zählen, dann aber richtig.
Lattice User schrieb:> Die Statemachine Version von> Frank kann sogar in einen illegalen Zustand springen.
Was aber völlig gleichgültig ist. Das Modul hat keine Ausgänge.
Dieses Snippet sollte keine vollständige Lösung darstellen, sondern
einen Weg aufzeigen.