VHDL中的通用移位算法
我正在设计通用移位算术运算符。 除了以下面介绍的方式使用32位多路复用器(解码器)之外,还有更好的方法来实现它吗VHDL中的通用移位算法,vhdl,fpga,circuit,hdl,Vhdl,Fpga,Circuit,Hdl,我正在设计通用移位算术运算符。 除了以下面介绍的方式使用32位多路复用器(解码器)之外,还有更好的方法来实现它吗 ENTITY isra IS PORT ( clk: in std_logic; rst: in std_logic; di: in std_logic_vector (31 downto 0); sel: in std_logic_vector (31 downto 0); res: out std_logic_vector
ENTITY isra IS
PORT (
clk: in std_logic;
rst: in std_logic;
di: in std_logic_vector (31 downto 0);
sel: in std_logic_vector (31 downto 0);
res: out std_logic_vector (31 downto 0) := (others => '0')
);
END isra;
PROCESS
BEGIN
WAIT UNTIL clk'EVENT AND clk = '1';
IF rst = '1' THEN
res <= (others => '0');
ELSE
CASE sel IS
when X"00000001" => res <= to_stdlogicvector(to_bitvector(a) sra 1);
when X"00000002" => res <= to_stdlogicvector(to_bitvector(a) sra 2);
...
when X"0000001F" => res <= to_stdlogicvector(to_bitvector(a) sra 31);
when others => res <= (others => '0');
END CASE;
END IF;
END PROCESS;
实体isra是
港口(
clk:标准逻辑中;
rst:标准逻辑中;
di:标准逻辑向量(31到0);
sel:标准逻辑向量(31向下至0);
res:out标准逻辑向量(31向下至0):=(其他=>“0”)
);
结束isra;
过程
开始
等待clk'事件和clk='1';
如果rst='1',则
res'0');
其他的
CASE sel是
当X“00000001”=>res'0');
终例;
如果结束;
结束过程;
从硬件的角度来看,要在一个时钟中右移一个可变的位置数,每个位都是一个触发器,根据选择的32个可能值中的一个。所以从这个角度来看,这就是你如何做到的
不过,我会将sel==0设为一个case,并将其设为passthrough。从逻辑上讲,这比将所有设置为零更有意义。从硬件的角度来看,要在单个时钟中右移可变数量的位置,每一位都是一个触发器,具有基于选择的32个可能值之一。所以从这个角度来看,这就是你如何做到的 不过,我会将sel==0设为一个case,并将其设为passthrough。从逻辑上讲,这比将所有内容设置为零更有意义。使用索引
PROCESS
VARIABLE shift_count : INTEGER RANGE 0 TO 31;
BEGIN
IF rst = '1' THEN
res <= (others => '0');
ELSIF RISING_EDGE(clk) THEN
shift_count := to_integer(sel);
FOR I IN 0 TO 31 LOOP
IF I + shift_count < 32 THEN
res(I) <= din(I + shift_count);
ELSE
res(I) <= din(31); -- for logical shift right, use '0' instead
END IF;
END LOOP;
END IF;
END PROCESS;
过程
可变移位计数:整数范围0到31;
开始
如果rst='1',则
res'0');
ELSIF上升沿(clk)则
移位计数:=到整数(sel);
对于0到31循环中的I
如果I+shift\u计数<32,则
res(I)是否使用索引
PROCESS
VARIABLE shift_count : INTEGER RANGE 0 TO 31;
BEGIN
IF rst = '1' THEN
res <= (others => '0');
ELSIF RISING_EDGE(clk) THEN
shift_count := to_integer(sel);
FOR I IN 0 TO 31 LOOP
IF I + shift_count < 32 THEN
res(I) <= din(I + shift_count);
ELSE
res(I) <= din(31); -- for logical shift right, use '0' instead
END IF;
END LOOP;
END IF;
END PROCESS;
过程
可变移位计数:整数范围0到31;
开始
如果rst='1',则
res'0');
ELSIF上升沿(clk)则
移位计数:=到整数(sel);
对于0到31循环中的I
如果I+shift\u计数<32,则
res(I)您可以在不使用任何循环或case语句的情况下使用SRA函数:
res <= to_stdlogicvector(to_bitvector(di) sra to_integer(sel));
如果您不想这样做,您仍然可以将sel强制转换为未签名的。您还需要向我们提供数字位:
use ieee.numeric_bit.all;
您可以在不使用任何循环或case语句的情况下使用SRA函数:
res <= to_stdlogicvector(to_bitvector(di) sra to_integer(sel));
如果您不想这样做,您仍然可以将sel强制转换为未签名的。您还需要向我们提供数字位:
use ieee.numeric_bit.all;
解复用器?这里没有异议。你说得对,我已经改变了描述。thx用于指出这一点。解复用器?这里没有异议。你说得对,我已经改变了描述。thx代表指出这一点。thx代表答案。我同意,这是一种更为通用的方法,使其更好。问题是,在我的例子中,sel必须是32位宽的,我相信“shift_count:=to_integer(sel)”在这种情况下不起作用。正如你所说的,这个设计的棘手部分是使用聪明的解码器——32:1是不明智的。您认为坚持您的设计并使用sel(5到0)是一个好主意吗?另一件事是,是否有一个异步rst对性能有好处?Thx。这是为FPGA设计的,对吗?FPGA的逻辑元件对每个D触发器都有专用的异步复位输入,因此无论在性能还是LE使用方面都不会花费任何成本(它可能报告使用了更多的门,但这些门不能用于任何其他功能)。拥有一个更宽的sel
总线不会造成任何伤害,因为I+shift\u count<32
测试将自动正确处理shift\u count
的任何值。“如果I+shift\u count<32,那么”这很聪明!谢谢你的回答。我同意,这是一种更为通用的方法,使其更好。问题是,在我的例子中,sel必须是32位宽的,我相信“shift_count:=to_integer(sel)”在这种情况下不起作用。正如你所说的,这个设计的棘手部分是使用聪明的解码器——32:1是不明智的。您认为坚持您的设计并使用sel(5到0)是一个好主意吗?另一件事是,是否有一个异步rst对性能有好处?Thx。这是为FPGA设计的,对吗?FPGA的逻辑元件对每个D触发器都有专用的异步复位输入,因此无论在性能还是LE使用方面都不会花费任何成本(它可能报告使用了更多的门,但这些门不能用于任何其他功能)。拥有一个更宽的sel
总线不会造成任何伤害,因为I+shift\u count<32
测试将自动正确处理shift\u count
的任何值。“如果I+shift\u count<32,那么”这很聪明!您好,谢谢您指出。case语句中的其他语句规定res信号写入每个分支。这有助于合成工具,以防止创建闩锁。嗨,thx指出它。case语句中的其他语句规定res信号写入每个分支。这有助于合成工具防止创建闩锁。