Ich versuche, Schaltungen mit geschalteten Kondensatoren zu implementieren, und muss daher einen zweiphasigen, nicht überlappenden Takt erzeugen. Ich habe versucht, ein FPGA für dasselbe zu verwenden. Leider gibt mein Synthesetool Quartus II Timing-Warnungen aus. Wenn ich den Code auf das FPGA (FPGA der Altera MAX7000S-Serie) speichere, beobachte ich außerdem deutlich metastabile Pegel und unvorhersehbare Ausgaben.
Der Code, den ich geschrieben habe, um dies zu implementieren, ist unten angegeben:
Architektur clock_gen_integrator_arch von clock_gen_integrator ist Signalzähler_15: STD_LOGIC_VECTOR (3 bis 0); Signal phi1_sig, phi2_sig: STD_LOGIC; Signalzähler: STD_LOGIC_VECTOR (14 bis 0);
begin
phi1 <= phi1_sig;
phi2 <= phi2_sig;
signal_gen: process (reset, clock25M) begin
if(reset = '0') then
counter_15 <= (others => '0');
counter <= (others => '0');
phi1_sig <= '1';
phi2_sig <= '0';
reset_int <= '1';
elsif(clock25M = '1' and clock25M'EVENT) then
if(counter < "000010000000000" and counter_15 < "1111") then
phi1_sig <= '0';
phi2_sig <= '0';
counter <= counter + 1;
reset_int <= '0';
elsif (counter < "011100000000000" and counter_15 < "1111") then
phi1_sig <= '1';
phi2_sig <= '0';
counter <= counter + 1;
reset_int <= '0';
elsif (counter < "100010000000000" and counter_15 < "1111") then
phi1_sig <= '0';
phi2_sig <= '0';
counter <= counter + 1;
reset_int <= '0';
elsif (counter < "111100000000000" and counter_15 < "1111") then
phi1_sig <= '0';
phi2_sig <= '1';
counter <= counter + 1;
reset_int <= '0';
elsif (counter < "111111111111111" and counter_15 < "1111") then
phi1_sig <= '0';
phi2_sig <= '0';
counter <= counter + 1;
reset_int <= '0';
elsif (counter = "111111111111111" and counter_15 < "1111") then
counter_15 <= counter_15 + 1;
counter <= counter + 1;
reset_int <= '0';
else
phi1_sig <= phi1_sig;
phi2_sig <= phi2_sig;
reset_int <= '0';
end if;
end if;
end process;
end architecture;
Leider kann ich hier nicht den gesamten Code einfügen, da ich Formatierungsprobleme habe. Da es sich jedoch nur um die Deklaration der Entität handelt, habe ich sie weggelassen. phi1(out), phi2(out), reset(in), reset_int(out), clock25M(in) sind in der Portliste vorhanden.
In diesem Code wähle ich willkürlich die Frequenz und die Arbeitszyklen der erforderlichen Uhren aus. Ich möchte speziell 15 Impulse von phi1 und 15 Impulse von phi2 und counter_15 hilft mir dabei.
Mir wird von QuartusII mitgeteilt, dass ich Setup-Zeitverletzungen habe.
Entschuldigung für das Graustufenbild, ich musste das Bild irgendwie verkleinern, um es hochzuladen. Der erste Kanal ist der Phi1-Ausgang und der zweite Kanal ist der Phi2-Ausgang. Da ich sowohl mit dem Tool als auch mit der Timing-Analyse neu bin, wäre ich dankbar, wenn jemand darauf hinweisen könnte, was ich falsch mache und wie ich die Timing-Verletzung beheben kann. Außerdem sind alle Tipps zur Vermeidung dieser Probleme im Allgemeinen willkommen.
Ein allgemeines Verfahren zur Verbesserung des Timings besteht darin, die Logik über mehrere Zyklen aufzuteilen, indem Ergebnisse registriert werden.
Du könntest so etwas versuchen...
signal_gen: process (reset, clock25M) begin
if(reset = '0') then
counter_15 <= (others => '0');
counter <= (others => '0');
phi1_sig <= '1';
phi2_sig <= '0';
reset_int <= '1';
counter_15_not_done <= true;
count_lt_000010000000000 <= false;
count_lt_011100000000000 <= false;
count_lt_100010000000000 <= false;
count_lt_111100000000000 <= false;
count_lt_111111111111111 <= false;
count_eq_111111111111111 <= false;
elsif(clock25M = '1' and clock25M'EVENT) then
--the comparisons are computed in parallel and registered
counter_15_not_done <= counter_15 < "1111";
count_lt_000010000000000 <= count < "000010000000000";
count_lt_011100000000000 <= count < "011100000000000";
count_lt_100010000000000 <= count < "100010000000000";
count_lt_111100000000000 <= count < "111100000000000";
count_lt_111111111111111 <= count < "111111111111111";
count_eq_111111111111111 <= count = "111111111111111";
--the logic now only depends on the registered results.
--The registered results are only 7 bits rather than 19 bits
--this should have much better timing
if(count_lt_000010000000000 and counter_15_not_done) then
phi1_sig <= '0';
phi2_sig <= '0';
counter <= counter + 1;
reset_int <= '0';
elsif (count_lt_011100000000000 and counter_15_not_done) then
phi1_sig <= '1';
phi2_sig <= '0';
counter <= counter + 1;
reset_int <= '0';
elsif (count_lt_100010000000000 and counter_15_not_done) then
phi1_sig <= '0';
phi2_sig <= '0';
counter <= counter + 1;
reset_int <= '0';
elsif (count_lt_111100000000000 and counter_15_not_done) then
phi1_sig <= '0';
phi2_sig <= '1';
counter <= counter + 1;
reset_int <= '0';
elsif (count_lt_111111111111111 and counter_15_not_done) then
phi1_sig <= '0';
phi2_sig <= '0';
counter <= counter + 1;
reset_int <= '0';
elsif (count_eq_111111111111111 and counter_15_not_done) then
counter_15 <= counter_15 + 1;
counter <= counter + 1;
reset_int <= '0';
else
phi1_sig <= phi1_sig;
phi2_sig <= phi2_sig;
reset_int <= '0';
end if;
end if;
end process;
end architecture;
Beachten Sie, dass die registrierten Ergebnisse den tatsächlichen Zählungen um 1 Taktzyklus nacheilen, sodass Sie möglicherweise die Vergleichspunkte um 1 Zyklus zurücksetzen müssen.
Gleichheit wird mit weniger 'Gatter'-Verzögerungsstufen implementiert als Magnitude ("<"), was eine Subtraktion beinhaltet und nicht vollständig wegoptimiert wird, wenn es Operandenwerte gibt, die größer als der größte statische Magnitude-Operand sind. (Der höchste Zählervergleichsoperand ist x"7800", der höchste Zählerstand ist x"7FFF".)
Verwenden Sie nur Gleichheitsvergleiche, zum Beispiel:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all; -- ADDED
entity clock_gen_integrator is
port (
clock25M: in std_logic;
reset: in std_logic;
reset_int: out std_logic;
phi1: out std_logic;
phi2: out std_logic
);
end entity;
architecture foo of clock_gen_integrator is
signal counter_15: unsigned (3 downto 0); -- WAS std_logic_vector
signal phi1_sig: std_logic;
signal phi2_sig: std_logic;
signal counter: unsigned(14 downto 0); -- WAS std_logic_vector
signal notcount15: boolean;
signal notcount15h: boolean;
begin
phi1 <= phi1_sig;
phi2 <= phi2_sig;
notcount15 <= counter_15 /= 15; -- 4 input NAND gate
signal_gen:
process (reset, clock25M)
begin
if reset = '0' then
counter_15 <= (others => '0');
notcount15h <= true;
counter <= (others => '0');
phi1_sig <= '1';
phi2_sig <= '0';
reset_int <= '1';
-- elsif clock25M = '1' and clock25M'EVENT then
elsif rising_edge (clock25M) then
-- the counters:
counter <= counter + 1;
if counter = x"3800" and notcount15 then
counter_15 <= counter_15 + 1;
end if;
-- notcount15h holdover flip flop for phi2
if counter = x"3800" and not notcount15 then
notcount15h <= false;
end if;
-- reset_int flip flop:
reset_int <= not reset;
-- toggle phi1:
if counter = x"400" and notcount15 then
phi1_sig <= '1';
elsif counter = x"3800" and notcount15 then
phi1_sig <= '0';
end if;
-- toggle phi2:
if counter = x"4400" and notcount15h then
phi2_sig <= '1';
elsif counter = x"7800" and notcount15h then
phi2_sig <= '0';
end if;
-- four equality comparators to specific 15 bits of counter
end if;
end process;
end architecture;
library ieee;
use ieee.std_logic_1164.all;
entity clock_gen_integrator_tb is
end entity;
architecture foo of clock_gen_integrator_tb is
signal clock25M: std_logic := '0';
signal reset: std_logic := '1';
signal reset_int: std_logic;
signal phi1: std_logic;
signal phi2: std_logic;
begin
CLOCK:
process
begin
wait for 20 ns;
clock25M <= not clock25m;
if now > 21 ms then
wait;
end if;
end process;
DUT:
entity work.clock_gen_integrator
port map (
clock25M => clock25M,
reset => reset,
reset_int => reset_int,
phi1 => phi1,
phi2 => phi2
);
STIMULUS:
process
begin
wait for 30 ns;
reset <= '0';
wait for 80 ns;
reset <= '1';
wait;
end process;
end architecture;
Die Testbench demonstriert 15 phi1- und phi2-Taktgeber ("Ich möchte speziell 15 Impulse von phi1 und 15 Impulse von phi2 und Zähler_15 hilft mir dabei, dies zu erreichen") auf denselben Zählerwerten wie in der ursprünglichen Architektur clock_gen_integrator_arch:
Alle unteren Bits in Ihren Übergangspunkten sind Null (ohne den Fall zu zählen, in dem Sie phi2
zweimal löschen, sodass Sie die Uhr einige Male teilen und einen kleineren Zähler verwenden können.
Sie können die Erzeugung einer kontinuierlichen Impulsfolge beliebiger Länge (niederwertige Bits des Zählers) und die Weiterleitung an einen Ausgang (höherwertige Bits) auch aufteilen, z. B. 16 Impulse mit an Einschaltdauer und zwei Ausgänge könnten mit einem 8-Bit-Zähler erreicht werden (nicht einmal kompiliert getestet, aber Sie sollten auf die Idee kommen):
pulse <= '1' WHEN counter(2 downto 0) = "000" ELSE '0';
output <= counter(3);
phi1 <= pulse AND NOT output;
phi2 <= pulse AND output;
Habe counter
nach oben gelaufen und danach angehalten "11111111"
.
Abhängig davon, was sonst noch im Design vor sich geht, würde ich wahrscheinlich auch eine PLL verwenden, um einen langsamen (1 MHz) Takt abzuleiten und von dort zu teilen.
Leider ist dies eine schlechte Implementierung eines Designs, das keine Spezifikationen oder Toleranzen hat. Beginnen Sie immer mit Konstruktionsspezifikationen und Toleranzen, bevor Sie versuchen, eine Lösung zu entwerfen.
Ihr Mangel an Impedanzdesign (RdsOn oder Schalter-ESR) und Durchhang durch Leckage zeigen Hinweise auf quantisiertes Klingeln und Kommutierungsrauschen.
Die Auswahl der Kappen sollte nicht aus Keramik sein, die Hysterese- und Mikrofonieprobleme in S&H-Designs haben, es sei denn, es handelt sich um den Typ NP0.
Gegeben;
Schaltungen mit geschalteten Kondensatoren und ich muss daher einen zweiphasigen, nicht überlappenden Takt erzeugen
Was sind die folgenden? Schließen Sie jeweils die erwarteten Toleranzen ein.
Je mehr Spezifikationen Sie im Voraus definieren, die Fehler verursachen können, desto größer ist die Chance, dass Sie es gleich beim ersten Mal richtig machen . Andernfalls Iterationen von Designspezifikationen und Wiederholung oder Verwirrung, wenn es fehlschlägt.
Welche Methode ist nun am einfachsten, um diese Anforderungen zu erstellen? analog? Wie bei allen Vollbrückendesigns oder digital mit Quantisierungszeitauflösungsgrenzen oder?
Welche Schaltungen haben Sie gelesen, die in CMOS-App-Büchern veröffentlicht wurden, die bereits funktionieren? Und wenn nicht, warum nicht?
ps
Es gibt viele Tools zum Ändern der Bildgröße oder des Komprimierungsverhältnisses, um die Dateigröße zu reduzieren und die 32-Bit-Farbe beizubehalten.
Erhöhen Sie den Abstand und die ruhige Hand mit der Kamera, dann Autofokus, direkt zum Monitor, um das klarste Bild zu erhalten, und schneiden Sie es dann nach Bedarf zu.
crj11
Alter Furz
Amog
Amog
Alter Furz
crj11
Amog
crj11
Amog
Chris Stratton