返回介绍

7.18.1 将动态尺寸的数据位流化

发布于 2020-09-09 22:55:47 字数 2239 浏览 919 评论 0 收藏 0

如果解压缩操作包含了庞大的动态尺寸类型,那么解压缩过程是很复杂的(就像强制类型转换中一样):第一个动态尺寸条目被重新调整尺寸以便容纳流中所有的有效数据(排除了后续的固定尺寸条目)。对于仅仅包含了一个动态尺寸数据条目的流来说,采用这种机制来实现解压缩操作是足够的。然而,当流中包含了多个可变尺寸的数据包,或者每一个数据包包含了多个可变尺寸的数据条目、或者解压缩的数据的尺寸存储与一个流的中间部分,那么这种机制是很麻烦的并且容易引入错误。为了解决这些问题,解压缩操作允许使用一个with表达式来显式地指明解压缩操作中可变尺寸域的范围。

with表达式的语法如下:

stream_expression ::= expression [with[array_range_expression]]
                                                       // 引用自附录A.8.1
array_range_expression ::=
    expression
  | expression : expression
  | expression +: expression
  | expression -: expression

语法7-5 — with表达式语法(摘录自附录A)

with结构内的数组范围表达式必须具有integral类型,并且能够计算成位于固定尺寸数组边界内的值,或者,对于动态数组或队列,计算成正的值。with之前的表达式可以是任何一维的非压缩数组(包括队列)。with结构之内的表达式在它对应的数组被流化(也就是压缩或解压缩)之前被立即计算。因此,这个表达式可以指向被相同的操作符解压缩但位于数组之前的数据。如果这个表达式指向在对应数组之后(数组的右侧)被解压缩的变量,那么表达式使用变量的前一个值进行计算。

如果使用在一个解压缩操作的关联文中,并且数组是一个可变尺寸的数组,那么应该调整尺寸以便容纳这个范围表达式。如果数组是一个固定尺寸的数组并且范围表达式被计算成一个位于数组边界之外的范围,那么只有位于数组范围之内的数据被解压缩,并会产生一个错误。如果范围表达式被计算成一个小于数组(固定尺寸或可变尺寸)边界的范围,那么仅仅那些指定的条目被解压缩到指定的数组位置;数组中余下的部分不会被修改。

当使用在一个压缩操作关联文(位于语句的右侧)中的时候,它与数组分片的行为相同:指定数目的数组条目被压缩到流中。如果范围表达式的值小于数组的边界,那么只有指定的数组条目被流化。如果范围表达式大于数组边界,那么整个数组被流化,剩余的条目由指定数组的缺省值(在表5-1中描述)产生。

例如,下面的代码使用流操作符来建模一个在字节流上传输的包,它使用小字节编码顺序:

byte stream[$]; // 字节流

class Packet
    rand int header;
    rand int len;
    rand byte payload[];
    int crc;
    constraint G {len > 1; payload.size == len;}
    function void post_randomize;
        crc = payload.sum;
    endfunction
endclass

...

send: begin // 产生随机包并发送
    byte q[$];
    Packet p = new;
    void'(p.randomize());
    q = {<< byte{p.header, p.len, p.payload, p.crc}}; // 压缩
    stream = {stream, q};  // 添加到to stream
end

...

receive: begin // 接收包,解压缩,并删除
    byte q[$];
    Packet p = new;
    {<< byte{p.header, p.len, p.payload with[0+:p.len], p.crc}} = stream;
    stream = stream[$bits(p)/8:$]; // 删除包
end

在上面的例子中,压缩操作也可以写成:

q = {<< byte{p.header, p.len, p.payload with[0+:p.len], p.crc}};

或者写成:

q = {<< byte{p.header, p.len, p.payload with[0:p.len-1], p.crc}};

或者写成:

q = {<< byte{p}};

这几种情况的操作结果是相同的,因为p.len通过约束被指定成p.payload的尺寸。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文