Skip to content

Commit fb7f039

Browse files
committed
shared memory under test
1 parent f07c03e commit fb7f039

9 files changed

Lines changed: 738 additions & 64 deletions

File tree

config/config.go

Lines changed: 44 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package config
33

44
import (
55
"fmt"
6+
"strconv"
67

78
"github.com/sarchlab/akita/v4/mem/idealmemcontroller"
89
"github.com/sarchlab/akita/v4/mem/mem"
@@ -20,8 +21,8 @@ type DeviceBuilder struct {
2021
monitor *monitoring.Monitor
2122
//portFactory portFactory
2223
width, height int
23-
memoryMode string // simple or shared or local
24-
memoryShare [][][]int // [[ [x1, y1], [x2, y2], ...], [ [x1, y1], [x2, y2], ...], ...]
24+
memoryMode string // simple or shared or local
25+
memoryShare map[[2]int]int //map[[x, y]]GroupID
2526
}
2627

2728
// type portFactory interface {
@@ -65,7 +66,7 @@ func (d DeviceBuilder) WithMemoryMode(mode string) DeviceBuilder {
6566
}
6667

6768
// WithMemoryShare sets the memory sharing configuration.
68-
func (d DeviceBuilder) WithMemoryShare(share [][][]int) DeviceBuilder {
69+
func (d DeviceBuilder) WithMemoryShare(share map[[2]int]int) DeviceBuilder {
6970
d.memoryShare = share
7071
return d
7172
}
@@ -90,39 +91,47 @@ func (d DeviceBuilder) createSharedMemory(dev *device) {
9091
if d.memoryMode == "shared" {
9192
// Create shared memory controller
9293

93-
// Connect tiles to shared memory based on memoryShare configuration
94-
for groupIndex, group := range d.memoryShare {
95-
// Create a connection for this memory group
94+
controllers := make(map[int]*idealmemcontroller.Comp)
95+
connections := make(map[int]*directconnection.Comp)
9696

97-
sharedMem := idealmemcontroller.MakeBuilder().
98-
WithEngine(d.engine).
99-
WithNewStorage(4 * mem.GB).
100-
WithLatency(5).
101-
Build("SharedMemory")
102-
103-
connName := fmt.Sprintf("MemConn_Group_%d", groupIndex)
104-
conn := directconnection.MakeBuilder().
105-
WithEngine(d.engine).
106-
WithFreq(d.freq).
107-
Build(connName)
108-
109-
// Connect shared memory to the connection
110-
conn.PlugIn(sharedMem.GetPortByName("Top"))
111-
112-
// Connect each tile in this group to the shared memory
113-
for _, tileCoords := range group {
114-
x, y := tileCoords[0], tileCoords[1]
115-
if x >= 0 && x < d.width && y >= 0 && y < d.height {
116-
tile := dev.Tiles[y][x]
117-
// Create a memory port for this tile
118-
memPort := tile.Core.GetPortByName("Memory")
119-
conn.PlugIn(memPort)
120-
121-
// Store the connection for later use
122-
123-
// Configure the core to use shared memory
124-
// This would need to be implemented in the core to set UseSharedMemory = true
125-
// and set the SharedMemoryPort
97+
for x := 0; x < d.width; x++ {
98+
for y := 0; y < d.height; y++ {
99+
tile := dev.Tiles[y][x]
100+
// if has mapping
101+
if _, ok := d.memoryShare[[2]int{x, y}]; !ok {
102+
panic("No mapping for tile " + strconv.Itoa(x) + "," + strconv.Itoa(y))
103+
}
104+
groupID := d.memoryShare[[2]int{x, y}]
105+
if _, ok := controllers[groupID]; !ok {
106+
// has not been created yet, create it
107+
controller := idealmemcontroller.MakeBuilder().
108+
WithEngine(d.engine).
109+
WithNewStorage(4 * mem.GB).
110+
WithLatency(5).
111+
Build("SharedMemory")
112+
controllers[groupID] = controller
113+
114+
name := fmt.Sprintf("SharedMemory%d%d", x, y)
115+
116+
conn := directconnection.MakeBuilder().
117+
WithEngine(d.engine).
118+
WithFreq(d.freq).
119+
Build(name)
120+
conn.PlugIn(controller.GetPortByName("Top"))
121+
conn.PlugIn(tile.Core.GetPortByName("Router"))
122+
connections[groupID] = conn
123+
tile.SetRemotePort(cgra.Router, controller.GetPortByName("Top").AsRemote())
124+
tile.SharedMemoryController = controller
125+
dev.SharedMemoryControllers = append(dev.SharedMemoryControllers, controller)
126+
127+
fmt.Println("Connect Tile (", x, ",", y, ") to SharedMemory Controller (", groupID, ") (new-created)")
128+
} else {
129+
// plug in the controller to the tile
130+
fmt.Println("Connect Tile (", x, ",", y, ") to SharedMemory Controller (", groupID, ") (already-created)")
131+
connections[groupID].PlugIn(tile.Core.GetPortByName("Router"))
132+
tile.SetRemotePort(cgra.Router, controllers[groupID].GetPortByName("Top").AsRemote())
133+
tile.SharedMemoryController = controllers[groupID]
134+
dev.SharedMemoryControllers = append(dev.SharedMemoryControllers, controllers[groupID])
126135
}
127136
}
128137
}

core/core.go

Lines changed: 52 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,10 @@ func (c *Core) Tick() (madeProgress bool) {
8585
return madeProgress
8686
}
8787

88+
func makeBytesFromUint32(data uint32) []byte {
89+
return []byte{byte(data >> 24), byte(data >> 16), byte(data >> 8), byte(data)}
90+
}
91+
8892
func (c *Core) doSend() bool {
8993
madeProgress := false
9094
for i := 0; i < 8; i++ { // only 8 directions
@@ -124,7 +128,27 @@ func (c *Core) doSend() bool {
124128
if c.state.SendBufHeadBusy[c.emu.getColorIndex("R")][cgra.Router] { // only one port, must be Router-red
125129

126130
if c.state.IsToWriteMemory {
131+
msg := mem.WriteReqBuilder{}.
132+
WithAddress(uint64(c.state.AddrBuf)).
133+
WithData(makeBytesFromUint32(c.state.SendBufHead[c.emu.getColorIndex("R")][cgra.Router])).
134+
WithSrc(c.ports[cgra.Side(cgra.Router)].local.AsRemote()).
135+
WithDst(c.ports[cgra.Side(cgra.Router)].remote).
136+
Build()
137+
138+
err := c.ports[cgra.Side(cgra.Router)].local.Send(msg)
139+
if err != nil {
140+
return madeProgress
141+
}
127142

143+
Trace("Memory",
144+
"Behavior", "Send",
145+
slog.Float64("Time", float64(c.Engine.CurrentTime()*1e9)),
146+
"Data", c.state.SendBufHead[c.emu.getColorIndex("R")][cgra.Router],
147+
"Color", "R",
148+
"Src", msg.Src,
149+
"Dst", msg.Dst,
150+
)
151+
c.state.SendBufHeadBusy[c.emu.getColorIndex("R")][cgra.Router] = false
128152
} else {
129153
msg := mem.ReadReqBuilder{}.
130154
WithAddress(uint64(c.state.AddrBuf)).
@@ -207,22 +231,37 @@ func (c *Core) doRecv() bool {
207231
return madeProgress
208232
}
209233

210-
msg := item.(*mem.DataReadyRsp)
234+
// if msg is DataReadyRsp, then the data is ready
235+
if msg, ok := item.(*mem.DataReadyRsp); ok {
236+
c.state.RecvBufHeadReady[c.emu.getColorIndex("R")][cgra.Router] = true
237+
c.state.RecvBufHead[c.emu.getColorIndex("R")][cgra.Router] = convert4BytesToUint32(msg.Data)
211238

212-
c.state.RecvBufHeadReady[c.emu.getColorIndex("R")][cgra.Router] = true
213-
c.state.RecvBufHead[c.emu.getColorIndex("R")][cgra.Router] = convert4BytesToUint32(msg.Data)
239+
Trace("Memory",
240+
"Behavior", "Recv",
241+
"Time", float64(c.Engine.CurrentTime()*1e9),
242+
"Data", msg.Data,
243+
"Src", msg.Src,
244+
"Dst", msg.Dst,
245+
"Color", "R",
246+
)
214247

215-
Trace("Memory",
216-
"Behavior", "Recv",
217-
"Time", float64(c.Engine.CurrentTime()*1e9),
218-
"Data", msg.Data,
219-
"Src", msg.Src,
220-
"Dst", msg.Dst,
221-
"Color", "R",
222-
)
248+
c.ports[cgra.Side(cgra.Router)].local.RetrieveIncoming()
249+
madeProgress = true
250+
} else if msg, ok := item.(*mem.WriteDoneRsp); ok {
251+
c.state.RecvBufHeadReady[c.emu.getColorIndex("R")][cgra.Router] = true
252+
c.state.RecvBufHead[c.emu.getColorIndex("R")][cgra.Router] = 0
223253

224-
c.ports[cgra.Side(cgra.Router)].local.RetrieveIncoming()
225-
madeProgress = true
254+
Trace("Memory",
255+
"Behavior", "Recv",
256+
"Time", float64(c.Engine.CurrentTime()*1e9),
257+
"Src", msg.Src,
258+
"Dst", msg.Dst,
259+
"Color", "R",
260+
)
261+
262+
c.ports[cgra.Side(cgra.Router)].local.RetrieveIncoming()
263+
madeProgress = true
264+
}
226265
}
227266

228267
return madeProgress

core/emu.go

Lines changed: 46 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -336,8 +336,12 @@ func (i instEmulator) RunOperation(inst Operation, state *coreState, time float6
336336
"LDD": i.runLoadDirect,
337337
"STD": i.runStoreDirect,
338338

339-
"LD": i.runLoadDRAM,
340-
"LDW": i.runLoadWaitDRAM,
339+
"LD": i.runLoadDRAM,
340+
"LDW": i.runLoadWaitDRAM,
341+
342+
"ST": i.runStoreDRAM,
343+
"STW": i.runStoreWaitDRAM,
344+
341345
"TRIGGER": i.runTrigger,
342346
}
343347

@@ -589,30 +593,29 @@ func (i instEmulator) runLoadDirect(inst Operation, state *coreState) {
589593
func (i instEmulator) runLoadDRAM(inst Operation, state *coreState) {
590594
src1 := inst.SrcOperands.Operands[0]
591595
addr := i.readOperand(src1, state)
592-
593-
// only send the read request
594-
pseudo_operand := Operand{
595-
Impl: "Router",
596-
Color: "R",
596+
dst := inst.DstOperands.Operands[0]
597+
if dst.Impl != "Router" {
598+
panic("the destination of a LOAD_DRAM instruction must be Router")
597599
}
600+
598601
slog.Warn("DRAM",
599602
"Behavior", "LoadDRAM",
600603
"Addr", addr,
601604
"X", state.TileX,
602605
"Y", state.TileY,
603606
)
604-
i.writeOperand(pseudo_operand, addr, state)
607+
i.writeOperand(dst, addr, state)
605608
state.AddrBuf = addr
606609
state.IsToWriteMemory = false // not for write memory
607610
}
608611

609612
func (i instEmulator) runLoadWaitDRAM(inst Operation, state *coreState) {
610-
pseudo_operand := Operand{
611-
Impl: "Router",
612-
Color: "R",
613-
}
613+
src := inst.SrcOperands.Operands[0]
614614

615-
value := i.readOperand(pseudo_operand, state)
615+
if src.Impl != "Router" {
616+
panic("the source of a LOAD_WAIT_DRAM instruction must be Router")
617+
}
618+
value := i.readOperand(src, state)
616619

617620
for _, dst := range inst.DstOperands.Operands {
618621
i.writeOperand(dst, value, state)
@@ -638,6 +641,36 @@ func (i instEmulator) runStoreDirect(inst Operation, state *coreState) {
638641
// elect no next PC
639642
}
640643

644+
func (i instEmulator) runStoreDRAM(inst Operation, state *coreState) {
645+
src1 := inst.SrcOperands.Operands[0]
646+
addr := i.readOperand(src1, state)
647+
src2 := inst.SrcOperands.Operands[1]
648+
value := i.readOperand(src2, state)
649+
dst := inst.DstOperands.Operands[0]
650+
if dst.Impl != "Router" {
651+
panic("the destination of a STORE_DRAM instruction must be Router")
652+
}
653+
654+
slog.Warn("DRAM",
655+
"Behavior", "StoreDRAM",
656+
"Addr", addr,
657+
"Value", value,
658+
"X", state.TileX,
659+
"Y", state.TileY,
660+
)
661+
i.writeOperand(dst, value, state) // store the value to the data channel
662+
state.AddrBuf = addr
663+
state.IsToWriteMemory = true // for write memory
664+
}
665+
666+
func (i instEmulator) runStoreWaitDRAM(inst Operation, state *coreState) {
667+
src := inst.SrcOperands.Operands[0]
668+
if src.Impl != "Router" {
669+
panic("the source of a STORE_WAIT_DRAM instruction must be Router")
670+
}
671+
i.readOperand(src, state) // do nothing, only get the write done
672+
}
673+
641674
func (i instEmulator) runTrigger(inst Operation, state *coreState) {
642675
src := inst.SrcOperands.Operands[0]
643676
i.readOperand(src, state)

core/emu_unit_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ var _ = Describe("InstEmulator", func() {
3636
}
3737
})
3838

39-
var mul_const_inst = CombinedInst{
40-
Insts: []Inst{
39+
var mul_const_inst = InstructionGroup{
40+
Operations: []Operation{
4141
{
4242
OpCode: "MUL",
4343
SrcOperands: OperandList{
@@ -59,7 +59,7 @@ var _ = Describe("InstEmulator", func() {
5959
Describe("MUL_CONST", func() {
6060
It("should multiply register by immediate", func() {
6161
s.Registers[0] = 5
62-
ie.RunCombinedInst(mul_const_inst, &s)
62+
ie.RunInstructionGroup(mul_const_inst, &s, 0)
6363
Expect(s.Registers[1]).To(Equal(uint32(15)))
6464
Expect(s.PCInBlock).To(Equal(int32(0)))
6565
// in the test, there is no SelectedBlock, so emu will not increase the PCInBlock

go.mod

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,10 @@ require (
1313
)
1414

1515
require (
16+
filippo.io/edwards25519 v1.1.0 // indirect
1617
github.com/go-logr/logr v1.4.2 // indirect
1718
github.com/go-ole/go-ole v1.3.0 // indirect
19+
github.com/go-sql-driver/mysql v1.8.1 // indirect
1820
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
1921
github.com/google/go-cmp v0.6.0 // indirect
2022
github.com/google/pprof v0.0.0-20240829160300-da1f7e9f2b25 // indirect

go.sum

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
2+
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
13
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
24
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
35
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
@@ -7,6 +9,8 @@ github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ4
79
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
810
github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
911
github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
12+
github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
13+
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
1014
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
1115
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
1216
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=

0 commit comments

Comments
 (0)