简体   繁体   English

ALU 32 位,溢出,零标志

[英]ALU 32 BIT, Overflow, Zero Flag

This ALU can perform addition, subtraction, AND, OR on the two data inputs according to an operation code supplied to the ALU.该 ALU 可以根据提供给 ALU 的操作代码对两个数据输入执行加法、减法、AND、OR。 The two-bit control input named Operation partially specifies the operation code.名为 Operation 的两位控制输入部分指定了操作代码。 I have been trying to work it but always get errors, still want to add proper zero flag and overflow but each time try something online I restart from scratch.我一直在尝试工作,但总是出错,仍然想添加适当的零标志和溢出,但每次在线尝试一些东西时,我都会从头开始。

Simple_ALU.VHDL 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;

and TB和结核病

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;

I have added zero flag but modelsim cant read output, also tried the overflow but it says identifier issues.我添加了零标志但modelsim无法读取输出,也尝试了溢出但它说标识符问题。 and when I wrte the if statement for zero flag it expects == or+or-or* etc当我为零标志编写 if 语句时,它期望 == or+or-or* 等

While this isn't necessarily an answer.虽然这不一定是答案。 There seems to be quite a few things wrong with your code.您的代码似乎有很多问题。 I made some fixes and recopied below.我做了一些修复并在下面重新复制。 Did not check your logic.没有检查你的逻辑。 Only your syntax.只有你的语法。 Run the TB now and see if this helps.现在运行 TB,看看这是否有帮助。 Also it would help in the future if you list the actual errors you received.如果您列出收到的实际错误,将来也会有所帮助。 Also I would suggest tying all your internal signals to a reset for initialization.此外,我建议将您所有的内部信号绑定到重置以进行初始化。

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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM