Skip to content
This repository has been archived by the owner on May 28, 2024. It is now read-only.

Commit

Permalink
add implementation of sender receiver synchronizer module
Browse files Browse the repository at this point in the history
  • Loading branch information
SinaKarvandi committed Apr 18, 2024
1 parent 0dbb93c commit 1b2f889
Show file tree
Hide file tree
Showing 3 changed files with 213 additions and 14 deletions.
13 changes: 7 additions & 6 deletions src/main/scala/hwdbg/communication/receiver.scala
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,11 @@ class DebuggerPacketReceiver(
//
val requestedActionOfThePacketOutput = Output(UInt(new DebuggerRemotePacket().RequestedActionOfThePacket.getWidth.W)) // the requested action
val requestedActionOfThePacketOutputValid = Output(Bool()) // whether data on the requested action is valid or not
val noNewData = Input(Bool()) // receive done or not?
val noNewDataReceiver = Input(Bool()) // receive done or not?

// (this contains and edge-detection mechanism, which means reader should make it low after reading the data)
// this contains and edge-detection mechanism, which means reader should make it low after reading the data
val readNextData = Input(Bool()) // whether the next data should be read or not?

val dataValidOutput = Output(Bool()) // whether data on the receiving data line is valid or not?
val receivingData = Output(UInt(bramDataWidth.W)) // data to be sent to the reader

Expand Down Expand Up @@ -141,7 +142,7 @@ class DebuggerPacketReceiver(
regRequestedActionOfThePacketOutputValid := false.B
regDataValidOutput := false.B
regReceivingData := 0.U
regFinishedIReceivingBuffer := false.B
regFinishedReceivingBuffer := false.B

}
is(sReadChecksum) {
Expand Down Expand Up @@ -254,7 +255,7 @@ class DebuggerPacketReceiver(
//
state := sReadActionBuffer

}.elsewhen(io.noNewData === true.B && io.readNextData === false.B) {
}.elsewhen(io.noNewDataReceiver === true.B && io.readNextData === false.B) {

//
// No new data, the receiving is done
Expand Down Expand Up @@ -330,7 +331,7 @@ object DebuggerPacketReceiver {
en: Bool,
plInSignal: Bool,
rdData: UInt,
noNewData: Bool,
noNewDataReceiver: Bool,
readNextData: Bool
): (UInt, UInt, Bool, Bool, UInt, Bool) = {

Expand All @@ -355,7 +356,7 @@ object DebuggerPacketReceiver {
debuggerPacketReceiver.io.en := en
debuggerPacketReceiver.io.plInSignal := plInSignal
debuggerPacketReceiver.io.rdData := rdData
debuggerPacketReceiver.io.noNewData := noNewData
debuggerPacketReceiver.io.noNewDataReceiver := noNewDataReceiver
debuggerPacketReceiver.io.readNextData := readNextData

//
Expand Down
206 changes: 202 additions & 4 deletions src/main/scala/hwdbg/communication/send_receive_synchronizer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,30 @@
package hwdbg.communication

import chisel3._
import chisel3.util.{switch, is}
import circt.stage.ChiselStage

import hwdbg.configs._
import hwdbg.types._

object SendReceiveSynchronizerEnums {
object State extends ChiselEnum {
val sIdle, sReceiver, sSender = Value
}
}

class SendReceiveSynchronizer(
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
bramAddrWidth: Int = DebuggerConfigurations.BLOCK_RAM_ADDR_WIDTH,
bramDataWidth: Int = DebuggerConfigurations.BLOCK_RAM_DATA_WIDTH
) extends Module {

//
// Import state enum
//
import SendReceiveSynchronizerEnums.State
import SendReceiveSynchronizerEnums.State._

val io = IO(new Bundle {

//
Expand All @@ -49,19 +62,24 @@ class SendReceiveSynchronizer(
val wrData = Output(UInt(bramDataWidth.W)) // write data

//
// Receiver ports
// Receiver signals
//
val requestedActionOfThePacketOutput = Output(UInt(new DebuggerRemotePacket().RequestedActionOfThePacket.getWidth.W)) // the requested action
val requestedActionOfThePacketOutputValid = Output(Bool()) // whether data on the requested action is valid or not

val noNewDataReceiver = Input(Bool()) // receive done or not?
val readNextData = Input(Bool()) // whether the next data should be read or not?

val dataValidOutput = Output(Bool()) // whether data on the receiving data line is valid or not?
val receivingData = Output(UInt(bramDataWidth.W)) // data to be sent to the reader
val finishedReceivingBuffer = Output(Bool()) // receiving is done or not?

val finishedReceivingBuffer = Output(Bool()) // Receiving is done or not?

//
// Sender ports
//
val beginSendingBuffer = Input(Bool()) // should sender start sending buffers or not?
val noNewData = Input(Bool()) // should sender finish sending buffers or not?
val noNewDataSender = Input(Bool()) // should sender finish sending buffers or not?
val dataValidInput = Input(Bool()) // should sender send next buffer or not?

val sendWaitForBuffer = Output(Bool()) // should the external module send next buffer or not?
Expand All @@ -73,9 +91,189 @@ class SendReceiveSynchronizer(
})

//
// To be implemented
// State registers
//
val state = RegInit(sIdle)

//
// Saving state of the controlling pins
//
val regPlInSignal = RegInit(false.B)
val regBeginSendingBuffer = RegInit(false.B)

//
// Shared BRAM pins
//
val sharedRdWrAddr = WireInit(0.U(bramAddrWidth.W)) // read/write address
val sharedRdData = WireInit(0.U(bramDataWidth.W)) // read data
val sharedWrEna = WireInit(false.B) // enable writing
val sharedWrData = WireInit(0.U(bramDataWidth.W)) // write data

//
// Instantiate the packet receiver module
//
val (
receiverRdWrAddr,
requestedActionOfThePacketOutput,
requestedActionOfThePacketOutputValid,
dataValidOutput,
receivingData,
finishedReceivingBuffer
) =
DebuggerPacketReceiver(
debug,
bramAddrWidth,
bramDataWidth
)(
io.en,
regPlInSignal,
io.rdData,
io.noNewDataReceiver,
io.readNextData
)

//
// Instantiate the packet sender module
//
val (
psOutInterrupt,
senderRdWrAddr,
wrEna,
wrData,
sendWaitForBuffer,
finishedSendingBuffer
) =
DebuggerPacketSender(
debug,
bramAddrWidth,
bramDataWidth
)(
io.en,
regBeginSendingBuffer,
io.noNewDataSender,
io.dataValidInput,
io.requestedActionOfThePacketInput,
io.sendingData
)

//
// Apply the chip enable signal
//
when(io.en === true.B) {

switch(state) {

is(sIdle) {

//
// Peform the resource sepration of shared BRAM
// and apply priority to receive over send
//
when(io.plInSignal === true.B) {

//
// Activate the receiver module
//
regPlInSignal := true.B

//
// Go to the receiver state
//
state := sReceiver

}.elsewhen(io.beginSendingBuffer === true.B && io.plInSignal === false.B) {

//
// Activate the sender module
//
regBeginSendingBuffer := true.B

//
// Go to the sender state
//
state := sReceiver

}.otherwise {

//
// Stay at the same state as there is no communication
//
state := sIdle

}

}
is(sReceiver) {

//
// Check whether the receiving is finished
//
when(finishedReceivingBuffer === true.B) {

//
// No longer in the receiver state
//
regPlInSignal := false.B

//
// Go to the idle state
//
state := sIdle

}.otherwise {

//
// Connect the address of BRAM reader to the receiver address
//
sharedRdWrAddr := receiverRdWrAddr

//
// On the receiver, writing is not allowed
//
sharedWrEna := false.B

//
// Stay at the same state
//
state := sReceiver

}
}
is(sSender) {

//
// Check whether sending data is finished
//
when(finishedSendingBuffer === true.B) {

//
// No longer in the sender state
//
regBeginSendingBuffer := false.B

//
// Go to the idle state
//
state := sIdle

}.otherwise {

//
// Connect shared BRAM signals to the sender
//
sharedRdWrAddr := senderRdWrAddr
sharedWrEna := wrEna
sharedWrData := wrData

//
// Stay at the same state
//
state := sSender

}
}
}
}
}

object SendReceiveSynchronizer {
Expand Down
8 changes: 4 additions & 4 deletions src/main/scala/hwdbg/communication/sender.scala
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ class DebuggerPacketSender(
// Sending signals
//
val beginSendingBuffer = Input(Bool()) // should sender start sending buffers or not?
val noNewData = Input(Bool()) // should sender finish sending buffers or not?
val noNewDataSender = Input(Bool()) // should sender finish sending buffers or not?
val dataValidInput = Input(Bool()) // should sender send next buffer or not?

val sendWaitForBuffer = Output(Bool()) // should the external module send next buffer or not?
Expand Down Expand Up @@ -257,7 +257,7 @@ class DebuggerPacketSender(
//
state := sSendData

}.elsewhen(io.noNewData === true.B && io.dataValidInput === true.B) {
}.elsewhen(io.noNewDataSender === true.B && io.dataValidInput === true.B) {

//
// Sending data was done
Expand Down Expand Up @@ -344,7 +344,7 @@ object DebuggerPacketSender {
)(
en: Bool,
beginSendingBuffer: Bool,
noNewData: Bool,
noNewDataSender: Bool,
dataValidInput: Bool,
requestedActionOfThePacketInput: UInt,
sendingData: UInt
Expand All @@ -370,7 +370,7 @@ object DebuggerPacketSender {
//
debuggerPacketSender.io.en := en
debuggerPacketSender.io.beginSendingBuffer := beginSendingBuffer
debuggerPacketSender.io.noNewData := noNewData
debuggerPacketSender.io.noNewDataSender := noNewDataSender
debuggerPacketSender.io.dataValidInput := dataValidInput
debuggerPacketSender.io.requestedActionOfThePacketInput := requestedActionOfThePacketInput
debuggerPacketSender.io.sendingData := sendingData
Expand Down

0 comments on commit 1b2f889

Please sign in to comment.