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

Commit

Permalink
add changes in receiver design
Browse files Browse the repository at this point in the history
  • Loading branch information
SinaKarvandi committed Apr 22, 2024
1 parent 1fc8de3 commit 7b1fbef
Show file tree
Hide file tree
Showing 7 changed files with 220 additions and 59 deletions.
8 changes: 8 additions & 0 deletions sim/hwdbg/communication/DebuggerPacketReceiver/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Makefile

TOPLEVEL_LANG = verilog
VERILOG_SOURCES = $(shell pwd)/../../../../generated/DebuggerPacketReceiver.sv
TOPLEVEL = DebuggerPacketReceiver
MODULE = test_DebuggerPacketReceiver

include $(shell cocotb-config --makefiles)/Makefile.sim
1 change: 1 addition & 0 deletions sim/hwdbg/communication/DebuggerPacketReceiver/test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
make SIM=icarus WAVES=1
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
##
# @file test_DebuggerPacketReceiver.py
#
# @author Sina Karvandi ([email protected])
#
# @brief Testing module for DebuggerPacketReceiver
#
# @details
#
# @version 0.1
#
# @date 2024-04-22
#
# @copyright This project is released under the GNU Public License v3.
#

import random

import cocotb
from cocotb.clock import Clock
from cocotb.triggers import RisingEdge
from cocotb.types import LogicArray

'''
input clock,
reset,
io_en,
io_plInSignal,
output [12:0] io_rdWrAddr,
input [31:0] io_rdData,
output [31:0] io_requestedActionOfThePacketOutput,
output io_requestedActionOfThePacketOutputValid,
input io_noNewDataReceiver,
io_readNextData,
output io_dataValidOutput,
output [31:0] io_receivingData,
output io_finishedReceivingBuffer
'''

@cocotb.test()
async def DebuggerPacketReceiver_test(dut):
"""Test DebuggerPacketReceiver module"""

#
# Assert initial output is unknown
#
assert LogicArray(dut.io_rdWrAddr.value) == LogicArray("XXXXXXXXXXXXX")
assert LogicArray(dut.io_requestedActionOfThePacketOutput.value) == LogicArray("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
assert LogicArray(dut.io_requestedActionOfThePacketOutputValid.value) == LogicArray("X")
assert LogicArray(dut.io_dataValidOutput.value) == LogicArray("X")
assert LogicArray(dut.io_receivingData.value) == LogicArray("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
assert LogicArray(dut.io_finishedReceivingBuffer.value) == LogicArray("X")

clock = Clock(dut.clock, 10, units="ns") # Create a 10ns period clock on port clock

#
# Start the clock. Start it low to avoid issues on the first RisingEdge
#
cocotb.start_soon(clock.start(start_high=False))

dut._log.info("Initialize and reset module")

#
# Initial values
#
dut.io_en.value = 0
dut.io_plInSignal.value = 0

#
# Reset DUT
#
dut.reset.value = 1
for _ in range(10):
await RisingEdge(dut.clock)
dut.reset.value = 0

dut._log.info("Enabling chip")

#
# Enable chip
#
dut.io_en.value = 1

for test_number in range(10):

dut._log.info("Enable receiving data on the chip (" + str(test_number) + ")")

#
# Tell the receiver to start receiving data (This mainly operates based on
# a rising-edge detector, so we'll need to make it low)
#
dut.io_plInSignal.value = 1
await RisingEdge(dut.clock)
dut.io_plInSignal.value = 0

#
# Wait until the data is received
#
for _ in range(1000):
if (dut.io_dataValidOutput.value == 1):
break
else:
match dut.io_rdWrAddr.value:
case 0x0: # checksum
dut.io_rdData.value = 0x00001234
case 0x8: # indicator
dut.io_rdData.value = 0x88888888
case 0x10: # type
dut.io_rdData.value = 0x10101010
case 0x14: # requested action
dut.io_rdData.value = 0x14141414
case _:
assert "invalid address in the address line"
await RisingEdge(dut.clock)

#
# Run extra waiting clocks
#
for _ in range(10):
await RisingEdge(dut.clock)

#
# Check the final input on the next clock
#
await RisingEdge(dut.clock)
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
'''

@cocotb.test()
async def DebuggerModuleTestingBRAM_test(dut):
async def DebuggerPacketSender_test(dut):
"""Test DebuggerPacketSender module"""

#
Expand Down Expand Up @@ -84,7 +84,7 @@ async def DebuggerModuleTestingBRAM_test(dut):

for test_number in range(10):

dut._log.info("Enable sending data chip (" + str(test_number) + ")")
dut._log.info("Enable sending data on the chip (" + str(test_number) + ")")

#
# Still there is data to send
Expand Down
103 changes: 71 additions & 32 deletions src/main/scala/hwdbg/communication/receiver.scala
Original file line number Diff line number Diff line change
Expand Up @@ -86,14 +86,15 @@ class DebuggerPacketReceiver(
val state = RegInit(sIdle)

//
// Output pins (registers)
// Output pins
//
val rdWrAddr = WireInit(0.U(bramAddrWidth.W))
val regRdWrAddr = RegInit(0.U(bramAddrWidth.W))
val regRequestedActionOfThePacketOutput = RegInit(0.U(new DebuggerRemotePacket().RequestedActionOfThePacket.getWidth.W))
val regRequestedActionOfThePacketOutputValid = RegInit(false.B)
val regDataValidOutput = RegInit(false.B)
val regReceivingData = RegInit(0.U(bramDataWidth.W))
val regFinishedReceivingBuffer = RegInit(false.B)
val finishedReceivingBuffer = WireInit(false.B)
val requestedActionOfThePacketOutput = WireInit(0.U(new DebuggerRemotePacket().RequestedActionOfThePacket.getWidth.W))
val requestedActionOfThePacketOutputValid = WireInit(false.B)
val dataValidOutput = WireInit(false.B)
val receivingData = WireInit(0.U(bramDataWidth.W))

//
// Rising-edge detector for start receiving signal
Expand Down Expand Up @@ -135,22 +136,22 @@ class DebuggerPacketReceiver(
}

//
// Configure the registers in case of sIdle
// Configure the output pins in case of sIdle
//
regRdWrAddr := 0.U
regRequestedActionOfThePacketOutput := 0.U
regRequestedActionOfThePacketOutputValid := false.B
regDataValidOutput := false.B
regReceivingData := 0.U
regFinishedReceivingBuffer := false.B
rdWrAddr := 0.U
requestedActionOfThePacketOutput := 0.U
requestedActionOfThePacketOutputValid := false.B
dataValidOutput := false.B
receivingData := 0.U
finishedReceivingBuffer := false.B

}
is(sReadChecksum) {

//
// Adjust address to read Checksum from BRAM (Not Used)
//
regRdWrAddr := (MemoryCommunicationConfigurations.BASE_ADDRESS_OF_PS_TO_PL_COMMUNICATION + receivedPacketBuffer.Offset.checksum).U
rdWrAddr := (MemoryCommunicationConfigurations.BASE_ADDRESS_OF_PS_TO_PL_COMMUNICATION + receivedPacketBuffer.Offset.checksum).U

//
// Goes to the next section
Expand All @@ -162,7 +163,7 @@ class DebuggerPacketReceiver(
//
// Adjust address to read Indicator from BRAM
//
regRdWrAddr := (MemoryCommunicationConfigurations.BASE_ADDRESS_OF_PS_TO_PL_COMMUNICATION + receivedPacketBuffer.Offset.indicator).U
rdWrAddr := (MemoryCommunicationConfigurations.BASE_ADDRESS_OF_PS_TO_PL_COMMUNICATION + receivedPacketBuffer.Offset.indicator).U

//
// Goes to the next section
Expand All @@ -174,12 +175,15 @@ class DebuggerPacketReceiver(
//
// Adjust address to read TypeOfThePacket from BRAM
//
regRdWrAddr := (MemoryCommunicationConfigurations.BASE_ADDRESS_OF_PS_TO_PL_COMMUNICATION + receivedPacketBuffer.Offset.typeOfThePacket).U
rdWrAddr := (MemoryCommunicationConfigurations.BASE_ADDRESS_OF_PS_TO_PL_COMMUNICATION + receivedPacketBuffer.Offset.typeOfThePacket).U

//
// Check whether the indicator is valid or not
//
when(io.rdData === HyperDbgSharedConstants.INDICATOR_OF_HYPERDBG_PACKET.U) {
LogInfo(debug)(
f"Comparing first 0x${BitwiseFunction.printFirstNBits(HyperDbgSharedConstants.INDICATOR_OF_HYPERDBG_PACKET, bramDataWidth)}%x bits of the indicator"
)
when(io.rdData === BitwiseFunction.printFirstNBits(HyperDbgSharedConstants.INDICATOR_OF_HYPERDBG_PACKET, bramDataWidth).U) {

//
// Indicator of packet is valid
Expand All @@ -190,7 +194,7 @@ class DebuggerPacketReceiver(
}.otherwise {

//
// Type of packet is not valid
// Indicator of packet is not valid
// (Receiving was done but not found a valid packet,
// so, go to the idle state)
//
Expand All @@ -202,7 +206,12 @@ class DebuggerPacketReceiver(
//
// Adjust address to read RequestedActionOfThePacket from BRAM
//
regRdWrAddr := (MemoryCommunicationConfigurations.BASE_ADDRESS_OF_PS_TO_PL_COMMUNICATION + receivedPacketBuffer.Offset.requestedActionOfThePacket).U
rdWrAddr := (MemoryCommunicationConfigurations.BASE_ADDRESS_OF_PS_TO_PL_COMMUNICATION + receivedPacketBuffer.Offset.requestedActionOfThePacket).U

//
// Save the address into a register
//
regRdWrAddr := (MemoryCommunicationConfigurations.BASE_ADDRESS_OF_PS_TO_PL_COMMUNICATION + receivedPacketBuffer.Offset.requestedActionOfThePacket + (bramDataWidth >> 3)).U

//
// Check whether the type of the packet is valid or not
Expand Down Expand Up @@ -232,12 +241,12 @@ class DebuggerPacketReceiver(
//
// Read the RequestedActionOfThePacket
//
regRequestedActionOfThePacketOutput := io.rdData
requestedActionOfThePacketOutput := io.rdData

//
// The RequestedActionOfThePacketOutput is valid from now
//
regRequestedActionOfThePacketOutputValid := true.B
requestedActionOfThePacketOutputValid := true.B

//
// Check if the caller needs to read the next part of
Expand All @@ -248,7 +257,8 @@ class DebuggerPacketReceiver(
//
// Adjust address to read next data to BRAM
//
regRdWrAddr := regRdWrAddr + bramDataWidth.U
rdWrAddr := regRdWrAddr
regRdWrAddr := regRdWrAddr + (bramDataWidth >> 3).U

//
// Read the next offset of the buffer
Expand Down Expand Up @@ -276,12 +286,12 @@ class DebuggerPacketReceiver(
//
// Data outputs are now valid
//
regDataValidOutput := true.B
dataValidOutput := true.B

//
// Adjust the read buffer data
//
regReceivingData := io.rdData
receivingData := io.rdData

//
// Return to the previous state of action
Expand All @@ -291,13 +301,18 @@ class DebuggerPacketReceiver(
}
is(sDone) {

//
// Reset the temporary address holder
//
regRdWrAddr := 0.U

//
// The receiving is done at this stage, either
// was successful of unsucessful, we'll release the
// sharing bram resource by indicating that the receiving
// module is no longer using the bram line
//
regFinishedReceivingBuffer := true.B
finishedReceivingBuffer := true.B

//
// Go to the idle state
Expand All @@ -310,14 +325,14 @@ class DebuggerPacketReceiver(
// ---------------------------------------------------------------------

//
// Connect output pins to internal registers
// Connect output pins
//
io.rdWrAddr := regRdWrAddr
io.requestedActionOfThePacketOutput := regRequestedActionOfThePacketOutput
io.requestedActionOfThePacketOutputValid := regRequestedActionOfThePacketOutputValid
io.dataValidOutput := regDataValidOutput
io.receivingData := regReceivingData
io.finishedReceivingBuffer := regFinishedReceivingBuffer
io.rdWrAddr := rdWrAddr
io.requestedActionOfThePacketOutput := requestedActionOfThePacketOutput
io.requestedActionOfThePacketOutputValid := requestedActionOfThePacketOutputValid
io.dataValidOutput := dataValidOutput
io.receivingData := receivingData
io.finishedReceivingBuffer := finishedReceivingBuffer

}

Expand Down Expand Up @@ -386,3 +401,27 @@ object DebuggerPacketReceiver {
)
}
}

object ReceiverModule extends App {

//
// Generate hwdbg verilog files
//
println(
ChiselStage.emitSystemVerilog(
new DebuggerPacketReceiver(
DebuggerConfigurations.ENABLE_DEBUG,
DebuggerConfigurations.BLOCK_RAM_ADDR_WIDTH,
DebuggerConfigurations.BLOCK_RAM_DATA_WIDTH
),
firtoolOpts = Array(
"-disable-all-randomization",
"--lowering-options=disallowLocalVariables", // because icarus doesn't support 'automatic logic', this option prevents such logics
"-strip-debug-info",
"--split-verilog", // The intention for this argument (and next argument) is to separate generated files.
"-o",
"generated/"
)
)
)
}
Loading

0 comments on commit 7b1fbef

Please sign in to comment.