【问题标题】:VHDL Synthesis: Conditional Reset ValueVHDL 综合:条件复位值
【发布时间】:2019-10-11 11:24:36
【问题描述】:

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

我知道当复位值是某个常数时,合成器会执行某些寄存器优化,但是在上面的示例中也是如此吗?

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

【问题讨论】:

  • 复位的基本功能是使系统进入一个已知状态。添加if 会阻止这一点。同样在重置时cond 的值是多少?为了让你计划工作,它也必须是可变的。您所做的只是将问题移到上游。避免这种情况的唯一方法是,如果 cond 来自外部信号。
  • cond 信号可以假定为外部信号,一旦reset 变低就稳定。
  • 我不确定你为什么想要两个初始状态。如果cond 是一个常量/泛型,并且初始状态可能会根据其值而有所不同,那么这是有道理的。否则,如果cond 在运行时发生变化,那么应该只有一个初始状态,而您在运行时切换到另一种状态。
  • cond 保持不变,直到下一次重置触发。这是一个优化问题,因为我们不会花费在时钟周期上选择先前状态的初始状态。
  • "cond 在下一次重置触发之前保持不变。" 因此cond 在第一次和第二次重置之间变化?如果是这样,你如何选择你想要的第一次重置?

标签: vhdl hardware reset synthesis circuit


【解决方案1】:

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

  • 通常公司设计规则会强制您进行异步复位断言和同步取消断言
  • 50% 的时间不会有与时钟同步的“cond”信号,因此无论如何您都必须对其进行双重采样

因此,考虑到 COND 的双采样将花费 2 个时钟周期,我们可以利用这些约束条件通过在 3 个时钟周期后取消断言内部复位来详细说明某种适当的(恕我直言)复位状态。

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

但可以肯定的是,您可以在 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;

【讨论】:

    【解决方案2】:

    我写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 信号将从所需的复位值开始。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多