diff --git a/.vscode/launch.json b/.vscode/launch.json index f2dd1cb..74fe7a2 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -4,6 +4,13 @@ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ + { + "name": "2D Pass Through", + "type": "go", + "request": "launch", + "mode": "auto", + "program": "${workspaceFolder}/samples/2Dpassthrough" + }, { "name": "Pass Through", "type": "go", @@ -11,6 +18,13 @@ "mode": "auto", "program": "${workspaceFolder}/samples/passthrough" }, + { + "name": "Matrix Multiplication", + "type": "go", + "request": "launch", + "mode": "auto", + "program": "${workspaceFolder}/samples/Matrixmulti" + }, { "name": "Test core", "type": "go", diff --git a/.vscode/settings.json b/.vscode/settings.json index 124ab45..d1d3cbb 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,5 +1,7 @@ { "cSpell.words": [ - "cgra" + "cgra", + "sarchlab", + "zeonica" ] } \ No newline at end of file diff --git a/api/driver.go b/api/driver.go index d362dfa..90ab1be 100644 --- a/api/driver.go +++ b/api/driver.go @@ -11,6 +11,8 @@ import ( // Driver provides the interface to control an accelerator. type Driver interface { + sim.Component + // RegisterDevice registers a device to the driver. The driver will // establish connections to the device. RegisterDevice(device cgra.Device) @@ -106,7 +108,10 @@ func (d *driverImpl) doOneFeedInTask(task *feedInTask) bool { if err != nil { panic("CGRA cannot handle the data rate") } - //fmt.Printf("Feed in %d to %v\n", task.data[task.round*task.stride+i], task.remotePorts[i]) + fmt.Printf("%10f, Feed in %d to %s\n", + d.Engine.CurrentTime()*1e9, + task.data[task.round*task.stride+i], + task.remotePorts[i].Name()) madeProgress = true } diff --git a/config/config.go b/config/config.go index c4f567d..7d2353d 100644 --- a/config/config.go +++ b/config/config.go @@ -4,6 +4,7 @@ package config import ( "fmt" + "github.com/sarchlab/akita/v3/monitoring" "github.com/sarchlab/akita/v3/noc/networking/mesh" "github.com/sarchlab/akita/v3/sim" "github.com/sarchlab/zeonica/cgra" @@ -14,6 +15,7 @@ import ( type DeviceBuilder struct { engine sim.Engine freq sim.Freq + monitor *monitoring.Monitor width, height int } @@ -29,6 +31,12 @@ func (d DeviceBuilder) WithFreq(freq sim.Freq) DeviceBuilder { return d } +// WithMonitor sets the monitor that monitors the device. +func (d DeviceBuilder) WithMonitor(monitor *monitoring.Monitor) DeviceBuilder { + d.monitor = monitor + return d +} + // WithWidth sets the width of CGRA mesh. func (d DeviceBuilder) WithWidth(width int) DeviceBuilder { d.width = width @@ -55,6 +63,9 @@ func (d DeviceBuilder) Build(name string) cgra.Device { WithFreq(d.freq). WithSwitchLatency(1). WithBandwidth(1) + if d.monitor != nil { + nocConnector = nocConnector.WithMonitor(d.monitor) + } nocConnector.CreateNetwork(name + ".Mesh") d.createTiles(dev, name, nocConnector) @@ -80,6 +91,10 @@ func (d DeviceBuilder) createTiles( WithFreq(d.freq). Build(coreName) + if d.monitor != nil { + d.monitor.RegisterComponent(tile.Core) + } + dev.Tiles[y][x] = tile nocConnector.AddTile( diff --git a/core/core.go b/core/core.go index 545a290..726f19b 100644 --- a/core/core.go +++ b/core/core.go @@ -35,7 +35,8 @@ func (c *Core) MapProgram(program []string) { // Tick runs the program for one cycle. func (c *Core) Tick(now sim.VTimeInSec) (madeProgress bool) { madeProgress = c.doRecv() || madeProgress - madeProgress = c.AlwaysPart() || madeProgress + // madeProgress = c.AlwaysPart() || madeProgress + madeProgress = c.emu.runRoutingRules(&c.state) || madeProgress madeProgress = c.runProgram() || madeProgress madeProgress = c.doSend() || madeProgress return madeProgress @@ -79,10 +80,15 @@ func (c *Core) doRecv() bool { madeProgress := false for i := 0; i < 4; i++ { //direction - item := c.ports[cgra.Side(i)].local.Retrieve(c.Engine.CurrentTime()) + item := c.ports[cgra.Side(i)].local.Peek() if item == nil { continue } + + // fmt.Printf("%10f, %s, %d retrieved\n", + // c.Engine.CurrentTime()*1e9, + // c.Name(), cgra.Side(i)) + //fmt.Printf("%s Scanning direction %d(0 is North, 3 is West)\n", c.Name(), i) for color := 0; color < 4; color++ { //fmt.Printf("%s Receiving Data with color %d. Recv buffer head: %+v\n", @@ -90,10 +96,12 @@ func (c *Core) doRecv() bool { if c.state.RecvBufHeadReady[color][i] { continue } + msg := item.(*cgra.MoveMsg) if color != msg.Color { continue } + c.state.RecvBufHeadReady[color][i] = true c.state.RecvBufHead[color][i] = msg.Data @@ -102,6 +110,8 @@ func (c *Core) doRecv() bool { c.Name(), msg.Data, msg.Src.Name(), msg.Dst.Name(), color) + + c.ports[cgra.Side(i)].local.Retrieve(c.Engine.CurrentTime()) madeProgress = true } } @@ -144,11 +154,13 @@ func (c *Core) AlwaysPart() bool { c.state.PC++ inst = c.state.Code[c.state.PC] } + for strings.HasPrefix(inst, "@") { prevPC := c.state.PC parts := strings.Split(inst, ",") instName := parts[0] instName = strings.TrimLeft(instName, "@") + switch instName { case "ROUTER_FORWARD": madeProgress = c.Router(parts[1], parts[2], parts[3]) || madeProgress @@ -157,17 +169,21 @@ func (c *Core) AlwaysPart() bool { default: panic("Invalid Instruction") } + c.state.PC++ nextPC := c.state.PC if prevPC == nextPC { return false } + fmt.Printf("%10f, %s, Inst %s\n", c.Engine.CurrentTime()*1e9, c.Name(), inst) if int(c.state.PC) >= len(c.state.Code) { return false } + inst = c.state.Code[c.state.PC] } + return madeProgress } diff --git a/core/emu.go b/core/emu.go index d56bf12..4662cbf 100644 --- a/core/emu.go +++ b/core/emu.go @@ -1,6 +1,7 @@ package core import ( + "fmt" "math" "strconv" "strings" @@ -8,15 +9,31 @@ import ( "github.com/sarchlab/zeonica/cgra" ) +type routingRule struct { + src cgra.Side + dst cgra.Side + color string +} + +// type trigger struct { +// src cgra.Side +// color string +// pc int +// } + type coreState struct { - PC uint32 - TileX, TileY uint32 - Registers []uint32 - Code []string + PC uint32 + TileX, TileY uint32 + Registers []uint32 + Code []string + RecvBufHead [][]uint32 //[Color][Direction] RecvBufHeadReady [][]bool SendBufHead [][]uint32 SendBufHeadBusy [][]bool + + routingRules []*routingRule + //triggers []*trigger } type instEmulator struct { @@ -40,13 +57,21 @@ func (i instEmulator) RunInst(inst string, state *coreState) { // } instFuncs := map[string]func([]string, *coreState){ - "WAIT": i.runWait, - "SEND": i.runSend, - "JMP": i.runJmp, - "CMP": i.runCmp, - "JEQ": i.runJeq, - "DONE": func(_ []string, _ *coreState) { i.runDone() }, // Since runDone might not have parameters - "MAC": i.runMac, + "WAIT": i.runWait, + "SEND": i.runSend, + "JMP": i.runJmp, + "CMP": i.runCmp, + "JEQ": i.runJeq, + "JNE": i.runJne, + "DONE": func(_ []string, _ *coreState) { i.runDone() }, // Since runDone might not have parameters + "MAC": i.runMac, + "CONFIG_ROUTING": i.runConfigRouting, + "TRIGGER_SEND": i.runTriggerSend, + "TRIGGER_TWO_SIDE": i.runTriggerTwoSide, + "ADDI": i.runIAdd, + "IDLE": func(_ []string, state *coreState) { i.runIdle(state) }, + "RECV_SEND": i.runRecvSend, + "TRIGGER_ONE_SIDE": i.runTriggerOneSide, } if instFunc, ok := instFuncs[instName]; ok { @@ -56,7 +81,7 @@ func (i instEmulator) RunInst(inst string, state *coreState) { } } -func (i instEmulator) getIndex(side string) int { +func (i instEmulator) getDirecIndex(side string) int { var srcIndex int switch side { @@ -103,6 +128,10 @@ func (i instEmulator) getColorIndex(color string) int { } } +/** + * @description: + * @prototype: + */ func (i instEmulator) runWait(inst []string, state *coreState) { dst := inst[1] src := inst[2] @@ -111,7 +140,7 @@ func (i instEmulator) runWait(inst []string, state *coreState) { i.waitSrcMustBeNetRecvReg(src) direction := src[9:] - srcIndex := i.getIndex(direction) + srcIndex := i.getDirecIndex(direction) if !state.RecvBufHeadReady[colorIndex][srcIndex] { return @@ -128,6 +157,10 @@ func (i instEmulator) waitSrcMustBeNetRecvReg(src string) { } } +/** + * @description: + * @prototype: + */ func (i instEmulator) runSend(inst []string, state *coreState) { dst := inst[1] src := inst[2] @@ -136,7 +169,7 @@ func (i instEmulator) runSend(inst []string, state *coreState) { i.sendDstMustBeNetSendReg(dst) direction := dst[9:] - dstIndex := i.getIndex(direction) + dstIndex := i.getDirecIndex(direction) if state.SendBufHeadBusy[colorIndex][dstIndex] { return @@ -154,9 +187,16 @@ func (i instEmulator) sendDstMustBeNetSendReg(dst string) { } } +/** + * @description: + * @prototype: + */ func (i instEmulator) runJmp(inst []string, state *coreState) { dst := inst[1] + i.Jump(dst, state) +} +func (i instEmulator) Jump(dst string, state *coreState) { for i := 0; i < len(state.Code); i++ { line := strings.Trim(state.Code[i], " \t\n") if strings.HasPrefix(line, dst) && strings.HasSuffix(line, ":") { @@ -190,6 +230,10 @@ func (i instEmulator) writeOperand(operand string, value uint32, state *coreStat } } +/** + * @description: + * @prototype:F32_CMP_[], Cmp_Res, Cmp_Src, imme + */ func (i instEmulator) runCmp(inst []string, state *coreState) { Itype := inst[0] //Float or Integer @@ -269,6 +313,10 @@ func (i instEmulator) parseAndCompareF32(inst []string, state *coreState) { state.PC++ } +/** + * @description: + * @prototype: + */ func (i instEmulator) runJeq(inst []string, state *coreState) { src := inst[2] imme, err := strconv.ParseUint(inst[3], 10, 32) @@ -286,10 +334,36 @@ func (i instEmulator) runJeq(inst []string, state *coreState) { } } +/** + * @description: + * @prototype: + */ +func (i instEmulator) runJne(inst []string, state *coreState) { + src := inst[2] + imme, err := strconv.ParseUint(inst[3], 10, 32) + + if err != nil { + panic("invalid compare number") + } + + srcVal := i.readOperand(src, state) + + if srcVal != uint32(imme) { + i.runJmp(inst, state) + } else { + state.PC++ + } +} + +/** + * @description: + * Get data from + * @prototype: MAC, DstReg, SrcReg1, SrcReg2 + */ func (i instEmulator) runMac(inst []string, state *coreState) { + dst := inst[1] src1 := inst[2] src2 := inst[3] - dst := inst[1] srcVal1 := i.readOperand(src1, state) srcVal2 := i.readOperand(src2, state) @@ -297,9 +371,210 @@ func (i instEmulator) runMac(inst []string, state *coreState) { dstVal += srcVal1 * srcVal2 i.writeOperand(dst, dstVal, state) + fmt.Printf("Mac Instruction, Data are %v and %v, Res is %v\n", srcVal1, srcVal2, dstVal) + state.PC++ } func (i instEmulator) runDone() { // Do nothing. } + +func (i instEmulator) runConfigRouting(inst []string, state *coreState) { + src := inst[2] + dst := inst[1] + color := inst[3] + + rule := &routingRule{ + src: cgra.Side(i.getDirecIndex(src)), + dst: cgra.Side(i.getDirecIndex(dst)), + color: color, + } + + i.addRoutingRule(rule, state) + state.PC++ +} + +func (i instEmulator) addRoutingRule(rule *routingRule, state *coreState) { + for _, r := range state.routingRules { + if r.src == rule.src && r.color == rule.color { + r.dst = rule.dst + return + } + } + + state.routingRules = append(state.routingRules, rule) +} + +func (i instEmulator) runRoutingRules(state *coreState) (madeProgress bool) { + for _, rule := range state.routingRules { + srcIndex := int(rule.src) + dstIndex := int(rule.dst) + colorIndex := i.getColorIndex(rule.color) + + if !state.RecvBufHeadReady[colorIndex][srcIndex] { + continue + } + + if state.SendBufHeadBusy[colorIndex][dstIndex] { + continue + } + + state.RecvBufHeadReady[colorIndex][srcIndex] = false + state.SendBufHeadBusy[colorIndex][dstIndex] = true + state.SendBufHead[colorIndex][dstIndex] = + state.RecvBufHead[colorIndex][srcIndex] + madeProgress = true + + fmt.Printf("Tile[%d][%d], %s->%s, %s\n", + state.TileX, state.TileY, + rule.src.Name(), rule.dst.Name(), rule.color) + } + + return madeProgress +} + +/** + * @description: If data is sent to the src side of the current tile, the instruction will receive it, + * save it to the register and send the old data to the dst side of the current tile, + * with no time consumed. (We need some dummy tail!!!) + * @prototype: Trigger_Send, dst, reg, src, color + */ +func (i instEmulator) runTriggerSend(inst []string, state *coreState) { + src := inst[1] + reg := inst[2] + dst := inst[3] + color := inst[4] + + srcIndex := i.getDirecIndex(src) + dstIndex := i.getDirecIndex(dst) + colorIndex := i.getColorIndex(color) + + if state.RecvBufHeadReady[colorIndex][srcIndex] && + state.SendBufHeadBusy[colorIndex][dstIndex] { + dataRecv := state.RecvBufHead[colorIndex][srcIndex] + dataSend := i.readOperand(reg, state) + + i.writeOperand(reg, dataRecv, state) + + state.RecvBufHeadReady[colorIndex][srcIndex] = false + state.SendBufHeadBusy[colorIndex][dstIndex] = true + state.SendBufHead[colorIndex][dstIndex] = dataSend + } + state.PC++ +} + +/** + * @description: When the data from two sides are available, trigger the code block. + * @prototype: Trigger_Two_Side, $Code_Block$, Src1, Src2 + */ +func (i instEmulator) runTriggerTwoSide(inst []string, state *coreState) { + codeBlock := inst[1] + src1 := inst[2] + src2 := inst[3] + + parts1 := strings.Split(src1, "_") + parts2 := strings.Split(src2, "_") + + src1Index := i.getDirecIndex(parts1[0]) + src2Index := i.getDirecIndex(parts2[0]) + color1Index := i.getColorIndex(parts1[1]) + color2Index := i.getColorIndex(parts2[1]) + + if state.RecvBufHeadReady[color1Index][src1Index] && + state.RecvBufHeadReady[color2Index][src2Index] { + fmt.Print("Triggered\n") + i.Jump(codeBlock, state) + return + } + fmt.Print("Untriggered\n") + state.PC++ +} + +/** + * @description: When the data from the side is available, trigger the code block. + * @prototype: Trigger_One_Side, $Code_Block$, Src + */ +func (i instEmulator) runTriggerOneSide(inst []string, state *coreState) { + codeBlock := inst[1] + src := inst[2] + + parts := strings.Split(src, "_") + + srcIndex := i.getDirecIndex(parts[0]) + colorIndex := i.getColorIndex(parts[1]) + + if state.RecvBufHeadReady[colorIndex][srcIndex] { + i.Jump(codeBlock, state) + return + } + state.PC++ +} + +/** + * @description: Add two numbers together. The input could be register or immediate number. + * @prototype: ADD, DstReg, SrcReg1, SrcReg2(Imme) + */ +func (i instEmulator) runIAdd(inst []string, state *coreState) { + dst := inst[1] + src1 := inst[2] + src2 := inst[3] + src1Val := i.readOperand(src1, state) + var src2Val uint32 + src2flag := false + + if strings.HasPrefix(src2, "$") { + src2flag = true + } + + if src2flag { + src2Val = i.readOperand(src2, state) + } else { + num, err := strconv.ParseUint(src2, 10, 32) + if err != nil { + fmt.Printf("Error: %v\n", err) + return + } + src2Val = uint32(num) + } + dstVal := src1Val + src2Val + i.writeOperand(dst, dstVal, state) + state.PC++ +} + +// Waste One time click +func (i instEmulator) runIdle(state *coreState) { + state.PC++ +} + +// RECV_SEND Dst, DstReg, Src +func (i instEmulator) runRecvSend(inst []string, state *coreState) { + dst := inst[1] + dstReg := inst[2] + src := inst[3] + + srcParts := strings.Split(src, "_") + dstParts := strings.Split(dst, "_") + + srcIndex := i.getDirecIndex(srcParts[0]) + dstIndex := i.getDirecIndex(dstParts[0]) + srcColorIndex := i.getColorIndex(srcParts[1]) + dstColorIndex := i.getColorIndex(dstParts[1]) + + if !state.RecvBufHeadReady[srcColorIndex][srcIndex] { + return + } + + val := state.RecvBufHead[srcColorIndex][srcIndex] + state.RecvBufHeadReady[srcColorIndex][srcIndex] = false + + i.writeOperand(dstReg, val, state) + + if state.SendBufHeadBusy[dstColorIndex][dstIndex] { + return + } + + state.SendBufHeadBusy[dstColorIndex][dstIndex] = true + state.SendBufHead[dstColorIndex][dstIndex] = val + state.PC++ +} diff --git a/samples/2Dpassthrough/2Dpassthrough b/samples/2Dpassthrough/2Dpassthrough deleted file mode 100755 index 41f9d24..0000000 Binary files a/samples/2Dpassthrough/2Dpassthrough and /dev/null differ diff --git a/samples/2Dpassthrough/2Dpassthrough.cgraasm b/samples/2Dpassthrough/2Dpassthrough.cgraasm index 962e2db..8e518a2 100644 --- a/samples/2Dpassthrough/2Dpassthrough.cgraasm +++ b/samples/2Dpassthrough/2Dpassthrough.cgraasm @@ -1,2 +1,2 @@ -@ROUTER_FORWARD,EAST,WEST,R -@ROUTER_FORWARD,SOUTH,NORTH,R \ No newline at end of file +CONFIG_ROUTING,EAST,WEST,R +CONFIG_ROUTING,SOUTH,NORTH,R \ No newline at end of file diff --git a/samples/2Dpassthrough/main.go b/samples/2Dpassthrough/main.go index 6b29fb4..081963e 100644 --- a/samples/2Dpassthrough/main.go +++ b/samples/2Dpassthrough/main.go @@ -3,7 +3,9 @@ package main import ( _ "embed" "fmt" + "time" + "github.com/sarchlab/akita/v3/monitoring" "github.com/sarchlab/akita/v3/sim" "github.com/sarchlab/zeonica/api" "github.com/sarchlab/zeonica/cgra" @@ -11,28 +13,28 @@ import ( "github.com/tebeka/atexit" ) -var width = 4 -var height = 4 +var width = 1 +var height = 1 //go:embed 2Dpassthrough.cgraasm var passThroughKernel string func passThrough(driver api.Driver) { - length := 8 + length := 2 src1 := make([]uint32, length) src2 := make([]uint32, length) dst1 := make([]uint32, length) dst2 := make([]uint32, length) for i := 0; i < length; i++ { - src1[i] = uint32(i) - src2[i] = uint32(length - i - 1) + src1[i] = uint32(i + 1) + src2[i] = uint32(length - i) } driver.FeedIn(src1, cgra.West, [2]int{0, height}, height, "R") - driver.FeedIn(src2, cgra.North, [2]int{0, height}, height, "R") + driver.FeedIn(src2, cgra.North, [2]int{0, height}, width, "R") driver.Collect(dst1, cgra.East, [2]int{0, height}, height, "R") - driver.Collect(dst2, cgra.South, [2]int{0, height}, height, "R") + driver.Collect(dst2, cgra.South, [2]int{0, height}, width, "R") for x := 0; x < width; x++ { for y := 0; y < height; y++ { @@ -49,23 +51,31 @@ func passThrough(driver api.Driver) { } func main() { + monitor := monitoring.NewMonitor() + engine := sim.NewSerialEngine() + monitor.RegisterEngine(engine) driver := api.DriverBuilder{}. WithEngine(engine). WithFreq(1 * sim.GHz). Build("Driver") + monitor.RegisterComponent(driver) device := config.DeviceBuilder{}. WithEngine(engine). WithFreq(1 * sim.GHz). WithWidth(width). WithHeight(height). + WithMonitor(monitor). Build("Device") driver.RegisterDevice(device) + monitor.StartServer() + passThrough(driver) + time.Sleep(100 * time.Hour) atexit.Exit(0) } diff --git a/samples/matrixmulti/main.go b/samples/matrixmulti/main.go index 572f2e8..1674eb9 100644 --- a/samples/matrixmulti/main.go +++ b/samples/matrixmulti/main.go @@ -3,7 +3,9 @@ package main import ( _ "embed" "fmt" + "time" + "github.com/sarchlab/akita/v3/monitoring" "github.com/sarchlab/akita/v3/sim" "github.com/sarchlab/zeonica/api" "github.com/sarchlab/zeonica/cgra" @@ -11,36 +13,43 @@ import ( "github.com/tebeka/atexit" ) -var width = 3 -var height = 3 +var width = 2 +var height = 2 //go:embed matrixmulti.cgraasm -var matrixMulti string +var matrixMultiKernal string //go:embed output.cgraasm var output string -func passThrough(driver api.Driver) { +func matrixMulti(driver api.Driver) { //1 2 3 //4 5 6 //7 8 9 - src1 := [15]uint32{1, 0, 0, 2, 4, 0, 3, 5, 7, 0, 6, 8, 0, 0, 9} + //src1 := []uint32{1, 0, 0, 2, 4, 0, 3, 5, 7, 0, 6, 8, 0, 0, 9} + src1 := []uint32{1, 0, 2, 4, 0, 3} //9 8 7 //6 5 4 //3 2 1 - src2 := [15]uint32{9, 0, 0, 6, 8, 0, 3, 5, 7, 0, 2, 4, 0, 0, 1} - dst := make([]uint32, 9) + //src2 := []uint32{9, 0, 0, 6, 8, 0, 3, 5, 7, 0, 2, 4, 0, 0, 1} //no need zeros + src2 := []uint32{9, 0, 6, 8, 5, 0} + src1Collect := make([]uint32, len(src1)) + src2Collect := make([]uint32, len(src1)) + dst := make([]uint32, 6) driver.FeedIn(src1[:], cgra.West, [2]int{0, height}, height, "R") driver.FeedIn(src2[:], cgra.North, [2]int{0, width}, width, "R") + driver.Collect(src1Collect, cgra.North, [2]int{0, height}, height, "R") //for matrix source data. + driver.Collect(src2Collect, cgra.North, [2]int{0, height}, height, "R") for x := 0; x < width; x++ { for y := 0; y < height; y++ { - driver.MapProgram(matrixMulti, [2]int{x, y}) + driver.MapProgram(matrixMultiKernal, [2]int{x, y}) } } driver.Run() - driver.Collect(dst, cgra.North, [2]int{0, height}, height, "Y") + driver.FeedIn(src2[:], cgra.North, [2]int{0, width}, width, "B") //for output signal + driver.Collect(dst, cgra.North, [2]int{0, height}, height, "B") //for output for x := width - 1; x > -1; x-- { for y := 0; y < height; y++ { driver.MapProgram(output, [2]int{x, y}) @@ -51,23 +60,31 @@ func passThrough(driver api.Driver) { } func main() { + monitor := monitoring.NewMonitor() + engine := sim.NewSerialEngine() + monitor.RegisterEngine(engine) driver := api.DriverBuilder{}. WithEngine(engine). WithFreq(1 * sim.GHz). Build("Driver") + monitor.RegisterComponent(driver) device := config.DeviceBuilder{}. WithEngine(engine). WithFreq(1 * sim.GHz). WithWidth(width). WithHeight(height). + WithMonitor(monitor). Build("Device") driver.RegisterDevice(device) - passThrough(driver) + monitor.StartServer() + + matrixMulti(driver) + time.Sleep(100 * time.Hour) atexit.Exit(0) } diff --git a/samples/matrixmulti/matrixmulti.cgraasm b/samples/matrixmulti/matrixmulti.cgraasm index ffc507c..9df58f9 100644 --- a/samples/matrixmulti/matrixmulti.cgraasm +++ b/samples/matrixmulti/matrixmulti.cgraasm @@ -1,7 +1,12 @@ -@ROUTER_FORWARD -@ROUTER_FORWARD -@WAIT_AND -@CONDITION_SEND START: + TRIGGER_TWO_SIDE, COMPUT, WEST_R, NORTH_R + TRIGGER_ONE_SIDE, SHIFT, NORTH_B + JMP, START sleep for all possible trigger +COMPUT: + RECV_SEND, SOUTH_R, $1, NORTH_R + RECV_SEND, EAST_R, $2, WEST_R MAC, $3, $1, $2 - JMP, START \ No newline at end of file + JMP, START sleep for all possible trigger +SHIFT: + RECV_SEND, SOUTH_B, $3, NORTH_B + sleep for all possible trigger \ No newline at end of file diff --git a/samples/matrixmulti/result.cgraasm b/samples/matrixmulti/result.cgraasm new file mode 100644 index 0000000..d754e99 --- /dev/null +++ b/samples/matrixmulti/result.cgraasm @@ -0,0 +1,4 @@ +START: + WAIT, $0, NET_RECV_WEST, R + SEND, NET_SEND_EAST, $0, R + JMP, START \ No newline at end of file