/* Author : Rick van der Zwet * S-number : 0433373 * Version : $Id: datapath.c 365 2007-12-03 08:54:04Z rick $ * Copyright : FreeBSD Licence * Description : Memory unit */ #include #include #include #include "datapath.h" #include "imm.h" #include "constant.h" #include "memory.h" word select_sx(const sx_control_t control) { word out=0; switch (control) { case NO_COMPONENT: out = 0; break; case A: out = a; break; case B: out = b; break; case TEMP: out = temp; break; case TEMP2: out = temp2; break; case PC: out = pc; break; case MAR: out = mar; break; case MDR: out = mdr; break; case CONST: out = constant; break; case IMM: out = imm; break; default: fprintf(stderr, "Switch '%i' not implemented\n", control); exit(EX_SOFTWARE); break; }; return (out); } void update_state(control_t control) { word temp_destbus; word temp_mem; constant = constant_call(control.constant); imm = imm_call(ir, control.ir); /* Going to ALU if activated */ word in1 = 0; word in2 = 0; if (control.alu_unit == ALU_STALLED) { temp_destbus = 0; } else { in1 = select_sx(control.s1); in2 = select_sx(control.s2); temp_destbus = alu(in1, in2, control.alu_unit); } if (control.c == WRITE) c = temp_destbus; if (control.temp == WRITE) temp = temp_destbus; if (control.temp2 == WRITE) temp2 = temp_destbus; if (control.pc == WRITE) pc = temp_destbus; if (control.mar == WRITE) mar = temp_destbus; if (control.mdr == WRITE) { if (control.mux == DATAPATH) mdr = temp_destbus; else if (control.mux == MEMORY) mdr = temp_mem; else { fprintf(stderr, "Mux control not defined\n"); exit(EX_SOFTWARE); } } /* Memory actions */ if (control.memory != MEM_STALLED) { mem_busy = TRUE; temp_mem = mem_operation(mar, mdr, control.memory); if (control.ir == WRITE) ir = temp_mem; if (control.mdr == WRITE && control.mux == MEMORY) mdr = temp_mem; } /* Register actions */ if (control.a == WRITE && ((control.reg & 1) != 0)) a = reg[control.register_address_a]; if (control.b == WRITE && ((control.reg & 2) != 0)) b = reg[control.register_address_b]; if ((control.reg & 4) != 0) reg[control.register_address_c] = c; }