diff --git a/.golangci.yml b/.golangci.yml index 71dced4..b77cddf 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -218,6 +218,13 @@ issues: - dupl - gosec + # Testbench main programs: skip strict checks to avoid unnecessary code churn + - path: test/testbench/ + linters: + - errcheck + - funlen + - lll + # Exclude known linters from partially hard-vendored code, # which is impossible to exclude via "nolint" comments. - path: internal/hmac/ diff --git a/config/config.go b/config/config.go index ea02b64..875f499 100644 --- a/config/config.go +++ b/config/config.go @@ -176,6 +176,7 @@ func (d DeviceBuilder) createTiles( ) { var exit = false var retVal = uint32(0) + var exitReqTimestamp = float64(0) for y := 0; y < d.height; y++ { dev.Tiles[y] = make([]*tile, d.width) for x := 0; x < d.width; x++ { @@ -186,6 +187,7 @@ func (d DeviceBuilder) createTiles( WithFreq(d.freq). WithExitAddr(&exit). WithRetValAddr(&retVal). + WithExitReqAddr(&exitReqTimestamp). Build(coreName) if d.monitor != nil { diff --git a/core/builder.go b/core/builder.go index 8025a48..e6c3a9d 100644 --- a/core/builder.go +++ b/core/builder.go @@ -7,10 +7,11 @@ import ( // Builder can create new cores. type Builder struct { - engine sim.Engine - freq sim.Freq - exitAddr *bool - retValAddr *uint32 + engine sim.Engine + freq sim.Freq + exitAddr *bool + retValAddr *uint32 + exitReqAddr *float64 } // WithEngine sets the engine. @@ -37,6 +38,11 @@ func (b Builder) WithRetValAddr(retValAddr *uint32) Builder { return b } +func (b Builder) WithExitReqAddr(exitReqAddr *float64) Builder { + b.exitReqAddr = exitReqAddr + return b +} + // Build creates a core. // //nolint:funlen @@ -48,10 +54,11 @@ func (b Builder) Build(name string) *Core { CareFlags: true, } c.state = coreState{ - exit: b.exitAddr, - retVal: b.retValAddr, - SelectedBlock: nil, - PCInBlock: -1, + exit: b.exitAddr, + retVal: b.retValAddr, + requestExitTimestamp: b.exitReqAddr, + SelectedBlock: nil, + PCInBlock: -1, Directions: map[string]bool{ "North": true, "East": true, @@ -87,8 +94,6 @@ func (b Builder) Build(name string) *Core { c.state.SendBufHeadBusy[i] = make([]bool, 12) } - c.state.States["Phiconst"] = false - c.ports = make(map[cgra.Side]*portPair) b.makePort(c, cgra.North) diff --git a/core/emu.go b/core/emu.go index 2eb4dfb..dfda1e9 100644 --- a/core/emu.go +++ b/core/emu.go @@ -15,7 +15,10 @@ import ( type OpMode int const ( - // SyncOp executes one instruction group synchronously. + ExitDelay = 100 +) + +const ( SyncOp OpMode = iota // AsyncOp executes operations asynchronously with reservation tracking. AsyncOp @@ -81,15 +84,16 @@ func (r *ReservationState) SetReservationMap(ig InstructionGroup, state *coreSta } type coreState struct { - exit *bool // the signal is shared between cores - retVal *uint32 // the value is shared between cores - SelectedBlock *EntryBlock - Directions map[string]bool - PCInBlock int32 - NextPCInBlock int32 - TileX, TileY uint32 - Registers []cgra.Data - States map[string]interface{} // This is to store core states, such as Phiconst, CmpFlags + exit *bool // the signal is shared between cores + requestExitTimestamp *float64 + retVal *uint32 // the value is shared between cores + SelectedBlock *EntryBlock + Directions map[string]bool + PCInBlock int32 + NextPCInBlock int32 + TileX, TileY uint32 + Registers []cgra.Data + States map[string]interface{} // This is to store core states, such as Phiconst, CmpFlags // still consider using outside block to control pc //Code [][]string Memory []uint32 @@ -129,7 +133,8 @@ func (i instEmulator) SetUpInstructionGroup(index int32, state *coreState) { func (i instEmulator) RunInstructionGroup(cinst InstructionGroup, state *coreState, time float64) bool { // check the Return signal - if *state.exit { + if *state.exit && time > *state.requestExitTimestamp { + fmt.Println("Exit signal ( requested at", *state.requestExitTimestamp, ") received at time", time) return false } prevPC := state.PCInBlock @@ -213,6 +218,8 @@ func (i instEmulator) RunInstructionGroupWithSyncOps(cinst InstructionGroup, sta } } if run { + // Collect all results first + allResults := make(map[Operand]cgra.Data) for index := range cinst.Operations { // Get reference to the original operation in state.SelectedBlock operation := &state.SelectedBlock.InstructionGroups[state.PCInBlock].Operations[index] @@ -222,14 +229,24 @@ func (i instEmulator) RunInstructionGroupWithSyncOps(cinst InstructionGroup, sta operation.InvalidIterations-- continue } - i.RunOperation(*operation, state, time) + results := i.RunOperation(*operation, state, time) + // Merge results into allResults + for operand, value := range results { + allResults[operand] = value + } //print("RunOperation", operation.OpCode, "@(", state.TileX, ",", state.TileY, ")", time, ":", "YES", "\n") } + // Write all results at once + for operand, value := range allResults { + i.writeOperand(operand, value, state) + } } return run } func (i instEmulator) RunInstructionGroupWithAsyncOps(cinst InstructionGroup, state *coreState, time float64) { + // Collect all results first + allResults := make(map[Operand]cgra.Data) for index := range cinst.Operations { // check all the operations in the instruction group and if any is ready, then run if !state.CurrReservationState.ReservationMap[index] { @@ -246,12 +263,20 @@ func (i instEmulator) RunInstructionGroupWithAsyncOps(cinst InstructionGroup, st operation.InvalidIterations-- continue } - i.RunOperation(*operation, state, time) + results := i.RunOperation(*operation, state, time) + // Merge results into allResults + for operand, value := range results { + allResults[operand] = value + } //print("RunOperation", operation.OpCode, "@(", state.TileX, ",", state.TileY, ")", time, ":", "YES", "\n") } else { //print("CheckFlags (", state.TileX, ",", state.TileY, ")", time, ":", "NO", "\n") } } + // Write all results at once + for operand, value := range allResults { + i.writeOperand(operand, value, state) + } } func (i instEmulator) normalizeDirection(s string) string { @@ -286,8 +311,16 @@ func (i instEmulator) CheckFlags(inst Operation, state *coreState) bool { for index, src := range inst.SrcOperands.Operands { if index == 1 { if inst.OpCode == "PHI_CONST" || inst.OpCode == "PHI_START" { - if state.States["Phiconst"] == false { // first execution + // Track PHI_CONST per instruction to avoid cross-interference. + var stateKey string + if inst.OpCode == "PHI_CONST" { + stateKey = fmt.Sprintf("PhiConst_%d", inst.ID) + } else if inst.OpCode == "PHI_START" { + stateKey = fmt.Sprintf("PhiStart_%d", inst.ID) + } + if state.States[stateKey] == nil || state.States[stateKey] == false { // first execution if len(inst.SrcOperands.Operands) > 1 { + fmt.Println("ID", inst.ID, "bypass check") continue } else { panic("PHI_CONST or PHI_START must have two sources") @@ -314,11 +347,11 @@ func (i instEmulator) CheckFlags(inst Operation, state *coreState) bool { } } //fmt.Println("[CheckFlags] checking flags for inst", inst.OpCode, "@(", state.TileX, ",", state.TileY, "):", flag) - fmt.Println("Check", inst.OpCode, "@(", state.TileX, ",", state.TileY, "):", flag) + fmt.Println("Check", inst.OpCode, "ID", inst.ID, "@(", state.TileX, ",", state.TileY, "):", flag) return flag } -func (i instEmulator) RunOperation(inst Operation, state *coreState, time float64) { +func (i instEmulator) RunOperation(inst Operation, state *coreState, time float64) map[Operand]cgra.Data { state.CurrentTime = time // Note: InvalidIterations is now handled in RunInstructionGroupWithSyncOps @@ -336,29 +369,25 @@ func (i instEmulator) RunOperation(inst Operation, state *coreState, time float6 // i.runAlwaysSendRec(tokens, state) // } - instFuncs := map[string]func(Operation, *coreState){ - "ADD": i.runAdd, // ADD, ADDI, INC, SUB, DEC - "SUB": i.runSub, - "LLS": i.runLLS, - "SHL": i.runLLS, // SHL is an alias for LLS - "LRS": i.runLRS, - "MUL": i.runMul, // MULI - "MUL_ADD": i.runMulAdd, // dst = src0 * src1 + src2 (systolic MAC) - "DIV": i.runDiv, - "OR": i.runOR, - "XOR": i.runXOR, // XOR XORI - "AND": i.runAND, - "MOV": i.runMov, - "JMP": i.runJmp, - "BNE": i.runBne, - "BEQ": i.runBeq, // BEQI - "BLT": i.runBlt, - "RETURN_VALUE": i.runRet, - "RETURN_VOID": i.runRet, - "RET": i.runRet, // backward compatibility - "PHI_CONST": i.runPhiConst, // backward compatibility - "SEXT": i.runMov, // identity operation by now - "ZEXT": i.runMov, // identity operation by now + instFuncs := map[string]func(Operation, *coreState) map[Operand]cgra.Data{ + "ADD": i.runAdd, // ADD, ADDI, INC, SUB, DEC + "SUB": i.runSub, + "SHL": i.runSHL, + "LRS": i.runLRS, + "MUL": i.runMul, // MULI + "MUL_ADD": i.runMulAdd, // dst = src0 * src1 + src2 + "DIV": i.runDiv, + "OR": i.runOR, + "XOR": i.runXOR, // XOR XORI + "AND": i.runAND, + "MOV": i.runMov, + "JMP": i.runJmp, + "BNE": i.runBne, + "BEQ": i.runBeq, // BEQI + "BLT": i.runBlt, + "PHI_CONST": i.runPhiConst, // backward compatibility + "SEXT": i.runMov, // identity operation by now + "ZEXT": i.runMov, // identity operation by now "FADD": i.runFAdd, // FADDI "FSUB": i.runFSub, @@ -366,14 +395,16 @@ func (i instEmulator) RunOperation(inst Operation, state *coreState, time float6 "NOP": i.runNOP, "PHI": i.runPhi, - "PHI_START": i.runPhiConst, + "PHI_START": i.runPhiStart, "GRANT_PREDICATE": i.runGrantPred, "GRANT_ONCE": i.runGrantOnce, + "SEL": i.runSel, // comparisons "ICMP_EQ": i.runCmpExport, "ICMP_SLT": i.runLTExport, "ICMP_SGT": i.runGTExport, + "ICMP_SGE": i.runSGEExport, // do not distinguish between data_mov and control mov "DATA_MOV": i.runMov, @@ -402,8 +433,16 @@ func (i instEmulator) RunOperation(inst Operation, state *coreState, time float6 "NOT": i.runNot, } + retFuncs := map[string]func(Operation, *coreState, float64) map[Operand]cgra.Data{ + "RETURN_VALUE": i.runRetImm, + "RETURN_VOID": i.runRetDelay, + "RET": i.runRetImm, // backward compatibility + } + if instFunc, ok := instFuncs[instName]; ok { - instFunc(inst, state) + return instFunc(inst, state) + } else if retFunc, ok := retFuncs[instName]; ok { + return retFunc(inst, state, time) } else { panic(fmt.Sprintf("unknown instruction '%s' at PC %d", instName, state.PCInBlock)) } @@ -566,22 +605,25 @@ func uint2Float(u uint32) float32 { // runMov handles the MOV instruction for both immediate values and register-to-register moves. // Prototype for moving an immediate: MOV, DstReg, Immediate // Prototype for register to register: MOV, DstReg, SrcReg -func (i instEmulator) runMov(inst Operation, state *coreState) { +func (i instEmulator) runMov(inst Operation, state *coreState) map[Operand]cgra.Data { src := inst.SrcOperands.Operands[0] oprStruct := i.readOperand(src, state) opr := oprStruct.First() finalPred := oprStruct.Pred - // Write the value into the destination register + // Collect results for destination operands + results := make(map[Operand]cgra.Data) for _, dst := range inst.DstOperands.Operands { - i.writeOperand(dst, cgra.NewScalarWithPred(opr, finalPred), state) + results[dst] = cgra.NewScalarWithPred(opr, finalPred) } Trace("Inst", "Time", state.CurrentTime, "OpCode", inst.OpCode, "ID", inst.ID, "X", state.TileX, "Y", state.TileY, "Pred", finalPred) + return results } -func (i instEmulator) runGep(inst Operation, state *coreState) { +func (i instEmulator) runGep(inst Operation, state *coreState) map[Operand]cgra.Data { + results := make(map[Operand]cgra.Data) if len(inst.SrcOperands.Operands) == 0 { - return + return results } src1 := inst.SrcOperands.Operands[0] @@ -596,21 +638,26 @@ func (i instEmulator) runGep(inst Operation, state *coreState) { src2Val := src2Struct.First() dstVal = src1Val + src2Val finalPred = src1Struct.Pred && src2Struct.Pred + + Trace("Inst", "Time", state.CurrentTime, "OpCode", inst.OpCode, "ID", inst.ID, "X", state.TileX, "Y", state.TileY, "Src1", fmt.Sprintf("%d(%t)", src1Val, src1Struct.Pred), "Src2", fmt.Sprintf("%d(%t)", src2Val, src2Struct.Pred), "Result", fmt.Sprintf("%d(%t)", dstVal, finalPred)) } for _, dst := range inst.DstOperands.Operands { - i.writeOperand(dst, cgra.NewScalarWithPred(dstVal, finalPred), state) + results[dst] = cgra.NewScalarWithPred(dstVal, finalPred) } - Trace("Inst", "Time", state.CurrentTime, "OpCode", inst.OpCode, "ID", inst.ID, "X", state.TileX, "Y", state.TileY, "Pred", finalPred) + Trace("Inst", "Time", state.CurrentTime, "OpCode", inst.OpCode, "ID", inst.ID, "X", state.TileX, "Y", state.TileY, "Src1", fmt.Sprintf("%d(%t)", src1Val, src1Struct.Pred), "Result", fmt.Sprintf("%d(%t)", dstVal, finalPred)) + + return results } -func (i instEmulator) runNOP(inst Operation, state *coreState) { +func (i instEmulator) runNOP(inst Operation, state *coreState) map[Operand]cgra.Data { // do nothing Trace("Inst", "OpCode", inst.OpCode, "ID", inst.ID, "X", state.TileX, "Y", state.TileY, "Pred", false) + return make(map[Operand]cgra.Data) } -func (i instEmulator) runNot(inst Operation, state *coreState) { +func (i instEmulator) runNot(inst Operation, state *coreState) map[Operand]cgra.Data { src := inst.SrcOperands.Operands[0] srcStruct := i.readOperand(src, state) srcVal := srcStruct.First() @@ -623,13 +670,15 @@ func (i instEmulator) runNot(inst Operation, state *coreState) { result = 0 } finalPred := srcPred + results := make(map[Operand]cgra.Data) for _, dst := range inst.DstOperands.Operands { - i.writeOperand(dst, cgra.NewScalarWithPred(result, finalPred), state) + results[dst] = cgra.NewScalarWithPred(result, finalPred) } Trace("Inst", "Time", state.CurrentTime, "OpCode", inst.OpCode, "ID", inst.ID, "X", state.TileX, "Y", state.TileY, "Pred", finalPred) + return results } -func (i instEmulator) runLoadDirect(inst Operation, state *coreState) { +func (i instEmulator) runLoadDirect(inst Operation, state *coreState) map[Operand]cgra.Data { src1 := inst.SrcOperands.Operands[0] addrStruct := i.readOperand(src1, state) addr := addrStruct.First() @@ -640,20 +689,23 @@ func (i instEmulator) runLoadDirect(inst Operation, state *coreState) { value := state.Memory[addr] slog.Warn("Memory", "Behavior", "LoadDirect", + "ID", inst.ID, "Value", value, "Addr", addr, "X", state.TileX, "Y", state.TileY, ) finalPred := addrStruct.Pred + results := make(map[Operand]cgra.Data) for _, dst := range inst.DstOperands.Operands { - i.writeOperand(dst, cgra.NewScalarWithPred(value, finalPred), state) + results[dst] = cgra.NewScalarWithPred(value, finalPred) } - Trace("Inst", "Time", state.CurrentTime, "OpCode", inst.OpCode, "ID", inst.ID, "X", state.TileX, "Y", state.TileY, "Pred", finalPred) + //Trace("Inst", "Time", state.CurrentTime, "OpCode", inst.OpCode, "ID", inst.ID, "X", state.TileX, "Y", state.TileY, "Pred", finalPred) // elect no next PC + return results } -func (i instEmulator) runLoadDRAM(inst Operation, state *coreState) { +func (i instEmulator) runLoadDRAM(inst Operation, state *coreState) map[Operand]cgra.Data { src1 := inst.SrcOperands.Operands[0] addrStruct := i.readOperand(src1, state) addr := addrStruct.First() @@ -669,15 +721,17 @@ func (i instEmulator) runLoadDRAM(inst Operation, state *coreState) { "Y", state.TileY, ) finalPred := addrStruct.Pred + results := make(map[Operand]cgra.Data) for _, dst := range inst.DstOperands.Operands { - i.writeOperand(dst, cgra.NewScalarWithPred(addr, finalPred), state) + results[dst] = cgra.NewScalarWithPred(addr, finalPred) } Trace("Inst", "Time", state.CurrentTime, "OpCode", inst.OpCode, "ID", inst.ID, "X", state.TileX, "Y", state.TileY, "Pred", finalPred) state.AddrBuf = addr state.IsToWriteMemory = false // not for write memory + return results } -func (i instEmulator) runLoadWaitDRAM(inst Operation, state *coreState) { +func (i instEmulator) runLoadWaitDRAM(inst Operation, state *coreState) map[Operand]cgra.Data { src := inst.SrcOperands.Operands[0] if src.Impl != "Router" { panic("the source of a LOAD_WAIT_DRAM instruction must be Router") @@ -685,13 +739,15 @@ func (i instEmulator) runLoadWaitDRAM(inst Operation, state *coreState) { valueStruct := i.readOperand(src, state) value := valueStruct.First() finalPred := valueStruct.Pred + results := make(map[Operand]cgra.Data) for _, dst := range inst.DstOperands.Operands { - i.writeOperand(dst, cgra.NewScalarWithPred(value, finalPred), state) + results[dst] = cgra.NewScalarWithPred(value, finalPred) } Trace("Inst", "Time", state.CurrentTime, "OpCode", inst.OpCode, "ID", inst.ID, "X", state.TileX, "Y", state.TileY, "Pred", finalPred) + return results } -func (i instEmulator) runStoreDirect(inst Operation, state *coreState) { +func (i instEmulator) runStoreDirect(inst Operation, state *coreState) map[Operand]cgra.Data { src1 := inst.SrcOperands.Operands[0] valueStruct := i.readOperand(src1, state) value := valueStruct.First() @@ -699,7 +755,7 @@ func (i instEmulator) runStoreDirect(inst Operation, state *coreState) { addrStruct := i.readOperand(src2, state) addr := addrStruct.First() if addr >= uint32(len(state.Memory)) { - panic("memory address out of bounds") + panic("memory address out of bounds, addr: " + strconv.Itoa(int(addr)) + ", len(state.Memory): " + strconv.Itoa(len(state.Memory))) } slog.Warn("Memory", "Behavior", "StoreDirect", @@ -712,9 +768,10 @@ func (i instEmulator) runStoreDirect(inst Operation, state *coreState) { finalPred := addrStruct.Pred && valueStruct.Pred Trace("Inst", "Time", state.CurrentTime, "OpCode", inst.OpCode, "ID", inst.ID, "X", state.TileX, "Y", state.TileY, "Pred", finalPred) // elect no next PC + return make(map[Operand]cgra.Data) } -func (i instEmulator) runStoreDRAM(inst Operation, state *coreState) { +func (i instEmulator) runStoreDRAM(inst Operation, state *coreState) map[Operand]cgra.Data { src1 := inst.SrcOperands.Operands[0] addrStruct := i.readOperand(src1, state) addr := addrStruct.First() @@ -734,29 +791,33 @@ func (i instEmulator) runStoreDRAM(inst Operation, state *coreState) { "Y", state.TileY, ) finalPred := addrStruct.Pred && valueStruct.Pred + results := make(map[Operand]cgra.Data) for _, dst := range inst.DstOperands.Operands { - i.writeOperand(dst, cgra.NewScalarWithPred(value, finalPred), state) + results[dst] = cgra.NewScalarWithPred(value, finalPred) } Trace("Inst", "Time", state.CurrentTime, "OpCode", inst.OpCode, "ID", inst.ID, "X", state.TileX, "Y", state.TileY, "Pred", finalPred) state.AddrBuf = addr state.IsToWriteMemory = true // for write memory + return results } -func (i instEmulator) runStoreWaitDRAM(inst Operation, state *coreState) { +func (i instEmulator) runStoreWaitDRAM(inst Operation, state *coreState) map[Operand]cgra.Data { src := inst.SrcOperands.Operands[0] if src.Impl != "Router" { panic("the source of a STORE_WAIT_DRAM instruction must be Router") } srcStruct := i.readOperand(src, state) // do nothing, only get the write done Trace("Inst", "OpCode", inst.OpCode, "ID", inst.ID, "X", state.TileX, "Y", state.TileY, "Pred", srcStruct.Pred) + return make(map[Operand]cgra.Data) } -func (i instEmulator) runTrigger(inst Operation, state *coreState) { +func (i instEmulator) runTrigger(inst Operation, state *coreState) map[Operand]cgra.Data { src := inst.SrcOperands.Operands[0] srcStruct := i.readOperand(src, state) // just consume a operand and do nothing Trace("Inst", "OpCode", inst.OpCode, "ID", inst.ID, "X", state.TileX, "Y", state.TileY, "Pred", srcStruct.Pred) // elect no next PC + return make(map[Operand]cgra.Data) } func (i instEmulator) parseAndCompareI(inst Operation, state *coreState) { @@ -825,7 +886,7 @@ func (i instEmulator) parseAndCompareF32(inst Operation, state *coreState) { // elect no next PC } -func (i instEmulator) runAdd(inst Operation, state *coreState) { +func (i instEmulator) runAdd(inst Operation, state *coreState) map[Operand]cgra.Data { src1 := inst.SrcOperands.Operands[0] src2 := inst.SrcOperands.Operands[1] src1Struct := i.readOperand(src1, state) @@ -838,14 +899,16 @@ func (i instEmulator) runAdd(inst Operation, state *coreState) { dstVal := uint32(dstValSigned) finalPred := src1Struct.Pred && src2Struct.Pred //fmt.Printf("IADD: Adding %d (src1) + %d (src2) = %d\n", src1Signed, src2Signed, dstValSigned) + results := make(map[Operand]cgra.Data) for _, dst := range inst.DstOperands.Operands { - i.writeOperand(dst, cgra.NewScalarWithPred(dstVal, finalPred), state) + results[dst] = cgra.NewScalarWithPred(dstVal, finalPred) } - Trace("Inst", "Time", state.CurrentTime, "OpCode", inst.OpCode, "ID", inst.ID, "X", state.TileX, "Y", state.TileY, "Pred", finalPred) + Trace("Inst", "Time", state.CurrentTime, "OpCode", inst.OpCode, "ID", inst.ID, "X", state.TileX, "Y", state.TileY, "Src1", fmt.Sprintf("%d(%t)", src1Val, src1Struct.Pred), "Src2", fmt.Sprintf("%d(%t)", src2Val, src2Struct.Pred), "Result", fmt.Sprintf("%d(%t)", dstVal, finalPred)) // elect no next PC + return results } -func (i instEmulator) runSub(inst Operation, state *coreState) { +func (i instEmulator) runSub(inst Operation, state *coreState) map[Operand]cgra.Data { src1 := inst.SrcOperands.Operands[0] src2 := inst.SrcOperands.Operands[1] src1Struct := i.readOperand(src1, state) @@ -861,14 +924,16 @@ func (i instEmulator) runSub(inst Operation, state *coreState) { fmt.Printf("ISUB: Subtracting %d (src1) - %d (src2) = %d\n", src1Signed, src2Signed, dstValSigned) finalPred := src1Struct.Pred && src2Struct.Pred + results := make(map[Operand]cgra.Data) for _, dst := range inst.DstOperands.Operands { - i.writeOperand(dst, cgra.NewScalarWithPred(dstVal, finalPred), state) + results[dst] = cgra.NewScalarWithPred(dstVal, finalPred) } Trace("Inst", "Time", state.CurrentTime, "OpCode", inst.OpCode, "ID", inst.ID, "X", state.TileX, "Y", state.TileY, "Pred", finalPred) // elect no next PC + return results } -func (i instEmulator) runMul(inst Operation, state *coreState) { +func (i instEmulator) runMul(inst Operation, state *coreState) map[Operand]cgra.Data { src1 := inst.SrcOperands.Operands[0] src2 := inst.SrcOperands.Operands[1] @@ -884,14 +949,16 @@ func (i instEmulator) runMul(inst Operation, state *coreState) { dstVal := uint32(dstValSigned) finalPred := src1Struct.Pred && src2Struct.Pred + results := make(map[Operand]cgra.Data) for _, dst := range inst.DstOperands.Operands { - i.writeOperand(dst, cgra.NewScalarWithPred(dstVal, finalPred), state) + results[dst] = cgra.NewScalarWithPred(dstVal, finalPred) } - Trace("Inst", "Time", state.CurrentTime, "OpCode", inst.OpCode, "ID", inst.ID, "X", state.TileX, "Y", state.TileY, "Pred", finalPred) + Trace("Inst", "Time", state.CurrentTime, "OpCode", inst.OpCode, "ID", inst.ID, "X", state.TileX, "Y", state.TileY, "Src1", fmt.Sprintf("%d(%t)", src1Val, src1Struct.Pred), "Src2", fmt.Sprintf("%d(%t)", src2Val, src2Struct.Pred), "Result", fmt.Sprintf("%d(%t)", dstVal, finalPred)) // elect no next PC + return results } -func (i instEmulator) runMulAdd(inst Operation, state *coreState) { +func (i instEmulator) runMulAdd(inst Operation, state *coreState) map[Operand]cgra.Data { // MUL_ADD: dst = src0 * src1 + src2 (systolic MAC: psum += activation * weight) src0 := inst.SrcOperands.Operands[0] src1 := inst.SrcOperands.Operands[1] @@ -908,13 +975,15 @@ func (i instEmulator) runMulAdd(inst Operation, state *coreState) { dstVal := uint32(dstValSigned) finalPred := s0.Pred && s1.Pred && s2.Pred + results := make(map[Operand]cgra.Data) for _, dst := range inst.DstOperands.Operands { - i.writeOperand(dst, cgra.NewScalarWithPred(dstVal, finalPred), state) + results[dst] = cgra.NewScalarWithPred(dstVal, finalPred) } Trace("Inst", "Time", state.CurrentTime, "OpCode", inst.OpCode, "ID", inst.ID, "X", state.TileX, "Y", state.TileY, "Pred", finalPred) + return results } -func (i instEmulator) runDiv(inst Operation, state *coreState) { +func (i instEmulator) runDiv(inst Operation, state *coreState) map[Operand]cgra.Data { src1 := inst.SrcOperands.Operands[0] src2 := inst.SrcOperands.Operands[1] @@ -936,15 +1005,17 @@ func (i instEmulator) runDiv(inst Operation, state *coreState) { dstVal := uint32(dstValSigned) finalPred := src1Struct.Pred && src2Struct.Pred + results := make(map[Operand]cgra.Data) for _, dst := range inst.DstOperands.Operands { - i.writeOperand(dst, cgra.NewScalarWithPred(dstVal, finalPred), state) + results[dst] = cgra.NewScalarWithPred(dstVal, finalPred) } Trace("Inst", "Time", state.CurrentTime, "OpCode", inst.OpCode, "ID", inst.ID, "X", state.TileX, "Y", state.TileY, "Pred", finalPred) // fmt.Printf("DIV Instruction, Data are %d and %d, Res is %d\n", src1Signed, src2Signed, dstValSigned) // elect no next PC + return results } -func (i instEmulator) runLLS(inst Operation, state *coreState) { +func (i instEmulator) runSHL(inst Operation, state *coreState) map[Operand]cgra.Data { src := inst.SrcOperands.Operands[0] shiftStr := inst.SrcOperands.Operands[1] @@ -955,15 +1026,17 @@ func (i instEmulator) runLLS(inst Operation, state *coreState) { result := srcVal << shiftStrVal finalPred := srcStruct.Pred && shiftStrStruct.Pred + results := make(map[Operand]cgra.Data) for _, dst := range inst.DstOperands.Operands { - i.writeOperand(dst, cgra.NewScalarWithPred(result, finalPred), state) + results[dst] = cgra.NewScalarWithPred(result, finalPred) } Trace("Inst", "Time", state.CurrentTime, "OpCode", inst.OpCode, "ID", inst.ID, "X", state.TileX, "Y", state.TileY, "Pred", finalPred) //fmt.Printf("LLS: %s = %s << %d => Result: %d\n", dst, src, shift, result) // elect no next PC + return results } -func (i instEmulator) runLRS(inst Operation, state *coreState) { +func (i instEmulator) runLRS(inst Operation, state *coreState) map[Operand]cgra.Data { src := inst.SrcOperands.Operands[0] shiftStr := inst.SrcOperands.Operands[1] @@ -974,15 +1047,17 @@ func (i instEmulator) runLRS(inst Operation, state *coreState) { result := srcVal >> shiftStrVal finalPred := srcStruct.Pred && shiftStrStruct.Pred + results := make(map[Operand]cgra.Data) for _, dst := range inst.DstOperands.Operands { - i.writeOperand(dst, cgra.NewScalarWithPred(result, finalPred), state) + results[dst] = cgra.NewScalarWithPred(result, finalPred) } Trace("Inst", "Time", state.CurrentTime, "OpCode", inst.OpCode, "ID", inst.ID, "X", state.TileX, "Y", state.TileY, "Pred", finalPred) //fmt.Printf("LRS: %s = %s >> %d => Result: %d\n", dst, src, shift, result) // elect no next PC + return results } -func (i instEmulator) runOR(inst Operation, state *coreState) { +func (i instEmulator) runOR(inst Operation, state *coreState) map[Operand]cgra.Data { src1 := inst.SrcOperands.Operands[0] src2 := inst.SrcOperands.Operands[1] @@ -992,15 +1067,17 @@ func (i instEmulator) runOR(inst Operation, state *coreState) { srcVal2 := src2Struct.First() result := srcVal1 | srcVal2 finalPred := src1Struct.Pred && src2Struct.Pred + results := make(map[Operand]cgra.Data) for _, dst := range inst.DstOperands.Operands { - i.writeOperand(dst, cgra.NewScalarWithPred(result, finalPred), state) + results[dst] = cgra.NewScalarWithPred(result, finalPred) } Trace("Inst", "Time", state.CurrentTime, "OpCode", inst.OpCode, "ID", inst.ID, "X", state.TileX, "Y", state.TileY, "Pred", finalPred) //fmt.Printf("OR: %s = %s | %s => Result: %d\n", dst, src1, src2, result) // elect no next PC + return results } -func (i instEmulator) runXOR(inst Operation, state *coreState) { +func (i instEmulator) runXOR(inst Operation, state *coreState) map[Operand]cgra.Data { src1 := inst.SrcOperands.Operands[0] src2 := inst.SrcOperands.Operands[1] @@ -1010,15 +1087,17 @@ func (i instEmulator) runXOR(inst Operation, state *coreState) { srcVal2 := src2Struct.First() result := srcVal1 ^ srcVal2 finalPred := src1Struct.Pred && src2Struct.Pred + results := make(map[Operand]cgra.Data) for _, dst := range inst.DstOperands.Operands { - i.writeOperand(dst, cgra.NewScalarWithPred(result, finalPred), state) + results[dst] = cgra.NewScalarWithPred(result, finalPred) } Trace("Inst", "Time", state.CurrentTime, "OpCode", inst.OpCode, "ID", inst.ID, "X", state.TileX, "Y", state.TileY, "Pred", finalPred) //fmt.Printf("XOR: %s = %s ^ %s => Result: %d\n", dst, src1, src2, result) // elect no next PC + return results } -func (i instEmulator) runAND(inst Operation, state *coreState) { +func (i instEmulator) runAND(inst Operation, state *coreState) map[Operand]cgra.Data { src1 := inst.SrcOperands.Operands[0] src2 := inst.SrcOperands.Operands[1] @@ -1028,27 +1107,30 @@ func (i instEmulator) runAND(inst Operation, state *coreState) { srcVal2 := src2Struct.First() result := srcVal1 & srcVal2 finalPred := src1Struct.Pred && src2Struct.Pred + results := make(map[Operand]cgra.Data) for _, dst := range inst.DstOperands.Operands { - i.writeOperand(dst, cgra.NewScalarWithPred(result, finalPred), state) + results[dst] = cgra.NewScalarWithPred(result, finalPred) } Trace("Inst", "Time", state.CurrentTime, "OpCode", inst.OpCode, "ID", inst.ID, "X", state.TileX, "Y", state.TileY, "Pred", finalPred) //fmt.Printf("AND: %s = %s & %s => Result: %d\n", dst, src1, src2, result) // elect no next PC + return results } func (i instEmulator) Jump(dst uint32, state *coreState) { state.NextPCInBlock = int32(dst) } -func (i instEmulator) runJmp(inst Operation, state *coreState) { +func (i instEmulator) runJmp(inst Operation, state *coreState) map[Operand]cgra.Data { src := inst.SrcOperands.Operands[0] srcStruct := i.readOperand(src, state) srcVal := srcStruct.First() i.Jump(srcVal, state) Trace("Inst", "OpCode", inst.OpCode, "ID", inst.ID, "X", state.TileX, "Y", state.TileY, "Pred", srcStruct.Pred) + return make(map[Operand]cgra.Data) } -func (i instEmulator) runBeq(inst Operation, state *coreState) { +func (i instEmulator) runBeq(inst Operation, state *coreState) map[Operand]cgra.Data { // not safe in new scenario src := inst.SrcOperands.Operands[0] imme := inst.SrcOperands.Operands[1] @@ -1063,9 +1145,10 @@ func (i instEmulator) runBeq(inst Operation, state *coreState) { i.Jump(srcVal, state) } Trace("Inst", "Time", state.CurrentTime, "OpCode", inst.OpCode, "ID", inst.ID, "X", state.TileX, "Y", state.TileY, "Pred", finalPred) + return make(map[Operand]cgra.Data) } -func (i instEmulator) runBne(inst Operation, state *coreState) { +func (i instEmulator) runBne(inst Operation, state *coreState) map[Operand]cgra.Data { // not safe in new scenario src := inst.SrcOperands.Operands[0] imme := inst.SrcOperands.Operands[1] @@ -1080,9 +1163,10 @@ func (i instEmulator) runBne(inst Operation, state *coreState) { i.Jump(srcVal, state) } Trace("Inst", "Time", state.CurrentTime, "OpCode", inst.OpCode, "ID", inst.ID, "X", state.TileX, "Y", state.TileY, "Pred", finalPred) + return make(map[Operand]cgra.Data) } -func (i instEmulator) runBlt(inst Operation, state *coreState) { +func (i instEmulator) runBlt(inst Operation, state *coreState) map[Operand]cgra.Data { // not safe in new scenario src := inst.SrcOperands.Operands[0] imme := inst.SrcOperands.Operands[1] @@ -1097,9 +1181,10 @@ func (i instEmulator) runBlt(inst Operation, state *coreState) { i.Jump(srcVal, state) } Trace("Inst", "Time", state.CurrentTime, "OpCode", inst.OpCode, "ID", inst.ID, "X", state.TileX, "Y", state.TileY, "Pred", finalPred) + return make(map[Operand]cgra.Data) } -func (i instEmulator) runRet(inst Operation, state *coreState) { +func (i instEmulator) runRetImm(inst Operation, state *coreState, time float64) map[Operand]cgra.Data { var finalPred bool if len(inst.SrcOperands.Operands) > 0 { src := inst.SrcOperands.Operands[0] @@ -1115,20 +1200,47 @@ func (i instEmulator) runRet(inst Operation, state *coreState) { ) *state.retVal = srcVal *state.exit = true + *state.requestExitTimestamp = time + fmt.Println("++++++++++++ RETURN executed", srcVal, "T=", time) + } else { + fmt.Println("++++++++++++ RETURN bypassed") } } else { - finalPred = false - slog.Info("Control: Un-cond", - "X", state.TileX, - "Y", state.TileY, - ) - *state.exit = true - *state.retVal = 0 + panic("RETURN_VALUE requires a source operand") + } + Trace("Inst", "Time", state.CurrentTime, "OpCode", inst.OpCode, "ID", inst.ID, "X", state.TileX, "Y", state.TileY, "Pred", finalPred) + return make(map[Operand]cgra.Data) +} + +func (i instEmulator) runRetDelay(inst Operation, state *coreState, time float64) map[Operand]cgra.Data { + var finalPred bool + if len(inst.SrcOperands.Operands) > 0 { + src := inst.SrcOperands.Operands[0] + srcStruct := i.readOperand(src, state) + srcVal := srcStruct.First() + srcPred := srcStruct.Pred + finalPred = srcPred + if srcPred { + slog.Info("Control: Cond", + "X", state.TileX, + "Y", state.TileY, + "SrcVal", srcVal, + ) + *state.retVal = 0 + *state.exit = true + *state.requestExitTimestamp = time + ExitDelay + fmt.Println("++++++++++++ RETURN executed", srcVal, "T=", time) + } else { + fmt.Println("++++++++++++ RETURN bypassed") + } + } else { + panic("RETURN_VOID requires a source operand") } Trace("Inst", "Time", state.CurrentTime, "OpCode", inst.OpCode, "ID", inst.ID, "X", state.TileX, "Y", state.TileY, "Pred", finalPred) + return make(map[Operand]cgra.Data) } -func (i instEmulator) runFAdd(inst Operation, state *coreState) { +func (i instEmulator) runFAdd(inst Operation, state *coreState) map[Operand]cgra.Data { src1 := inst.SrcOperands.Operands[0] src2 := inst.SrcOperands.Operands[1] @@ -1146,14 +1258,16 @@ func (i instEmulator) runFAdd(inst Operation, state *coreState) { resultUint := float2Uint(resultFloat) finalPred := src1Pred && src2Pred + results := make(map[Operand]cgra.Data) for _, dst := range inst.DstOperands.Operands { - i.writeOperand(dst, cgra.NewScalarWithPred(resultUint, finalPred), state) + results[dst] = cgra.NewScalarWithPred(resultUint, finalPred) } Trace("Inst", "Time", state.CurrentTime, "OpCode", inst.OpCode, "ID", inst.ID, "X", state.TileX, "Y", state.TileY, "Pred", finalPred) // elect no next PC + return results } -func (i instEmulator) runFSub(inst Operation, state *coreState) { +func (i instEmulator) runFSub(inst Operation, state *coreState) map[Operand]cgra.Data { src1 := inst.SrcOperands.Operands[0] src2 := inst.SrcOperands.Operands[1] @@ -1171,14 +1285,16 @@ func (i instEmulator) runFSub(inst Operation, state *coreState) { resultUint := float2Uint(resultFloat) finalPred := src1Pred && src2Pred + results := make(map[Operand]cgra.Data) for _, dst := range inst.DstOperands.Operands { - i.writeOperand(dst, cgra.NewScalarWithPred(resultUint, finalPred), state) + results[dst] = cgra.NewScalarWithPred(resultUint, finalPred) } Trace("Inst", "Time", state.CurrentTime, "OpCode", inst.OpCode, "ID", inst.ID, "X", state.TileX, "Y", state.TileY, "Pred", finalPred) // elect no next PC + return results } -func (i instEmulator) runFMul(inst Operation, state *coreState) { +func (i instEmulator) runFMul(inst Operation, state *coreState) map[Operand]cgra.Data { src1 := inst.SrcOperands.Operands[0] src2 := inst.SrcOperands.Operands[1] @@ -1196,37 +1312,80 @@ func (i instEmulator) runFMul(inst Operation, state *coreState) { resultUint := float2Uint(resultFloat) finalPred := src1Pred && src2Pred + results := make(map[Operand]cgra.Data) for _, dst := range inst.DstOperands.Operands { - i.writeOperand(dst, cgra.NewScalarWithPred(resultUint, finalPred), state) + results[dst] = cgra.NewScalarWithPred(resultUint, finalPred) } Trace("Inst", "Time", state.CurrentTime, "OpCode", inst.OpCode, "ID", inst.ID, "X", state.TileX, "Y", state.TileY, "Pred", finalPred) // elect no next PC + return results } -func (i instEmulator) runCmpExport(inst Operation, state *coreState) { +func (i instEmulator) runCmpExport(inst Operation, state *coreState) map[Operand]cgra.Data { src1 := inst.SrcOperands.Operands[0] src2 := inst.SrcOperands.Operands[1] src1Val := i.readOperand(src1, state) src2Val := i.readOperand(src2, state) + resultVal := 0 + var finalPred bool + results := make(map[Operand]cgra.Data) if src1Val.First() == src2Val.First() && src1Val.Pred == src2Val.Pred { finalPred = src1Val.Pred + resultVal = 1 for _, dst := range inst.DstOperands.Operands { - i.writeOperand(dst, cgra.NewScalarWithPred(1, finalPred), state) + results[dst] = cgra.NewScalarWithPred(1, finalPred) } + fmt.Println(">>>>>>>>>>>>>>> ICMP_EQ: ", src1Val.First(), src2Val.First(), "Yes") } else { finalPred = src1Val.Pred + resultVal = 0 + for _, dst := range inst.DstOperands.Operands { + results[dst] = cgra.NewScalarWithPred(0, finalPred) + } + fmt.Println(">>>>>>>>>>>>>>> ICMP_EQ: ", src1Val.First(), src2Val.First(), "No") + } + Trace("Inst", "Time", state.CurrentTime, "OpCode", inst.OpCode, "ID", inst.ID, "X", state.TileX, "Y", state.TileY, "Src1", fmt.Sprintf("%d(%t)", src1Val.First(), src1Val.Pred), "Src2", fmt.Sprintf("%d(%t)", src2Val.First(), src2Val.Pred), "Result", fmt.Sprintf("%d(%t)", resultVal, finalPred)) + return results +} + +func (i instEmulator) runSgtExport(inst Operation, state *coreState) map[Operand]cgra.Data { + src1 := inst.SrcOperands.Operands[0] + src2 := inst.SrcOperands.Operands[1] + + src1Struct := i.readOperand(src1, state) + src2Struct := i.readOperand(src2, state) + src1Val := src1Struct.First() + src2Val := src2Struct.First() + + src1Pred := src1Struct.Pred + src2Pred := src2Struct.Pred + resultPred := src1Pred && src2Pred + + finalPred := resultPred + + //o + src1Signed := int32(src1Val) + src2Signed := int32(src2Val) + + results := make(map[Operand]cgra.Data) + if src1Signed > src2Signed { for _, dst := range inst.DstOperands.Operands { - i.writeOperand(dst, cgra.NewScalarWithPred(0, finalPred), state) + results[dst] = cgra.NewScalarWithPred(1, finalPred) + } + } else { + for _, dst := range inst.DstOperands.Operands { + results[dst] = cgra.NewScalarWithPred(0, finalPred) } } Trace("Inst", "Time", state.CurrentTime, "OpCode", inst.OpCode, "ID", inst.ID, "X", state.TileX, "Y", state.TileY, "Pred", finalPred) // elect no next PC + return results } -func (i instEmulator) runLTExport(inst Operation, state *coreState) { +func (i instEmulator) runLTExport(inst Operation, state *coreState) map[Operand]cgra.Data { src1 := inst.SrcOperands.Operands[0] src2 := inst.SrcOperands.Operands[1] @@ -1239,20 +1398,22 @@ func (i instEmulator) runLTExport(inst Operation, state *coreState) { resultPred := src1Pred && src2Pred finalPred := resultPred + results := make(map[Operand]cgra.Data) if src1Val < src2Val { for _, dst := range inst.DstOperands.Operands { - i.writeOperand(dst, cgra.NewScalarWithPred(1, finalPred), state) + results[dst] = cgra.NewScalarWithPred(1, finalPred) } } else { for _, dst := range inst.DstOperands.Operands { - i.writeOperand(dst, cgra.NewScalarWithPred(0, finalPred), state) + results[dst] = cgra.NewScalarWithPred(0, finalPred) } } Trace("Inst", "Time", state.CurrentTime, "OpCode", inst.OpCode, "ID", inst.ID, "X", state.TileX, "Y", state.TileY, "Pred", finalPred) // elect no next PC + return results } -func (i instEmulator) runGTExport(inst Operation, state *coreState) { +func (i instEmulator) runGTExport(inst Operation, state *coreState) map[Operand]cgra.Data { src1 := inst.SrcOperands.Operands[0] src2 := inst.SrcOperands.Operands[1] @@ -1265,20 +1426,55 @@ func (i instEmulator) runGTExport(inst Operation, state *coreState) { resultPred := src1Pred && src2Pred finalPred := resultPred + results := make(map[Operand]cgra.Data) if src1Val > src2Val { for _, dst := range inst.DstOperands.Operands { - i.writeOperand(dst, cgra.NewScalarWithPred(1, finalPred), state) + results[dst] = cgra.NewScalarWithPred(1, finalPred) } } else { for _, dst := range inst.DstOperands.Operands { - i.writeOperand(dst, cgra.NewScalarWithPred(0, finalPred), state) + results[dst] = cgra.NewScalarWithPred(0, finalPred) } } Trace("Inst", "Time", state.CurrentTime, "OpCode", inst.OpCode, "ID", inst.ID, "X", state.TileX, "Y", state.TileY, "Pred", finalPred) // elect no next PC + return results +} + +func (i instEmulator) runSGEExport(inst Operation, state *coreState) map[Operand]cgra.Data { + src1 := inst.SrcOperands.Operands[0] + src2 := inst.SrcOperands.Operands[1] + + src1Struct := i.readOperand(src1, state) + src2Struct := i.readOperand(src2, state) + src1Val := src1Struct.First() + src2Val := src2Struct.First() + src1Pred := src1Struct.Pred + src2Pred := src2Struct.Pred + resultPred := src1Pred && src2Pred + + src1Signed := int32(src1Val) + src2Signed := int32(src2Val) + + resultVal := 0 + + results := make(map[Operand]cgra.Data) + if src1Signed >= src2Signed { + resultVal = 1 + for _, dst := range inst.DstOperands.Operands { + results[dst] = cgra.NewScalarWithPred(1, resultPred) + } + } else { + resultVal = 0 + for _, dst := range inst.DstOperands.Operands { + results[dst] = cgra.NewScalarWithPred(0, resultPred) + } + } + Trace("Inst", "Time", state.CurrentTime, "OpCode", inst.OpCode, "ID", inst.ID, "X", state.TileX, "Y", state.TileY, "Src1", fmt.Sprintf("%d(%t)", src1Val, src1Pred), "Src2", fmt.Sprintf("%d(%t)", src2Val, src2Pred), "Result", fmt.Sprintf("%d(%t)", resultVal, resultPred)) + return results } -func (i instEmulator) runPhi(inst Operation, state *coreState) { +func (i instEmulator) runPhi(inst Operation, state *coreState) map[Operand]cgra.Data { src1 := inst.SrcOperands.Operands[0] src2 := inst.SrcOperands.Operands[1] @@ -1286,29 +1482,31 @@ func (i instEmulator) runPhi(inst Operation, state *coreState) { src2Struct := i.readOperand(src2, state) var finalPred bool + results := make(map[Operand]cgra.Data) if src1Struct.Pred && !src2Struct.Pred { finalPred = src1Struct.Pred for _, dst := range inst.DstOperands.Operands { - i.writeOperand(dst, cgra.NewScalarWithPred(src1Struct.First(), finalPred), state) + results[dst] = cgra.NewScalarWithPred(src1Struct.First(), finalPred) } } else if !src1Struct.Pred && src2Struct.Pred { finalPred = src2Struct.Pred for _, dst := range inst.DstOperands.Operands { - i.writeOperand(dst, cgra.NewScalarWithPred(src2Struct.First(), finalPred), state) + results[dst] = cgra.NewScalarWithPred(src2Struct.First(), finalPred) } } else if !src1Struct.Pred && !src2Struct.Pred { finalPred = false for _, dst := range inst.DstOperands.Operands { - i.writeOperand(dst, cgra.NewScalarWithPred(0, finalPred), state) + results[dst] = cgra.NewScalarWithPred(0, finalPred) } } else { panic("Phi operation: both sources have the same predicate") } Trace("Inst", "Time", state.CurrentTime, "OpCode", inst.OpCode, "ID", inst.ID, "X", state.TileX, "Y", state.TileY, "Pred", finalPred) // elect no next PC + return results } -func (i instEmulator) runPhiConst(inst Operation, state *coreState) { +func (i instEmulator) runPhiConst(inst Operation, state *coreState) map[Operand]cgra.Data { // Possibly wrong src1 := inst.SrcOperands.Operands[0] src2 := inst.SrcOperands.Operands[1] @@ -1319,27 +1517,80 @@ func (i instEmulator) runPhiConst(inst Operation, state *coreState) { src1Pred := src1Struct.Pred src2Pred := src2Struct.Pred + // Track PHI_CONST per instruction to avoid cross-interference. + stateKey := fmt.Sprintf("PhiConst_%d", inst.ID) var result uint32 var finalPred bool - if state.States["Phiconst"] == false { + results := make(map[Operand]cgra.Data) + if state.States[stateKey] == nil || state.States[stateKey] == false { result = src1Val finalPred = src1Pred - state.States["Phiconst"] = true + state.States[stateKey] = true for _, dst := range inst.DstOperands.Operands { - i.writeOperand(dst, cgra.NewScalarWithPred(result, finalPred), state) + results[dst] = cgra.NewScalarWithPred(result, finalPred) } } else { result = src2Val finalPred = src2Pred for _, dst := range inst.DstOperands.Operands { - i.writeOperand(dst, cgra.NewScalarWithPred(result, finalPred), state) + results[dst] = cgra.NewScalarWithPred(result, finalPred) } } Trace("Inst", "Time", state.CurrentTime, "OpCode", inst.OpCode, "ID", inst.ID, "X", state.TileX, "Y", state.TileY, "Pred", finalPred) // elect no next PC + return results +} + +func (i instEmulator) runPhiStart(inst Operation, state *coreState) map[Operand]cgra.Data { + src1 := inst.SrcOperands.Operands[0] + src2 := inst.SrcOperands.Operands[1] + src1Struct := i.readOperand(src1, state) + src1Val := src1Struct.First() + src1Pred := src1Struct.Pred + + // Track PHI_START per instruction to avoid cross-interference. + stateKey := fmt.Sprintf("PhiStart_%d", inst.ID) + var result uint32 + var finalPred bool + results := make(map[Operand]cgra.Data) + + if state.States[stateKey] == nil || state.States[stateKey] == false { // first execution + if !src1Pred { + panic("Predicate of first time PHI_START must be true at (" + strconv.Itoa(int(state.TileX)) + "," + strconv.Itoa(int(state.TileY)) + ") instruction " + strconv.Itoa(inst.ID)) + } + result = src1Val + finalPred = src1Pred + state.States[stateKey] = true + fmt.Println("set state.States[", stateKey, "] to true") + for _, dst := range inst.DstOperands.Operands { + results[dst] = cgra.NewScalarWithPred(result, finalPred) + } + Trace("Inst", "Time", state.CurrentTime, "OpCode", inst.OpCode, "ID", inst.ID, "X", state.TileX, "Y", state.TileY, "Src0(FirstTime)", fmt.Sprintf("%d(%t)", src1Val, src1Pred), "Result", fmt.Sprintf("%d(%t)", result, finalPred)) + } else { + src2Struct := i.readOperand(src2, state) // only in normal path will consume src2 + src2Val := src2Struct.First() + src2Pred := src2Struct.Pred + if src1Pred && src2Pred { + panic("Only one of the predicates of PHI_START can be true at (" + strconv.Itoa(int(state.TileX)) + "," + strconv.Itoa(int(state.TileY)) + ") instruction " + strconv.Itoa(inst.ID)) + } + if src1Pred { + result = src1Val + finalPred = src1Pred + } else { // src2Pred is true or both are false(arbitrary) + result = src2Val + finalPred = src2Pred + } + for _, dst := range inst.DstOperands.Operands { + results[dst] = cgra.NewScalarWithPred(result, finalPred) + } + Trace("Inst", "Time", state.CurrentTime, "OpCode", inst.OpCode, "ID", inst.ID, "X", state.TileX, "Y", state.TileY, "Src0", fmt.Sprintf("%d(%t)", src1Val, src1Pred), "Src1", fmt.Sprintf("%d(%t)", src2Val, src2Pred), "Result", fmt.Sprintf("%d(%t)", result, finalPred)) + } + + // elect no next PC + return results } -func (i instEmulator) runGrantPred(inst Operation, state *coreState) { +func (i instEmulator) runGrantPred(inst Operation, state *coreState) map[Operand]cgra.Data { src := inst.SrcOperands.Operands[0] pred := inst.SrcOperands.Operands[1] @@ -1347,6 +1598,8 @@ func (i instEmulator) runGrantPred(inst Operation, state *coreState) { predStruct := i.readOperand(pred, state) srcVal := srcStruct.First() predVal := predStruct.First() + srcPred := srcStruct.Pred + predPred := predStruct.Pred resultPred := false @@ -1357,32 +1610,76 @@ func (i instEmulator) runGrantPred(inst Operation, state *coreState) { } //fmt.Printf("GRANTPRED: srcVal = %d, predVal = %t at (%d, %d)\n", srcVal, predVal, state.TileX, state.TileY) - finalPred := resultPred + finalPred := resultPred && predPred && srcPred + results := make(map[Operand]cgra.Data) for _, dst := range inst.DstOperands.Operands { - i.writeOperand(dst, cgra.NewScalarWithPred(srcVal, finalPred), state) + results[dst] = cgra.NewScalarWithPred(srcVal, finalPred) } - Trace("Inst", "Time", state.CurrentTime, "OpCode", inst.OpCode, "ID", inst.ID, "X", state.TileX, "Y", state.TileY, "Pred", finalPred) + + fmt.Println("<<<<<<<<<<<<<< GRANTPRED: ", srcVal, predVal, finalPred) + + Trace("Inst", "Time", state.CurrentTime, "OpCode", inst.OpCode, "ID", inst.ID, "X", state.TileX, "Y", state.TileY, "SrcOperand", fmt.Sprintf("%d(%t)", srcVal, srcStruct.Pred), "PredOperand", fmt.Sprintf("%d(%t)", predVal, predStruct.Pred), "Pred", finalPred, "Result", fmt.Sprintf("%d(%t)", srcVal, finalPred)) // elect no next PC + return results } -func (i instEmulator) runGrantOnce(inst Operation, state *coreState) { +func (i instEmulator) runGrantOnce(inst Operation, state *coreState) map[Operand]cgra.Data { src := inst.SrcOperands.Operands[0] srcStruct := i.readOperand(src, state) // Track GRANT_ONCE per instruction to avoid cross-interference. stateKey := fmt.Sprintf("GrantOnce_%d", inst.ID) var finalPred bool + results := make(map[Operand]cgra.Data) if state.States[stateKey] == nil || state.States[stateKey] == false { state.States[stateKey] = true finalPred = srcStruct.Pred for _, dst := range inst.DstOperands.Operands { - i.writeOperand(dst, cgra.NewScalarWithPred(srcStruct.First(), finalPred), state) + results[dst] = cgra.NewScalarWithPred(srcStruct.First(), finalPred) } } else { finalPred = false for _, dst := range inst.DstOperands.Operands { - i.writeOperand(dst, cgra.NewScalarWithPred(srcStruct.First(), finalPred), state) + results[dst] = cgra.NewScalarWithPred(srcStruct.First(), finalPred) } } Trace("Inst", "Time", state.CurrentTime, "OpCode", inst.OpCode, "ID", inst.ID, "X", state.TileX, "Y", state.TileY, "Pred", finalPred) + return results +} + +func (i instEmulator) runSel(inst Operation, state *coreState) map[Operand]cgra.Data { + sel := inst.SrcOperands.Operands[0] + src1 := inst.SrcOperands.Operands[1] + src2 := inst.SrcOperands.Operands[2] + + selStruct := i.readOperand(sel, state) + src1Struct := i.readOperand(src1, state) + src2Struct := i.readOperand(src2, state) + + selVal := selStruct.First() + src1Val := src1Struct.First() + src2Val := src2Struct.First() + + selPred := selStruct.Pred + src1Pred := src1Struct.Pred + src2Pred := src2Struct.Pred + + resultPred := selPred && src1Pred && src2Pred + + if selVal != 0 && selVal != 1 { + panic("Sel must be 0 or 1") + } + + results := make(map[Operand]cgra.Data) + if selVal == 0 { // if sel is 0, select src2 + for _, dst := range inst.DstOperands.Operands { + results[dst] = cgra.NewScalarWithPred(src2Val, resultPred) + } + } else { // if sel is 1, select src1 + for _, dst := range inst.DstOperands.Operands { + results[dst] = cgra.NewScalarWithPred(src1Val, resultPred) + } + } + Trace("Inst", "Time", state.CurrentTime, "OpCode", inst.OpCode, "ID", inst.ID, "X", state.TileX, "Y", state.TileY, "Sel", fmt.Sprintf("%d(%t)", selVal, selPred), "Src1", fmt.Sprintf("%d(%t)", src1Val, src1Pred), "Src2", fmt.Sprintf("%d(%t)", src2Val, src2Pred), "Sel", fmt.Sprintf("%d(%t)", selVal, selPred)) + return results } diff --git a/test/testbench/gemv/gemv-annotated.png b/test/testbench/gemv/gemv-annotated.png new file mode 100644 index 0000000..6ed64f9 Binary files /dev/null and b/test/testbench/gemv/gemv-annotated.png differ diff --git a/test/testbench/gemv/gemv-dfg.yaml b/test/testbench/gemv/gemv-dfg.yaml new file mode 100644 index 0000000..35b6662 --- /dev/null +++ b/test/testbench/gemv/gemv-dfg.yaml @@ -0,0 +1,554 @@ +nodes: + - id: 0 + opcode: "GRANT_ONCE" + tile_x: 0 + tile_y: 0 + time_step: 0 + - id: 1 + opcode: "GRANT_ONCE" + tile_x: 2 + tile_y: 2 + time_step: 5 + - id: 12 + opcode: "DATA_MOV" + tile_x: 1 + tile_y: 0 + time_step: 1 + - id: 15 + opcode: "PHI_START" + tile_x: 1 + tile_y: 0 + time_step: 2 + - id: 16 + opcode: "PHI_START" + tile_x: 0 + tile_y: 0 + time_step: 1 + - id: 17 + opcode: "PHI_START" + tile_x: 2 + tile_y: 2 + time_step: 6 + - id: 20 + opcode: "DATA_MOV" + tile_x: 0 + tile_y: 1 + time_step: 4 + - id: 24 + opcode: "PHI_START" + tile_x: 1 + tile_y: 1 + time_step: 3 + - id: 25 + opcode: "PHI_START" + tile_x: 1 + tile_y: 0 + time_step: 8 + - id: 26 + opcode: "PHI_START" + tile_x: 0 + tile_y: 1 + time_step: 5 + - id: 27 + opcode: "SHL" + tile_x: 0 + tile_y: 0 + time_step: 2 + - id: 28 + opcode: "PHI_START" + tile_x: 2 + tile_y: 2 + time_step: 7 + - id: 29 + opcode: "PHI_START" + tile_x: 2 + tile_y: 2 + time_step: 8 + - id: 31 + opcode: "DATA_MOV" + tile_x: 2 + tile_y: 1 + time_step: 4 + - id: 36 + opcode: "DATA_MOV" + tile_x: 1 + tile_y: 1 + time_step: 9 + - id: 38 + opcode: "DATA_MOV" + tile_x: 2 + tile_y: 1 + time_step: 8 + - id: 41 + opcode: "ADD" + tile_x: 1 + tile_y: 1 + time_step: 4 + - id: 42 + opcode: "GEP" + tile_x: 2 + tile_y: 1 + time_step: 5 + - id: 43 + opcode: "GEP" + tile_x: 0 + tile_y: 0 + time_step: 3 + - id: 44 + opcode: "DATA_MOV" + tile_x: 2 + tile_y: 1 + time_step: 6 + - id: 48 + opcode: "ICMP_EQ" + tile_x: 1 + tile_y: 1 + time_step: 5 + - id: 49 + opcode: "LOAD" + tile_x: 3 + tile_y: 1 + time_step: 6 + - id: 50 + opcode: "PHI_START" + tile_x: 0 + tile_y: 1 + time_step: 4 + - id: 51 + opcode: "DATA_MOV" + tile_x: 1 + tile_y: 2 + time_step: 8 + - id: 52 + opcode: "DATA_MOV" + tile_x: 1 + tile_y: 0 + time_step: 8 + - id: 53 + opcode: "DATA_MOV" + tile_x: 2 + tile_y: 1 + time_step: 9 + - id: 56 + opcode: "DATA_MOV" + tile_x: 2 + tile_y: 1 + time_step: 7 + - id: 58 + opcode: "DATA_MOV" + tile_x: 1 + tile_y: 1 + time_step: 5 + - id: 59 + opcode: "GRANT_PREDICATE" + tile_x: 1 + tile_y: 2 + time_step: 9 + - id: 60 + opcode: "GRANT_PREDICATE" + tile_x: 1 + tile_y: 0 + time_step: 9 + - id: 61 + opcode: "GRANT_PREDICATE" + tile_x: 0 + tile_y: 1 + time_step: 6 + - id: 62 + opcode: "NOT" + tile_x: 2 + tile_y: 1 + time_step: 6 + - id: 63 + opcode: "GEP" + tile_x: 1 + tile_y: 1 + time_step: 6 + - id: 65 + opcode: "DATA_MOV" + tile_x: 1 + tile_y: 1 + time_step: 10 + - id: 67 + opcode: "DATA_MOV" + tile_x: 0 + tile_y: 0 + time_step: 8 + - id: 68 + opcode: "DATA_MOV" + tile_x: 2 + tile_y: 2 + time_step: 9 + - id: 69 + opcode: "DATA_MOV" + tile_x: 1 + tile_y: 0 + time_step: 9 + - id: 70 + opcode: "DATA_MOV" + tile_x: 1 + tile_y: 1 + time_step: 9 + - id: 75 + opcode: "ADD" + tile_x: 0 + tile_y: 1 + time_step: 7 + - id: 76 + opcode: "GEP" + tile_x: 0 + tile_y: 0 + time_step: 9 + - id: 77 + opcode: "GRANT_PREDICATE" + tile_x: 2 + tile_y: 2 + time_step: 10 + - id: 78 + opcode: "GRANT_PREDICATE" + tile_x: 1 + tile_y: 0 + time_step: 10 + - id: 79 + opcode: "GRANT_PREDICATE" + tile_x: 1 + tile_y: 1 + time_step: 10 + - id: 80 + opcode: "GRANT_PREDICATE" + tile_x: 0 + tile_y: 1 + time_step: 10 + - id: 81 + opcode: "GRANT_PREDICATE" + tile_x: 2 + tile_y: 1 + time_step: 7 + - id: 82 + opcode: "LOAD" + tile_x: 1 + tile_y: 1 + time_step: 7 + - id: 88 + opcode: "CTRL_MOV" + tile_x: 0 + tile_y: 1 + time_step: 15 + - id: 90 + opcode: "CTRL_MOV" + tile_x: 1 + tile_y: 1 + time_step: 13 + - id: 92 + opcode: "ICMP_EQ" + tile_x: 0 + tile_y: 1 + time_step: 8 + - id: 93 + opcode: "MUL" + tile_x: 2 + tile_y: 1 + time_step: 8 + - id: 98 + opcode: "GRANT_PREDICATE" + tile_x: 0 + tile_y: 1 + time_step: 9 + - id: 99 + opcode: "NOT" + tile_x: 1 + tile_y: 1 + time_step: 9 + - id: 100 + opcode: "ADD" + tile_x: 2 + tile_y: 1 + time_step: 9 + - id: 104 + opcode: "DATA_MOV" + tile_x: 0 + tile_y: 1 + time_step: 10 + - id: 107 + opcode: "RETURN_VOID" + tile_x: 0 + tile_y: 2 + time_step: 10 + - id: 108 + opcode: "GRANT_PREDICATE" + tile_x: 1 + tile_y: 2 + time_step: 10 + - id: 109 + opcode: "GRANT_PREDICATE" + tile_x: 1 + tile_y: 1 + time_step: 11 + - id: 110 + opcode: "GRANT_PREDICATE" + tile_x: 0 + tile_y: 1 + time_step: 11 + - id: 111 + opcode: "GRANT_PREDICATE" + tile_x: 2 + tile_y: 1 + time_step: 10 + - id: 112 + opcode: "GRANT_PREDICATE" + tile_x: 2 + tile_y: 1 + time_step: 11 + - id: 113 + opcode: "CTRL_MOV" + tile_x: 2 + tile_y: 2 + time_step: 16 + - id: 114 + opcode: "CTRL_MOV" + tile_x: 1 + tile_y: 0 + time_step: 12 + - id: 117 + opcode: "CTRL_MOV" + tile_x: 2 + tile_y: 2 + time_step: 17 + - id: 118 + opcode: "STORE" + tile_x: 2 + tile_y: 0 + time_step: 11 + - id: 530000 + opcode: "DATA_MOV" + tile_x: 1 + tile_y: 1 + time_step: 6 + - id: 690001 + opcode: "DATA_MOV" + tile_x: 1 + tile_y: 1 + time_step: 7 + - id: 700001 + opcode: "DATA_MOV" + tile_x: 3 + tile_y: 1 + time_step: 7 + - id: 700002 + opcode: "DATA_MOV" + tile_x: 2 + tile_y: 1 + time_step: 8 + - id: 710001 + opcode: "DATA_MOV" + tile_x: 2 + tile_y: 0 + time_step: 7 + - id: 710002 + opcode: "DATA_MOV" + tile_x: 1 + tile_y: 0 + time_step: 8 + - id: 710003 + opcode: "DATA_MOV" + tile_x: 0 + tile_y: 0 + time_step: 9 + - id: 850001 + opcode: "DATA_MOV" + tile_x: 1 + tile_y: 0 + time_step: 10 +edges: + - from: 113 + to: 17 + - from: 0 + to: 12 + - from: 12 + to: 15 + - from: 114 + to: 15 + - from: 16 + to: 20 + - from: 20 + to: 26 + - from: 88 + to: 26 + - from: 117 + to: 28 + - from: 90 + to: 24 + - from: 50 + to: 58 + - from: 58 + to: 63 + - from: 24 + to: 31 + - from: 31 + to: 42 + - from: 49 + to: 56 + - from: 56 + to: 93 + - from: 28 + to: 38 + - from: 38 + to: 100 + - from: 41 + to: 44 + - from: 44 + to: 81 + - from: 81 + to: 90 + - from: 112 + to: 117 + - from: 26 + to: 36 + - from: 36 + to: 79 + - from: 79 + to: 88 + - from: 62 + to: 68 + - from: 68 + to: 77 + - from: 48 + to: 52 + - from: 52 + to: 60 + - from: 48 + to: 51 + - from: 51 + to: 59 + - from: 61 + to: 67 + - from: 67 + to: 76 + - from: 99 + to: 104 + - from: 104 + to: 110 + - from: 60 + to: 65 + - from: 65 + to: 109 + - from: 109 + to: 114 + - from: 108 + to: 113 + - from: 62 + to: 710001 + - from: 710001 + to: 710002 + - from: 710002 + to: 710003 + - from: 62 + to: 700001 + - from: 700001 + to: 700002 + - from: 700002 + to: 70 + - from: 70 + to: 79 + - from: 62 + to: 690001 + - from: 690001 + to: 69 + - from: 69 + to: 78 + - from: 48 + to: 530000 + - from: 530000 + to: 53 + - from: 53 + to: 111 + - from: 76 + to: 850001 + - from: 110 + to: 16 + - from: 99 + to: 109 + - from: 99 + to: 108 + - from: 98 + to: 107 + - from: 93 + to: 100 + - from: 92 + to: 98 + - from: 78 + to: 25 + - from: 77 + to: 29 + - from: 850001 + to: 118 + - from: 92 + to: 99 + - from: 27 + to: 43 + - from: 61 + to: 75 + - from: 25 + to: 60 + - from: 80 + to: 50 + - from: 24 + to: 41 + - from: 17 + to: 29 + - from: 26 + to: 61 + - from: 59 + to: 108 + - from: 17 + to: 28 + - from: 25 + to: 78 + - from: 16 + to: 27 + - from: 82 + to: 93 + - from: 24 + to: 63 + - from: 15 + to: 25 + - from: 15 + to: 24 + - from: 100 + to: 112 + - from: 43 + to: 50 + - from: 62 + to: 112 + - from: 0 + to: 16 + - from: 710003 + to: 80 + - from: 29 + to: 59 + - from: 29 + to: 77 + - from: 41 + to: 48 + - from: 63 + to: 82 + - from: 100 + to: 111 + - from: 42 + to: 49 + - from: 48 + to: 61 + - from: 75 + to: 110 + - from: 48 + to: 62 + - from: 75 + to: 92 + - from: 111 + to: 118 + - from: 50 + to: 80 + - from: 1 + to: 17 + - from: 62 + to: 81 \ No newline at end of file diff --git a/test/testbench/gemv/gemv-instructions.yaml b/test/testbench/gemv/gemv-instructions.yaml new file mode 100644 index 0000000..cb76f7a --- /dev/null +++ b/test/testbench/gemv/gemv-instructions.yaml @@ -0,0 +1,1089 @@ +array_config: + columns: 4 + rows: 4 + compiled_ii: 11 + cores: + - column: 0 + row: 0 + core_id: "0" + entries: + - entry_id: "entry0" + instructions: + - index_per_ii: 0 + operations: + - opcode: "GRANT_ONCE" + id: 0 + time_step: 0 + invalid_iterations: 0 + src_operands: + - operand: "#0" + color: "RED" + dst_operands: + - operand: "NORTH" + color: "RED" + - operand: "EAST" + color: "RED" + - index_per_ii: 6 + operations: + - opcode: "MUL" + id: 78 + time_step: 6 + invalid_iterations: 0 + src_operands: + - operand: "NORTH" + color: "RED" + - operand: "EAST" + color: "RED" + dst_operands: + - operand: "EAST" + color: "RED" + - column: 1 + row: 0 + core_id: "1" + entries: + - entry_id: "entry0" + instructions: + - index_per_ii: 1 + operations: + - opcode: "PHI_START" + id: 15 + time_step: 1 + invalid_iterations: 0 + src_operands: + - operand: "WEST" + color: "RED" + - operand: "NORTH" + color: "RED" + dst_operands: + - operand: "$0" + color: "RED" + - operand: "NORTH" + color: "RED" + - index_per_ii: 2 + operations: + - opcode: "SHL" + id: 26 + time_step: 2 + invalid_iterations: 0 + src_operands: + - operand: "$0" + color: "RED" + - operand: "#2" + color: "RED" + dst_operands: + - operand: "$0" + color: "RED" + - index_per_ii: 3 + operations: + - opcode: "GEP" + id: 42 + time_step: 3 + invalid_iterations: 0 + src_operands: + - operand: "$0" + color: "RED" + dst_operands: + - operand: "$0" + color: "RED" + - opcode: "DATA_MOV" + id: 31 + time_step: 3 + invalid_iterations: 0 + src_operands: + - operand: "NORTH" + color: "RED" + dst_operands: + - operand: "$1" + color: "RED" + - index_per_ii: 4 + operations: + - opcode: "GEP" + id: 49 + time_step: 4 + invalid_iterations: 0 + src_operands: + - operand: "$0" + color: "RED" + - operand: "$1" + color: "RED" + dst_operands: + - operand: "$0" + color: "RED" + - index_per_ii: 5 + operations: + - opcode: "LOAD" + id: 61 + time_step: 5 + invalid_iterations: 0 + src_operands: + - operand: "$0" + color: "RED" + dst_operands: + - operand: "WEST" + color: "RED" + - index_per_ii: 7 + operations: + - opcode: "DATA_MOV" + id: 860001 + time_step: 7 + invalid_iterations: 0 + src_operands: + - operand: "WEST" + color: "RED" + dst_operands: + - operand: "NORTH" + color: "RED" + - column: 2 + row: 0 + core_id: "2" + entries: + - entry_id: "entry0" + instructions: + - index_per_ii: 8 + operations: + - opcode: "DATA_MOV" + id: 380001 + time_step: 8 + invalid_iterations: 0 + src_operands: + - operand: "EAST" + color: "RED" + dst_operands: + - operand: "NORTH" + color: "RED" + - column: 3 + row: 0 + core_id: "3" + entries: + - entry_id: "entry0" + instructions: + - index_per_ii: 2 + operations: + - opcode: "CTRL_MOV" + id: 109 + time_step: 13 + invalid_iterations: 1 + src_operands: + - operand: "NORTH" + color: "RED" + dst_operands: + - operand: "$2" + color: "RED" + - index_per_ii: 4 + operations: + - opcode: "GRANT_ONCE" + id: 1 + time_step: 4 + invalid_iterations: 0 + src_operands: + - operand: "#0" + color: "RED" + dst_operands: + - operand: "$0" + color: "RED" + - index_per_ii: 5 + operations: + - opcode: "PHI_START" + id: 16 + time_step: 5 + invalid_iterations: 0 + src_operands: + - operand: "$0" + color: "RED" + - operand: "$2" + color: "RED" + dst_operands: + - operand: "$0" + color: "RED" + - operand: "NORTH" + color: "RED" + - index_per_ii: 7 + operations: + - opcode: "PHI_START" + id: 28 + time_step: 7 + invalid_iterations: 0 + src_operands: + - operand: "$0" + color: "RED" + - operand: "$1" + color: "RED" + dst_operands: + - operand: "NORTH" + color: "RED" + - operand: "WEST" + color: "RED" + - index_per_ii: 10 + operations: + - opcode: "CTRL_MOV" + id: 82 + time_step: 10 + invalid_iterations: 0 + src_operands: + - operand: "NORTH" + color: "RED" + dst_operands: + - operand: "$1" + color: "RED" + - column: 0 + row: 1 + core_id: "4" + entries: + - entry_id: "entry0" + instructions: + - index_per_ii: 1 + operations: + - opcode: "PHI_START" + id: 14 + time_step: 1 + invalid_iterations: 0 + src_operands: + - operand: "SOUTH" + color: "RED" + - operand: "NORTH" + color: "RED" + dst_operands: + - operand: "$0" + color: "RED" + - operand: "EAST" + color: "RED" + - index_per_ii: 2 + operations: + - opcode: "DATA_MOV" + id: 180000 + time_step: 2 + invalid_iterations: 0 + src_operands: + - operand: "$0" + color: "RED" + dst_operands: + - operand: "EAST" + color: "RED" + - index_per_ii: 3 + operations: + - opcode: "DATA_MOV" + id: 30 + time_step: 3 + invalid_iterations: 0 + src_operands: + - operand: "EAST" + color: "RED" + dst_operands: + - operand: "$0" + color: "RED" + - index_per_ii: 4 + operations: + - opcode: "GEP" + id: 41 + time_step: 4 + invalid_iterations: 0 + src_operands: + - operand: "$0" + color: "RED" + dst_operands: + - operand: "$0" + color: "RED" + - index_per_ii: 5 + operations: + - opcode: "LOAD" + id: 48 + time_step: 5 + invalid_iterations: 0 + src_operands: + - operand: "$0" + color: "RED" + dst_operands: + - operand: "SOUTH" + color: "RED" + - column: 1 + row: 1 + core_id: "5" + entries: + - entry_id: "entry0" + instructions: + - index_per_ii: 0 + operations: + - opcode: "GRANT_PREDICATE" + id: 107 + time_step: 11 + invalid_iterations: 1 + src_operands: + - operand: "$5" + color: "RED" + - operand: "$1" + color: "RED" + dst_operands: + - operand: "SOUTH" + color: "RED" + - index_per_ii: 1 + operations: + - opcode: "STORE" + id: 108 + time_step: 12 + invalid_iterations: 1 + src_operands: + - operand: "$6" + color: "RED" + - operand: "$7" + color: "RED" + - index_per_ii: 2 + operations: + - opcode: "PHI_START" + id: 23 + time_step: 2 + invalid_iterations: 0 + src_operands: + - operand: "WEST" + color: "RED" + - operand: "$0" + color: "RED" + dst_operands: + - operand: "SOUTH" + color: "RED" + - operand: "WEST" + color: "RED" + - operand: "$0" + color: "RED" + - opcode: "DATA_MOV" + id: 19 + time_step: 2 + invalid_iterations: 0 + src_operands: + - operand: "SOUTH" + color: "RED" + dst_operands: + - operand: "$1" + color: "RED" + - index_per_ii: 3 + operations: + - opcode: "ADD" + id: 40 + time_step: 3 + invalid_iterations: 0 + src_operands: + - operand: "$0" + color: "RED" + - operand: "#1" + color: "RED" + dst_operands: + - operand: "NORTH" + color: "RED" + - operand: "$0" + color: "RED" + - opcode: "DATA_MOV" + id: 18 + time_step: 3 + invalid_iterations: 0 + src_operands: + - operand: "WEST" + color: "RED" + dst_operands: + - operand: "$2" + color: "RED" + - index_per_ii: 4 + operations: + - opcode: "PHI_START" + id: 25 + time_step: 4 + invalid_iterations: 0 + src_operands: + - operand: "$1" + color: "RED" + - operand: "$3" + color: "RED" + dst_operands: + - operand: "$1" + color: "RED" + - operand: "$0" + color: "RED" + - opcode: "DATA_MOV" + id: 430000 + time_step: 4 + invalid_iterations: 0 + src_operands: + - operand: "$0" + color: "RED" + dst_operands: + - operand: "NORTH" + color: "RED" + - index_per_ii: 5 + operations: + - opcode: "GRANT_PREDICATE" + id: 59 + time_step: 5 + invalid_iterations: 0 + src_operands: + - operand: "$0" + color: "RED" + - operand: "NORTH" + color: "RED" + dst_operands: + - operand: "EAST" + color: "RED" + - operand: "$0" + color: "RED" + - opcode: "DATA_MOV" + id: 350000 + time_step: 5 + invalid_iterations: 0 + src_operands: + - operand: "$1" + color: "RED" + dst_operands: + - operand: "NORTH" + color: "RED" + - index_per_ii: 6 + operations: + - opcode: "ADD" + id: 72 + time_step: 6 + invalid_iterations: 0 + src_operands: + - operand: "$0" + color: "RED" + - operand: "#1" + color: "RED" + dst_operands: + - operand: "EAST" + color: "RED" + - operand: "$5" + color: "RED" + - opcode: "DATA_MOV" + id: 52 + time_step: 6 + invalid_iterations: 0 + src_operands: + - operand: "NORTH" + color: "RED" + dst_operands: + - operand: "$3" + color: "RED" + - index_per_ii: 7 + operations: + - opcode: "PHI_START" + id: 24 + time_step: 7 + invalid_iterations: 0 + src_operands: + - operand: "$2" + color: "RED" + - operand: "$4" + color: "RED" + dst_operands: + - operand: "$2" + color: "RED" + - operand: "NORTH" + color: "RED" + - opcode: "CTRL_MOV" + id: 85 + time_step: 7 + invalid_iterations: 0 + src_operands: + - operand: "NORTH" + color: "RED" + dst_operands: + - operand: "$0" + color: "RED" + - index_per_ii: 8 + operations: + - opcode: "ADD" + id: 88 + time_step: 8 + invalid_iterations: 0 + src_operands: + - operand: "SOUTH" + color: "RED" + - operand: "EAST" + color: "RED" + dst_operands: + - operand: "NORTH" + color: "RED" + - operand: "$1" + color: "RED" + - opcode: "DATA_MOV" + id: 67 + time_step: 8 + invalid_iterations: 0 + src_operands: + - operand: "NORTH" + color: "RED" + dst_operands: + - operand: "$4" + color: "RED" + - index_per_ii: 9 + operations: + - opcode: "GRANT_PREDICATE" + id: 96 + time_step: 9 + invalid_iterations: 0 + src_operands: + - operand: "$1" + color: "RED" + - operand: "$3" + color: "RED" + dst_operands: + - operand: "$6" + color: "RED" + - opcode: "DATA_MOV" + id: 81 + time_step: 9 + invalid_iterations: 0 + src_operands: + - operand: "EAST" + color: "RED" + dst_operands: + - operand: "$7" + color: "RED" + - index_per_ii: 10 + operations: + - opcode: "GRANT_PREDICATE" + id: 75 + time_step: 10 + invalid_iterations: 0 + src_operands: + - operand: "$2" + color: "RED" + - operand: "$4" + color: "RED" + dst_operands: + - operand: "$4" + color: "RED" + - opcode: "DATA_MOV" + id: 101 + time_step: 10 + invalid_iterations: 0 + src_operands: + - operand: "EAST" + color: "RED" + dst_operands: + - operand: "$1" + color: "RED" + - opcode: "CTRL_MOV" + id: 84 + time_step: 10 + invalid_iterations: 0 + src_operands: + - operand: "NORTH" + color: "RED" + dst_operands: + - operand: "$3" + color: "RED" + - column: 2 + row: 1 + core_id: "6" + entries: + - entry_id: "entry0" + instructions: + - index_per_ii: 0 + operations: + - opcode: "RETURN_VOID" + id: 104 + time_step: 11 + invalid_iterations: 1 + src_operands: + - operand: "$0" + color: "RED" + - index_per_ii: 6 + operations: + - opcode: "DATA_MOV" + id: 50 + time_step: 6 + invalid_iterations: 0 + src_operands: + - operand: "NORTH" + color: "RED" + dst_operands: + - operand: "$0" + color: "RED" + - opcode: "DATA_MOV" + id: 65 + time_step: 6 + invalid_iterations: 0 + src_operands: + - operand: "WEST" + color: "RED" + dst_operands: + - operand: "$1" + color: "RED" + - index_per_ii: 7 + operations: + - opcode: "ICMP_EQ" + id: 87 + time_step: 7 + invalid_iterations: 0 + src_operands: + - operand: "WEST" + color: "RED" + - operand: "#4" + color: "RED" + dst_operands: + - operand: "NORTH" + color: "RED" + - operand: "$2" + color: "RED" + - operand: "$3" + color: "RED" + - opcode: "DATA_MOV" + id: 370001 + time_step: 7 + invalid_iterations: 0 + src_operands: + - operand: "EAST" + color: "RED" + dst_operands: + - operand: "WEST" + color: "RED" + - index_per_ii: 8 + operations: + - opcode: "GEP" + id: 73 + time_step: 8 + invalid_iterations: 0 + src_operands: + - operand: "$1" + color: "RED" + dst_operands: + - operand: "WEST" + color: "RED" + - index_per_ii: 9 + operations: + - opcode: "GRANT_PREDICATE" + id: 57 + time_step: 9 + invalid_iterations: 0 + src_operands: + - operand: "SOUTH" + color: "RED" + - operand: "$0" + color: "RED" + dst_operands: + - operand: "NORTH" + color: "RED" + - opcode: "DATA_MOV" + id: 1010001 + time_step: 9 + invalid_iterations: 0 + src_operands: + - operand: "NORTH" + color: "RED" + dst_operands: + - operand: "WEST" + color: "RED" + - index_per_ii: 10 + operations: + - opcode: "GRANT_PREDICATE" + id: 94 + time_step: 10 + invalid_iterations: 0 + src_operands: + - operand: "$2" + color: "RED" + - operand: "$3" + color: "RED" + dst_operands: + - operand: "$0" + color: "RED" + - column: 3 + row: 1 + core_id: "7" + entries: + - entry_id: "entry0" + instructions: + - index_per_ii: 1 + operations: + - opcode: "CTRL_MOV" + id: 1090002 + time_step: 12 + invalid_iterations: 1 + src_operands: + - operand: "NORTH" + color: "RED" + dst_operands: + - operand: "SOUTH" + color: "RED" + - index_per_ii: 2 + operations: + - opcode: "CTRL_MOV" + id: 103 + time_step: 13 + invalid_iterations: 1 + src_operands: + - operand: "NORTH" + color: "RED" + dst_operands: + - operand: "$0" + color: "RED" + - index_per_ii: 6 + operations: + - opcode: "PHI_START" + id: 27 + time_step: 6 + invalid_iterations: 0 + src_operands: + - operand: "SOUTH" + color: "RED" + - operand: "$0" + color: "RED" + dst_operands: + - operand: "WEST" + color: "RED" + - index_per_ii: 8 + operations: + - opcode: "DATA_MOV" + id: 39 + time_step: 8 + invalid_iterations: 0 + src_operands: + - operand: "SOUTH" + color: "RED" + dst_operands: + - operand: "$0" + color: "RED" + - opcode: "DATA_MOV" + id: 66 + time_step: 8 + invalid_iterations: 0 + src_operands: + - operand: "NORTH" + color: "RED" + dst_operands: + - operand: "$1" + color: "RED" + - index_per_ii: 9 + operations: + - opcode: "GRANT_PREDICATE" + id: 74 + time_step: 9 + invalid_iterations: 0 + src_operands: + - operand: "$0" + color: "RED" + - operand: "$1" + color: "RED" + dst_operands: + - operand: "SOUTH" + color: "RED" + - column: 0 + row: 2 + core_id: "8" + entries: + - entry_id: "entry0" + instructions: + - index_per_ii: 0 + operations: + - opcode: "CTRL_MOV" + id: 1100002 + time_step: 11 + invalid_iterations: 1 + src_operands: + - operand: "EAST" + color: "RED" + dst_operands: + - operand: "SOUTH" + color: "RED" + - index_per_ii: 6 + operations: + - opcode: "DATA_MOV" + id: 670001 + time_step: 6 + invalid_iterations: 0 + src_operands: + - operand: "EAST" + color: "RED" + dst_operands: + - operand: "EAST" + color: "RED" + - column: 1 + row: 2 + core_id: "9" + entries: + - entry_id: "entry0" + instructions: + - index_per_ii: 4 + operations: + - opcode: "ICMP_EQ" + id: 47 + time_step: 4 + invalid_iterations: 0 + src_operands: + - operand: "SOUTH" + color: "RED" + - operand: "#4" + color: "RED" + dst_operands: + - operand: "$0" + color: "RED" + - operand: "SOUTH" + color: "RED" + - operand: "$1" + color: "RED" + - operand: "$2" + color: "RED" + - operand: "EAST" + color: "RED" + - index_per_ii: 5 + operations: + - opcode: "NOT" + id: 60 + time_step: 5 + invalid_iterations: 0 + src_operands: + - operand: "$0" + color: "RED" + dst_operands: + - operand: "$1" + color: "RED" + - operand: "$4" + color: "RED" + - operand: "$3" + color: "RED" + - operand: "WEST" + color: "RED" + - operand: "EAST" + color: "RED" + - opcode: "DATA_MOV" + id: 43 + time_step: 5 + invalid_iterations: 0 + src_operands: + - operand: "SOUTH" + color: "RED" + dst_operands: + - operand: "$0" + color: "RED" + - opcode: "DATA_MOV" + id: 520000 + time_step: 5 + invalid_iterations: 0 + src_operands: + - operand: "$1" + color: "RED" + dst_operands: + - operand: "SOUTH" + color: "RED" + - index_per_ii: 6 + operations: + - opcode: "GRANT_PREDICATE" + id: 77 + time_step: 6 + invalid_iterations: 0 + src_operands: + - operand: "$0" + color: "RED" + - operand: "$1" + color: "RED" + dst_operands: + - operand: "SOUTH" + color: "RED" + - opcode: "DATA_MOV" + id: 35 + time_step: 6 + invalid_iterations: 0 + src_operands: + - operand: "SOUTH" + color: "RED" + dst_operands: + - operand: "$0" + color: "RED" + - index_per_ii: 7 + operations: + - opcode: "DATA_MOV" + id: 670002 + time_step: 7 + invalid_iterations: 0 + src_operands: + - operand: "WEST" + color: "RED" + dst_operands: + - operand: "SOUTH" + color: "RED" + - index_per_ii: 8 + operations: + - opcode: "GRANT_PREDICATE" + id: 58 + time_step: 8 + invalid_iterations: 0 + src_operands: + - operand: "SOUTH" + color: "RED" + - operand: "$2" + color: "RED" + dst_operands: + - operand: "EAST" + color: "RED" + - index_per_ii: 9 + operations: + - opcode: "GRANT_PREDICATE" + id: 76 + time_step: 9 + invalid_iterations: 0 + src_operands: + - operand: "$0" + color: "RED" + - operand: "$3" + color: "RED" + dst_operands: + - operand: "SOUTH" + color: "RED" + - opcode: "DATA_MOV" + id: 93 + time_step: 9 + invalid_iterations: 0 + src_operands: + - operand: "SOUTH" + color: "RED" + dst_operands: + - operand: "$0" + color: "RED" + - index_per_ii: 10 + operations: + - opcode: "GRANT_PREDICATE" + id: 97 + time_step: 10 + invalid_iterations: 0 + src_operands: + - operand: "$0" + color: "RED" + - operand: "$4" + color: "RED" + dst_operands: + - operand: "EAST" + color: "RED" + - opcode: "CTRL_MOV" + id: 1100001 + time_step: 10 + invalid_iterations: 0 + src_operands: + - operand: "EAST" + color: "RED" + dst_operands: + - operand: "WEST" + color: "RED" + - column: 2 + row: 2 + core_id: "10" + entries: + - entry_id: "entry0" + instructions: + - index_per_ii: 0 + operations: + - opcode: "CTRL_MOV" + id: 1030001 + time_step: 11 + invalid_iterations: 1 + src_operands: + - operand: "WEST" + color: "RED" + dst_operands: + - operand: "EAST" + color: "RED" + - index_per_ii: 5 + operations: + - opcode: "DATA_MOV" + id: 500001 + time_step: 5 + invalid_iterations: 0 + src_operands: + - operand: "WEST" + color: "RED" + dst_operands: + - operand: "SOUTH" + color: "RED" + - index_per_ii: 6 + operations: + - opcode: "DATA_MOV" + id: 660001 + time_step: 6 + invalid_iterations: 0 + src_operands: + - operand: "WEST" + color: "RED" + dst_operands: + - operand: "EAST" + color: "RED" + - index_per_ii: 8 + operations: + - opcode: "NOT" + id: 95 + time_step: 8 + invalid_iterations: 0 + src_operands: + - operand: "SOUTH" + color: "RED" + dst_operands: + - operand: "SOUTH" + color: "RED" + - operand: "$1" + color: "RED" + - operand: "$0" + color: "RED" + - index_per_ii: 9 + operations: + - opcode: "GRANT_PREDICATE" + id: 106 + time_step: 9 + invalid_iterations: 0 + src_operands: + - operand: "WEST" + color: "RED" + - operand: "$1" + color: "RED" + dst_operands: + - operand: "WEST" + color: "RED" + - index_per_ii: 10 + operations: + - opcode: "GRANT_PREDICATE" + id: 105 + time_step: 10 + invalid_iterations: 0 + src_operands: + - operand: "SOUTH" + color: "RED" + - operand: "$0" + color: "RED" + dst_operands: + - operand: "EAST" + color: "RED" + - column: 3 + row: 2 + core_id: "11" + entries: + - entry_id: "entry0" + instructions: + - index_per_ii: 0 + operations: + - opcode: "CTRL_MOV" + id: 1090001 + time_step: 11 + invalid_iterations: 1 + src_operands: + - operand: "WEST" + color: "RED" + dst_operands: + - operand: "SOUTH" + color: "RED" + - index_per_ii: 1 + operations: + - opcode: "CTRL_MOV" + id: 1030002 + time_step: 12 + invalid_iterations: 1 + src_operands: + - operand: "WEST" + color: "RED" + dst_operands: + - operand: "SOUTH" + color: "RED" + - index_per_ii: 7 + operations: + - opcode: "DATA_MOV" + id: 660002 + time_step: 7 + invalid_iterations: 0 + src_operands: + - operand: "WEST" + color: "RED" + dst_operands: + - operand: "SOUTH" + color: "RED" diff --git a/test/testbench/gemv/main.go b/test/testbench/gemv/main.go new file mode 100644 index 0000000..22505f2 --- /dev/null +++ b/test/testbench/gemv/main.go @@ -0,0 +1,101 @@ +package main + +import ( + "fmt" + "log/slog" + "os" + + "github.com/sarchlab/akita/v4/sim" + "github.com/sarchlab/zeonica/api" + "github.com/sarchlab/zeonica/config" + "github.com/sarchlab/zeonica/core" +) + +func Relu() { + width := 4 + height := 4 + + engine := sim.NewSerialEngine() + + driver := api.DriverBuilder{}. + WithEngine(engine). + WithFreq(1 * sim.GHz). + Build("Driver") + + device := config.DeviceBuilder{}. + WithEngine(engine). + WithFreq(1 * sim.GHz). + WithWidth(width). + WithHeight(height). + Build("Device") + + driver.RegisterDevice(device) + + programPath := "test/testbench/gemv/gemv-instructions.yaml" + + // preload data + + data := []int32{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16} // A matrix + data2 := []int32{10, 20, 30, 40} // x vector + + for i := 0; i < len(data); i++ { + driver.PreloadMemory(1, 0, uint32(data[i]), uint32(i)) + } + for i := 0; i < len(data2); i++ { + driver.PreloadMemory(0, 1, uint32(data2[i]), uint32(i)) + } + + program := core.LoadProgramFileFromYAML(programPath) + + fmt.Println("program:", program) + + if len(program) == 0 { + panic("Failed to load program") + } + + for x := 0; x < width; x++ { + for y := 0; y < height; y++ { + coord := fmt.Sprintf("(%d,%d)", x, y) + if prog, exists := program[coord]; exists { + driver.MapProgram(prog, [2]int{x, y}) + } + } + } + + // fire all the cores in the beginning + for x := 0; x < width; x++ { + for y := 0; y < height; y++ { + tile := device.GetTile(x, y) + // convert to tileCore + tickingComponent := tile.GetTickingComponent() + engine.Schedule(sim.MakeTickEvent(tickingComponent, 0)) + } + } + + driver.Run() + + fmt.Println("========================") + fmt.Println("========================") + fmt.Println("========================") + + // get memory values in (2,3) from 0x0-0x31 + for i := 0; i < 4; i++ { + value := driver.ReadMemory(1, 1, uint32(i)) + fmt.Println("memory[", i, "]:", value) + } +} + +func main() { + f, err := os.Create("gemv.json.log") + if err != nil { + panic(err) + } + defer f.Close() + + handler := slog.NewJSONHandler(f, &slog.HandlerOptions{ + Level: core.LevelTrace, + }) + + slog.SetDefault(slog.New(handler)) + Relu() +} diff --git a/test/testbench/histogram/main.go b/test/testbench/histogram/main.go index a237d87..3376de8 100644 --- a/test/testbench/histogram/main.go +++ b/test/testbench/histogram/main.go @@ -94,7 +94,9 @@ func Histogram(rt *runtimecfg.Runtime) int { for addr := 0; addr < scanLimit; addr++ { val := driver.ReadMemory(outputTile[0], outputTile[1], uint32(addr)) outputData[addr] = val - fmt.Printf(" addr %d -> %d\n", addr, val) + if addr < len(inputData) { + fmt.Printf(" addr %d -> %d\n", addr, val) + } } fmt.Println("expected histogram (CPU):") diff --git a/test/testbench/relu/main.go b/test/testbench/relu/main.go new file mode 100644 index 0000000..e47dd49 --- /dev/null +++ b/test/testbench/relu/main.go @@ -0,0 +1,100 @@ +package main + +import ( + "fmt" + "log/slog" + "os" + + "github.com/sarchlab/akita/v4/sim" + "github.com/sarchlab/zeonica/api" + "github.com/sarchlab/zeonica/config" + "github.com/sarchlab/zeonica/core" +) + +func Relu() { + width := 4 + height := 4 + + engine := sim.NewSerialEngine() + + driver := api.DriverBuilder{}. + WithEngine(engine). + WithFreq(1 * sim.GHz). + Build("Driver") + + device := config.DeviceBuilder{}. + WithEngine(engine). + WithFreq(1 * sim.GHz). + WithWidth(width). + WithHeight(height). + Build("Device") + + driver.RegisterDevice(device) + + programPath := "test/testbench/relu/relu.yaml" + + // preload data + + data := []int32{1, -2, 3, -4, 5, -6, 7, -8, 9, -10, 11, -12, 13, 14, -15, 16, 17, 18, 19, 20, -21, 22, 23, 24, -25, 26, 27, 28, -29, 30, -31, 32} // length is 32 + + for i := 0; i < len(data); i++ { + driver.PreloadMemory(3, 2, uint32(data[i]), uint32(i)) + } + + program := core.LoadProgramFileFromYAML(programPath) + + fmt.Println("program:", program) + + if len(program) == 0 { + panic("Failed to load program") + } + + for x := 0; x < width; x++ { + for y := 0; y < height; y++ { + coord := fmt.Sprintf("(%d,%d)", x, y) + if prog, exists := program[coord]; exists { + driver.MapProgram(prog, [2]int{x, y}) + } + } + } + + // fire all the cores in the beginning + for x := 0; x < width; x++ { + for y := 0; y < height; y++ { + tile := device.GetTile(x, y) + // convert to tileCore + tickingComponent := tile.GetTickingComponent() + engine.Schedule(sim.MakeTickEvent(tickingComponent, 0)) + } + } + + // TODO: Add PreloadMemory calls if needed for relu test + // driver.PreloadMemory(x, y, data, baseAddr) + + driver.Run() + + fmt.Println("========================") + fmt.Println("========================") + fmt.Println("========================") + + // get memory values in (1,3) from 0x0-0x31 + for i := 0; i < 32; i++ { + value := driver.ReadMemory(1, 3, uint32(i)) + fmt.Println("memory[", i, "]:", value) + } +} + +func main() { + f, err := os.Create("relu.json.log") + if err != nil { + panic(err) + } + defer f.Close() + + handler := slog.NewJSONHandler(f, &slog.HandlerOptions{ + Level: core.LevelTrace, + }) + + slog.SetDefault(slog.New(handler)) + Relu() +} diff --git a/test/testbench/relu/relu-dfg-annotated.png b/test/testbench/relu/relu-dfg-annotated.png new file mode 100644 index 0000000..724f9b3 Binary files /dev/null and b/test/testbench/relu/relu-dfg-annotated.png differ diff --git a/test/testbench/relu/relu-dfg.yaml b/test/testbench/relu/relu-dfg.yaml new file mode 100644 index 0000000..732560b --- /dev/null +++ b/test/testbench/relu/relu-dfg.yaml @@ -0,0 +1,224 @@ +nodes: + - id: 0 + opcode: "GRANT_ONCE" + tile_x: 3 + tile_y: 2 + time_step: 0 + - id: 1 + opcode: "GRANT_ONCE" + tile_x: 0 + tile_y: 3 + time_step: 3 + - id: 7 + opcode: "PHI_START" + tile_x: 2 + tile_y: 2 + time_step: 1 + - id: 8 + opcode: "PHI_START" + tile_x: 0 + tile_y: 2 + time_step: 4 + - id: 10 + opcode: "DATA_MOV" + tile_x: 2 + tile_y: 3 + time_step: 4 + - id: 12 + opcode: "DATA_MOV" + tile_x: 1 + tile_y: 2 + time_step: 6 + - id: 13 + opcode: "DATA_MOV" + tile_x: 1 + tile_y: 2 + time_step: 5 + - id: 14 + opcode: "ADD" + tile_x: 2 + tile_y: 2 + time_step: 2 + - id: 15 + opcode: "GEP" + tile_x: 2 + tile_y: 3 + time_step: 5 + - id: 16 + opcode: "GEP" + tile_x: 3 + tile_y: 2 + time_step: 2 + - id: 21 + opcode: "ICMP_EQ" + tile_x: 2 + tile_y: 2 + time_step: 3 + - id: 22 + opcode: "LOAD" + tile_x: 3 + tile_y: 2 + time_step: 3 + - id: 23 + opcode: "DATA_MOV" + tile_x: 2 + tile_y: 1 + time_step: 4 + - id: 26 + opcode: "DATA_MOV" + tile_x: 1 + tile_y: 2 + time_step: 5 + - id: 28 + opcode: "GRANT_PREDICATE" + tile_x: 2 + tile_y: 1 + time_step: 5 + - id: 29 + opcode: "NOT" + tile_x: 2 + tile_y: 2 + time_step: 4 + - id: 30 + opcode: "ICMP_SGE" + tile_x: 3 + tile_y: 2 + time_step: 4 + - id: 35 + opcode: "RETURN_VOID" + tile_x: 2 + tile_y: 1 + time_step: 6 + - id: 36 + opcode: "GRANT_PREDICATE" + tile_x: 1 + tile_y: 2 + time_step: 7 + - id: 37 + opcode: "GRANT_PREDICATE" + tile_x: 2 + tile_y: 2 + time_step: 5 + - id: 38 + opcode: "SEL" + tile_x: 1 + tile_y: 2 + time_step: 6 + - id: 39 + opcode: "CTRL_MOV" + tile_x: 0 + tile_y: 2 + time_step: 8 + - id: 42 + opcode: "STORE" + tile_x: 1 + tile_y: 3 + time_step: 7 + - id: 120000 + opcode: "DATA_MOV" + tile_x: 0 + tile_y: 2 + time_step: 5 + - id: 190000 + opcode: "DATA_MOV" + tile_x: 2 + tile_y: 3 + time_step: 6 + - id: 240000 + opcode: "DATA_MOV" + tile_x: 2 + tile_y: 2 + time_step: 4 + - id: 260001 + opcode: "DATA_MOV" + tile_x: 2 + tile_y: 2 + time_step: 4 + - id: 320001 + opcode: "DATA_MOV" + tile_x: 2 + tile_y: 3 + time_step: 5 + - id: 320002 + opcode: "DATA_MOV" + tile_x: 1 + tile_y: 3 + time_step: 6 + - id: 340001 + opcode: "DATA_MOV" + tile_x: 2 + tile_y: 2 + time_step: 5 +edges: + - from: 39 + to: 8 + - from: 8 + to: 13 + - from: 13 + to: 38 + - from: 7 + to: 10 + - from: 10 + to: 15 + - from: 36 + to: 39 + - from: 21 + to: 23 + - from: 23 + to: 28 + - from: 30 + to: 340001 + - from: 22 + to: 260001 + - from: 260001 + to: 26 + - from: 26 + to: 38 + - from: 15 + to: 190000 + - from: 8 + to: 120000 + - from: 120000 + to: 12 + - from: 12 + to: 36 + - from: 29 + to: 320001 + - from: 320001 + to: 320002 + - from: 21 + to: 240000 + - from: 38 + to: 42 + - from: 29 + to: 37 + - from: 340001 + to: 38 + - from: 0 + to: 7 + - from: 14 + to: 21 + - from: 28 + to: 35 + - from: 1 + to: 8 + - from: 190000 + to: 42 + - from: 320002 + to: 36 + - from: 7 + to: 14 + - from: 37 + to: 7 + - from: 7 + to: 16 + - from: 240000 + to: 28 + - from: 14 + to: 37 + - from: 16 + to: 22 + - from: 21 + to: 29 + - from: 22 + to: 30 \ No newline at end of file diff --git a/test/testbench/relu/relu.yaml b/test/testbench/relu/relu.yaml new file mode 100644 index 0000000..65a2854 --- /dev/null +++ b/test/testbench/relu/relu.yaml @@ -0,0 +1,433 @@ +array_config: + columns: 4 + rows: 4 + compiled_ii: 5 + cores: + - column: 2 + row: 1 + core_id: "6" + entries: + - entry_id: "entry0" + instructions: + - index_per_ii: 0 + operations: + - opcode: "GRANT_PREDICATE" + id: 28 + time_step: 5 + invalid_iterations: 1 + src_operands: + - operand: "$0" + color: "RED" + - operand: "NORTH" + color: "RED" + dst_operands: + - operand: "$0" + color: "RED" + - index_per_ii: 1 + operations: + - opcode: "RETURN_VOID" + id: 35 + time_step: 6 + invalid_iterations: 1 + src_operands: + - operand: "$0" + color: "RED" + - index_per_ii: 4 + operations: + - opcode: "DATA_MOV" + id: 23 + time_step: 4 + invalid_iterations: 0 + src_operands: + - operand: "NORTH" + color: "RED" + dst_operands: + - operand: "$0" + color: "RED" + - column: 0 + row: 2 + core_id: "8" + entries: + - entry_id: "entry0" + instructions: + - index_per_ii: 0 + operations: + - opcode: "DATA_MOV" + id: 120000 + time_step: 5 + invalid_iterations: 1 + src_operands: + - operand: "$0" + color: "RED" + dst_operands: + - operand: "EAST" + color: "RED" + - index_per_ii: 3 + operations: + - opcode: "CTRL_MOV" + id: 39 + time_step: 8 + invalid_iterations: 1 + src_operands: + - operand: "EAST" + color: "RED" + dst_operands: + - operand: "$0" + color: "RED" + - index_per_ii: 4 + operations: + - opcode: "PHI_START" + id: 8 + time_step: 4 + invalid_iterations: 0 + src_operands: + - operand: "NORTH" + color: "RED" + - operand: "$0" + color: "RED" + dst_operands: + - operand: "EAST" + color: "RED" + - operand: "$0" + color: "RED" + - column: 1 + row: 2 + core_id: "9" + entries: + - entry_id: "entry0" + instructions: + - index_per_ii: 0 + operations: + - opcode: "DATA_MOV" + id: 26 + time_step: 5 + invalid_iterations: 1 + src_operands: + - operand: "EAST" + color: "RED" + dst_operands: + - operand: "$0" + color: "RED" + - opcode: "DATA_MOV" + id: 13 + time_step: 5 + invalid_iterations: 1 + src_operands: + - operand: "WEST" + color: "RED" + dst_operands: + - operand: "$1" + color: "RED" + - index_per_ii: 1 + operations: + - opcode: "SEL" + id: 38 + time_step: 6 + invalid_iterations: 1 + src_operands: + - operand: "EAST" + color: "RED" + - operand: "$0" + color: "RED" + - operand: "$1" + color: "RED" + dst_operands: + - operand: "NORTH" + color: "RED" + - opcode: "DATA_MOV" + id: 12 + time_step: 6 + invalid_iterations: 1 + src_operands: + - operand: "WEST" + color: "RED" + dst_operands: + - operand: "$0" + color: "RED" + - index_per_ii: 2 + operations: + - opcode: "GRANT_PREDICATE" + id: 36 + time_step: 7 + invalid_iterations: 1 + src_operands: + - operand: "$0" + color: "RED" + - operand: "NORTH" + color: "RED" + dst_operands: + - operand: "WEST" + color: "RED" + - column: 2 + row: 2 + core_id: "10" + entries: + - entry_id: "entry0" + instructions: + - index_per_ii: 0 + operations: + - opcode: "GRANT_PREDICATE" + id: 37 + time_step: 5 + invalid_iterations: 1 + src_operands: + - operand: "$1" + color: "RED" + - operand: "$0" + color: "RED" + dst_operands: + - operand: "$0" + color: "RED" + - opcode: "DATA_MOV" + id: 340001 + time_step: 5 + invalid_iterations: 1 + src_operands: + - operand: "EAST" + color: "RED" + dst_operands: + - operand: "WEST" + color: "RED" + - index_per_ii: 1 + operations: + - opcode: "PHI_START" + id: 7 + time_step: 1 + invalid_iterations: 0 + src_operands: + - operand: "EAST" + color: "RED" + - operand: "$0" + color: "RED" + dst_operands: + - operand: "EAST" + color: "RED" + - operand: "NORTH" + color: "RED" + - operand: "$0" + color: "RED" + - index_per_ii: 2 + operations: + - opcode: "ADD" + id: 14 + time_step: 2 + invalid_iterations: 0 + src_operands: + - operand: "$0" + color: "RED" + - operand: "#1" + color: "RED" + dst_operands: + - operand: "$0" + color: "RED" + - operand: "$1" + color: "RED" + - index_per_ii: 3 + operations: + - opcode: "ICMP_EQ" + id: 21 + time_step: 3 + invalid_iterations: 0 + src_operands: + - operand: "$0" + color: "RED" + - operand: "#32" + color: "RED" + dst_operands: + - operand: "$0" + color: "RED" + - operand: "SOUTH" + color: "RED" + - operand: "$2" + color: "RED" + - index_per_ii: 4 + operations: + - opcode: "NOT" + id: 29 + time_step: 4 + invalid_iterations: 0 + src_operands: + - operand: "$0" + color: "RED" + dst_operands: + - operand: "$0" + color: "RED" + - operand: "NORTH" + color: "RED" + - opcode: "DATA_MOV" + id: 260001 + time_step: 4 + invalid_iterations: 0 + src_operands: + - operand: "EAST" + color: "RED" + dst_operands: + - operand: "WEST" + color: "RED" + - opcode: "DATA_MOV" + id: 240000 + time_step: 4 + invalid_iterations: 0 + src_operands: + - operand: "$2" + color: "RED" + dst_operands: + - operand: "SOUTH" + color: "RED" + - column: 3 + row: 2 + core_id: "11" + entries: + - entry_id: "entry0" + instructions: + - index_per_ii: 0 + operations: + - opcode: "GRANT_ONCE" + id: 0 + time_step: 0 + invalid_iterations: 0 + src_operands: + - operand: "#0" + color: "RED" + dst_operands: + - operand: "WEST" + color: "RED" + - index_per_ii: 2 + operations: + - opcode: "GEP" + id: 16 + time_step: 2 + invalid_iterations: 0 + src_operands: + - operand: "WEST" + color: "RED" + dst_operands: + - operand: "$0" + color: "RED" + - index_per_ii: 3 + operations: + - opcode: "LOAD" + id: 22 + time_step: 3 + invalid_iterations: 0 + src_operands: + - operand: "$0" + color: "RED" + dst_operands: + - operand: "$0" + color: "RED" + - operand: "WEST" + color: "RED" + - index_per_ii: 4 + operations: + - opcode: "ICMP_SGE" + id: 30 + time_step: 4 + invalid_iterations: 0 + src_operands: + - operand: "$0" + color: "RED" + - operand: "#0" + color: "RED" + dst_operands: + - operand: "WEST" + color: "RED" + - column: 0 + row: 3 + core_id: "12" + entries: + - entry_id: "entry0" + instructions: + - index_per_ii: 3 + operations: + - opcode: "GRANT_ONCE" + id: 1 + time_step: 3 + invalid_iterations: 0 + src_operands: + - operand: "#0" + color: "RED" + dst_operands: + - operand: "SOUTH" + color: "RED" + - column: 1 + row: 3 + core_id: "13" + entries: + - entry_id: "entry0" + instructions: + - index_per_ii: 1 + operations: + - opcode: "DATA_MOV" + id: 320002 + time_step: 6 + invalid_iterations: 1 + src_operands: + - operand: "EAST" + color: "RED" + dst_operands: + - operand: "SOUTH" + color: "RED" + - index_per_ii: 2 + operations: + - opcode: "STORE" + id: 42 + time_step: 7 + invalid_iterations: 1 + src_operands: + - operand: "SOUTH" + color: "RED" + - operand: "EAST" + color: "RED" + - column: 2 + row: 3 + core_id: "14" + entries: + - entry_id: "entry0" + instructions: + - index_per_ii: 0 + operations: + - opcode: "GEP" + id: 15 + time_step: 5 + invalid_iterations: 1 + src_operands: + - operand: "$0" + color: "RED" + dst_operands: + - operand: "$0" + color: "RED" + - opcode: "DATA_MOV" + id: 320001 + time_step: 5 + invalid_iterations: 1 + src_operands: + - operand: "SOUTH" + color: "RED" + dst_operands: + - operand: "WEST" + color: "RED" + - index_per_ii: 1 + operations: + - opcode: "DATA_MOV" + id: 190000 + time_step: 6 + invalid_iterations: 1 + src_operands: + - operand: "$0" + color: "RED" + dst_operands: + - operand: "WEST" + color: "RED" + - index_per_ii: 2 + operations: + - opcode: "DATA_MOV" + id: 10 + time_step: 2 + invalid_iterations: 0 + src_operands: + - operand: "SOUTH" + color: "RED" + dst_operands: + - operand: "$0" + color: "RED"