我在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;
答案 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列出了桶式移位器的典型成本。
如何改进取决于您的申请。
答案 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的预移位不需要逻辑元素。