7月27日(金)
3月21(日)
一年ぶりの更新。一年間、何もしていなかったわけではないが、なんの進歩もなかったというだけのこと。ハーフサイズのマウスは、いまいちやる気がでない、私の目的や理念と異なってしまったので、静かに消えてゆくつもりだ。
ただ、せめて一台は試作して迷路の上を走らせてから消えないと、未練が残る。で、マウス以後のことを考えたが、DCモータの制御ができるようになりたい、できれば、センサレスで、ブラシレスモータを廻してみたい。そこで、PLDを使えるようになりたいのだ。
一年前のソースを読み直し、書き直して、昨夜、やっとのことで、シンタックスエラーは出なくなったが、
WARNING:Xst - Property "use_dsp48" is not applicable for this technology. という、警告がでる。ようするに、このCPLDでは、DSP48という技術を使えないということだろう、多分。
で、『DSP48』って、なんなのさ ???。
やっと、問題が一つ解決した。コンポーネントの名前と信号の名前を同じにすると、コンパイラが混乱してエラーになるということが、骨身に沁みて理解できた。
このことに気が付くまで一週間という時間を費やしてしまったが、どうにか、階層設計の入り口の門に手をかけることができた。-- 右motor 回転方向 設定(make right_motor_direction) library ieee ; use ieee.std_logic_1164.all ; use ieee.std_logic_arith.all ; use ieee.std_logic_unsigned.all ; entity make_right_direction is port ( CLOCK : in std_logic ; right_motor_direction : in std_logic ; -- right_motor_direction is '1' then cw wize right_PWM : in std_logic ; right_motor_direction_flag : out std_logic_vector (1 downto 0) ) ; end make_right_direction ; architecture RTL of make_right_direction is -- right_motor_direction set component right_dead_time is -- 右motor PWM 信号 デッドタイム 作成 port ( CLOCK : in std_logic ; right_PWM : in std_logic ; right_dead_time_flag : out std_logic ) ; end component ; signal right_dead_time_flagA : std_logic ; signal temp_right_directionF : std_logic_vector (1 downto 0) ; begin RightDead : right_dead_time port map ( CLOCK => CLOCK , right_PWM => right_PWM , right_dead_time_flag => right_dead_time_flagA ) ; process(CLOCK,right_PWM,right_motor_direction) begin if (CLOCK 'event and CLOCK = '1') then -- if (CLOCK's rising edge is detected) then if (right_dead_time_flagA = '1') then temp_right_directionF <= "11" ; -- all FET cut off elsif (right_PWM = '1') then if (right_motor_direction = '1') then temp_right_directionF <= "10" ; -- right_motor_direction is '1' then cw wize else temp_right_directionF <= "01" ; -- right_motor_direction is '0' then ccw wize end if ; elsif (right_PWM = '0') then temp_right_directionF <= "00" ; -- brak mode else temp_right_directionF <= "00" ; end if ; end if ; end process ; right_motor_direction_flag <= temp_right_directionF ; end RTL ; -- 右motor 駆動信号出力 library ieee ; use ieee.std_logic_1164.all ; use ieee.std_logic_arith.all ; use ieee.std_logic_unsigned.all ; -- use ieee.std_logic_signed.all ; entity right_motor_contact is port( CLOCK : in std_logic ; POWER : in std_logic ; right_motor_direction : in std_logic ; -- right_motor_direction is '1' then cw wize right_PWM : in std_logic ; right_motor_signal : out std_logic_vector (3 downto 0) ) ; end right_motor_contact ; architecture RTL of right_motor_contact is component make_right_direction is port ( CLOCK : in std_logic ; right_motor_direction : in std_logic ; -- right_motor_direction is '1' then cw wize right_PWM : in std_logic ; right_motor_direction_flag : out std_logic_vector (1 downto 0) ) ; end component ; signal right_motor_direction_flagA : std_logic_vector (1 downto 0) ; signal right_motor_signalA : std_logic_vector (3 downto 0) ; begin RightDirec : make_right_direction port map ( CLOCK => CLOCK , right_motor_direction => right_motor_direction , right_PWM => right_PWM , right_motor_direction_flag => right_motor_direction_flagA ) ; process(POWER, CLOCK,right_motor_direction_flagA) -- Right motor PWM signal out begin if ( (POWER = '0') or (right_motor_direction_flagA = "11" ) ) then -- all FET cut off right_motor_signalA(0) <= '1' ; right_motor_signalA(1) <= '1' ; right_motor_signalA(2) <= '0' ; right_motor_signalA(3) <= '0' ; elsif (CLOCK 'event and CLOCK = '1') then if ( right_motor_direction_flagA = "10" ) then -- Right_pwm is 'H' then CW wise right_motor_signalA(0) <= '0' ; right_motor_signalA(1) <= '1' ; right_motor_signalA(2) <= '0' ; right_motor_signalA(3) <= '1' ; elsif ( right_motor_direction_flagA = "01" ) then -- Right_pwm is 'L' then CCW wise right_motor_signalA(0) <= '1' ; right_motor_signalA(1) <= '0' ; right_motor_signalA(2) <= '1' ; right_motor_signalA(3) <= '0' ; elsif ( right_motor_direction_flagA = "00" ) then -- brak mode right_motor_signalA(0) <= '0' ; right_motor_signalA(1) <= '0' ; right_motor_signalA(2) <= '1' ; right_motor_signalA(3) <= '1' ; else null ; end if ; else null ; end if ; end process ; right_motor_signal <= right_motor_signalA ; end RTL ;entity の名前を、以前は、変数???と呼んで良いのかな、と同じ名前の right_motor_direction にしていた。これで、コンパイラ???が混乱していたらしい。entity を、 make_right_direction に変更してエラーが消えた。
駆動信号の出力部分は、std_logic_vector型の変数???を使えば、もう少し格好良くなるのだが、後でゆっくり直す予定。他人のためのソースでは無いが、他人が読んでも理解しやすいように書いておけば、後で、自分が読んでも理解できる。
美しく理解し難いプログラムよりも、汚くて冗長だが理解しやすいプログラムを、あたしゃ書くのだ。
で、残るのは、WARNING:Xst - Property "use_dsp48" is not applicable for this technology. という、警告だけだ。
ま、もう少し考えよう、そのまえに、テストベンチの作り方とシミュレーションを勉強しないとね。
DCモータの制御にはPLDが使えれば助かるわなぁ。もう少し頑張ってみるかぃ。
8月17日(日)
参考書と同じバージョンのISE を使うということは、理解の速度が非常に上がる。いちいちアイコンを探すという、およそ創造性の片鱗も無い作業に時間を費やさなくとも良いので、ストレスが溜まらない。
おまけに、時間の節約になり、眼と脳細胞の疲労は確実に減少する。シミュレーションのための波形作成まで進んだ。とりあえず、ここいらへんで、本日の作業は終わりにする。
急ぎすぎて、最初の方を忘れてしまっては、意味が無い。
センシビリティリストには、クロックなどの信号の変化で変化する信号は全て書かなければならないようだ。警告は完全に消えた、なんか気分が良い、ピンアサインの画面がでたが、ここまでで終わり。
パーツの配置によって、ピンアサインは変わる、いまやるべきことでは無い。
8月16日(土)
ザイリンクスのホームページに行って、最新版のISEウエブパックをダウンロードしてきた。ところが、インストールするのに時間が懸かる。やっとインストールして動かしたが、いままでのものと画面が全く異なる。
っていうことで、全く同じ反省、『参った!、もう少し英語を勉強しとくんだった。』の言葉とともに沈没、というか撃墜されたというか、撃沈された。せめて日本語のマニュアルは無いのか。
在った、在ったけど、こいつもバージョンが異なる、涙、涙、涙・・・・・
手も足もでないので、最新版のISEウエブパックを削除することにした。インストールするのにも時間が懸かったが、アンインストールも凄く時間が懸かる。なんか重たそうなソフトだわね。
っていうことで、沈没、というか撃墜されたというか、撃沈されたというか、撃破された。
かなり苦労したが、参考書と同じバージョンのISE WebPACKとModelSimXEをダウンロードしてインストールすることに成功した。なんのことは無い、参考書のサポートページというのが、web上にあった。
そこに、旧バージョンのISE WebPACKとModelSimXEをダウンロードできる、ザイリンクス社のURLが掲載されていたのだ。まさか、サポートページが在るなどとは、思ってもいなかった。
著者に、心より感謝いたします。
若干の問題が残った、今まで造ったプロジェクトを読み込んでくれない。それと、ソースの拡張子が全く異なる、バージョン9.1iで書いたプロジェクトを6.3iのISEが読めると思う方に無理がある。
9.1iのソースはフォルダに退避させた。まずは、参考書を真似して、シミュレーションの方法を覚えることが先だ。
ちょっと動かしてみた。警告が一ヵ所にでている。センシビリティリストには、アーキテクチャーとビギンの間で宣言した変数???も書かなきゃなんないのかなぁ、疑問だ。
8月 1日(水)
8月15日(金)
一年ぶりの更新。一年間、何もしていなかったわけではないが、なんの進歩もなかったというだけのこと。Cで書いたマウスのソースすらまともに動かない、ましてや、PLDなんざ、一発で動いたら奇跡ってもんだ。
せめてコンピュータの上で、シミュレーションをし、動くのを確認してから、書き込み器の製作や書き込み、LEDの点灯試験などに進みたいという計画だった。
だが、シミュレーションの方法が全く理解できない。ISEのバージョンが参考書と異なるため、手も足もでなかった。ザイリンクスのホームページに行って、参考書と同じバージョンのISEをダウンロードしてきた。
ところが、インストールできない。自動解凍のファイルなので、クリックすると動き出す。ところが、フォルダがなんたらかんたら、英語なので意味不明、とクレームがでて、インストールが中止になる。
現在のところ、打つ手無し、お手上げというところ。
原因が判った。私は、サービスパックと、ISE WebPACKを同じものだと勘違いしていたようだ。サービスパックと、ISE WebPACKは、全く違うソフトだった。
サービスパックは、追加のソフトみたいだ。従って、ISE WebPACKをインストールしてからでないと、サービスパックはインストールできないみたいだ、断定はしないが。
英語をもう少し勉強しておくんだった。
あいもかわらず警告がわんさかでるが、無視して先に進むことにした。『ラッチが有ります』などという警告まで出されたんじゃ、チェックする元気が無くなってしまう。
とりあえず、そこそこにソースはできた、シミュレーションの準備に入る。
90日間のアクセス権が、消費税を含めて、¥1、890円と廉価だったので、インターネットでVHDLの講習をするという、サイバーラボの講習を申し込んだ。
まず、アクセスのパスワードが届かない。『パスワードの発行まで、ニ三日懸かります。一週間待って届かなければ連絡を下さい。』と書かれていたので、ニ三日待ったが届かない。一週間待って、連絡した。
パスワードが届いてからも、なかなか大変だった。ネット詐欺にしては金額が少なすぎるので余計な心配はしなかったが、アクセスできない。アクセスできても途中で接続が切れる。一度接続が切れると、ホームページにすら接続できなくなってしまう。
流石に少し怒りを覚えた、今日一日待って、環境が改善されなければ、詐欺じゃないだろうか、と日記に書こうかと思っていた。7月23日に送金してから、まともにアクセスできるようになるまで、一週間以上かかった。
やっと、本日、フルアクセスできるようになった、疲れた。
この講習で、VHDLが理解できるようになるのだろうか、・・・・・・・
Design encoder has been optimized and fit into device XC95108-15-PC84. Started : "Generate HTML report". Release 9.1i - CPLD HTML Report Processor J.30 Copyright (c) 1995-2007 Xilinx, Inc. All rights reserved. Process "Generate HTML report" completed successfully Started : "Generate Post-Fit Timing Data". Creating NGA for simulation. Speed File: Version 3.0 Process "Generate Post-Fit Timing Data" completed successfully Process "Fit" completed successfully Started : "Generate Timing". Release 9.1i - Timing Report Generator J.30 Copyright (c) 1995-2007 Xilinx, Inc. All rights reserved. Note: This design contains no timing constraints. Note: A default set of constraints using a delay of 0.000ns will be used for analysis. Path tracing ...... The number of paths traced: 265. . The number of paths traced: 531. Checking for asynchronous logic... No asynchronous logic found. Generating TA GUI report ... Generating detailed paths report ... C:/XilinxWorkSpace/encoder/encoder/encoder_html/tim/timing_report.htm has been created. Process "Generate Timing" completed successfully Started : "Generate Programming File". Release 9.1i - Programming File Generator J.30 Copyright (c) 1995-2007 Xilinx, Inc. All rights reserved. Process "Generate Programming File" completed successfully
Process "Generate Programming File" completed successfully というメッセージがでるということはだぜ、意図したとうりに動くか否かは別にして、これでデバグは完了ということなのだろうか ???
したらば、山のようにでる警告は無視しても良いのだろうか、疑問じゃ。
7月26日(木)
やっと、VHDLで書いているCPLDのソースのエラーが無くなったが、警告がわんさかでる。あいも変わらず、脳細胞が熱くなる夜が続いている、ストレスで心臓麻痺でも起こすんじゃないだろな。
オシムがPK戦を観ない気持ちが、なんとなく判かる、しかし、負けちゃった。library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity speed is port ( SubClock : in std_logic; -- システムクロックを分周したクロック RESET : in std_logic; ReadWrite : in std_logic; CS,A13,A2,A1,A0 : in std_logic; encodLeftA : in std_logic; -- A相入力線 outLeftCounter : out std_logic_vector(7 downto 0) -- 8 bit 出力ポート ); end speed; architecture RTL of speed is -- 内部信号の定義 (define internal signal) signal encLeftA_new: std_logic; -- A相1段目バッファ signal encLeftA_old: std_logic; -- A相2段目バッファ signal LeftSpeed: std_logic_vector(15 downto 0); -- 16 bit counter signal reserveLeftSpeed: std_logic_vector(15 downto 0); -- 1回前のdataの退避エリア begin process ( SubClock, RESET, ReadWrite, CS,A13,A2,A1,A0, encodLeftA, outLeftCounter, encLeftA_new, encLeftA_old, LeftSpeed, reserveLeftSpeed ) begin -- 無条件 data 読み込み encLeftA_new <= encodLeftA; -- A相入力を1段目バッファにコピー encLeftA_old <= encLeftA_new; -- 1段目バッファ(O回の値)bQi目バッファにコピー if ( RESET = '0' ) then -- リセット信号が low なら outLeftCounter(7 downto 0) <= (others => '0'); -- 出力 poat クリア LeftSpeed(15 downto 0) <= (others => '0'); -- 現在の走行速度 クリア reserveLeftSpeed(15 downto 0) <= (others => '0'); -- 1回前の走行速度 クリア end if; -- 此処から、data の 出力をおこなう -- if ( ReadWrite == 0x00) then data output if ( (RESET = '1' and CS = '0' and A13 = '1') and ReadWrite = '0' ) then -- 走行速度 output if ( A2 = '0' and A1 = '1' and A0 = '0') then outLeftCounter(7 downto 0) <= reserveLeftSpeed(7 downto 0); elsif ( A2 = '0' and A1 = '1' and A0 = '1') then outLeftCounter(7 downto 0) <= reserveLeftSpeed(15 downto 8); elsif ( A2 = '1' and A1 = '0' and A0 = '0') then outLeftCounter(7 downto 0) <= LeftSpeed(7 downto 0); elsif ( A2 = '1' and A1 = '0' and A0 = '1') then outLeftCounter(7 downto 0) <= LeftSpeed(15 downto 8); end if; end if; -- 此処から、速度を計測する -- エンコーダ信号の、Hの幅を測定する if ((RESET = '1' and CS = '1' and A13 = '0') and ( encLeftA_new = '1' and encLeftA_old = '0' )) then LeftSpeed(15 downto 0) <= (others => '0'); -- 現在の走行速度 クリア end if; if ((RESET = '1' and CS = '1' and A13 = '0') and ( encLeftA_new = '0' and encLeftA_old = '1' )) then reserveLeftSpeed <= LeftSpeed; -- カウンタの値 退避 LeftSpeed(15 downto 0) <= (others => '0'); -- 現在の走行速度 クリア end if; -- 出力は 'H' か if ((RESET = '1' and CS = '1' and A13 = '0') and ( encLeftA_new = '1' and encLeftA_old = '1' )) then if (SubClock'event and SubClock = '1') then -- システムクロックを分周したパルスをcountする LeftSpeed <= LeftSpeed + '1'; -- カウントアップ end if; end if; end process; end RTL;チェックを全く通らない、エラーが何処かも判らない、エラーメッセージの意味が理解できなかった。悔しいことに、文法チェックは通るのだ。って、さっぱり進歩していないじゃないか。
自分のスキルの低さと頭の悪さに、今夜も枕を濡らすのだろうか。
井谷さんの話によれば、ロータリーエンコーダのHの幅は変化するので、パルスの1周期の時間を計測した方が良いそうだ。だもんで、このソースは、一部修正しないと使えない。
その前に、エラーをとらないと、修正もなにもあったもんじゃないわな。もう少し判り易いエラーメッセージは無いもんか、昔のマニュアルは親切だった、英文のエラーメッセージと日本語の対応表が添付されていた。
昔はあたしも若かった、あたりまえだろが、生まれたときからおじさんじゃないわい。
7月23日(月)
やっと、VHDLで書いているCPLDのソースのエラーが無くなった。ここんとこ、脳細胞が熱くなる毎日だったが、努力すればなんとかなるということか。井谷さん、感謝します。
なんか、少し判ってきたみたいだ、あはは、気のせいだったりして。library IEEE; use IEEE.STD_LOGIC_1164.all; use IEEE.STD_LOGIC_ARITH.all; use IEEE.STD_LOGIC_UNSIGNED.all; entity cwccwRight is port ( MainClock : in std_logic; -- システムクロック(for trigger) RESET : in std_logic; POWER : in std_logic; Right_Pwm : in std_logic; right_P0 : out std_logic; right_N1 : out std_logic; right_P1 : out std_logic; right_N0 : out std_logic ); end cwccwRight; architecture RTL of cwccwRight is signal timerRight : std_logic_vector(4 downto 0); -- 5 bit counter begin process (MainClock, Right_Pwm) begin if (RESET = '0' or POWER = '0') then right_P0 <= '1'; -- right_P0 off right_N1 <= '0'; -- right_N1 off right_P1 <= '1'; -- right_P1 off right_N0 <= '0'; -- right_N1 off elsif ( Right_Pwm' event and Right_Pwm = '1' ) then -- 立上がりエッジの時 cw 時計周りに回転 -- all FET cut off right_P1 <= '1'; -- right_P1 is off right_N0 <= '0'; -- right_N0 is off right_P1 <= '1'; -- right_P1 is off right_N0 <= '0'; -- right_N0 is off -- 此処で delay をとる 24MHz is 2.5 us timerRight <= "00000"; while (timerRight(4) = '0') loop if(MainClock'event and MainClock = '0') then timerRight <= timerRight+ '1'; end if; end loop; -- cw 時計周りに回転させる right_P0 <= '0'; -- right_P0 on right_N1 <= '1'; -- right_N1 on right_P1 <= '1'; -- right_P1 is off right_N0 <= '0'; -- right_N0 is off elsif ( Right_Pwm' event and Right_Pwm = '0' ) then -- 立下りエッジの時 ccw 反時計周りに回転 -- all FET cut off right_P0 <= '1'; -- right_P0 is off right_N1 <= '0'; -- right_N1 is off right_P1 <= '1'; -- right_P1 is off right_N0 <= '0'; -- right_N0 is off -- 此処で delay をとる 24MHz is 2.5 us timerRight <= "00000"; while (timerRight(4) = '0') loop if(MainClock'event and MainClock = '0') then timerRight <= timerRight+ '1'; end if; end loop; -- ccw 反時計周りに回転させる right_P0 <= '1'; -- right_P0 is off right_N1 <= '0'; -- right_N1 is off right_P1 <= '0'; -- right_P1 is on right_N0 <= '1'; -- right_N0 is on end if; end process; end RTL;チェックを全く通らなかった、エラーが何処かも判らなかった、エラーメッセージの意味が理解できなかった。はやい話が、手も足もでなかった。悔しいことに、文法チェックは通るのだ。
自分のスキルの低さと頭の悪さに、一人寝の枕を濡らした夜はいく晩続いたろうか。
チェックを通ったソースは、動作確認ができたら、公開するかもしれない、しないかもしれない。気分しだいというところか、ま、公開できるようなソースが書けないということではあるが。
コンピュータのプログラムの概念を全て棄てないと、CPLDのソースは書けないということが判った。ノイマン型のコンピュータのプログラムにどっぷり浸かっていた私には、理解はできても実行するのは至難の技だった。
上記のコードだって、Cのソースなら、何処が悪いんだ、と言いたくなるのだが。
6月22日(金)
昨日の日記に、『CPLDのプラスとグランドの結線が終わった、なんと、CPLDにはリセット入力端子ってのは無いということを発見した。おまけにシステムクロック?を入力するピンも無い。』と書いたら、I谷さんの日記にこたえが書いてあった。
心より感謝いたします。で、ずうずうしくも、IO/GTSnという端子の使い方を教えて下さいとメッセージを入れた、よろしくお願いします。なんで、RESTとかCLKと書いてないのかな。データシートってのは、なるべく理解し難いように書くという決まりてもあるのだろうか。
それとも、ブロック図を読めない人間は使うなということか。
VHDLのソース、一部修正、速度計測を走行距離の計測のなかに組み込んだ。文法チェックはそれ程苦労せずに通ったが、はたしてきちんと回路になるのかと自問すると自信が無い。
特に、 if とend if の対応で弾かれる、そこで、C言語ライクに、{} で括ってみたが、弾かれた。エラーの大部分が、if とend if の対応が不適切と、;と:の書き間違い、私のミスではあるが、ちょっと悔しい。
人間は間違えるもんだ、間違えないような構造で言語を設計して欲しいと願うのは勝手な言い分か。
CPLDのVccとGNDの結線が終わった、今夜からH8/3052とCPLDの結線を始める。
昼休みなので、ザイリンクス社のホームページにアクセスして、ピン機能などを説明したファイルを探している。探し方が悪いのか見つからない。それとも、日本のデータシートみたいに親切なデータシートは無いのだろうか。
日本のデータシートには、参考回路まで書いてある、すごく有りがたい。ブロック図を読んで、ピンの機能などは自分で考えなければならないのだろうか。今夜時間がとれたら、もう少しホームページの中を捜してみよう。
本社のホームページにアクセスしなければならない、なんてなことは無いと信じたい。あたしゃ英語は駄目なのよ。
6月18日(月)
昼休みに、ロータリーディップスイッチとパワースイッチ、リセットスイッチ、スタートスイッチの取り付け位置を決める。ジュンフロン線の切れ端で基板に縛り付けて、干渉しないのを確認する。
ついでに、配線の色を決めてこれで昼休み終わり。
夕方、マイクロマウス委員会山形支部総会に出席するため、斎藤先生の車に乗せてもらって、長井のTASに行く。私は参加しない方が、会議がスムースに進むような気がする。
パスコンを取り付けるために、PLCCのICソケットの中央部をフライス盤で削る。斜めにすれば、パスコンを2個くらいは取り付けできそうなスペースを確保する。
84ピンのPLCCは大きい、ちょっと違和感を感じる。
今夜はこれまで。
6月17日(日)
一日中、H8/3052とCPLDのインターフェイスで悩む。CPLDは、XC95108-15PC84Cを搭載することにした。XC9572-15PC44Cの方が小型なのだが、下手糞な私の書いたコードが作り出す回路が、入らない可能性を考えてのこと。
XC95108-15PC84Cが上手く動いたら、XC9572-15PC44Cに載らないか考えることにする。
余計なプルアップ抵抗を極力減らすために、H8/3052の機能を最大限(と、自分は思っているが)に生かして、CPLDとのインターフェイスを決めた。なかなか楽しいというか、面倒な作業だった。
ポートが不足するので、使わないアドレスはポートにしたりと、そこそこ工夫した。
ポートアサインは、ファイルにして残した、しっかりドキュメント管理をする。
6月16日(土)
昼休みにソースを見ていたらバグ発見。if ( READ = '0' ) then -- if ( read == 0x00) then data output if ( A1 = '0' and A0 = '0') then outLeftCounter(7 downto 0) <= LeftCounter(7 downto 0);and でなきゃ、常に条件が成立するわな。
ソースを書いていて、いろいろ疑問がでてきた。
まず、architecture の中に、process は1組しか書けないのだろうか。もし、いくつものprosess文が書けるのであれば、動作は、上から順番に実行されるのだろうか。それとも、同時に実行されるのだろうか。
加えて、以下のような使い方は可能なのだろうか、疑問だ。architecture RTL of encorder108 is begin process (Clock) begin TRIG_1 <= presses_1_out ; end process; process (TRIG_1) begin TRIG_2 <= presses_2_out ; end process; process (TRIG_2) begin end process; end RTL;似たような疑問だが、以下のように process の中に if文を複数組書いたとする。その場合、複数組のif 文は、同時に実行されるのだろうか、それとも、上から順番に実行されるのだろうか。
同時に実行されないと、ディレイが生じる、困るわな。process (MainClock) begin if ( enc1A_new = '0' and enc1A_old = '0' ) then 中略 end if; if ( enc1A_new = '1' and enc1A_old = '0' ) then 中略 end if; if ( enc1A_new = '1' and enc1A_old = '1' ) then 中略 end if; end process;1個のCPLDの中に複数の回路を組み込んで使う場合、ま、殆どがこういう使い方になるのだろうが、1本のピンから入力した信号、例えばクロック信号などを、複数の回路で使うことが可能なのだろうか。
可能ならば、ピンアサインの指示はどうすれば良いのだろうか。
悩みというか疑問は尽きない、初心者の上記のような疑問に対する答えは、私が購入した参考書には無かった。
6月15日(金)
今日のお昼休みも根性で頑張ったのだ、ま、いつまで続くか、というところか。以下はCPUとデータの入出力をする部分を追加したソースファイル。なかなか面倒というか、難しい。
ま、標準ロジックICで組むことを考えれば、時間の節約にはなるし、バグも減るのだが。library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; --use IEEE.STD_LOGIC_UNSIGNED.ALL; use IEEE.STD_LOGIC_SIGNED.ALL; entity encorder108 is port ( MainClock : in std_logic; -- システムクロック(for trigger) RESET : in std_logic; READ : in std_logic; CS,A13,A1,A0 : in std_logic; encodLeftA : in std_logic; -- A相入力線 encodLeftB : in std_logic; -- B相入力線 outLeftCounter : inout std_logic_vector(15 downto 0) -- 16 bit counter ); end encorder108; architecture RTL of encorder108 is -- 内部信号の定義 (define internal signal) signal enc1A_new: std_logic; -- A相1段目バッファ signal enc1A_old: std_logic; -- A相2段目バッファ signal enc1B_new: std_logic; -- B相1段目バッファ signal enc1B_old: std_logic; -- B相2段目バッファ signal LeftCounter: std_logic_vector(15 downto 0); -- 16 bit counter begin process (MainClock) begin if ( RESET = '0' ) then -- リセット信号が low なら LeftCounter <= "0000000000000000"; -- カウンタクリア elsif ( (CS = '0') and (A13 = '0') ) then -- カウンタ data 入出力 -- counter data input or putput if ( READ = '0' ) then -- if ( read == 0x00) then data output if ( A1 = '0' or A0 = '0') then outLeftCounter(7 downto 0) <= LeftCounter(7 downto 0); elsif ( A1 = '0' or A0 = '1') then outLeftCounter(15 downto 8) <= LeftCounter(15 downto 8); elsif ( A1 = '1' or A0 = '0') then outLeftCounter(7 downto 0) <= LeftCounter(7 downto 0); elsif ( A1 = '1' or A0 = '1') then outLeftCounter(15 downto 8) <= LeftCounter(15 downto 8); end if; else -- if ( read != 0x00) then data intput if ( A1 = '0' or A0 = '0') then LeftCounter(7 downto 0) <= outLeftCounter(7 downto 0); elsif ( A1 = '0' or A0 = '1') then LeftCounter(15 downto 8) <= outLeftCounter(15 downto 8); elsif ( A1 = '1' or A0 = '0') then LeftCounter(7 downto 0) <= outLeftCounter(7 downto 0); elsif ( A1 = '1' or A0 = '1') then LeftCounter(15 downto 8) <= outLeftCounter(15 downto 8); end if; end if; else enc1A_new <= encodLeftA; -- A相入力を1段目バッファにコピー enc1A_old <= enc1A_new; -- 1段目バッファ(前回の値)を2段目バッファにコピー enc1B_new <= encodLeftB; -- B相入力を1段目バッファにコピー enc1B_old <= enc1B_new; -- 1段目バッファ(前回の値)を2段目バッファにコピー end if ; if ( enc1A_new = '1' and enc1A_old = '0' ) then -- A相が立ち上がりエッジ if ( enc1B_new = '0' ) then LeftCounter <= LeftCounter+ '1'; -- A相が立ち上がりエッジで B相が low else LeftCounter <= LeftCounter- '1'; -- A相が立ち上がりエッジで B相が high end if; elsif ( enc1A_new = '0' and enc1A_old = '1' ) then -- A相が立ち下がりエッジ if ( enc1B_new = '0' ) then LeftCounter <= LeftCounter- '1'; -- A相が立ち下がりエッジで B相が low else LeftCounter <= LeftCounter+ '1'; -- A相が立ち下がりエッジで B相が high end if; elsif ( enc1B_new = '1' and enc1B_old = '0' ) then -- B相が立ち上がりエッジ if (enc1A_new = '0' ) then LeftCounter <= LeftCounter- '1'; -- B相が立ち上がりエッジで A相が low else LeftCounter <= LeftCounter+ '1'; -- B相が立ち上がりエッジで A相が high end if; elsif ( enc1B_new = '0' and enc1B_old = '1' ) then -- B相が立ち下がりエッジ if (enc1A_new = '0' ) then LeftCounter <= LeftCounter+ '1'; -- B相が立ち下がりエッジで A相が low else LeftCounter <= LeftCounter- '1'; -- B相が立ち下がりエッジで A相が high end if; else LeftCounter <= LeftCounter; end if; end process; end RTL;で、結果は以下のとうり、文法エラーだけは無いようだ。Started : "Check Syntax for encorder108". ========================================================================= * HDL Compilation * ========================================================================= Compiling vhdl file "C:/XilinxWorkSpace/encoder/encoder108/encoder108.vhd" in Library work. EntityRESET信号入力でカウンタクリア、READ信号でデータの入出力の方向を制御、CS,A13,A1,A0で、入出力するデータを制御するという回路なのだが、果たして上手く動くだろうか。compiled. Entity (Architecture ) compiled. Process "Check Syntax" completed successfully
これは、左モータ用のエンコーダ対応なので、右モータ用も書かなければならないのかな。同じじゃ駄目かな、疑問だ。
6月14日(木)
お昼休みに根性で頑張ったのだ。VerilogHDLに変更するか、悩むわなぁ。library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity encorder108 is port ( MainClock : in std_logic; -- システムクロック(for trigger) encodLeftA : in std_logic; -- A相入力線 encodLeftB : in std_logic; -- B相入力線 outLeftCounter : out std_logic_vector(15 downto 0) -- 16 bit counter ); end encorder108; architecture RTL of encorder108 is -- 内部信号の定義 (define internal signal) signal enc1A_new: std_logic; -- A相1段目バッファ signal enc1A_old: std_logic; -- A相2段目バッファ signal enc1B_new: std_logic; -- B相1段目バッファ signal enc1B_old: std_logic; -- B相2段目バッファ signal LeftCounter: std_logic_vector(15 downto 0); -- 16 bit counter begin process (MainClock) begin enc1A_new <= encodLeftA; -- A相入力を1段目バッファにコピー enc1A_old <= enc1A_new; -- 1段目バbファ(前回の値)を2段目バッtァにコピー enc1B_new <= encodLeftB; -- B相入力を1段目バッファにコピー enc1B_old <= enc1B_new; -- 1段目バッファ(前回の値)を2段目バッファにコピー if ( enc1A_new = '1' and enc1A_old = '0') then -- A相が立ち上がりエッジ if ( enc1B_new = '0' ) then LeftCounter <= LeftCounter+ '1'; -- A相が立ち上がりエッジで B相が low else LeftCounter <= LeftCounter- '1'; -- A相が立ち上がりエッジで B相が high end if; else if ( enc1A_new = '0' and enc1A_old = '1') then -- A相が立ち下がりエッジ if (enc1B_new = '0' ) then LeftCounter <= LeftCounter- '1'; -- A相が立ち下がりエッジで B相が low else LeftCounter <= LeftCounter+ '1'; -- A相が立ち下がりエッジで B相が high end if; else if ( enc1B_new = '1' and enc1B_old = '0') then -- B相が立ち上がりエッジ if (enc1A_new = '0' ) then LeftCounter <= LeftCounter- '1'; -- B相が立ち上がりエッWで A相が low else LeftCounter <= LeftCounter+ '1'; -- B相が立ち上がりエッジで A相が high end if; else if ( enc1B_new = '0' and enc1B_old = '1' ) then -- B相が立ち下がりエッジ if (enc1A_new = '0' ) then LeftCounter <= LeftCounter+ '1'; -- B相が立ち下がりエッジで A相が low else LeftCounter <= LeftCounter- '1'; -- B相が立ち下がりエッジで A相が high end if; else LeftCounter <= LeftCounter; -- 上記のいずれにも該当しない条件の時は LeftCounter は現在の値を保持する end if;
end if;
end if;
end if;
end process;outLeftCounter <= LeftCounter; end RTL;やっとエラーがでなくなった、やけくそで『end if;』を5個、prosess; の前に置いてみた。そうしたら、prosessの置く位置ではなく、end if が多いというエラーがでた。
で、減らしていったら、赤い字分の end if で、エラーが消えた。意味不明。
今度は、警告の嵐、なんか深刻な警告だ・・・・・・
WARNING::Xst:819 - "C:/XilinxWorkSpace/encoder/encoder108/encoder108.vhd" line 47: The following signals are missing in the process sensitivity list: WARNING:Xst:647 - Inputis never used. WARNING:Xst:737 - Found 16-bit latch for signal . WARNING:Xst - Property "use_dsp48" is not applicable for this technology. WARNING:Xst - Property "use_dsp48" is not applicable for this technology. WARNING:Xst:1710 - FF/Latch (without init value) has a constant value of 0 in block . WARNING:Xst:1710 - FF/Latch (without init value) has a constant value of 0 in block . WARNING:Xst:1710 - FF/Latch (without init value) has a constant value of 0 in block . WARNING:Xst:1710 - FF/Latch (without init value) has a constant value of 0 in block . WARNING:Xst:1710 - FF/Latch (without init value) has a constant value of 0 in block . WARNING:Xst:1710 - FF/Latch (without init value) has a constant value of 0 in block . WARNING:Xst:1710 - FF/Latch (without init value) has a constant value of 0 in block . WARNING:Xst:1710 - FF/Latch (without init value) has a constant value of 0 in block . WARNING:Xst:1710 - FF/Latch (without init value) has a constant value of 0 in block . WARNING:Xst:1710 - FF/Latch (without init value) has a constant value of 0 in block . WARNING:Xst:1710 - FF/Latch (without init value) has a constant value of 0 in block . WARNING:Xst:1710 - FF/Latch (without init value) has a constant value of 0 in block . WARNING:Xst:1710 - FF/Latch (without init value) has a constant value of 0 in block . WARNING:Xst:1710 - FF/Latch (without init value) has a constant value of 0 in block . WARNING:Xst:1710 - FF/Latch (without init value) has a constant value of 0 in block . WARNING:Xst:1710 - FF/Latch (without init value) has a constant value of 0 in block . VHDLは、なかなか楽しめるわぃ・・・・あはは、負け惜しみ。
とりあえず、『end if;』を3個も余計に書かなければならない理由は判った。C言語では『else if』だが、VHDLでは『elsif』と書かなければならないのだ。知らなかった、参考書はしっかり読まないと。
ちなみに、井谷さんの VerilogHDLのソースでは、『else if』と書いてある。VerilogHDLに変更するかなぁ、こんなことで時間をとられちゃたまらん、と、原因を他人に求めちゃだめだよなぁ。
しかし、『else if』で良いじゃないか・・・・・さて、警告の嵐を解決しないと・・・・・・・
文法チェックが終わった、やったゼィ!!!Started : "Check Syntax for encorder108". ========================================================================= * HDL Compilation * ========================================================================= Compiling vhdl file "C:/XilinxWorkSpace/encoder/encoder108/encoder108.vhd" in Library work. Entityどうにか、文法チェックは終わった。私の使い方が間違っていた、アホだ。結局、文法的には、何処も間違っていなかったということになる、なんと愚かなことか、泣きたくなるわな。compiled. Entity (Architecture ) compiled. Process "Check Syntax" completed successfully
原因は、文法チェックの方法を間違っていたことによる、参考書は真面目に、しっかり読みましょう。
6月13日(水)
開発言語の選択に失敗したみたいだ。井谷さんから、ロータリーエンコーダの位相計数回路を組むためのHDLのソースを見せていただいた。VHDLのソースと比較して読み易い。VerilogHDLは、なんかC言語に感じが似ている。
VHDLは、手続きが面倒臭い、読み難い、理解し難い。特にエンティティとかプロセス、コンポーネントの概念が理解し難い、そのうち慣れるだろうとは思いたいが、自信が無い。
今から、VerilogHDLに変更するか、悩むわなぁ。
初期投資が無駄になるから、VHDLで頑張ってみようねっと。誰か助けてくれぇ!!!
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity encorder108 is port ( MainClock : in std_logic; -- システムクロック(for trigger) encodLeftA : in std_logic; -- A相入力線 encodLeftB : in std_logic; -- B相入力線 outLeftCounter : out std_logic_vector(15 downto 0) -- 16 bit counter ); end encorder108; architecture Behavioral of encorder108 is -- 内部信号の定義 (define internal signal) signal enc1A_new: std_logic; -- A相1段目バッファ signal enc1A_old: std_logic; -- A相2段目バッファ signal enc1B_new: std_logic; -- B相1段目バッファ signal enc1B_old: std_logic; -- B相2段目バッファ signal LeftCounter: std_logic_vector(15 downto 0); -- 16 bit counter begin process ( MainClock ) begin enc1A_new <= encodLeftA ; -- A相入力を1段目バッファにコピー enc1A_old <= enc1A_new ; -- 1段目バッファ(前回の値)を2段目バッファにコピー enc1B_new <= encodLeftB ; -- B相入力を1段目バッファにコピー enc1B_old <= enc1B_new ; -- 1段目バッファ(前回の値)を2段目バッファにコピー if ( enc1A_new = '1' and enc1A_old = '0' and enc1B_new = '0' ) then -- A相が立ち上がりエッジで B相が low LeftCounter <= LeftCounter+ '1'; else if ( enc1A_new = '1' and enc1A_old = '0' and enc1B_new = '1' ) then -- A相が立ち上がりエッジで B相が high LeftCounter <= LeftCounter- '1'; else if ( enc1A_new = '0' and enc1A_old = '1' and enc1B_new = '0' ) then -- A相が立ち下がりエッジで B相が low LeftCounter <= LeftCounter- '1'; else if ( enc1A_new = '0' and enc1A_old = '1' and enc1B_new = '1' ) then -- A相が立ち下がりエッジで B相が high LeftCounter <= LeftCounter+ '1'; else if ( enc1B_new = '1' and enc1B_old = '0' and enc1A_new = '0' ) then -- B相が立ち上がりエッジで A相が low LeftCounter <= LeftCounter- '1'; else if ( enc1B_new = '1' and enc1B_old = '0' and enc1A_new = '1' ) then -- B相が立ち上がりエッジで A相が high LeftCounter <= LeftCounter+ '1'; else if ( enc1B_new = '0' and enc1B_old = '1' and enc1A_new = '0' ) then -- B相が立ち下がりエッジで A相が low LeftCounter <= LeftCounter+ '1'; else if ( enc1B_new = '0' and enc1B_old = '1' and enc1A_new = '1' ) then -- B相が立ち下がりエッジで A相が high LeftCounter <= LeftCounter- '1'; -- 上記のいずれにも該当しない条件の時は LeftCounter は現在の値を保持する end if; end process; end Behavioral;このソースの、48行にエラーが有ると、以下のようにメッセージがでるERROR HDLParsers:164 - "C:/XilinxWorkSpace/encoder/encorder108/encorder108.vhd" Line 48. parse error, unexpected PROCESS, expecting IF『end process;』の位置が悪いと言っていると思うのだが、何処に置けば良いのかが全く判らない、お手上げなのだ。
このソースの何処が悪いのか、誰か教えて下さい m(__)m。
6月10日(日)
多分、ルネサスのH8/3052を搭載したCPUボードでは最も小さいだろうエフテックのH8/3052ボードModel No.F0293/52Fに、Xilinx社のCPLDを搭載する計画で、ハードの設計中。
まず悩むのが、H8−−>CPLDのアクセス。データアクセスを16ビットモードにすると、データバスが16本必要になる。外部拡張するので、アドレス信号や制御信号も必要なので、入出力に使えるピンが少なくなる。
おまけに、配線も16本必要だ。で、8ビットアクセスしたい。ネットで調べたが、8ビットのRAMを並べて16ビットRAMにしている人は見つけられなかった。RAMも廉価になったし、1個の方がスペースが節約できるわな。
ただ今、嫌になるくらい厚いマニュアルと格闘中。
エフテックの、H8/3052ボードの、CN4の14番ピン、『/RES』の信号の向きが理解できない、というか書いてないような気がするのだが。『CPUーー>外部』だと助かる、CPLDに直接入れれば良い。
エフテックさんにメールで問い合わせ中。
ザイリンクスのCPLDには、GCK、GTS、GSR、という端子が有る。端子の役目と使い方はこれから勉強するとして、使わないときはオープンにしておいて良いのだろうか。
それとも、プルダウンとかプルアップの処理をしなければならないのだろうか。
もう、悩みというか、判らないことだらけだ。いろいろな参考書を読んでいるが、全くの初心者が、最初に悩むところが書かれていないような気がするのは、私の僻みだろうか。
忘れやすい自分のために、軌跡を書き残しておく。
6月 7日(木)
昨夜、Xilinx社のホームページからダウンロードしたISE WebPACKは無事解凍できたので、セットアップを始めた。
日本語で説明が書いてあり、セットアップは簡単に始められたが、暫くは画面が変化しない。かなり慌てたが、時間が懸かるようなので、セットアップを中止して、今日の朝、6時45分からインストール開始。
8時20分、セットアップ終了、えらく時間が懸かった。で、ここで失敗、ウエブアップデードと環境のチェックにチェックを入れていたので、別のプログラムが動き出した。
現在、8時45分、まだ終わらない、まいった。
ウエブアップデードと環境のチェックにチェックを入れるのは止めた方が良いみたい。
ただいま9時10分、諦めて、ウエブアップデードと環境のチェックをキャンセルする。これにてインストール終了、デフラグを実行する。
立ち上がりが遅い、凄く重たい感じがする、メモリが足りないのか。
6月 5日(火)
Xilinx社のホームページから、ISE WebPACKをダウンロードする。 ログインのためのIDを取得するまでがなかなか面倒臭かった。
ダウンロードしたファイルを、日本語名のフォルダに保存したためか、ZIPファイルを解凍できない。アルファベットのフォルダに名前を変更して、解凍はどうにか無事終了。
インストールは明日以降にする。
6月 4日(月)
事務所のノートパソコンと作業室のデスクトップをルーターを通してLANケーブルで結んだ。これで作業室のデスクトップもネットに接続できるようになった。すぐに、Hewを最新版にアップデートする。
設定変更で、ちょっとトラブルがあったが無事終了。動作を確認する。
CPLDの開発環境までは手が廻らなかったが、若松電子通商に、Xilinx社の、XC9572-15PC44Cと、XC95108-15PC84Cを注文した。
希望の回路が全部入らないと困るので、XC95108-15PC84Cも注文したが、できれば44ピンのXC9572-15PC44Cを使いたい。16ビットの位相計数回路2組と、DCモータ用のディレイ回路を2回路入れたいのだが。
44ピンに入りきらなかったら84ピンを使う予定。ピン数が多ければ、たくさん回路が入ると思っているところが、初心者の初心者たる所以か。
ま、そのうち、なんとかなるだろう、きっと。
6月 3日(日)
朝から、ヒューマンデータ社の、CPLD学習用ボード組み立てキットXSP-019KITのハンダ付け。なんとか、今夜中に終わしたい。
明日からは予備のデスクトップがネットに接続できるはずだ、開発環境を整えたいのだが・・・・
5月26日(土)
地元の書店に注文したPLD関係の参考書が届く、全部で、13000円を越える、これで挫折したら馬鹿みたいなもんだ。
5月21日(月)
昨夜、ヒューマンデータ社に注文した、CPLD学習用ボード組み立てキットと、XILINX対応のダウンロードケーブル自作キットは、明日届くらしい。
送料、代金引き換え手数料別で、16066円也。CPLDが使えるようになれば廉価な投資。
5月20日(日)
PLDの勉強のため、ヒューマンデータ社の、CPLD学習用ボード組み立てキットXSP-019KITを購入することに決めた。悩んでいても仕方がないので、すぐにネットで発注する。
ついでに、CPLD関係の参考書も地元の書店に注文する。
5月19日(土)
FPGAとCPLDのどちらを選ぶか、アルテラとザイリンクスのどちらを選ぶかで、ずいぶん悩んだ。マウスに使うので、なるべく小型にしたいという点から、外付けのROMが不要なCPLDを選択した。
アルテラとザイリンクスのどちらを選ぶかで少し悩んだ。どちらも、いろいろな種類があり、なんとも決めかねた。そこで、発想を変えて、開発言語に注目した。
開発言語では、VerilogHDL、VHDLなどが代表的なものらしい。で、VHDLは、アメリカ国防省の計画から生まれたらしい。Z80のアセンブラを記憶してもH8には、使えなかったという経験から、民間会社の自社のICに特化した開発言語は採用したくなかった。
これで、開発言語はVHDLに決定した。ま、VerilogHDLも、そう、大きな違いは無いらしいのだが。
開発言語がVHDLに決まった。XILINX社の、WebPACKに入っているソフトウェアは、VerilogHDL、VHDLのどちらにも対応しているらしい、しかも無料らしい。アルテラ社の開発環境も無料らしいのだが。
開発言語の主流が、VHDLから、VerilogHDLに変わっても、開発環境が両方に対応しているらしい点をポイントに加算して、ザイリンクス社の製品を使うことに決めた。
ザイィンクス社のCPLDを、VHDLを開発言語にして、XILINX社の、WebPACKに入っているソフトウェアで開発する。
5月15日(火)
長井の帰りに閃いたのはもう一つ、PLDを使ってみたいということ。一度挫折してるが、ネットには参考になる記事がたくさんあるし、参考書も多くでているようだ。
むざむざと討ち死にすることもないだろさ。
暫くネットで情報を集めよう。