`timescale 1ns / 1ps
module tb_exp3;
    reg clk;
    reg [31:0] Instr;
    reg RegWr, MemToReg, MemWrEn, ALUBSrc, srcReg;
    reg [1:0] ExtOp;
    reg [2:0] AluCtrl;
    wire Zero;

    Datapath uut (
        .clk(clk), .Instr(Instr), .RegWr(RegWr), .MemToReg(MemToReg), .MemWrEn(MemWrEn),
        .ALUBSrc(ALUBSrc), .srcReg(srcReg), .ExtOp(ExtOp), .AluCtrl(AluCtrl), .Zero(Zero)
    );

    wire [31:0] r1_val = uut.u_Registers.regs[1];
    wire [31:0] r2_val = uut.u_Registers.regs[2];
    wire [31:0] r3_val = uut.u_Registers.regs[3];

    initial begin clk = 0; forever #5 clk = ~clk; end

    initial begin
        $display("----------------- 开始实验三仿真 -----------------");
        uut.u_Registers.regs[1] = 32'd10;
        uut.u_Registers.regs[2] = 32'd20;
        #10;
        $display("T=%0t: 初始化 r1=10, r2=20", $time);

        $display("\n模拟 add.w r3, r1, r2");
        Instr = {11'b0, 5'd2, 5'd1, 5'd3};
        RegWr=1; MemToReg=0; MemWrEn=0; ALUBSrc=0; srcReg=0; ExtOp=2'bxx; AluCtrl=3'b000;
        #10;
        $display("T=%0t: 执行 add.w. 期望 r3 = 30. 实际 r3 = %d", $time, r3_val);

        uut.u_DataRAM.ram[120/4] = 32'hDEADBEEF;
        $display("\n模拟 ld.w r1, 100(r2)");
        Instr = {12'd100, 5'd2, 5'd1};
        RegWr=1; MemToReg=1; MemWrEn=0; ALUBSrc=1; srcReg=0; ExtOp=2'b00; AluCtrl=3'b000;
        #10;
        $display("T=%0t: 执行 ld.w. 期望 r1 = 0xDEADBEEF. 实际 r1 = %h", $time, r1_val);

        $display("\n----------------- 实验三仿真结束 -----------------");
        $stop;
    end
endmodule
