Hallo,
ich möchte einen Impulszähler konstruieren. Die Rahmenbedingungen sind:
- systemtakt 20MHz
- Impulse (>= 1us) sollen gezählt werden
- periodisch (z.Zt. 100ms) soll das Ergebnis gepuffert, der Zähler
zurückgesetzt,neu gestartet werden und weiterlaufen während dann das
gepufferte Ergebnis seriell übertragen wird
Die serielle Übertragung kommt später, wenn der Zähler mal läuft.
Aktuell funktioniert die Zählung in der Pre-Synth Simulation.
Der Synthesizer meint allerdings die Signale "Count" und "timebase"
wären ungenutzt (Toplevel.srr Zeile 141ff). Ausserdem werden noch
diverse Register rausoptimiert, was ich noch nicht einordnen kann.
Ich denke mal da habe ich was nicht synthetisierbares konstruiert.
der Counter:
Never ever!
Die numeric_std kann alles, was du brauchst.
1
process(clk,rd,busif,outputbuffer,reset)
Da gehören nur clk und reset rein. Und reset ist im Grunde nicht nötig.
1
ifclk='1'andclk'eventthen
2
.....
3
cnt<=cnt+1;
4
5
6
ifclk='0'andclk'eventthen
7
.....
8
cnt<=0;
cnt sind 16 Flipflops. Und du möchtest da getne Flipflops haben, die mit
beiden Flanken getriggert werden können. Hat dein FPGA sowas?
Mein Tipp: im gesamten Design nur 1 Takt und nur überall die selbe
Flanke.
Markus schrieb:> Impulse (>= 1us) sollen gezählt werden
Das heißt, wenn das Eingangssignal mindestens für 1us high ist?
Vermutlich also zur Unterdrückung von Störungen...
Was soll aber passieren, wenn das Eingangssignal 10us high, dann 500ns
liw, dann wieder 10us high ist? Ist das dann 1 gestörter Impuls, oder
sind es 2 Impulse?
BTW: irgendwie habe ich den Eindruck, du machst das unnötig kompliziert
mit den ganzen Enable Signalen...
Ich würde das entkoppeln und erst mal sicher stellen, dass ich nur
gültige Impulse erkenne und verarbeite. Und das hat was mit "Entprellen"
zu tun: erst, wenn das Signal 1us stabil ist, ist es ein valides Signal.
Wo ich das schreibe sehe ich gerade, dass du das vermutlich asynchrone
Eingangssignal es ohne jegliche Einsynchronisierung verwendest. Das geht
sicher schief.
Lothar M. schrieb:> Das heißt, wenn das Eingangssignal mindestens für 1us high ist?
Nicht zwingend. In der Praxis reicht es aber aus, nur diese Impulse zu
berücksichtigen.
> Was soll aber passieren, wenn das Eingangssignal 10us high, dann 500ns> liw, dann wieder 10us high ist? Ist das dann 1 gestörter Impuls, oder> sind es 2 Impulse?
Das sind dann 2 Impulse. Eine Ausfilterung von Störungen ist (erstmal)
nicht notwendig.
Bisher wird der Eventcounter eines Mikrocontrollers genutzt. Es gibt
überlegungen auch weiterhin uC zu nutzen, allerdings wird das bei ~20
Kanälen eher unsauber.
>> BTW: irgendwie habe ich den Eindruck, du machst das unnötig kompliziert> mit den ganzen Enable Signalen...
Kann sein. Es soll letztendlich festgestellt werden, wiviele Impulse in
einer definierten Zeit angekommen sind.
Ich werde mal anfangen, die asynchronen Signale einzutakten und dann den
Zähler neu konstruieren.
Ich habe den Counter jetzt in einer Statemachine realisiert. In der
Pre-Synth Simulation funktioniert das wie gewünscht. In der Post-Synth
Simulation habe ich bei der funften clk-Flanke einen undefinierten
Zustand.
Wo kann der Mist wieder herkommen?
Markus schrieb:> Das Problem war, daß "timebase" bei reset nicht initialisiert wurde
1. Du kannst einen Initialwert bei der Deklaration des Signals angeben,
dann ist
2. im ganzen Design kein Reset nötig. Denn was ist dieser "Reset"? Ein
Knopf, wo jemand draufdrückt?
Lothar M. schrieb:> 1. Du kannst einen Initialwert bei der Deklaration des Signals angeben,> dann ist
Nein, das ist nicht möglich. Hast du selbst mal festgestellt:
Beitrag "Re: Modelsim: Zählerausgang funktioniert nicht"> 2. im ganzen Design kein Reset nötig. Denn was ist dieser "Reset"? Ein> Knopf, wo jemand draufdrückt?
Das wird ein Reset-Baustein.
Markus
Markus schrieb:> Lothar M. schrieb:>> 1. Du kannst einen Initialwert bei der Deklaration des Signals angeben,>> dann ist>> Nein, das ist nicht möglich.
Klar ist das möglich, weil das LRM das so fordert (für die Simulation).
Für manche FPGA-Architekturen kann das auch die Synthese:
https://docs.xilinx.com/v/u/en-US/wp272
Blick mit Krausen schrieb:> Klar ist das möglich, weil das LRM das so fordert (für die Simulation).
Da ich aber die Simulation möglichst nahe an der Realität haben möchte
und meine FPGA-Architekturen das nicht hergibt bleibe ich beim Reset.
Markus
Markus schrieb:> Blick mit Krausen schrieb:>> Klar ist das möglich, weil das LRM das so fordert (für die Simulation).>> Da ich aber die Simulation möglichst nahe an der Realität haben möchte
Naja, man kann unterschiedliche Nähe zur Realität simulieren, jenachdem
wielange man auf das Ergebniss warten will. Nah an der Realität ist man
mit einer post-P&R aka timing simu - da wartet man aber ewig ....
Und eine Simulation bleibt eine Simulation, der Realität ist das
wurscht, die macht ohnehin was real ist.
> und meine FPGA-Architekturen das nicht hergibt bleibe ich beim Reset.
Statt (klassisch, externen) PowerUp-Reset, könnte man auch eine (µC
gesteuerte) Initphase vorsehen.
Markus schrieb:> Nein, das ist nicht möglich. Hast du selbst mal festgestellt Flash-FPGAs von
Microsemi... Pech...
Markus schrieb:> Da ich aber die Simulation möglichst nahe an der Realität haben möchte
Warum hat dann nicht jeder getaktete Prozess einen Reset-Pfad?
Die Sensitivliste dort ist noch zu lang:
readout : process (clk, rd, busif, outputbuffer, reset)
Das würde reichen:
readout : process (clk, reset)
Aber prinzipiell ist dieser Prozess eh seltsam, denn wenn das rd ein
Steuersignal von außen ist, dann muss der externe Datenbus sofort
reagieren und nicht erst beim nächsten Takt. Der ganze Prozess kann also
auf diese Kombinatorik abgebildet werden:
busif <= outputbuffer when rd *'1' else (others => 'Z');
Wenn das aber ein Bus innerhalb des FPGAs ist, dann muss er sowieso in
einen Multiplexer aufgelöst werden, denn im FPGA gibt es kein 'Z'.
Markus schrieb:> Wie bekommt man das hin, dass in Modelsim die states im Klartext> angezeigt werden?
Das geht bei 'enumeration types' automatisch.
Bei einer 'post-synthesis' oder 'post-implementation' wird natürlich
alles std_logic bzw. std_logic_vector gemappt und die Zuordnung geht
verloren.
Aber in 99,5% der Fälle ist eine 'post-$$$'-Simulation nicht nötig.
Duke
Ohne das jetzt genau gelesen zu haben: Ich würde das Signal auf dem die
Pulse passieren können per Schieberegister einsynchronisieren und dann
aus dem seriellen Stream die Pulse rauslesen (evtl. per state machine:
puls beginnt, puls endet). Und dann zählst Du halt wie oft die state
machine durchgelaufen ist.
Immer einsynchronisieren, auch wenn dir dabei Takte verloren gehen. Das
kann sonst ganz komische Effekte geben wie: Funktioniert mal und nach 5
Minuten wieder nicht. Das hat mir zum Beispiel bei den Xilinx Spartans
schon Tage an Fehlersuche gekostet.