Menu Close

Verilog 按位运算符

Verilog 按位运算符

Verilog 位运算符也是主要由与、或、非等逻辑运算构成,但与逻辑运算符不同。逻辑运算符主要是对关系运算及等式运算后的值进行操作。而位运算是针对变量进行运算。运算的操作数可以取0,1,x,z四种,运算的结果包含0,1,x 三种情况的值。位运算符也叫按位操作符,是二元操作符(除~是一元操作符外),操作符对应的操作数是按照对应位一一运算的。

  • 按位操作符:

按位操作符包括取反(~),与(&),或(|),异或(^),同或(~^)。其中同或也可以理解为两个操作数先异或操作,再对异或的结果取反。

按位操作符对 2 个操作数的位进行按位操作。如果 2 个操作数位宽不相等,则用‘0’ 向左扩展补充较短的操作数。

如 c[3:0] = a[3:0] & b[0]  相当于 c[3:0] = a[3:0] & {3’b0, b[0]},

c[3] = a[3] & 1’b0,

c[2] = a[2] & 1’b0,

c[1] = a[1] & 1’b0,

c[0] = a[0] & b[0]。

  • 取反操作符:

取反操作符只有一个操作数,它对操作数的每 bit 数据进行取反操作。

操作数的类型不限,可以为输入、输出端口,也可以是wire类型数据,reg类型数据,甚至integer类型数据。

操作符决断函数表

1) ~

操作符 ~
输入 输出
a y
0 1
1 0
x x
z x

2) &

操作符&
输入 输出
a b y
0 0 0
0 1 0
0 x 0
0 z 0
1 0 0
1 1 1
1 x x
1 z x
x 0 0
x 1,x,z x
z 0 0
z 1 x
z x x
z z x

3) |

操作符|
输入 输出
a b y
0 0 0
0 1 1
0 x x
0 z x
1 0 1
1 1 1
1 x 1
1 z 1
x 1 1
x 0,x,z x
z 0 x
z 1 1
z x x
z z x

4) ^

操作符^
输入 输出
a b y
0 0 0
0 1 1
0 x x
0 z x
1 0 1
1 1 0
1 x x
1 z x
x 0 x
x 1,x,z x
z 0 x
z 1 x
z x x
z z x

5) ~^

操作符~^
输入 输出
a b y
0 0 1
0 1 0
0 x x
0 z x
1 0 0
1 1 1
1 x x
1 z x
x 0 x
x 1,x,z x
z 0 x
z 1 x
z x x
z z x

例:

module bit_op
(
  input  [3:0]  a,
  input  [3:0]  b,
 
  output [3:0]  na,
  output [3:0]  a_and_b,
  output [3:0]  a_and_b0,
  output [3:0]  a_or_b,
  output [3:0]  a_or_b0,
  output [3:0]  a_xor_b,
  output [3:0]  a_xor_b0,
  output [3:0]  a_nxor_b,
  output [3:0]  a_nxor_b0,
  output [3:0]  y
);
 
 
integer    i=3;
 
assign na        = ~a;
assign a_and_b   = a & b;
assign a_and_b0  = a & b[0];
assign a_or_b    = a | b;
assign a_or_b0   = a | b[0];
assign a_xor_b   = a ^ b;
assign a_xor_b0  = a ^ b[0];
assign a_nxor_b  = a ~^ b;
assign a_nxor_b0 = a ~^ b[0];   
 
assign y = ~i; 
 
endmodule

 

Modelsim testbench tb.v

`timescale 1 ns/1 ps
 
module tb
(
 
);
 
reg  [3:0]   a,b;
 
wire [3:0] na;
wire [3:0] a_and_b, a_and_b0;
wire [3:0] a_or_b, a_or_b0;
wire [3:0] a_xor_b, a_xor_b0;
wire [3:0] a_nxor_b, a_nxor_b0;
wire [3:0] y;
 
initial 
begin
    a = 4'b0000;
    b = 4'b0000;
    #10
 
    b = 4'b0001;
    #10
 
    a = 4'b0010;
    #10
 
    b = 4'b01x0;
    #10
 
    a = 4'b0x10;
    b = 4'b1x00;
    #10
 
    a = 4'bz110;
    b = 4'bx0z1;
    #10
 
    a = 4'b0111;
    b = 4'bz1x0;
    #10
 
    a = 4'b1111;
    b = 4'b0110;
    #10
 
    a = 4'b111x;
    b = 4'b0110;
    #10
 
    a = 4'b111x;
    b = 4'b011z;
    #10
 
    a = 4'b1111;
    b = 4'b011z;
end
 
bit_op  bit_op_dut
(
  .a           (a),
  .b           (b),
 
  .na          (na),
  .a_and_b     (a_and_b),
  .a_and_b0    (a_and_b0),
  .a_or_b      (a_or_b),
  .a_or_b0     (a_or_b0),
  .a_xor_b     (a_xor_b),
  .a_xor_b0    (a_xor_b0),
  .a_nxor_b    (a_nxor_b),
  .a_nxor_b0   (a_nxor_b0),
  .y           (y)
);
 
 
endmodule

 

%title插图%num

图1

根据决断函数表很容易分析表中的结果,这里需要单独解释的是当整数运算时,首先将整数按照32bit的方式展开,与其它参与运算的变量按照右对齐的方式,截取需要的位参与运算。

例:

integer i = 3;

wire [3:0] y;

assign y = ~i;

第一步:将i展开成   i = 32’b0000_0000_0000_0000 _0000_0000_0000_0011;

第二步: 按位取反 ~i = 32’b1111_1111_1111_1111_1111_1111_1111_1100;

第三步:右对齐按照被赋值的变量位宽截取: y = ~i = 4’b1100;

这个结果和modelsim的仿真结果一致。

关于多变量运算及赋值问题,参见赋值语句。

 

Posted in FPGA, FPGA, Verilog, Verilog
0 0 投票数
Article Rating
订阅评论
提醒
guest
0 评论
内联反馈
查看所有评论

相关链接