【问题标题】:How to "sample" a value in VHDL?如何在 VHDL 中“采样”一个值?
【发布时间】:2015-06-01 06:01:15
【问题描述】:

所以我有一个从 1->15 的模数计数器,然后在一个单独的实体中不断循环回来。我想在一个取决于某些输出的案例语句中,在时钟的上升沿采样这个值,但只做一次,否则这个值会不断变化。有没有办法做到这一点?分配信号并让它保持静止? 我已经发布了一些代码,希望能更好地展示我想说的内容。

process(all) 
      begin --sensitivity list?
      if(reset) then
          playerCards <= "0000000000000000";
          dealerCards <= "0000000000000000";
      elsif rising_edge(clock) then
        case? deal & dealTo & dealToCardSlot is
          when "1100" =>
            playerCards(3 downto 0) <= singleCard;
                    playerCards(15 downto 4) <= (others => '0');
          when "1101" =>
            playerCards(7 downto 4) <= singleCard;
                    playerCards(15 downto 8) <= (others => '0');
          when "1110" =>
            playerCards(11 downto 8) <= singleCard;
                    playerCards(15 downto 12) <= (others => '0');
          when "1111" =>
            playerCards(15 downto 12) <= singleCard;
          when "1000" =>
            dealerCards(3 downto 0)   <= singleCard; --dcard1
            dealerCards( 15 downto 4) <= (others => '0');
          when "1001" =>
            dealerCards(7 downto 4)   <= singleCard; --dcard2
            dealerCards( 15 downto 8) <= (others => '0');
          when "1010" =>
            dealerCards(11 downto 8)  <= singleCard; --dcard3
            dealerCards( 15 downto 12) <= (others => '0');
          when "1011" =>
            dealerCards(15 downto 12) <= singleCard; --dcard4
          when "0--0" => null;                       --do nothing when in win/end
          when others => --this covers the start case --sets cards to 0
            playerCards <= "0000000000000000";
            dealerCards <= "0000000000000000"; 
        end case?;
      end if;
  end process;

在这里,我将 singleCard 链接到我的计数器的输出,它会在每个时钟沿递增。所以基本上我希望我的案例陈述只发生一次更新 playerCards 的值,然后停止。 感谢您的帮助。

【问题讨论】:

    标签: case vhdl counter


    【解决方案1】:

    您的要求可以表述为:该过程可以处于两种状态 - 采样或不采样,以及在采样时转换为不采样。

    因此您可以使用状态变量来执行此操作,在这种情况下可以是布尔值 - 这会将您的流程变成状态机。正如另一个答案所说,您可以在此处使用信号而不是变量,但这会破坏封装,使进程内部工作可见。

    有些人会坚持把状态机分成另外两个(甚至三个)进程,但我认为单进程形式要小得多,也更容易理解。

       process(reset,clock) -- original sens list is incorrect for a clocked process
       variable sampling : boolean;
       begin 
          if(reset) then
              sampling <= true;
              -- other reset actions
          elsif rising_edge(clock) then
             if sampling then   -- add conditions here, or it'll sample on the first clock.
                sampling := false;
                case ... -- sampling process and program logic
                end case;
             else
                -- if you need to turn sampling back on, set "sampling" here
             end if;
          end if;
       end process;
    

    【讨论】:

    • 那么他会成为我数据路径中的一种状态机吗?我按理说是这样问的(这是针对学校实验室的),无需在我的 FSM 和数据路径之间添加更多信号即可完成。我想知道像 deal'event & dealTo'event & dealToCardSlot'event 这样的事情是否有效?目前我的 FSM 在按钮按下时转换,我使用与您描述的非常相似的 FSM,然后更新 deal/dealTo/dealToCardSlot 的值。感谢您的帮助,我已经坚持了好几天了。
    • deal'event &amp; dealTo'event &amp; dealToCardSlot'event 对我来说听起来是一个非常糟糕的主意,通常你只在时钟信号上寻找 ' 事件,并且将事件连接到一个聚合中是......很奇怪。干什么用的?
    • 由于 deal,dealTo,dealToCardSlot 在多个时钟周期内保持它们的值,因此 case 语句不断将 singleCard 分配给我的 playerCards 信号。我只是想知道是否有办法拥有一个常量类型,一旦分配就不能再改变了?
    • 当然!这就是上面的过程所做的(在输入错误被修复之后,我刚刚做了。对不起那些)。如果您的意思是,将该行为移到类型本身而不是上面的状态机中,对不起,不。恒定性与类型正交。如果你有一个单独的状态机,将更新/不更新逻辑移到那里可能是有意义的。
    【解决方案2】:

    是的,您需要一个额外的内部信号来控制您的操作模式:更新和非更新。

    这实际上是一种反馈信号。您根据输入条件生成它,然后您也可以在输入时使用它来修改行为。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-12-14
      • 1970-01-01
      • 2012-10-05
      • 2023-03-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多