Hallo, ich brauche 16 voneinander unabhängige Zähler, welche alle ihre eigenen "Triggerleitungen" haben. D.h. ich möchte eine bestimmten Zähler von meinen 16 Stück inkrementieren, wenn auf einem Signal eine Taktflanke anliegt. Dazu habe ich mir einen Array angelegt: type cnt_type is array (0 to 15) of std_logic_vector(15 downto 0); signal counters : cnt_type; Gibt es nun eine Möglichkeit die Zähler über irgendwelche logischen Verknüpfungen so anzusteuern, dass er bei einer Taktflanke auf dem Triggersignal(jeder Counter hat ein eigenes) inkrementiert wird? Dies würde mir ersparen 16 einzelne Zähler schreiben zu müssen. Das Ganze dient einer Zeitverzögerung in welcher auf ein anderes Signal gewartet wird. Von diesen Signalen habe ich 16 Stück und alle müssen unabhängig voneinander ausgewertet werden... Vielen Dank. Daniel
Du hast also für jeden Zähler ein eigenes Triggersignal, mit dem du den Zähler um eins inkrementieren willst? Dann musst du auch für jedes Signal beschreiben, was passieren soll. type trigger_type is array (0 to 15) of std_logic; signal trigger : trigger_type; in der synchronen Umgebung (also innerhalb des Clock-Prozesses) beschreibst du dann für jeden Trigger: if trigger(0) = '1' then counters(0) <= counters(0) + 1; if trigger(1) = '1' then counters(1) <= counters(1) + 1; usw....
>Du hast also für jeden Zähler ein eigenes Triggersignal, mit dem du den >Zähler um eins inkrementieren willst? Richtig. >Dann musst du auch für jedes Signal beschreiben, was passieren soll. Genau das wollte ich verhindern.... :( Gibt es also definitiv keine andere Möglichkeit? Daniel
Es ist nicht ganz klar was Du mit Trigger-Signal meinst. Hast Du 16 Signale, und wenn an einem eine aufsteigende Flanke kommt, dann soll der dazugehörige Zähler erhöht werden? Die einfache Variante dazu wäre eine separates Modul mit einem Zähler, der bei der aufsteigenden Taktflanke erhöht wird. Dieses Modul verwendest Du 16 mal, und verknüpst dein "Triggersignal" mit dem Takteingang des Zählmodul. Das Zählmodul wird also nur 1 mal geschrieben, aber 16 mal verwendet. Du kannst Dir sogar noch ein bischen Schreibarbeit sparen, wenn Du das Generate-Statement verwendest. Diese Variante hat aber den Nachteil, daß dabei 16 Taktleitungen im CPLD oder FPGA benötigt würden. So viele gibt es aber meist nicht, es werden dann andere Signal-Leitungen verwendet. Bei der kompliziertere Variante hast Du einen Takt, der viel schneller als deine Trigger-Signale ist, und das ganze Design läüft synchron mit diesem Takt. Du schreibst wieder ein Modul mit einem Zähler, der nit dem schnellen Takt läuft, und wenn das Trigger-Signal beim Vorhergehenden Taktzyklus 0 war und beim aktuellen 1 ist, dann wird der Zähler erhöht. Wieder brauchst Du dieses Modul nur 1 mal zu schreiben. Im Top Level Modul verwendest Du das Zählermodul 16 mal. Grüße Klaus
Denk mal nicht, dass es das gibt.. Woher sollte das synthesetool denn erraten, was du vorhast? Wenn die Triggersignale gleichzeitig kommen würden, dann wäre es ja kein Prroblem.... Hmmm... eventuell könntest du ja versuchen, den gesamten Array ein Feld zuzuweisen und in dieses Feld deine Trigger reinzuschreiben. So in der art... counters <= counters + (trigger(0), trigger(1), trigger(2)....) müsstest mal probieren, ob du das Syntxmässig hinbekommst. Dann würde einfach bei jedem Takt der Wert jedes Triggers zum zugehörigen Counter addiert (entweder 1 oder 0) Glaub aber nicht, dass das läuft. Aber Versuch macht klug ;-)
Warum machst du nicht ne Schleife im Prozess? Also vorausgesetzt deine Eingänge sind in der Entity als trigger: in std_logic_vector(15 downto 0) definiert, und die counter Stände wie von dir beschrieben: process(clk) variable i: natural range 0 to 15; begin if rising_edge(clk) then for i in to 15 loop if trigger(i) = '1' then counters(i) <= counters(i) + 1; end loop; end process; Kein Anspruch auf syntaktische Richtigkeit, bin zu faul das jetzt zu testen ;)
Na ja, so kann man es auch machen, aber ehrlich gesagt, bei Schleifen bin ich vorsichtig... man weiss nie so richtig, was die Synthese draus macht, oder?
@Klaus Falser >>Hast Du 16 Signale, und wenn an einem eine aufsteigende Flanke kommt, >>dann soll der dazugehörige Zähler erhöht werden? Ja, stimmt. Ich habe die Signale bereits über 2 FFs eingetaktet. Das meintest Du glaub ich auch mit der "komplizierteren Variante". D.h. bei einer steigenden Flanke am "Triggersignal" kommt nach den 2 FFs nur noch eine einen Takt lange Flanke. Diese soll letztendlich das Inkrementieren des dazugehörigen Counters auslösen. Die Triggersignale sind relativ langsam. @Matthias Dann würde ja bei jedem Durchlauf eins dazuaddiert werden, unabhängig vom Triggersignal oder? @Schlumpf counters <= counters + (trigger(0), trigger(1), trigger(2)....) Das würde gehen(vorausgesetzt ich kriegs mit dem Syntax hin). Ich brauche im Prinzip einen Addierer, der einen Vector inkrementiert, wenn eine Taktflanke reinkommt(das Triggersignal). Und dieses Ding brauch ich 16 mal... Daniel
So beschreibst du zwar auch 16 Counter, aber der Code ist recht übersichtlich: (Hier im Beispiel mit 2 Counter) LIBRARY ieee; USE ieee.std_logic_1164.all; USE ieee.numeric_std.all; USE ieee.std_logic_unsigned.all;USE ieee.std_logic_arith.all; ENTITY conterversuch IS PORT( clk : IN std_logic; reset : IN std_logic; trigger : IN std_logic_vector (0 TO 1) ); END conterversuch ; ARCHITECTURE arch OF conterversuch IS type cnt_type is array (0 to 1) of std_logic_vector (15 downto 0); signal counters_in, counters_q : cnt_type; BEGIN process(clk, reset) begin if reset = '0' then counters_q <= (x"0000", x"0000"); elsif clk'event and clk <= '1' then counters_q <= counters_in; end if; end process; process(counters_q, trigger) begin counters_in <= counters_q; if trigger(0) = '1' then counters_in(0) <= counters_q(0) + 1; end if; if trigger(1) = '1' then counters_in(1) <= counters_q(1) + 1; end if; end process; END arch;
Daniel, ich hab das mit dem addieren versucht, aber leider erfolglos. Mein Compiler meckert das + an, wenn ich versuche, ein Feld zu addieren. Aber wenn du das hinbekommst, dann sag bescheid, mich würde das interessieren
Ich denke, Matthias hat schon die richtige Lösung gebracht. Man kann es auch mit einen Generate Statement schreiben, dann ist der Loop außerhalb des Prozesses .. g: for i in 0 to 15 generate process(clk) begin if rising_edge(clk) then if trigger(i) = '1' then counters(i) <= counters(i) + 1; end if; end if; end process; end generate g1; Klaus
Ich weiß, hier im Forum machen alle VHDL ... ... außer mir, ich find Verilog etwas cooler, obwohl die Unterschiede sicher marginal sind. In Verilog würde man so oder so ähnlich schreiben: module counter(input trigger, output reg [15:0] out); always @(posedge trigger) out <= out + 1; endmodule module test( /* ... */ ); wire [15:0] manytriggers wire [15:0] manyouts [15:0]; counter manycounters [15:0] (trigger, out); endmodule Das erste Modul definiert einen Einzelzähler, im zweiten werden 16 Stück davon instantiiert. Natürlich müssen die manytriggers und manyouts noch mit irgendwas vebunden werden. In VHDL gibt's soch sicher ein vergleichbares Konstrukt.
'tschuldigung, das zweite Modul muss natürlich so aussehen module test( /* ... */ ); wire [15:0] manytriggers wire [15:0] manyouts [15:0]; counter manycounters [15:0] (manytriggers, manyouts); endmodule Die Namen der Argumente der manycounters waren falsch.
Vielen Dank an alle!!! Ich denke Matthias´ und Klaus´ Lösung ist die Richtige. Genau das, was ich gesucht habe. Ich kannte die Generate Anweisung zuvor nicht. Falls es Probleme gibt komme ich auf Euch zurück. Daniel
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.