Verilog语法中运算符的用法

描述

Verilog语法--位选择运算(+: 和 -:)

verilog语法中使用以下两个运算符可以简化我们的位选择代码

+:

-:

这两个的用法如下

 

wire [7:0] a;
a[base_addr +: width]
a[base_addr -: width]

 

其中base_addr指的是起始选择位,width指的是选择的位宽

比如以下使用说明

 

wire [31:0] a;
a[0 +: 8]  等价于 a[7:0]
a[0 +: 16] 等价于 a[15:0]
a[16 +: 8] 等价于 a[23:16]

a[7 -: 8]  等价于 a[7:0]
a[15 -: 16]等价于 a[15:0]
a[15 -: 2] 等价于 a[15:14]

 

这样写有什么好处呢,比如下面两个使用场景

假设有一个128bit的数据,怎么方便的将其分割为16个8bit的数据

对一个32比特的数据进行按字节的大小端翻转

问题一

假设有一个128bit的数据,怎么方便的将其分割为16个8bit的数据

如果要解决上面的问题,我们可以直接手动的进行位选择,代码如下:

 

`timescale 1ns / 1ps
module tb(

    );
wire [127:0] a;
wire [7:0] b [15:0];

assign a = {8'd1, 8'd2, 8'd3, 8'd4, 8'd5, 8'd6, 8'd7, 8'd8, 8'd9, 8'd10, 8'd11, 8'd12, 8'd13, 8'd14, 8'd15, 8'd16};

assign b[ 0] = [  7:  0];
assign b[ 1] = [ 15:  8];
assign b[ 2] = [ 23: 16];
assign b[ 3] = [ 31: 24];
assign b[ 4] = [ 39: 32];
assign b[ 5] = [ 47: 40];
assign b[ 6] = [ 55: 48];
assign b[ 7] = [ 63: 56];
assign b[ 8] = [ 71: 64];
assign b[ 9] = [ 79: 72];
assign b[10] = [ 87: 80];
assign b[11] = [ 95: 88];
assign b[12] = [103: 96];
assign b[13] = [111:104];
assign b[14] = [119:112];
assign b[15] = [127:120];
endmodule

 

为了方便观察,我们将a的值赋值为1到16的特殊值,下面b里面的每一个元素都从a里面进行截取,如果bit数比较少的话,可以按上述代码这样完成,但是这个代码看着也很啰嗦,所以可以按照下面的代码进行改进

 

`timescale 1ns / 1ps
module tb(

    );
wire [127:0] a;
wire [7:0] b [15:0];
genvar i;

assign a = {8'd1, 8'd2, 8'd3, 8'd4, 8'd5, 8'd6, 8'd7, 8'd8, 8'd9, 8'd10, 8'd11, 8'd12, 8'd13, 8'd14, 8'd15, 8'd16};

generate
    for (i = 0; i < 16; i = i+1) begin
        assign b[i] = a[(i*8) +: 8];
    end
endgenerate

endmodule

 

可以看到使用位选择加for循环的方式会很方便,以后即使位宽改变了,也仅仅只是在for循环这边改一下就好

Verilog

问题二

对一个32比特的数据进行按字节的大小端翻转

最直接的代码可以按下面这样写

 

`timescale 1ns / 1ps
module tb(

    );
wire [31:0] a;
wire [31:0] b;

assign a = {8'd1, 8'd2, 8'd3, 8'd4};

assign b = {a[7:0], a[8:15], a[23:16], a[31:24]};
endmodule

 

当位宽比较小的时候可以按上面的方式进行,如果位宽比较大的话,上面的这种方法就显得很冗余了,我们就可以使用位选择的方式来进行赋值

 

`timescale 1ns / 1ps
module tb(

    );
wire [31:0] a;
wire [31:0] b;

genvar i;

assign a = {8'd1, 8'd2, 8'd3, 8'd4};

generate
    for (i = 0; i < 4; i = i + 1) begin
        assign b[(4 - i) * 8 - 1 -: 8] = a[i * 8 +: 8];
    end
endgenerate

endmodule

 

Verilog

可以看到正确的完成了我们的需求

 

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分