在VHDL.....,如何计算向量的前导零?[英] In VHDL ..... how to count leading zeros of vector?

本文是小编为大家收集整理的关于在VHDL.....,如何计算向量的前导零?的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

我正在一个VHDL项目中工作,我正在面临计算向量长度的问题.我知道矢量有长度属性,但这不是我想要的长度.例如,我有std_logic_vector

    E : std_logic_vector(7 downto 0);  

然后

    E <= "00011010";

so,len = E'length = 8,但我不是在寻找这个.我想在丢弃大多数零零后计算len,所以len = 5;

我知道我可以通过检查" 0" s位从左到右检查循环,并在发生" 1"位时停止.但这不是有效的,因为我有1024或更多的位,这会减慢我的电路.因此,是否有任何方法或算法可以有效地计算长度?例如使用log(n)门的组合门(其中n =位数).

推荐答案

您使用的"位计数"与对数非常相似(基数2).

这是在VHDL中使用的,以确定表示信号需要多少位.例如,如果您想在RAM中存储多达n个元素,则解决RAM所需的位数是CEIL(log2(n)).为此我使用:

function log2ceil(m:natural) return natural is
begin -- note: for log(0) we return 0
    for n in 0 to integer'high loop
        if 2**n >= m then
            return n;
        end if;
    end loop;
end function log2ceil;

通常,您想在与常数合成时进行此操作,而速度无关紧要.但是,如果您确实想要的话,您也可以生成FPGA逻辑.

正如其他人提到的那样,VHDL中的" for"循环仅用于生成一个查找表,该表可能由于较长的信号路径而慢,但仍然只需一个时钟.可能发生的是您的最大时钟频率下降.通常,如果您在大于64位(提到1024位)和比100MHz快的矢量上操作时,这只是一个问题.也许合成器已经告诉您这是您的问题,否则我建议您先尝试.

然后,您必须在多个时钟上将操作分开,然后将一些中间结果存储到FF中. (我会预先忘记试图通过重新安排代码来超越合成器.查找桌是一个表.为什么要在此表中生成值,但是请确保您告诉合成器有关"不在乎" "如果您有它们.)

如果您关心的速度,请使用第一个时钟并行检查所有16位块(彼此独立),然后使用第二个时钟周期将所有16位块的结果组合到单个结果中.如果您关注的FPGA逻辑的数量,请在每个时钟周期内实现检查单个16位块的状态机.

但是请注意,您在这样做时不会重新发明CPU.

其他推荐答案

使用循环的问题是,当您合成时,您可能会获得很长的逻辑链.

查看您的问题的另一种方法是找到最重要的设置位的索引. 为此,您可以使用优先级编码器.关于这一点的好处是,您可以通过在树结构中使用较小的优先级编码来制作大量优先级编码器,因此延迟是O(log n)而不是O(n).

这是一个4位优先级编码器: http://en.wikibooks.org/wiki/VHDL_for_FPGA_Design/Priority_Encoder 您可以使用其中5个块进行16位优先级编码器,然后从5个16位编码器等中进行256位编码器.

,由于您有很多位,它将相当巨大.

其他推荐答案

好吧,VHDL不是SW,不需要时间执行这样的操作,它只是从您的FPGA中获取资源.

您可以将1024位数据分为32位部分,并在所有位之间执行或执行或在所有位之间执行或在一次检查中,您一次检查32位.这不是真正的必要在你的数组中1.我没有编译此代码,但是类似的代码应该对您有用:

FirstOne <= 1023;
for i in E'reverse_range loop
  if (E(i) == '1') then
    FirstOne <= i;
    exit;
  end if;
end loop;

毕竟它不会是FPGA内部的大块.

本文地址:https://www.itbaoku.cn/post/2090953.html

问题描述

I'm working in a VHDL project and I'm facing a problem to calculate the length of vector. I know there is length attribute of a vector but this not the length I'm looking for. For example, I have std_logic_vector

    E : std_logic_vector(7 downto 0);  

then

    E <= "00011010";

so, len = E'length = 8 but I'm not looking for this. I want to calculate len after discarding the left most zeros , so len = 5;

I know that I can use for loop by checking "0"s bits from left to right and stop if "1" bit occur. But that's not efficient, because I have 1024 or more of bits and that will slow my circuit. So is there is any method or algorithm to calculate the length in efficient way? Such as using combinational gates of log(n) level of gates, ( where n = number of bits ).

推荐答案

What you do with your "bit counting" very similar to the logarithm (base 2).

This is commonly used in VHDL to figure out how many bits are required to represent a signal. For example if you want to store up to N elements in RAM, the number of bits required for addressing that RAM is ceil(log2(N)). For this I use:

function log2ceil(m:natural) return natural is
begin -- note: for log(0) we return 0
    for n in 0 to integer'high loop
        if 2**n >= m then
            return n;
        end if;
    end loop;
end function log2ceil;

Usually, you want to do this at synthesis time with constants, and speed is no concern. But you can also generate FPGA logic, if that's really what you want.

As others have mentioned, a "for" loop in VHDL is just used to generate a lookup table, which may be slow due to long signal paths, but still only takes a single clock. What can happen is that your maximum clock frequency goes down. Usually this is only a problem if you operate on vectors larger than 64bit (you mentioned 1024 bits) and clocks faster than 100MHz. Maybe the synthesizer already told you that this is your problem, otherwise I suggest you try first.

Then you have to split up the operation over multiple clocks, and store some intermediate result into a FF. (I would upfront forget about trying to outsmart the synthesizer by rearranging your code. A lookup-table is a table. Why should it matter how you generate the values in this table? But make sure you tell the synthesizer about "don't care" values if you have them.)

If speed is your concern, use the first clock to check all 16bit blocks in parallel (independent of each other), and then use a second clock cycle to combine the results of all 16bit blocks into a single result. If the amount of FPGA logic is your concern, implement a state machine that checks a single 16bit block at every clock cycle.

But be careful that you don't re-invent the CPU while doing that.

其他推荐答案

The problem with using a loop is that when you synthesize you might get a very long chain of logic.

Another way to look at your problem is to find the index of the most significant set bit. To do this you can use a priority encoder. The nice thing about this is you can make a large priority encoder by using smaller priority encoders in a tree structure, so the delay is O(log N) instead of O(N).

Here is a 4 bit priority encoder: http://en.wikibooks.org/wiki/VHDL_for_FPGA_Design/Priority_Encoder You can make a 16 bit priority encoder using 5 of these blocks, then a 256 bit encoder from five 16 bit encoders, etc.

But since you have so many bits it is going to be fairly huge.

其他推荐答案

Well, VHDL is not SW, it does not take time to perform an operation like this, it just takes resources from your FPGA.

You can divide your 1024 bits data into 32 bits section and perform an OR between all the bits, this way, you check 32 bits at a time. It is not really necessary since the the for loop would work perfectly fine for what you want to do, just write the code, look for the first 1 in the array and stop the loop and use the loop index number as the pointer to the first 1 in your array. I didn't compile this code, but something like this should work for you:

FirstOne <= 1023;
for i in E'reverse_range loop
  if (E(i) == '1') then
    FirstOne <= i;
    exit;
  end if;
end loop;

It will not be such a big blocks inside an FPGA after all.