ブロック図から回路を組み立てる

📌 このページの概要と目標

概要: そろそろ本格的な回路記述を始めます。仕様が与えられるので、それを理解して記述してください。ちょっと大変かもしれませんが頑張ってください。

目標:

  • 動作仕様・ブロック図から回路の動作を把握できる
  • 仕様から入出力端子表を作成できる
  • 内部ブロック図(回路構成)を検討できる
  • 各ブロックを組み合わせ回路/順序回路に分類できる
  • ブロック構成に沿ってVerilog記述ができる

1. 仕様から回路記述への手順

もふねこ

いきなりコードを書き始めるのはNG!🐾
まずは仕様から「どんな入出力があるか」「どういうブロックに分けるか」を整理するのが、失敗しない回路設計のコツだよ!

新しく回路を記述する場合には回路の仕様から作成することもありますが、ここでは動作仕様とブロック図が与えられた場合の回路記述手順について説明します。

ステップ作業内容成果物の例
① 仕様理解動作仕様・ブロック図から何を行う回路か・どのように動作するか把握する入出力端子表、タイミングチャート
② 回路構成の検討必要な回路を書き出し、信号の流れを書き込んで内部ブロック図を完成させる内部ブロック図
③ 回路種別の決定各回路ブロックを「組み合わせ回路」または「順序回路」のどちらにするか決める回路種別一覧
④ 回路記述決定した回路構成に沿って各ブロックをVerilogで記述するVerilogソースコード

2. 繰り返し演算回路の仕様

終了判定を通して「繰り返し演算回路」の仕様の理解から回路記述までを体験します。繰り返し演算回路の仕様を示します。何を行う回路か・またどのように動作するかを理解してください。

📌 繰り返し演算回路の動作仕様
  • クロックの立ち上がりでLD=1 のとき → 入力DINDOUTに出力(ロード動作)
  • クロックの立ち上がりでLD=0 のとき → DOUTの値に応じて演算を繰り返す:
    • DOUT奇数のとき → DOUT - 1
    • DOUT偶数のとき → DOUT ÷ 2(右シフト1ビット)
    • DOUT0のとき → 0を保持(終了状態)
  • DOUTが0になると次にLD=1でDINを読み込むまでDOUTは0を保持する

動作例:DIN = 255 の場合

クロックLDDOUT演算次のDOUT
1回目↑1(ロード)DIN読み込み255
2回目↑0255(奇数)255 − 1254
3回目↑0254(偶数)254 ÷ 2127
4回目↑0127(奇数)127 − 1126
5回目↑0126(偶数)126 ÷ 263
0繰り返し
最終00終了(0保持)0

3. 入出力端子表

信号名方向ビット幅機能
CLK入力1動作クロック(立ち上がりで動作)
RB入力1非同期リセット(0でリセット)
LD入力1ロード制御(1のときDINをロード)
DIN入力8演算の初期値入力(0〜255)
DOUT出力8演算結果出力

4. 動作タイミングの確認ポイント

タイミングチャートの読み方のポイントを整理します。

💡 タイミングチャートの読み方
  • CLKの立ち上がりエッジで出力が変化する
  • LD=1のとき:次のCLK↑でDOUT = DIN(ロード)
  • LD=0のとき:次のCLK↑でDOUT = DOUT[0]==1 ? DOUT-1 : DOUT>>1
  • DOUT=0になったら:LD=1にしてDINを再ロードするまで0を保持

5. 内部ブロック構成の検討

もふねこ

回路をブロックに分けるときの鉄則!🐾
「計算(組み合わせ回路)」と「記憶(順序回路)」をしっかり分けること!これができると、一気にプロっぽい設計になるよ!

この回路の動作が理解できたら今度は回路構成を考えます。以下の構成で実現できます。

ブロック名回路種別機能
演算ブロック(NEXT_DOUT)組み合わせ回路現在のDOUTとLDから次のDOUT値を計算する
レジスタブロック(DOUT_REG)順序回路(D-FF)CLKの立ち上がりで演算結果をラッチして出力する
💡 内部ブロック設計のポイント
  • 「次の状態を計算する」部分 → 組み合わせ回路(function または assign)
  • 「値を保持・出力する」部分 → 順序回路(always + posedge CLK)
  • LD=0かつDOUT[0]==1 → DOUT-1(奇数判定は最下位ビットDOUT[0]で判定)
  • LD=0かつDOUT[0]==0かつDOUT≠0 → DOUT>>1(右1ビットシフト = ÷2)

6. 回路記述(解答例)

内部ブロック構成に沿って回路記述を行います。演算部はfunction、レジスタ部はalways文で記述します。

module REPEAT_CALC ( CLK, RB, LD, DIN, DOUT );
input        CLK, RB, LD;
input  [7:0] DIN;
output [7:0] DOUT;
reg    [7:0] DOUT;

// ① 演算ブロック: 次のDOUT値を計算する(組み合わせ回路 → function)
function [7:0] NEXT_DOUT;
input        ld;
input  [7:0] dout;
begin
    if ( ld == 1'b1 )
        NEXT_DOUT = dout;           // LD=1: そのまま保持(ロード動作はalways側で実施)
    else if ( dout == 8'd0 )
        NEXT_DOUT = 8'd0;           // DOUT=0: 終了(0を保持)
    else if ( dout[0] == 1'b1 )
        NEXT_DOUT = dout - 8'd1;    // 奇数: -1演算
    else
        NEXT_DOUT = dout >> 1;      // 偶数: ÷2(右シフト)
end
endfunction

// ② レジスタブロック: CLK立ち上がりで演算結果をラッチ(順序回路)
always @( posedge CLK or negedge RB )
begin
    if ( RB == 1'b0 )
        DOUT <= 8'd0;               // 非同期リセット
    else if ( LD == 1'b1 )
        DOUT <= DIN;                // LD=1: DINをロード
    else
        DOUT <= NEXT_DOUT( LD, DOUT );  // LD=0: 演算結果をラッチ
end
endmodule
📌 記述のポイント
  • 奇数・偶数の判定は最下位ビット DOUT[0] で行う(1なら奇数、0なら偶数)
  • ÷2はVerilogの右シフト演算子 >> 1 で実現(符号なし右シフト)
  • DOUT=0の終了判定を忘れずに記述すること(無限ループ防止)
  • 非同期リセット → LD=1(ロード) → 演算の優先順位で記述する

📝 C7 まとめ: ブロック図から回路記述へ

設計ステップ作業内容
①仕様理解動作仕様とブロック図から何を行う回路かを把握する
②入出力端子表外部接続信号の名前・方向・ビット幅・機能を整理する
③内部ブロック図必要な回路を書き出し、信号の流れを整理する
④回路種別決定各ブロックを組み合わせ回路か順序回路かに分類する
⑤回路記述ブロック構成に沿ってVerilogで記述する