凿子中的systemverilog联合类型

Posted

技术标签:

【中文标题】凿子中的systemverilog联合类型【英文标题】:systemverilog union type in chisel 【发布时间】:2020-05-31 07:05:27 【问题描述】:

我将一些 systermverilog 代码重写到 chisel 中,但我找不到在 chisel 中表达 systemverilog 打包联合的好方法。例如,

typedef struct packed 
    logic [3:0]     version;
    logic [3:0]     ihl;
    logic [7:0]     tos;
    logic [15:0]    total_length;
    logic [15:0]    id;
    logic           reserved;
    logic           df;
    logic           mf;
    logic [12:0]    frag_offset;
    logic [7:0]     ttl;
    logic [7:0]     protocol;
    logic [15:0]    checksum;
    logic [31:0]    ip_sa;
    logic [31:0]    ip_da;
 ipv4_s;

typedef struct packed 
    logic [63:0] DW0;
    logic [63:0] DW1;
    logic [31:0] DW2;
 common_20b_s;

typedef union packed 
    ipv4_s  structured;
    common_20b_s array;
    logic [$bits(ipv4_s)-1:0] bits;
 ipv4_hdr_u;

module test (
    input clk,
    input [$bits(ipv4_s)-1:0] pkt_stream_in,
    input [3:0] mode,
    input [127:0] config_in,
    output reg [$bits(ipv4_s)-1:0] pkt_stream_out
);

    ipv4_hdr_u ipv4_hdr;
    always @* begin
        ipv4_hdr.bits = pkt_stream_in;

        case(mode)
            0: ipv4_hdr.structured.ip_sa = config_in[31:0];
            1: ipv4_hdr.array.DW0 = config_in[63:0];
        endcase
    end

    always @(posedge clk)
        pkt_stream_out <= ipv4_hdr.bits;

endmodule: test

对于ipv4_scommon_2b_s这两个数据结构,结构中的每个字段都可以单独更新,但是要凿。有没有办法表达这种功能?

【问题讨论】:

【参考方案1】:

没有对打包联合的内置支持,但您可以创建自定义类(子类型Bundle)并自己构建类似的东西。它会导致更多样板,所以我认为一些内置支持会很好,但它可以完成工作:

可运行音译:https://scastie.scala-lang.org/5jOMpEYuRbu9VbzScvDffQ

粘贴在下面:

import chisel3._
import chisel3.util._
import chisel3.stage.ChiselStage

class IPV4_s extends Bundle 
  val version = UInt(4.W)
  val ihl = UInt(4.W)
  val tos = UInt(8.W)
  val total_length = UInt(16.W)
  val id = UInt(16.W)
  val reserved = Bool()
  val df = Bool()
  val mf = Bool()
  val frag_offset = UInt(13.W)
  val ttl = UInt(8.W)
  val protocol = UInt(8.W)
  val checksum = UInt(16.W)
  val ip_sa = UInt(32.W)
  val ip_da = UInt(32.W)

object IPV4_s 
  // Utility, I got sick of typing this righthand expression
  val width = (new IPV4_s).getWidth


class Common_20b_s extends Bundle 
  val DW0 = UInt(64.W)
  val DW1 = UInt(64.W)
  val DW2 = UInt(32.W)



class IPV4_hdr_u extends Bundle 
  val bits = UInt(IPV4_s.width.W)
  // These helpers aren't really necessary but can save some typing
  def asIPV4_s = this.asTypeOf(new IPV4_s)
  def asCommon_20b_s = this.asTypeOf(new Common_20b_s)


class Test extends MultiIOModule 
  // clock is inherited
  val pkt_stream_in = IO(Input(new IPV4_hdr_u))
  val mode = IO(Input(UInt(4.W)))
  val config_in = IO(Input(UInt(128.W)))
  val pkt_stream_out = IO(Output(new IPV4_hdr_u))

  // Default to using stream_in
  val ipv4_hdr = WireInit(pkt_stream_in)
  switch (mode) 
    is (0.U) 
      // Cast input and use temporary for subfield assignment
      val t = WireInit(pkt_stream_in.asIPV4_s)
      t.ip_sa := config_in(31, 0)
      ipv4_hdr := t.asTypeOf(new IPV4_hdr_u)
    
    is (1.U) 
      val t = WireInit(pkt_stream_in.asCommon_20b_s)
      t.DW0 := config_in(63, 0)
      ipv4_hdr := t.asTypeOf(new IPV4_hdr_u)
    
  
  pkt_stream_out := ipv4_hdr

【讨论】:

以上是关于凿子中的systemverilog联合类型的主要内容,如果未能解决你的问题,请参考以下文章

system verilog 数据结构(转)

systemverilog 为啥要用$cast类型转换函数

vcs怎么编译产生随机激励的systemverilog语句

SystemVerilog结构体

FPGA小白学习之路 System Verilog的概念以及与verilog的对比

AI芯片与SystemVerilog参数化