从 SV 约束的动态范围中选取随机地址的方法

发布于 2025-01-18 02:19:22 字数 1761 浏览 1 评论 0 原文

我需要从 Systemverilog 中的一组预定义范围中选择随机地址,

program test;

int unsigned q[$], rSz;
typedef struct {
  int unsigned from, till;
} range_t;

initial begin
    range_t ranges[$];

    ranges.push_back('{from: 'h10, till: 'h1F});
    ranges.push_back('{from: 'h30, till: 'h3F});
    ranges.push_back('{from: 'h50, till: 'h5F});

    rSz = ranges.size();
    $displayh(rSz, ranges);

    repeat (10) begin
        std::randomize(q) with {
            q.size() inside {[4:8]};
            foreach (q[i]) {
                q[i] inside {[ranges[0].from: ranges[0].till]} ||
                q[i] inside {[ranges[1].from: ranges[1].till]} ||
                q[i] inside {[ranges[2].from: ranges[2].till]} ;
            }
        };
        $displayh(q);
    end
end

endprogram : test

如果我有固定数量的可以硬编码的范围,那么效果很好。 但范围数量本身是动态的,我无法像 foreach 循环中那样对范围进行硬编码。

我无法使用嵌套的 foreach,因为内部循环中的语句将被视为单独的约束,并且由于范围不重叠而彼此失败。

我能想出的就是像下面这样的东西,我按顺序使用范围,然后在最后随机播放。

program test;

int unsigned q[$], rSz;
typedef struct {
  int unsigned from, till;
} range_t;

initial begin
    range_t ranges[$];
    ranges.push_back('{from: 'h10, till: 'h1F});
    ranges.push_back('{from: 'h30, till: 'h3F});
    ranges.push_back('{from: 'h50, till: 'h5F});

    rSz = ranges.size();
    $displayh(rSz, ranges);

    repeat (10) begin
        std::randomize(q) with {
            q.size() inside {[4:8]};
            foreach (q[i]) {
                q[i] inside {[ranges[i % rSz].from: ranges[i % rSz].till]};
            }
        };
        q.shuffle();
        $displayh(q);
    end
end

endprogram : test

一般来说,有更好的方法吗?

我正在寻找类似 foreach-or 的东西,其中循环中的所有行都是 or-ed 而不是 and-ed - 如果这解释了要求。

I have a requirement to pick random addresses from a set of predefined ranges in Systemverilog

program test;

int unsigned q[$], rSz;
typedef struct {
  int unsigned from, till;
} range_t;

initial begin
    range_t ranges[$];

    ranges.push_back('{from: 'h10, till: 'h1F});
    ranges.push_back('{from: 'h30, till: 'h3F});
    ranges.push_back('{from: 'h50, till: 'h5F});

    rSz = ranges.size();
    $displayh(rSz, ranges);

    repeat (10) begin
        std::randomize(q) with {
            q.size() inside {[4:8]};
            foreach (q[i]) {
                q[i] inside {[ranges[0].from: ranges[0].till]} ||
                q[i] inside {[ranges[1].from: ranges[1].till]} ||
                q[i] inside {[ranges[2].from: ranges[2].till]} ;
            }
        };
        $displayh(q);
    end
end

endprogram : test

It works fine if I have a fixed number of ranges that I can hard-code.
But the number of ranges itself is dynamic, I can not hard-code the ranges as in the foreach loop.

I can't use a nested foreach as the statements in the inner loop will be treated as individual constraints and fail with each other as the ranges are non-overlapping.

All I could come up with is something like below where I use the ranges in order and then shuffle at the end.

program test;

int unsigned q[$], rSz;
typedef struct {
  int unsigned from, till;
} range_t;

initial begin
    range_t ranges[$];
    ranges.push_back('{from: 'h10, till: 'h1F});
    ranges.push_back('{from: 'h30, till: 'h3F});
    ranges.push_back('{from: 'h50, till: 'h5F});

    rSz = ranges.size();
    $displayh(rSz, ranges);

    repeat (10) begin
        std::randomize(q) with {
            q.size() inside {[4:8]};
            foreach (q[i]) {
                q[i] inside {[ranges[i % rSz].from: ranges[i % rSz].till]};
            }
        };
        q.shuffle();
        $displayh(q);
    end
end

endprogram : test

Is there a better way of doing this in general?

I am looking for something like foreach-or where all lines in loop are or-ed instead of and-ed - if that explains the requirement.

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

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

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

枫林﹌晚霞¤ 2025-01-25 02:19:22

大多数人都熟悉 sum()数组减少方法,但是也有或()和() XOR()还原方法。

module test;
  int unsigned q[$], rSz;
  typedef struct {
    int unsigned from, till;
  } range_t;
  
  initial begin
    range_t ranges[$];

    ranges.push_back('{from: 'h10, till: 'h1F});
    ranges.push_back('{from: 'h30, till: 'h3F});
    ranges.push_back('{from: 'h50, till: 'h5F});

    rSz = ranges.size();
    $displayh(rSz,, ranges);

    repeat (10) begin
      assert(std::randomize(q) with {
        q.size() inside {[4:8]};
        foreach (q[i]) 
          ranges.or(range) with (q[i] inside {[range.from: range.till]});
      });
      $displayh(q);
    end
  end
endmodule: test

请参阅 7.12.3 7.12.3阵列减少方法 /a>。

Most people are familiar with the sum() array reduction method, but there are also or(), and(), and xor() reduction methods as well.

module test;
  int unsigned q[$], rSz;
  typedef struct {
    int unsigned from, till;
  } range_t;
  
  initial begin
    range_t ranges[$];

    ranges.push_back('{from: 'h10, till: 'h1F});
    ranges.push_back('{from: 'h30, till: 'h3F});
    ranges.push_back('{from: 'h50, till: 'h5F});

    rSz = ranges.size();
    $displayh(rSz,, ranges);

    repeat (10) begin
      assert(std::randomize(q) with {
        q.size() inside {[4:8]};
        foreach (q[i]) 
          ranges.or(range) with (q[i] inside {[range.from: range.till]});
      });
      $displayh(q);
    end
  end
endmodule: test

See section 7.12.3 Array reduction methods in the IEEE 1800-2017 SystemVerilog LRM.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文