右移和左移(SLL / SRL)

时间:2011-06-22 13:06:54

标签: vhdl fpga intel-fpga

所以,我正在开发一个用于MIPS架构的ALU,我正在尝试向左移位和向右移位,以便ALU可以移位任意数量的位。

我的想法是将移位值转换为整数并选择将在结果上的条目(整数存储在X中),但Quartus不接受变量值,只有常量

我该怎么做才能做到这一点? (案例在“WHEN”1000“=> ......”和“WHEN”1001“=> ......”)

感谢。

PROCESS ( ALU_ctl, Ainput, Binput, X )
BEGIN
                -- Select ALU operation
    --ALU_output_mux <= X"00000000"; --padrao   
CASE ALU_ctl IS
    WHEN "1000" =>  ALU_output_mux(31 DOWNTO X) <= (Ainput( 31-X DOWNTO 0 ));
    WHEN "1001" =>  ALU_output_mux(31-X DOWNTO 0) <= (Ainput( 31 DOWNTO X ));
    WHEN OTHERS =>  ALU_output_mux  <= X"00000000";
END CASE;
END PROCESS;

3 个答案:

答案 0 :(得分:3)

如果Quartus不喜欢它,你有两个选择:

  1. 写一些Quartus喜欢的方式 - 你试图推断一个桶形移位器,所以你可以用一个写出来然后实例化它。时间上可能很昂贵
  2. 获取一个可以接受它的其他合成器。金钱可能很贵。

答案 1 :(得分:0)

我在Quartus中遇到过这个问题,虽然你的代码也有一些隐式锁存器(你没有在两个移位情况下分配输出的所有位)。

我使用的解决方法是定义一个包含所有可能结果的中间数组,然后使用您的选择器选择其中一个结果。在您的情况下,类似于以下内容:

subtype DWORD_T         is std_logic_vector( 31 downto 0);
type    DWORD_A         is array (natural range <>) of DWORD_T;
signal  shift_L         : DWORD_A(31 downto 0);
signal  shift_R         : DWORD_A(31 downto 0);
signal  zero            : DWORD_T;

...

zero <= (others=>'0');

process (Ainput)
begin    
    for index in Ainput'range loop
        shift_L(index) <= Ainput(31 - index downto 0) & zero(index - 1 downto 0);
        shift_R(index) <= zero(index - 1 downto 0) & Ainput(31 downto index);
    end loop;
end process;

ALR_output_mux <= shift_L(to_integer(X)) when ALU_ctl="1000", 
                  shift_R(to_integer(X)) when ALU_ctl="1001",
                  (others=>'0') when others;

答案 2 :(得分:0)

您可以使用generatefor创建每个班次/轮播级别来解决此问题,或者您可以使用standard functions({shift,rotate} _ {left,right })用于移动和旋转。