用spinalhdl编写一个数据报文解析的模块,每段输入为512b的fragment型stream,1个报文可能有这样的多段输入,输出需要给出这个报文的五元组信息,需要支持IPinIP、GTP等各类隧道报文,同时1个报文最多可以携带4层vlan和6层mpls标签
时间: 2024-02-18 14:06:17 浏览: 181
整了一个报文解析工具
以下是一个使用SpinalHDL编写数据报文解析模块的示例。这个模块可以处理IPinIP、GTP和多层VLAN和MPLS标签的报文,并输出五元组信息。
```scala
import spinal.core._
import spinal.lib._
import spinal.lib.fsm._
case class FiveTuple(ipSrc: UInt, ipDst: UInt, srcPort: UInt, dstPort: UInt, protocol: UInt)
class PacketParser extends Component {
val io = new Bundle {
val input = slave Stream(Bits(512 bits))
val output = master Stream(FiveTuple())
}
// Define constants for protocol types
val ProtocolIP = 0x0800
val ProtocolIPinIP = 0x4
val ProtocolGTP = 0x86dd
val ProtocolVLAN = 0x8100
val ProtocolMPLS = 0x8847
// Define state machine states
val sIdle = new State()
val sIP = new State()
val sIPinIP = new State()
val sGTP = new State()
val sVLAN = new State()
val sMPLS = new State()
// Define state machine inputs
val inputValid = io.input.valid
val input = io.input.payload
val inputLast = io.input.last
// Define state machine outputs
val outputValid = io.output.valid
val output = io.output.payload
// Define state machine registers
val state = Reg(sIdle)
val ipSrc = Reg(UInt(32 bits))
val ipDst = Reg(UInt(32 bits))
val srcPort = Reg(UInt(16 bits))
val dstPort = Reg(UInt(16 bits))
val protocol = Reg(UInt(16 bits))
// Define state machine transitions
switch(state) {
is(sIdle) {
when(inputValid) {
when(input(12 downto 1) === ProtocolIP) {
state := sIP
} .elsewhen(input(12 downto 1) === ProtocolIPinIP) {
state := sIPinIP
} .elsewhen(input(12 downto 1) === ProtocolGTP) {
state := sGTP
} .elsewhen(input(15 downto 1) === ProtocolVLAN) {
state := sVLAN
} .elsewhen(input(19 downto 1) === ProtocolMPLS) {
state := sMPLS
}
}
}
is(sIP) {
when(inputValid) {
ipSrc := input(47 downto 16).asUInt
ipDst := input(79 downto 48).asUInt
srcPort := input(95 downto 80).asUInt
dstPort := input(111 downto 96).asUInt
protocol := input(23 downto 16).asUInt
when(inputLast) {
outputValid := True
output.ipSrc := ipSrc
output.ipDst := ipDst
output.srcPort := srcPort
output.dstPort := dstPort
output.protocol := protocol
state := sIdle
}
}
}
is(sIPinIP) {
// Handle IPinIP packets
}
is(sGTP) {
// Handle GTP packets
}
is(sVLAN) {
// Handle VLAN packets
}
is(sMPLS) {
// Handle MPLS packets
}
}
}
```
这个模块使用有限状态机来处理输入数据流。在空闲状态下,它等待输入有效信号。一旦输入有效,它会检查输入数据的协议类型,并根据需要切换到相应的状态。
对于IP报文,它会提取源IP地址、目的IP地址、源端口、目的端口和协议类型,并将这些信息存储在寄存器中。一旦收到报文的最后一个片段,它将输出五元组信息并返回空闲状态。
对于其他类型的报文,您可以添加额外的状态来处理它们。例如,对于IPinIP报文,您可以提取内部IP报文并递归调用PacketParser模块来处理它们。
请注意,这个示例仅包含了IP报文的处理。您需要根据需要扩展它来支持其他类型的报文,并添加对VLAN和MPLS标签的支持。
阅读全文