本文介绍了在 VHDL'93 中声明具有可变位宽的可变数量的信号的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试实现类似于 的通用加法器树这里.为了存储中间结果,我需要声明具有可变位宽的可变数量的信号.例如:

I'm trying to implement an generic adder tree similar to here. For storing the intermediate results, I need to declare a variable number of signals with variable bitwidth. For example:

位宽 = 8 的 4 个输入值:

4 input values with bitwidth = 8:

  1. 第一阶段之后:2 个位宽 = 9 的值
  2. 第二阶段之后:位宽 = 10 的 1 个值

位宽 = 8 的 9 个输入值:

9 input values with bitwidth = 8:

  1. 第一阶段之后:5 个位宽 = 9 的值
  2. 第二阶段后:3 个位宽 = 10 的值
  3. 第三阶段后:2 个位宽 = 11 的值
  4. 第四阶段之后:位宽 = 12 的 1 个值

我刚刚找到了一种使用length = # input valuesbitwidth = 最后一个信号的位宽 来实例化数组的解决方案.但我想要类似以下的东西.包含连接到 std_logic_vector 的每个阶段的值的记录,但它显然不起作用:

I just found one solution to instantiate an array with length = # input values and bitwidth = bitwidth of the last signal. But I want to have something like the following. A record including the values of each stage concatenated to an std_logic_vector, but it's obviously not working:

lb(INPUT_VALUES) == 阶段数

nr_val(i) == 阶段值的数量 ->在单独的函数中计算

type adder_stages is record
  for i in 1 to lb(INPUT_VALUES) generate
    stage(i-1) : std_logic_vector(nr_val(i)*(BITWIDTH+i)-1 downto 0);
  end generate;
end record adder_stages;

是否可以根据 VHDL '93 中的输入值数量来声明具有增加位宽的可变数量的信号?

Is it possible to declare a variable amount of signals with increasing bitwidth and dependent on the number of input values in VHDL '93?

推荐答案

与 NiM 的断言相反,NiM 断言不可能在任何版本(修订版)的 VHDL,都可能在 -2008 年.

Contrary to NiM's assertion that it's impossible to declare a variable amount of signals with increasing bitwidth and dependent on the number of input values in any version (revision) of VHDL, it is possible in -2008.

秘诀是对输入端口使用组件实例化递归,该输入端口的类型是无界数组,并在对象声明中提供元素子类型指示.输入的数量及其长度可以在连续的递归级别中更改(输入数量向下,元素子类型长度向上).输出端口等宽,由最底层的加法器输出驱动.

The secret is to use component instantiation recursion with an input port whose type is an unbounded array with an element subtype indication provided in the object declaration. The number of inputs and their length can be changed (number of inputs down, element subtype length up) in successive recursion levels. The output port is of a constant width and is driven by the lowest level adder output.

-1993 年不支持定义具有延迟元素子类型指示的无界数组定义.

Defining an unbounded array definition with a deferred element subtype indication is not supported in -1993.

除了保证级别的长度和数量正常工作之外,此代码尚未经过验证.它使用无符号算术,因为 OP 没有另外指定.Resize 用于增加加法器结果长度.

This code hasn't been verified other than guaranteeing the lengths and numbers of levels work correctly. It uses unsigned arithmetic because the OP didn't specify otherwise. Resize is used to increase the adder result length.

报告语句用于调试并且可以删除(令人惊讶的是,您可以在稍微复杂的事情中犯下多少简单的错误).

The report statements were used for debugging and can be removed (amazing how many simple errors you can make in something only mildly convoluted).

library ieee;
use ieee.std_logic_1164.all;

package adder_tree_pkg is  
    function clog2 (n: positive) return natural;
    type input_array is array (natural range <>) of
               std_logic_vector; --  -2008 unbounded array definition
    function isodd (n: positive) return natural;
end package;

package body adder_tree_pkg is
    function clog2 (n: positive) return natural is
        variable r: natural := 0;
        variable m: natural := n - 1;
    begin
        while m /= 0 loop
            r := r + 1; 
            m := m / 2;
        end loop;
        return r;
    end function clog2;

    function isodd (n: positive) return natural is
    begin
        if (n/2 * 2 < n) then
            return 1;
        else 
            return 0;
        end if;
    end function;
end package body;

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std_unsigned.all;

use work.adder_tree_pkg.all;

entity adder_tree_level is
    generic (
        constant INPUTS:  positive := 9;
        constant BITS:    positive := 8;
        constant LEVEL:   positive  := clog2(INPUTS);
        constant Y_OUT_LEN: positive := LEVEL + BITS
    );
    port (
        clk:    in  std_logic;
        rst_n:  in  std_logic;
        x_in:   in  input_array (INPUTS - 1 downto 0) (BITS - 1 downto 0);
        y_out:  out std_logic_vector (Y_OUT_LEN - 1 downto 0)
    );
end entity;

architecture foo of adder_tree_level is
    constant ODD_NUM_IN:    natural := isodd(INPUTS);
    constant NXT_INPS:  natural := INPUTS/2 + ODD_NUM_IN;

    signal x:           input_array (INPUTS - 1 downto 0) (BITS - 1 downto 0);
    signal nxt_x:       input_array (NXT_INPS - 1 downto 0)
                                    (BITS downto 0);
    constant NPAIRS:    natural  := (INPUTS)/2;
begin
INPUT_REGISTER:
    process (clk, rst_n)

    begin
        if rst_n = '0' then
            x <= (others =>(others => '0')); 
        elsif rising_edge (clk) then
            x <= x_in;
        end if;
    end process;

ADDERS: 
    process (x)
    begin
        report "LEVEL = " & integer'image(LEVEL);
        report "y_out'length = " & integer'image(y_out'length);
        report "nxt_x(0)'length = " & integer'image(nxt_x(0)'length);
        for i in 0 to NPAIRS - 1 loop  -- odd out is x'high ('left)
            nxt_x(i) <= resize(x(i * 2), BITS + 1) + x(i * 2 + 1);
            report "i * 2 = " & integer'image (i * 2);
            report "i * 2 + 1 = " & integer'image (i * 2 + 1);
        end loop;
        if ODD_NUM_IN = 1 then
            report "x'left = " & integer'image(x'left);
            nxt_x(nxt_x'HIGH) <= resize(x(x'LEFT), BITS + 1);
        end if;
    end process;
RECURSE:
    if LEVEL > 1 generate 
NEXT_LEVEL:
        entity work.adder_tree_level
        generic map (
            INPUTS => NXT_INPS,
            BITS => BITS + 1,
            LEVEL => LEVEL - 1,
            Y_OUT_LEN => Y_OUT_LEN
        )
        port map (
            clk => clk,
            rst_n => rst_n,
            x_in => nxt_x,
            y_out => y_out
        );
    end generate;
OUTPUT: 
   if LEVEL = 1 generate
FINAL_OUTPUT:
        y_out <= nxt_x(0);
    end generate;
end architecture;

此示例不符合对 OP 问题回答是"的标准(这是一个 是/否问题)并简单地驳斥了 NiM 的断言,即您不能在 VHDL 的任何版本(修订版)中做到这一点.

This example doesn't meet the criteria for answering Yes to the OP's question (which is a yes/no question) and simply refutes NiM's assertion that you can't do it in any version (revision) of VHDL.

它的端口的灵感来自于 Pipelined Adder Tree VHDL 代码发现通过 图像 OP 链接.

It's ports are inspired by the Pipelined Adder Tree VHDL code found by the image the OP linked.

这篇关于在 VHDL'93 中声明具有可变位宽的可变数量的信号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-29 20:50