1

我已经在 VHDL 中实现了一个移位寄存器。它使用“BITS”作为参数,能够将用户定义的数字向右移动。它按预期工作,但根据 Quartus II 中的 Compilation Report 占用 164 个逻辑元素。谁能告诉我为什么我的代码如此糟糕,也许给我一两个提示来优化它?:) 先感谢您。

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity ssi_data_align is

    port
    (
        DATA_IN      : in   std_logic_vector(31 downto 0);
        BITS         : in   std_logic_vector(4 downto 0);
        DATA_OUT     : out std_logic_vector(31 downto 0));

end entity;

architecture Behavioral of ssi_data_align is

begin

DATA_OUT <= std_logic_vector(SHIFT_RIGHT(unsigned(not DATA_IN), natural(32-(to_integer(unsigned(BITS))))));

end Behavioral;
4

3 回答 3

1

如果您有很多时间,请尝试始终将您的 data_in 移动 32 次。然后只需将 BITS 用作选择器,即可在适当的时钟周期上分接。您应该尝试使用时钟逻辑来解决问题,因为它会合成更小。

也许是这样的?

process (clk)
begin
  if rising_edge(clk) then

    SHIFT_DATA <= '0' & DATA_IN(30 downto 0);

    if BITS = count then
      DATA_OUT <= SHIFT_DATA;
      count <= 0;
    else
      count <= count + 1;
    end if;
  end if;
end process;
于 2014-07-15T13:59:09.513 回答
0

其实你的设计还不错。如果您查看了桶式移位器的典型成本,那么您就处于一个定义的区域(维基百科这里有桶式移位器的典型成本列表。

如何改进取决于您的应用程序。

  • 如果您有足够的时间,您可以切换多个时钟周期。这将逻辑减少到固定大小的 1 位移位器和用于计算移位次数的少量开销,这需要更少的逻辑元素(按常数移位非常便宜)。
  • 如果班次大小是静态的,则可以将其替换为泛型。
于 2014-07-15T13:20:54.233 回答
0

使用适合您的设计规范的测试台:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity data_align_tb is
end entity;

architecture foo of data_align_tb is

    function image(inp: std_logic_vector) return string is
        variable image_str: string (1 to inp'length);
        alias input_str:  std_logic_vector (1 to inp'length) is inp;
    begin
        for i in input_str'range loop
            image_str(i) := character'VALUE(std_ulogic'IMAGE(input_str(i)));
        end loop;
        return image_str;
    end;

    signal DATA_IN:     std_logic_vector (31 downto 0) := (others => '0');
    signal BITS:        std_logic_vector (4 downto 0);
    signal DATA_OUT:    std_logic_vector (31 downto 0);
begin

DUT:
    entity work.ssi_data_align 
        port map (
            DATA_IN => DATA_IN,
            BITS => BITS,
            DATA_OUT => DATA_OUT
        );

STIMULUS:
    process
    begin
        for i in 0 to 31 loop
            BITS <= std_logic_vector(
                        TO_UNSIGNED(natural(i),5)
                    );
            wait for 1 ns;           
        end loop;
        wait;
    end process;

MONITOR:
    process (DATA_OUT)
    begin
        report "BITS = " & image(BITS) & "    DATA_OUT = " & image(DATA_OUT);
    end process;

end architecture;

我们看到的所有 '0' 的常量 DATA_IN 值:

../../../src/ieee/numeric_std-body.v93:2098:7:@0ms:(assertion warning): NUMERIC_STD.TO_INTEGER: metavalue detected, returning 0 ssi_data_align.vhdl:79:9:@0ms:(report note): BITS = uuuuu DATA_OUT = uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu ssi_data_align.vhdl:79:9:@0ms:(report note): BITS = 00000 DATA_OUT = 00000000000000000000000000000000 ssi_data_align.vhdl:79:9:@1ns:(report note): BITS = 00001 DATA_OUT = 00000000000000000000000000000001 ssi_data_align.vhdl:79:9:@2ns:(report note): BITS = 00010 DATA_OUT = 00000000000000000000000000000011 ssi_data_align.vhdl:79:9:@3ns:(report note): BITS = 00011 DATA_OUT = 00000000000000000000000000000111 ssi_data_align.vhdl:79:9:@4ns:(report note): BITS = 00100 DATA_OUT = 00000000000000000000000000001111 ssi_data_align.vhdl:79:9:@5ns:(report note): BITS = 00101 DATA_OUT = 00000000000000000000000000011111 ssi_data_align.vhdl:79:9:@6ns:(report note): BITS = 00110 DATA_OUT = 00000000000000000000000000111111 ssi_data_align.vhdl:79:9:@7ns:(report note): BITS = 00111 DATA_OUT = 00000000000000000000000001111111 ssi_data_align.vhdl:79:9:@8ns:(report note): BITS = 01000 DATA_OUT = 00000000000000000000000011111111 ssi_data_align.vhdl:79:9:@9ns:(report note): BITS = 01001 DATA_OUT = 00000000000000000000000111111111 ssi_data_align.vhdl:79:9:@10ns:(report note): BITS = 01010 DATA_OUT = 00000000000000000000001111111111 ssi_data_align.vhdl:79:9:@11ns:(report note): BITS = 01011 DATA_OUT = 00000000000000000000011111111111 ssi_data_align.vhdl:79:9:@12ns:(report note): BITS = 01100 DATA_OUT = 00000000000000000000111111111111 ssi_data_align.vhdl:79:9:@13ns:(report note): BITS = 01101 DATA_OUT = 00000000000000000001111111111111 ssi_data_align.vhdl:79:9:@14ns:(report note): BITS = 01110 DATA_OUT = 00000000000000000011111111111111 ssi_data_align.vhdl:79:9:@15ns:(report note): BITS = 01111 DATA_OUT = 00000000000000000111111111111111 ssi_data_align.vhdl:79:9:@16ns:(report note): BITS = 10000 DATA_OUT = 00000000000000001111111111111111 ssi_data_align.vhdl:79:9:@17ns:(report note): BITS = 10001 DATA_OUT = 00000000000000011111111111111111 ssi_data_align.vhdl:79:9:@18ns:(report note): BITS = 10010 DATA_OUT = 00000000000000111111111111111111 ssi_data_align.vhdl:79:9:@19ns:(report note): BITS = 10011 DATA_OUT = 00000000000001111111111111111111 ssi_data_align.vhdl:79:9:@20ns:(report note): BITS = 10100 DATA_OUT = 00000000000011111111111111111111 ssi_data_align.vhdl:79:9:@21ns:(report note): BITS = 10101 DATA_OUT = 00000000000111111111111111111111 ssi_data_align.vhdl:79:9:@22ns:(report note): BITS = 10110 DATA_OUT = 00000000001111111111111111111111 ssi_data_align.vhdl:79:9:@23ns:(report note): BITS = 10111 DATA_OUT = 00000000011111111111111111111111 ssi_data_align.vhdl:79:9:@24ns:(report note): BITS = 11000 DATA_OUT = 00000000111111111111111111111111 ssi_data_align.vhdl:79:9:@25ns:(report note): BITS = 11001 DATA_OUT = 00000001111111111111111111111111 ssi_data_align.vhdl:79:9:@26ns:(report note): BITS = 11010 DATA_OUT = 00000011111111111111111111111111 ssi_data_align.vhdl:79:9:@27ns:(report note): BITS = 11011 DATA_OUT = 00000111111111111111111111111111 ssi_data_align.vhdl:79:9:@28ns:(report note): BITS = 11100 DATA_OUT = 00001111111111111111111111111111 ssi_data_align.vhdl:79:9:@29ns:(report note): BITS = 11101 DATA_OUT = 00011111111111111111111111111111 ssi_data_align.vhdl:79:9:@30ns:(report note): BITS = 11110 DATA_OUT = 00111111111111111111111111111111 ssi_data_align.vhdl:79:9:@31ns:(report note): BITS = 11111 DATA_OUT = 01111111111111111111111111111111

从上次报告的值中显示DATA_IN(0)未使用的值,并且可能会导致一个或多个综合警告。您还可以从元值清除后的第一个报告语句中看到,没有一个DATA_IN用于 32 - BITS for BITS= "0000" 的移位。

对于 0 到 31 的 BITS 等价物,您的表达式natural(32-(to_integer(unsigned(BITS))))产生 32 到 1 的值natural。您可以对移位器进行编码,直接保存 7 个逻辑元素,同时避免在消除减法时出于预期目的使用类型转换而引起过多的宗教反对。

范围为 1 到 32(或 0 到 31)的单向移位器是 5 级 2:1 多路复用器,其中每个 BITS“位”在两个值之一之间进行选择以馈送到下一级。SHIFT_RIGHT 提供算术移位(0 个填充)。

将这些多路复用器直接表示为查找表中的一位 2:1 多路复用器(占用一个逻辑元件)告诉我们您需要 159 个逻辑元件。(5级多路复用器为31 + 32 + 32 + 32 + 32,not隐藏在第一级)。

BITS 和 32 - BITS 之间存在二进制补码关系,通过交换来消除减法:

architecture foo of ssi_data_align is

begin 

SHIFTER:
    DATA_OUT <= std_logic_vector(
                    SHIFT_RIGHT(
                        unsigned('0' & not DATA_IN(31 downto 1)),
                        to_integer(unsigned(not BITS))
                    )
                );

end architecture;

BITS 的反转和 DATA_IN 的预移位。

正如 Jim Lewis 所指出的,natural不需要将类型转换为,并且为了尊重 Brian 缩进和添加新行字符,以增强维护和理解的便利性。

它给出了相同的答案:

../../../src/ieee/numeric_std-body.v93:2098:7:@0ms:(assertion warning): NUMERIC_STD.TO_INTEGER: metavalue detected, returning 0 ssi_data_align.vhdl:84:13:@1ns:(report note): BITS = 00000 DATA_OUT = 00000000000000000000000000000000 ssi_data_align.vhdl:84:13:@2ns:(report note): BITS = 00001 DATA_OUT = 00000000000000000000000000000001 ssi_data_align.vhdl:84:13:@3ns:(report note): BITS = 00010 DATA_OUT = 00000000000000000000000000000011 ssi_data_align.vhdl:84:13:@4ns:(report note): BITS = 00011 DATA_OUT = 00000000000000000000000000000111 ssi_data_align.vhdl:84:13:@5ns:(report note): BITS = 00100 DATA_OUT = 00000000000000000000000000001111 ssi_data_align.vhdl:84:13:@6ns:(report note): BITS = 00101 DATA_OUT = 00000000000000000000000000011111 ssi_data_align.vhdl:84:13:@7ns:(report note): BITS = 00110 DATA_OUT = 00000000000000000000000000111111 ssi_data_align.vhdl:84:13:@8ns:(report note): BITS = 00111 DATA_OUT = 00000000000000000000000001111111 ssi_data_align.vhdl:84:13:@9ns:(report note): BITS = 01000 DATA_OUT = 00000000000000000000000011111111 ssi_data_align.vhdl:84:13:@10ns:(report note): BITS = 01001 DATA_OUT = 00000000000000000000000111111111 ssi_data_align.vhdl:84:13:@11ns:(report note): BITS = 01010 DATA_OUT = 00000000000000000000001111111111 ssi_data_align.vhdl:84:13:@12ns:(report note): BITS = 01011 DATA_OUT = 00000000000000000000011111111111 ssi_data_align.vhdl:84:13:@13ns:(report note): BITS = 01100 DATA_OUT = 00000000000000000000111111111111 ssi_data_align.vhdl:84:13:@14ns:(report note): BITS = 01101 DATA_OUT = 00000000000000000001111111111111 ssi_data_align.vhdl:84:13:@15ns:(report note): BITS = 01110 DATA_OUT = 00000000000000000011111111111111 ssi_data_align.vhdl:84:13:@16ns:(report note): BITS = 01111 DATA_OUT = 00000000000000000111111111111111 ssi_data_align.vhdl:84:13:@17ns:(report note): BITS = 10000 DATA_OUT = 00000000000000001111111111111111 ssi_data_align.vhdl:84:13:@18ns:(report note): BITS = 10001 DATA_OUT = 00000000000000011111111111111111 ssi_data_align.vhdl:84:13:@19ns:(report note): BITS = 10010 DATA_OUT = 00000000000000111111111111111111 ssi_data_align.vhdl:84:13:@20ns:(report note): BITS = 10011 DATA_OUT = 00000000000001111111111111111111 ssi_data_align.vhdl:84:13:@21ns:(report note): BITS = 10100 DATA_OUT = 00000000000011111111111111111111 ssi_data_align.vhdl:84:13:@22ns:(report note): BITS = 10101 DATA_OUT = 00000000000111111111111111111111 ssi_data_align.vhdl:84:13:@23ns:(report note): BITS = 10110 DATA_OUT = 00000000001111111111111111111111 ssi_data_align.vhdl:84:13:@24ns:(report note): BITS = 10111 DATA_OUT = 00000000011111111111111111111111 ssi_data_align.vhdl:84:13:@25ns:(report note): BITS = 11000 DATA_OUT = 00000000111111111111111111111111 ssi_data_align.vhdl:84:13:@26ns:(report note): BITS = 11001 DATA_OUT = 00000001111111111111111111111111 ssi_data_align.vhdl:84:13:@27ns:(report note): BITS = 11010 DATA_OUT = 00000011111111111111111111111111 ssi_data_align.vhdl:84:13:@28ns:(report note): BITS = 11011 DATA_OUT = 00000111111111111111111111111111 ssi_data_align.vhdl:84:13:@29ns:(report note): BITS = 11100 DATA_OUT = 00001111111111111111111111111111 ssi_data_align.vhdl:84:13:@30ns:(report note): BITS = 11101 DATA_OUT = 00011111111111111111111111111111 ssi_data_align.vhdl:84:13:@31ns:(report note): BITS = 11110 DATA_OUT = 00111111111111111111111111111111 ssi_data_align.vhdl:84:13:@32ns:(report note): BITS = 11111 DATA_OUT = 01111111111111111111111111111111

仍然DATA_IN(0)未使用,但保存产生 6 位距离的减法运算。

DATA_IN 的预移位不消耗逻辑元件。

于 2014-07-16T01:18:31.287 回答