Verilog 并位操作符
在Verilog语法中,向量可以按位(bit)引用,也可以部分引用,如:wire [7:0] a; 在使用向量a时,可以使用a[0], a[1],…a[7]; 也可以使用部分连续的位组成新的向量,如:a[7:6], a[4:3], a[2:1], a[5:3] 等。但如果使用不连续的位拼接起来是否可以呢?利用位拼接符可实现。
Verilog中 位拼接符是由一对花括号{} 实现的,在花括号内,任何位,矢量,常数都可以拼接起来。{}不仅可以拼接,而且还是有序的。例如: bit拼接可以形成新的向量,因此a[3:0] 可以写成 {a[3],a[2],a[1],a[0]}。下面介绍位拼接的一些用法:
- 位拼接可以实现多个位的组合形成新的变量向量,参加运算。如: {a[3:2},a[0],a[1]}, {a[3:0],b[3:0]} ,{a[3:0],1’b0} 等。
- 位拼接可以嵌套,如:
{a[3:2],{4{2’b01}} } 等效为{a[3:2],8’b01010101},即 四个2’b01拼接在一起。也可以向量嵌套,{3{a[3:2]}}等效为{a[3:2],a[3:2],a[3:2]}。
- 参与赋值运算
移位寄存器的使用:
例:
module shift8 ( input clk, input load, input [7:0] a, output [7:0] c ); reg [7:0] shift_r; assign c = shift_r; always@(posedge clk) if(load) shift_r <= a; else shift_r <= {shift_r[6:0], shift_r[7]}; endmodule
上例就是利用位拼接的方式实现循环左移,如果要实现循环右移只要将 shift_r<={shift_r[6:0],shift_r[7]};改成 shift_r<={shift_r[0],shift_r[7:1]};即可。由于在CPU的开发中,会经常用到各种移位,下面列举利用位拼接实现的移位:
(a)循环左移
shift_r <= {shift_r[6:0], shift_r[7]};
(b)循环右移
shift_r <= {shift_r[0],shift_r[7:1]};
(c)逻辑左移
shift_r <= {shift_r[6:0], 1’b0};
(d)逻辑右移
shift_r <= {1’b0, shift_r[7:1]};
(e)算术左移
shift_r <= {shift_r[7],shift_r[5:0],1’b0};
(f)算术右移
shift_r <= {shift[7], shift_r[7:1]};
进位位的使用:如四位全加器的代码
assign {co,y} = a + b + ci;
注意:如果有常量参与位拼接,不能用在赋值语句的左边。
算术左移的shift[5:0]不应该是shift_r[5:0]?
笔误已更新,谢谢指出!
欢迎同学阅读指正!