VHDL整数范围输出总线宽度

VHDL整数范围输出总线宽度,vhdl,quartus,intel-fpga,Vhdl,Quartus,Intel Fpga,我目前正在用VHDL编写一个简单的计数器,试图尽可能地将其泛化。理想情况下,我最终得到一个计数器,它可以暂停、向上/向下计数,并只取两个整数(最小值、最大值)来确定适当的总线宽度 据我所知,为了得到一个给定范围的整数,我只需要关心一下 变量cnt:最小到最大的整数范围:=0 其中,min和max在实体中定义为泛型(两个整数)。我的理解是,如果min是0,max是5,例如,它将创建一个3位的整数变量 我的问题是我实际上想要输出这个整数。所以,很自然地,我写作 计数器输出:输出最小到最大的整数范围

我目前正在用VHDL编写一个简单的计数器,试图尽可能地将其泛化。理想情况下,我最终得到一个计数器,它可以暂停、向上/向下计数,并只取两个整数(最小值、最大值)来确定适当的总线宽度

据我所知,为了得到一个给定范围的整数,我只需要关心一下

变量cnt:最小到最大的整数范围:=0

其中,min和max在实体中定义为泛型(两个整数)。我的理解是,如果min是0,max是5,例如,它将创建一个3位的整数变量

我的问题是我实际上想要输出这个整数。所以,很自然地,我写作

计数器输出:输出最小到最大的整数范围

但这似乎不是我所需要的。我用Quartus Prime生成了一个原理图块,它从[min…max]创建了一个总线输出。例如,如果min=0,max=65,则输出66位总线。它应该取代七位总线

如果我将计数器限制为无符号值,我可能就能够计算出输出总线的大小,但我希望尽可能地保持灵活性,当然我想知道我到底做错了什么,以及如何正确地做

TL;DR:我希望VHDL实体采用通用的最小值、最大值,并生成所需宽度的整数输出总线,以保持值的范围。怎么办

如果重要的话,我现在使用的是Quartus Prime Lite版本V20.1.0

注意:我知道我可以使用STD_LOGIC_VECTOR来代替,但它的模拟速度要慢得多,而且据我所知,它比整数类型更不容易使用。如果有必要,我可以提供更多的代码,但就我所知,这一行确实是问题所在

我最初在Stackexchange上发布了这篇文章,但我认为Stackoverflow可能是一个更好的地方,因为它更多的是一个编程问题,而不是一个硬件问题

编辑:完整代码如下所示

LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;
USE ieee.std_logic_signed.all;

ENTITY Counter IS
    GENERIC (modulo : INTEGER := 32;
                min : INTEGER := 0;
                max : INTEGER := 64);
    PORT( pause : IN STD_LOGIC;
            direction : IN STD_LOGIC; -- 1 is up, 0 is down
            clk : IN STD_LOGIC;
            counterOut : OUT INTEGER RANGE min TO max --RANGE 0 TO 32 -- THIS line is the one generating an incorrect output bus width
            );
END ENTITY Counter; 
-- or entity

ARCHITECTURE CounterArch OF Counter IS
BEGIN
    PROCESS(direction, pause, clk)
    VARIABLE cnt : INTEGER RANGE min TO max := 0; 
    VARIABLE dir : INTEGER;
    BEGIN
    IF direction = '1' THEN
        dir := 1;
    ELSE
        dir := -1;
    END IF;
    IF clk'EVENT AND clk = '1' THEN
        IF pause = '0'THEN
            IF (cnt = modulo AND direction = '1') THEN
                cnt := min; -- If we're counting up and hit modulo, reset to min value.
            ELSIF (cnt = min AND direction = '0') THEN
                cnt := modulo; --Counting down hit 0, go back to modulo.
            ELSE
                cnt := cnt + dir;
            END IF;
        END IF;
    END IF;
    counterOut <= cnt;
    END PROCESS;
END ARCHITECTURE CounterArch;
ieee库;
使用ieee.std_logic_1164.all;
使用ieee.numeric_std.all;
使用ieee.std\u logic\u signed.all;
实体计数器为
通用(模:整数:=32;
最小值:整数:=0;
最大值:整数=64);
端口(暂停:在STD_逻辑中;
方向:在STD_逻辑中,-1向上,0向下
clk:标准逻辑中;
计数器输出:输出整数范围从最小到最大——范围从0到32——这一行生成的输出总线宽度不正确
);
终端实体计数器;
--或实体
柜台的建筑反拱是
开始
过程(方向、暂停、时钟)
变量cnt:最小到最大的整数范围:=0;
变量dir:整数;
开始
如果方向='1',则
dir:=1;
其他的
dir:=-1;
如果结束;
如果clk'事件和clk='1',则
如果pause='0',则
如果(cnt=模,方向='1'),则
cnt:=min;--如果我们计算并点击模,重置为最小值。
ELSIF(cnt=min,方向为'0'),然后
cnt:=模--倒计时点击0,返回模。
其他的
cnt:=cnt+dir;
如果结束;
如果结束;
如果结束;

这不是一个VHDL问题,而是一个工具问题。整数在VHDL本身中没有二进制表示,工具自己进行转换。至于std_逻辑_向量比整数慢-几乎没有。std_逻辑_向量更可能需要更多ram(多几个字节)。最大的加速比是使用变量而不是信号。您需要发布一些失败的代码。您的一般理解是可以的,只是您没有得到3位整数-您得到的是只有一些值有效的完整整数。要精确到3个实位,您需要转换为与位相关的类型。@我同意,我认为在这一点上这肯定是一个工具问题,Quartus出于某种原因在使用泛型时做出了与直接在范围内硬编码不同的假设,与它斗争以实现我想要的可能是不值得的。如果向量不会太慢,我可能会彻底修改代码,使用无符号作为输出。谢谢你的建议@EML我添加了我的代码,虽然我认为我已经决定这只是一个工具合成的东西,Quartus正在对我的代码做一些假设,在使用泛型和整数文本之间进行更改。我很可能会改为在输出总线上使用unsigned和一个通用的宽度参数(这里的整数的想法是设置一个容易定制的范围,避免使用计数器时使用width->range的二进制数学,但这不是必要的)。至于整数是满的,你确定吗?我已经对它进行了模拟,当我指定时,内部变量的位肯定会减少。VHDL没有整数的二进制表示。Synth工具将转换为有限整数范围的适当位数。但是一个模拟整数,即使范围有限,仍然是32位(或实现定义的)。