Forum: FPGA, VHDL & Co. effizienterer VHDL Counter


von chris h. (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

ich habe hier einen Counter der dem IP Core lpm_counter von Altera 
Quartus nachempfunden ist. Dieser zählt 32 Takte runter und setzt beim 
Nullübergang ein Flag. Mein Problem sind dabei die LEs. Mein Design 
benötigt 13 LEs der IP Core von Altera nur 8 LEs. Ich habe versucht das 
Überlauf- Bit für mein Counter = 0 Flag (cout) zu nutzen.
Was könnte ich in meinem Design ändern um LEs zu sparen. Anbei Code mit 
TB.
Danke für die Hilfe.

von Schlumpf (Gast)


Lesenswert?

Warum lädst du den Counter nicht mit 31 und lässt ihn auf 0 laufen?

von Sigi (Gast)


Lesenswert?

Du hast 2X "-1"-Operation, einmal mit 6 und einmal
mit 7 Bits, macht "13 Bits": Das 2. "-1" wird bei
Dir nur für den Überlauftest verwendet.

Mach mal eine komplette Tabelle mit einem z.B.
2-Bit-Counter + 1 Bit für Überlauf, dann siehst du,
wo man einsparen kann (Hinweis: fang z.B. mit 2^n-1
an zu zählen und zähl runter bis -1 => NEG-Flag
gesetzt).

von chris h. (Gast)


Lesenswert?

Hallo,

danke für deine Anwort, ja kann ich theoretisch auch machen würd mir 
auch 2 LEs sparen, aber immerhin...
Ich denke man müsste das Überlauf-Bit effizienter nutzen...

von Sigi (Gast)


Lesenswert?

Nein, du sparst nicht 2 LEs, sondern 6; d.h. Du hast 7 LEs
inkl. Überlaufflag. (+ evtl. nach ein weitere LE für sonst.
Statusinfos, macht also 8 LEs).

von chris h. (Gast)


Lesenswert?

Ok, wenn ich dich richtig verstehe, soll ich einen von den zwei Countern 
streichen. Diesen bis -1 dekrementieren...und nehme dann das neg Flag 
für meinen Nulldurchlauf.

von chris h. (Gast)


Lesenswert?

Hallo,
ich habe jetzt für meinen Zähler nur den Ausdruck cnt := ( '0' & cnt )-1 
verwendet. Allerdings muss ich meinen zu ladendenden Wert (load) in eine 
Variable legen und diese dann zuwweisen...
Kann ich noch was vereinfachen?

von Schlumpf (Gast)


Lesenswert?

Beschreibe mal ganz exakt, was dein Counter können soll.
Also laden mit Flanke oder Pegel von "load"..?
Start mit Flanke oder Pegel von "start"..?
Zählen von 31 Takten und dann im nächsten Takt "overrun" auf High.. oder 
sind es 32 Takte und dann "overrun" auf High.

Und wenn du mit Signalen statt Variablen arbeitest, dann bist du auch 
gedanklich "näher" an der Hardware :-)

von chris h. (Gast)


Lesenswert?

Danke für deine Antwort. Der Counter soll wenn dieser enabled ist 32 
Taktzyklen runterzählen und anschließend beim Nulldurchlauf  ein Flag 
setzen (roll over zero flag). Der Counter soll mit einem festen Wert 
geladen werden können, quasi mit den 32 Zyklen. Wenn die 32 Zyklen 
runtergezählt sind soll mit dem overrun bit einen Takt lang ein Flag 
gesetzt werden. Es passt ja auch alles wunderbar nur ich brauche halt 
einfach zu viele LEs im Vergleich zum IP Core von Altera.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

chris h. schrieb:
> Kann ich noch was vereinfachen?
Es ist idR. besser, einen Zähler hochzählen und mit dem Endwert 
vergleichen zu lassen. Hast du das mal probiert?
1
signal   cnt : integer range 0 to 63 := 0;
2
3
process (clk,aclr)
4
begin
5
   if aclr  = '1' then
6
     cnt <= 0;
7
   elsif (rising_edge(clk)) then
8
      cout <='0';
9
      if load = '1' then
10
         -- Laden und Zurücksetzen ist das Selbe!?
11
         cnt <= 0;
12
      elsif enable = '1' then
13
         if cnt<31 then   -- sättigender Zähler nötig?
14
            cnt <= cnt+1;
15
         else 
16
            cout <='1';
17
         end if;
18
      end if;
19
   end if;
20
end process;
21
22
-- Output the current count
23
q <= std_logic_vector(to_unsigned(cnt,6));


BTW:
deine Sensitivliste ist nicht vollständig: aclr fehlt.
Und die Kommentare sind fragwürdig:
1
   -- Increment the counter if counting is enabled         
2
   cnt := cnt - 1;
"minus eins" ist ein Decrement...

von Schlumpf (Gast)


Lesenswert?

Also wenn ich dich richtig verstehe, dann willst du 32 mal zählen und 
erst mit dem 33. Takt wird der Überlauf gesetzt und bleibt so lange 
gesetzt, bis der counter neu gestartet wird.

Dann würde ich einen Zähler machen, der von 31 auf 0 zählt (oder 
andersrum) und mit Erreichen des Vergleichswertes das Overrun-REGISTER. 
setzen, welches dann erst einen Takt später seinen Zustand ändert.

Dann hast einen 5-Bit Zähler, der bei erreichen von 0 (oder 31) EINEN 
Takt später einen Overrun auslöst.

von chris h. (Gast)


Lesenswert?

Danke für deine Antwort. Hochzählen würde genauso funktionieren. Dein 
Design benötigt aber auch noch 11 LEs, so wie meines...Hmm, ich habe auf 
meinem MAX3000 nur noch 8 LEs frei...

von chris h. (Gast)


Lesenswert?

Ja richtig, nur das mein zero Flag auch nur solange aktiv ist, solange 
der Counter den Wert 0 hat, also genau einen Takt lang.

von Schlumpf (Gast)


Lesenswert?

chris h. schrieb:
> Ja richtig, nur das mein zero Flag auch nur solange aktiv ist, solange
>
> der Counter den Wert 0 hat, also genau einen Takt lang.

Also du willst, dass es nur EINEN Takt lang aktiv ist?

von chris h. (Gast)


Lesenswert?

Ja genau, nur solange der Counter den Nulldurchgang hat...

von Schlumpf (Gast)


Lesenswert?

Brauchst du das Enable-Signal unbedingt? Und wenn ja, muss das jederzeit 
den Zählvorgang anhalten können?

von chris h. (Gast)


Lesenswert?

Ja, das enable muss nach dem load signal die zweite Prio haben. Es 
schaltet den Zählvoragng ein und aus.

von Schlumpf (Gast)


Lesenswert?

also unterbricht auch einen aktiven Zählvorgang? Oder setzt diesen 
zurück oder was macht das?
Ist Laden auch ohne Enable erlaubt? Also steuert enable nur das zählen?

von chris h. (Gast)


Lesenswert?

Ja, wenn enable weg ist bricht das Zählen auch ab. Laden ohne enable ist 
erlaubt...nur das Zählen läuft über den enable.

von Schlumpf (Gast)


Lesenswert?

Wenn load den Counter zurücksetzt, aber er nicht losläuft, solange 
enable nicht aktiv ist. Und ein inaktives enable den Counter ebenfalls 
abbricht, dann haben meines Erachtens doch enable und load die gleiche 
Funktion, oder nicht?

von Schlumpf (Gast)


Lesenswert?

probier mal sowas aus:
Ist ein bisschen gemurkst, aber könnte evtl klein werden
1
process (clk, aclr, load)
2
begin
3
   if ((aclr  = '1') or (load = '1')) then
4
     cnt <= "000000";
5
   elsif (rising_edge(clk)) then
6
     if enable = '1' then
7
        cnt <= cnt+1;
8
        if cnt(5) = '1' then
9
          cnt <= "111111";
10
        end if;
11
     end if;  
12
   end if;
13
end process;
14
cout <= cnt(5) and not cnt(4);

von chris h. (Gast)


Lesenswert?

ja, genau genommen schon...

von chris h. (Gast)


Lesenswert?

Ja genau so in etwa, danke für den Tipp.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

chris h. schrieb:
> nur das Zählen läuft über den enable.
Was soll passieren, wenn das enable weggeht und wieder aktiviert wird? 
Soll weitergezählt werden?
Falls ja: woher kommt das enable? Ist das ein asynchrones Signal?

> if ((aclr  = '1') or (load = '1')) then
>      cnt <= "000000";
Obacht: ein kombinatorischer asynchroner Reset. Man sollte genau wissen, 
welche Fußanglen da auftauchen können...

von Schlumpf (Gast)


Lesenswert?

Lothar Miller schrieb:
> Man sollte genau wissen, welche Fußanglen da auftauchen können...

... darum auch mein Hinweis...

Schlumpf schrieb:
> Ist ein bisschen gemurkst

von dennis (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Zusammen,
falls es noch aktuell ist, hab ich meine Version angehängt.
Weiss zwar nicht wie groß der in einem MAX3000 wird aber funktional 
enspricht er deinen Vorgaben.
Vielleicht könnte ihn mal jemand für einen MAX3000 synthetisieren und 
Posten wie viel LEs es sind?

Mfg Dennis

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
Noch kein Account? Hier anmelden.