Vhdl 简单倒计时计数器整数与无符号

Vhdl 简单倒计时计数器整数与无符号,vhdl,Vhdl,不必按如下方式构建计数器- signal my_counter : unsigned(3 downto 0) := to_unsigned(9, 4); signal reset_value : unsigned(3 downto 0) := to_unsigned(9, 4); --... --... process(clk) begin if rising_edge(clk) then counter <= counter - 1; if cou

不必按如下方式构建计数器-

signal my_counter : unsigned(3 downto 0) := to_unsigned(9, 4);
signal reset_value : unsigned(3 downto 0) := to_unsigned(9, 4);
--...
--...
process(clk)
begin
    if rising_edge(clk) then
        counter <= counter - 1;
        if counter = 0 then
            counter <= reset_value;
            -- raise flag telling other logic to do stuff
        end if;
    end if;
end process;
signal my_counter:unsigned(3到0):=to_unsigned(9,4);
信号重置值:无符号(3到0):=到无符号(9,4);
--...
--...
过程(clk)
开始
如果上升沿(clk),则

counter从整数创建您自己的子类型,并将
counter
变量定义为该类型:

subtype MY_COUNTER_TYPE is integer range 0 to 9;
signal counter : MY_COUNTER_TYPE := 9;
为您自己的子类型声明一个“滚动减量”函数,如果减量会减少范围下的值,则该函数会将值折叠回范围内可能的最高值:

function r_decrement(val : MY_COUNTER_TYPE) return MY_COUNTER_TYPE is
begin
  if val = MY_COUNTER_TYPE'LOW then
    return MY_COUNTER_TYPE'HIGH;
  else
    return val - 1;
  end if;
end function;
现在,您可以使用该类型的滚动减量功能,而不用担心手动重置计数器或检查减量是否会导致信号超出允许范围:

if rising_edge(clk) then

  counter <= r_decrement(counter); -- "rolling" decrement

  if counter = 0;
    -- raise flag telling other logic to do stuff
  end if;

end if;
如果上升沿(clk),则

计数器无符号类型在变为0(返回到2**N-1,其中N是位数)时将发生翻滚,integer在模拟中试图减小到其最小值以下时将给出错误。但实际硬件可能会发生翻滚,导致模拟/硬件不匹配。整数不对二的幂进行模运算的原因是它们是标量,没有位,它们是数学定义的。进一步的算术运算不是为模运算定义的,它们遵循普通的数学意义。通过转换为二进制等价物来合成整数数学的思想,即使在使用二进制数表示类型时,也不会扩展到两个模运算的非幂次。在这里声明子类型和声明具有子类型指示的对象之间没有有用的区别,就像在原始问题中一样。答案中没有提供是/否问题的答案。唯一有用的区别是避免声明可能的最高值,而是使用属性。我知道实现所需行为的唯一方法是使用一个递减和滚动值的函数。
if rising_edge(clk) then

  counter <= r_decrement(counter); -- "rolling" decrement

  if counter = 0;
    -- raise flag telling other logic to do stuff
  end if;

end if;