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循环这边改一下就好
问题二
对一个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
可以看到正确的完成了我们的需求
全部0条评论
快来发表一下你的评论吧 !