Lynx-EyEDの電音鍵盤 新館

広帯域制御屋の駄文とか

PSoCでVerilog

画像を利用した姿勢制御計画がちょっと部品選定で頓挫中です。
MachXO2 → PLD付きCPUのPSoC3でも出来そうということで、部品選定フェーズに巻き戻ししてます。あーあ。

【メリット】
・CPUによってPLDのステートマシーンをなくす、または最小限に出来る。あるいは低速バス調停をすべてCPU任せにできる
・USBFS回路を持っているのでCDC経由のprintfデバッグやHIDデバイスを簡単に作れる
・一部のロジックがメモリ空間にマッピングされているため、論理回路の演算結果をCPUが読み出す事が出来る
・要求が満たせば、アナログ回路を外付けする必要が無い(内蔵アナログ機能で間に合うかも)

【デメリット】
・PSoC3/5以外への移植はほぼ不可能
・どう転んでも192マクロセルしかない


PLDでジョンソンカウンタを作り、CPU側から値を読み出し、キャラクタLCDに読み出します。
使用するボードはCY8CKIT-030 Development Kitです。

□参考リンク
PSoC Creator 113: PLD Based Verilog Components - Cypress Semiconductor
ダウンロードして閲覧できるムービを見ると大体Verilogをどこに記述すれば良いか分かると思います。

■ジョンソンカウンタ
ジョンソンカウンタは、ハミング距離が1*1です。
例えば3bitジョンソンカウンタならば、出力は2進数で

000
001
011
111
110
100
000

となります。
状態遷移時のスタティックハザードに対して堅牢なため、FPGAでは異なるクロック領域からのデータ入出力時によく用いられます。OpenCoresで見つかるSPI/I2Cスレーブコアでもグレイコードやジョンソンカウンタがしばしば用いられています。

PSoC Creatorでロジックブロックを作る
いつも通りWorkspaceを作ります(今回はDesign01というデフォルト名に)。 Workspace Explorer上のProject 'Design01'…で右クリック→ Add Component Item… を選択。
f:id:Lynx-EyED:20120917130006p:plain

Templates: Symbol Wizardを選択
Component name: JohnsonCounterと入力
Create Newをクリック
f:id:Lynx-EyED:20120917130025p:plain

Symbol Creation Wizardでは
Clock → Digital → INPUT
PreReset → Digital → INPUT
Q[2:0] → Digital → OUTPUT
でOK
f:id:Lynx-EyED:20120917130034p:plain

ブロックが出来たら、JohnsonCounter.cysymをクリックして表示させる。ここで右クリックし、Generate Verilogを選択
f:id:Lynx-EyED:20120917130111p:plain

VerilogHDLファイルが自動生成されるので、ジョンソンカウンタの動作をさせるロジックを追記します。こんな感じ。

//`#start header` -- edit after this line, do not edit this line
// ========================================
//
// Copyright YOUR COMPANY, THE YEAR
// All Rights Reserved
// UNPUBLISHED, LICENSED SOFTWARE.
//
// CONFIDENTIAL AND PROPRIETARY INFORMATION
// WHICH IS THE PROPERTY OF your company.
//
// ========================================
`include "cypress.v"
//`#end` -- edit above this line, do not edit this line
// Generated on 09/15/2012 at 15:59
// Component: JohnsonCounter
module JohnsonCounter (
	Q,
	Clock,
	PreReset
);
	output [2:0] Q;
	input   Clock;
	input   PreReset;
//`#start body` -- edit after this line, do not edit this line

reg [2:0] Q ;

always @ (negedge PreReset or negedge Clock)
    if(! PreReset)
        Q <= 3'b1;
    else 
    begin
        Q <= { Q[1:0], ~Q[2] } ;      
    end

//`#end` -- edit above this line, do not edit this line
endmodule
//`#start footer` -- edit after this line, do not edit this line
//`#end` -- edit above this line, do not edit this line

ここで、Save Allしておく。
TopDesign.cyschにJohnsonCounterと1Hzのクロック、Digital Input、Character LCDなどを追加する。
f:id:Lynx-EyED:20120917130128p:plain

CPUから出力Q[2:0]を見たいのでStatusRegを追加する。このときStatusRegの入力をDataBusとして表示させるのがコツみたいです。
※のりたんさんに教えていただきました。ありがとうございます。
忘れずにLCDとリセット(上図のPin_2)入出力ピンの割当てをします。

■CPUのプログラミング
main.cをさくっと書きます。1sごとにジョンソンカウンタが変化しますので、それを200ms周期でポーリンクして、LCDに出力するだけの簡単なお仕事です。

/* ========================================
 *
 * Copyright YOUR COMPANY, THE YEAR
 * All Rights Reserved
 * UNPUBLISHED, LICENSED SOFTWARE.
 *
 * CONFIDENTIAL AND PROPRIETARY INFORMATION
 * WHICH IS THE PROPERTY OF your company.
 *
 * ========================================
*/
#include <device.h> 
#include <stdio.h>
void main()
{
    uint8   status = 0u;
    char    strings[10];
 
    CyGlobalIntEnable;
    
    LCD_Char_1_Start();


    for(;;)
    {
        status = Status_Reg_1_Read(); // StatusRegからデータ読み込み
        
        sprintf(strings, "%#x", status);
        LCD_Char_1_Position(0u, 0u);
        LCD_Char_1_PrintString(strings); // LCDに表示
        
        CyDelay(200);   //200ms待つ
    }
}

/* [] END OF FILE */

ちなみに合成結果をみてみると、

------------------------------------------------------------
Technology mapping summary
------------------------------------------------------------

Resource Type                 : Used : Free :  Max :  % Used
============================================================
Digital domain clock dividers :    1 :    7 :    8 :  12.50%
Analog domain clock dividers  :    0 :    4 :    4 :   0.00%
Pins                          :   11 :   61 :   72 :  15.28%
Macrocells                    :    3 :  189 :  192 :   1.56%
Unique Pterms                 :    3 :  381 :  384 :   0.78%
Total Pterms                  :    3 :      :      : 
Datapath Cells                :    0 :   24 :   24 :   0.00%
Status Cells                  :    1 :   23 :   24 :   4.17%
             Status Registers :    1 
Control Cells                 :    0 :   24 :   24 :   0.00%
DMA Channels                  :    0 :   24 :   24 :   0.00%
Interrupts                    :    0 :   32 :   32 :   0.00%
DSM Fixed Blocks              :    0 :    1 :    1 :   0.00%
VIDAC Fixed Blocks            :    0 :    4 :    4 :   0.00%
SC Fixed Blocks               :    0 :    4 :    4 :   0.00%
Comparator Fixed Blocks       :    0 :    4 :    4 :   0.00%
Opamp Fixed Blocks            :    0 :    4 :    4 :   0.00%
CapSense Buffers              :    0 :    2 :    2 :   0.00%
CAN Fixed Blocks              :    0 :    1 :    1 :   0.00%
Decimator Fixed Blocks        :    0 :    1 :    1 :   0.00%
I2C Fixed Blocks              :    0 :    1 :    1 :   0.00%
Timer Fixed Blocks            :    0 :    4 :    4 :   0.00%
DFB Fixed Blocks              :    0 :    1 :    1 :   0.00%
USB Fixed Blocks              :    0 :    1 :    1 :   0.00%
LCD Fixed Blocks              :    0 :    1 :    1 :   0.00%
EMIF Fixed Blocks             :    0 :    1 :    1 :   0.00%
LPF Fixed Blocks              :    0 :    2 :    2 :   0.00%

マクロセル3個使ってる。。。
ビルドして書き込みます。

LCDには16進表記で

0x100
0x300
0x700
0x600
0x400
0x000

と出力されるはずです

f:id:Lynx-EyED:20120917130537j:plain

*1:1度の変化で1ビットしか変化しない