所以我一直在研究这个任务,它要求我设计一个由几位控制的4位ALU(即S1,S0,Cin / C0(进位)和M)取决于值M ALU将执行逻辑或算术运算。我暂时设计了一个ALU,它使用名为'Sel'的输入,同时我弄清楚如何取3个diff输入(S0,S1,Cin / C0)的值。我无法弄清楚如何连接3位。在执行逻辑操作时,我还使用' - '作为不关心位。此外,由于我没有使用3个控制选择,Mode(m)感觉多余。因此忽略代码的某些部分,因为它们没用。
我在最后附上了一张图片,说明了预期的内容。
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_unsigned.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity codeALU is
Port ( A : in STD_LOGIC_VECTOR (3 downto 0);
B : in STD_LOGIC_VECTOR (3 downto 0);
Cin : in STD_LOGIC;
--S0 : in STD_LOGIC;
--S1 : in STD_LOGIC;
Sel : in STD_LOGIC_VECTOR (2 downto 0);
M : in STD_LOGIC;
Cout : out STD_LOGIC;
Z : out STD_LOGIC;
F : out STD_LOGIC_VECTOR (3 downto 0));
end codeALU;
architecture Behavioral of codeALU is
begin
process(A, B, M, Cin, Sel)
--variable X : STD_LOGIC_VECTOR (1 downto 0);
--variable Y : STD_LOGIC_VECTOR (2 downto 0);
variable temp : STD_LOGIC_VECTOR (4 downto 0);
variable Fx : STD_LOGIC_VECTOR (3 downto 0);
variable Cx, Zx : STD_LOGIC;
begin
--X := S1 & S0;
--Y := S1 & S0 & Cin;
Cx := '0';
Zx := '0';
if M = '0' then
Z <= '0';
case Sel is
when "00-" =>
Fx := A AND B;
Zx := '0';
when "01-" =>
Fx := A XOR B;
when "10-" =>
Fx := A OR B;
when "11-" =>
Fx := A XNOR B;
when others =>
null;
end case;
elsif M = '1' then
case Sel is
when "000" =>
temp := (B(3)&B(3 downto 1) + ('0'&A));
Fx := temp(3 downto 0);
Cx := temp(4);
when "001" =>
temp := (A(3)&A(3 downto 1) + ('0'&B));
Fx := temp(3 downto 0);
Cx := temp(4);
when "010" =>
temp := ('0'&A) + ('0'&B);
Fx := temp(3 downto 0);
Cx := temp(4);
when "011" =>
temp := ('0'&A) + ('0'&B) + ('0'&Cin);
Fx := temp(3 downto 0);
Cx := temp(4);
when "100" =>
temp := ('0'&A) + (not B);
Fx := temp(3 downto 0);
Cx := temp(4);
when "101" =>
temp := (not B) + ('0'&A) + 1;
Fx := temp(3 downto 0);
Cx := temp(4);
when "110" =>
temp := ('0'&A) + ('0'&B(3 downto 1));
Fx := temp(3 downto 0);
Cx := temp(4);
when "111" =>
temp := ('0'&B) + ('0'&A(3 downto 1));
Fx := temp(3 downto 0);
Cx := temp(4);
when others =>
null;
end case;
for i in 0 to 3 loop
Zx := Zx or Fx(i);
end loop;
Z <= not Zx;
else null;
end if;
F <= Fx;
Cout <= Cx;
end process;
end Behavioral;
![LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--USE ieee.numeric_std.ALL;
ENTITY test2ALU IS
END test2ALU;
ARCHITECTURE behavior OF test2ALU IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT codeALU
PORT(
A : IN std_logic_vector(3 downto 0);
B : IN std_logic_vector(3 downto 0);
Cin : IN std_logic;
Sel : IN std_logic_vector(2 downto 0);
M : IN std_logic;
Cout : OUT std_logic;
Z : OUT std_logic;
F : OUT std_logic_vector(3 downto 0)
);
END COMPONENT;
--Inputs
signal A : std_logic_vector(3 downto 0) := (others => '0');
signal B : std_logic_vector(3 downto 0) := (others => '0');
signal Cin : std_logic := '0';
signal Sel : std_logic_vector(2 downto 0) := (others => '0');
signal M : std_logic := '0';
--Outputs
signal Cout : std_logic;
signal Z : std_logic;
signal F : std_logic_vector(3 downto 0);
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: codeALU PORT MAP (
A => A,
B => B,
Cin => Cin,
Sel => Sel,
M => M,
Cout => Cout,
Z => Z,
F => F
);
-- Stimulus process
stim_proc: process
begin
-- hold reset state for 100 ns.
wait for 100 ns;
A <= "1001";
B <= "1111";
M <= '0';
wait for 50 ns;
Sel <= "00-";
wait for 50 ns;
Sel <= "01-";
wait for 50 ns;
Sel <= "10-";
wait for 50 ns;
Sel <= "11-";
wait for 50 ns;
M <= '1';
Sel <= "000";
wait for 50 ns;
Sel <= "001";
wait for 50 ns;
Sel <= "010";
wait for 50 ns;
Sel <= "011";
wait for 50 ns;
Sel <= "100";
wait for 50 ns;
Sel <= "101";
wait for 50 ns;
Sel <= "110";
wait for 50 ns;
Sel <= "111";
-- insert stimulus here
wait;
end process;
END;][1]
答案 0 :(得分:1)
您尝试使用X
和Y
(以及您注释掉的)是一种非常合理的方式来连接您的选择。问题是不关心。普通的case
声明不会像你期望的那样处理不关心的事情(即它不会像对待它们那样匹配它们 - 它将它们作为一种独特的方式处理它们std_logic
值与其他所有值相同)。如果您有支持VHDL-2008的工具,则可以使用case?
, 按照您想要的方式匹配不在乎的值。您甚至可以将M
连接到您的选择中并稍微缩短您的代码。像:
process (all)
variable sel : std_logic_vector(3 downto 0);
begin
sel := M & S1 & S0 & Cin;
case? sel is
when "000-" =>
Fx := A and B;
when "001-" =>
Fx := A or B;
...
when "1000" =>
...
(请注意,我在这里使用sel
作为内部变量而不是端口。)
如果无法使用VHDL-2008,则必须适当地嵌套if / case语句。提示:您可以在案例陈述中使用sel
切片,因此如果Cin始终是M = '0'
的关注点,您可以执行以下操作:
process (M, S0, S1, Cin, A, B)
variable sel : std_logic_vector(2 downto 0);
begin
sel := S1 & S0 & Cin;
if M = '0' then
case sel(2 downto 1) is -- Cin is don't-care
when "00" =>
Fx := A and B;
when "01" =>
Fx := A or B;
...
else
case sel is -- all control bits are significant
when "000" =>
...
正如Paebbels指出的那样,为您提供更好的解决方案或许只是明确地给出了多个选择,尽管这对于拥有更多控制位的设计来说可能会变得乏味。