void Processor::execute() { StageBuffer buf; Result result; for (unsigned int i=0; i < instructions.size(); i++) { buf.rel.reset(); buf.address = -1; ID(buf); ALU(buf); if(buf.IR.isMemInstruction()) { currentMem = buf; result = applyAllRules(currentMem, prevMem); if(result != ignored) fout<< currentMem.PC+1 << ":" << prevMem.PC+1 << "=" << getStringFromResult(result) << "\n"; currentMem.amIdirty = reg[currentMem.IR.sReg1].dirtyNo; prevMem = currentMem; } PC++; } fout.close(); }
void CU() { trace; int tick_ignore; int current_instruction; int memory_contents; sc_instGet(¤t_instruction); log_debug(sformat("current_instruction %d", current_instruction)); sc_memoryGet(current_instruction, &memory_contents); int command; int operand; if (sc_commandDecode(memory_contents, &command, &operand)) { sc_regSet(FLAG_WRONG_COMMAND, 1); sc_regSet(FLAG_TICK_IGNORE, 1); trace; return; } ALU(command, operand); int had_overflow; sc_regGet(FLAG_OVERFLOW, &had_overflow); if (had_overflow) { trace; sc_regSet(FLAG_TICK_IGNORE, 1); return; } sc_regGet(FLAG_TICK_IGNORE, &tick_ignore); if (tick_ignore) { trace; return; } int new_instruction; sc_instGet(&new_instruction); if (new_instruction != current_instruction) { trace; return; } current_instruction++; if (current_instruction < 0 || current_instruction > 99) { trace; sc_regSet(FLAG_TICK_IGNORE, 1); return; } sc_instSet(current_instruction); }
#define RMW(type, op) SMP_OP_RMW_##type##_DECL(op) #define RMWW(op) SMP_OP_RMWW_DP_DECL(op) #define MOVE(dst, src) SMP_OP_MOVE_##dst##_DECL(src) #define MOVE_(dst, src) SMP_OP_MOVE_DECL(dst, src) #define BRANCH(flag) SMP_OP_BRANCH_FLAG_DECL(flag) #define BRANCH_N(flag) SMP_OP_BRANCH_N_FLAG_DECL(flag) smp_op_t ssnes_smp_optable[256] = { NOP, // 0x00 TCALL(0), // 0x01 SET1(0), // 0x02 BBS(0), // 0x03 ALU(DP, or), // 0x04 ALU(ADDR, or), // 0x05 ALU(DPX, or), // 0x06 ALU(IDPX, or), // 0x07 ALU(IMM, or), // 0x08 ALU(DP_DP, or), // 0x09 ALU(BIT, or1), // 0x0a RMW(DP, asl), // 0x0b RMW(ADDR, asl), // 0x0c smp_op_push_p, // 0x0d smp_op_rmw_tset, // 0x0e smp_op_brk, // 0x0f BRANCH_N(n), // 0x10 TCALL(1), // 0x11 CLR1(0), // 0x12
// Execute Cycle void Execute() { fprintf(stacktrace_file, "%2d\t%s\t%d\t%d", IR.line, OPS[IR.OP], IR.L, IR.M); switch(IR.OP) { case LIT: sp++; stack[sp] = IR.M; break; case OPR: ALU(IR); break; case LOD: sp++; stack[sp] = stack[base(IR.L, bp) + IR.M]; break; case STO: stack[base(IR.L, bp) + IR.M] = stack[sp]; sp--; break; case CAL: current_level++; pipes[current_level] = sp + 1; stack[sp + 1] = 0; stack[sp + 2] = base(IR.L, bp); stack[sp + 3] = bp; stack[sp + 4] = pc; bp = sp + 1; pc = IR.M; break; case INC: sp = sp + IR.M; break; case JMP: pc = IR.M; break; case JPC: if( stack[sp] == 0 ) { pc = IR.M; } sp--; break; case SIO1: fprintf(stacktrace_file, "%d\n", stack[sp]); sp--; break; case SIO2: sp++; scanf("%d", &stack[sp]); break; case SIO3: pc = 0; bp = 0; sp = 0; break; default: printf("Invalid Operation\n"); fprintf(stacktrace_file, "Invalid Operation\n"); HALT = true; } if(!HALT) { printPointers(); printStack(); } }
int main(int argc, char ** argv) { char * binfilename = NULL; char * srcfilename = NULL; char * base = NULL; int i, cycle; bus32 tmp; bus8 inst_mem[4096]; /* instruction memory */ bus8 main_mem[4096]; /* main memory */ bus32 gnd; /* ground bus signal */ bus32 pc; /* program counter */ bus32 pc4; /* PC + 4 bus */ bus32 ir; /* instruction register */ bus32 jmp_addr; /* jump bus */ bus32 imm_sext; /* immediate sign extended bus */ bus32 imm_shext; /* immediate sign extended shifted bus */ bus32 branch_addr; /* branch bus */ bus32 mbranch_addr; /* mbranch bus */ /* control unit signals */ wire reg_write, reg_dest; wire mem_read, mem_write, mem_toreg; wire jump, branch; wire alu_src; bus3 alu_op; /* register memory signals & controls */ bus32 reg_in, reg_out1, reg_out2; bus32 reg_write_addr; /* main memory signal */ bus32 mem_out; /* alu signals */ wire zero; bus32 alu_src_val, alu_out; if (argc == 1) { fprintf(stderr, "usage: %s <filename>\n", argv[0]); return -1; } srcfilename = argv[1]; base = _parse_filename(srcfilename); if (!base) return -1; binfilename = malloc(sizeof(char) * (strlen(base) + 5)); sprintf(binfilename, "%s.bin", base); printf("assembling %s to %s...\n", srcfilename, binfilename); if (!Assemble(srcfilename, binfilename)) return -1; printf("loading %s into memory...\n", binfilename); LoadMemory(binfilename, inst_mem); /* load PC with initial VM address of 0x00000000 */ setbus32(gnd, "00000000000000000000000000000000"); setbus32(pc, gnd); /* initialize memory */ InitializeRegisterFileAccess(); for (i=0; i < 4096; i++) setbus8(main_mem[i], "00000000"); for(cycle=0; ; cycle++) { /* load IR with PC value */ MemoryAccess(ir, pc, gnd, '0', inst_mem); /* report fetched register values */ printf("cycle: %d, PC: %.32s (%d), IR: %.32s\n\t", cycle, pc, bus32toint(pc), ir); /* halt check */ if (bus32toint(ir) == 0x0000003F) { printf("\nmachine halted\n"); break; } /* PC + 4 data path */ RCAdder_32(pc4, gnd, pc, "00000000000000000000000000000100", '0'); /* jump data path */ shiftleft2x(jmp_addr, ir); jmp_addr[0] = pc4[0]; jmp_addr[1] = pc4[1]; jmp_addr[2] = pc4[2]; jmp_addr[3] = pc4[3]; /* sign extended / shifted immediate data path */ signextend(imm_sext, &ir[16]); shiftleft2x(imm_shext, imm_sext); /* control unit data path */ ControlUnit(ir, &ir[26], ®_write, ®_dest, &mem_read, &mem_write, &mem_toreg, &jump, &branch, &alu_src, alu_op); /* register memory data path - read */ Mux2_5(reg_write_addr, &ir[11], &ir[16], reg_dest); RegisterFileAccess(®_out1, ®_out2, &ir[6], &ir[11], reg_write_addr, reg_in, '0'); /* alu data path */ Mux2_32(alu_src_val, reg_out2, imm_sext, alu_src); zero = ALU(&alu_out, reg_out1, alu_src_val, alu_op); /* branch data path */ RCAdder_32(branch_addr, gnd, pc4, imm_shext, '0'); Mux2_32(mbranch_addr, pc4, branch_addr, AND2_1(zero, branch)); Mux2_32(pc, mbranch_addr, jmp_addr, jump); /* main memory data path */ MemoryAccess(mem_out, alu_out, reg_out2, mem_write, main_mem); Mux2_32(reg_in, alu_out, mem_out, mem_toreg); /* register memory data path - write */ RegisterFileAccess(®_out1, ®_out2, &ir[6], &ir[11], reg_write_addr, reg_in, reg_write); /* dump register memory and signal information */ for (i=0; i < 14; i++) { inttobusn(i, 5, tmp); RegisterFileAccess(®_out1, ®_out2, tmp, &ir[11], reg_write_addr, reg_in, '0'); printf("R%d: %d, ", i, bus32toint(reg_out1)); } printf("\b\b\n\tbranch_addr = %.32s (%d) jmp_addr = %.32s (%d)\n", branch_addr, bus32toint(branch_addr), jmp_addr, bus32toint(jmp_addr)); printf("\topcode = %.6s, imm_sext = %.32s (%d), imm_shext = %.32s (%d), PC+4 = %.32s (%d)\n", ir, imm_sext, bus32toint(imm_sext), imm_shext, bus32toint(imm_shext), pc4, bus32toint(pc4)); printf("\treg_write = %c, reg_dest = %c, mem_read = %c, mem_write = %c, mem_toreg = %c, jump = %c, branch = %c, alu_src = %c, alu_op = %.3s, zero = %c\n", reg_write, reg_dest, mem_read, mem_write, mem_toreg, jump, branch, alu_src, alu_op, zero); getchar(); } printf("\ntotal no. cycles: %d\n", cycle); // report end of program information free(binfilename); }
void PE_base::CPU() { assert(!in_queue_.empty()); assert(in_queue_.size() == 2); //printf("ALU_IN0 = %lf, %lf\n", in_queue_.front().cplx_n.real, in_queue_.front().cplx_n.imaginary); //printf("ALU_IN1 = %lf, %lf\n", in_queue_.back().cplx_n.real, in_queue_.back().cplx_n.imaginary); packet tmp = in_queue_.front(); switch (tmp.info.layer) { case 0: //x switch (tmp.info.index) { case 0: ALU_in[0] = in_queue_.front().cplx_n; ALU_in[1] = in_queue_.back().cplx_n; ALU(0); CPU_out[0] = FSM_d[0]; CPU_out[1] = FSM_d[2]; break; case 1: ALU_in[0] = in_queue_.front().cplx_n; ALU_in[1] = in_queue_.back().cplx_n; ALU(0); CPU_out[0] = FSM_d[4]; CPU_out[1] = FSM_d[6]; break; case 2: ALU_in[0] = in_queue_.front().cplx_n; ALU_in[1] = in_queue_.back().cplx_n; ALU(0); CPU_out[0] = FSM_d[1]; CPU_out[1] = FSM_d[3]; break; case 3: ALU_in[0] = in_queue_.front().cplx_n; ALU_in[1] = in_queue_.back().cplx_n; ALU(0); CPU_out[0] = FSM_d[5]; CPU_out[1] = FSM_d[7]; break; case 4: ALU_in[1] = in_queue_.front().cplx_n; ALU_in[0] = in_queue_.back().cplx_n; ALU(0); CPU_out[0] = FSM_d[0]; CPU_out[1] = FSM_d[2]; break; case 5: ALU_in[1] = in_queue_.front().cplx_n; ALU_in[0] = in_queue_.back().cplx_n; ALU(0); CPU_out[0] = FSM_d[4]; CPU_out[1] = FSM_d[6]; break; case 6: ALU_in[1] = in_queue_.front().cplx_n; ALU_in[0] = in_queue_.back().cplx_n; ALU(0); CPU_out[0] = FSM_d[1]; CPU_out[1] = FSM_d[3]; break; case 7: ALU_in[1] = in_queue_.front().cplx_n; ALU_in[0] = in_queue_.back().cplx_n; ALU(0); CPU_out[0] = FSM_d[5]; CPU_out[1] = FSM_d[7]; break; default: printf("Impossible Index\n"); break; } break; case 1: //y switch (tmp.info.index) { case 0: ALU_in[0] = in_queue_.front().cplx_n; ALU_in[1] = in_queue_.back().cplx_n; ALU(0); CPU_out[0] = FSM_d[0]; CPU_out[1] = FSM_d[4]; break; case 1: ALU_in[0] = in_queue_.front().cplx_n; ALU_in[1] = in_queue_.back().cplx_n; ALU(2); CPU_out[0] = FSM_d[2]; CPU_out[1] = FSM_d[6]; break; case 2: ALU_in[1] = in_queue_.front().cplx_n; ALU_in[0] = in_queue_.back().cplx_n; ALU(0); CPU_out[0] = FSM_d[0]; CPU_out[1] = FSM_d[4]; break; case 3: ALU_in[1] = in_queue_.front().cplx_n; ALU_in[0] = in_queue_.back().cplx_n; ALU(2); CPU_out[0] = FSM_d[2]; CPU_out[1] = FSM_d[6]; break; case 4: ALU_in[0] = in_queue_.front().cplx_n; ALU_in[1] = in_queue_.back().cplx_n; ALU(0); CPU_out[0] = FSM_d[1]; CPU_out[1] = FSM_d[5]; break; case 5: ALU_in[0] = in_queue_.front().cplx_n; ALU_in[1] = in_queue_.back().cplx_n; ALU(2); CPU_out[0] = FSM_d[3]; CPU_out[1] = FSM_d[7]; break; case 6: ALU_in[1] = in_queue_.front().cplx_n; ALU_in[0] = in_queue_.back().cplx_n; ALU(0); CPU_out[0] = FSM_d[1]; CPU_out[1] = FSM_d[5]; break; case 7: ALU_in[1] = in_queue_.front().cplx_n; ALU_in[0] = in_queue_.back().cplx_n; ALU(2); CPU_out[0] = FSM_d[3]; CPU_out[1] = FSM_d[7]; break; default: printf("Impossible Index\n"); break; } break; case 2: //z switch (tmp.info.index) { case 0: ALU_in[0] = in_queue_.front().cplx_n; ALU_in[1] = in_queue_.back().cplx_n; ALU(0); CPU_out[0] = FSM_d[0]; CPU_out[1] = FSM_d[4]; break; case 1: ALU_in[0] = in_queue_.front().cplx_n; ALU_in[1] = in_queue_.back().cplx_n; ALU(2); CPU_out[0] = FSM_d[2]; CPU_out[1] = FSM_d[6]; break; case 2: ALU_in[0] = in_queue_.front().cplx_n; ALU_in[1] = in_queue_.back().cplx_n; ALU(1); CPU_out[0] = FSM_d[1]; CPU_out[1] = FSM_d[5]; break; case 3: ALU_in[0] = in_queue_.front().cplx_n; ALU_in[1] = in_queue_.back().cplx_n; ALU(3); CPU_out[0] = FSM_d[3]; CPU_out[1] = FSM_d[7]; break; case 4: ALU_in[1] = in_queue_.front().cplx_n; ALU_in[0] = in_queue_.back().cplx_n; ALU(0); CPU_out[0] = FSM_d[0]; CPU_out[1] = FSM_d[4]; break; case 5: ALU_in[1] = in_queue_.front().cplx_n; ALU_in[0] = in_queue_.back().cplx_n; ALU(2); CPU_out[0] = FSM_d[2]; CPU_out[1] = FSM_d[6]; break; case 6: ALU_in[1] = in_queue_.front().cplx_n; ALU_in[0] = in_queue_.back().cplx_n; ALU(1); CPU_out[0] = FSM_d[1]; CPU_out[1] = FSM_d[5]; break; case 7: ALU_in[1] = in_queue_.front().cplx_n; ALU_in[0] = in_queue_.back().cplx_n; ALU(3); CPU_out[0] = FSM_d[3]; CPU_out[1] = FSM_d[7]; break; default: printf("Impossible Index\n"); break; } break; default: printf("Impossible Layer\n"); break; } //FSM_Controller finished. ALU_out ready for pack-up }
int main () { int i; srand(time(NULL)); DEF_GENPAT("dpt_alu_genpat"); DECLAR("A" , ":2", "X", IN , "31 down to 0", ""); DECLAR("B" , ":2", "X", IN , "31 down to 0", ""); DECLAR("Ctrl", ":2", "X", IN , "2 down to 0", ""); DECLAR("Res" , ":2", "X", OUT, "31 down to 0", ""); DECLAR("Zero", ":2", "B", OUT, "", "" ); DECLAR("Vdd" , ":2", "B", IN , "", "" ); DECLAR("Vss" , ":2", "B", IN , "", "" ); LABEL ("ALU"); AFFECT("0", "Vdd", "0b1"); AFFECT("0", "Vss", "0b0"); // AND : Ctrl = 0 ALU(0x00000000, 0x00000000, 0); ALU(0x00000000, 0xFFFFFFFF, 0); ALU(0xFFFFFFFF, 0x00000000, 0); ALU(0xFFFFFFFF, 0xFFFFFFFF, 0); // OR : Ctrl = 1 ALU(0x00000000, 0x00000000, 1); ALU(0x00000000, 0xFFFFFFFF, 1); ALU(0xFFFFFFFF, 0x00000000, 1); ALU(0xFFFFFFFF, 0xFFFFFFFF, 1); // add : ctrl = 2 (0b010) ALU(0xFFFFFFFF, 1, 2); // test all carry bits, overflow and zero flag for(i = 0; i < 10; i++) { ALU(rand(), rand(), 2); } // A AND ~B : Ctrl = 4 ALU(0x00000000, 0x00000000, 4); ALU(0x00000000, 0xFFFFFFFF, 4); ALU(0xFFFFFFFF, 0x00000000, 4); ALU(0xFFFFFFFF, 0xFFFFFFFF, 4); // A OR ~B : Ctrl = 5 ALU(0x00000000, 0x00000000, 5); ALU(0x00000000, 0xFFFFFFFF, 5); ALU(0xFFFFFFFF, 0x00000000, 5); ALU(0xFFFFFFFF, 0xFFFFFFFF, 5); // sub : ctrl = 6 (0b110) ALU(0x0F0F0F0F, 0x00F00F00, 6); ALU(0xFFFFFFFF, 0xFFFFFFFF, 6); ALU(0x00000000, 0x00000001, 6); for(i = 0; i < 10; i++) { ALU(rand(), rand(), 6); } // slt : ctrl = 7 (0b111) ALU(-300, 255, 7); ALU(25, -30, 7); for(i = 0; i < 10; i++) { ALU(rand(), rand(), 7); } SAV_GENPAT(); return 0; }
#include <malloc.h> #include <string.h> #include <wiiu/gx2/common.h> #include "gx2_shader_inl.h" #include "menu_shaders.h" __attribute__((aligned(GX2_SHADER_ALIGNMENT))) static struct { u64 cf[32]; u64 alu[16]; } vs_program = { { CALL_FS NO_BARRIER, ALU(32,16) KCACHE0(CB1, _0_15), EXP_DONE(POS0, _R1,_x,_y,_z,_w), EXP_DONE(PARAM0, _R0,_m,_m,_m,_m) END_OF_PROGRAM }, { /* 0 */ ALU_MUL(__,_x, _R1,_w, KC0(3),_w), ALU_MUL(__,_y, _R1,_w, KC0(3),_z), ALU_MUL(__,_z, _R1,_w, KC0(3),_y), ALU_MUL(__,_w, _R1,_w, KC0(3),_x) ALU_LAST, /* 1 */ ALU_MULADD(_R123,_x, _R1,_z, KC0(2),_w, ALU_SRC_PV,_x), ALU_MULADD(_R123,_y, _R1,_z, KC0(2),_z, ALU_SRC_PV,_y), ALU_MULADD(_R123,_z, _R1,_z, KC0(2),_y, ALU_SRC_PV,_z),
//occurs in the fetch function AFTER //the instruction register gets instruction from code[PC] and PC is incremented void execute(Instruction IR) { //The Instruction Set switch(IR.op) { //LIT: Pushes literal value of IR.m onto the stack case 1: SP++; stack[SP] = IR.m; break; //OPR: if IR.m is 0, returns from procedure call case 2: if(IR.m == 0) { //new top of stack is 1 below the base of the current stack frame SP = BP - 1; //see case 5 --> stack[SP+4] contains the return address PC = stack[SP+4]; //see case 5 --> stack[SP+3] contains dynamic link //(base of stack frame where the procedure was called from) BP = stack[SP+3]; } //if IR.m is not 0, an ALU operation is performed else ALU(IR.m); break; //LOD: go IR.l levels down, read value at offset IR.m case 3: SP++; stack[SP] = stack[base(IR.l, BP) + IR.m]; break; //STO: go IR.l levels down, pop stack and store value at offset IR.m case 4: stack[base(IR.l, BP)+IR.m] = stack[SP]; SP--; break; //CAL: call procedure at IR.m //Generate Activation Record case 5: //Functional Value stack[SP+1] = 0; //Static Link (points to the frame of the current procedure's parent procedure) stack[SP+2] = base(IR.l, BP); //Dynamic Link (points to the caller's frame) stack[SP+3] = BP; //Return Address (instruction to be executed after current procedure ends) stack[SP+4] = PC; //new base of stack frame = 1 above the top of current stack frame BP = SP+1; //next instruction is a procedure at IR.m PC = IR.m; break; //INC: allocate space for IR.m local variables case 6: SP = SP + IR.m; break; //JMP: Next instruction will be at IR.m case 7: PC = IR.m; break; //JPC: pop, and if value is 0 --> branch to IR.m case 8: if(stack[SP] == 0) PC = IR.m; SP--; break; //SIO pop and write to screen case 9: printf("%d\n", stack[SP]); SP--; break; //SIO push value input from user case 10: SP++; scanf("%d", &stack[SP]); break; //SIO stop the machine (halt) case 11: PC = 0; SP = 0; BP = 0; HALT = 1; break; default: break; } }