Verilog基础:操作数的位选(bit-select)和域选(part select)

相关阅读

Verilog基础icon-default.png?t=N7T8https://blog.csdn.net/weixin_45791458/category_12263729.html?spm=1001.2014.3001.5482


位选

        位选(bit-select)用于选择一个向量(vector)的某位,可以是线网大类(net),也可以是变量大类(variable)中的reg、integer和time(注意:real和realtime不可以位选)。

        位选的语法如下所示。

vector [expression]

         如果位选expression的结果超出vector的范围或者位选expression的结果包含x或z,则位选作为右值计算的结果是x,仿真器会给出警告,如下例所示。

module test();
    reg [2:0] a = 3'b101;
    reg b = 1'b1;

    initial #1 $display("a[0] is %d", a[0]);        //a[0] is 1
    initial #1 $display("a[b] is %d", a[b]);        //a[b] is 0
    initial #1 $display("a[1'bx] is %d", a[1'bx]);  //a[1'bx] is x
    initial #1 $display("a[3] is %d", a[3]);        //a[3] is x
endmodule

        如果位选expression的结果超出vector的范围或者位选expression的结果包含x或z,则位选作为左值不会有任何作用,仿真器会给出警告,如下例所示。 

module test();
  reg [2:0] a = 3'b000;
  initial #1 begin a[3]=1'b1;a[1'bx]=1'b1;end
  initial #2 $display(a is "%b",a); // a is 000
endmodule

域选

        域选(part select)用于选择一个向量(vector)的连续某几位,该向量可以是线网大类(net),也可以是变量大类(variable)中的reg、integer和time(注意:real和realtime不可以域选)。

        域选有两种形式,常量域选和索引域选(Verilog 2001标准引入),下面分别进行说明。

常量域选

        常量域选的语法如下所示。

vector [msb_expr : lsb_expr]

        其中msb_expr和lsb_expr都必须计算为常量。msb_expr和lsb_expr的相对大小,需要符合vector定义时msb_expr和lsb_expr的相对大小,如下例所示。

module test();
    reg [4:0] b = 5'b01010;     //msb(left hand) is greater than lsb(right hand)
    reg [0:4] a = 5'b01010;     //msb(left hand) is less than lsb(right hand)

    initial #1 $display("b[1:0] is %b", b[1:0]);  //right, select lsb 2 bits, 10
    initial #1 $display("b[1:0] is %b", b[0:1]);  //false, msb(left hand) should be greater than lsb(right hand)
    initial #1 $display("a[1:0] is %b", a[3:4]);  //right, select lsb 2 bits, 10
    initial #1 $display("a[1:0] is %b", a[4:3]);  //false, msb(left hand) should be less than lsb(right hand)
endmodule

        msb_expr和lsb_expr可以相等,此时相当于位选,如下例所示。

module test();  
    reg [4:0] b = 5'b01010;;    

    initial #1 $display("b[1] is %b", b[1]);  //right bit-select, 1
    initial #1 $display("b[1:1] is %b", b[1:1]);  //right part-select, 1
endmodule

        如果域选作为右值超出界限,则超出界限的部分为x,这是多数仿真器的处理方式,但也有仿真器选择让所有结果为x,不管如何处理,仿真器会给出警告,如下例所示。 

module test();
    reg [4:0] b = 5'b01010;;    
    initial #1 $display("b[5:-1] is %b", b[5:-1]);  //x01010x for most simulator
endmodule

// x01010x
Mentor Modelsim SE
Aldec Riviera Pro
Mentor Questa
Synopsys VCS
Icarus Verilog

// xxxxxx
Cadence Xcelium

        如果域选作为左值超出界限,则超出界限的位不会写入,只有界限中的位会被写入,这是多数仿真器的处理方式,但也有仿真器选择不进行任何写入,不管如何处理,仿真器会给出警告,如下例所示。

module test();
  reg [2:0] a = 3'b000;
  initial #1 begin a[2:-1]=4'b1100;end
  initial #2 $display("%b",a);
endmodule

// 110
Mentor Modelsim SE
Aldec Riviera Pro
Mentor Questa
Synopsys VCS
Icarus Verilog

// 000
Cadence Xcelium

        如果msb_expr或lsb_expr出现了x或z,则仿真器会报错。 

索引域选

        索引域选的语法如下所示。

reg [15:0] big_vector;
reg [0:15] little_vector;

big_vector    [lsb_base_expr +: width_expr]
little_vector [msb_base_expr +: width_expr]
big_vector    [msb_base_expr -: width_expr]
little_vector [lsb_base_expr -: width_expr]

        可以看出,根据向量msb_expr和lsb_expr的相对大小,索引域选的解释方式不同。但都由两部分组成,base表达式可以是一个非常量表达式,width表达式必须是一个常量表达式,即可以动态索引固定数量的位,下面给出了一些等价写法。

reg [15:0] big_vector;
reg [0:15] little_vector;
reg a=0;
reg b=5;

******************
big_vector [5:0]  
big_vector [a+:6]
******************
big_vector [5:0]  
big_vector [b-:6]
******************
little_vector [0:5]
little_vector [a+:6]
******************
little_vector [0:5]
little_vector [b-:6]

        索引域选的越界问题和常量域选是一样处理的,因为它们本来就是可互相转换的。

  • 33
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

日晨难再

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

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

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

打赏作者

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

抵扣说明:

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

余额充值