0

したがって、私はこの割り当てに取り組んでおり、いくつかのビット (つまり、S1、S0、Cin/C0 (キャリーイン)、および M) によって制御される 4 ビット ALU を設計する必要があります。M の値に応じて、ALU論理演算または算術演算を実行します。3 つの差分入力 (S0、S1、Cin/C0) の値を取得する方法を見つけながら、'Sel' という名前の入力で動作する ALU を一時的に設計しました。3ビットを連結する方法がわかりません。また、論理演算の実行中にドント ケア ビットに「-」を使用しました。また、3 つのコントロール セレクトを使用していないため、モード (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]

ここに画像の説明を入力

譲渡書

4

1 に答える 1

1

XandでやろうとしたことY(およびコメントアウトしたこと) は、select を連結する完全に合理的な方法です。問題はドントケアです。通常のcaseステートメントは、あなたが期待している方法でドントケアを処理しません (つまり、それらが何でもあり得るかのようにそれらに対して一致しません - それはstd_logic他のすべてと同じようにそれらを一意の値として処理します)。VHDL-2008 をサポートするツールがある場合はcase?、 を使用できます。これ、任意の方法でドントケア値と一致します。select に連結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 ステートメントを適切にネストする必要があります。ヒント: case ステートメントでスライス of を使用できるselため、Cin が常に don't-care forM = '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 が指摘したように、おそらくより良い解決策は、ドントケアがある場合に複数の選択肢を明示的に与えることですが、より多くの制御ビットを持つ設計では面倒になるかもしれません.

于 2015-01-28T14:53:53.247 に答える