入力にタスクを使う

[] [] []


入力波形をべた書きするよりも、taskを使った方が読みやすくなる。taskfunctionと似ているが、functionは出力が1個なのに対して、taskでは外部のreg変数に代入することができる。

× 入力波形をべた書きする

initial begin

  // 初期値

  wr  = 1'b0;

  rd  = 1'b0;

  adr = 8'bx;

  dat = 16'bz;

  // バスライト 1回目

  @(posedge clk);

  wr  <= #(TCO) 1'b1;

  adr <= #(TCO) 8'h05;

  dat <= #(TCO) 16'h5555;

  @(posedge clk);

  wr  <= #(TCO) 1'b0;

  adr <= #(TCO) 8'bx;

  dat <= #(TCO) 16'bz;

  // バスライト 2回目

  @(posedge clk);

  wr  <= #(TCO) 1'b1;

  adr <= #(TCO) 8'h0a;

  dat <= #(TCO) 16'haaaa;

  @(posedge clk);

  wr  <= #(TCO) 1'b0;

  adr <= #(TCO) 8'bx;

  dat <= #(TCO) 16'bz;

  ...

  $finish;

end

 

入力波形をtaskで書く

reg[15:0] rdat;

initial begin

 $timeformat(-6,3," us",10); // "000.000 us"

  // 初期値

  wr  = 1'b0;

  rd  = 1'b0;

  adr = 8'h00;

  dat = 16'bz;

  // ライトしてリードする

  bus_wr(8'h05,16'h5555);

  bus_wr(8'h0a,16'haaaa);

  bus_rd(8'h05,16'hxxxx,rdat);

  bus_rd(8'h0a,16'haaaa,rdat);

  bus_rd(8'h05,16'h6666,rdat);

  // 1us毎にポーリングする

  bus_rd(8'h01,16'bx,rdat);

  while(rda!==16'h0001) #(1000) bus_rd(8'h01,16'bx,rdat);

  $finish;

end

// Note:SystemVerilogなら変数名も書けてわかりやすい

//   bus_wr(.a(8'h05),.d(16'h5555));

 

// バスライト動作のタスク

task bus_wr

  (input[7:0]  a  // アドレス

  ,input[15:0] d  // ライト値

  );

  begin

  @(posedge clk);

  wr  <= #(TCO) 1'b1;

  adr <= #(TCO) a;

  dat <= #(TCO) d;

  @(posedge clk);

  while(ack!==1'b1) @(posedge clk); // ackを待つ

  // Note:SystemVerilogなら1行で書ける

  //   do @(posedge clk); while(ack!==1'b1);

  wr  <= #(TCO) 1'b0;

  adr <= #(TCO) 8'bx;

  dat <= #(TCO) 16'bz;

  $display("--(%t) %m(%h,%h)",$time,a,d);

  end

endtask

 

// バスリード動作のタスク

task bus_rd

  (input[7:0]  a  // アドレス

  ,input[15:0] d  // リード期待値

  ,output[15:0] rdat  // 実際のリード値

  );

  begin

  @(posedge clk)

  rd  <= #(TCO) 1'b1;

  adr <= #(TCO) a;

  @(posedge clk);

  while(ack!==1'b1) @(posedge clk); // ackを待つ

  rd  <= #(TCO) 1'b0;

  adr <= #(TCO) 8'bx;

  rdat = dat;

 // リード値の判定

  $write("--(%t) %m(%h,%h)",$time,a,rdat);

  if(d===16'bx)     $display("");

  else if(d===rdat) $display(" [PASS]");

  else              $display(" expectd=%h [FAIL]",d);

  end

endtask

(構文の補足)

$write( )は改行なし、$display( )は改行ありが違うだけ。

%mは現在の階層名を表示するので表示は次のようになる

--(  0.030 us) tb.bus_mod.bus_wr(05,5555)

--(  0.060 us) tb.bus_mod.bus_wr(0a,aaaa)

--(  0.090 us) tb.bus_mod.bus_rd(05,5555)

--(  0.120 us) tb.bus_mod.bus_rd(0a,aaaa) [PASS]

--(  0.150 us) tb.bus_mod.bus_rd(0a,5555) expected=6666 [FAIL]

--(  0.180 us) tb.bus_mod.bus_rd(01,0000)

--(  1.200 us) tb.bus_mod.bus_rd(01,0000)

--(  2.220 us) tb.bus_mod.bus_rd(01,0001)


[] [] []