返回介绍

12.16 随机序列产生 — randsequence

发布于 2020-09-09 22:55:51 字数 2597 浏览 1355 评论 0 收藏 0

分析程序生成器,例如yacc,使用巴科斯-诺尔范式(BNF)或类似的符号来描述被分析语言的文法。因此文法被用来产生一个程序,它能够检查一个标记流是否代表了该语言中一个语法正确的表达方式。SystemVerilog的序列产生器反转了这个过程。它使用文法来随机地产生一个文法所描述的语言的正确的表达方式(也就是一个标记流)。随机序列发生器对于随机地产生结构化的激励序列(例如指令或网络流量模式)非常有用。

序列发生器使用个randsequence块内的一组规则和生成式。randsequence块的语法如下:

statement_item ::=           // 引用自附录A.6.4
    ...
  | randsequence_statement

randsequence_statement ::= randsequence([production_identifier])  // 引用自附录A.6.12
        production {production}
    endsequence

production ::= [function_data_type] production_name[(tf_port_list)]:rs_rule{|rs_rule};

rs_rule ::= rs_production_list [:= expression[rs_code_block]]

rs_production_list ::=
    rs_prod {rs_prod}
  | rand join [(expression)] production_item production_item {production_item}

rs_code_block ::= {{data_declaration} {statement_or_null}}

rs_prod ::=
    production_item
  | rs_code_block
  | rs_if_else
  | rs_repeat
  | rs_case

production_item ::= production_identifier[(list_of_arguments)]

rs_if_else ::= if(expression) production_item [else production_item]

rs_repeat ::= repeat(expression) production_item

rs_case ::= case(expression) rs_case_item {rs_case_item} endcase

rs_case_item ::=
    expression{, expression}:production_item
  | default [:] production_item

语法12-12 — randsequence语法(摘录自附录A)

一个randsequence文法有一个或多个生成式组成。每一个生成式都包含了一个名字和一个生成式条目的列表。生成式条目可以进一步分类成端接和非端接。非端接根据端接和其它的非端接定义。一个端接是一个不可分割的条目,除了与其关联的代码块外它不需要进一步的定义。最终,每一个非端接被分解成它的端接。一个生成式列表包含了一连串的生成式条目,它指示这些条目必须按顺序形成流。单个生成式可以包含以|符号分割的多个生成式列表。以|符号分割的生成式列表意味着一组选择,发生器能够随机地对它们做出选择。

下面的简单的例子演示了一些基本概念:

randsequence(main)
    main   : first second done;
    first  : add | dec;
    second : pop | push;
    done   : {$display("done");};
    add    : {$display("add");};
    dec    : {$display("dec");};
    pop    : {$display("pop");};
    push   : {$display("push");};
endsequence

生成式main依据三个非端接(first、second和done)定义。当main被选择的时候,它产生序列first,second和done。当first被产生的时候,它被分解成它的生成式,它在add和dec之间指定一个随机选择。类似地,second生成式在pop和push之间指定一个选择。所有其它的生成式都是端接;它们被它们的代码块完全指定,在这个例子中就是显示生成式名字。因此,文法会导致下列可能的结果:

add pop done
add push done
dec pop done
dec push done

当randsequence语句被执行的时候,它产生一个文法驱动的随机生成式的流。当每一个生成式被产生的时候,执行它的相关代码块的边带效应产生了期望的激励。除了基本文法外,序列发生器规定了随机权重、交叉和其它的控制机制。尽管randsequence语句在本质上不会产生一个循环,然而一个递归的生成式会导致循环。

randsequence语句产生一个自动的范围。所有的生成式标识符对于这个范围来讲是本地的。另外,在randsequence块内部的每一个代码块都产生一个匿名的自动范围。对在代码块内部的变量的层次化引用是不被允许的。为了声明一个静态变量,必须使用static前缀。randsequence关键字可以跟着一个可选的生成式名字(在圆括号内),它指定了顶层生成式的名字。如果没有指定的话,第一个生成式成为顶层生成式。

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

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

发布评论

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