module Datapath(
    input         clk,
    input  [31:0] Instr,
    input         RegWr,
    input         MemToReg,
    input         MemWrEn,
    input         ALUBSrc,
    input         srcReg,
    input  [1:0]  ExtOp,
    input  [2:0]  AluCtrl,
    output        Zero
);
    wire [31:0] busA_out, busB_out, ext_out, alu_in_b, alu_result, ram_data_out, reg_write_data;
    wire [4:0] rj = Instr[9:5];
    wire [4:0] rk_or_rd_store = Instr[14:10];
    wire [4:0] rd_write = Instr[4:0];

    Registers u_Registers(.clk(clk), .RegWr(RegWr), .Ra(rj), .Rb(srcReg ? Instr[4:0] : rk_or_rd_store), .Rw(rd_write), .busW(reg_write_data), .busA(busA_out), .busB(busB_out));
    Ext u_Ext(.DataIn(Instr), .ExtOp(ExtOp), .DataOut(ext_out));
    assign alu_in_b = ALUBSrc ? ext_out : busB_out;
    ALU u_ALU(.a(busA_out), .b(alu_in_b), .AluCtrl(AluCtrl), .AddResult(alu_result), .Zero(Zero));
    DataRAM u_DataRAM(.clk(clk), .MemWrEn(MemWrEn), .addr(alu_result), .data_in(busB_out), .data_out(ram_data_out));
    assign reg_write_data = MemToReg ? ram_data_out : alu_result;
endmodule