2010-11-13 44 views
0

我正在设计通用移位算术运算符。 除了以下述方式使用32位多路复用器(解码器)之外,还有更好的方法来实现吗?VHDL中的通用移位算术权利

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; 
+1

demultiplexer?这里没有demux。 – 2010-11-13 21:24:28

+0

你是对的,我改变了描述。 thx指出这一点。 – name 2010-11-13 23:33:49

回答

1

使用索引?

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; 

此版本更容易参数化为通用。

请记住,VHDl是一种行为描述,它没有指定多路复用器。编译器可以生成不同的设计,具体取决于您是否优化了大小,速度,允许流水线等。

请注意,5 2:1多路复用器可以在比单个32:1多路复用器小得多的区域内实现。如果这不是限制你的时钟频率的块,那可能是更可取的。

另请注意,您的sel输入太宽,只需要5位。

+0

Thx为答案。我同意这是更通用的方法,使它更好。问题是,在我的情况下sel必须是32位宽,我认为“shift_count:= to_integer(sel)”在这种情况下不起作用。正如你所说,这个设计中棘手的部分是使用聪明的解码器 - 做32:1并不明智。你认为坚持你的设计和使用sel(5 downto 0)是一个好主意吗?另一件事是,如果出于性能方面的考虑,首先有异步是有好处的?谢谢。 – name 2010-11-13 23:23:10

+1

这是一个FPGA,对吧? FPGA的逻辑单元对每个D触发器都有专门的异步复位输入,因此无论是性能还是LE使用(它可能报告使用更多*门*)都不会造成任何损失,但这些门不能用于任何其他功能)。拥有更广泛的'sel'总线不应该伤害任何东西,因为'I + shift_count <32'测试会自动正确处理'shift_count'的任何值。 – 2010-11-14 06:20:47

+0

“如果我+ shift_count <32那么”这很聪明! – name 2010-11-15 12:34:11

1
从硬件的角度来看

好了,在一个单一的时钟右移可变数量的位置,每个位是单触发器与基于选择32个可能值之一。所以从这个角度来看,这是你如何做到的。

虽然,我会让sel == 0一个案例,并使其成为直通。从逻辑上讲,这比将所有内容设置为零更有意义。

+0

嗨,thx指出它。 case语句中的其他语句规定res信号写入每个分支。这有助于综合工具来防止创建锁存器。 – name 2010-11-13 23:25:58

4

可以使用SRA功能没有任何循环或case语句:你需要做SEL无符号,而不是std_logic_vector

res <= to_stdlogicvector(to_bitvector(di) sra to_integer(sel)); 

注:

sel: in unsigned (31 downto 0); 

在你所不懂的情况下,不要这样,你仍然可以将sel转换为无符号。您还需要我们numeric_bit:

use ieee.numeric_bit.all;