Ich muss ein Lattice Semiconductor FPGA einschränken und habe einige Zweifel an der hier beschriebenen Multicycle-Einschränkung . Ich habe folgendes RTL:
Im Grunde ist es ein Zähler, der von einem Anstiegsflankendetektor angesteuert wird. Jedes Mal, wenn ein Signal von 0 auf 1 ansteigt, wird ein Impuls erzeugt und der Zähler erhöht sich. Dies ist auch der VHDL-Code, nur um klar zu sein:
type COM_PACKETS_COUNTER is array ( 7 downto 0) of std_logic_vector(31 downto 0);
signal capture_com_tx_packet_counter : COM_PACKETS_COUNTER;
signal capture_com_rx_packet_counter : COM_PACKETS_COUNTER;
signal capture_com_tx_data_reg : std_logic_vector(7 downto 0);
signal capture_com_rx_data_reg : std_logic_vector(7 downto 0);
signal capture_com_tx_start_byte_reg : std_logic_vector(7 downto 0);
signal capture_com_rx_start_byte_reg : std_logic_vector(7 downto 0);
signal capture_com_tx_start_byte_reg_delay : std_logic_vector(7 downto 0);
signal capture_com_rx_start_byte_reg_delay : std_logic_vector(7 downto 0);
signal capture_com_tx_start_byte_reg_edge : std_logic_vector(7 downto 0);
signal capture_com_rx_start_byte_reg_edge : std_logic_vector(7 downto 0);
..........................
COM_COUNTER_PROCESS :
for i in 0 to capture_com_tx_data_reg'length-1 generate
process(clk_i, rst_i)
begin
if rst_i = '1' then
capture_com_rx_start_byte_reg_delay(i) <= '0';
capture_com_rx_start_byte_reg_edge(i) <= '0';
capture_com_tx_start_byte_reg_delay(i) <= '0';
capture_com_tx_start_byte_reg_edge(i) <= '0';
elsif clk_i = '1' and clk_i'event then
capture_com_rx_start_byte_reg_delay(i) <= capture_com_rx_start_byte_reg(i);
capture_com_rx_start_byte_reg_edge(i) <= not ( capture_com_rx_start_byte_reg_delay(i) ) and capture_com_rx_start_byte_reg(i) and CAPTURE_COM_RX_SELECTED_FILTER(i);
capture_com_tx_start_byte_reg_delay(i) <= capture_com_tx_start_byte_reg(i);
capture_com_tx_start_byte_reg_edge(i) <= not ( capture_com_tx_start_byte_reg_delay(i) ) and capture_com_tx_start_byte_reg(i) and CAPTURE_COM_TX_SELECTED_FILTER(i);
end if;
end process;
process(clk_i,rst_i)
begin
if rst_i = '0' then
capture_com_tx_packet_counter(i) <= (others => '0');
elsif clk_i'event and clk_i = '1' then
if capture_com_tx_start_byte_reg_edge(i) = '1' then
capture_com_tx_packet_counter(i) <= capture_com_tx_packet_counter(i) + 1;
end if;
if capture_com_rx_start_byte_reg_edge(i) = '1' then
capture_com_rx_packet_counter(i) <= capture_com_rx_packet_counter(i) + 1;
end if;
end if;
end process;
end generate;
Ich habe mehrere Zähler in meinem Design. Jetzt möchte ich das Timing entspannen, also frage ich mich, ob ich eine "Multicycle-Einschränkung" zwischen dem Quellregister ( capture_com_rx_start_byte_reg_edge ) und dem Zielregister ( capture_com_rx_packet_counter ) verwenden kann, weil ich nicht brauche, dass der Zähler nach dem Anstieg aktualisiert wird von capture_com_tx_start_byte_reg.
Meine einzige Sorge ist, dass der erzeugte Impuls länger als einen Taktzyklus dauern könnte, was ein Problem sein könnte, da der Zähler um mehr als 1 Einheit erhöht werden könnte.
Bei der Verwendung von Multicycles muss darauf geachtet werden, dass der Pfad tatsächlich Multicycle-sicher ist. In Ihrem Fall würde das Fehlen von Clock-Enable capture_com_rx_packet_counter
es "unsicher" machen. Es sollte möglich sein, das Synthesewerkzeug zu zwingen, ein Flip-Flop-Grundelement mit einem Clock-en zu verwenden, was der erste Schritt zum Multicycle wäre.
Obwohl Multicycle sehr nützlich ist, um das Timing zu entspannen, würde ich es nur empfehlen, wenn es Ihre letzte Lösung ist. Ist dieser Weg wirklich problematisch? Versagt es Timings? Ist jeder andere Pfad deutlich schneller?
Sie können die Timings auch mit VHDL-Code schneiden. Ein Beispiel, das die Addition in 2 Zyklen durchführt (Eingabe muss 2 Zyklen lang stabil sein, Ausgabe ist nur im zweiten Zyklus gültig):
signal s_lo : unsigned(16 downto 0);
signal s_hi : unsigned(15 downto 0);
process(clk)
begin
if rising_edge(clk) then
s_lo <= '0' & a(15 downto 0) + b(15 downto 0);
s_hi <= a(31 downto 16) + b(31 downto 16) + s_lo(16);
end if;
end process;
s <= s_hi & s_lo(15 downto 0);
haster8558