Skip to content

Commit

Permalink
Remove flipped bus from MemPortIO, moving it a new IO bundle in mem p…
Browse files Browse the repository at this point in the history
…orts
  • Loading branch information
Jared Barocsi committed Jul 25, 2019
1 parent bd27852 commit 49e4b66
Show file tree
Hide file tree
Showing 8 changed files with 76 additions and 73 deletions.
5 changes: 0 additions & 5 deletions src/main/scala/base-cpu.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,4 @@ class CoreIO extends Bundle {

class BaseCPU extends Module {
val io = IO(new CoreIO())

// These signals are not and should not be used in the CPU implementation at all -
// they correspond with the port<=>memory connection, but we are in the pipeline<=> port side
io.imem.bus <> 0.U.asTypeOf(new MemPortBusIO)
io.dmem.bus <> 0.U.asTypeOf(new MemPortBusIO)
}
21 changes: 16 additions & 5 deletions src/main/scala/components/memory/base-memory-components.scala
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,26 @@ abstract class BaseDualPortedMemory(size: Int, memfile: String) extends Module {
* Base class for all instruction ports. Simply declares the IO.
*/
abstract class BaseIMemPort extends Module {
val io = IO (new IMemPortIO)
io <> 0.U.asTypeOf (new IMemPortIO)
val io = IO (new Bundle {
val pipeline = new IMemPortIO
val bus = Flipped (new MemPortBusIO)
})

io.pipeline <> 0.U.asTypeOf (new IMemPortIO)
io.bus <> 0.U.asTypeOf (new MemPortBusIO)
}

/**
* Base class for all data ports. Simply declares the IO.
*/
abstract class BaseDMemPort extends Module {
val io = IO (new DMemPortIO)
io <> 0.U.asTypeOf (new DMemPortIO)
io.good := io.bus.response.valid
val io = IO (new Bundle {
val pipeline = new DMemPortIO
val bus = Flipped (new MemPortBusIO)
})

io.pipeline <> 0.U.asTypeOf (new DMemPortIO)
io.bus <> 0.U.asTypeOf (new MemPortBusIO)

io.pipeline.good := io.bus.response.valid
}
46 changes: 23 additions & 23 deletions src/main/scala/components/memory/memory-combin-ports.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ import dinocpu.MemoryOperation._
*/
class ICombinMemPort extends BaseIMemPort {
// When the pipeline is supplying a high valid signal
when (io.valid) {
when (io.pipeline.valid) {
val request = Wire(new Request)
request.address := io.address
request.address := io.pipeline.address
request.operation := Read
request.writedata := 0.U

Expand All @@ -26,8 +26,8 @@ class ICombinMemPort extends BaseIMemPort {
}

// When the memory is outputting a valid instruction
io.good := io.bus.response.valid
io.instruction := io.bus.response.bits.data
io.pipeline.good := io.bus.response.valid
io.pipeline.instruction := io.bus.response.bits.data
}

/**
Expand All @@ -36,16 +36,16 @@ class ICombinMemPort extends BaseIMemPort {
* The I/O for this module is defined in [[DMemPortIO]].
*/
class DCombinMemPort extends BaseDMemPort {
io.good := io.bus.response.valid && io.memread && !io.memwrite
io.pipeline.good := io.bus.response.valid && io.pipeline.memread && !io.pipeline.memwrite

when (io.valid && (io.memread || io.memwrite)) {
when (io.pipeline.valid && (io.pipeline.memread || io.pipeline.memwrite)) {
// Check that we are not issuing a read and write at the same time
assert(!(io.memread && io.memwrite))
assert(!(io.pipeline.memread && io.pipeline.memwrite))

io.bus.request.bits.address := io.address
io.bus.request.bits.address := io.pipeline.address
io.bus.request.valid := true.B

when (io.memwrite) {
when (io.pipeline.memwrite) {
// We issue a ReadWrite to the backing memory.
// Basic run-down of the ReadWrite operation:
// - DCombinMemPort sends a ReadWrite at a specific address, **addr**.
Expand All @@ -66,53 +66,53 @@ class DCombinMemPort extends BaseDMemPort {

// Response path
when (io.bus.response.valid) {
when (io.memwrite) {
when (io.pipeline.memwrite) {
// Perform writedata modification and send it down io.request.writedata.
val writedata = Wire (UInt (32.W))

// When not writing a whole word
when (io.maskmode =/= 2.U) {
when (io.pipeline.maskmode =/= 2.U) {
// Read in the existing piece of data at the address, so we "overwrite" only part of it
val offset = io.address (1, 0)
val offset = io.pipeline.address (1, 0)
val readdata = Wire (UInt (32.W))

readdata := io.bus.response.bits.data

val data = Wire (UInt (32.W))
// Mask the portion of the existing data so it can be or'd with the writedata
when (io.maskmode === 0.U) {
when (io.pipeline.maskmode === 0.U) {
data := readdata & ~(0xff.U << (offset * 8.U))
} .otherwise {
data := readdata & ~(0xffff.U << (offset * 8.U))
}
writedata := data | (io.writedata << (offset * 8.U))
writedata := data | (io.pipeline.writedata << (offset * 8.U))
} .otherwise {
// Write the entire word
writedata := io.writedata
writedata := io.pipeline.writedata
}

io.bus.request.bits.writedata := writedata
} .elsewhen (io.memread) {
} .elsewhen (io.pipeline.memread) {
// Perform normal masking and sign extension on the read data
val readdata_mask = Wire(UInt(32.W))
val readdata_mask_sext = Wire(UInt(32.W))

val offset = io.address(1,0)
when (io.maskmode === 0.U) {
val offset = io.pipeline.address(1,0)
when (io.pipeline.maskmode === 0.U) {
// Byte
readdata_mask := (io.bus.response.bits.data >> (offset * 8.U)) & 0xff.U
} .elsewhen (io.maskmode === 1.U) {
} .elsewhen (io.pipeline.maskmode === 1.U) {
// Half-word
readdata_mask := (io.bus.response.bits.data >> (offset * 8.U)) & 0xffff.U
} .otherwise {
readdata_mask := io.bus.response.bits.data
}

when (io.sext) {
when (io.maskmode === 0.U) {
when (io.pipeline.sext) {
when (io.pipeline.maskmode === 0.U) {
// Byte sign extension
readdata_mask_sext := Cat(Fill(24, readdata_mask(7)), readdata_mask(7, 0))
} .elsewhen (io.maskmode === 1.U) {
} .elsewhen (io.pipeline.maskmode === 1.U) {
// Half-word sign extension
readdata_mask_sext := Cat(Fill(16, readdata_mask(15)), readdata_mask(15, 0))
} .otherwise {
Expand All @@ -123,7 +123,7 @@ class DCombinMemPort extends BaseDMemPort {
readdata_mask_sext := readdata_mask
}

io.readdata := readdata_mask_sext
io.pipeline.readdata := readdata_mask_sext
}
}
}
18 changes: 9 additions & 9 deletions src/main/scala/components/memory/memory-noncombin-ports.scala
Original file line number Diff line number Diff line change
Expand Up @@ -45,26 +45,26 @@ class DNonCombinMemPort extends BaseDMemPort {
// it has been satisfied this cycle. Note: we cannot send a read until one cycle after the write has
// been sent.
val ready = !outstandingReq.valid || (io.bus.response.valid && (outstandingReq.valid && outstandingReq.bits.operation === MemoryOperation.Read))
when (io.valid && (io.memread || io.memwrite) && ready) {
when (io.pipeline.valid && (io.pipeline.memread || io.pipeline.memwrite) && ready) {
// Check if we aren't issuing both a read and write at the same time
assert (! (io.memread && io.memwrite))
assert (! (io.pipeline.memread && io.pipeline.memwrite))

// On either a read or write we must read a whole block from memory. Store the necessary
// information to redirect the memory's response back into itself through a write
// operation and get the right subset of the block on a read.
outstandingReq.bits.address := io.address
outstandingReq.bits.writedata := io.writedata
outstandingReq.bits.maskmode := io.maskmode
outstandingReq.bits.sext := io.sext
when (io.memwrite) {
outstandingReq.bits.address := io.pipeline.address
outstandingReq.bits.writedata := io.pipeline.writedata
outstandingReq.bits.maskmode := io.pipeline.maskmode
outstandingReq.bits.sext := io.pipeline.sext
when (io.pipeline.memwrite) {
outstandingReq.bits.operation := Write
} .otherwise {
outstandingReq.bits.operation := Read
}
sending := true.B

// Program memory to perform a read. Always read since we must read before write.
io.bus.request.bits.address := io.address
io.bus.request.bits.address := io.pipeline.address
io.bus.request.bits.writedata := 0.U
io.bus.request.bits.operation := Read
io.bus.request.valid := true.B
Expand Down Expand Up @@ -138,7 +138,7 @@ class DNonCombinMemPort extends BaseDMemPort {
readdata_mask_sext := readdata_mask
}

io.readdata := readdata_mask_sext
io.pipeline.readdata := readdata_mask_sext
}
// Mark the outstanding request register as being invalid, unless sending
outstandingReq.valid := sending
Expand Down
3 changes: 0 additions & 3 deletions src/main/scala/components/memory/memory-port-io.scala
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,6 @@ class MemPortIO extends Bundle {
val address = Input(UInt(32.W))
val valid = Input(Bool())
val good = Output(Bool())

// Port <=> Memory
val bus = Flipped(new MemPortBusIO)
}

/**
Expand Down
4 changes: 2 additions & 2 deletions src/main/scala/top.scala
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@ class Top(val conf: CPUConfig) extends Module
val dmem = Module(conf.getDMemPort())

mem.wireMemory (imem, dmem)
cpu.io.imem <> imem.io
cpu.io.dmem <> dmem.io
cpu.io.imem <> imem.io.pipeline
cpu.io.dmem <> dmem.io.pipeline
}
26 changes: 13 additions & 13 deletions src/test/scala/components/CombinMemoryUnitTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -44,19 +44,19 @@ class CombinMemoryTestHarness(size: Int, memFile: String) extends Module {
memory.io := DontCare


imem.io.address := io.imem_address
imem.io.valid := io.imem_valid
io.imem_instruction := imem.io.instruction
io.imem_good := imem.io.good
dmem.io.address := io.dmem_address
dmem.io.valid := io.dmem_valid
dmem.io.writedata := io.dmem_writedata
dmem.io.memread := io.dmem_memread
dmem.io.memwrite := io.dmem_memwrite
dmem.io.maskmode := io.dmem_maskmode
dmem.io.sext := io.dmem_sext
io.dmem_readdata := dmem.io.readdata
io.dmem_good := dmem.io.good
imem.io.pipeline.address := io.imem_address
imem.io.pipeline.valid := io.imem_valid
io.imem_instruction := imem.io.pipeline.instruction
io.imem_good := imem.io.pipeline.good
dmem.io.pipeline.address := io.dmem_address
dmem.io.pipeline.valid := io.dmem_valid
dmem.io.pipeline.writedata := io.dmem_writedata
dmem.io.pipeline.memread := io.dmem_memread
dmem.io.pipeline.memwrite := io.dmem_memwrite
dmem.io.pipeline.maskmode := io.dmem_maskmode
dmem.io.pipeline.sext := io.dmem_sext
io.dmem_readdata := dmem.io.pipeline.readdata
io.dmem_good := dmem.io.pipeline.good

memory.wireMemory (imem, dmem)
}
Expand Down
26 changes: 13 additions & 13 deletions src/test/scala/components/NonCombinMemoryUnitTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -47,19 +47,19 @@ class NonCombinMemoryTestHarness(size: Int, memFile: String, latency: Int) exten
memory.io := DontCare


imem.io.address := io.imem_address
imem.io.valid := io.imem_valid
io.imem_instruction := imem.io.instruction
io.imem_good := imem.io.good
dmem.io.address := io.dmem_address
dmem.io.valid := io.dmem_valid
dmem.io.writedata := io.dmem_writedata
dmem.io.memread := io.dmem_memread
dmem.io.memwrite := io.dmem_memwrite
dmem.io.maskmode := io.dmem_maskmode
dmem.io.sext := io.dmem_sext
io.dmem_readdata := dmem.io.readdata
io.dmem_good := dmem.io.good
imem.io.pipeline.address := io.imem_address
imem.io.pipeline.valid := io.imem_valid
io.imem_instruction := imem.io.pipeline.instruction
io.imem_good := imem.io.pipeline.good
dmem.io.pipeline.address := io.dmem_address
dmem.io.pipeline.valid := io.dmem_valid
dmem.io.pipeline.writedata := io.dmem_writedata
dmem.io.pipeline.memread := io.dmem_memread
dmem.io.pipeline.memwrite := io.dmem_memwrite
dmem.io.pipeline.maskmode := io.dmem_maskmode
dmem.io.pipeline.sext := io.dmem_sext
io.dmem_readdata := dmem.io.pipeline.readdata
io.dmem_good := dmem.io.pipeline.good

memory.wireMemory (imem, dmem)
}
Expand Down

0 comments on commit 49e4b66

Please sign in to comment.