未定义的 ALU 结果值 (VHDL)

问题描述 投票:0回答:1

我正在研究这个 VHDL 16 位 MIPS 处理器,并且在执行单元(更具体地说是 ALU 结果)方面遇到了一些问题。我已经为 ALU 单独创建了一个测试台(按预期工作),为执行单元创建了一个测试台(也按预期工作),但是当为连接的整个处理器创建测试台时,我在 ALU 中收到错误,结果未定义(“000X”的形式)。

这是我正在使用的代码:

ALU.vhd
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL; 
use IEEE.STD_LOGIC_UNSIGNED.ALL; 

entity ALU is
    Port (
    ALU_OP: in std_logic_vector(2 downto 0):= (others => '0');
    REG1: in std_logic_vector(15 downto 0):= (others => '0');
    REG2: in std_logic_vector(15 downto 0):= (others => '0');
    RESULT: out std_logic_vector(15 downto 0);
    ZERO: out std_logic := '0'
    );
end ALU;

architecture Behavioral of ALU is

signal result_temp: std_logic_vector(15 downto 0):= (others => '0');

begin

    MUX: process(ALU_OP, REG1, REG2)
    begin
        if(result_temp = x"0000") then
            ZERO <= '1';
        else
            ZERO <= '0';
        end if;
    
        case ALU_OP is
            when "000" =>
                result_temp <= REG1 + REG2;
            when "001" =>
                result_temp <= REG1-REG2;
            when "010" =>
            --AND
                result_temp <= REG1 AND REG2;
            when "011" =>
            --OR
                result_temp <= REG1 OR REG2;
            when "100" =>
            --SHL 1
                result_temp <= REG1(14 downto 0)&"0";
            when "101" =>
            --SHR 1
                result_temp <= "0"&REG1(15 downto 1);
            when "110" =>
                result_temp <= REG1 XOR REG2;
            when others =>
            --NOT
                result_temp <= NOT(REG1);
        end case;
        
    end process MUX;
    RESULT <= result_temp; 
    
end Behavioral;
EXECUTION_UNIT.vhd
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL; 
use IEEE.STD_LOGIC_UNSIGNED.ALL; 

entity EXECUTE_UNIT is
    Port ( PC_PLUS : in STD_LOGIC_VECTOR (15 downto 0):= (others => '0');
           RD1 : in STD_LOGIC_VECTOR (15 downto 0):= (others => '0');
           RD2 : in STD_LOGIC_VECTOR (15 downto 0):= (others => '0');
           EXT_IMMEDIATE : in STD_LOGIC_VECTOR (15 downto 0):= (others => '0');
           FUNC : in STD_LOGIC_VECTOR (2 downto 0):= (others => '0');
           --SHIFT_AMMOUNT : in STD_LOGIC;
           ALUSrc : in STD_LOGIC := '0';
           ALUOp : in STD_LOGIC_VECTOR (2 downto 0):= (others => '0');
           BranchAddress : out STD_LOGIC_VECTOR (15 downto 0):= (others => '0');
           ALU_Result : out STD_LOGIC_VECTOR (15 downto 0);
           ZERO : out STD_LOGIC := '0');
end EXECUTE_UNIT;

architecture Behavioral of EXECUTE_UNIT is

component ALU is
    Port (
    ALU_OP: in std_logic_vector(2 downto 0):= (others => '0');
    REG1: in std_logic_vector(15 downto 0):= (others => '0');
    REG2: in std_logic_vector(15 downto 0):= (others => '0');
    RESULT: out std_logic_vector(15 downto 0);
    ZERO: out std_logic := '0'
    );
end component ALU;
signal ALU_CONTROL: std_logic_vector(2 downto 0):= (others => '0');
signal ALU_MUX: STD_LOGIC_VECTOR(15 downto 0):= (others => '0');
signal EXT_IMM_SH: STD_LOGIC_VECTOR(15 downto 0) := (others => '0');

begin
ALU_init: ALU Port map(
    ALU_OP => ALU_CONTROL,
    REG1=>RD1,
    REG2=>ALU_MUX,
    RESULT => ALU_Result,
    ZERO => ZERO
);

ALUMUX: process(ALUSrc,RD2,EXT_IMMEDIATE)
begin
    case ALUSrc is
        when '0' => ALU_MUX <= RD2;
        when others => ALU_MUX <= EXT_IMMEDIATE;
    end case;
end process;

--BranchAddress <= PC_PLUS + EXT_IMMEDIATE(13 downto 0)&"0";
EXT_IMM_SH <= EXT_IMMEDIATE(13 downto 0)&"00";

BranchAddressProcess: process(PC_PLUS, EXT_IMM_SH)
begin
    BranchAddress <= PC_PLUS + EXT_IMM_SH;
end process;

ALUControl: process(FUNC,ALUOp)
begin
    case ALUOp is
        when "000" =>
            case FUNC is
                when "000" => ALU_CONTROL <= "000";
                when "001" => ALU_CONTROL <= "001";
                when "010" => ALU_CONTROL <= "100";
                when "011" => ALU_CONTROL <= "101";
                when "100" => ALU_CONTROL <= "010";
                when "101" => ALU_CONTROL <= "011";
                when "110" => ALU_CONTROL <= "110";
                when others => ALU_CONTROL <= "111";
            end case;
        when "001" => 
            --ADDI
            ALU_CONTROL <= "000";
        when "010" => 
            --SUBI
            ALU_CONTROL <= "001";
        when "011" => 
            --LW
            ALU_CONTROL <= "000";
        when "100" => 
            --SW
            ALU_CONTROL <= "000";
        when "101" => 
            --BEQ
            ALU_CONTROL <= "001";
        when "110" => 
            --BNE
            ALU_CONTROL <= "001";
        when others => 
            --JMP
            ALU_CONTROL <= "000";
    end case;
end process;

end Behavioral;
TEST_ENVIRONMENT.vhd
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL; 
use IEEE.STD_LOGIC_UNSIGNED.ALL; 

entity TEST_ENVIRONMENT_DESIGN is
    Port(
        CLOCK: in STD_LOGIC;
        REGISTER0_CONTENT: out STD_LOGIC_VECTOR(15 downto 0);
        REGISTER1_CONTENT: out STD_LOGIC_VECTOR(15 downto 0);
        REGISTER2_CONTENT: out STD_LOGIC_VECTOR(15 downto 0);
        REGISTER3_CONTENT: out STD_LOGIC_VECTOR(15 downto 0);
        REGISTER4_CONTENT: out STD_LOGIC_VECTOR(15 downto 0);
        REGISTER5_CONTENT: out STD_LOGIC_VECTOR(15 downto 0);
        REGISTER6_CONTENT: out STD_LOGIC_VECTOR(15 downto 0);
        REGISTER7_CONTENT: out STD_LOGIC_VECTOR(15 downto 0);
        INSTRUCTION_CURRENT: out STD_LOGIC_VECTOR(15 downto 0);
        PROGRAM_COUNTER: out std_logic_vector (15 downto 0)
    );
end TEST_ENVIRONMENT_DESIGN;

architecture Behavioral of TEST_ENVIRONMENT_DESIGN is

component INSTRUCTION_FETCH is
    Port ( CLK : in STD_LOGIC;
           BRANCH_ADDRESS : in STD_LOGIC_VECTOR (15 downto 0):= (others => '0');
           JMP_ADDRESS : in STD_LOGIC_VECTOR (15 downto 0):= (others => '0');
           JMP_CTRL : in STD_LOGIC := '0';
           BRANCH_CTRL : in STD_LOGIC := '0';
           INSTRUCTION : out STD_LOGIC_VECTOR (15 downto 0):= (others => '0');
           NEXT_PC : out STD_LOGIC_VECTOR (15 downto 0):= (others => '0')
           );
end component INSTRUCTION_FETCH;

component INSTRUCTION_DECODE is
    Port ( CLK : in STD_LOGIC;
           INSTRUCTION : in STD_LOGIC_VECTOR (15 downto 0):= (others => '0');
           WRITE_DATA : in STD_LOGIC_VECTOR (15 downto 0):= (others => '0');
           REGISTER_WRITE : in STD_LOGIC := '0';
           REGISTER_DESTINATION : in STD_LOGIC := '0';
           EXT_OP : in STD_LOGIC := '0';
           REG1 : out STD_LOGIC_VECTOR (15 downto 0):= (others => '0');
           REG2 : out STD_LOGIC_VECTOR (15 downto 0):= (others => '0');
           EXT_IMMEDIATE : out STD_LOGIC_VECTOR (15 downto 0):= (others => '0');
           FUNC : out STD_LOGIC_VECTOR (2 downto 0):= (others => '0');
           SHIFT_AMMOUNT : out STD_LOGIC := '0';
           reg0_cont : out STD_LOGIC_VECTOR (15 downto 0) := (others => '0');
           reg1_cont : out STD_LOGIC_VECTOR (15 downto 0) := (others => '0');
           reg2_cont : out STD_LOGIC_VECTOR (15 downto 0) := (others => '0');
           reg3_cont : out STD_LOGIC_VECTOR (15 downto 0) := (others => '0');
           reg4_cont : out STD_LOGIC_VECTOR (15 downto 0) := (others => '0');
           reg5_cont : out STD_LOGIC_VECTOR (15 downto 0) := (others => '0');
           reg6_cont : out STD_LOGIC_VECTOR (15 downto 0) := (others => '0');
           reg7_cont : out STD_LOGIC_VECTOR (15 downto 0) := (others => '0')
    );
end component INSTRUCTION_DECODE;

component EXECUTE_UNIT is
    Port ( PC_PLUS : in STD_LOGIC_VECTOR (15 downto 0):= (others => '0');
           RD1 : in STD_LOGIC_VECTOR (15 downto 0):= (others => '0');
           RD2 : in STD_LOGIC_VECTOR (15 downto 0):= (others => '0');
           EXT_IMMEDIATE : in STD_LOGIC_VECTOR (15 downto 0):= (others => '0');
           FUNC : in STD_LOGIC_VECTOR (2 downto 0):= (others => '0');
           --SHIFT_AMMOUNT : in STD_LOGIC;
           ALUSrc : in STD_LOGIC := '0';
           ALUOp : in STD_LOGIC_VECTOR (2 downto 0):= (others => '0');
           BranchAddress : out STD_LOGIC_VECTOR (15 downto 0):= (others => '0');
           ALU_Result : out STD_LOGIC_VECTOR (15 downto 0);
           ZERO : out STD_LOGIC := '0');
end component EXECUTE_UNIT;

component MEMORY_UNIT is
    Port ( CLK : in STD_LOGIC;
           ALURes : inout STD_LOGIC_VECTOR (15 downto 0);
           RD2 : in STD_LOGIC_VECTOR (15 downto 0):= (others => '0');
           MemWrite : in STD_LOGIC := '0';
           MemData : out STD_LOGIC_VECTOR(15 downto 0):= (others => '0')
           );
end component MEMORY_UNIT;

component MAIN_CONTROL is
    Port ( INSTRUCTION : in STD_LOGIC_VECTOR (2 downto 0);
           RegDst : out STD_LOGIC;
           ExtOp : out STD_LOGIC;
           ALUSrc : out STD_LOGIC;
           Branch : out STD_LOGIC;
           Jump : out STD_LOGIC;
           ALUOp : out STD_LOGIC_VECTOR (2 downto 0);
           MemWrite : out STD_LOGIC;
           MemToReg : out STD_LOGIC;
           RegWrite : out STD_LOGIC);
end component MAIN_CONTROL;

signal INSTRUCTION_sim: std_logic_vector(15 downto 0):= (others => '0');
signal JMP_ADDRESS_sim: std_logic_vector(15 downto 0):= (others => '0');
signal BRANCH_ADDRESS_sim: std_logic_vector(15 downto 0):= (others => '0');
signal NEXT_PC_sim: std_logic_vector(15 downto 0):= (others => '0');
signal DATA_WRITE: STD_LOGIC_VECTOR(15 downto 0):= (others => '0');

signal REGISTER1_DATA: STD_LOGIC_VECTOR(15 downto 0):= (others => '0');
signal REGISTER2_DATA: STD_LOGIC_VECTOR(15 downto 0):= (others => '0');

signal EXT_IMMEDIATE_sim: STD_LOGIC_VECTOR(15 downto 0):= (others => '0');
signal FUNC_sim: STD_LOGIC_VECTOR(2 downto 0):= (others => '0');

signal ALURes_sim: std_logic_vector(15 downto 0);
signal ZERO_sim: std_logic :='0';
signal SHIFT_AMMOUNT_sim: STD_LOGIC;

signal READ_DATA_sim: STD_LOGIC_VECTOR(15 downto 0):= (others => '0');

--CONTROL
signal RegDst_sim: std_logic :='0';
signal ExtOp_sim: std_logic :='0';
signal ALUSrc_sim: std_logic :='0';
signal Branch_sim: std_logic :='0';
signal Jump_sim: std_logic :='0';
signal ALUOp_sim: std_logic_vector(2 downto 0):= (others => '0');
signal MemWrite_sim: std_logic :='0';
signal MemToReg_sim: std_logic :='0';
signal RegWrite_sim: std_logic :='0';
signal PCSrc: std_logic :='0';

begin

PCSrc <= Branch_sim AND ZERO_sim;
INSTRUCTION_CURRENT <= INSTRUCTION_sim;
PROGRAM_COUNTER <= NEXT_PC_sim - 1;

INSTRUCTION_FETCH_init: INSTRUCTION_FETCH Port map(
    CLK => CLOCK,
    BRANCH_ADDRESS => BRANCH_ADDRESS_sim,
    JMP_ADDRESS => JMP_ADDRESS_sim,
    JMP_CTRL => Jump_sim,
    BRANCH_CTRL => PCSrc,
    INSTRUCTION => INSTRUCTION_sim,
    NEXT_PC => NEXT_PC_sim
);

INSTRUCTION_DECODE_init: INSTRUCTION_DECODE Port map(
    CLK => CLOCK,
    INSTRUCTION => INSTRUCTION_sim,
    WRITE_DATA => DATA_WRITE,
    REGISTER_WRITE => RegWrite_sim,
    REGISTER_DESTINATION => RegDst_sim,
    EXT_OP => ExtOp_sim,
    REG1 => REGISTER1_DATA,
    REG2 => REGISTER2_DATA,
    EXT_IMMEDIATE => EXT_IMMEDIATE_sim,
    FUNC => FUNC_sim,
    SHIFT_AMMOUNT => SHIFT_AMMOUNT_sim,
    reg0_cont => REGISTER0_CONTENT,
    reg1_cont => REGISTER1_CONTENT,
    reg2_cont => REGISTER2_CONTENT,
    reg3_cont => REGISTER3_CONTENT,
    reg4_cont => REGISTER4_CONTENT,
    reg5_cont => REGISTER5_CONTENT,
    reg6_cont => REGISTER6_CONTENT,
    reg7_cont => REGISTER7_CONTENT
);

EXECUTE_UNIT_init: EXECUTE_UNIT Port map(
    PC_PLUS => NEXT_PC_sim,
    RD1 => REGISTER1_DATA,
    RD2 => REGISTER2_DATA,
    EXT_IMMEDIATE => EXT_IMMEDIATE_sim,
    FUNC => FUNC_sim,
    ALUSrc => ALUSrc_sim,
    ALUOp => ALUOp_sim,
    BranchAddress => Branch_Address_sim,
    ALU_Result => ALURes_sim,
    ZERO => ZERO_sim
);

MEMORY_UNIT_init: MEMORY_UNIT Port map(
    CLK => CLOCK,
    ALURes => ALURes_sim,
    RD2 => REGISTER2_DATA,
    MemWrite => MemWrite_sim,
    MemData => READ_DATA_sim
);

MAIN_CONTROL_init: MAIN_CONTROL Port map(
    INSTRUCTION => INSTRUCTION_sim(15 downto 13),
    RegDst => RegDst_sim,
    ExtOp => ExtOp_sim,
    ALUSrc => ALUSrc_sim,
    Branch => Branch_sim,
    Jump => Jump_sim,
    ALUOp => ALUOp_sim,
    MemWrite => MemWrite_sim,
    MemToReg => MemToReg_sim,
    RegWrite =>RegWrite_sim
);

MemoryToRegister: process(MemToReg_sim, READ_DATA_sim, REGISTER2_DATA)
begin
    case MemToReg_sim is
        when '0' => DATA_WRITE <= REGISTER2_DATA;
        when others => DATA_WRITE <= READ_DATA_sim;
    end case;
end process;
end Behavioral;

一切都按其应有的方式编译,只是 ALU 不想计算。我在网上读到,当两个实例覆盖它时,就会出现 X,但我一辈子都无法弄清楚我不小心覆盖了它的位置。我已经尝试了我能想到的所有方法,但鉴于我是 FPGA 的初学者,我完全不知所措,所以任何方法都会有帮助。

使用添加的代码进行编辑:

MEMORY_UNIT.vhd
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL; 
use IEEE.STD_LOGIC_UNSIGNED.ALL; 

entity MEMORY_UNIT is
    Port ( CLK : in STD_LOGIC;
           ALURes : inout STD_LOGIC_VECTOR (15 downto 0):= (others => '0');
           RD2 : in STD_LOGIC_VECTOR (15 downto 0):= (others => '0');
           MemWrite : in STD_LOGIC := '0';
           MemData : out STD_LOGIC_VECTOR(15 downto 0):= (others => '0')
           );
end MEMORY_UNIT;

architecture Behavioral of MEMORY_UNIT is

component RAM is
    port ( 
        CLK : in std_logic;
        WRITE_ENABLE : in std_logic;
        ADDRESS : in std_logic_vector(15 downto 0);
        WRITE_DATA : in std_logic_vector(15 downto 0);
        READ_DATA : out std_logic_vector(15 downto 0)
    );
end component RAM;

begin

RAM_int: RAM Port map(
    CLK=>CLK,
    WRITE_ENABLE=>MemWrite,
    ADDRESS=>ALURes,
    WRITE_DATA=>RD2,
    READ_DATA=>MemData
);

end Behavioral;
RAM.vhd
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL; 
use IEEE.STD_LOGIC_UNSIGNED.ALL; 

entity RAM is
    port ( 
        CLK : in std_logic;
        WRITE_ENABLE : in std_logic;
        ADDRESS : in std_logic_vector(15 downto 0);
        WRITE_DATA : in std_logic_vector(15 downto 0);
        READ_DATA : out std_logic_vector(15 downto 0)
    );
end RAM;

architecture syn of RAM is
    type ram_type is array (0 to 63) of std_logic_vector (15 downto 0);
    signal RAM_signal: ram_type := (others => (others => '0'));
    
    begin
    process (CLK)
        begin
        if CLK'event and CLK = '1' then
             if WRITE_ENABLE = '1' then
                 RAM_signal(conv_integer(ADDRESS)) <= WRITE_DATA;
             else
                 READ_DATA <= RAM_signal(conv_integer(ADDRESS));
             end if;
        end if;
    end process;
end syn;
mips vhdl cpu xilinx vivado
1个回答
0
投票

MEMORY_UNIT 的端口 ALURes 是一个输入输出。 这意味着 MEMORY_UNIT 不仅正在读取而且正在驱动该端口。 由于您没有为 MEMORY_UNIT 中的 ALURes 赋值 (ALURes 仅由 RAM 读取)ALURes 所有位的驱动值 MEMORY_UNIT 中的默认值是“U”。要解决该问题,您可以更改 将 ALURes 端口设置为“in”,或者您可以在 MEMORY_UNIT 中分配

ALURes <= (others => 'Z');

© www.soinside.com 2019 - 2024. All rights reserved.