这是我的问题:我需要从头开始使用组合逻辑设计一个16位左/右逻辑/算术移位组件(除了使用std_logic_vector和std_logic)。
这就是我所拥有的:
library ieee;
use ieee.std_logic_1164.all;
entity Shift16 is
port
(
-- Input ports
I : in std_logic_vector(15 downto 0);
Shift : in std_logic_vector(3 downto 0);
-- Sel(1) == 0 -> Logical ; Sel(0) == Left
Sel : in std_logic_vector(1 downto 0);
-- Output ports
O : out std_logic_vector(15 downto 0)
);
end Shift16;
architecture Struct of Shift16 is
component Mux16to1 is
port (I : in std_logic_vector(15 downto 0);
S : in std_logic_vector(3 downto 0);
O : out std_logic);
end component;
component Mux2to1_16 is
port
( A, B : in std_logic_vector(15 downto 0); S : in std_logic;
Q : out std_logic_vector(15 downto 0) );
end component;
signal OLeft, ORight : std_logic_vector(15 downto 0);
signal PadVal : std_logic;
type gen_signal is array (15 downto 0) of std_logic_vector(15 downto 0);
signal leftPad, rightPad : gen_signal;
begin
process (I, Sel)
begin
if (Sel(0) = '0') then -- logical
PadVal <= '0';
else
PadVal <= I(15); -- aritmetic
end if;
for j in 15 downto 0 loop
for k in j downto 0 loop
leftPad(j, k) <= I(15-j);
rightPad(j, k) <= PadVal;
end loop;
for k in 15 downto j+1 loop
leftPad(j, k) <= PadVal;
rightPad(j, k) <= I(15-j);
end loop;
end loop;
end process;
muxarr_left_shift: for index in 15 downto 0 generate
begin
mux: Mux16to1 port map (leftPad(index), Shift, OLeft(index));
end generate;
muxarr_right_shift: for index in 15 downto 0 generate
begin
mux: Mux16to1 port map (rightPad(index), Shift, ORight(index));
end generate;
OutputMux: Mux2to1_16 port map (ORight, OLeft, Sel(1), O);
end Struct;
Mux
组件正是它们的样子,只是我的自定义版本。
我最初的想法是使用16个16对1多路复用器并将它们连接起来,因此移位量是每个的选择。这将非常快,但由于某种原因,代码无法编译。
我想我也过于复杂,我不知道我能做些什么来做得更好......
编译错误是:Error (10382): VHDL error at Shl16.vhd(52): index of object of array type gen_signal must have 1 dimensions
答案 0 :(得分:1)
我认为你应该改变:
for j in 15 downto 0 loop
for k in j downto 0 loop
leftPad(j, k) <= I(15-j);
rightPad(j, k) <= PadVal;
end loop;
for k in 15 downto j+1 loop
leftPad(j, k) <= PadVal;
rightPad(j, k) <= I(15-j);
end loop;
end loop;
到
for j in 15 downto 0 loop
for k in j downto 0 loop
leftPad(j)(k) <= I(15-j);
rightPad(j)(k) <= PadVal;
end loop;
for k in 15 downto j+1 loop
leftPad(j)(k) <= PadVal;
rightPad(j)(k) <= I(15-j);
end loop;
end loop;
因为你的类型声明。
type gen_signal is array (15 downto 0) of std_logic_vector(15 downto 0);
P / s:如果您想保持循环,请将类型更改为:
type gen_signal is array (15 downto 0, 15 downto 0) of std_logic;
但我认为它不适合您的portmap。所以,你应该使用上面的方法。我用Questasim 10.0b检查了第一个方法。
P / S(再次):我仔细阅读了您的代码并找到了:process (I, Sel)
敏感列表可能不适合循环,除非您想要latch
。我认为你应该分成两个过程。
答案 1 :(得分:0)
如下:
process (all) is
variable shift_bits : integer;
begin
shift_bits := to_integer(unsigned(shift));
O <= (others => '0'); -- fill with padding first - stop latch
if sel(0) = '1' then -- left shift
O(O'high downto - O'high-shift_bits) <=
I(shift_bits-1 downto 0);
else -- right shift
if sel(1) = '1' then -- if arithmetic
O <= (others => I(I'high)); -- pad with sign bit
end if;
O(shift_bits-1 downto 0) <=
I(I'high downto i'high-shift_bits);
end if;
end process;
合成67 LUT6s
另一条评论 - 为什么没有明确定义控制位,所以你不必用评论来描述发生了什么:
entity Shift16 is
port
(
I : in std_logic_vector(15 downto 0);
Shift_count : in unsigned(3 downto 0);
shift_logical : in std_logic;
shift_right : in std_logic;
O : out std_logic_vector(15 downto 0)
);
end Shift16;