SystemVerilog: Dynamic part-select and array slicing

目录

1. What is part select and array slicing?

2. Dynamic part select

2.1 错误的写法

2.2 直观的正确写法

2.3 简明的写法

3. Dynamic array slicing


 

1. What is part select and array slicing?

        Slicing是指从数组中选择一个连续区间的元素,比如说,a[3:5],表示选择数组a中的索引为3,4,5的元素。Slice is a selection of one or more contiguous elements of an array, whereas part select is a selection of one or more contiguous bits of an element.

需要注意的是,SystemVerilog与Python在Slicing处理方面有细微差别,Python中是不包含上界的,而SystemVerilog中则是包含上界。比如说在Python中a[3:5]是指选择数组中索引为3和4的元素,不包括索引为5的元素。

part-select是指对一个多比特数据选择其中一段连续区间内的数据,比如说对于32比特的整型数a,a[3:5]表示选择a[3],a[4],a[5]。

 

2. Dynamic part select

2.1 错误的写法

        在普通用法中,不管是part-select还是array slicing,上界和下界应该都是常数。而不能是变量,比如说,你不能像下面这么用:

program partselect_arrayslice;
    bit [63:0] data;
    byte       byte_data[8];
    byte       byte_data2[3];

initial begin : example1
    void'(std::randomize(data));
    for(int k=0; k<8; k++)begin
        byte_data[k] = data[k*8+7 : k*8];
    end    
end

endprogram

        这段代码编译后会报告错误:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA56yo54mb5oWi6ICV,size_20,color_FFFFFF,t_70,g_se,x_16

        最直观的做法就是不用for-loop,直接逐个赋值就是了,如下所示:

 

2.2 直观的正确写法

program partselect_arrayslice;
    bit [63:0] data;
    byte       byte_data[8];
    byte       byte_data2[3];

initial begin : example2
    void'(std::randomize(data));
    
    $display("Value of data is %h",data);

    // Using part select to copy data from data to byte_data.
    byte_data[0] = data[07:0];
    byte_data[1] = data[15:8];
    byte_data[2] = data[23:16];
    byte_data[3] = data[31:24]; 
    byte_data[4] = data[39:32]; 
    byte_data[5] = data[47:40]; 
    byte_data[6] = data[55:48]; 
    byte_data[7] = data[63:56]; 
    
    $display("After the part select...");
    foreach(byte_data[i])
        $display("\t byte_data[%0d] = %h",i,byte_data[i]);              
end  

endprogram

        运行后会得到(当然由于以上data是随机生成的,所以每次运行可能得到不同结果):

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA56yo54mb5oWi6ICV,size_15,color_FFFFFF,t_70,g_se,x_16

 

2.3 简明的写法

        在比特数比较少的时候自然这样做也可以,但是比特数很多的时候,比如说256比特的数据像以上这样拆分要写32条语句,这就有点郁闷了。甚至在验证环境中这个比特数是可变的,像以上这样确定性的分拆本身就不可能了。该怎么办呢? 

        SystemVerilog提供了如下所示的简明的写法(但是,老实讲为什么就不能按照直观的方式定义成a[k:j]之类的写法我也不甚了了,还要进一步学习):

+: Notation
byte = data[j +: k];
j  -> bit start position
k -> Number of bits up from j’th position

        如上所述,j表示起点位置,k表示从起点位置开始的连续区间的长度。“+:”是用于索引上升区间,类似的还有索引下降区间的写法,如下所示:

-: Notation
byte = data[j -: k];
j  -> bit start position
k -> Number of bits down from the j’th position

        利用这个语法,以上例子可以改写为: 

program partselect_arrayslice;
    bit [63:0] data;
    byte       byte_data[8];
    byte       byte_data2[3];

initial begin : example3
    void'(std::randomize(data));
    
    $display("Value of data is %h",data);

    // Using part select to copy data from data to byte_data.       
    $display("After the ascending part select...");
    foreach(byte_data[i])begin
        byte_data[i] = data[8*i +: 8];
        $display("\t byte_data[%0d] = %h",i,byte_data[i]);   
    end      

    $display("After the descending part select...");
    foreach(byte_data[i])begin
        byte_data[i] = data[8*i+7 -: 8];
        $display("\t byte_data[%0d] = %h",i,byte_data[i]);   
    end      
endprogram

3. Dynamic array slicing

        与part-select相似,array slicing也可以用以上这种语法来实现动态的区间选择。 

        如下例所示为纯行为级的模拟一个信号处理中常用的滑动窗的数据窗移动的处理过程。如果这个数据窗宽度非常大,用直接赋值的方法就会非常繁琐,而用"+:"或者"-:"则非常简单明了。

program partselect_arrayslice;
    bit [63:0] data;
    byte       byte_data[8];
    byte       byte_data2[3];

initial begin : example4
    foreach(byte_data[i]) begin
        //void'(std::randomize(byte_data[i])); // NG.
        byte tmp;
        void'(std::randomize(tmp));
        byte_data[i] = tmp;
        $display("byte_data[%d] = %h",i,byte_data[i]);
    end
      
    // Dynamic array slicing to simulate sliding window
    for(int k=0; k<5; k++)begin
        byte_data2 = byte_data[k +: 3];
        $display("byte_data2 = %h %h %h",byte_data2[0],byte_data2[1],byte_data2[2]);
    end      
end    
endprogram

        运行结果如下,可以看出byte_data2中存储的3个字节的数据是byte_data中的一个宽度为3的窗口内的数据。 

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA56yo54mb5oWi6ICV,size_16,color_FFFFFF,t_70,g_se,x_16

 

Ref: SystemVerilog Array Slice - Verification Guide

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

笨牛慢耕

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值