SSブログ

続・PSoC 3 で、倍増器を作った [PSoC]このエントリーを含むはてなブックマーク#

10倍増器

前回は、 FIFO を応用して入ってきたデータを2倍にして返す倍増器を作りました。 今回も倍増器を作ります。 ただし、倍率が前回とは違っています。

今度は、10倍

10倍増データフロー

今回は、10倍に挑戦します。

値を10倍にする仕組みをデータフローで表現しています。 足し算とシフトを駆使して、 D0 に入った値 "d" を10倍にしています。 10倍の値を得るために必要なクロック数は、5クロックに伸びました。 それぞれのステップで ALU の振る舞いを変化させて、計算を行っています。


ここでは、演算部分だけを解説します。

  • STEP1

    このステップでは、前回と同様、 "SL1" 操作を行います。 A0 には、 FIFO0 から取り出した値 "d" の二倍の値 "2d" が入ります。

  • STEP2

    このステップでは、新たに定義した "SL0" 操作を行います。 "SL1" とは違い、シフターを通す前に "D0" を加算しません。 そのため、A0 には、値 "d" の4倍の値 "4d" が入ります。

  • STEP3

    このステップでは、ふたたび、 "SL1" 操作を行います。 A0 に "d" を足してからシフターを通すので、A0 には、値 "d" の10倍の値 "10d" が入ります。 これで、元の値の10倍の値を得る事ができました。

以上の3ステップで、 D0 の値は10倍されます。 "SL1" と "SL0" の適用順序を変えると、違う倍率の倍増器を構成することも出来ます。

Verilog の実装のコンセプトは、前回とほぼ同じです。 ここでは省略しますが、興味があれば、プロジェクトを開いて確認してください。

データパスの実装

10倍増器のデータパス設定

データパスの設定は、 "SL1" が追加されました。 また、後の戦略の都合上、 "SL0" を Reg4 に、 "SL1" を Reg5 に割り当てています。 "SL1" と "SL0" の違いは、 ALU の演算設定だけで、 ADD の部分が PASS になっています。

10倍増器の動作

10倍増器の使い方は、前回の倍増器と同じです。 そのため、テストプログラムも同じものが使えます。 ただし、倍増器のインスタンス名が変わっていますので、レジスタアクセスに使用する名前を変更する必要があります。

/* ========================================
 *
 * Copyright noritan.org, 2013
 * All Rights Reserved
 * UNPUBLISHED, LICENSED SOFTWARE.
 *
 * CONFIDENTIAL AND PROPRIETARY INFORMATION
 * WHICH IS THE PROPERTY OF NORITAN.ORG.
 *
 * ========================================
*/
#include <device.h>

void main()
{
    uint8           i = 0;
    uint8           v[16];
    volatile uint8  w = 0;
    
    CR1_Write(1);
    CY_SET_REG8(Times10_dp_u0__F0_REG, w++);
    for (i = 0; i < 16; i++) {
        CY_SET_REG8(Times10_dp_u0__F0_REG, w++);
        v[ i] = CY_GET_REG8(Times10_dp_u0__F1_REG);
    }

    LCD_Start();
    LCD_Position(0, 0);
    for (i = 0; i < 8; i++) {
        LCD_PrintInt8(v[i]);
    }
    LCD_Position(1, 0);
    for (i = 8; i < 16; i++) {
        LCD_PrintInt8(v[i]);
    }

    CY_SET_REG8(Times10_dp_u0__F0_REG, i++);
    CY_SET_REG8(Times10_dp_u0__F0_REG, i++);

    /* CyGlobalIntEnable; */ /* Uncomment this line to enable global interrupts. */
    for(;;)
    {
        CY_SET_REG8(Times10_dp_u0__F0_REG, i++);
        w = CY_GET_REG8(Times10_dp_u0__F1_REG);
    }
}

/* [] END OF FILE */

奇数倍の場合

WS000536.png

データパスの設定 "SL0" と "SL1" を使う事によってすべての倍率に対応できるようになったかかというと、そうはいきません。 "SL0" も "SL1" も、最後にシフターを通しているので、偶数倍の値しか出てきません。

5倍増器のデータフロー

5倍増器のデータフロー

では、どうするかというと、最後の1ステップのために、シフターを通さない操作を追加します。 このデータフロー図は、5倍増器の場合です。 10倍増器の STEP3 の演算で、 "SL1" の代わりに "ADD1" が使用されています。 "ADD1" は、 A0 と D0 を加算して、シフターを通さずにそのまま A0 に格納する操作です。 この操作を使う事で、奇数倍の場合にも対応することができます。

5倍増器対応のデータパス設定

5倍増器対応データパスの設定

データパスは、奇数倍に対応させるために、さらに操作を追加しています。 上の5倍増器のデータフローでは、 "ADD1" のみが必要になっていましたが、ここでは、後のことを考えて、 "ADD0" という操作も追加しています。 この操作は、 D0 の加算も行わず、シフターも通さないで、 A0 を単に書き直すという操作になっています。

さあ、これで任意の値に対応する役者が揃いました。

プロジェクトアーカイブ

この記事を書くために作成したプロジェクトは、このファイルの拡張子を ZIP に変更して展開すると再現できます。

関連文献


nice!(0)  コメント(0)  トラックバック(0)  このエントリーを含むはてなブックマーク#

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 0

トラックバックの受付は締め切りました

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。