情報画像学実験II

実験II-1. 論理回路

回路作成例・解説


第4週目-課題1

図1 に記述例を示す。

module COUNTER5(OUT, CLK, RST);
    input CLK;
    input RST;
    
    output [2:0] OUT;
    reg [2:0] OUT;
    
    always@(posedge CLK) begin
        if(RST) begin    // リセット
            OUT <= 0;
        end else begin
            if(OUT==4) begin    // 4の次は 0
                OUT <= 0;
            end else begin    // それ以外の場合は1増加
                OUT <= OUT+1;
            end
        end
    end
endmodule
図1. 5進カウンタの Verilog 記述例

第4週目-課題2A

1. 図2 が Tフリップフロップの Verilog 記述例である。T フリップフロップの出力値は 入力 T が 0 のとき、直前の値と同値、 T が 1 のとき、直前の値の反転値となる。すなわち、Tフリップフロップの出力値は、直前の値と入力 T の排他的論理和 (XOR) により得られる値となる。

module T_FLIPFLOP(T, CLK, Q);
        input T;
        input CLK;
        output Q;

        reg Q;
        
        always@(posedge CLK) begin
                Q <= Q ^ T;
        end
endmodule
図2. Tフリップフロップの Verilog 記述例

図2のプログラムをシミュレーションすると、出力 Q の値は x となる。これは、出力 Q の値が直前の値に依存しており、かつ初期値が定められていないからである。シミュレーションを正しく実施するためには何かしらの初期値を与える必要がある。図3はリセット信号付き Tフリップフロップの Verilog 記述である。リセット信号 RST を用いることにより、出力値を直前の値に関わらず 0 にすることができる。なお、図では RST が 0 のとき出力値をリセットしている。RST を押しボタンに割り当てた場合、ボタンを押したときリセットする。

module T_FLIPFLOP(T, CLK, RST, Q);
        input T;
        input CLK;
        input RST;
        output Q;
        
        reg Q;
        
        always@(posedge CLK) begin
                Q <= RST ? Q ^ T: 1'b0;
                    // RST=0 のとき リセット
        end
endmodule
図3. リセット付きTフリップフロップの Verilog 記述例

2. クロックは非常にデリケートな信号であり、そのため、クロック専用の特殊な入力からしか入力できないように制限されている。押しボタンスイッチに割り当てようとすると、エラーが出てコンフィギュレーションデータを作成できないはずである。

3. 6MHz のクロックを用いていることから、秒間 3,000,000 回 LED が点滅していることになる。とても確認できる速度ではない。

4. 点滅を確認できるようにするためにはクロックの周波数を下げればよい。しかし、ボード上の水晶の発振を制御し、P39 から得られる周波数を直接下げることはできない。代わりに周波数を下げる回路を構成する。図4 に示す8進カウンタの波形図に注目されたい。カウンタを 6MHz のクロックで動作させたとき、最下位ビット I[0] は 3MHz, 続く I[1] は 1.5MHz, I[2] は 0.75 MHz で振動することは分かる。つまり、カウンタは周波数を下げる回路として使用できる。


図4. 8進カウンタの波形図

図5 に LED 点滅回路の Verilog 記述例を示す。例の場合、221進カウンタを用いており、3×106÷221≒1.43 Hz でLED が点滅する。なお、図1 の5進カウンタと異なり、カウンタ値を 0 に戻す操作を記述していない。これはカウンタ値が 221 になったとき、オーバフローが発生し、カウンタ値が 0 に戻るからである。

module BLINK(T, CLK, RST, Q);
        input T;
        input CLK;
        input RST;
        output Q;

        reg [21:0] R;    // カウンタ値
        assign Q = R[21];
            // カウンタ値の最上位ビットをそのまま出力

        always@(posedge CLK) begin
                if(!RST) begin    // リセット
                        R <= 0;
                end else begin
                        if(T) begin    // T=1 のとき、カウントアップ
                                R <= R + 1;
                        end
                end
        end
endmodule
図5. LED 点滅回路の Verilog 記述例

第4週目-課題3A

1. 図6に 10進カウンタ回路の Verilog 記述例を示す。ここでは、第2週、第3週に作成したモジュール DECODER7 を利用する。

押しボタンが押されたことを検出するためには、押しボタンに割り当てられた入力信号の立ち上がりを検出すればよい。フリップフロップのクロック入力を用いれば立ち上がりを検出できるように思うだろう。しかし、既に述べたとおり、押しボタンをクロック入力に割り当てることはできない。そこで、以下のように立ち上がりを検出する。まず、入力 IN の値を、INB に保存することとする。1クロック後、INB に保存された古い IN値が 1 (ボタンが押されていない状態) であり、かつ新しい IN 値が 0 (ボタンが押されている状態)であるとき、IN の立ち上がりを検出しカウンタの値を 1増加させる。

module BUTTON(IN, P19, P20, P21, P22, P30, P31, P40, P46, CLK, RST);
        input IN;
        output P19;
        output P20;
        output P21;
        output P22;
        output P30;
        output P31;
        output P40;
        output P46;
        input CLK;
        input RST;
        
        reg [3:0] COUNT;
        reg INB;
        
        DECODER7 U0 (.I3(COUNT[3]), .I2(COUNT[2]), .I1(COUNT[1]), .I0(COUNT[0]),
                .A(P19), .B(P20), .C(P21), .D(P22), .E(P30), .F(P31), .G(P40));
        
        always@(posedge CLK) begin    // IN の古い値を INB に保存
                INB <= IN;
        end
        
        always@(posedge CLK) begin
                if(!RST) begin
                        COUNT <= 0;
                end else begin
                        if(INB==1 && IN==0) begin    // 立ち上がり検出時
                                COUNT <= (COUNT == 9) ? 0 : COUNT + 1;
                        end
                end
        end
        
        assign P46 = 0;
endmodule
図6. 10進カウンタ回路の Verilog 記述例

2. 一度に2以上値が増加するのは第1週目にも考察したとおり、チャタリングのためである。つまり、押しボタンを押した瞬間、値は綺麗には 1 から 0 に変更されず、図7 のように、しばらく1へ0へと振動する。


図7. チャタリングが発生している入力波形図例

図8 にチャタリング対策を行った10進カウンタ回路の Verilog 記述例を示す。チャタリングを防ぐためには様々な方法がある。ここでは、チャタリングが発生する期間より十分長い、100Hz 前後の遅い周期で入力をサンプリングすることにする。具体的に 65536進カウンタを設け、カウンタ値 CLOCK_COUNT が 0 のときだけ押しボタンの状態をサンプリングする。サンプリングは INB, IN 取得時の2回行われる。サンプリング周期がチャタリング発生期間より十分長いことから、この両方にチャタリングの影響が出ることはまずない。よって、チャタリングの影響を受けることなく、入力値の立ち上がりを検出することができる。

module BUTTON(IN, P19, P20, P21, P22, P30, P31, P40, P46, CLK, RST);
        input IN;
        output P19;
        output P20;
        output P21;
        output P22;
        output P30;
        output P31;
        output P40;
        output P46;
        input CLK;
        input RST;
        
        reg [3:0] COUNT;
        reg [15:0] CLOCK_COUNT;
        reg INB;

        DECODER7 U0 (.I3(COUNT[3]), .I2(COUNT[2]), .I1(COUNT[1]), .I0(COUNT[0]),
                .A(P19), .B(P20), .C(P21), .D(P22), .E(P30), .F(P31), .G(P40));
        
        always@(posedge CLK) begin
                if(!RST) begin
                        CLOCK_COUNT <= 0;
                        COUNT <=0;
                end else begin
                        CLOCK_COUNT <= CLOCK_COUNT + 1;
                        if(CLOCK_COUNT == 0) begin
                                    // カウンタ値が 0 のときだけ IN値をサンプリング
                                if(INB==0 && IN==1) begin
                                        COUNT <= (COUNT == 9) ? 0 : COUNT + 1;
                                end
                                INB <= IN;
                        end
                end
        end
        
        assign P46 = 0;
endmodule
図8. チャタリング対策を行った10進カウンタ回路の Verilog 記述例

第4週目-課題3B

サンプルプログラムがそうであったように、Verilog には 同じような記述を何度も繰り返し行う必要がしばしば発生する。一応、繰り返しを避けるための記法もいくらか用意されており、創意工夫で繰り返しを減らすこともできる。しかし、繰り返し書いてしまった方が、分かり易く、手っ取り早いことも多い。エクセルの連番機能とコピー&ペーストを活用することにより、繰り返し記述する苦痛とミスもある程度は軽減できる。頑張って書いて欲しい。

1. 図9 に左右反転フィルタの記述例を示す。なお、繰り返しになる箇所は中略している。コピー&ペーストするときは適宜補うこと。

module FILTER(
                S00, S01, S02, S03, S04, S05, S06, S07,
                S08, S09, S10, S11, S12, S13, S14, S15,
                S16, S17, S18, S19, S20, S21, S22, S23,
                S24, S25, S26, S27, S28, S29, S30, S31,
                D00, D01, D02, D03, D04, D05, D06, D07,
                D08, D09, D10, D11, D12, D13, D14, D15,
                D16, D17, D18, D19, D20, D21, D22, D23,
                D24, D25, D26, D27, D28, D29, D30, D31,
                CLK, RESET, ROW, IN, OUT);
        
        input [7:0] S00;
        input [7:0] S01;
        input [7:0] S02;
           /* 中略 */
        input [7:0] S30;
        input [7:0] S31;
        
        output [7:0] D00;
        output [7:0] D01;
        output [7:0] D02;
           /* 中略 */
        output [7:0] D30;
        output [7:0] D31;
        
        reg [7:0] D00;
        reg [7:0] D01;
        reg [7:0] D02;
           /* 中略 */
        reg [7:0] D30;
        reg [7:0] D31;
        
        input CLK;
        input RESET;
        input [4:0] ROW;
        input IN;
        output OUT;
        
        reg OUT;
        
        always@(posedge CLK) begin
                D00 <= S31;
                D01 <= S30;
                D02 <= S29;
                D03 <= S28;
                D04 <= S27;
                D05 <= S26;
                D06 <= S25;
                D07 <= S24;
                D08 <= S23;
                D09 <= S22;
                D10 <= S21;
                D11 <= S20;
                D12 <= S19;
                D13 <= S18;
                D14 <= S17;
                D15 <= S16;
                D16 <= S15;
                D17 <= S14;
                D18 <= S13;
                D19 <= S12;
                D20 <= S11;
                D21 <= S10;
                D22 <= S09;
                D23 <= S08;
                D24 <= S07;
                D25 <= S06;
                D26 <= S05;
                D27 <= S04;
                D28 <= S03;
                D29 <= S02;
                D30 <= S01;
                D31 <= S00;
                
                OUT <= IN;
        end
endmodule
図9. 左右反転フィルタの Verilog 記述例

2. 図10 に一次空間微分フィルタ(横方向) の Verilog 記述例を示す。このフィルタの出力値は隣接する2ビットの差である。各画素の定義域は 0〜255 であることから、出力値の値域は -255 〜 255 となる。しかし、出力画像もまた256調画像とする必要があることから、出力値を (本来の出力値)÷2+127 としている。

この計算はモジュール TWO_COLUMN_DIFFERENTIAL 内で行っている。算術演算を行うため画素信号 S, SA を signed 付きの信号線 SIGNED_S, SIGNED_SA に変換している。また、画素値が 128〜255 のとき正数として計算させるため、SIGNED_S, SIGNED_SA は 9ビットバスとし、最上位ビット、すなわち符号ビットは 0 としている。なお除算演算子 / は ISE では使用できないと第3週目に説明したが、定数値 2 で割るなど、シフト演算子で容易に置き換えられるような演算の場合には使用できる。

module FILTER(
                S00, S01, S02, S03, S04, S05, S06, S07,
                S08, S09, S10, S11, S12, S13, S14, S15,
                S16, S17, S18, S19, S20, S21, S22, S23,
                S24, S25, S26, S27, S28, S29, S30, S31,
                D00, D01, D02, D03, D04, D05, D06, D07,
                D08, D09, D10, D11, D12, D13, D14, D15,
                D16, D17, D18, D19, D20, D21, D22, D23,
                D24, D25, D26, D27, D28, D29, D30, D31,
                CLK, RESET, ROW, IN, OUT);
        
        input [7:0] S00;
        input [7:0] S01;
        input [7:0] S02;
           /* 中略 */
        input [7:0] S30;
        input [7:0] S31;
        
        output [7:0] D00;
        output [7:0] D01;
        output [7:0] D02;
           /* 中略 */
        output [7:0] D30;
        output [7:0] D31;
        
        input CLK;
        input RESET;
        input [4:0] ROW;
        input IN;
        output OUT;
        
        reg OUT;
        
        TWO_COLUMN_DIFFERENTIAL U00 (.S(S00), .SA(S01), .D(D00), .CLK(CLK));
        TWO_COLUMN_DIFFERENTIAL U01 (.S(S01), .SA(S02), .D(D01), .CLK(CLK));
        TWO_COLUMN_DIFFERENTIAL U02 (.S(S02), .SA(S03), .D(D02), .CLK(CLK));
        TWO_COLUMN_DIFFERENTIAL U03 (.S(S03), .SA(S04), .D(D03), .CLK(CLK));
        TWO_COLUMN_DIFFERENTIAL U04 (.S(S04), .SA(S05), .D(D04), .CLK(CLK));
        TWO_COLUMN_DIFFERENTIAL U05 (.S(S05), .SA(S06), .D(D05), .CLK(CLK));
        TWO_COLUMN_DIFFERENTIAL U06 (.S(S06), .SA(S07), .D(D06), .CLK(CLK));
        TWO_COLUMN_DIFFERENTIAL U07 (.S(S07), .SA(S08), .D(D07), .CLK(CLK));
        TWO_COLUMN_DIFFERENTIAL U08 (.S(S08), .SA(S09), .D(D08), .CLK(CLK));
        TWO_COLUMN_DIFFERENTIAL U09 (.S(S09), .SA(S10), .D(D09), .CLK(CLK));
        TWO_COLUMN_DIFFERENTIAL U10 (.S(S10), .SA(S11), .D(D10), .CLK(CLK));
        TWO_COLUMN_DIFFERENTIAL U11 (.S(S11), .SA(S12), .D(D11), .CLK(CLK));
        TWO_COLUMN_DIFFERENTIAL U12 (.S(S12), .SA(S13), .D(D12), .CLK(CLK));
        TWO_COLUMN_DIFFERENTIAL U13 (.S(S13), .SA(S14), .D(D13), .CLK(CLK));
        TWO_COLUMN_DIFFERENTIAL U14 (.S(S14), .SA(S15), .D(D14), .CLK(CLK));
        TWO_COLUMN_DIFFERENTIAL U15 (.S(S15), .SA(S16), .D(D15), .CLK(CLK));
        TWO_COLUMN_DIFFERENTIAL U16 (.S(S16), .SA(S17), .D(D16), .CLK(CLK));
        TWO_COLUMN_DIFFERENTIAL U17 (.S(S17), .SA(S18), .D(D17), .CLK(CLK));
        TWO_COLUMN_DIFFERENTIAL U18 (.S(S18), .SA(S19), .D(D18), .CLK(CLK));
        TWO_COLUMN_DIFFERENTIAL U19 (.S(S19), .SA(S20), .D(D19), .CLK(CLK));
        TWO_COLUMN_DIFFERENTIAL U20 (.S(S20), .SA(S21), .D(D20), .CLK(CLK));
        TWO_COLUMN_DIFFERENTIAL U21 (.S(S21), .SA(S22), .D(D21), .CLK(CLK));
        TWO_COLUMN_DIFFERENTIAL U22 (.S(S22), .SA(S23), .D(D22), .CLK(CLK));
        TWO_COLUMN_DIFFERENTIAL U23 (.S(S23), .SA(S24), .D(D23), .CLK(CLK));
        TWO_COLUMN_DIFFERENTIAL U24 (.S(S24), .SA(S25), .D(D24), .CLK(CLK));
        TWO_COLUMN_DIFFERENTIAL U25 (.S(S25), .SA(S26), .D(D25), .CLK(CLK));
        TWO_COLUMN_DIFFERENTIAL U26 (.S(S26), .SA(S27), .D(D26), .CLK(CLK));
        TWO_COLUMN_DIFFERENTIAL U27 (.S(S27), .SA(S28), .D(D27), .CLK(CLK));
        TWO_COLUMN_DIFFERENTIAL U28 (.S(S28), .SA(S29), .D(D28), .CLK(CLK));
        TWO_COLUMN_DIFFERENTIAL U29 (.S(S29), .SA(S30), .D(D29), .CLK(CLK));
        TWO_COLUMN_DIFFERENTIAL U30 (.S(S30), .SA(S31), .D(D30), .CLK(CLK));
        assign D31 = 127;
            /* S32 なる画素はないので、右端 D31 の出力値は
                とりあえず 127 にする。大した意味はない。 */
        
        always @(posedge CLK) begin
                OUT <= IN;
        end
endmodule

module TWO_COLUMN_DIFFERENTIAL(S, SA, D, CLK);
        input [7:0] S;
        input [7:0] SA;
        output [7:0] D;
        input CLK;
        
        reg [7:0] D;
        
        wire signed [8:0] SIGNED_S;    // signed 付き信号へ変換
        wire signed [8:0] SIGNED_SA;
        
        assign SIGNED_S = {1'b0, S};    // 最上位に符号ビットを付加
        assign SIGNED_SA = {1'b0, SA};
        
        always@(posedge CLK) begin
                D <= (SIGNED_SA - SIGNED_S) / 2 + 127;
        end
endmodule
図10. 一次空間微分フィルタ(横方向) の Verilog 記述例

3. 今までのフィルタでは各行のデータをそれぞれ独立に処理していた。そのため、各行毎、入力されたデータについて、処理結果を即時出力することができた。しかし、縦方向の一次空間微分フィルタにおいては、ある行の画素と、隣接する行の画素との差をとる必要があり、行毎の演算が独立していない。そのため、過去に入力された演算に必要な行データをフィルタ内に記憶しておく必要がある。

図11 に一次空間微分フィルタ(縦方向) の Verilog 記述例を示す。このフィルタは制御用レジスタ IR を用いながら、以下の通り動作する。

  1. 最初、IN = 0, IR = 00 である。
  2. IN = 1 となり、1行目が入力されたとき、IR = 01 となり、1行目の画像データはモジュール ONE_COLUMN_DIFFERENTIAL 内のレジスタ R に記憶される。ここで OUT=0 となり、フィルタはデータ出力しない。
  3. 2行目が入力されたとき、IR = 11 となる。2行目と1行目の差を計算し、1行目の出力データとして出力する。
  4. 以降、同様の処理を32行目のデータが入力され、31行目のデータが出力されるまで繰り返す。
  5. 32行全てのデータが入力し終わったことから、以後 IN = 0 となる。フィルタは 32行目のデータとして 127 を出力する。このとき、IR = 10 とし、OUT = 1 とする。
  6. 32行全てのデータを出力し終えたことで、シミュレーションは終了する。
module FILTER(
                S00, S01, S02, S03, S04, S05, S06, S07,
                S08, S09, S10, S11, S12, S13, S14, S15,
                S16, S17, S18, S19, S20, S21, S22, S23,
                S24, S25, S26, S27, S28, S29, S30, S31,
                D00, D01, D02, D03, D04, D05, D06, D07,
                D08, D09, D10, D11, D12, D13, D14, D15,
                D16, D17, D18, D19, D20, D21, D22, D23,
                D24, D25, D26, D27, D28, D29, D30, D31,
                CLK, RESET, ROW, IN, OUT);
        
        input [7:0] S00;
        input [7:0] S01;
        input [7:0] S02;
           /* 中略 */
        input [7:0] S30;
        input [7:0] S31;
        
        output [7:0] D00;
        output [7:0] D01;
        output [7:0] D02;
           /* 中略 */
        output [7:0] D30;
        output [7:0] D31;
        
        input CLK;
        input RESET;
        input [4:0] ROW;
        input IN;
        output OUT;
        
        reg [1:0] IR;
        
        ONE_COLUMN_DIFFERENTIAL U00 (.S(S00), .D(D00), .IN(IN), .CLK(CLK));
        ONE_COLUMN_DIFFERENTIAL U01 (.S(S01), .D(D01), .IN(IN), .CLK(CLK));
        ONE_COLUMN_DIFFERENTIAL U02 (.S(S02), .D(D02), .IN(IN), .CLK(CLK));
        ONE_COLUMN_DIFFERENTIAL U03 (.S(S03), .D(D03), .IN(IN), .CLK(CLK));
        ONE_COLUMN_DIFFERENTIAL U04 (.S(S04), .D(D04), .IN(IN), .CLK(CLK));
        ONE_COLUMN_DIFFERENTIAL U05 (.S(S05), .D(D05), .IN(IN), .CLK(CLK));
        ONE_COLUMN_DIFFERENTIAL U06 (.S(S06), .D(D06), .IN(IN), .CLK(CLK));
        ONE_COLUMN_DIFFERENTIAL U07 (.S(S07), .D(D07), .IN(IN), .CLK(CLK));
        ONE_COLUMN_DIFFERENTIAL U08 (.S(S08), .D(D08), .IN(IN), .CLK(CLK));
        ONE_COLUMN_DIFFERENTIAL U09 (.S(S09), .D(D09), .IN(IN), .CLK(CLK));
        ONE_COLUMN_DIFFERENTIAL U10 (.S(S10), .D(D10), .IN(IN), .CLK(CLK));
        ONE_COLUMN_DIFFERENTIAL U11 (.S(S11), .D(D11), .IN(IN), .CLK(CLK));
        ONE_COLUMN_DIFFERENTIAL U12 (.S(S12), .D(D12), .IN(IN), .CLK(CLK));
        ONE_COLUMN_DIFFERENTIAL U13 (.S(S13), .D(D13), .IN(IN), .CLK(CLK));
        ONE_COLUMN_DIFFERENTIAL U14 (.S(S14), .D(D14), .IN(IN), .CLK(CLK));
        ONE_COLUMN_DIFFERENTIAL U15 (.S(S15), .D(D15), .IN(IN), .CLK(CLK));
        ONE_COLUMN_DIFFERENTIAL U16 (.S(S16), .D(D16), .IN(IN), .CLK(CLK));
        ONE_COLUMN_DIFFERENTIAL U17 (.S(S17), .D(D17), .IN(IN), .CLK(CLK));
        ONE_COLUMN_DIFFERENTIAL U18 (.S(S18), .D(D18), .IN(IN), .CLK(CLK));
        ONE_COLUMN_DIFFERENTIAL U19 (.S(S19), .D(D19), .IN(IN), .CLK(CLK));
        ONE_COLUMN_DIFFERENTIAL U20 (.S(S20), .D(D20), .IN(IN), .CLK(CLK));
        ONE_COLUMN_DIFFERENTIAL U21 (.S(S21), .D(D21), .IN(IN), .CLK(CLK));
        ONE_COLUMN_DIFFERENTIAL U22 (.S(S22), .D(D22), .IN(IN), .CLK(CLK));
        ONE_COLUMN_DIFFERENTIAL U23 (.S(S23), .D(D23), .IN(IN), .CLK(CLK));
        ONE_COLUMN_DIFFERENTIAL U24 (.S(S24), .D(D24), .IN(IN), .CLK(CLK));
        ONE_COLUMN_DIFFERENTIAL U25 (.S(S25), .D(D25), .IN(IN), .CLK(CLK));
        ONE_COLUMN_DIFFERENTIAL U26 (.S(S26), .D(D26), .IN(IN), .CLK(CLK));
        ONE_COLUMN_DIFFERENTIAL U27 (.S(S27), .D(D27), .IN(IN), .CLK(CLK));
        ONE_COLUMN_DIFFERENTIAL U28 (.S(S28), .D(D28), .IN(IN), .CLK(CLK));
        ONE_COLUMN_DIFFERENTIAL U29 (.S(S29), .D(D29), .IN(IN), .CLK(CLK));
        ONE_COLUMN_DIFFERENTIAL U30 (.S(S30), .D(D30), .IN(IN), .CLK(CLK));
        ONE_COLUMN_DIFFERENTIAL U31 (.S(S31), .D(D31), .IN(IN), .CLK(CLK));

        always@(posedge CLK) begin
                    // 状態レジスタ IR による状態遷移器
                if(RESET) begin
                        IR <= 2'b00;
                end else begin
                        if(IN) begin
                                IR <= (IR == 2'b00) ? 2'b01 : 2'b11;
                        end else begin
                                IR <= (IR == 2'b11) ? 2'b10 : 2'b00;
                        end
                end
        end
        
        assign OUT = IR[1];    // IR = 10 または 11 のとき、データ出力
endmodule

module ONE_COLUMN_DIFFERENTIAL(S, IN, D, CLK);
        input [7:0] S;
        input IN;
        output [7:0] D;
        input CLK;
        
        reg [7:0] R;
        reg [7:0] D;
        
        wire signed [8:0] SIGNED_R;
        wire signed [8:0] SIGNED_S;
        
        assign SIGNED_R = {1'b0, R};
        assign SIGNED_S = {1'b0, S};
        
        always@(posedge CLK) begin
                D <= IN ? (SIGNED_R - SIGNED_S) / 2 + 127 : 127;
                R <= S;
                    // 入力された画素データを次行処理時に用いるため、 R に記憶
        end
endmodule
図11. 一次空間微分フィルタ(縦方向) の Verilog 記述例

第3週目の回路作成例・解説に戻る
実験II-1トップページに戻る
難波担当実験・演習のページに戻る

難波 一輝 (助教・伊藤・北神・難波研究室)
工学部1号棟4階409号室、内線3255、043-290-3255、namba@ieee.org