| **银杏科技有限公司旗下技术文档发布平台** |||| |技术支持电话|**0379-69926675-801**||| |技术支持邮件|Gingko@vip.163.com||| ^ 版本 ^ 日期 ^ 作者 ^ 修改内容 ^ | V1.0 | 2019-02-18 | gingko | 初次建立 | ===== 实验五:逻辑门实验——基本运算符 ===== ==== 一、 实验目的与意义 ==== - 掌握Verilog HDL语言中基本运算符的使用方法 - 掌握QuartusII的使用方法 ==== 二、 实验设备及平台 ==== - iCore4T 双核心板。 - iTool A(或相同功能)仿真器。 - USB Type C线缆。 - Keil MDK 开发平台。 - Quartus开发平台。 - 电脑一台。 ==== 三、 实验原理 ==== * 运算符是用来执行程序代码运算的,是一段代码的重要组成部分。在Verilog HDL中按照功能划分,运算符可分为算术运算符、逻辑运算符、关系运算符、条件运算符、按位运算符、拼接运算符、移位运算符、等式运算符、赋值运算符等类型。按照运算符所带的操作数的个数划分可分为3类,即: * (1)单目操作符,运算符可带一个操作数; * (2)双目操作符,运算符可带两个操作数; * (3)三目操作符,运算符可带三个操作数。 === 1、算术运算符 === * 在Verilog HDL中的算术运算符有多种,其中最常用的有4种,如表5-1所示。 * 表5-1 算术运算符 |操作符 |执行的操作 |操作数个数 |表达式| |+ |加法运算 |2 |rega + 10| |- |减法运算 |2 |rega - 10| |* |乘法运算 |2 |rega * 10| |/ |除法运算 |2 |23 / 10,运行结果为2。| * **在基本算术运算符应用过程中需要注意:** * (1)在进行整数除法运算时,省略所有小数部分,只保留整数部分; * (2)在进行算术运算操作时,如果操作符的某个操作数出现x或z时,则整个操作的运算结果为x。 === 2、逻辑运算符 === * 在Verilog HDL中有三种逻辑运算符,如表5-2所示。逻辑运算的结果只有两种:0(假)和1(真),其逻辑真值如表5-3所示。 * 表5-2 逻辑运算符 |操作符 |执行的操作| 操作数个数 表达式 |! |逻辑求反 |1 |!a| |&& |逻辑与 |2 |a && b| |//||// |逻辑或 |2 |//a || b//| * 表5-3 逻辑运算真值表 |a |b |!a |!b |a && b |//a || b//| |1 |1 |0 |0 |1 |1| |1 |0 |0 |1 |0 |1| |0 |1 |1 |0 |0 |1| |0 |0 |1 |1 |0 |0| === 3、关系运算符 === * 关系运算符主要表征两者之间的关系,常用于两个操作数的比较,常用的有四种符号类型,如表5-4所示。 * 表5-4 关系运算符 |操作符 |执行的操作 |操作数个数 |表达式| |< |小于 |2 |a < b| |> |大于 |2 |a > b| |< = |小于等于 |2 |a <= b| |>= |大于等于 |2 |a >= b| * 在进行关系运算时,如果表达式的两个操作数之间的关系时正确的,则运行结果为1(真),否则,运行结果为0(假);如果表达式中的某个操作数为不定值(x和z),则运行结果为x。 === 4、条件运算符 === * 条件运算是根据条件表达式的运行结果来选择执行表达式的,有3个操作数,其符号位“?:”,使用方式如下: con_expression ? true_expression : false_expression; * 在运行条件运算符时,若条件表达式(con_expression)为真,则运行真表达式(true_expression),否则,运行假表达式(false_expression)。例如: wire data_out = sel_en ? a : b; 其运行结果为:若sel_en为真,data_out的值取a;否则,data_out的值取b。 === 5、按位运算符 === * 按位运算是两个操作数按照对应位进行“与”或“非”等逻辑操作,常用的按位运算符有5种,如表5-5所示。 * 表5-5 按位运算符 |操作符 |执行的操作 |操作数个数 |表达式| |~ |按位求反 |1 |~a| |& |按位与 |2 |a & b| |//|// |按位或 |2 |//a | b//| |//^// |按位异或 |2 |//a ^ b//| |//~^,^~// |按位同或 |2 |//a ~^ b,a ^~ b//| * 在按位运算中,若两个操作数的位宽不一致,则会自动将两个操作数右对齐,高位补0后进行运算。 === 6、拼接运算符 === * 拼接运算是将两个或多个操作数的某些位拼接起来得到一个新数据的表达式,其运算符号为“{}”,被拼接的操作数用“,”隔开,其表达式如下: {signal1,signal2} === 7、移位运算符 === * 在Verilog HDL中有两种移位运算符,如表5-6所示。 * 表5-6 移位运算符 |操作符 |执行的操作 |操作数个数 |表达式| |>> |右移 |2 |a >> m,a为操作数,m为移的位数| |<< |左移 |2 |a << m,a为操作数,m为移的位数| === 8、等式运算符 === * 在Verilog HDL中有四种等式运算符,如表5-7所示。 * 表5-7 等式运算符 |操作符 |执行的操作 |操作数个数 |表达式| |== |等于 |2 |a == b| |!= |不等于 |2 |a != b| |=== |等于 |2 |a === b| |!== |不等于 |2 |a !=== b| * 在进行等式运算中,“==”和“!=”又被称作是逻辑等式运算符,由于等式运算中的两个操作数有可能是x和z,因此其运算结果可能是不定值x。但是,“===”和“!==”对比时要求两个操作数必须完全一致,因此其运行结果只有0和1两种。 === 9、赋值运算符 === * 赋值运算就是Verilog HDL的赋值语句,根据赋值操作后变量改变方式的不同,赋值语句又分为连续赋值和过程赋值两种,如表5-8所示。 * 表5-8 赋值运算符 |操作符 |执行的操作 |操作数个数 |表达式| |= |连续赋值 |不定 |a = b| |= |过程赋值 |不定 |a = b| |<= |过程赋值 |不定 |a <= b| * 通常,连续赋值运算用于“assign”语句中,用于对wire型变量进行赋值,“=”两侧的操作数时随时变化的,例如: * assign a = b,当b信号发生变化时,a都随之变化。 * 在过程赋值中,按照操作数改变时刻的不同,分为阻塞赋值(=)和非阻塞赋值(<=)两种。 * **(1)阻塞赋值方式** * 1)赋值语句执行完成后,才结束块的运行; * 2)操作数在赋值语句执行后立刻改变变量值; * **(2)非阻塞赋值方式** * 1)在语句块中,赋值语句执行完成后,在块结束前,赋值语句中操作数的值保持不变; * 2)块结束后,对操作数进行赋值操作,且所赋值为上一次赋值得到的; * 3)非阻塞赋值方式常用于编写可综合的时序逻辑模块中。 ==== 四、 代码讲解 ==== === 1、算数运算符表达式 === 根据原理中描述的算数运算符使用规则,首先定义两个有初始值的变量,然后对两个变量进行“加、减、乘、除”运算,然后通过Signaltap工具观察运行结果是否与实际相符。其代码如下: reg [5:0]x1 = 6'd10; reg [5:0]y1 = 6'd25; assign a = x1 + y1;//加法运算符表达式,运行结果a=6'd35; assign b = y1 - x1;//减法运算符表法式,运行结果b=6'd15; assign c = 2 * x1;//乘法运算符,运行结果c=6'd20; assign d = y1 / 5;//除法运算符,运行结果d=6'd5; //注意:若y1无法被除尽时,小数位直接省去,只保留整数位; === 2、逻辑运算符表达式 === 其代码如下: reg x2 = 1'b1; reg y2 = 1'b0; assign e = !x2;//逻辑求反表达式,运行结果e=0; assign f = x2 && y2;//逻辑与表达式,运行结果f=0; assign g = x2 || y2;//逻辑或表达式,运行结果g=1; === 3、关系运算符表达式 === 其代码如下: reg [3:0]x3 = 4'd3; reg [3:0]y3 = 4'd8; reg [3:0]z3 = 4'd8; assign h = (x3 < y3) ? (y3 - x3) : 4'd0;//小于号表达式,运行结果h=5; assign i = (x3 > y3) ? 4'd0 : (y3 + x3);//大于号表达式,运行结果i=11; assign j = (y3 <= z3) ? (y3 - x3) : 4'd0;//小于等于号表达式,运行结果i=5; assign k = (y3 >= z3) ? (y3 - x3) : 4'd0;//大于等于号表达式,运行结果i=5; === 4、按位运算符表达式 === 其代码如下: reg [3:0]x4 = 4'b0101; reg [3:0]y4 = 4'b1001; assign l = ~x4;//按位求反表达式,运算结果l=4’b1010; assign m = x4 & y4;//按位与表达式,运算结果m=4'b0001; assign n = x4 | y4;//按位或表达式,运算结果n=4'b1101; assign o = x4 ^ y4;//按位异或表达式,运行结果0=4’b1100; assign p = x4 ~^ y4;//按位同或表达式,运行结果p=4'b0101; === 5、拼接运算符 === 其代码如下: reg [3:0]x5 = 4'b0101; reg [3:0]y5 = 4'b1100; assign q = {x5,y5};//拼接运算符表达式,运行结果q=8'b01011100; === 6、移位运算符表达式 === 其代码如下: reg [3:0]x6 = 4'b1001; assign r = x6 << 3;//左移表达式,运行结果r=4'b1000; assign s = x6 >>3;//右移表达式,运算结果s=4'b0001; ==== 五、 实验步骤及实验结果 ==== 1、将硬件正确连接,如图5.1所示。 {{ :icore4t:icore4t_ide_1_37.jpg?600 |图5.1}} 2、将编写好的代码进行编译,并将要观察的所有输出信号添加到Sinaltap中; 3、通过Signaltap工具对所有运算结果进行采集,采集结果如图5.2所示。 {{ :icore4t:icore4t_fpga_5_2.png?direct |图5.1}} 4、观察Signaltap采集到的运算结果与代码中注释的实验结果相同。 ==== 六、 拓展实验 ==== - 更改实验代码中的变量的初始值,看看运算结果有何不同; - 编写代码观察阻塞赋值与非阻塞赋值有何不同。