effizienterer VHDL Counter

Gast #3041347
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.
Angehängte Dateien:
Gast #3041496
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).
Gast #3042829
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?
Gast #3042924
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 :-)
Gast #3042948
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.
Moderator (Firma: Titel) Persönliche Seite #3042987
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...
Gast #3043041
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.
Gast #3043183
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?
Gast #3043204
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);
Moderator (Firma: Titel) Persönliche Seite #3044068
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...
Gast #3407533
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
Angehängte Dateien:

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren