3.14 ステートに名前を付ける![]()
WaveformViewを見ていても数字の羅列で分かりにくい事があります。Verilog3.1では、enumを使って記述できるのですが、Verilog3.1がメジャーになり、普通に合成ツールのサポートされるまで、まだ数年かかるでしょう。Veritakで実装することも考えたのですが、当面、`ifdef Veritakで、記述がスマートでなくなってしまうし、、と思っていたところ、あるUser様より素晴らしいアイデアを頂戴しました。
その方法は、名前をパラメータのリストで実現するものです。
たとえば、次のような記述になります。
勿論、Verilog言語仕様に完全に合致する記述です。
module sub (clock,a);
parameter [3:0] as0=4'h0,as1=4'h1,asx=4'bxxxx,asz=4'bzzzz,
as2=4'h2,as3=4'h3,as4=4'h4,as5=4'h5;
parameter[3:0] astate=4'h0,bstate=4'h1,cstate=4'h2,dstate=3;
input clock;
input [3:0] a;
wire [3:0] a_func_result=a_func(a);
function [3:0] a_func;
input [3:0] a;
case (a)
astate:a_func=as0;
bstate:a_func=as1;
cstate:a_func=as2;
dstate:a_func=as3;
default:a_func=asx;
endcase
endfunction
endmodule
|
これを、WaveformViewで見ると、下図のようになります。断然分かりやすいですね。ToolTipで、数字も出しています。

ところで、これをするには、WaveformView上で、信号とステート名の対応付けを指定してやる必要があります。下のように信号右クリック=>表示選択=>enum選択を指定します。

するとパラメータを選択するダイアログが現れるので、指定します。

なお、ダイアログ内に表示されるのは、インスタンス展開した後の、モジュール内パラメータリストで、記述順に並びます。Veritak内部では、この記述順で、対応(バインディング)を管理しています。(従って、順番が変わらなければ、中身が変わっても関知しませんが、Scopeが変わると消失します。)
Note:
次の例は、YACCプロジェクトのALUの記述例です。
module alu (a,b,alu_func,alu_out);
parameter [3:0] ALU_NOTHING =4'b0000,
ALU_ADD =4'b0001,
ALU_SUBTRACT =4'b0010,
ALU_LESS_THAN_UNSIGNED =4'b0101, //Jul.5.2004
ALU_LESS_THAN_SIGNED =4'b0100, //Jul.5.2004
ALU_OR =4'b0011,
ALU_AND =4'b0110,
ALU_XOR =4'b0111,
ALU_NOR =4'b1000;
input [31:0] a,b;
output [31:0] alu_out;
input [3:0] alu_func;
reg [31:0] alu_out;
reg [32:0] sum;
always @(a , b ,alu_func,sum) begin
case (alu_func)
ALU_NOTHING : alu_out=32'h0000;
ALU_ADD : alu_out=a+b;
ALU_SUBTRACT : alu_out=a+~b+1'b1;//a-b;
ALU_OR : alu_out=a | b;
ALU_AND : alu_out=a & b;
ALU_XOR : alu_out=a ^ b;
ALU_NOR : alu_out=~(a | b);
ALU_LESS_THAN_UNSIGNED : alu_out=a < b;//Jun.29.2004
ALU_LESS_THAN_SIGNED: begin
sum={a[31],a}+~{b[31],b}+1'b1;//a-b $signed(a) > $signed(b);
alu_out={31'h0000_0000,sum[32]};
end
default : alu_out=32'h0000_0000;
endcase
end
endmodule
|

TIPS
Verilo2001では、$sformat($sprintf)を使い、上図のように逆アセンブラも容易に書くことができます。YACCプロジェクトのページをご参照ください。