我有一个向量signal tmp : std_logic_vector(15 downto 0)
我必须将它移到n位左侧或右侧。我怎么才能实现这个操作。我想连接操作,但我不知道如何使用它。
答案 0 :(得分:24)
使用ieee.numeric_std
库以及您正在处理的数字(unsigned
或signed
)的相应矢量类型。
然后运算符为 sla
/ sra
用于算术移位(即在右移位上填充符号位,在左移位上填充lsb)和sll
/ srl
用于逻辑移位(即填写'0'。
将参数传递给运算符以定义要移位的位数:
A <= B srl 2; -- logical shift right 2 bits
我不知道我上面写的是什么(感谢Val指出这一点!)
当然,转换signed
和unsigned
类型的正确方法是使用shift_left
中定义的shift_right
和ieee.numeric_std
函数。
移位和旋转运算符sll
,ror
等are for vectors of boolean
, bit
or std_ulogic
,并且可以interestingly unexpected behaviour,因为即使向左移位,算术移位也会复制结束位。 / p>
此处可以找到更多历史记录:
http://jdebp.eu./FGA/bit-shifts-in-vhdl.html
然而,原始问题的答案仍然是
sig <= tmp sll number_of_bits;
答案 1 :(得分:16)
有两种方法可以实现这一目标。连接和移位/旋转功能。
连接是&#34;手册&#34;做事的方式。你可以指定你想要的原始信号的哪个部分&#34;保持&#34;然后将数据连接到一端或另一端。例如: tmp&lt; = tmp(14 downto 0)&amp; &#39; 0&#39 ;;
移位函数(逻辑,算术):这些是通用函数,允许您以多种方式移动或旋转向量。函数是:sll(向左移位逻辑),srl(向右移位逻辑)。逻辑移位插入零。算术位移(sra / sla)插入最左边或最右边的位,但工作方式与逻辑移位相同。 请注意,对于所有这些操作,您可以指定要移位的内容(tmp),以及要执行移位的次数( n 位)
旋转功能:rol(向左旋转),ror(向右旋转)。旋转就是这样,MSB最终进入LSB,一切都向左移动(rol)或反过来为ror。
这是我找到的handy reference(见第一页)。
答案 2 :(得分:6)
就个人而言,我认为连接是更好的解决方案。通用实现将是
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;
两者都将实现为移位寄存器。如果您发现自己需要更多的移位寄存器而不是您愿意花费资源(EG将1000个数字除以4),您可以考虑使用BRAM来存储值,并使用单个移位寄存器来包含导致所有数字的正确移位。
答案 3 :(得分:4)
我不建议将sll
或srl
与std_logic_vector一起使用。
在模拟期间sll
给了我&#39; U&#39;这些位的值,我预期的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))));
答案 4 :(得分:2)
这通常通过从向量中选择适当的位然后追加0来手动完成。
例如,将矢量移位8位
variable tmp : std_logic_vector(15 downto 0)
...
tmp := x"00" & tmp(15 downto 8);
希望这个简单的答案对某人有用
答案 5 :(得分:0)
add_Pbl <= to_stdlogicvector(to_bitvector(dato_cu(25 downto 2)) sll 1);
add_Pbl is a std_logic_vector of 24 bit
dato_cu is a std_logic_vector of 32 bit
首先,您需要使用std_logic_vector
函数转换to_bitvector()
因为sll语句使用逻辑1和0位。