Ich habe ein 1-Bit-Signal, das von einem Teil meiner Schaltung kommt, der mit einem 40-MHz-Takt läuft. Das Signal ist meistens 0, außer es ist 1 für einen einzelnen 40-MHz-Zyklus alle ~ Millionen Zyklen.
Ein anderer Teil meiner Schaltung läuft mit einem 1-MHz-Takt. Ich möchte das oben beschriebene Signal in diesem Teil meiner Schaltung synchron verarbeiten. Was ist der richtige Weg, um das Einzelzyklus-40-MHz-Signal in ein Einzelzyklus-1-MHz-Signal umzuwandeln?
Falls dies wichtig ist, werden sowohl der 40-MHz- als auch der 1-MHz-Takt von demselben Taktmanager ausgegeben, der vom 32-MHz-Takt auf meiner Entwicklungsplatine gesteuert wird, sodass sie phasenstarr sein sollten.
Konvertieren Sie diesen Impuls in eine Pegeländerung (invertieren Sie den Ausgang eines Flipflops, wenn ein Impuls erzeugt wird), leiten Sie ihn mit ein paar Flipflops zur Synchronisierung weiter und wandeln Sie die Pegeländerung mit einem Flipflop und einem XOR-Gatter wieder in einen Impuls um . Dies wird Impulssynchronisation mit einem Toggle-Synchronisierer genannt und ist eine sehr verbreitete Technik. Siehe: http://www.edn.com/electronics-blogs/day-in-the-life-of-a-chip-designer/4435339/Synchronizer-techniques-for-multi-clock-domain-SoCs .
Bearbeiten: Diese Lösung geht davon aus, dass Sie keinen Zugriff auf den 40-MHz-Takt haben. Wenn ja, dann ist die Antwort von @alex.forencich besser.
Warum verwenden Sie den 40-MHz-Impuls nicht als asynchronen Satz für ein Register im 1-MHz-Bereich. Wenn Sie danach einen Doppelregister-Synchronisierer haben, gefolgt von einem Detektor für steigende Flanken, können Sie den 1-MHz-Impulsausgang des Detektors für steigende Flanken verwenden, um eine beliebige andere Logik auszulösen und als synchrones Löschen des ersten Registers zu fungieren (der mit einem asynchronen Satz).
signal async_reg : std_logic := '0';
signal synchroniser : std_logic_vector (2 downto 0) := (others => '0');
signal rising_edge_detected : std_logic;
...
process (clk1MHz)
begin
if (pulse40MHz = '1') then
async_reg <= '1';
elsif (rising_edge(clk1MHz)) then
if (rising_edge_detected = '1') then
async_reg <= '0';
end if;
end if;
end process;
process (clk1MHz)
begin
if (rising_edge(clk1MHz)) then
synchroniser <= synchroniser(1 downto 0) & async_reg;
end if;
end process;
rising_edge_detected <= synchroniser(1) and not synchroniser(2);
scary_jeff
Argus Braun
alex.forencich
Paebbels
Kaktus