I am designing universal shift arithmetic operator. Is there a better way to achieve it besides using the 32bit multiplexer (decoder) in a way presented bellow?
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;
You can use the SRA function without any loops or case statements:
res <= to_stdlogicvector(to_bitvector(di) sra to_integer(sel));
Note that you need to make sel an unsigned, not a std_logic_vector:
sel: in unsigned (31 downto 0);
In case you don't want that, you can still cast sel into an unsigned. You also need to us numeric_bit:
use ieee.numeric_bit.all;
Use indexing?
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;
This version is much easier to parameterize into a generic.
Remember that VHDl is a behavioral description, it doesn't specify a mux. The compiler can generate different designs depending on whether you optimize for size, speed, allow pipelining, etc.
Note that 5 2:1 muxes can implement this in a far smaller area than a single 32:1 mux. If this isn't the block that limits your clock rate, that might be preferable.
Also note that your sel
input is far too wide, it only needs to be 5 bits.
Well from a hardware point of view, to shift right in a single clock a variable number of positions, each bit is a single flip-flop with one of 32 possible values based on a selection. So from that point of view, this is how you do it.
I would make sel == 0 a case and make it a passthrough, though. Logically, that makes more sense than setting everything to zeros.
精彩评论