library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity shift_reg is
port(
d : in std_logic;
clk : in std_logic;
rst_bar : in std_logic;
q : out std_logic_vector(7 downto 0)
);
end shift_reg;
architecture post_vhdl_08 of shift_reg is
begin
process(clk, rst_bar)
variable q_int : std_logic_vector(7 downto 0);
begin
if rst_bar = '0' then
q_int := (others => '0');
elsif rising_edge(clk) then
q_int := q_int(6 downto 0) & d;
end if;
q <= q_int;
end process;
end post_vhdl_08;
我已经使用"切片"实现了具有串行输入和并行输出的左移寄存器来实现移位;但是我不知道如何使用重载的移位运算符实现相同的逻辑:"sll"(左移逻辑(运算符。谢谢大家提供的任何帮助。
下面是如何使用 sll
运算符的示例。正如你所看到的,这是一种痛苦,因为它没有做你想做的事,还有其他事情要做:
process(clk, rst_bar)
variable q_int : unsigned(7 downto 0);
subtype st is unsigned(7 downto 0);
begin
if rst_bar = '0' then
q_int := (others => '0');
elsif rising_edge(clk) then
q_int := q_int sll 1;
q_int := q_int or st'(0=>d,others=>'0');
q <= std_logic_vector(q_int);
end if;
end process;
http://www.edaplayground.com/x/3YGu
所以,对于初学者来说,sll
'0'
中转变,这不是你想要的。因此,您需要一个or
操作来包含d
输入。但是,sll
不会重载std_logic_vector
,因此您必须使用 unsigned
或 signed
(unsigned
在这里有意义(。不仅如此,这些类型的运算符在VHDL中做奇怪的事情。所以,如果我是你,我会坚持串联。
此外,您对q
的分配在错误的位置。执行顺序过程时,不得分配给if rising_edge
之外的信号,否则(在这种情况下(将在两个时钟边沿分配q
- 不可合成的行为。
最后,根据合成器的能力,你可以得到 16 个人字拖而不是 8 个。这是因为您的变量将合成为 8 个触发器,而您的信号将合成另外 8 个触发器("在时钟过程中分配的每个信号都推断出一个触发器"(。然后,您在合成器上回复以优化其中的 8 个人字拖。
我可以为您提供这种方法来向左/向右移动或使用旋转(VHDL '87!
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity Barrelshifter is
generic (gSize : natural := 3);
port (
iPortA : in std_ulogic_vector(2**gSize-1 downto 0);
oPortQ : out std_ulogic_vector(2**gSize-1 downto 0);
iShiftDigits : in std_ulogic_vector(gSize-1 downto 0);
iModeSelect : in std_ulogic_vector(1 downto 0)
);
end Barrelshifter;
architecture Rtl of Barrelshifter is
begin -- architecture Rtl
Comb: process (iPortA, iShiftDigits, iModeSelect)
-- component variables
variable Count : integer;
begin -- process Comb
Count := to_integer(unsigned(iShiftDigits));
if iModeSelect = "00" then
oPortQ <= std_ulogic_vector(shift_left(unsigned(iPortA), Count));
elsif iModeSelect = "01" then
oPortQ <= std_ulogic_vector(shift_right(unsigned(iPortA), Count));
elsif iModeSelect = "10" then
oPortQ <= std_ulogic_vector(rotate_left(unsigned(iPortA), Count));
else
oPortQ <= std_ulogic_vector(rotate_right(unsigned(iPortA), Count));
end if;
end process Comb;
end Rtl ;