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?
Gast
#4888574
Stefan A. schrieb: > Die Idee ist, ich habe einen Divider den ich über eine extern anlegbares > Bitmuster steuern kann. Ok. Was willst Du mit dem resultierenden Takt anstellen? Duke
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.
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.
Die Idee mit jeden Takt was reinschreiben war nicht schlecht. Ich habe folgendes hinzugefügt:
1 | |
2 | |
3 | |
4 | |
5 | |
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?
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.
Ok ich konnte das in meinen großen Programm jetzt nachvollziehen. Mit volgendem Code funktioniert es:
1 | |
2 | |
3 | |
4 | |
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 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
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 | |
2 | |
1 | |
(Verilog 2001, sollten alle aktuellen FPGA Tools inzwischen können)
So, ich hab es gerade nochmal getestet. Es gibt 2 Konstallationen die funktionieren: 1. Trivial
1 | |
2. Kurios
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
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..."
Gast
#4908354
und? wie isses nun?
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.