右移和左移 (SLL/SRL)

发布于 2024-11-16 10:07:09 字数 649 浏览 4 评论 0原文

因此,我正在为 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;

so, I'm developing an ALU for MIPS architecture and I'm trying to make a shift left and a shift right so that the ALU can shift any amount of bits.

the Idea I had is to convert the shift value to an integer and select the piece of the entry that'll be on the result(the integer is stored in X) but Quartus doesn't accept a variable value, only constants.

What could I do to make this?
(Cases are on lines "WHEN "1000" =>..." and "WHEN "1001" =>...")

Thanks.

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;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

猥︴琐丶欲为 2024-11-23 10:07:09

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

  1. 以 Quartus 喜欢的方式编写它 - 您试图推断一个桶形移位器,因此您可以手写一个,然后实例化它。时间上可能会很昂贵
  2. 获取一个可以接受它的不同合成器。金钱上可能很贵。

If Quartus doesn't like it you have two choices:

  1. Write it some way that Quartus does like - you're trying to infer a barrel shifter, so you could write one out longhand and then instantiate that. Potentially expensive in time
  2. Get a different synthesizer that will accept it. Potentially expensive in money.
浮云落日 2024-11-23 10:07:09

我在 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;

I have had issues with this in Quartus as well, although your code also has some implicit latches (you are not assigning all bits of the output in your two shift cases).

The work-around I use is to define an intermediate array with all the possible results, then select one of those results using your selector. In your case, something like the following:

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;
以为你会在 2024-11-23 10:07:09

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

You could work around this by using generate or for to create each shift/rotate level, or you can use the standard functions ({shift,rotate}_{left,right}) for shifting and rotating.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文