一、逻辑运算符与按位运算符
区别:按位运算符进行逐位的逻辑运算(如:与或非),输出与输入位数一致;逻辑运算符进行逻辑运算,不关注输入的某一位而是将输入作为整体进行逻辑操作,输出位数为 1;
列举:
- 与:& 按位与;&& 逻辑与;
- 或:| 按位或;|| 逻辑或;
- 非:~ 按位非;! 逻辑非;
二、缩位运算符
灵活使用缩位运算符,可以简化代码,避免重复工作;
如:
&a 可实现 a 各位间的与运算,即:&a 等价于 a(0)&a(1)&…&a(n)
| a 可实现 a 各位间的或运算,即:| a 等价于 a(0)|a(1)|…|a(n)
三、迭代连接运算符
连接功能:将若干个寄存器类型/线网类型的变量首尾连接,形成一个更大位宽的变量;
如:
a = 2’b10;
b = 3’b010;
有{a,b} = 5’b10010;
迭代功能:把一个变量复制多次,首尾连接组成一个更大位宽的变量;(实际仍为连接功能的一个特例:连接元素相同)
如:
a = 2’b10;
有{4{a}},即{a,a,a,a}
注意:要保证迭代的完整性:例如 { {4{a}},b},其中 {4{a}} 为迭代功能,括号不能少;即不能写为{ 4{a},b}。
另外,迭代连接运算符还可用于常量操作:{ {4{1’b1}},2’b10}
四、逻辑移位运算符与数字移位运算符
列举:
<< 逻辑左移运算符;<<< 数字左移运算符;
>> 逻辑右移运算符;>>> 数字右移运算符;
区别:逻辑移位运算符不关心符号位;逻辑左移右端补零,逻辑右移左端补零;数字左移位运算符不关心符号位,与逻辑左移一样;数字右移运算符关心符号位,左端补符号位;
如:
1010101010,其中[]是添加的位
逻辑左移一位:010101010[0]
算数左移一位:010101010[0]
逻辑右移一位:[0]101010101
算数右移一位:[1]101010101
五、仿真验证
进行部分仿真(感觉很简单,着手去编写的时候却碰见了不少问题,万不可眼高手低!!!),代码如下:
`timescale 1ns / 1ps // // Company: // Engineer: guoliang CLL // // Create Date: 2020/02/19 10:15:53 // Design Name: // Module Name: operation // Project Name: // Target Devices: // Tool Versions: // Description: 常见操作符测试 // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // // module operation( input [1:0]a, input [2:0]b, input signed[5:0]c, //input signed[5:0]d, output [5:0]e,// {3{a}} output [4:0]f, // {a,b} output [5:0]g,// {{2{2'b10}},b} output [5:0]sl, // 逻辑左移 output [5:0]sr,// 逻辑右移 output [5:0]sl1, // 数字左移 output [5:0]sr1 // 数字右移 ); integer N = 2'b11; assign e = {3{a}}; assign f = {a,b}; assign g = { {2{2'b11}} ,a}; assign sl = c << 1; assign sr = c >> 1; assign sl1 = c <<< 1; assign sr1 = c >>> 1; endmodule
添加测试文件:
`timescale 1ns / 1ps // // Company: // Engineer: // // Create Date: 2020/02/19 10:59:51 // Design Name: // Module Name: operation_tsb // Project Name: // Target Devices: // Tool Versions: // Description: // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // // module operation_tsb( ); reg [1:0]a; reg [2:0]b; reg signed[5:0]c; //input signed[5:0]d, wire [5:0]e;// {3{a}} wire [4:0]f; // {a,b} wire [5:0]g;// {{2{2'b11}},b} wire [5:0]sl; // 逻辑左移 wire [5:0]sr;// 逻辑右移 wire [5:0]sl1; // 数字左移 wire [5:0]sr1; // 数字右移 initial begin a = 2'b10; b = 3'b101; c = 6'b110010; # 20 c = 6'b010011; end operation ins( .a(a), .b(b), .c(c), .e(e), .f(f), .g(g), .sl(sl), .sr(sr), .sl1(sl1), .sr1(sr1) ); endmodule
RTL 电路以及仿真结果:


从上述仿真结果,可以看出移位、迭代连接操作与上文描述一致;
g 的输出,证明迭代连接运算符确实可以用于常量操作,并且可以常量与变量混用,即仿真中的{ 2{2‘b11},a}
需要注意的地方:
验证迭代连接运算符确实可以用于常量操作时,如果将常量声明为 integer 类型,g 的输出就不正确,即仿真中的 integer N=2‘b11;
g = { {2{N}},a}时输出不对;改为 parameter 类型时,输出正确;
原因在于 interger 默认为 32 位宽,拼接后被截取导致只有低位,因此不正确;即使定义时限定了 interger 的位宽,还是会按照默认 32 位宽;integer 好像就是位宽不能精确定义,这也是在位宽敏感时避免使用的原因。
扫码关注尚为网微信公众号

原创文章,作者:sunev,如若转载,请注明出处:https://www.sunev.cn/embedded/1236.html