VHDL综合:条件重置值

时间:2019-10-11 11:24:36

标签: vhdl hardware reset synthesis circuit

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

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

之所以这样设计是因为状态机的优化,因为不需要在两个初始状态之间进行选择就可以选择中间状态。

2 个答案:

答案 0 :(得分:1)

我写了Verilog。

我曾经修改过一个实现条件重置值的行业代码。

assign ctrl_rst_n = sw_rst_n |  cond;
assign ctrl_set_n = sw_rst_n | ~cond;
always@(posedge clk or negedge ctrl_rst_n or negedge ctrl_set_n)begin
  if(~ctrl_rst_n)begin
    ctrl <= 1'b0;
  end else if(~ctrl_set_n)begin
    ctrl <= 1'b1;
  end else begin
    (... normal function logic ...)
  end
end

综合后,我得到了以下网表:

ctrl_rst_n ---+
           ___v___
          |  clr  |
          |D     Q|
          |CK     |
          |__set__|
              ^
ctrl_set_n ---+

在外部模块中有两个名为sw_rst_ncond的用户寄存器,可以通过软件访问。

编程指南如下:

  1. 用户设置或清除cond寄存器以配置信号ctrl的重置值;

  2. 然后清除sw_rst_n寄存器,然后进行设置操作以发出软件复位(软件复位不会复位用户寄存器块);

  3. 软件重置后,信号ctrl从所需的重置值开始。

答案 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;