目次
1. デザインコード
1 Always の組み合わせロジック
always@(*)begin
end
2 シーケンシャルロジック
- 最初に同期する
always@(posedge clk)begin
if(!rst)
else
end
- 非同期最初
always@(posedge clk or negedge rst)begin
if(!rst)
else
end
3 インスタンス化されたループ文
genvar i;
generate
for()begin:name
instance
end
endgenerate
4 機能
1) 遅延、タイミング、またはタイミング制御ロジックが含まれていない
2) 少なくとも 1 つの入力変数がある
3)戻り値が 1 つだけあり、出力がない
4) ノンブロッキング代入ステートメントが含まれていない
5) 関数は他の関数を呼び出すことができるが、タスクを呼び出すことができません
function [N-1,0] function_id(
input A,
input B
);
//outher_declaration
//procedural statement
endfunction
- 定数関数の例
parameter MEM_DEPTH = 256 ;
reg [log2(MEM_DEPTH)-1: 0] addr_width ; //可得addr的宽度为8bit
function integer log2;
input integer depth ;
//256为9bit,我们最终数据应该是8,所以需depth=2时提前停止循环
for(log2=0; depth>1; log2=log2+1) begin
depth = depth >> 1 ;
end
endfunction
- 自動機能
一般的な関数を呼び出すと、その関数のローカル変数が同じ記憶領域を使用するため、同時に2箇所を呼び出すと不定な値が生成されてしまいます。
自動機能により、アドレス空間を自動的に割り当て、階層アクセスを行うことができます。
wire [16:0] results3 = plusd(6);
function automatic integer plusd ;
input integer data_in ;
begin
plusd = (data_in>=2)? data_in * plusd(data_in-1) : 1 ;
end
endfunction//阶乘运算
5 タスク
比較ポイント | 関数 | タスク |
---|---|---|
入力 | 関数には少なくとも 1 つの入力があり、ポート宣言に inout 型を含めることはできません | タスクは入力をまったく持たないか複数持つことができ、ポート宣言は inout 型にすることができます。 |
出力 | 関数には出力がありません | タスクには出力がまったくないか、複数の出力がある場合があります |
戻り値 | 関数には少なくとも 1 つの戻り値があります | タスクが値を返さない |
シミュレーションの瞬間 | 関数は常に時刻 0 に実行を開始します。 | タスクはゼロ以外の時間でも実行可能 |
シーケンシャルロジック | 関数にはタイミング制御ロジックを含めることはできません | Always ステートメントはタスク内に含めることはできませんが、遅延ステートメントなどの他のタイミング制御を含めることはできます。 |
移行 | 関数は関数のみを呼び出すことができ、タスクは呼び出すことはできません | タスクは関数とタスクを呼び出すことができます |
書き方の規範 | 関数は単一のステートメントとして出現できず、割り当て言語の右端にのみ配置できます。 | タスクはステートメント ブロック内の単一のステートメントとして表示できます。 |
シミュレーション時間単位 | この関数はメインモジュールと時間単位を共有します。 | タスクは独自のシミュレーション時間単位を定義できます |
https://www.runoob.com/w3cnote/verilog-task.html
task task_name;
//<端口名及数据类型说明>
//procedural statement
endtask
call
task_name(port1,port2,...);
ノート:
タスクの場合、入力はデフォルトで Wire、出力はデフォルトで reg になります。改めて説明する必要はありません。
- 例えば
task and;
input [N-1:0] a;
input [N-1:0] b;
output [N-1:0] c;
#3 c = a & b;
endtask
- 自動タスク
task automatic test;
2、テストベンチコード
1工程
//1 port type
//2 initialization signal
//3 stimulate signal
//4 generate clock
//5 module instance
//6 stop
2ストップ
initial begin
forever begin
#100;
if ($time >= 1000) $finish ;
end
end
3 時計
必ず 2.0 を使用してください。そうでない場合は問題が発生します (精度の問題)。
always #(period/2.0) clk = ~clk;