我想知道逻辑合成器如何解释条件复位值。例如,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;
我知道当复位值是某个常数时,某些寄存器优化是由合成器执行的,但是在上述示例中,情况也是这样吗?
这种设计的一个原因可能是状态机的优化,因为不需要在两个初始状态之间进行选择的中间状态。
我不确定我们是否可以考虑对这个小代码示例进行优化
因此,考虑到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;