FPGA入门系列5--运算符号

文章简介

本系列文章主要针对FPGA初学者编写,包括FPGA的模块书写、基础语法、状态机、RAM、UART、SPI、VGA、以及功能验证等。将每一个知识点作为一个章节进行讲解,旨在更快速的提升初学者在FPGA开发方面的能力,每一个章节中都有针对性的代码书写以及代码的讲解,可作为读者参考。

第六章:运算符号

Verilog HDL 中的运算符号基本和 c 语言中的运算符号相同,本章讲解常用的几种运算符。 

        算数运算符(+、-、x、\、%)是非常熟悉的运算符,只拿%作介绍。在测试文件中我们有时候会想要产生 0~N 之间的数据,那么就可以用求余加上随机函数得到,假设我们实现 0~9 之间的随机数,我们可以按照如下代码示例所示实现。 

代码示例 1: 

reg [3:0] a; 

always #5 a = {$random}%10; 

代码解析 1:

 ① 第 1 行定义一个能表示 0 到 15 的变量;

 ② 第 2 行对随机数取 10 的余数,得到的值为 0~9。 

关系运算符有(>、<、>=、<=、==、!=),关系运算符得到的结果要么为真(1)要么为假(0)。但是在运用中很多人会犯一些错误,比如 b 的结果根据 a 是否在 5~9 来决定,现有如下两种代码示例情况。

代码示例 2: 

代码解析 2:

 ①当 a=2 时,(1)中可写成 5<2<9,此时 5<2 的结果为假(0),2<9 的结果为真(1),所以此时 b=1;同理可知无论 a 为任何值,b 均为 1。所以这种 写法虽然语法无错误,但是实现不了我们想要的功能。 

②当 a=2 时,(2)中可写成 5<2&&2<9,此时此时 5<2 的结果为假(0), 2<9 的结果为假(0),假(0)与(&)假(0)的结果为假(0),所以此时 b=0。此种写法才能满足我们的逻辑功能。

逻辑运算符(&&、||、!)运算的结果只有真(1)和假(0)。对于&&来 说,运算的两个数据有一个为 0,其结果就为 0,否则为 1。对于||来说,只有 运算的两个数据都有 0 时,其结果才为 0,否则为 1。任何数据取 !,逻辑结果则取反。具体举例如下所示。 

代码示例 3:

                        wire[1:0]     a; 

                        wire[2:0]     b; 

                        assign c = a && b; 

                        assign c = a || b; 

                        assign c = ! a; 

代码解析 3:

 ①第 1、2 行定义两个变量,假设 a=2,b=3;

 ②第 3 行求 a&&b 的结果,由于 a、b 都不为 0,所以运算结果为 1; 

③第 4 行求 a||b 的结果,由于 a、b 不同时为 0,所以运算结果为 1; 

④第 5 行求!a 的结果,由于 a 不为 0,所以运算结果为 1。

位运算符(&、|、~)是按照运行数据的每一位分别进行运算的。

对于 & 来说,运算的两个数据的对应位进行相与,结果为每一位相与的值。

对于 | 来说, 运算的两个数据的对应位进行相或,结果为每一位相或的值。

对于 ~ 来说,是将参与运算的数据按位取反。需要注意按位运算是需要将参与运算的数据转变成二进制,然后再运算。举例如下所示。

代码示例 4:

                        wire[1:0] a = 2'b10; 

                        wire[2:0] b = 3'd3; 

                        assign c = a & b; 

                        assign c = a | b; 

                        assign c = ~ a;

                        assign c = & a; 

代码解析 4: 

①第 1、2 行定义两个赋有初始值的变量;

②第 3 行实现 a & b,此时需要将 a 和 b 都转换成二进制,a=2’b10,b=3’b011, 此 时 a 和 b 的 位 宽 不 一 样 , 位 宽 少 的 需 要 在 高 位 补 0 , 最 后 运 算 为 3’b010 & 3’b011 = 3’b010;

③第 4 行实现 a | b,此时需要将 a 和 b 都转换成二进制,a=2’b10,b=3’b011, 此 时 a 和 b 的 位 宽 不 一 样 , 位 宽 少 的 在 高 位 补 0 , 最 后 运 算 为 3’b010 | 3’b011 = 3’b011; 

④第5行实现 ~ a,最后运算为~2’b10 =2’b01; 

⑤第6行实现&a,最后运算为 a[1]&a[0]=1&0=0。

 条件运算符(()?:),assign 语句后面只能跟一条语句,有时候可能会需要在条件不一样时对某变量赋不同的值,所以用条件运算符可以很方便的满足该要求, 示例如下。 

代码示例 5: 

assign a = (b>6) ? 1'b1 : 1'b0 ; 

代码解析 5: 

当 b 大于 6 为真时将顿号前面的值(1'b1)赋值给 a,否则将顿号后面的值(1'b0)赋值给 a。

 赋值运算符(=、<=),阻塞赋值运算符(=)用在组合逻辑中,非阻塞赋值运算符(<=)用在时序逻辑中,非阻塞赋值运算符与小于等于号比较像,但是非阻塞赋值运算符是赋值号,小于等于号是判断符,所以非常好区分。

 移位运算符(>>、<<),>>为右移运算符,每次右移一位,数据的高位补 0;<<为左移运算符,每次左移一位,数据的低位补 0。示例如下所示。 

代码示例 6: 

                        reg[3:0] a = 4'b0110; 

                        always @ (posedge clk)

                            b <= a >> 1'b1; 

                        always @ (posedge clk) 

                            c <= a << 1'b1; 

代码分析 6: 

①第 1 行定义一个寄存器变量 a,其值为 4’b0110; 

②第 2、3 行描述了将 a 右移一位赋值给 b,当遇到 clk 沿时,b=4’b0011; 

③第 4、5 行描述了将 a 左移一位赋值给 c,当遇到 clk 沿时,c=4’b1100。 

位拼接运算符({})可以将不同数据的位拼接成一个新的数据,示例如下所示。

代码示例 7:

                        reg[3:0] a= 4'b0110; 

                        reg[4:0] b= 5'b10110;

                        always @ (posedge clk) 

                        c <= { b[1], a[1:0], b[3], b[1] };

 代码解析 7: 

①第 1、2 行定义了 a、b 两个 reg 型变量,值分别为 4’b0110、 5’b10110; 

②第 3、4 行描述了将 a、b 不同的位拼接成一个新的变量 c,结果 c = 5’b11001。

在第七章中将对Verilog HDL 中的判断语句进行讲解。

FPGA入门系列1--模块书写&电路综合

FPGA入门系列2--仿真验证

FPGA入门系列3--wire与reg

FPGA入门系列4--赋值语句

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值