module tb_exp2;
    reg clk;

    reg         DR_WE;
    reg  [31:0] DR_DataIn;
    wire [31:0] DR_DataOut;
    
    reg         PC_rst, PC_pc_inc;
    reg  [31:0] PC_offset;
    wire [31:0] PC_PCdata;

    reg         RegWr;
    reg  [4:0]  Ra, Rb, Rw;
    reg  [31:0] busW;
    wire [31:0] busA, busB;

    reg         MemWrEn;
    reg  [31:0] addr, data_in;
    wire [31:0] data_out;

    DR        u_DR        (.clk(clk), .WE(DR_WE), .DataIn(DR_DataIn), .DataOut(DR_DataOut));
    PC        u_PC        (.clk(clk), .rst(PC_rst), .pc_inc(PC_pc_inc), .offset(PC_offset), .PCdata(PC_PCdata));
    Registers u_Registers (.clk(clk), .RegWr(RegWr), .Ra(Ra), .Rb(Rb), .Rw(Rw), .busW(busW), .busA(busA), .busB(busB));
    DataRAM   u_DataRAM   (.clk(clk), .MemWrEn(MemWrEn), .addr(addr), .data_in(data_in), .data_out(data_out));

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

    initial begin
        $display("----------------- 开始实验二仿真 -----------------");
        
        $display("\n=========== 1. 测试 DR 模块 ===========");
        DR_DataIn = 32'h12345678; DR_WE = 1; #10;
        $display("T=%0t: 写入 DR, DataIn=%h. 期望 DataOut=%h. 实际 DataOut=%h", $time, DR_DataIn, DR_DataIn, DR_DataOut);
        DR_WE = 0; DR_DataIn = 32'hFFFFFFFF; #10;
        $display("T=%0t: 禁用写入, DataIn=%h. 期望 DataOut保持不变. 实际 DataOut=%h", $time, DR_DataIn, DR_DataOut);

        $display("\n=========== 2. 测试 PC 模块 ===========");
        PC_rst = 1; #10;
        $display("T=%0t: 异步复位. 期望 PCdata=0. 实际 PCdata=%d", $time, PC_PCdata);
        PC_rst = 0; PC_pc_inc = 1; #10;
        $display("T=%0t: PC自增. 期望 PCdata=4. 实际 PCdata=%d", $time, PC_PCdata);
        PC_pc_inc = 1; #10;
        $display("T=%0t: PC再次自增. 期望 PCdata=8. 实际 PCdata=%d", $time, PC_PCdata);
        PC_pc_inc = 0; PC_offset = 32'd100; #10;
        $display("T=%0t: PC加偏移量100. 期望 PCdata=108. 实际 PCdata=%d", $time, PC_PCdata);

        $display("\n=========== 3. 测试 Registers 模块 ===========");
        RegWr = 1; Rw = 5; busW = 32'hAAAAAAAA; #10;
        $display("T=%0t: 写入 r5 数据 0xAAAAAAAA", $time);
        Rw = 10; busW = 32'hBBBBBBBB; #10;
        $display("T=%0t: 写入 r10 数据 0xBBBBBBBB", $time);
        RegWr = 0; Ra = 5; Rb = 10; #10;
        $display("T=%0t: 读取 r5, r10. busA=%h, busB=%h", $time, busA, busB);

        $display("\n=========== 4. 测试 DataRAM 模块 ===========");
        MemWrEn = 1; addr = 32'd100; data_in = 32'hCAFECAFE; #10;
        $display("T=%0t: 写入内存地址 100, 数据 0xCAFECAFE", $time);
        MemWrEn = 0; addr = 32'd100; #10;
        $display("T=%0t: 读取内存地址 100. data_out=%h", $time, data_out);

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