ブロックと非ブロックの割り当て

29537 ワード

無双兄貴のブログを見て
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

阻塞和非阻塞赋值_第1张图片
 こんな風に変えたら?またいくつか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レベル
阻塞和非阻塞赋值_第2张图片
2つのブロック賦値を1つのalwaysに入れると、以下に示すようにregが1つだけ統合されます.
 
 

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

 
2つの非ブロック付与値を1つのalwaysに変更すると、以下に示すように2つの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を見てみましょう
このコードは、1クロック周期で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