vhdl - ALU 32 位,溢出,零标志
问题描述
该 ALU 可以根据提供给 ALU 的操作码对两个数据输入执行加法、减法、AND 或 OR。名为 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;
我添加了零标志,但 modelsim 无法读取输出,也尝试了溢出,但它说标识符问题。当我为零标志编写 if 语句时,它期望 == or+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;
推荐阅读
- rust - 如何为字段编写具有生命周期约束的函数?
- r - packrat::resolve() 一直要求我在 Rtools 已经安装时安装它
- admob - 在禁用 c++ 模块时使用“@import”,考虑使用 -fmodules 和 -fcxx-modules
- python - Edge 的关键属性含义 OSMNX
- javascript - JavaScript DOM 音频未播放
- c# - 如何确保在 CefSharp 中执行 ExecuteScriptAsync
- vue.js - 商店用品 6 | 自定义字段为空
- java - Java 解密创建附加符号
- php - PHP函数从段落中删除第一句话
- javascript - Vue 和 Firebase RTDB 连接