Fix
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
<!--The data in this file is primarily intended for consumption by Xilinx tools.
|
||||
The structure and the elements are likely to change over the next few releases.
|
||||
This means code written to parse this file will need to be revisited each subsequent release.-->
|
||||
<application name="pa" timeStamp="Mon Jun 16 23:42:35 2025">
|
||||
<application name="pa" timeStamp="Wed Jun 18 12:07:36 2025">
|
||||
<section name="Project Information" visible="false">
|
||||
<property name="ProjectID" value="bf8c3145fb1f463a9279744865a6650a" type="ProjectID"/>
|
||||
<property name="ProjectIteration" value="1" type="ProjectIteration"/>
|
||||
@@ -19,41 +19,79 @@ This means code written to parse this file will need to be revisited each subseq
|
||||
<item name="Java Command Handlers">
|
||||
<property name="AddSources" value="2" type="JavaHandler"/>
|
||||
<property name="NewProject" value="1" type="JavaHandler"/>
|
||||
<property name="OpenProject" value="1" type="JavaHandler"/>
|
||||
<property name="OpenProject" value="2" type="JavaHandler"/>
|
||||
<property name="RunSchematic" value="6" type="JavaHandler"/>
|
||||
<property name="SetTopNode" value="1" type="JavaHandler"/>
|
||||
<property name="SimulationRun" value="6" type="JavaHandler"/>
|
||||
<property name="ShowSource" value="1" type="JavaHandler"/>
|
||||
<property name="SimulationRun" value="7" type="JavaHandler"/>
|
||||
<property name="ToolsSettings" value="1" type="JavaHandler"/>
|
||||
<property name="ViewTaskRTLAnalysis" value="2" type="JavaHandler"/>
|
||||
<property name="ZoomFit" value="7" type="JavaHandler"/>
|
||||
<property name="ZoomIn" value="13" type="JavaHandler"/>
|
||||
<property name="ZoomOut" value="24" type="JavaHandler"/>
|
||||
</item>
|
||||
<item name="Gui Handlers">
|
||||
<property name="AbstractCombinedPanel_REMOVE_SELECTED_ELEMENTS" value="1" type="GuiHandlerData"/>
|
||||
<property name="AbstractFileView_RELOAD" value="2" type="GuiHandlerData"/>
|
||||
<property name="AddSrcWizard_SPECIFY_SIMULATION_SPECIFIC_HDL_FILES" value="1" type="GuiHandlerData"/>
|
||||
<property name="BaseDialog_CANCEL" value="1" type="GuiHandlerData"/>
|
||||
<property name="BaseDialog_OK" value="12" type="GuiHandlerData"/>
|
||||
<property name="BaseDialog_CANCEL" value="4" type="GuiHandlerData"/>
|
||||
<property name="BaseDialog_OK" value="16" type="GuiHandlerData"/>
|
||||
<property name="CmdMsgDialog_MESSAGES" value="1" type="GuiHandlerData"/>
|
||||
<property name="CmdMsgDialog_OK" value="2" type="GuiHandlerData"/>
|
||||
<property name="ConfirmSaveTextEditsDialog_NO" value="1" type="GuiHandlerData"/>
|
||||
<property name="CreateSrcFileDialog_FILE_NAME" value="10" type="GuiHandlerData"/>
|
||||
<property name="FPGAChooser_FPGA_TABLE" value="1" type="GuiHandlerData"/>
|
||||
<property name="FileSetPanel_FILE_SET_PANEL_TREE" value="15" type="GuiHandlerData"/>
|
||||
<property name="FlowNavigatorTreePanel_FLOW_NAVIGATOR_TREE" value="9" type="GuiHandlerData"/>
|
||||
<property name="FileSetPanel_FILE_SET_PANEL_TREE" value="17" type="GuiHandlerData"/>
|
||||
<property name="FlowNavigatorTreePanel_FLOW_NAVIGATOR_TREE" value="16" type="GuiHandlerData"/>
|
||||
<property name="GettingStartedView_CREATE_NEW_PROJECT" value="1" type="GuiHandlerData"/>
|
||||
<property name="GettingStartedView_OPEN_PROJECT" value="1" type="GuiHandlerData"/>
|
||||
<property name="GettingStartedView_OPEN_PROJECT" value="2" type="GuiHandlerData"/>
|
||||
<property name="GraphicalView_ZOOM_FIT" value="1" type="GuiHandlerData"/>
|
||||
<property name="InstanceMenu_FLOORPLANNING" value="5" type="GuiHandlerData"/>
|
||||
<property name="MainMenuMgr_FLOORPLANNING" value="1" type="GuiHandlerData"/>
|
||||
<property name="MainMenuMgr_IO_PLANNING" value="1" type="GuiHandlerData"/>
|
||||
<property name="MainMenuMgr_REPORTS" value="2" type="GuiHandlerData"/>
|
||||
<property name="MainMenuMgr_TOOLS" value="2" type="GuiHandlerData"/>
|
||||
<property name="MainMenuMgr_WINDOW" value="4" type="GuiHandlerData"/>
|
||||
<property name="MainWinMenuMgr_LAYOUT" value="2" type="GuiHandlerData"/>
|
||||
<property name="NetlistSchMenuAndMouse_VIEW" value="5" type="GuiHandlerData"/>
|
||||
<property name="NetlistSchematicView_SHOW_CELLS_IN_THIS_SCHEMATIC" value="1" type="GuiHandlerData"/>
|
||||
<property name="NetlistTreeView_NETLIST_TREE" value="14" type="GuiHandlerData"/>
|
||||
<property name="PACommandNames_AUTO_UPDATE_HIER" value="5" type="GuiHandlerData"/>
|
||||
<property name="PACommandNames_EXPORT_SCHEMATIC" value="1" type="GuiHandlerData"/>
|
||||
<property name="PACommandNames_SCHEMATIC" value="5" type="GuiHandlerData"/>
|
||||
<property name="PACommandNames_SET_AS_TOP" value="4" type="GuiHandlerData"/>
|
||||
<property name="PACommandNames_SIMULATION_RUN_BEHAVIORAL" value="6" type="GuiHandlerData"/>
|
||||
<property name="PAViews_CODE" value="1" type="GuiHandlerData"/>
|
||||
<property name="PACommandNames_SIMULATION_RUN_BEHAVIORAL" value="7" type="GuiHandlerData"/>
|
||||
<property name="PACommandNames_ZOOM_FIT" value="7" type="GuiHandlerData"/>
|
||||
<property name="PACommandNames_ZOOM_IN" value="4" type="GuiHandlerData"/>
|
||||
<property name="PACommandNames_ZOOM_OUT" value="11" type="GuiHandlerData"/>
|
||||
<property name="PAViews_CODE" value="2" type="GuiHandlerData"/>
|
||||
<property name="PAViews_SCHEMATIC" value="2" type="GuiHandlerData"/>
|
||||
<property name="PrimitivesMenu_HIGHLIGHT_LEAF_CELLS" value="10" type="GuiHandlerData"/>
|
||||
<property name="ProjectNameChooser_CREATE_PROJECT_SUBDIRECTORY" value="1" type="GuiHandlerData"/>
|
||||
<property name="ProjectNameChooser_PROJECT_NAME" value="1" type="GuiHandlerData"/>
|
||||
<property name="RDICommands_CUSTOM_COMMANDS" value="1" type="GuiHandlerData"/>
|
||||
<property name="RDICommands_SETTINGS" value="1" type="GuiHandlerData"/>
|
||||
<property name="SaveSchematicDialog_ORIENTATION" value="2" type="GuiHandlerData"/>
|
||||
<property name="SchMenuAndMouse_SAVE_AS_PDF_FILE" value="2" type="GuiHandlerData"/>
|
||||
<property name="SelectMenu_HIGHLIGHT" value="6" type="GuiHandlerData"/>
|
||||
<property name="SelectMenu_MARK" value="5" type="GuiHandlerData"/>
|
||||
<property name="SettingsDialog_OPTIONS_TREE" value="1" type="GuiHandlerData"/>
|
||||
<property name="SettingsEditorPage_CUSTOM_EDITOR" value="1" type="GuiHandlerData"/>
|
||||
<property name="SettingsEditorPage_ENTER_COMMAND_LINE_FOR_CUSTOM" value="1" type="GuiHandlerData"/>
|
||||
<property name="SimulationObjectsPanel_SIMULATION_OBJECTS_TREE_TABLE" value="2" type="GuiHandlerData"/>
|
||||
<property name="SrcChooserPanel_ADD_HDL_AND_NETLIST_FILES_TO_YOUR_PROJECT" value="1" type="GuiHandlerData"/>
|
||||
<property name="SrcChooserPanel_CREATE_FILE" value="10" type="GuiHandlerData"/>
|
||||
<property name="SrcChooserTable_SRC_CHOOSER_TABLE" value="3" type="GuiHandlerData"/>
|
||||
<property name="SrcMenu_IP_HIERARCHY" value="3" type="GuiHandlerData"/>
|
||||
<property name="SyntheticaGettingStartedView_RECENT_PROJECTS" value="1" type="GuiHandlerData"/>
|
||||
<property name="TclConsoleView_COPY" value="2" type="GuiHandlerData"/>
|
||||
<property name="TclConsoleView_TCL_CONSOLE_CODE_EDITOR" value="35" type="GuiHandlerData"/>
|
||||
<property name="WaveformNameTree_WAVEFORM_NAME_TREE" value="2" type="GuiHandlerData"/>
|
||||
<property name="WaveformNameTree_WAVEFORM_NAME_TREE" value="4" type="GuiHandlerData"/>
|
||||
</item>
|
||||
<item name="Other">
|
||||
<property name="GuiMode" value="7" type="GuiMode"/>
|
||||
<property name="BatchMode" value="0" type="BatchMode"/>
|
||||
<property name="TclMode" value="3" type="TclMode"/>
|
||||
<property name="TclMode" value="4" type="TclMode"/>
|
||||
</item>
|
||||
</section>
|
||||
</application>
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
# Webtalk v2018.1 (64-bit)
|
||||
# SW Build 2188600 on Wed Apr 4 18:40:38 MDT 2018
|
||||
# IP Build 2185939 on Wed Apr 4 20:55:05 MDT 2018
|
||||
# Start of session at: Tue Jun 17 00:19:34 2025
|
||||
# Process ID: 36764
|
||||
# Start of session at: Wed Jun 18 16:55:31 2025
|
||||
# Process ID: 19784
|
||||
# Current directory: D:/Schoolwork/ComputerComposition/LA32R/Hardware/LA32R.sim/sim_1/behav/xsim
|
||||
# Command line: wbtcv.exe -mode batch -source D:/Schoolwork/ComputerComposition/LA32R/Hardware/LA32R.sim/sim_1/behav/xsim/xsim.dir/cpu_tb_snapshot/webtalk/xsim_webtalk.tcl -notrace
|
||||
# Log file: D:/Schoolwork/ComputerComposition/LA32R/Hardware/LA32R.sim/sim_1/behav/xsim/webtalk.log
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
# Webtalk v2018.1 (64-bit)
|
||||
# SW Build 2188600 on Wed Apr 4 18:40:38 MDT 2018
|
||||
# IP Build 2185939 on Wed Apr 4 20:55:05 MDT 2018
|
||||
# Start of session at: Tue Jun 17 00:19:31 2025
|
||||
# Process ID: 16180
|
||||
# Start of session at: Wed Jun 18 16:55:28 2025
|
||||
# Process ID: 30852
|
||||
# Current directory: D:/Schoolwork/ComputerComposition/LA32R/Hardware/LA32R.sim/sim_1/behav/xsim
|
||||
# Command line: wbtcv.exe -mode batch -source D:/Schoolwork/ComputerComposition/LA32R/Hardware/LA32R.sim/sim_1/behav/xsim/xsim.dir/cpu_tb_snapshot/webtalk/xsim_webtalk.tcl -notrace
|
||||
# Log file: D:/Schoolwork/ComputerComposition/LA32R/Hardware/LA32R.sim/sim_1/behav/xsim/webtalk.log
|
||||
Binary file not shown.
@@ -2,8 +2,8 @@
|
||||
# xsim v2018.1 (64-bit)
|
||||
# SW Build 2188600 on Wed Apr 4 18:40:38 MDT 2018
|
||||
# IP Build 2185939 on Wed Apr 4 20:55:05 MDT 2018
|
||||
# Start of session at: Tue Jun 17 00:19:32 2025
|
||||
# Process ID: 35112
|
||||
# Start of session at: Wed Jun 18 16:55:28 2025
|
||||
# Process ID: 40140
|
||||
# Current directory: D:/Schoolwork/ComputerComposition/LA32R/Hardware/LA32R.sim/sim_1/behav/xsim
|
||||
# Command line: xsim.exe -log ..\..\..\..\..\simulation.log -mode tcl -source {xsim.dir/cpu_tb_snapshot/xsim_script.tcl}
|
||||
# Log file: D:/Schoolwork/ComputerComposition/LA32R/Hardware/LA32R.sim/sim_1/behav/xsim/../../../../../simulation.log
|
||||
|
||||
@@ -17,8 +17,17 @@
|
||||
**
|
||||
** [FIXED] Restructured the case statement to correctly handle instructions
|
||||
** that share the same opcode, such as LD.W and ST.W.
|
||||
** [FIXED] ADDI.W decoding now correctly uses opcode 000000 + func4.
|
||||
** [FIXED] Added new control signal 'ALUAsrc' to force ALU's A-operand to 0
|
||||
** for LUI12I.W instruction.
|
||||
** [FINAL FIX] Corrected the logic within the opcode '000000' group.
|
||||
** The previous version incorrectly evaluated func fields, causing 3R-type
|
||||
** instructions to fail after the ADDI.W fix. This version ensures both
|
||||
** ADDI.W and all 3R instructions are decoded correctly according to the ISA.
|
||||
**
|
||||
** Revision:
|
||||
** Revision 0.04 - Fixed logic for 3R-type instructions.
|
||||
** Revision 0.03 - Fixed ADDI.W decoding and shared opcode logic.
|
||||
** Revision 0.02 - Corrected case statement logic for shared opcodes.
|
||||
** Revision 0.01 - File Created
|
||||
**
|
||||
@@ -36,131 +45,84 @@ module control_unit (
|
||||
output reg src_reg, // 选择寄存器堆的第二读地址源 (Selects Register File's second read address source)
|
||||
output reg [2:0] ext_op, // 立即数扩展控制 (Immediate extender control)
|
||||
output reg [3:0] alu_op, // ALU操作控制 (ALU operation control)
|
||||
output reg alu_asrc, // [NEW] 选择ALU第一操作数源 (Selects ALU's first operand source)
|
||||
output wire pcsource // PC下一个地址来源选择 (PC next address source selection)
|
||||
);
|
||||
|
||||
// 提取指令中的关键字段
|
||||
// Extract key fields from the instruction
|
||||
wire [5:0] opcode = instr[31:26];
|
||||
wire [1:0] func2 = instr[21:20]; // for 3R-type per ISA document
|
||||
wire [4:0] func5 = instr[19:15]; // for 3R-type per ISA document
|
||||
wire [3:0] func4 = instr[25:22]; // for 2RI12-type
|
||||
|
||||
// 定义指令操作码 (Opcode Definitions)
|
||||
localparam OP_GROUP_00 = 6'b000000; // Contains 3R instructions
|
||||
localparam OP_ADDI_W = 6'b000010;
|
||||
// -- 功能码字段 --
|
||||
wire [3:0] func_2ri12 = instr[25:22]; // For ADDI.W, LD.W, ST.W
|
||||
wire [1:0] func_3r_f2 = instr[21:20]; // For 3R-type
|
||||
wire [4:0] func_3r_f5 = instr[19:15]; // For 3R-type
|
||||
|
||||
// -- 操作码定义 --
|
||||
localparam OP_GROUP_00 = 6'b000000; // Contains 3R & ADDI.W
|
||||
localparam OP_LUI12I = 6'b000101;
|
||||
localparam OP_GROUP_0A = 6'b001010; // Contains LD.W, ST.W
|
||||
localparam OP_B = 6'b010100;
|
||||
localparam OP_BEQ = 6'b010110;
|
||||
localparam OP_BLT = 6'b011000;
|
||||
|
||||
// 定义ALU操作码 (ALU Operation Definitions)
|
||||
localparam ALU_ADD = 4'b0000;
|
||||
localparam ALU_SUB = 4'b0001;
|
||||
localparam ALU_AND = 4'b0010;
|
||||
localparam ALU_OR = 4'b0011;
|
||||
localparam ALU_NOR = 4'b0100;
|
||||
localparam ALU_SLT = 4'b0101;
|
||||
localparam ALU_SLTU = 4'b0110;
|
||||
localparam ALU_ADD = 4'b0000, ALU_SUB = 4'b0001, ALU_AND = 4'b0010,
|
||||
ALU_OR = 4'b0011, ALU_NOR = 4'b0100, ALU_SLT = 4'b0101,
|
||||
ALU_SLTU= 4'b0110;
|
||||
|
||||
// 定义立即数扩展类型 (Immediate Extension Type Definitions)
|
||||
localparam EXT_SI12 = 3'b001;
|
||||
localparam EXT_SI16 = 3'b010;
|
||||
localparam EXT_UI20 = 3'b011;
|
||||
localparam EXT_SI26 = 3'b100;
|
||||
localparam EXT_SI12 = 3'b001, EXT_SI16 = 3'b010, EXT_UI20 = 3'b011, EXT_SI26 = 3'b100;
|
||||
|
||||
// 主译码逻辑 (Main Decoding Logic)
|
||||
always @(*) begin
|
||||
// --- 控制信号默认值,防止生成锁存器 ---
|
||||
// Default values for control signals to prevent latches
|
||||
reg_write_en = 1'b0;
|
||||
mem_to_reg = 1'b0;
|
||||
mem_write_en = 1'b0;
|
||||
alu_src = 1'b0;
|
||||
src_reg = 1'b0;
|
||||
ext_op = 3'bxxx;
|
||||
alu_op = 4'bxxxx;
|
||||
// -- 默认值 --
|
||||
reg_write_en = 1'b0; mem_to_reg = 1'b0; mem_write_en = 1'b0;
|
||||
alu_src = 1'b0; src_reg = 1'b0; alu_asrc = 1'b0;
|
||||
ext_op = 3'bxxx; alu_op = 4'bxxxx;
|
||||
|
||||
case (opcode)
|
||||
OP_GROUP_00: begin
|
||||
// Differentiate based on func2 field
|
||||
if (func2 == 2'b01) begin // This is a 3R-type arithmetic/logic instruction
|
||||
// 3R 和 ADDI.W 共享主操作码 000000
|
||||
if (func_2ri12 == 4'b1010) begin // ADDI.W
|
||||
reg_write_en = 1'b1;
|
||||
alu_src = 1'b0; // B operand comes from register
|
||||
src_reg = 1'b0; // Second read address comes from rk field
|
||||
// Further decode based on func5
|
||||
case(func5)
|
||||
5'b00000: alu_op = ALU_ADD;
|
||||
5'b00010: alu_op = ALU_SUB;
|
||||
5'b00100: alu_op = ALU_SLT;
|
||||
5'b00101: alu_op = ALU_SLTU;
|
||||
5'b01000: alu_op = ALU_NOR;
|
||||
5'b01001: alu_op = ALU_AND;
|
||||
5'b01010: alu_op = ALU_OR;
|
||||
default: alu_op = 4'bxxxx;
|
||||
alu_src = 1'b1;
|
||||
ext_op = EXT_SI12;
|
||||
alu_op = ALU_ADD;
|
||||
end
|
||||
// 对于3R指令, func_2ri12 ([25:22]) 字段为 '0000'
|
||||
// 并且 func_3r_f2 ([21:20]) 字段为 '01'
|
||||
else if (instr[25:22] == 4'b0000 && func_3r_f2 == 2'b01) begin // 3R-type
|
||||
reg_write_en = 1'b1;
|
||||
alu_src = 1'b0;
|
||||
src_reg = 1'b0;
|
||||
case(func_3r_f5)
|
||||
5'b00000: alu_op = ALU_ADD; 5'b00010: alu_op = ALU_SUB;
|
||||
5'b00100: alu_op = ALU_SLT; 5'b00101: alu_op = ALU_SLTU;
|
||||
5'b01000: alu_op = ALU_NOR; 5'b01001: alu_op = ALU_AND;
|
||||
5'b01010: alu_op = ALU_OR; default: alu_op = 4'bxxxx;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
OP_ADDI_W: begin
|
||||
// ADDI.W has its own opcode
|
||||
reg_write_en = 1'b1;
|
||||
alu_src = 1'b1; // B operand comes from immediate
|
||||
ext_op = EXT_SI12;
|
||||
alu_op = ALU_ADD;
|
||||
end
|
||||
OP_LUI12I: begin
|
||||
reg_write_en = 1'b1;
|
||||
alu_src = 1'b1;
|
||||
mem_to_reg = 1'b0; // ALU result writes back
|
||||
ext_op = EXT_UI20;
|
||||
alu_op = ALU_ADD; // ALU adds immediate to zero
|
||||
reg_write_en = 1'b1; alu_src = 1'b1; alu_asrc = 1'b1;
|
||||
ext_op = EXT_UI20; alu_op = ALU_ADD;
|
||||
end
|
||||
OP_GROUP_0A: begin
|
||||
// Differentiate LD.W and ST.W based on func4
|
||||
if (func4 == 4'b0010) begin // LD.W
|
||||
reg_write_en = 1'b1;
|
||||
mem_to_reg = 1'b1; // Data from memory writes back
|
||||
alu_src = 1'b1;
|
||||
ext_op = EXT_SI12;
|
||||
alu_op = ALU_ADD; // Calculate address
|
||||
if (func_2ri12 == 4'b0010) begin // LD.W
|
||||
reg_write_en = 1'b1; mem_to_reg = 1'b1;
|
||||
alu_src = 1'b1; ext_op = EXT_SI12; alu_op = ALU_ADD;
|
||||
end
|
||||
else if (func4 == 4'b0110) begin // ST.W
|
||||
mem_write_en = 1'b1;
|
||||
alu_src = 1'b1;
|
||||
src_reg = 1'b1; // Second read address comes from rd field
|
||||
ext_op = EXT_SI12;
|
||||
alu_op = ALU_ADD; // Calculate address
|
||||
else if (func_2ri12 == 4'b0110) begin // ST.W
|
||||
mem_write_en = 1'b1; alu_src = 1'b1; src_reg = 1'b1;
|
||||
ext_op = EXT_SI12; alu_op = ALU_ADD;
|
||||
end
|
||||
end
|
||||
OP_B: begin
|
||||
// Unconditional branch
|
||||
ext_op = EXT_SI26;
|
||||
end
|
||||
OP_BEQ: begin
|
||||
alu_src = 1'b0;
|
||||
src_reg = 1'b1; // Second read address comes from rd field
|
||||
ext_op = EXT_SI16;
|
||||
alu_op = ALU_SUB; // Compare
|
||||
end
|
||||
OP_BLT: begin
|
||||
alu_src = 1'b0;
|
||||
src_reg = 1'b1; // Second read address comes from rd field
|
||||
ext_op = EXT_SI16;
|
||||
alu_op = ALU_SUB; // Compare
|
||||
end
|
||||
default: begin
|
||||
// All signals keep their default values
|
||||
end
|
||||
OP_B: ext_op = EXT_SI26;
|
||||
OP_BEQ: begin alu_src = 1'b0; src_reg = 1'b1; ext_op = EXT_SI16; alu_op = ALU_SUB; end
|
||||
OP_BLT: begin alu_src = 1'b0; src_reg = 1'b1; ext_op = EXT_SI16; alu_op = ALU_SUB; end
|
||||
default: begin end
|
||||
endcase
|
||||
end
|
||||
|
||||
// PC下一个地址来源的逻辑
|
||||
// Logic for PC's next address source
|
||||
wire beq_cond = (opcode == OP_BEQ) && zero_flag;
|
||||
wire blt_cond = (opcode == OP_BLT) && lt_flag;
|
||||
wire b_cond = (opcode == OP_B);
|
||||
|
||||
assign pcsource = beq_cond || blt_cond || b_cond;
|
||||
|
||||
endmodule
|
||||
@@ -16,129 +16,72 @@
|
||||
** immediate extender, and the control unit. The connections follow the
|
||||
** datapath diagram provided in the course design guide.
|
||||
**
|
||||
** [FIXED] Added a multiplexer for the ALU's first operand (A-operand) to
|
||||
** support the LUI12I.W instruction by allowing it to select 0.
|
||||
**
|
||||
** Revision:
|
||||
** Revision 0.02 - Added ALUAsrc control signal to support LUI12I.W instruction.
|
||||
** Revision 0.01 - File Created
|
||||
** Additional Comments:
|
||||
** - This file integrates the entire design.
|
||||
**
|
||||
*******************************************************************************/
|
||||
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
module cpu_top (
|
||||
input wire clk,
|
||||
input wire rst
|
||||
);
|
||||
|
||||
// --- 内部连线声明 (Internal Wire Declarations) ---
|
||||
wire [31:0] pc_out;
|
||||
wire [31:0] instr;
|
||||
wire [31:0] imm_ext;
|
||||
wire [31:0] read_data1;
|
||||
wire [31:0] read_data2;
|
||||
wire [31:0] alu_result;
|
||||
wire [31:0] mem_read_data;
|
||||
wire [31:0] write_back_data;
|
||||
wire [31:0] alu_b_operand;
|
||||
wire [31:0] pc_out, instr, imm_ext, read_data1, read_data2, alu_result,
|
||||
mem_read_data, write_back_data, alu_a_operand, alu_b_operand;
|
||||
|
||||
wire [4:0] reg_write_addr;
|
||||
wire [4:0] reg_read_addr1;
|
||||
wire [4:0] reg_read_addr2;
|
||||
wire [4:0] reg_read_addr2_final;
|
||||
|
||||
// 控制信号
|
||||
// Control Signals
|
||||
wire reg_write_en;
|
||||
wire mem_to_reg;
|
||||
wire mem_write_en;
|
||||
wire alu_src;
|
||||
wire src_reg;
|
||||
wire pcsource;
|
||||
wire zero_flag;
|
||||
wire lt_flag;
|
||||
// 控制信号 (Control Signals)
|
||||
wire reg_write_en, mem_to_reg, mem_write_en, alu_src, src_reg,
|
||||
alu_asrc, pcsource, zero_flag, lt_flag;
|
||||
wire [2:0] ext_op;
|
||||
wire [3:0] alu_op;
|
||||
|
||||
|
||||
// --- 模块实例化 (Module Instantiation) ---
|
||||
|
||||
// PC (程序计数器)
|
||||
pc u_pc (
|
||||
.clk (clk),
|
||||
.rst (rst),
|
||||
.pcsource (pcsource),
|
||||
.imm_ext (imm_ext),
|
||||
.pc_out (pc_out)
|
||||
);
|
||||
pc u_pc (.clk(clk), .rst(rst), .pcsource(pcsource), .imm_ext(imm_ext), .pc_out(pc_out));
|
||||
|
||||
// Instruction Memory (指令存储器)
|
||||
instruction_memory u_inst_mem (
|
||||
.addr (pc_out),
|
||||
.instr (instr)
|
||||
);
|
||||
instruction_memory u_inst_mem (.addr(pc_out), .instr(instr));
|
||||
|
||||
// Control Unit (控制单元)
|
||||
control_unit u_ctrl_unit (
|
||||
.instr (instr),
|
||||
.zero_flag (zero_flag),
|
||||
.lt_flag (lt_flag),
|
||||
.reg_write_en (reg_write_en),
|
||||
.mem_to_reg (mem_to_reg),
|
||||
.mem_write_en (mem_write_en),
|
||||
.alu_src (alu_src),
|
||||
.src_reg (src_reg),
|
||||
.ext_op (ext_op),
|
||||
.alu_op (alu_op),
|
||||
.pcsource (pcsource)
|
||||
.instr(instr), .zero_flag(zero_flag), .lt_flag(lt_flag),
|
||||
.reg_write_en(reg_write_en), .mem_to_reg(mem_to_reg), .mem_write_en(mem_write_en),
|
||||
.alu_src(alu_src), .src_reg(src_reg), .ext_op(ext_op), .alu_op(alu_op),
|
||||
.alu_asrc(alu_asrc), .pcsource(pcsource)
|
||||
);
|
||||
|
||||
// Immediate Extender (立即数扩展单元)
|
||||
imm_extender u_imm_ext (
|
||||
.instr (instr),
|
||||
.ext_op (ext_op),
|
||||
.imm_ext (imm_ext)
|
||||
);
|
||||
imm_extender u_imm_ext (.instr(instr), .ext_op(ext_op), .imm_ext(imm_ext));
|
||||
|
||||
// MUX for Register File's second read address (src_reg_mux)
|
||||
assign reg_read_addr2_final = src_reg ? instr[4:0] : instr[14:10];
|
||||
wire [4:0] reg_read_addr2_final = src_reg ? instr[4:0] : instr[14:10];
|
||||
|
||||
// Register File (寄存器堆)
|
||||
register_file u_reg_file (
|
||||
.clk (clk),
|
||||
.rst (rst),
|
||||
.reg_write_en (reg_write_en),
|
||||
.read_addr1 (instr[9:5]),
|
||||
.read_addr2 (reg_read_addr2_final),
|
||||
.write_addr (instr[4:0]),
|
||||
.write_data (write_back_data),
|
||||
.read_data1 (read_data1),
|
||||
.read_data2 (read_data2)
|
||||
.clk(clk), .rst(rst), .reg_write_en(reg_write_en),
|
||||
.read_addr1(instr[9:5]), .read_addr2(reg_read_addr2_final),
|
||||
.write_addr(instr[4:0]), .write_data(write_back_data),
|
||||
.read_data1(read_data1), .read_data2(read_data2)
|
||||
);
|
||||
|
||||
// MUX for ALU's second operand (alu_src_mux)
|
||||
// [NEW] MUX for ALU's first operand (A)
|
||||
assign alu_a_operand = alu_asrc ? 32'b0 : read_data1;
|
||||
|
||||
// MUX for ALU's second operand (B)
|
||||
assign alu_b_operand = alu_src ? imm_ext : read_data2;
|
||||
|
||||
// ALU (算术逻辑单元)
|
||||
alu u_alu (
|
||||
.a (read_data1),
|
||||
.b (alu_b_operand),
|
||||
.alu_op (alu_op),
|
||||
.result (alu_result),
|
||||
.zero (zero_flag),
|
||||
.lt (lt_flag)
|
||||
.a(alu_a_operand), .b(alu_b_operand), .alu_op(alu_op),
|
||||
.result(alu_result), .zero(zero_flag), .lt(lt_flag)
|
||||
);
|
||||
|
||||
// Data Memory (数据存储器)
|
||||
data_memory u_data_mem (
|
||||
.clk (clk),
|
||||
.mem_write_en (mem_write_en),
|
||||
.addr (alu_result),
|
||||
.write_data (read_data2), // ST.W指令的数据来自第二个读端口(rd)
|
||||
.read_data (mem_read_data)
|
||||
.clk(clk), .mem_write_en(mem_write_en), .addr(alu_result),
|
||||
.write_data(read_data2), .read_data(mem_read_data)
|
||||
);
|
||||
|
||||
// MUX for write-back data (mem_to_reg_mux)
|
||||
assign write_back_data = mem_to_reg ? mem_read_data : alu_result;
|
||||
|
||||
|
||||
endmodule
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
<Option Name="EnableBDX" Val="FALSE"/>
|
||||
<Option Name="DSAVendor" Val="xilinx"/>
|
||||
<Option Name="DSANumComputeUnits" Val="60"/>
|
||||
<Option Name="WTXSimLaunchSim" Val="5"/>
|
||||
<Option Name="WTXSimLaunchSim" Val="6"/>
|
||||
<Option Name="WTModelSimLaunchSim" Val="0"/>
|
||||
<Option Name="WTQuestaLaunchSim" Val="0"/>
|
||||
<Option Name="WTIesLaunchSim" Val="0"/>
|
||||
|
||||
@@ -7,29 +7,28 @@ LA32R Simple Assembler
|
||||
- Supports all 14 instructions required by the course design.
|
||||
- Handles register names like '$r4', '$r12' and immediate values.
|
||||
- Outputs a 'program.hex' file suitable for Verilog's $readmemh.
|
||||
- [FIXED] Corrected the encoding for ADDI.W to match the ISA specification
|
||||
(opcode 000000 + func4).
|
||||
- [FINAL FIX] Corrected the string formatting for 3R-type instructions, which
|
||||
was scrambling the register and function fields.
|
||||
"""
|
||||
|
||||
# 指令编码定义
|
||||
# Instruction encoding definitions
|
||||
OPCODES = {
|
||||
'add.w': '000000', 'sub.w': '000000', 'slt': '000000', 'sltu': '000000',
|
||||
'add.w': '000000', 'sub.w': '000000', 'slt': '000000', 'sltu': '000000',
|
||||
'nor': '000000', 'and': '000000', 'or': '000000',
|
||||
'addi.w': '000010', 'lu12i.w': '000101', 'ld.w': '001010', 'st.w': '001010',
|
||||
'b': '010100', 'beq': '010110', 'blt': '011000'
|
||||
'addi.w': '000000', 'lu12i.w': '000101', 'ld.w': '001010', 'st.w': '001010',
|
||||
'b': '010100', 'beq': '010110', 'blt': '011000'
|
||||
}
|
||||
|
||||
FUNC_3R = {
|
||||
# 'opcode': ('func2', 'func5')
|
||||
'add.w': ('01', '00000'), 'sub.w': ('01', '00010'), 'slt': ('01', '00100'),
|
||||
'sltu': ('01', '00101'), 'nor': ('01', '01000'), 'and': ('01', '01001'),
|
||||
'or': ('01', '01010')
|
||||
'add.w': ('01', '00000'), 'sub.w': ('01', '00010'), 'slt': ('01', '00100'),
|
||||
'sltu': ('01', '00101'), 'nor': ('01', '01000'), 'and': ('01', '01001'),
|
||||
'or': ('01', '01010')
|
||||
}
|
||||
|
||||
FUNC_2RI12 = {
|
||||
# 'opcode': 'func4'
|
||||
'addi.w': '1010',
|
||||
'ld.w': '0010',
|
||||
'st.w': '0110'
|
||||
'addi.w': '1010', 'ld.w': '0010', 'st.w': '0110'
|
||||
}
|
||||
|
||||
|
||||
@@ -52,42 +51,39 @@ def assemble_line(line):
|
||||
parts = re.split(r'[\s,]+', line)
|
||||
op = parts[0]
|
||||
|
||||
if op in FUNC_3R: # 3R-type: add.w $r3, $r1, $r2
|
||||
if op in FUNC_3R: # 3R-type
|
||||
rd, rj, rk = parse_register(parts[1]), parse_register(parts[2]), parse_register(parts[3])
|
||||
opcode = OPCODES[op]
|
||||
func2, func5 = FUNC_3R[op]
|
||||
# [THE FIX] Removed the erroneous hardcoded '00000' field.
|
||||
# The correct format for these 3R instructions is opcode | 0000 | func2 | func5 | rk | rj | rd
|
||||
return f"{opcode}0000{func2}{func5}{rk}{rj}{rd}"
|
||||
|
||||
elif op in ['addi.w', 'ld.w', 'st.w']: # 2RI12-type
|
||||
rd = parse_register(parts[1])
|
||||
rj = parse_register(parts[2])
|
||||
# FIX: Use int(str, 0) to auto-detect base (e.g., '0x' for hex)
|
||||
imm = to_binary(int(parts[3], 0), 12)
|
||||
opcode = OPCODES[op]
|
||||
func4 = FUNC_2RI12[op]
|
||||
return f"{opcode}{func4}{imm}{rj}{rd}"
|
||||
|
||||
elif op == 'lu12i.w': # 1RI20-type: lu12i.w $r1, 0x12345
|
||||
elif op == 'lu12i.w': # 1RI20-type
|
||||
rd = parse_register(parts[1])
|
||||
imm = to_binary(int(parts[2], 0), 20) # Support hex (0x) and dec
|
||||
imm = to_binary(int(parts[2], 0), 20)
|
||||
opcode = OPCODES[op]
|
||||
return f"{opcode}0{imm}{rd}"
|
||||
|
||||
elif op in ['beq', 'blt']: # 2RI16-type: beq $r1, $r2, -4
|
||||
rj = parse_register(parts[1])
|
||||
rd = parse_register(parts[2])
|
||||
# FIX: Use int(str, 0) to auto-detect base
|
||||
offset = int(parts[3], 0) >> 2 # Offset is in bytes, convert to word offset for encoding
|
||||
elif op in ['beq', 'blt']: # 2RI16-type
|
||||
rj, rd = parse_register(parts[1]), parse_register(parts[2])
|
||||
offset = int(parts[3], 0) >> 2
|
||||
imm = to_binary(offset, 16)
|
||||
opcode = OPCODES[op]
|
||||
return f"{opcode}{imm}{rj}{rd}"
|
||||
|
||||
elif op == 'b': # I26-type: b -8
|
||||
# FIX: Use int(str, 0) to auto-detect base
|
||||
offset = int(parts[1], 0) >> 2 # Convert to word offset
|
||||
elif op == 'b': # I26-type
|
||||
offset = int(parts[1], 0) >> 2
|
||||
imm = to_binary(offset, 26)
|
||||
offs_25_16 = imm[0:10]
|
||||
offs_15_0 = imm[10:26]
|
||||
offs_25_16, offs_15_0 = imm[0:10], imm[10:26]
|
||||
opcode = OPCODES[op]
|
||||
return f"{opcode}{offs_15_0}{offs_25_16}"
|
||||
|
||||
@@ -110,7 +106,6 @@ def main():
|
||||
# Ignore comments and empty lines
|
||||
if not line or line.startswith('//'):
|
||||
continue
|
||||
|
||||
try:
|
||||
# 移除行内注释
|
||||
# Remove inline comments
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
14246004
|
||||
0a915884
|
||||
02915884
|
||||
15110005
|
||||
0abffca5
|
||||
02bffca5
|
||||
00101486
|
||||
00111487
|
||||
00121488
|
||||
@@ -9,13 +9,13 @@
|
||||
0014948a
|
||||
0015148b
|
||||
00142d4c
|
||||
0a819001
|
||||
02819001
|
||||
29800024
|
||||
29801025
|
||||
2880002d
|
||||
2880102e
|
||||
580009a4
|
||||
0a80040f
|
||||
0280040f
|
||||
600008e6
|
||||
0a800410
|
||||
02800410
|
||||
53ffffff
|
||||
|
||||
Reference in New Issue
Block a user