Variabler Clockdivider in Verilog

OP #4888545
Hallo,

ich habe für einen Cyclone5 einen variablen Clockdivider geschrieben, 
der leider nur bei statischer Vorgabe funktioniert.
Die Idee ist, ich habe einen Divider den ich über eine extern anlegbares 
Bitmuster steuern kann.
Als Anhang habe ich die zwei verwendeten Dateien.
Das Ganze funktioniert, sobald ich in fpgatest.v:15 eine feste Zahl 
anstatt der Speicherzelle vorgebe, was allerdings nicht Sinn und Zweck 
der Sache ist. Der Crux ist dass es in der Simulation funktioniert. Wenn 
ich es aber auf den FPGA spiele bekommt der Divider immer 0 als 
Divisionswert.

Hat jemand eine Idee was ich da falsch mache?
Angehängte Dateien:
Gast #4888592
Hm, Du deklarierst ein Register, das initial den Wert 2000 bekommt und 
sonst nicht mehr verändert wird. Sprich, es ist eigentlich kein 
Register. Das sollte zumindest eine Warning geben. Woher weißt Du, dass 
divider immer 0 bleibt? Pack das Register mal in ein sequential 
statement und schreib in jedem Takt 2000 hinein.
OP #4888646
Das Ganze ist aus einem größeren Projekt, das einen konfigurierbaren 
UART mit CRC hat. Dort kann man über ein Dual Port RAM vom Prozessor aus 
Transferlänge und Clock einstellen.
Ich bin sicher, dass dort 0 steht, weil ohne das "if(divider == 0" kein 
takt mehr kommt weil "if(divider /2 -1) -> 0/2 -1 = 0xFFFF und der 
SignalTap Logic Analyzer von Quartus sagt das Gleiche.
OP #4888672
Die Idee mit jeden Takt was reinschreiben war nicht schlecht.
Ich habe folgendes hinzugefügt:
1
always @ (posedge FPGA_CLK1_50)
2
  begin
3
  if(divider == 0)
4
    divider <= 1000;
5
  end
Und siehe da, ein Takt am Ausgang.
Allerdings nicht der für divider <= 1000, sondern divider <= 2000, wie 
bei initial.
Gibt es da Optimizer, die Amok laufen können?
Moderator (Firma: Titel) Persönliche Seite #4888682
Stefan A. schrieb:
> clock_out <= ~clock_out;
> Hat jemand eine Idee was ich da falsch mache?
Du erzeugst Takte, wo du mit Clock-Enables arbeiten müsstest. Das ist 
aber ein eher generelles Problem...

Stefan A. schrieb:
> Das Ganze ist aus einem größeren Projekt, das einen konfigurierbaren
> UART mit CRC hat. Dort kann man über ein Dual Port RAM vom Prozessor aus
> Transferlänge und Clock einstellen.
Dann musst du diesen Teil mit dem DPRAM auch noch implementieren. Durch 
das Weglassen dieses Interfaces beobachtest du hier ein simples 
"Wegoptimieren": weil du das Register divider nie verwendest (in Form 
von "verändern"), wird es hinfortoptimiert. Du solltest den Synthesizer 
zwingen, indem du z.B. einen Reset für divider einführt. Und bei deren 
Abwesenheit den Wert zuweist.

EDIT: schon gesehen, du hast es jetzt so gemacht... ;-)

Stefan A. schrieb:
> Gibt es da Optimizer, die Amok laufen können?
Das steht im Handbuch der Toolchain. Und ja, das ist ein 
Optimierungseffekt.
OP #4888729
Ok ich konnte das in meinen großen Programm jetzt nachvollziehen.
Mit volgendem Code funktioniert es:
1
    if(divider < 4)
2
      begin
3
      divider <= 1000;
4
      end

Allerdings in meinem Fall seltsam, da es auch ohne nicht wegoptimiert 
werden dürfte.
Ich habe kurz danach nämlich seit jeher folgendes Konstrukt:
1
    control_verarbeiten <= control_verarbeiten +1;
2
    case(control_verarbeiten)
3
...
4
...
5
      // Lowbyte von Divider liegt an
6
      7:  begin
7
        divider[7:0] <= mem_control_readdata;
8
        mem_control_address <= 0;
9
        end
10
      // Highbyte von Divider liegt an
11
      8:  begin
12
        divider[15:8] <= mem_control_readdata;
13
        end

Der Witz ist, das hat auch schon einmal funktioniert. Erst seit ich die 
CRC Funktion dazugebastelt habe klappt es nichtmehr. In der Simulation 
allerdings kein Problem.
Meiner Ansicht nach ein klarer Bug, wundert mich allerdings nicht so 
wirklich. Das Quartus ist allgemein sehr hakelig und stürzt auch 
regelmäßig ab.
Gast #4888854
initial Blocks sind im Allgemeinen nicht synthesierbar. (@VHDLer, das 
entspricht einem Process der nur einmal durchlaufen wird)

statt
1
reg [15:0] divider;
2
initial divider = 2000;
1
reg [15:0] divider = 0;
(Verilog 2001, sollten alle aktuellen FPGA Tools inzwischen können)
OP #4892131
So, ich hab es gerade nochmal getestet.
Es gibt 2 Konstallationen die funktionieren:

1. Trivial
1
reg [15:0] divider = 2000;

2. Kurios
1
reg [15:0] divider;
2
initial divider = 2000;
3

4
always @ (posedge FPGA_CLK1_50)
5
  begin
6
  if(divider == 0)
7
    divider <= 0;
8
  end

Da wie in Version 2 ersichtlich die "initial" Anweisung offensichtlich 
ausgewertet wird (Takt wird tatsächlich durch 2000 geteilt) und das if 
an sich nutzlos ist, ist das meiner Auffassung nach ein Bug.


Besten Dank an Alle.
Gast #4892521
Stefan A. schrieb:
> Da wie in Version 2 ersichtlich die "initial" Anweisung offensichtlich
> ausgewertet wird (Takt wird tatsächlich durch 2000 geteilt) und das if
> an sich nutzlos ist, ist das meiner Auffassung nach ein Bug.

Nö, weil Links die Zeit nach dem Takt und rechts die Zeit vor dem Takt.

Du verschleppst damit bei einem Zähler einen Takt und ob das hier 
richtig ist, wage Ich mal zu bezweiffeln. Du muss mit einem Takt Vorlauf 
denken, also:

"Wenn Zähler + Inkrement im nächsten Takt mehr als Limit, dann limit or 
wrap etc..."

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 9 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.