verilog里面always块中的阻塞赋值的问题
input [7:0] din;
reg [7:0] aaa;
reg [7:0] data;
always @(posedge clk) begin
if (flag == 0) begin
aaa[7:4] = din[3:0];
end
else begin
aaa[3:0] = din[3:0];
data <= aaa;
end
end
假设这个flag是每个时钟周期翻转一下,代码功能就是当io工作在4bit模式时,每两个时钟周期,搜集一次数据存在一个byte的data中,这个data后面要用到的,所以调整时序什么的就不说了,这段代码实现了在flag==1的那个周期,data就能完整的记录下第一个完整的8bit,假如全部改成非阻塞赋值,肯定就要等到下一个flag==1才能记录下了。貌似这么写挺奇怪的,不过实际使用当中倒是也没有问题。当然我也可以改成data <= {aaa[7:4],din[3:0]}。不过大家看下面这种怎么解决?
这个代码中还在always块中定义了一些reg变量,被当做local变量使用,赋值时候也是使用阻塞赋值,比如一个tmp变量经过一系列复杂判断后( 例如tmp=XXXXXX ),然后data <= tmp,这样data就能在当前的时钟周期就被修改而不用等到下一个时钟周期,这么写使用上也没有问题,就是觉得怪怪的,大家实际中有经常这么写么?假如这种想要修改成规范的写法应该如何修改比较好?
阻塞非阻塞在一个always里边用,这种东西别说是写来给别人看了,写来自己看都容易头晕。
阻塞和非阻塞一起用,只要是always里面只对一个寄存器操作,其实没有什么区别。
在你这个例子里面,也没有区别,你自己综合看一下网表就知道了。
规范就是把=改成<=
求教什么叫做“只对一个寄存器操作”,不是很明白
这是符合规范的写法——如果信号在always描述里面只作为临时变量使用的话,该信号可以使用阻塞赋值。具体参见IEEE 1364.1标准第5.2.2小节:
“Blocking procedural assignments may be used for variables that are temporarily assigned and used within an always statement.”
我对项目开发代码的要求就是可读性差的代码都是垃圾。。。
人家那段代码符合IEEE 1364.1 Verilog RTL综合标准,没任何问题
再说可读性怎么差了?你不过是先入为主而已
时序逻辑里不应该出现阻塞赋值 难懂且非主流啊。。。虽然综合着没问题
input [7:0] din;
reg [3:0] aaa;
reg [7:0] data;
always @(posedge clk) begin
if (flag == 0) begin
aaa[3:0] <= din[3:0];
end
end
always @ (posedge clk) begin
if(flag == 1) begin
data <= {aaa[3:0], din[3:0]};
end
end
可以改成这个样子嘛
改成这样
always @(posedge clk) begin
if (flag == 0) begin
aaa[7:4] = din[3:0];
end
else begin
data = {aaa[7:4], din[3:0]};
end
end
和改成这样
always @(posedge clk) begin
if (flag == 0) begin
aaa[7:4] <= din[3:0];
end
else begin
data <= {aaa[7:4], din[3:0]};
end
end
综合出来的网表没区别
always语句里面只有一个寄存器的时候,你用=还是用<=,最后综合出来的结果是没有区别的。
因为只有一个,它阻塞不了谁也不会被谁阻塞
你写RTL的时候,时序逻辑最好都要用<=, 组合逻辑的always里面最好都用=.
不要混杂=跟<=, 可读性太差,而且难以估计综合出什么样的结构出来。
一般编译工具都会警告你不要在一个always语句里面混用=何<=。