我正在研究这个 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"®1(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;
MEMORY_UNIT 的端口 ALURes 是一个输入输出。 这意味着 MEMORY_UNIT 不仅正在读取而且正在驱动该端口。 由于您没有为 MEMORY_UNIT 中的 ALURes 赋值 (ALURes 仅由 RAM 读取)ALURes 所有位的驱动值 MEMORY_UNIT 中的默认值是“U”。要解决该问题,您可以更改 将 ALURes 端口设置为“in”,或者您可以在 MEMORY_UNIT 中分配
ALURes <= (others => 'Z');
。