我有一个矢量 signal tmp : std_logic_vector(15 downto 0)
我必须把它移到n位的左边或右边.我怎么才能实现这个操作.我想连接操作,但我不知道如何使用它.
Mar*_*son 25
使用ieee.numeric_std
库以及正在处理(unsigned
或signed
)的数字的相应矢量类型.
然后运算符是sla
/ sra
用于算术移位(即在右移位上填充符号位,在左移位上填充lsb)和sll
/ srl
用于逻辑移位(即填充'0').
您将参数传递给运算符以定义要移位的位数:
A <= B srl 2; -- logical shift right 2 bits
Run Code Online (Sandbox Code Playgroud)
我不知道我上面写的是什么(感谢Val指出这一点!)
当然,移位signed
和unsigned
类型的正确方法是使用shift_left
和中shift_right
定义的函数ieee.numeric_std
.
的移位和循环运算符sll
,ror
等是用于向量boolean
,bit
或std_ulogic
,并且可以具有有趣的是意外的行为,所述算术移位即使复制结束位左移时.
在这里可以找到更多的历史:
http://jdebp.eu./FGA/bit-shifts-in-vhdl.html
但是,原始问题的答案仍然是
sig <= tmp sll number_of_bits;
Run Code Online (Sandbox Code Playgroud)
Jos*_*osh 16
有两种方法可以实现这一目标.连接和移位/旋转功能.
连接是"手动"的做事方式.您可以指定要"保留"原始信号的哪一部分,然后将数据连接到一端或另一端.例如:tmp <= tmp(14 downto 0)&'0';
移位函数(逻辑,算术):这些是通用函数,允许您以多种方式移动或旋转矢量.函数是:sll(向左移位逻辑),srl(向右移位逻辑).逻辑移位插入零.算术位移(sra/sla)插入最左边或最右边的位,但工作方式与逻辑移位相同.请注意,对于所有这些操作,您可以指定要移位的内容(tmp),以及要执行移位的次数(n位)
旋转功能:rol(向左旋转),ror(向右旋转).旋转就是这样,MSB最终进入LSB,一切都向左移动(rol)或反过来为ror.
这是我找到的一个方便的参考(见第一页).
就个人而言,我认为连接是更好的解决方案.通用实现将是
entity shifter is
generic (
REGSIZE : integer := 8);
port(
clk : in str_logic;
Data_in : in std_logic;
Data_out : out std_logic(REGSIZE-1 downto 0);
end shifter ;
architecture bhv of shifter is
signal shift_reg : std_logic_vector(REGSIZE-1 downto 0) := (others<='0');
begin
process (clk) begin
if rising_edge(clk) then
shift_reg <= shift_reg(REGSIZE-2 downto 0) & Data_in;
end if;
end process;
end bhv;
Data_out <= shift_reg;
Run Code Online (Sandbox Code Playgroud)
两者都将实现为移位寄存器.如果您发现自己需要更多的移位寄存器而不是您愿意花费资源(EG将1000个数字除以4),您可以考虑使用BRAM来存储值,并使用单个移位寄存器来包含导致所有数字的正确移位.
我不建议使用sll
或srl
与 std_logic_vector一起使用。
在模拟过程中sll
,这些位为我提供了“U”值,我期望为 0。
使用shift_left()
,shift_right()
函数。
例如:
OP1 : in std_logic_vector(7 downto 0);
signal accum: std_logic_vector(7 downto 0);
-- ...
accum <= std_logic_vector(shift_left(unsigned(accum), to_integer(unsigned(OP1))));
accum <= std_logic_vector(shift_right(unsigned(accum), to_integer(unsigned(OP1))));
Run Code Online (Sandbox Code Playgroud)
这通常是通过从向量中选择适当的位然后附加 0 来手动完成的。
例如,将向量移位 8 位
variable tmp : std_logic_vector(15 downto 0)
...
tmp := x"00" & tmp(15 downto 8);
Run Code Online (Sandbox Code Playgroud)
希望这个简单的答案对某人有用