VHDL-синтез: условное значение сброса - PullRequest
0 голосов
/ 11 октября 2019

Мне было интересно, как логический синтезатор интерпретирует значение условного сброса. Например, начальное состояние автомата FSM зависит от сигнала асинхронного сброса и некоторых других сигналов, как показано ниже.

state_reg : process(clk, reset)
begin
    if reset = '0' then
        if cond = '1' then
            state <= init_state_0;
        else
            state <= init_state_1;
        end if;
    elsif rising_edge(clk) then
        state <= next_state;
    end if;
end process;

Я знаю, что некоторые оптимизации регистров выполняются синтезаторами, когда значение сброса равно некоторомуконстанта, однако, это также имеет место в примере, подобном приведенному выше?

Одной из причин такой конструкции может быть оптимизация конечного автомата, поскольку не требуется промежуточное состояние для выбора между двумя начальными состояниями.

1 Ответ

0 голосов
/ 12 октября 2019

Я не уверен, что мы можем подумать об оптимизации на этом небольшом примере кода

  • Часто правила разработки компании вынуждают вас иметь асинхронное утверждение сброса и синхронное де-утверждение
  • В 50% случаев у вас не будет сигнала «cond», синхронного с часами, так что вам все равно придется удвоить его выборку

Так что мы можем воспользоваться этими ограничениями, чтобы разработать несколькоправильное (imho) состояние сброса путем отмены внутреннего сброса через 3 такта, учитывая, что двойная выборка COND займет 2 такта.

Таким образом, мы можем извлечь выгоду из (почти) состояния стабильного сброса за один тактовый период.

Но вы наверняка можете сделать это на FPGA, где вы можете экспортировать сигнал данных (здесь внутренний сброспо сравнению с внешним RESET_N) в «сетку» распределения «часов».

Код приведен для информации ниже, и вы можете найти его в EDA Playground

library IEEE;
use IEEE.std_logic_1164.all;

entity state_machine is
port (    CLOCK    : in std_logic;
        RESET_N    : in std_logic;
        COND    : in std_logic;
        OUTPUT     : out std_logic_vector(7 downto 0));
end entity;

architecture rtl of state_machine is

    type state_type is ( S1, S2, S3, S4);
    signal state, next_state : state_type; 

    signal      reset_state        : state_type;

    constant    RSYNC_LENGTH     : natural := 3;
    signal         reset             : std_logic;
    signal         reset_v         : std_logic_vector(RSYNC_LENGTH-1 downto 0);

    signal         scond             : std_logic;
    signal         scond_q1        : std_logic;

    signal         outbuf             : std_logic_vector(7 downto 0);

begin
    reset_sync: process(CLOCK,RESET_N)
    begin
          if RESET_N = '0' then 
            reset_v <= (others => '1');
        elsif rising_edge(CLOCK) then
            reset_v(0) <= '0';
            reset_v(RSYNC_LENGTH-1 downto 1) <=  reset_v(RSYNC_LENGTH-2 downto 0);
        end if;
    end process reset_sync;

    reset <= reset_v(RSYNC_LENGTH-1);

    sync: process(CLOCK,RESET_N)
    begin
          if RESET_N = '0' then 
            scond <= '0';
            scond_q1 <= '0';
        elsif rising_edge(CLOCK) then
            scond_q1 <= COND;
            scond <= scond_q1;
        end if;
    end process sync;

    reset_state <= S2 when scond='1' else S1;

    SM : process(CLOCK,reset)
    begin
        if reset = '1' then
            state <= reset_state;
        elsif ( rising_edge(CLOCK) ) then
            state <= next_state;
        end if;    
    end process SM;

    statedecoder: process(state)
    begin
        case ( state ) is 
            when S1 =>     next_state <= S2;
                        outbuf <= x"01";
            when S2 =>     next_state <= S3;
                        outbuf <= x"02";
            when S3 =>     next_state <= S4;
                        outbuf <= x"03";
            when S4 =>     next_state <= S1;
                        outbuf <= x"04";
            when others => 
                           next_state <= S1;
                        outbuf <= x"00";
        end case;
    end process statedecoder;

    OUTPUT <= outbuf when reset = '0' else x"00";

end architecture rtl;
...