●C言語に似たverilogですが、intはあるけどfloatとかdoubleはありません.代わりに、レジスタを宣言するregと、配線の宣言をするwireがあり、regとwireを区別して宣言しなくてはいけません.
reg a;
1bitのフリップフロップを設けてその出力にaと名付ける.reg宣言した時点では、clockとかresetについてはまだ何も言及していません.
reg [3:0] abc;
4bitのフリップフロップを設けてその出力にabcと名付ける.変数を使うときはabcと略記するとabc[3:0]の4bitバスを意味します.律儀にabc[3:0]と表記してもOKです.バスの1本1本を表現したいときはabc[2]のように表記します.abc[1:0]のように一部でもOKです.
wire [4:0] sum;
フリップフロップではなく、ゲート回路(組み合わせ回路ともいう)の出力にsumと名付ける.wire宣言した時点では「なにかの回路」がなんなのかにはまだ何も言及してません.
assign sum = a + abc;
または
wire [4:0] sum = a + abc;
これらは式を読んでそのまんま加算の意味です.assignというのが面食らいますが、配線をつなぐ意味があります.後者はwire宣言と同時に配線をつないでいるのでassignを省略できてます.
ここまでの記述で、下図のように、フリップフロップ出力を加算したsumという値を得ることができています.
●下図のような完全な回路にするにはフリップフロップの実体を記述しなくてはいけません.フリップフロップの実体とは、clock,reset,入力,出力です.
まずフリップフロップaの実体を記述します.
wire ain;
always @(posedge clock or negedge reset)
if(!reset) a<=0;
else a<=ain;
フリップフロップにはverilog特有の記述がいろいろあります.
posedge clockは、clockの立ち上がりエッジで動作させる意味です.
negedge resetは、resetがLOW activeである意味です.
if(!reset) a<=0;は、resetがLOWならaをゼロにする意味です.
a<=ain;は、clockの立ち上がりでainをラッチしてaに出力する意味です.
if文は上の行が高プライオリティですので、resetが高優先度です.
<=はreg宣言した変数に代入する時のおきまりの表記です.=だとエラーになります.
reg宣言した変数にはalways文の中でしか代入できません.
要するにこれは、reset付きのDフリップフロップです.
次にフリップフロップabcの実体を記述します.
wire [3:0] abcin;
always @(posedge clock or negedge reset)
if(!reset) abc<=0;
else abc<=abcin;
最後にフリップフロップsumoutの実体を記述します.
reg [4:0] sumout;
always @(posedge clock or negedge reset)
if(!reset) sumout<=0;
else sumout<=sum;
●最後にサブルーチンみたいなmoduleという単位に閉じ込めます.
module adder (
input clock,
input reset,
input ain,
input [3:0] abcin,
output [4:0] sumout
);
上記の全てのcodeをここに転記する.......
endmodule
こうしたことで、adderという名前のmoduleをいくつでも呼び出して使うことができます.
●上記でフリップフロップでバッファされた演算回路の完全な記述をひとまず解説しました.つぎは、verilogならではの小技を解説します.
4bitバスを2つ連結して8bitバスにする
wire [3:0] P, Q; このように連続して宣言もできます.
wire [7:0] R = {P,Q};
こまかく書くとこういうこと→R={P[3],P[2],P[1],P[0],Q[3],Q[2],Q[1],Q[0]};
論理反転する
wire [7:0] POS;
wire [7:0] NEG = ~POS; POSが11001010ならNEGは00110101になります.
MSBだけ反転する
wire [7:0] MSBREV = {~POS[7],POS[6:0]};
引き算
wire [8:0] sub = POS - NEG;
かけ算
wire [15:0] mul = POS * NEG;
割り算
source codeに/演算子を記述することはできますが、論理合成してくれないのでhardware化できません.なのでverilogでhardwareを記述するときには/演算子は使いません.ただし、純粋softwareであるテストベンチを記述するには/演算子を使えるので使います.注意しましょう.
8bitシフトレジスタ
wire in;
reg [7:0] shift;
always @(posedge clk or negedge xrst)
if(!xrst) shift<=0;
else shift <= {shift[6:0],in}; LSBからMSBへ向けてshiftする
レジスタのenable動作
wire en;
wire [31:0] in;
reg [31:0] out;
always @(posedge CLOCK or negedge RESET)
if(!RESET) out<=0;
else if(en) out<=in; en=1の時だけinをラッチする、それ以外はダンマリ.
これでverilogがバシバシ使えるかというと、そうではありませんけど、これくらいを理解すれば、次のステップの解説へ進むことができると思います.
つぎへ 前へ
人気ブログランキングへ
verilogなどのソース記述する人の頭の中は、
返信削除スケマティック(回路図)が浮かんでいるのでしょうか。
それとも、ずばりソースで考えているのでしょうか?
ナイスな質問です.
返信削除わたしは1993年に初めてverilogを触りました.それまではgate使いでした.たぶん、gate使いだった最後の世代じゃないかと思います.
そのわたしですら、schematicを思い浮かべてverilogを吐くことはしません.頭の中で浮かべるのはデータフローです.データフローをverilogとして吐き出します.
なので、schematicからの派生としてverilogを位置づけた上記の解説は、どんだけ有意味なのかあまり自信がないのです.