More bus doc #266

This commit is contained in:
Dolu1990 2022-09-26 11:39:58 +02:00
parent 051d140c33
commit 7b9891829a
1 changed files with 104 additions and 0 deletions

104
README.md
View File

@ -868,6 +868,41 @@ Simple and light multi-way instruction cache.
Note: If you enable the twoCycleRam option and if wayCount is bigger than one, then the register file plugin should be configured to read the regFile in an asynchronous manner.
The memory bus is defined as :
```scala
case class InstructionCacheMemCmd(p : InstructionCacheConfig) extends Bundle{
val address = UInt(p.addressWidth bit)
val size = UInt(log2Up(log2Up(p.bytePerLine) + 1) bits)
}
case class InstructionCacheMemRsp(p : InstructionCacheConfig) extends Bundle{
val data = Bits(p.memDataWidth bit)
val error = Bool
}
case class InstructionCacheMemBus(p : InstructionCacheConfig) extends Bundle with IMasterSlave{
val cmd = Stream (InstructionCacheMemCmd(p))
val rsp = Flow (InstructionCacheMemRsp(p))
override def asMaster(): Unit = {
master(cmd)
slave(rsp)
}
}
```
The address is in byte and aligned to the bytePerLine config, the size will always be equal to log2(bytePerLine).
Note that the cmd stream transaction need to be consumed before starting to send back some rsp transactions (1 cycle minimal latency)
Some documentation about Stream here :
https://spinalhdl.github.io/SpinalDoc-RTD/master/SpinalHDL/Libraries/stream.html?highlight=stream
Flow are the same as Stream but without ready signal.
#### DecoderSimplePlugin
This plugin provides instruction decoding capabilities to other plugins.
@ -1046,6 +1081,75 @@ Multi way cache implementation with writh-through and allocate on read strategy.
You can invalidate the whole cache via the 0x500F instruction, and you can invalidate a address range (single line size) via the instruction 0x500F | RS1 << 15 where RS1 should not be X0 and point to one byte of the desired address to invalidate.
The memory bus is defined as :
```scala
case class DataCacheMemCmd(p : DataCacheConfig) extends Bundle{
val wr = Bool
val uncached = Bool
val address = UInt(p.addressWidth bit)
val data = Bits(p.cpuDataWidth bits)
val mask = Bits(p.cpuDataWidth/8 bits)
val size = UInt(p.sizeWidth bits) //... 1 => 2 bytes ... 2 => 4 bytes ...
val exclusive = p.withExclusive generate Bool()
val last = Bool
}
case class DataCacheMemRsp(p : DataCacheConfig) extends Bundle{
val aggregated = UInt(p.aggregationWidth bits)
val last = Bool()
val data = Bits(p.memDataWidth bit)
val error = Bool
val exclusive = p.withExclusive generate Bool()
}
case class DataCacheInv(p : DataCacheConfig) extends Bundle{
val enable = Bool()
val address = UInt(p.addressWidth bit)
}
case class DataCacheAck(p : DataCacheConfig) extends Bundle{
val hit = Bool()
}
case class DataCacheSync(p : DataCacheConfig) extends Bundle{
val aggregated = UInt(p.aggregationWidth bits)
}
case class DataCacheMemBus(p : DataCacheConfig) extends Bundle with IMasterSlave{
val cmd = Stream (DataCacheMemCmd(p))
val rsp = Flow (DataCacheMemRsp(p))
val inv = p.withInvalidate generate Stream(Fragment(DataCacheInv(p)))
val ack = p.withInvalidate generate Stream(Fragment(DataCacheAck(p)))
val sync = p.withInvalidate generate Stream(DataCacheSync(p))
override def asMaster(): Unit = {
master(cmd)
slave(rsp)
if(p.withInvalidate) {
slave(inv)
master(ack)
slave(sync)
}
}
}
```
If you don't use memory coherency you can ignore the inv/ack/sync streams, also write cmd should not generate any rsp transaction.
As the cache is write through, there is no write burst but only individual write transactions.
The address is in byte and aligned to the bytePerLine config, the size will is encoded as log2(number of bytes in the burst).
last should be set only on the last transaction of a burst.
Note that the cmd stream transaction need to be consumed before starting to send back some rsp transactions (1 cycle minimal latency)
Some documentation about Stream here :
https://spinalhdl.github.io/SpinalDoc-RTD/master/SpinalHDL/Libraries/stream.html?highlight=stream
Flow are the same as Stream but without ready signal.
#### MulPlugin
Implements the multiplication instruction from the RISC-V M extension. Its implementation was done in a FPGA friendly way by using 4 17*17 bit multiplications.