diff --git a/Hardware/LA32R.cache/wt/webtalk_pa.xml b/Hardware/LA32R.cache/wt/webtalk_pa.xml index 5053921..a009afc 100644 --- a/Hardware/LA32R.cache/wt/webtalk_pa.xml +++ b/Hardware/LA32R.cache/wt/webtalk_pa.xml @@ -3,7 +3,7 @@ - +
@@ -19,41 +19,79 @@ This means code written to parse this file will need to be revisited each subseq - + + - + + + + + + + - - + + + + - - + + - + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + - + - +
diff --git a/Hardware/LA32R.sim/sim_1/behav/xsim/webtalk.jou b/Hardware/LA32R.sim/sim_1/behav/xsim/webtalk.jou index 2507de1..a029100 100644 --- a/Hardware/LA32R.sim/sim_1/behav/xsim/webtalk.jou +++ b/Hardware/LA32R.sim/sim_1/behav/xsim/webtalk.jou @@ -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 diff --git a/Hardware/LA32R.sim/sim_1/behav/xsim/webtalk_16180.backup.jou b/Hardware/LA32R.sim/sim_1/behav/xsim/webtalk_30852.backup.jou similarity index 92% rename from Hardware/LA32R.sim/sim_1/behav/xsim/webtalk_16180.backup.jou rename to Hardware/LA32R.sim/sim_1/behav/xsim/webtalk_30852.backup.jou index 885483f..ff8736c 100644 --- a/Hardware/LA32R.sim/sim_1/behav/xsim/webtalk_16180.backup.jou +++ b/Hardware/LA32R.sim/sim_1/behav/xsim/webtalk_30852.backup.jou @@ -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 diff --git a/Hardware/LA32R.sim/sim_1/behav/xsim/xsim.dir/cpu_tb_snapshot/xsim.mem b/Hardware/LA32R.sim/sim_1/behav/xsim/xsim.dir/cpu_tb_snapshot/xsim.mem index 769a9b4..8397d44 100644 Binary files a/Hardware/LA32R.sim/sim_1/behav/xsim/xsim.dir/cpu_tb_snapshot/xsim.mem and b/Hardware/LA32R.sim/sim_1/behav/xsim/xsim.dir/cpu_tb_snapshot/xsim.mem differ diff --git a/Hardware/LA32R.sim/sim_1/behav/xsim/xsim.jou b/Hardware/LA32R.sim/sim_1/behav/xsim/xsim.jou index 215a6fd..65b516a 100644 --- a/Hardware/LA32R.sim/sim_1/behav/xsim/xsim.jou +++ b/Hardware/LA32R.sim/sim_1/behav/xsim/xsim.jou @@ -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 diff --git a/Hardware/LA32R.srcs/sources_1/new/control_unit.v b/Hardware/LA32R.srcs/sources_1/new/control_unit.v index bcb295b..aea8553 100644 --- a/Hardware/LA32R.srcs/sources_1/new/control_unit.v +++ b/Hardware/LA32R.srcs/sources_1/new/control_unit.v @@ -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 + + // -- 功能码字段 -- + 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 - // 定义指令操作码 (Opcode Definitions) - localparam OP_GROUP_00 = 6'b000000; // Contains 3R instructions - localparam OP_ADDI_W = 6'b000010; + // -- 操作码定义 -- + 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 +endmodule \ No newline at end of file diff --git a/Hardware/LA32R.srcs/sources_1/new/cpu_top.v b/Hardware/LA32R.srcs/sources_1/new/cpu_top.v index ecc238d..9ef76a5 100644 --- a/Hardware/LA32R.srcs/sources_1/new/cpu_top.v +++ b/Hardware/LA32R.srcs/sources_1/new/cpu_top.v @@ -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 diff --git a/Hardware/LA32R.xpr b/Hardware/LA32R.xpr index 6e1158e..fd224b2 100644 --- a/Hardware/LA32R.xpr +++ b/Hardware/LA32R.xpr @@ -31,7 +31,7 @@