Forum: FPGA, VHDL & Co. Simulation und Resourcen?


von ChristofR (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

ich habe einen Frequenzteiler mit angehängt, der aus 1Mhz -> 100 Hz
machen soll.

Da das ding dabei bis 10000 zählen muss, weiß ich nun aber nicht, wie
ich das mit einer testbench überprüfen kann ?

Weiter hab ich eine Frage zum Resourcenverbrauch:
Beim Xilinx CPLD 9536, werden nach der synthese 17 von 36 macrozellen
verbraucht und 149 von 180 Produkttermen. Ist das nicht ein bischen
viel ?, da bleibt ja fast nix mehr übrig. Hab ich den Frequenzteiler
vielleicht zu schlecht beschrieben ?

Grüße

Christof

von Hagen (Gast)


Lesenswert?

signal Q : std_logic_vector ( 15 downto 0);
signal CLK_Temp : std_logic;

verbrauchen schonmal 17 Makrozellen.

Du solltest den Reset auch asynchron machen, in etwa so

architecture Takteiler of Clock_Generator is

  signal Q: std_logic_vector (15 downto 0);
  signal CLK_Temp: std_logic;

begin

  process(OSC_Inv_In, Reset)
  begin
    if Reset = '1' then
      Q <= (others => '0');
  CLK_Temp <= '0';
    elsif OSC_Inv_In'Event and OSC_Inv_In = '1' then
  if Q < x"2710" then
        Q <= Q + 1;
  else
        Q <= (others => '0');
        CLK_Temp <= not CLK_Temp;
  end if;
    end if;
  end process Clock_Inverter;

  CLK_Out <= CLK_Temp;

end Takteiler;

Oder du probierst es andersrum, manchmal spart das Resourcen:

architecture Takteiler of Clock_Generator is

  signal Q: std_logic_vector (15 downto 0);
  signal CLK_Temp: std_logic;

begin

  process(OSC_Inv_In, Reset)
  begin
    if Reset = '1' then
      Q <= x"2710";
  CLK_Temp <= '0';
    elsif OSC_Inv_In'Event and OSC_Inv_In = '1' then
  if Q > 0 then
        Q <= Q - 1;
  else
        Q <= x"2710";
        CLK_Temp <= not CLK_Temp;
  end if;
    end if;
  end process Clock_Inverter;

  CLK_Out <= CLK_Temp;

end Takteiler;

Desweiteren kannst du im WebPack in den Fitter Optionen einiges
einstellen. Probiere mal alle Einstellungen von Speed auf Density,
besonders den Hacken bei "use Multi-Level-Optimization" raus nehmen.
Ich habe die Erfahrung gemacht das entgegen dem Wortlaut der Hacken das
genaue Gegenteil bewirkt. Also angehackt -> mehr Resourcen verbraucht,
abgehackt -> weniger Resourcem verbraucht.

Gruß Hagen

von Hagen (Gast)


Lesenswert?

Au man ist das ein Shit, du arbeitest mit Tabulatoren in deinen Source:

architecture Takteiler of Clock_Generator is

  signal Q: std_logic_vector (15 downto 0);
  signal CLK_Temp: std_logic;

begin

  process(OSC_Inv_In, Reset)
  begin
    if Reset = '1' then
      Q <= (others => '0');
      CLK_Temp <= '0';
    elsif OSC_Inv_In'Event and OSC_Inv_In = '1' then
      if Q < x"2710" then
        Q <= Q + 1;
      else
        Q <= (others => '0');
        CLK_Temp <= not CLK_Temp;
      end if;
    end if;
  end process Clock_Inverter;

  CLK_Out <= CLK_Temp;

end Takteiler;


architecture Takteiler of Clock_Generator is

  signal Q: std_logic_vector (15 downto 0);
  signal CLK_Temp: std_logic;

begin

  process(OSC_Inv_In, Reset)
  begin
    if Reset = '1' then
      Q <= x"2710";
      CLK_Temp <= '0';
    elsif OSC_Inv_In'Event and OSC_Inv_In = '1' then
      if Q > 0 then
        Q <= Q - 1;
      else
        Q <= x"2710";
        CLK_Temp <= not CLK_Temp;
      end if;
    end if;
  end process Clock_Inverter;

  CLK_Out <= CLK_Temp;

end Takteiler;

von Hagen (Gast)


Lesenswert?

Ach übrigens

Q: std_logic_vector(15 downto 0);

ist zu groß deklariert für 0x2710. Du benötigst nur 14 Bits, also

Q: std_logic_vector(13 downto 0);

sollte ausreichend sein.

Gruß Hagen

von ChristofR (Gast)


Lesenswert?

Danke Hagen ;o)

aber was macht denn diese zeile genau :

Q <= (others => '0');      ?

Was bringt es denn für einen Vorteil, wenn der Reset asynchron ist ?
hab gedacht man soll alles immer möglichst synchron ausführen.

Warum steht die zuweisung:

CLK_Out <= CLK_Temp;

außerhalb des prozesses ?

von Hagen (Gast)


Lesenswert?

>> Q <= (others => '0');

Umgkehrt gefragt, was für Nachteile hat es wenn man es so macht ?

Q <= "00000";

Ganz einfach, änderst du dir Deklaration von Q, sprich der Vektor hat
später mal mehr oder weniger Bits, dann musst du die zweite Zuweisung
jedesmal mit ändern, das kann nerven. Bei der ersten Deklaration werden
einfach alle Bits des Vektore auf '0' gesetzt, automatisch zur
aktuellen Breite des Vektors.


>> Was bringt es denn für einen Vorteil, wenn der Reset asynchron ist
?

Das sofort und solange der Reset aktiv ist intern sich nichts rühren
kann. Schau mal wenn Reset == '1' ist dann wird der komplette elsif
Teil mit der Clock garnicht mehr ausgeführt. Das hat noch einen
weiteren ganz wichtigen Vorteil: du der nachfolgende Clock Code wird
vereinfacht und kann durch den Fitter nun sehr einfach in getaktete
FF's umgesetzt werden, denn Clock ist der Takteingang für den Zähler
und Reset ist der asynchrone Reset des gleichen Zählers. So wie du es
gemacht hast benötigt der Fitter zusätzliche Logik, da der ansychrone
Reset der FF's eben nun synchron zur Clock ist. Das benötigt
mindestens ein AND zusätzlich.


>> Warum steht die zuweisung: CLK_Out <= CLK_Temp; außerhalb des
prozesses ?

Damit sie asynchron wird und so eventuell Makrozellen einspart. Also
für CLK_Temp benötigst du schon ein FF das den Status speichert. Jeden
Ausgangspin den du nun nur innerhalb eines synchronen Clock Prozesses
anspricht hat "zeitlich" eine Lücke in der die Daten gehalten werden
müssen, man benötig im ungünstigsten Falle also einen Buffer->ergo ein
FF zusätzlich. Das ist aber garnicht nötig da ja CLK_Temp schon den
Inhalt für den CLK_Out Ausgang enthält. Mit der externen asynchronen
Zuweisungist sichergestellt das CLK_Out immer zu jedem Zeitpunkt mit
CLK_Temp verknüpft ist.

Schwierig zu erklären, bin selber noch Anfänger.

Gruß Hagen

von ChristofR (Gast)


Lesenswert?

Hey Spitze ich habs verstanden ;o)
Was heißt hier Anfänger, tu mal nicht so bescheiden g

Also ich werd dann mal weiter probieren und bestimmt bald mal wieder ne
Frage auf dem Herzen zu VHDL haben...

Danke !

von Andreas Ehret (Gast)


Lesenswert?

Hallo Christoph,

hast Du schon eine Lösung bzgl. des Testbenchs, weil Du nicht
simulieren kannst?

Ich habe das gleiche Problem bei einem Taktteiler 1 MHz --> 1 kHz ....

Gruß
  Andy

von unknown (Gast)


Lesenswert?

Du kannst die Schleife auch Hilfe von Integer Zahlen durchlaufen lassen.
Dürfte dann so aussehen:

entity counter is
generic (ende: natural:= 27);
port (iCLK, iRESET: in std_logic;
    oCLK: out std_logic);
end counter;

architecture Behavioral of counter is
signal temp: integer range 0 to ende;
signal pCLK: std_logic := '1';
begin
    P1: process(iCLK,temp)
    begin
      if rising_edge(iCLK) then
      if iRESET='0' then
          temp <= 0;
          pCLK <= '0';

          else
          if temp < ende-1 then
            temp <= temp+1;

          else
            temp <= 0;
            pCLK <= not pCLK;

          end if;
      end if;
      end if;

    end process P1;

      oCLK <= pCLK;

end Behavioral;

von Kutzi (Gast)


Lesenswert?

Testbench sieht dann in etwa so aus:

bench : process
  begin

    iclk <= '0';
    wait for 10 ps;

    iclk <= '1';
    wait for 10 ps;

  end process;




  RESET: process
  begin

  iRESET <= '0';
  iRESET <= '1' after 100 ps;
  wait;
  END PROCESS;

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.