-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add the CsrManager for the Post-Processing SIMD datapath (#6)
* add simd top and test * testNum from 1 to 100 * address commnets for 3+1 csr
- Loading branch information
1 parent
382770a
commit c69eee0
Showing
4 changed files
with
440 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
package simd | ||
|
||
import chisel3._ | ||
import chisel3.util._ | ||
|
||
/** simplified csr read/write cmd | ||
* | ||
* @param csrAddrWidth | ||
* csr registers address width | ||
*/ | ||
class CsrReq(csrAddrWidth: Int) extends Bundle { | ||
val data = UInt(32.W) | ||
val addr = UInt(csrAddrWidth.W) | ||
val write = Bool() | ||
} | ||
|
||
class CsrRsp extends Bundle { | ||
val data = UInt(32.W) | ||
} | ||
|
||
/** This class represents the csr input and output ports of the streamer top | ||
* module | ||
* | ||
* @param csrAddrWidth | ||
* csr registers address width | ||
*/ | ||
class CsrReqRspIO(csrAddrWidth: Int) extends Bundle { | ||
|
||
val req = Flipped(Decoupled(new CsrReq(csrAddrWidth))) | ||
val rsp = Decoupled(new CsrRsp) | ||
|
||
} | ||
|
||
/** This class represents the input and output ports of the CsrManager module. | ||
* The input is connected to the SNAX CSR port. The output is connected to the | ||
* streamer configuration port. | ||
* @param csrNum | ||
* the number of csr registers | ||
* @param csrAddrWidth | ||
* the width of the address | ||
*/ | ||
class CsrManagerIO( | ||
csrNum: Int, | ||
csrAddrWidth: Int | ||
) extends Bundle { | ||
|
||
val csr_config_in = new CsrReqRspIO(csrAddrWidth) | ||
val csr_config_out = Decoupled(Vec(csrNum, UInt(32.W))) | ||
|
||
} | ||
|
||
/** This class represents the CsrManager module. It contains the csr registers | ||
* and the read and write control logic. | ||
* @param csrNum | ||
* the number of csr registers | ||
* @param csrAddrWidth | ||
* the width of the address | ||
*/ | ||
class CsrManager( | ||
csrNum: Int, | ||
csrAddrWidth: Int | ||
) extends Module | ||
with RequireAsyncReset { | ||
|
||
val io = IO(new CsrManagerIO(csrNum, csrAddrWidth)) | ||
|
||
// generate a vector of registers to store the csr state | ||
val csr = RegInit(VecInit(Seq.fill(csrNum)(0.U(32.W)))) | ||
|
||
// read and write csr cmd | ||
val read_csr = io.csr_config_in.req.fire && !io.csr_config_in.req.bits.write | ||
val write_csr = io.csr_config_in.req.fire && io.csr_config_in.req.bits.write | ||
|
||
// keep sending response to a read request until we receive the response ready signal | ||
val keep_sending_csr_rsp = RegNext( | ||
io.csr_config_in.rsp.valid && !io.csr_config_in.rsp.ready | ||
) | ||
// a register to store the read request response data until the request is successful | ||
val csr_rsp_data_reg = RegInit(0.U(32.W)) | ||
|
||
// store the csr data for later output because the address only valid when io.csr.fire | ||
csr_rsp_data_reg := Mux( | ||
read_csr, | ||
csr(io.csr_config_in.req.bits.addr), | ||
csr_rsp_data_reg | ||
) | ||
|
||
// streamer configuration valid signal | ||
val config_valid = WireInit(0.B) | ||
|
||
// check if the csr address overflow (access certain csr that doesn't exist) | ||
def startCsrAddr = (csrNum - 1).U | ||
|
||
when(io.csr_config_in.req.fire) { | ||
|
||
assert( | ||
io.csr_config_in.req.bits.addr <= startCsrAddr, | ||
"csr address overflow!" | ||
) | ||
|
||
} | ||
|
||
// write req | ||
when(write_csr) { | ||
csr(io.csr_config_in.req.bits.addr) := io.csr_config_in.req.bits.data | ||
} | ||
|
||
// handle read requests: keep sending response data until the request succeeds | ||
when(read_csr) { | ||
io.csr_config_in.rsp.bits.data := csr(io.csr_config_in.req.bits.addr) | ||
io.csr_config_in.rsp.valid := 1.B | ||
}.elsewhen(keep_sending_csr_rsp) { | ||
io.csr_config_in.rsp.bits.data := csr_rsp_data_reg | ||
io.csr_config_in.rsp.valid := 1.B | ||
}.otherwise { | ||
io.csr_config_in.rsp.valid := 0.B | ||
io.csr_config_in.rsp.bits.data := 0.U | ||
} | ||
|
||
// we are ready for a new request if two conditions hold: | ||
// if we write to the config_valid register (the last one), the streamer must not be busy (io.csr_config_out.ready) | ||
// if there is a read request in progress, we only accept new write requests | ||
io.csr_config_in.req.ready := (io.csr_config_out.ready || !(io.csr_config_in.req.bits.addr === startCsrAddr)) && (!keep_sending_csr_rsp || io.csr_config_in.req.bits.write) | ||
|
||
// a write/read to the last csr means the config is valid | ||
config_valid := io.csr_config_in.req.fire && (io.csr_config_in.req.bits.addr === startCsrAddr) | ||
|
||
// signals connected to the output ports | ||
io.csr_config_out.bits <> csr | ||
io.csr_config_out.valid <> config_valid | ||
|
||
} | ||
|
||
// Scala main function for generating CsrManager system verilog file | ||
object CsrManager extends App { | ||
emitVerilog( | ||
new CsrManager( | ||
SIMDConstant.csrNum, | ||
SIMDConstant.csrAddrWidth | ||
), | ||
Array("--target-dir", "generated/csr_manager") | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
package simd | ||
|
||
import chisel3._ | ||
import chisel3.util._ | ||
|
||
class SIMDTopIO() extends Bundle { | ||
val csr = new CsrReqRspIO(SIMDConstant.csrAddrWidth) | ||
val data = new SIMDDataIO() | ||
} | ||
|
||
// post-processing SIMD with uniformed interface: csr (snax side) and data ports (streamer side) | ||
class SIMDTop() extends Module with RequireAsyncReset { | ||
|
||
val io = IO(new SIMDTopIO()) | ||
|
||
val csrManager = Module( | ||
new CsrManager(SIMDConstant.csrNum, SIMDConstant.csrAddrWidth) | ||
) | ||
val simd = Module(new SIMD()) | ||
|
||
// io.csr and csrManager input connection | ||
csrManager.io.csr_config_in <> io.csr | ||
|
||
// csrManager output and simd control port connection | ||
// control signals | ||
simd.io.ctrl.valid := csrManager.io.csr_config_out.valid | ||
csrManager.io.csr_config_out.ready := simd.io.ctrl.ready | ||
|
||
// splitting csrManager data ports to the simd configuration ports | ||
// the meanings of these ports can be found at PE.scala | ||
// the order is also the same as at PE.scala | ||
// as each control input port is 8 bits so 4 control input port shares 1 csr | ||
simd.io.ctrl.bits.input_zp_i := csrManager.io.csr_config_out | ||
.bits(0)(7, 0) | ||
.asSInt | ||
simd.io.ctrl.bits.output_zp_i := csrManager.io.csr_config_out | ||
.bits(0)(15, 8) | ||
.asSInt | ||
|
||
// this control input port is 32 bits, so it needs 1 csr | ||
simd.io.ctrl.bits.multiplier_i := csrManager.io.csr_config_out.bits(2).asSInt | ||
|
||
simd.io.ctrl.bits.shift_i := | ||
csrManager.io.csr_config_out.bits(0)(23, 16).asSInt | ||
simd.io.ctrl.bits.max_int_i := | ||
csrManager.io.csr_config_out.bits(0)(31, 24).asSInt | ||
|
||
simd.io.ctrl.bits.min_int_i := | ||
csrManager.io.csr_config_out.bits(1)(7, 0).asSInt | ||
|
||
// this control input port is only 1 bit | ||
simd.io.ctrl.bits.double_round_i := | ||
csrManager.io.csr_config_out.bits(1)(8).asBool | ||
|
||
io.data <> simd.io.data | ||
|
||
} | ||
|
||
object SIMDTop extends App { | ||
emitVerilog( | ||
new (SIMDTop), | ||
Array("--target-dir", "generated/simd") | ||
) | ||
} |
Oops, something went wrong.