Verilog HDL F.A.Q.s (Frequently Ask Questions)

If文のネスト動作
if (a >= 5)
 if (a <= 10)
  $display ("Hello Veritak!");
else
  $display ("Hello Veritak!") ;


は、正しい解釈ではありません。Verilog HDLには、elseif というレキサ(単語の認識)はなく、あるのは、if とelse だけです。

else 文は、最も最近のif とペアになります。下記が正しい解釈です。

if (a >= 5)
 if (a <= 10)
   $display ("Hello Veritak!");
 else
   $display ("Hello Veritak!") ;


ですから、

always @(negedge reset_n or posedge clk ) begin
   if(~reset_n)
       s_reg    <=  8'h00;
   else if (rio)
       if (adr_hit )
           s_reg    <=  8'h01;
   else if (wt_pls)
       if (d )
         s_reg    <=  8'h01;
   else
         s_reg    <= 8'h02;
end

と書いても、コンパイラの解釈は、下のようになります。

always @(negedge reset_n or posedge clk ) begin
   if(~reset_n)
       s_reg    <=  8'h00;
   else if (rio)
       if (adr_hit )
           s_reg    <=  8'h01;
     else if (wt_pls)
         if (d )
            s_reg    <=  8'h01;
       else
            s_reg    <= 8'h02;
end

意図したように動かすには、begin -end を適切に挿入するしかありません。


always @(negedge reset_n or posedge clk ) begin
   if(~reset_n)       s_reg    <=  8'h00;
   else if (rio) begin
       if (adr_hit )  s_reg    <=  8'h01;
   end
  else if (wt_pls) begin
         if (d )   s_reg    <=  8'h01;
   end else s_reg    <= 8'h02;
  	
end

この問題は、C言語に由来し構文解釈的にはShift-Reduce問題として知られています。元々C言語は、構文解釈的には、曖昧な言語でして、大半のCに由来する言語も同じ動きをします。また、この辺の反省でelsif を構文で持っている言語もあります。特に、Pythonの場合、インテンド自体に構文の意味を持たせているので、曖昧な解釈自体が排除されており、このような問題が生じません。