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
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
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;
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
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 ?
>> 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
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 !
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
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;
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.