VHDL合成:条件重置值

问题描述 投票:0回答:1

我想知道逻辑合成器如何解释条件复位值。例如,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;

我知道当复位值是某个常数时,某些寄存器优化是由合成器执行的,但是在上述示例中,情况也是这样吗?

这种设计的一个原因可能是状态机的优化,因为不需要在两个初始状态之间进行选择的中间状态。

vhdl hardware reset synthesis circuit
1个回答
0
投票

我不确定我们是否可以考虑对这个小代码示例进行优化

  • 通常,公司设计规则会迫使您进行异步重置声明和同步取消声明
  • 50%的时间,您将不会有与时钟同步的'cond'信号,因此无论如何您都必须对其进行两次采样

因此,考虑到COND的两次采样将花费2个时钟周期,我们可以在3个时钟周期后取消内部复位,从而利用这些约束条件来制定某种适当的(imho)复位状态。

通过这种方式,我们可以受益于(几乎)一个时钟周期的稳定复位状态。

但是可以肯定的是,您可以在FPGA上执行此操作,在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;
© www.soinside.com 2019 - 2024. All rights reserved.