移位寄存器使用太多逻辑元素

时间:2014-07-15 13:09:44

标签: vhdl shift-register

我在VHDL中实现了一个移位寄存器。它使用" BITS"作为能够将用户定义的数字向右移动的参数。它按预期工作,但根据Quartus II中的编译报告占用了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;

3 个答案:

答案 0 :(得分: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;

答案 1 :(得分:0)

实际上你的设计并不是那么糟糕。如果你看一下桶式移位器的典型成本,那么你就可以进入一个明确的区域(Wikipedia here列出了桶式移位器的典型成本。

如何改进取决于您的申请。

  • 如果你有足够的时间,你可以转换多个时钟周期。这减少了逻辑到固定大小的1位移位器和用于计算移位数的小开销,这需要更少的逻辑元素(通过常数移位非常便宜)。
  • 如果班次大小是静态的,您可以将其替换为通用。

答案 2 :(得分: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没有用于BITS =“0000”的32 - BITS的转换。

您的表达式natural(32-(to_integer(unsigned(BITS))))为BITS natural等效0到31生成32 downto 1的值。您可以直接编码移位器,保存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的预移位不需要逻辑元素。