【发布时间】:2012-02-19 13:04:12
【问题描述】:
我有一个向量signal tmp : std_logic_vector(15 downto 0)
我必须将它移到 n 位的左侧或右侧。我怎样才能实现这个操作。想串联操作,不知道怎么用。
【问题讨论】:
标签: vhdl
我有一个向量signal tmp : std_logic_vector(15 downto 0)
我必须将它移到 n 位的左侧或右侧。我怎样才能实现这个操作。想串联操作,不知道怎么用。
【问题讨论】:
标签: vhdl
我不建议将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))));
【讨论】:
使用ieee.numeric_std 库和适合您正在处理的数字的向量类型(unsigned 或signed)。
然后运算符是sla/sra 用于算术移位(即在右移时填充符号位,在左移时填充 lsb)和sll/srl 用于逻辑移位(即用'0'填充)。 s>
您将参数传递给运算符以定义要移位的位数:
A <= B srl 2; -- logical shift right 2 bits
我不知道我在上面写了什么(感谢 Val 指出这一点!)
当然,转移signed 和unsigned 类型的正确方法是使用ieee.numeric_std 中定义的shift_left 和shift_right 函数。
移位和循环运算符sll、ror 等are for vectors of boolean, bit or std_ulogic 和interestingly unexpected behaviour 是因为即使向左移位,算术移位也会复制结束位。
更多历史可以在这里找到:
http://jdebp.eu./FGA/bit-shifts-in-vhdl.html
但是,原来问题的答案仍然是
sig <= tmp sll number_of_bits;
【讨论】:
这通常是通过从向量中选择适当的位然后附加 0 来手动完成的。
例如,将向量移动 8 位
variable tmp : std_logic_vector(15 downto 0)
...
tmp := x"00" & tmp(15 downto 8);
希望这个简单的答案对某人有用
【讨论】:
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 位。
【讨论】:
就个人而言,我认为串联是更好的解决方案。通用实现将是
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;
两者都将实现为移位寄存器。如果您发现自己需要的移位寄存器数量超过了您愿意花费的资源(例如,将 1000 个数字除以 4),您可能会考虑使用 BRAM 来存储值并使用单个移位寄存器来包含“索引”,从而导致所有数字的正确移位。
【讨论】:
有两种方法可以实现这一目标。连接和移位/旋转函数。
串联是“手动”的做事方式。您指定要“保留”原始信号的哪一部分,然后将数据连接到一端或另一端。例如:tmp
移位函数(逻辑、算术):这些是通用函数,允许您以多种方式移位或旋转向量。函数有:sll(逻辑左移)、srl(逻辑右移)。逻辑移位插入零。算术移位 (sra/sla) 插入最左边或最右边的位,但工作方式与逻辑移位相同。 请注意,对于所有这些操作,您要指定要移位的内容 (tmp),以及要执行移位的次数(n 位)
旋转函数:rol(向左旋转)、ror(向右旋转)。旋转就是这样做的,MSB 最终在 LSB 中,一切都向左移动 (rol) 或相反的 ror。
这是我找到的handy reference(见第一页)。
【讨论】: