ALU 32位,溢出,零标志

问题描述

此ALU可以对运算符进行加,减,与或运算 根据提供给ALU的操作代码,两个数据输入。两位控制 名为Operation的输入部分指定了操作代码。 我一直在尝试工作,但总是会出错,仍然想添加适当的零标志和溢出,但是每次尝试在线操作时,我都会从头开始重启。

Simple_ALU.VHDL

   library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity simple_alu is
port( Clk : in std_logic; --clock signal
 A,B : in signed(31 downto 0); --input operands
 Op : in unsigned(2 downto 0); --Operation to be performed
 R : out signed(31 downto 0); --output of ALU
 z: out STD_LOGIC; --Zero flag
 Cry : out  STD_LOGIC
 );
end simple_alu;
architecture Behavioral of simple_alu is
--temporary signal declaration.
signal Reg1,Reg2,Reg3 : signed(31 downto 0) := (others => '0');
begin
Reg1 <= A;
Reg2 <= B;
R <= Reg3;
z<=z;
--Cout <= Cry;
process(Clk)
 variable temp : std_logic_vector (31 downto 0);
begin
 if(rising_edge(Clk)) then --Do the calculation at the positive edge
--of clock cycle.
 case Op is
 when "000" =>
 Reg3 <= Reg1 + Reg2; --addition
 when "001" =>
 Reg3 <= Reg1 - Reg2; --subtraction
  case OP is
          -when "010" =>
               temp := std_logic_vector((unsigned("0" & Reg1) + unsigned(Reg2)));
            Reg3 <= temp(31 downto 0);
              Cry <= temp(32);
 when "011" =>
 Reg3 <= Reg1 nand Reg2; --NAND gate
 when "100" =>
 Reg3 <= Reg1 nor Reg2; --nor gate
 when "101" =>
 Reg3 <= Reg1 and Reg2; --AND gate
 when "110" =>
 Reg3 <= Reg1 or Reg2; --OR gate
 when "111" =>
 Reg3 <= Reg1 xor Reg2; --XOR gate
 when others =>
 NULL;
 end case;
 end if;
if (Reg3="0000000000000000000000000000000")then 
z='01'
else
z='00'
end process;
end Behavioral;

和结核病

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;
ENTITY tb IS
END tb;
ARCHITECTURE behavior OF tb IS
 signal Clk : std_logic := '0';
 signal A,B,R : signed(31 downto 0) := (others => '0');
 signal Op : unsigned(2 downto 0) := (others => '0');
 constant Clk_period : time := 10 ns;
BEGIN
 -- Instantiate the Unit Under Test (UUT)
 uut: entity work.simple_alu PORT MAP (
 Clk => Clk,A => A,B => B,Op => Op,R => R
 );
 -- Clock process deFinitions
 Clk_process :process
 begin
 Clk <= '0';
 wait for Clk_period/2;
 Clk <= '1';
 wait for Clk_period/2;
 end process;

 -- Stimulus process
 stim_proc: process
 begin
 wait for Clk_period*1;
 A <= "00010010000100100001001000010010"; --18 in decimal
 B <= "00001010000100100001001000010010"; --10 in decimal
 Op <= "000"; wait for Clk_period; --add A and B
 Op <= "001"; wait for Clk_period; --subtract B from A.
 Op <= "010"; wait for Clk_period; --Bitwise NOT of A
 Op <= "011"; wait for Clk_period; --Bitwise NAND of A and B
 Op <= "100"; wait for Clk_period; --Bitwise nor of A and B
 Op <= "101"; wait for Clk_period; --Bitwise AND of A and B
 Op <= "110"; wait for Clk_period; --Bitwise OR of A and B
 Op <= "111"; wait for Clk_period; --Bitwise XOR of A and B
 wait;
 end process;
END;

添加了零标志,但是modelsimim无法读取输出,也尝试了溢出,但是它表示标识符问题。 当我将if语句写为零标志时,它期望==或+ or-or *等

解决方法

虽然这不一定是答案。您的代码似乎有很多错误。我做了一些修复,并在下面重新复制。没有检查你的逻辑。只有您的语法。现在运行TB,看看是否有帮助。如果您列出收到的实际错误,这也将对将来有所帮助。另外,我建议您将所有内部信号都绑定到用​​于初始化的重置。

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity simple_alu is
port( 
    Clk : in std_logic; --clock signal
    rst_i : std_logic; -- reset signal
    A,B : in std_logic_vector(31 downto 0); --input operands
    Op : in std_logic_vector(2 downto 0); --Operation to be performed
    R : out std_logic_vector(31 downto 0); --output of ALU
    z: out STD_LOGIC; --Zero flag
    Cry : out  STD_LOGIC
 );
end simple_alu;
architecture Behavioral of simple_alu is

--temporary signal declaration
signal Reg1 : std_logic_vector(31 downto 0) := (others => '0'); --Changed these to SLV to match below. 
signal Reg2 : std_logic_vector(31 downto 0) := (others => '0');
signal Reg3 : std_logic_vector(31 downto 0) := (others => '0');


begin   
    --Do you intend for the internal signal assignments to be asynchronous? This means that a signal value could change while waiting on an operation to be performed. Could give bad results.
    Reg1 <= A;
    Reg2 <= B;
    R <= Reg3;
    --z <=z; commented out. Not sure what you are trying to say here.
    --Cout <= Cry;

process(Clk,rst_i)
    variable temp : std_logic_vector(32 downto 0); --This was marked (31 downto 0),but below you are calling bit 32. Changed the size of this vector to match logic.
begin
    --OP Code Handling
    if(rst_i = '1') then -- Example of reset
        --reset internal signals
        --Reg3 <= (others => '0'); -- an example
    elsif(rising_edge(Clk)) then --Do the calculation at the positive edge of clock cycle.
        case Op is
        when "000" =>
            Reg3 <= std_logic_vector(unsigned(Reg1) + unsigned(Reg2)); --addition. Use subtype conversions for handling adding of SLVs
        when "001" =>
            Reg3 <= std_logic_vector(unsigned(Reg1) - unsigned(Reg2)); --subtraction
        when "010" => -- called case Op twice. removed the second call
            temp := std_logic_vector(("0" & unsigned(Reg1)) + unsigned(Reg2));
            Reg3 <= temp(31 downto 0);
            Cry <= temp(32);
        when "011" =>
            Reg3 <= Reg1 nand Reg2; --NAND gate
        when "100" =>
            Reg3 <= Reg1 nor Reg2; --NOR gate
        when "101" =>
            Reg3 <= Reg1 and Reg2; --AND gate
        when "110" =>
            Reg3 <= Reg1 or Reg2; --OR gate
        when "111" =>
            Reg3 <= Reg1 xor Reg2; --XOR gate
        when others =>  NULL;
        end case;
    end if;

    if (Reg3="00000000000000000000000000000000")then --This wasn't large enough. Added another Zero
        z <='1'; -- Changed these to single bit,you had them as 2 bit values.
    else
        z <='0';
    end if; --forgot to end if
end process;
end Behavioral;