SpinalHDL icon indicating copy to clipboard operation
SpinalHDL copied to clipboard

Arbitrary data bundle type for Axi4Stream

Open KireinaHoro opened this issue 1 year ago • 12 comments

I'm trying to translate a Verilog IP for AXI DMA into a BlackBox and find that it would be nice if the Axi4Stream from amba4.axis supported arbitrary bundles as data, instead of only with Bits. An example looks like the following:

    input  wire [AXI_ADDR_WIDTH-1:0]  s_axis_read_desc_addr,
    input  wire [LEN_WIDTH-1:0]       s_axis_read_desc_len,
    input  wire [TAG_WIDTH-1:0]       s_axis_read_desc_tag,
    input  wire [AXIS_ID_WIDTH-1:0]   s_axis_read_desc_id,
    input  wire [AXIS_DEST_WIDTH-1:0] s_axis_read_desc_dest,
    input  wire [AXIS_USER_WIDTH-1:0] s_axis_read_desc_user,
    input  wire                       s_axis_read_desc_valid,
    output wire                       s_axis_read_desc_ready,

I'm thinking of using it approximately like this:

val dmaReqBundle = new Bundle {
  val addr = UInt(addrWidth bits)
  val len = UInt(lenWidth bits)
  val tag = UInt(tagWidth bits)
}
val config = Axi4StreamConfig(dataType = dmaReqBundle)
val io = new Bundle {
  val s_axis_read_desc = slave(Axi4Stream(config))
}

Here addr, len, and tag together would consist of the data component in the Axi4StreamBundle. Is it possible that such a use-case could be supported?

KireinaHoro avatar Dec 06 '23 17:12 KireinaHoro

Hi, i kinda recentrly implemented a feature a bit like it. But instead of using a DataType parameter, i used something a bit more "dynamic" it is named HardMap : https://github.com/SpinalHDL/VexiiRiscv/blob/39ec45a01d0cf9e1701823f64f1897337fdc34f1/src/main/scala/spinal/core/HardMap.scala#L8

Idea is that you can create it and fill it with NamedType a bit like a hash map.

Dolu1990 avatar Dec 06 '23 18:12 Dolu1990

This looks interesting. So I imagine one would put this into the data element of the Axi4Stream bundle? How would this look like if used in IO?

KireinaHoro avatar Dec 06 '23 20:12 KireinaHoro

Something around that :

  case class MyBus(things : Seq[NamedType[_ <: Data]]) extends Bundle{
    val hm = new HardMap()
    things.foreach(e => hm.add(e))
  }
  
  val CTX_A = NamedType(Bool())
  val CTX_B = NamedType(Bool())
  
  val bus = MyBus(Seq(CTX_A, CTX_B))

Dolu1990 avatar Dec 11 '23 11:12 Dolu1990

Since Axi4Stream is very much an analog of Stream would it not make sense to make it generic over the type?

andreasWallner avatar Dec 14 '23 00:12 andreasWallner

would it not make sense to make it generic over the type?

How do you mean it ? (for me to understand)

Dolu1990 avatar Dec 18 '23 09:12 Dolu1990

https://fars.ee/Co-Z/scala @Dolu1990 I have something like this that works quite well for my use case. But this is not the same thing as the HardMap solution you proposed since I pass in a payloadType: Bundle to the config.

KireinaHoro avatar Dec 18 '23 12:12 KireinaHoro

How do you mean it ? (for me to understand)

To have the payload as a generic type, just like the Stream has it, i.e. Axi4Stream(MyBundle(), ...) and maybe a conversion function to Axi4Stream(Bits(), ...) for the edges. Do we have to stick to the "type" in the spec here?

andreasWallner avatar Dec 18 '23 23:12 andreasWallner

since I pass in a payloadType: Bundle to the config.

Yes it is also a good solution, [T <: Data] ... payloadType[HardType[T]]

I'm not sure what is the best between having a ArrayBuffer[NamedType] vs payloadType[HardType[T]]

Maybe i'm bing too much into the HardMap thing because of composability in CPU design, which isn't the rule in general design

Axi4Stream(MyBundle(), ...) and maybe a conversion function to Axi4Stream(Bits(), ...) for the edge

Ahhh i would say it would be kinda too much away from the the Axi4stream spec usage. Axi4stream is realy a byte oriented stream, with some eventual "compagnions", so more Axi4StreamConfig(dataWidth, ... , optionalHardType)

Dolu1990 avatar Dec 29 '23 10:12 Dolu1990

@Dolu1990 I'm trying to build something else with the HardMap as the USER field; would you mind upstreaming it into SpinalHDL (from VexiiRiscv)? Thanks :)

KireinaHoro avatar Jan 22 '24 10:01 KireinaHoro

@KireinaHoro Pused to SpinalHDL dev branch :)

Dolu1990 avatar Jan 29 '24 10:01 Dolu1990

Keep in mind, not sure what is the best overall :

  • Bits with parametrable bit count
  • Parametrable Data type
  • HardMap with elements in parameter

I'm thinking that maybe the best is just Bits, as when you have a Axi4Stream interconnect, you realy don't care about the meaning of the data.

Dolu1990 avatar Jan 29 '24 10:01 Dolu1990

I agree about the Bits option; we can probably use HardMap to wrap another layer for such a use-case. However, the current implementation enforces a Byte interface as required by the standard; allowing Bits means deviation.

KireinaHoro avatar Jan 29 '24 10:01 KireinaHoro