Verilog中的数据位操作技巧

大家好,这里是程序员 杰克 。一名平平无奇的嵌入式软件工程师。
fpga相比mcu而言,在数据位操作上有很明显的优势。fpga支持任意位拼接以及数据截取操作。本篇主要是总结和分享一些对数据位操作的实用语法技巧。内容不多,其中最最最重要的内容是数据的动态位截取操作。
下面正式进入本章推送的内容。
01 数据位操作技巧
数据移位(shift)
verilog中的移位操作有两种:逻辑移位操作(logical)、算数移位操作(arithmetic)。逻辑移位使用“”,而算术移位使用“<>”,描述以及代码示例如下所示:
//本示例使用逻辑、算术右移为例://逻辑右移( >>), 初始值为4'b1000, 移位结果为4'b0010module shift();reg [3:0] value, rusult;initial begin value = 4'b1000; result = (value > > 2);endendmodule//算术右移( >> >), 初始值为4'b1000, 移位结果为4'b1110module shift();reg signed [3:0] value, rusult;initial begin value = 4'b1000; result = (value > >> 2);endendmodule数据位拼接(concatenations)
顾名思义,“数据位拼接”是由多个表达式产生的位拼接在一起的输出结果。其使用大括号“{}”来表示,内部表达式之间使用逗号“,”隔开。
对于位拼接操作,不允许使用不确定大小的常量;位拼接中唯一可以使用的操作是复制(replication)。
数据位拼接操作示例如下:
//1. 简单位拼接操作reg [1:0] a;reg [3:0] b;reg [9:0] result = {2'b10, a, b[2:0], 3'd7};//2. 复制拼接操作reg [1:0] c;reg [2:0] d;reg [9:0] result;result = {2{c, d}};//=={ {c[1:0], d[2:0]}, {c[1:0], d[2:0]} }//3. 参数化代码示例parameter para = 32; //para = [1,32]wire [31:0] e;assign e = { {(32-para){1'b1}}, f[(para-1):0] };数据位截取(bit select)
数据位截取(bit select)可以从线网( net )、寄存器( reg )、整数( integer )、时间( time )、参数( parameter )等类型进行任意位截取。ieee中verilog标准中对位截取的语法表达式如下:
vect[msb_expr : lsb_expr];/*其中msb_expr 是整形/常量表达式, lsb_expr 是常量表达式;当msb_expr为常量表达式时,数据位截取则为静态截取;当msb_expr为整形表达式时,数据位截取则为动态截取;*/静态截取示例代码如下:
//从vect[31:0]截取低16位赋值给value[15:0]module bit_select();reg [31:0] vect;reg [15:0] value;initial begin vect = 32'haaaa_cccc; value = vect[23:8]; //value = 16'haacc;endendmoduleieee标准verilog中,对reg、integer、time变量/parameter参数动态截取语法如下所示:
//动态截取操作语法reg [15:0] big_vect;reg [0:15] little_vect;big_vect [lsb_base_expr +: width_expr]little_vect [msb_base_expr +: width_expr]bit_vect [msb_base_expr -: width_expr]little_vect [lsb_base_expr -: width_expr]/*width_expr为常量表达式, 在代码运行时不能改变;lsb/msb_base_expr为整形表达式, 作为从在运行时可以动态改变;width_expr作为截取的位宽值, 而msb/lsb_base_expr为截取的起始地址;“+”为地址向上递增操作, “-”为地址向下递增操作;上面代码功能是: 从msb/lsb_base_expr地址开始, 向上(+)/向下-截取width_expr位宽的数据;*/在上面的代码中,width_expr为常量表达式,代码运行时不能改变;lsb_base_expr/msb_base_expr 为整形表达式,在运行时可以改变;代码示例:
reg [31:0] big_vect;reg [0:31] little_vect;reg [63:0] dword;integer sel;big_vect[0 +:8] //==big_vect[7 :0], 从第0位向上截取8bit的数据big_vect[15-:8] //==big_vect[15:8], 从第15位向下截取8bit的数据little_vect[0 +:8] //==little_vect[0: 7]little_vect[15-:8] //==little_vect[8:15]dword[8*sel +: 8] //从第(8*sel)位截取8位宽总结说明:
在表达式vect[base_expr +:/-: width_expr]中,
width_expr为截取的固定位宽,是常量值;
base_expr为截取的 起始第bit位地址 ,可以 是整形变量值,动态变更 ;
05 文章总结
对于一名优秀的fpga工程师而言,合理应用数据位操作是一项非常重要的能力。对于一些特定的使用场合,合理使用数据位操作可以很大地节约逻辑资源。

金立要卷土重来?靠新机化解负债211亿?
50家锂电板块企业业绩预报出炉,几家欢喜几家愁
华为预计今年将在5G研发上投入超100亿元全力支持运营商建好中国5G
下一代晶体管露脸
0月租免实名 一张成本几块钱利润几十块 诚招代理
Verilog中的数据位操作技巧
什么是平均值和有效值?
中琛魔方如何助力企业深度挖掘数据价值,成为创新发展的新动力
LED章鱼玩具的制作
泰凌微电子B91通用开发板合入OpenHarmony社区主干
Allegro MicroSytems, LLC发布具有电池反接保护功能的全新240kHz带宽、高精度、现场可编程线性霍尔传感器IC
三电控制器功率级联合仿真测试
新能源汽车新政:支持力度加大 产业链将受益
雷达流速监测系统的特点及应用
dcdc开关频率高低有什么影响
浅谈电池电芯卷材准确的张力控制
全项目多功能食品安全综合检测仪器设备功能介绍
西安市青年科技从业者人文艺术关爱计划 应用材料公司各美讲堂正式启动
小米11 Pro支持IP68防水?
PCB Layout 1A电流需要1mm的线宽的原因分析