2

所以,我正在为 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;
4

3 回答 3

3

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

  1. 以 Quartus 喜欢的方式编写它——你试图推断一个桶形移位器,所以你可以手写一个然后实例化它。时间上可能很昂贵
  2. 获得一个可以接受它的不同合成器。钱可能很贵。
于 2011-06-22T14:42:32.157 回答
0

generate您可以通过使用或for创建每个移位/旋转级别来解决此问题,或者您可以使用标准函数({shift,rotate}_{left,right}) 进行移位和旋转。

于 2011-07-12T14:30:26.630 回答
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;
于 2011-06-22T14:40:28.053 回答