Forum: FPGA, VHDL & Co. VHDL Zähler mit beliebiger Breite


von theFloe (Gast)


Lesenswert?

Hallo,

ich verwende erst seit kurzem VHDL auf einem Cyclone mit Quartus II.
Ich habe mir einen 8bit Zähler zusammengebaut und will diesen jetzt
universeller machen.
Ich habe das irgendwo schon mal mit Latches oder Speicherbausteinen
gesehen, dass man die Bus-Breite als Parameter angibt.

Das sieht bei mir im Moment so aus:
COUNTER_0: counter
  generic map (WIDTH => 8)
  port map (Din => cnt0 , Clk=>Clk, Clr_n=>'1', enable=>'1', Cout =>
Cout0);
COUNTER_1: counter
  generic map (WIDTH => 16)
  port map (Din => cnt1 , Clk=>Clk, Clr_n=>'1', enable=>'1', Cout =>
Cout1);

Jedoch bei COUNTER_1 bekomme ich folgenden Fehler:
Error: VHDL expression error at Comm.vhd(81): expression has 16
elements, but must have 8 elements

Zeile 81 ist die bei Counter_1 mit port map(...)

Der Zähler selber sieht so aus:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;



ENTITY counter IS
  generic (WIDTH : Integer := 8);
  PORT
  (
    Din    : IN  std_logic_vector(WIDTH-1 downto 0);
    Clk    : IN  STD_LOGIC;
    Clr_n  : IN  STD_LOGIC;
    enable  : IN  STD_LOGIC;
    Cout  : OUT  STD_LOGIC
  );

END counter;

ARCHITECTURE a OF counter IS
  SIGNAL  value  : std_logic_vector(WIDTH-1 downto 0);
BEGIN

  PROCESS (Clk, Clr_n)
  BEGIN

    IF Clr_n = '0' THEN
      value <= Din;
    ELSIF rising_edge(Clk) THEN
        IF enable = '1' THEN
          value <= value - 1;
        ELSE
          value <= value;
        END IF;

        IF value = 0 then
          Cout <= '1';
          value <= Din;
        ELSE
          Cout <= '0';
        END IF;

    END IF;
  END PROCESS;

END a;


Was ist mein Fehler bzw. wie mache ich das mit der variablen Breite
richtig?

von Ines (Gast)


Lesenswert?

Hallo theFloe,

auf Anhieb sehe ich keinen Fehler :-|. Evtl. hast Du die Länge von cnt1
falsch angesetzt. Ist das Siganl 16 Bit breit?

Ines

von theFloe (Gast)


Lesenswert?

Hallo Ines,

cnt1 hat 16bit:

signal cnt1 : std_logic_vector(15 downto 0) := (others=>'0');

hier noch die component deklaration mir der ich den Zähler einbinde:

component counter
  generic (WIDTH : integer);
  PORT
  (
    Din    : IN  std_logic_vector(7 downto 0);
    Clk    : IN  STD_LOGIC;
    Clr_n  : IN  STD_LOGIC;
    enable  : IN  STD_LOGIC;
    Cout  : OUT  STD_LOGIC
  );
end component;

von Ines (Gast)


Lesenswert?

Aha, da scheint mir der Hund begraben zu liegen. Probiers mal statt
  Din    : IN  std_logic_vector(7 downto 0);

folgende Zeile in der Component Declaration:
  Din    : IN  std_logic_vector(WIDTH-1 downto 0);

Gruß
Ines

von theFloe (Gast)


Lesenswert?

arrr... das ist peinlich...

ja das wars, habe es vergessen zu ändern!

Danke!

von high_speed (Gast)


Lesenswert?

Hallo theFloe
1
IF enable = '1' THEN
2
   value <= value - 1;        
3
ELSE
4
   value <= value;        
5
END IF;
Kann vereinfacht werden.
Die "ELSE"-Verzweigung ist überflüssig und wird wegoptimiert.
[VHDL]
IF enable = '1' THEN
   value <= value - 1;
END IF;
[VHDL]
Bei einem größeren Projekt ist man über jede Vereinfachung dankbar, da
dadurch die Übersichtlichkeit verbessert wird.

MfG
Holger

von theFloe (Gast)


Lesenswert?

Danke, der else zweig stammt noch von einer vorhergehenden zähler den
ich dann umgebaut habe.

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.