// // make_connections.C // // Description: // Component connection function. At execution time, this will // connect all the CPU components according to the design of // the architecture. // // Version: // $Id$ // // Revision: // $Log$ // // Author: // Brian J. Alliet // Jonathon W. Donaldson // #include "includes.h" void make_connections() { static bool connected; // only allow connections to be made once if(connected) return; connected = true; // create register file for(int i=0;i<32;i++) { char buf[4]; sprintf(buf,"R%d",i); // create numbered register name regs[i] = new StorageObject(buf,32,i==31?0xdeadbeef:i==29?MEM_SIZE:0); } // create alias to reference data mem MAR in order to avoid extra clock cycle // rquired to avoid MAR StorageObject& ex_mem_aluout = dmem.MAR(); /* Make all Fetch phase connections */ StorageObject& pc = imem.MAR(); //create alias to avoid clock cycle pc.connectsTo(imem.READ()); pc.connectsTo(if_pc_bus.IN()); if_add.connectFrom(if_4.OUT(),if_pc_bus.OUT()); pc.connectsTo(if_add.OUT()); pc.connectsTo(id_add.OUT()); pc.connectsTo(id_jump_target_bus.OUT()); pc.connectsTo(id_reg_rs_bus.OUT()); pc.connectsTo(id_reg_jr_bus.OUT()); if_id_npc.connectsTo(if_add.OUT()); if_id_npc.connectsTo(id_add.OUT()); if_id_npc.connectsTo(id_jump_target_bus.OUT()); if_id_npc.connectsTo(id_reg_rs_bus.OUT()); if_id_npc.connectsTo(id_reg_jr_bus.OUT()); if_id_ir.connectsTo(imem.READ()); /* Decode */ if_id_npc.connectsTo(id_npc_bus.IN()); // next PC if_id_npc.connectsTo(id_onpc_bus.IN()); // old next PC (in case of jump) id_ex_onpc.connectsTo(id_onpc_bus.OUT()); if_id_ir.connectsTo(id_branch_off_bus.IN()); // branch offset (15-0 of IR) if_id_ir.connectsTo(id_jump_target_bus.IN()); // (25-0 of IR) id_add.connectFrom(id_npc_bus.OUT(),id_branch_off_bus.OUT()); mem_wb_lmd.connectsTo(id_reg_in_bus.IN()); mem_wb_aluout.connectsTo(id_reg_in_bus.IN()); id_ex_rs.connectsTo(id_reg_rs_bus.OUT()); id_ex_rt.connectsTo(id_reg_rt_bus.OUT()); for(int i=0;i<32;i++) { regs[i]->connectsTo(id_reg_in_bus.OUT()); // from WB stage regs[i]->connectsTo(id_reg_rs_bus.IN()); regs[i]->connectsTo(id_reg_rt_bus.IN()); regs[i]->connectsTo(id_reg_jr_bus.IN()); //feed back jump target to PC mux for JR instrux } // Connections used to read a value *just* written // (since we cannot do this with the arch package and // would normally be implemented physically in hardware) mem_wb_aluout.connectsTo(id_reg_rs_bus.IN()); mem_wb_lmd.connectsTo(id_reg_rs_bus.IN()); mem_wb_aluout.connectsTo(id_reg_rt_bus.IN()); mem_wb_lmd.connectsTo(id_reg_rt_bus.IN()); mem_wb_aluout.connectsTo(id_reg_jr_bus.IN()); mem_wb_lmd.connectsTo(id_reg_jr_bus.IN()); ex_mem_aluout.connectsTo(id_reg_jr_bus.IN()); // Sign-Extend Bus if_id_ir.connectsTo(id_imm_bus.IN()); id_ex_imm.connectsTo(id_imm_bus.OUT()); id_ex_uimm.connectsTo(id_imm_bus.OUT()); // shift amount if_id_ir.connectsTo(id_shamt_bus.IN()); id_ex_shamt.connectsTo(id_shamt_bus.OUT()); // copy IR pipeline register if_id_ir.connectsTo(id_ir_bus.IN()); id_ex_ir.connectsTo(id_ir_bus.OUT()); /* Execute */ id_ex_rs.connectsTo(alu.OP1()); id_ex_rs.connectsTo(alu.OP2()); id_ex_rt.connectsTo(alu.OP1()); // for shifting id_ex_rt.connectsTo(alu.OP2()); id_ex_imm.connectsTo(alu.OP1()); // allows load of Imm into upper 16-bits id_ex_imm.connectsTo(alu.OP2()); id_ex_uimm.connectsTo(alu.OP2()); id_ex_onpc.connectsTo(alu.OP1()); // for link instructions id_ex_shamt.connectsTo(alu.OP2()); ex_4.connectsTo(alu.OP2()); // for link calculation (add 4 to PC to get return addr) ex_16.connectsTo(alu.OP2()); // for load of Imm into upper 16-bits ex_mem_aluout.connectsTo(alu.OUT()); ex_mem_aluout.connectsTo(syscall_ret.OUT()); // copy RT id_ex_rt.connectsTo(ex_rt_bus.IN()); ex_mem_rt.connectsTo(ex_rt_bus.OUT()); // copy IR id_ex_ir.connectsTo(ex_ir_bus.IN()); ex_mem_ir.connectsTo(ex_ir_bus.OUT()); // For forwarding (Figure 2 in hardware documentation) ex_mem_aluout.connectsTo(alu.OP1()); ex_mem_aluout.connectsTo(alu.OP2()); ex_mem_aluout.connectsTo(ex_rt_bus.IN()); mem_wb_aluout.connectsTo(alu.OP1()); mem_wb_aluout.connectsTo(alu.OP2()); mem_wb_aluout.connectsTo(ex_rt_bus.IN()); mem_wb_lmd.connectsTo(alu.OP1()); mem_wb_lmd.connectsTo(alu.OP2()); mem_wb_lmd.connectsTo(ex_rt_bus.IN()); /* Memory */ ex_mem_rt.connectsTo(dmem.WRITE()); mem_wb_lmd.connectsTo(dmem.READ()); // copy ALUout ex_mem_aluout.connectsTo(mem_aluout_bus.IN()); mem_wb_aluout.connectsTo(mem_aluout_bus.OUT()); // copy IR ex_mem_ir.connectsTo(mem_ir_bus.IN()); mem_wb_ir.connectsTo(mem_ir_bus.OUT()); }