0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看威廉希尔官方网站 视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Verilog中的数据位操作技巧

CHANBAEK 来源:杰克拉力船长 作者:杰克拉力船长 2023-10-01 17:12 次阅读

大家好,这里是程序员 杰克 。一名平平无奇的嵌入式软件工程师

FPGA相比MCU而言,在数据位操作上有很明显的优势。FPGA支持任意位拼接以及数据截取操作。本篇主要是总结和分享一些对数据位操作的实用语法技巧。内容不多,其中最最最重要的内容是数据的动态位截取操作。

下面正式进入本章推送的内容。

01 数据位操作技巧

数据移位(shift)

Verilog中的移位操作有两种:逻辑移位操作(logical)、算数移位操作(arithmetic)。逻辑移位使用“<<”、和“>>”,而算术移位使用“<<<”、和“>>>”,描述以及代码示例如下所示:

image.png

//本示例使用逻辑、算术右移为例:
//逻辑右移( >>), 初始值为4'b1000, 移位结果为4'b0010
module shift();
reg [3:0] value, rusult;
initial begin
    value = 4'b1000;
    result = (value > > 2);
end
endmodule


//算术右移( >> >), 初始值为4'b1000, 移位结果为4'b1110
module shift();
reg signed [3:0] value, rusult;
initial begin
    value = 4'b1000;
    result = (value > >> 2);
end
endmodule

数据位拼接(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;
end
endmodule

IEEE标准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工程师而言,合理应用数据位操作是一项非常重要的能力。对于一些特定的使用场合,合理使用数据位操作可以很大地节约逻辑资源。

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

    关注

    1629

    文章

    21736

    浏览量

    603389
  • mcu
    mcu
    +关注

    关注

    146

    文章

    17148

    浏览量

    351199
  • Verilog
    +关注

    关注

    28

    文章

    1351

    浏览量

    110100
  • 语法
    +关注

    关注

    0

    文章

    44

    浏览量

    9815
收藏 人收藏

    评论

    相关推荐

    stm32的串口通信中的USART_WordLength,数据位的长度包不包括开始哪些?

    stm32的串口通信中的USART_WordLength,数据位的长度包不包括开始哪些?
    发表于 10-11 17:57

    请问如何提取modbus RTU协议数据位

    图一是“接收内容”-创建-字符串类的属性-显示样式(因为十六进制显示才能正常接收,否则乱码),图二是modbus rtu 协议的数据传输,图三是传感器传输的“接收内容”的一组数据,请问如何实现
    发表于 03-30 15:16

    串口数据位问题

    原子哥在串口初始化 void uart_init(u32 pclk2,u32 bound){。。。。USART1->CR1|=0X200C;//1停止,无校验.。。。。}没有对bit12进行或
    发表于 06-13 04:35

    如何使用不同数据位的LCD改变4X数据位和掩码的移位?

    任何人都可以帮助代码或功能,将在4模式下接口4X20液晶和PIC18F46K22与端口1,2,3,4,而不是上或下Nybble,因为我发现的所有代码。我已经尝试改变4X数据位和掩码的移位,但是没有成功。我希望有人有一个功能,你可以改变
    发表于 11-07 09:41

    如何收发数据位宽度为9数据

    如何收发数据位宽度为9数据
    发表于 01-27 06:33

    操作的相关资料推荐

    支持操作),详情请参考相关内核处理器的指南或威廉希尔官方网站 参考手册(TRM)。1、操作CPU不能直接对位带区的单个
    发表于 02-07 09:24

    上位机如何设置串口9位数据位/TB8

    串口多机通讯,上位机如何设置串口9位数据位/TB8**常用的串口数据位设置只有5~8,但对于多机通讯要求9位数据位,即要求通过设置TB8区分地址与
    发表于 02-23 07:28

    在RTTlibmodbus支持的数据位是怎样去配置的

    一、结论大家都很忙,所以先说结论。libmodbus 中支持的数据位为 5,6,7,8(图1)。 但是,如果使用STM32 并且配置了奇偶校验,那么正确的数据长度配置应该是9。有人说这是ST的bug
    发表于 03-16 09:51

    关于NICE接口传输的数据位宽问题

    上图是NICE 接口的内存通道,图中内存通道的读写数据位宽都是32bit,根据赛题要求,需要在协处理器设计加速核心,挂靠NICE接口 我的预期:我所设计的加速核心需要更大的数据带宽(比如
    发表于 08-12 07:40

    stm32串口7位数据位

    STM32系列单片机控制寄存器只支持8、9位数据位
    的头像 发表于 07-23 11:15 6738次阅读

    stm32 7位数据位 usart_wordlength_

    stm32 7位数据位如何设置?一般情况下设置数据位为8、1个停止,再设置每个发送字节的最高位为“1”,去掉收到字节的最高位即可。这样每个字节的最高位自动变成1个停止
    的头像 发表于 07-26 09:17 5010次阅读

    问题笔记:STM32串口数据位与校验

    问题:STM32移植freemodbus 后测试时,只能使用无校验 ,设置奇偶校验时无法与上位机通讯解决方法如果串口助手使用串口配置为:数据位8 停止1 有奇偶校验STM32需设置为:数据位9
    发表于 12-24 18:44 19次下载
    问题笔记:STM32串口<b class='flag-5'>数据位</b>与校验<b class='flag-5'>位</b>

    初识“操作

    ”什么是“操作”?CPU不能直接对位带区的单个数据位寻址,只能通过对位带别名区的访问(或读/写)实现对位带区单个
    发表于 01-12 17:18 0次下载
    初识“<b class='flag-5'>位</b>带<b class='flag-5'>操作</b>”

    串行通信中的波特率、数据位和校验设置

    当进行串行通信时,波特率、数据位和校验是必须要设置的参数,以确保发送端和接收端之间的数据传输能够正确进行。
    的头像 发表于 06-29 18:14 7045次阅读

    RS-232串口通信起始数据位,停止怎么区分?

    数据位和停止。 1. 起始 起始是指在RS-232用来标识开始传输数据的信号
    的头像 发表于 09-12 16:04 7197次阅读