阻塞和非阻塞赋值

看了无双大哥的blog

http://www.cnblogs.com/oomusou/archive/2010/07/30/blocking_vs_nonblocking.html

记下自己的一点想法

首先

module nonblocking (
clk,
rst_n,
a_i,
b_i,
a_o,
b_o
);

input clk;
input rst_n;
input a_i;
input b_i;
output a_o;
output b_o;

reg a;
reg b;

assign a_o = a;
assign b_o = b;

always@(posedge clk or negedge rst_n) begin
if (~rst_n) begin
a
<= a_i;
b
<= b_i;
end
else begin
a
<= b;
b
<= a;
end
end

endmodule

 如果改成这样呢?又是几个reg

module div_2(
clk,
Din,
OUT
);


input wire clk;
input wire [1:0] Din;
output reg [1:0] OUT;

reg [1:0] DFF_inst;


always@(posedge clk)
begin
begin
DFF_inst[
1:0] = Din[1:0];
end
end


always@(posedge clk)
begin
begin
OUT[
1:0] = DFF_inst[1:0];
end
end


endmodule

RTL级

如果把两个阻塞赋值放到一个always里,如下所示,则只会综合出一个reg

 

 

1 always@(posedge clk)
2  begin
3 DFF_inst[1:0] = Din[1:0];
4 OUT[1:0] = DFF_inst[1:0];
5  end

 

如果改成两个非阻塞赋值放到一个always里,如下所示,则会综合出二个reg

 

1 always@(posedge clk)
2 begin
3 DFF_inst[1:0] <= Din[1:0];
4 OUT[1:0] <= DFF_inst[1:0];
5 end

 

 

 再来看看特权同志的http://blog.ednchina.com/ilove314/141803/message.aspx

这段代码的用意是在一个时钟周期内计算出13路脉冲信号为高电平的个数,

一般人都会感觉这个任务交给for循环来做再合适不过了,但是for循环能完成这个任务吗?

 

1 module test(clk,rst_n,data,numout);
2  input clk;
3
4  input rst_n;
5
6  input[12:0] data; //the input data
7  
8  output[15:0] numout; //the total number of the input data
9  
10  wire[15:0] numout;
11
12  reg[3:0] i;
13
14  reg[15:0] num;
15
16  always @ (posedge clk) begin
17 if(!rst_n) begin
18 num <= 0;
19 end
20 else begin
21 for(i=0;i<13;i=i+1'b1) begin //use for to number
22   if(data[i]) num <= num+1'b1;end
23   end
24
25  end
26
27  assign numout = num;
28
29 endmodule
30
31

 

 有仿真结果可知,这种方法不行,若改成阻塞的呢?

 

1 module test(clk,rst_n,data,numout);
2 input clk;
3
4 input rst_n;
5
6 input[12:0] data; //the input data
7
8 output[15:0] numout; //the total number of the input data
9
10 wire[15:0] numout;
11
12 reg[3:0] i;
13
14 reg[15:0] num;
15
16 always @ (posedge clk) begin
17 if(!rst_n) begin
18 num = 0;
19 end
20 else begin
21 for(i=0;i<13;i=i+1'b1) begin //use for to number
22 if(data[i]) num = num+1'b1;end
23 end
24
25 end
26
27 assign numout = num;
28
29 endmodule
30
31

 

这次就可以了。。。。

原因:Always语句中使用非阻塞赋值<=时,是在always结束后才把值赋给左边的寄存器,因此才第一种情况。

测试代码:

 

`timescale 1ns/1ns
module test_tb();

reg clk;

reg rst_n;

reg [12:0] data;     
wire[15:0] numout;     
test U1
(
	.clk(clk),
	.rst_n(rst_n),
	.data(data),
	.numout(numout)
);

initial
begin
	clk=0;	
	rst_n=0;
	#3 rst_n=1;
	data=13'b0101010110101;
	#40 data=13'b1111000000111;
	#40 data=13'b0000000000000;
end 

always #10 clk=~clk;

endmodule 

 

 

posted on 2010-11-22 16:49  齐威王  阅读(809)  评论(0编辑  收藏  举报

导航