VHDL - 自定义移位器 - 串联输入(在定义的范围内)和剩余的零

时间:2016-02-20 01:03:38

标签: logic concatenation vhdl

我正在尝试编写自己的移位器。关于变速器都没关系,所以请不要建议我以不同的方式做变速器。移位器只是为了演示我遇到的问题。

这是一段移民描述:

 1:   with operand_b select result <=
 2:   operand_a when "0000",
 3:   operand_a(14 downto 0) & '0' when "0001",
 4:   operand_a(13 downto 0) & "00" when "0010",
 5:   operand_a(12 downto 0) & "000" when "0011",
 6:   operand_a(11 downto 0) & "0000" when "0100",
 7:   operand_a(10 downto 0) & "00000" when "0101",
 8:   operand_a(9 downto 0) & "000000" when "0110",
 9:   operand_a(8 downto 0) & "0000000" when "0111",
10:   operand_a(7 downto 0) & "00000000" when "1000",
11:   operand_a(6 downto 0) & "000000000" when "1001",
12:   operand_a(5 downto 0) & "0000000000" when "1010",
13:   operand_a(4 downto 0) & "00000000000" when "1011",
14:   operand_a(3 downto 0) & "000000000000" when "1100",
15:   operand_a(2 downto 0) & "0000000000000" when "1101",
16:   operand_a(1 downto 0) & "00000000000000" when "1110",
17:   operand_a(0) & "000000000000000" when others;

operand_b是用于移位的值,result是移位器的输出。

正如您所看到的,这是非常瓶颈的。当我们有64位移位器时会发生什么 - 很多无用的零。我在网上发现了很多如何更合理地写出来,但我尝试的每个解决方案,如operand_a(13 downto 0) & (others => '0') when "0010"(15 downto 2 => operand_a(13 downto 0), others => '0') when "0010"(operand_a(13 downto 0), others => '0') when "0010"都不起作用。我每次收到报告都有错误。

请问任何解决方案?

抱歉我的英文。

修改

当我用第4行替换operand_a(13 downto 0) & "00" when "0010",时:

  • operand_a(13 downto 0) & (others => '0') when "0010",它返回

无法确定聚合中的“其他”值。 (&lt; =也适用于第17行) concat操作的大小不同于目标的大小。

  • (15 downto 2 => operand_a(13 downto 0), others => '0') when "0010",它返回

聚合中元素的类型与任何数组类型都不对应。

  • (operand_a(13 downto 0), others => '0') when "0010",它返回

找不到具有与聚合匹配的类型元素的数组或记录类型。

  • operand_a(13 downto 0) & (1 downto 0 => '0') when "0010",

这个正在运作,但是这里没有办法使用others吗?

1 个答案:

答案 0 :(得分:1)

(operand_a(13 downto 0), others => '0')等值表达式应该适用于IEEE Std 1076-2008。

比较9.3.3.3阵列聚合,第1段和第2段:

  

对于一维数组类型的聚合,每个选项应指定索引类型的值,并且每个元素关联的表达式应为元素类型或聚合类型。如果元素关联的表达式的类型是聚合的类型,那么元素关联应该是位置的,或者选择应该是离散范围。

     

对于具有离散范围的选择的元素关联以及聚合的元素类型的表达式,表达式的值是该范围中每个索引值处的元素。 < / p>

到IEEE Std 1076-1993阵列聚合第1段:

  

对于一维数组类型的聚合,每个选项必须指定索引类型的值,并且每个元素关联的表达式必须是元素类型。 n的聚合-dimensional数组类型,其中n大于1,被写为一维聚合,其中聚合的索引子类型由数组类型的第一个索引位置给出,并且为每个元素关联指定的表达式是(n-1) - 维数组或数组聚合,称为子聚合。允许字符串或位字符串文字作为子集合代替字符类型的一维数组的任何聚合。

在-2008中,我们可以拥有作为聚合类型的关联元素(一维数组类型)。这允许关联相同类型的切片名称。

同时-2008 9.3.3.3第7段允许使用其他选择:

  

e)作为赋值语句中的值表达式,其中目标是声明的对象(或其成员),并且目标的子类型是完全约束的数组子类型,或者目标是切片名称

(目标是切片名称已添加到以前的版本中。)您可以使用其他选项的规则要求您具有提供子类型约束的上下文。

因此它告诉我们您使用的VHDL实现不是-2008兼容(或者不用作-2008兼容)。

此功能在升级到-2008兼容性时实现的优先级较低。

如果您发现您的VHDL工具缺乏支持,还有其他方式来表达您的移位器,例如:

SHIFTER:
    process (operand_b, operand_a)
        variable b: integer range 0 to operand_a'HIGH;
    begin
        result <= (others => '0');
        if not is_x(operand_b) then  -- culling meta-values
            b := to_integer(unsigned(operand_b));
                for i in result'range loop
                    if i = b then
                        result(result'high downto i) <= 
                                operand_a (operand_a'high - i downto 0);
                    end if;
                end loop;
        end if;
    end process;

此过程符合要求,因为切片范围取决于静态值,包括循环常量,循环展开或并行化以进行合成。每个二进制值operand_b都有一个赋值语句,你依赖于综合中的优化(对多路复用器和移位器这样的东西来说效果非常好。)

此方法的工作原理是将所有result写为'0',然后将所需的operand_a部分写入result。它取决于同一进程内的顺序赋值(并且可以与-2008兼容实现中的顺序条件信号赋值一起使用)和if语句或case语句。 (但不是选择的信号分配,它取决于相同的左手侧目标)。

在一个进程中执行的两个赋值语句取决于是否存在单个驱动程序并且由综合支持。最后写入的数组元素值会覆盖先前的数组元素值写入,在投影输出波形中任何特定模拟时间只有一个时隙。