Dies Aliquanti

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

元ガンヲタの日曜の午後 (2)

 「ラインセレクタ(笑)」用の部品は一通りそろったのだが、先週は諸般の都合により、ず~っと呑んだくれていたせいもあり、土曜は家内の相手、日曜も自動車を洗って芝の水遣りであとはクーラーの効いた部屋でぐで~っとしているばかり。
 3時くらいから、とりためてあったガンダム(1st)を観だしたらはまってしまった。ジャブローの攻防から、シャリア・ブルあたりまで見てしまい、期せずして、ガンダム・マラソンになってしまった。

 いい加減部屋を片付けないと、半田付けもできない。
----
[本日の御託]
途中から家内も一緒に見ていた(再放送を見たことがあるらしい)のだが、ところどころで、

「悲しいけど、これ戦争なのよねぇ」
「あれはいいものだぞぉ・・・」(ちゅど~ん)
「若者をあまりいじめないでいただきたい」

などと、言っていたら、家内に「おかしいよ、絶対!なんでせりふおぼえてんの?!」などといわれる始末(笑)。

 まあ、当時は(たまには)「OUT」とか「メック」とか買ったりもしていたわけで・・・
ちなみに、「ガンプラ」ブームのころには、女の子の尻を追いかける方が忙しくなってしまい、全く手を出していない。でも、「ザクレロ」欲しいな・・・

バンダイ(BANDAI)機動戦士ガンダムMA-04X ザクレロ1/550スケールガンダムプラモデル・ガンプラ【エンタメセール0303】



スポンサーサイト

やってもうた…

やってもうた…。土曜日に芝刈りをしたのだが、欲張って肥料を撒いた。盛夏の肥料は禁物なのだが、少しならいいか、とやって、水遣りをいい加減にしたら、見事に肥料焼けしてしまった…
 秋までに回復するかなぁ…。芝も3年目だが、最大の失敗。orz.
----
[本日の御託]
 まあ、落ち込んでばかりもいられないので、秋月に残りの部品を発注しよう。金皮の抵抗は、今週秋葉に行くか…

ビデオラインセレクタ(笑)を作る。その10

 一応、シミュレーション上ではちゃんと動作するようになりました。うまく動作しなかったのは、PIC16F648のI/Oの設定がまずかったり、ソースコードの大半をVerilogからコピペしていたので、代入文が <= のままだったり(orz cでは代入ではないですが、文法上は誤りではないです),LMH1981のモデルにバグがあったり・・・。 

 あと、HI-TECH社のPCCにもちょっと問題を見つけました。いや、正確にはPCCの問題というのは、正しくないかもしれません。たとえば、short形の変数iを使用するとします。メイン・ルーチンとインタラプト・サービス・ルーチン(ISR)の両方で、参照・変更する場合に気をつける必要があります。メインルーチンで代入を行う場合、
   i=0 ;
は、
   CLRF _i
   CLRF _i +1

のように、コンパイルされますが、2つの命令の間で、割り込みが受けつれられ、ISRの中で、iを参照したり、変更したりするとへんてこな値が参照されたり、メインルーチンで値を壊すことになります。
 代入する場合、
   GIE =0 ;
       i = 0 ;
   GIE = 1 ;

とすればよいでしょう。参照の場合も同様ですが、割り込み禁止区間を短くしたいのであれば、
   GIE = 0 ;
       i_snapshot = i ;
      GIE = 1 ;

として、実際の演算は、スナップショットである、i_snapshotに対して行うようにします。
本質的には、マルチスレッド(もしくは並行プログラム)とアトミックな命令の問題ですが・・・
---
[本日の御託]
 とりたてて、「用事」があるわけではなかったのだが、ラゾーナ川崎へ出かけた。謎にすっげぇ混んでた。
 ラゾーナ川崎って、エスカレーターがわかりにくい。中庭に面したエスカレータの場所がまちまちで、ちょっと「イラっ」とする。ついでにいえば、中庭のステージでなにもしていないときも、がんがん音楽をかけているのも×。
 「コールド・ストーン」は、となりの「銀だこ」(決してきらいじゃないけど)のにおいが立ち込めていて、食べる気がせず。



ビデオラインセレクタ(笑)を作る。その9 とほほ

 HI-TECH社のPICCの統合環境である、HI-TIDEもなんとなく使い方がわかったので、サクッとプログラムを書いてみました。Cで200行ちょっと。Verilog-HDLで既にアルゴリズムの検討は終えているのでCへの移植は簡単です。普通は、Cでアルゴリズムの検討をしてVerilogでハードウェアにするのに、逆ですね(笑)。
 ただ、割り込み処理ルーチン(ISR)での処理をある程度軽くする必要があるので、デコード部分は、メインルーチン側でちんたらやることにします。

 前に作ったPICのVerilogモデルとLMH1981も一緒にして、「一発で動け!」とばかりに、Veritak上でシミュレーションして見ますが、どうも動作がヘンです。よく見ると、PICクロックが10分の1。 orz
 クロックを修正し、気を取り直して再度トライしてみますが、ちゃんと動きません。ぬぅ・・・どうも、PICの方がおかしいみたいです。デバッグをする気にもなれず、今日はここまで・・・

あぁ、私D3とD4を逆に考えてますね・・・お恥ずかしい  orz
---
[本日の御託]
 PICのプログラムと並行して、秋月にいくつか部品を頼もうと思うのですが、送料などのことを考えるとある程度まとめて買わないともったいない気がします。なに買おうかな~っ♪

ビデオラインセレクタ(笑)を作る。その8 PICのプログラミング (2)

 PICのプログラムですが、さすがにアセンブラはきついので、PICCをチェックすべくHi-Tech社のWebページにいったら、PICC Liteがバージョンアップされています。

 統合環境のHi-Tideもバージョンアップされていて、見た目がずいぶん変わってしまいました。どうやら、eclipseベースになったようですが、使い方がよくわかりません。 orz
 3連休で仕上げようと思っていましたがちょっと無理・・・
---
[本日の御託]
 実はDigiKeyに注文していた、LMH1981が届いてしまいました。4日位で届くので、秋月と大差ないですね・・・
 写真は、前後して届いたDigikeyのカタログ。「電話帳」ですね。、「でこピンマーク」のイタズラ書きは、家内いわく、郵便受けではみ出しているカタログを見つけた時の本人の怒り、をあらわしているそうです(大笑)。
DigiKey



ビデオラインセレクタ(笑)を作る。その7

 割り込みの周期が、D4の場合で60μSくらいになってしまう件ですが、手元に余っている16F648Aでは内蔵クロック(4MHz)を使うと、1μS/インストラクション(実際には分岐するときのムダがあるのでもっと遅い)ですので、せいぜい40ステップくらいになってしまいます。D5の場合はさらに半分の時間になります。2バイトデータの比較だけで4ステップ以上喰いますから、とても無理そうです。

 外部の発振素子を使うことにして、20MHzとかにするしかなさそうです。これでも、200ステップくらいなので、ぎりぎりかな?D5はあきらめることにします。また、ただでさえ少ないIOピンがまた少なくなってしまうので、機能をすこしケチることにします。本当は、16F877あたりを使えばよいのですが、なにせ648Aが余っているので・・・

 ラインセレクトの範囲ですが、どうせ見たいのはVSYNCの辺りだけです(笑)。そこで、本来11ビット必要なところですが、5ビットだけ割り当てることにします。また、奇数/偶数フィールドの選択に1ビット、インターレースの両方または奇数、偶数ののどちらかを選択するのに1ビット、LMH1981からのインターフェースに3ビットで入力は合計10ビット。
 ラインセレクトの出力に1ビット、入力フォーマットD1~D4の表示で2ビット合計3ビット、あと1ビット余りますが、イザというときのための予備とします。
---
[本日の御託]
 麦茶に牛乳を入れてみた。意外においしかった。。。

ビデオラインセレクタ(笑)を作る~検証

Hardtest

 Verilogの設計をVeritakでシミュレーションしてみました。調べた範囲では、うまく動作しているようです。ところで、PICで実装するつもりでいましたが、D4の場合でも1Hの時間は60μSくらいしかありません。ん~、ちょっとつらいかな…
---
[本日の御託]
 我が家の夕飯は、イサキの塩焼きであった。家内は、頭のついているサカナが怖くて触れないのだが、週末に私の誕生日ということで行ったすし屋で食った塩焼き(イナダのカマ焼き)がよっぽど気に入ったらしく、焼き魚をやってみる気になったらしい。
 聞くと、スーパーの魚屋でワタを抜いてもらったはいいが、家で調理しようとしたら、やっぱり怖くて触ることができず、「手術用のゴム手袋」(なんでそんなものがあるんだ?笑)をして、やったらしい。途中、化粧塩をひれにつけていたら、手袋に刺さり、手袋をひれが貫通したり、と大騒ぎだったらしい。(大笑)
 でも、イサキはおいしかったよんっ!



ビデオラインセレクタ(笑)を作る~設計編その2

 昨日の方針に従って、アルゴリズムの検証をするために、Verilog-HDLでさくっと回路を書いてみることにします。
 最終的にはPICでインプリメントするつもりですが、回路をシミュレーションで検証するにはこのほうが簡単なので・・・RTLは最後に載せます。

 最初のalwaysブロックは、HSYNCによるカウンタの制御です。
 // manage line count
のコメント以下のifブロックは、1フィールドあたりのHSYNCの数をreg [10:0] count で数えています。数えた結果は、totalというregに入ります。

 この結果を // decoder for maxval , initialval, D1,D2 ...
以下のalwaysブロックでデコードしています。D_oは、D1~D4を表示します。その他の変数は、「本当のline」数を数えているカウンタの制御に用いられます。

 すこし戻り、 // manage real line number in 'line'
以下のifブロックでは、「本当のline」数-1をreg [10:0]line に数えています。

 最後のassign文はlineと目標とするラインの比較、同期パルスの作成をしています。信号gateNにはダイナミックハザードが乗ってしまいますが、HSYNCの立ち上がり周辺に限られるので問題にはなりません。
 論理合成可能な記述にしましたので、XilinxのISEにかけて見ましたが、特に問題はないようです。

---
[本日の御託]
 相変わらず庭の芝の雑草がひどいです。昨日も朝から雑草抜きをしていたら、お隣のご主人が、ペンチ型の雑草抜きを教えてくれました。周りの芝も一緒に抜いてしまうのがなんだが、確かに手でやるより楽です。早速ホームセンターで買い求めてみたが、調子にのってやっていたら、親指にマメができてしまいました。ううむ、なかなかうまくいかんものよのう・・・

//
// line selecter
//  (c) 2008 B.O.
//
module lineSel(
    input hs_i ,    // H Sync  -- from LMH1981
    input vs_i ,    // V Sync  -- from LMH1981
    input oe_i ,     // Odd (oe=1), Even (oe=0) -- from LMH1981

    input [10:0] linesel_i,    // line to select
    input linesel_oe_i,     // Odd/Even field select Odd(=1)
    input linesel_both_i,   // =0, Odd or Evn/ =1 Both
    input por_i,     // power on reset

    output reg [5:1] D_o,     // indicater D1,D2,,D5
    output sel_o     // Selecter out
);
    reg [10:0] count , total, line , maxval, maxval_half, maxval_half2,
     initialval, initialval2;
    reg prev_vsync ;

    always@( posedge hs_i or posedge por_i ) begin
 if( por_i ==1'b1 ) begin
     count <= 11'b0 ;
     line <= 11'd20 ;
     total <= 11'b0 ;
     prev_vsync <= 1'b0 ;
 end // if
 else begin
     prev_vsync <= vs_i ;

     // manage line count
     if( (prev_vsync == 1'b1) && ( vs_i == 1'b0 )) begin
  total <= count ;
  count <= 11'b0 ;
     end // if
     else begin
  count <= count + 11'b1 ;
     end

     // manage real line number in 'line'
     //  in case of VSYNC, aligning counter
     if(  (( linesel_both_i == 1'b1 ) 
   &&  (prev_vsync == 1'b1) && ( vs_i == 1'b0 ))
      ||(( linesel_both_i == 1'b0 ) 
   &&  (prev_vsync == 1'b1) && ( vs_i == 1'b0 )
   && ( linesel_oe_i == oe_i ) ) ) begin
  if ( oe_i == 1'b1 ) begin // odd
      line <= initialval ;
  end // if
  else begin
      line <= initialval2 ;
  end // else
     end // if
     //  overflow control
     else if((linesel_both_i == 1'b1) //  in case of interlace, both fileds
      && (   ((oe_i == 1'b1 ) && ( line == maxval_half))
          || ((oe_i == 1'b0 ) && ( line == maxval_half2)) ) ) begin
  line <= 11'b1 ;    // interlace both fiels overflow, line count
     end // elseif
     else if( line == maxval )  begin  // in case of Odd or Even
  line <= 11'b1 ;   
     end // else if
     else begin
  line <= line + 11'd1 ;
     end // else

 end // else
    end // always
 
    // decoder for maxval , initialval, D1,D2 ...
    always@( total ) begin
 case ( total[10:5] )
     'b00_1000 : begin
  D_o <= 5'b0_0001 ; // D1 480i
  maxval  <= 525 ;
  maxval_half <= 525 / 2 + 1 ;
  maxval_half2 <= 525 / 2 ;
  initialval <= 11'd6 ;
  initialval2 <= 11'd5 ;
     end
     'b01_0000 : begin
  D_o <= 5'b0_0010 ; // D2 480p
  maxval <= 525 ;
  maxval_half <= 525 ;
  maxval_half2 <= 525 ;
  initialval <= 11'd9 ;
  initialval2<= 11'd9 ;
     end
     'b01_0111 : begin
  D_o <= 5'b0_0100 ; // D3 720p
  maxval <= 750 ;
  maxval_half <= 750 ;
  maxval_half2 <= 750 ;
  initialval <= 11'd3 ;
  initialval2 <= 11'd3 ;
     end
     'b01_0001 : begin
  D_o <= 5'b0_1000 ; // D4 1080i
  maxval <= 1125 ;
  maxval_half <= 1125 /2 + 1 ;
  maxval_half2 <= 1125 /2 ;
  initialval <= 11'd3 ;
  initialval2 <= 11'd2 ;
     end
     'b10_0011 : begin
  D_o <= 5'b1_0000 ; // D5 1080p
  maxval <= 1125 ;
  maxval_half <= 1125 ;
  maxval_half2 <= 1125 ;
  initialval <= 11'd3 ;
  initialval2 <= 11'd3 ;
     end
     default  : begin
  D_o <= 5'b0_0000 ; // out of range
  maxval <= 0 ;
  maxval_half <= 11'd0 ;
  initialval <= 11'd0 ;
  initialval2 <= 11'd0 ;
     end
 endcase
    end // always

    assign gateN = ~( line ==  linesel_i ) ;
    assign sel_o  = ~( ~gateN & ~ hs_i ) ;
   
endmodule // lineSel
// [EOF] lineSel.v



ビデオラインセレクタ(笑)を作る~設計編その1

 LMH1981以降の回路だが、余っているPICを使うつもりです。HSYNCの数を数えるのが基本だが、同期したクロックが作れれば、ソフトでラインセレクト信号をかなり正確に作れるはずです。
 HSYNCに同期したクロックを作るにはPLLしかないのですが、結構範囲が広いですね。D1の場合、約15.8KHz、(D5は実際にはあまり対応した機器はないので、省略としても)D4の場合で、約29.6KHzになります。ざっと倍のロック範囲が必要になります。正直ちょっと自信ないですね~(笑)。もっともこの範囲で連続的にロックする必要はないので、複数のPLLを用意して、ほかの方法で切り替えるという方法もありますね。
 まあ、いずれにしても結構複雑なのでボツ。ソフトウェアでは、大まかなイネーブル信号を作成し、HSYNCとANDをとることで、正確なラインセレクト用の同期パルスを作ることにしました。外付けのANDとかを使うのは、ちょっとしゃくに障りますが、PLL用のICよりは単純に済むでしょう。

 HSYNCの数え方ですが、LMH1981のデータシートを見ると、HSYNCとVSYNCの関係はイマイチはっきりしないのですが、HSYNC(負論理)の↑エッジでカウントするほうがよさそうです。また、ライン・カウンタは、VSYNC(これも負論理)をHSYNCの立ち上がりで微分してエッジを検出して、リセットすることでなんとかなりそうです。リセットする際に再設定する値は0ではなく、適切な値にしなければなりませんが、ビデオのフォーマットによって適切な値にする必要があります。
 LMH1981にはフォーマットを出力する機能がありますが、どうせ、ラインを数えなければならないので、自分で数えてしまったほうが、全体の処理は簡単そうです。

 あと、いわゆる測定器としてのラインセレクタでは、インターレース(D1、D4)の場合、フレーム単位ではなく、フィールド単位、あるいは奇数/偶数の区別なくライン選択の機能があったほうが便利です。
---
[本日の御託]
 我が家の冷蔵庫の製氷機能が壊れました。結婚したときに買ったのでそろそろ11年になる。家内によると、自動製氷がうまく働かず、水タンクに水があるのに「水切れ」と誤解してしまう。また、出来た氷が溶けて、さらに固まったようになってしまうそうです。

 さすがにこの時期氷なしはきついので、気の早い私はカタログを集めてきたりしたのだが、カタログの自動製氷の仕組みの説明を見ていて家内が、「製氷皿が反転したままになっているんじゃないか?」と言い出した。
 なるほど、そうだとすると説明がつく。水タンクの水は製氷皿ではなく、氷を貯蔵するところに直接流れ、そのあとで凍っているのだ。
 修理は火曜日だそうだが、果たして「正解」だろうか?

ビデオラインセレクタ(笑)を作る~検討編その3

DigiKeyで買うものが決まらないのだが、とりあえず後段の回路の設計のために、LMH1981のビヘイビアモデルをVerilogでサクッっと書いてみました。
H-SYNCとV-SYNCの関係がイマイチデータブックからは読み取りがたいのですが、まあこのへんは現物を見てからということで。。。
簡単なテストベンチを用意して、Veritakを使って動かしてみるが、まあ所望する動作をしているようです。
 最後にソースを張っておきます。もちろん「なんちゃってモデル」なので、ビデオ信号を入力できるわけではなく、単に出力をするだけ。それもCSYNCは「はしょって」あります(どうせ使い道ないでしょ?)。

---
[本日の御託]
 ん~、これ欲しい。hauppauge HD PVR Model1212ハードウェアでのH264エンコードは「地雷」かも知れないが、$249は魅力だ・・・

(インデントがめちゃめちゃ)

//
// NS LMH1981 simplified bahavior model  (C)2008 B.O.
//  public tasks
//    task p1080 -- perform 1 frame with 1080p
//    task p720  -- perform 1 frame with 720p
//    task p480  -- perform 1 frame with 480p
//    task i1080 -- perform 1 frame with 1080i
//    task i480  -- perform 1 frame with 480i

`timescale 1ns/1ns
module LMH1981(
    output reg hsout_o ,    // H sync
    output reg vsout_o ,    // V sync
    output reg oeout_o ,    // Odd (oe=0), Even (oe=1)
    output vfout_o        // VF DATA  
) ;

    reg [10:0] line, maxline ;
    reg interlace ;
    time t_hinterval, t_hsout ;
    real vsync_delay ; // unit is H preiod

    integer frame ;
    wire frame2, startofframe ; // debug purpose
    reg [10:0] Data ;    // for vfout
    assign vfout_o = Data[10] ;

    // debug purpose
    assign frame2 = (frame == 2) ? 1'b1 : 1'b0 ;
    assign startofframe = (line == 1 ) ? 1'b1 : 1'b0 ;


    // internal tasks
    task HSync ;
    begin
    for( line = 1 ; line <= maxline ; line = line + 1 ) begin
        fork
        begin
            hsout_o <= 1'b0 ;
            #(t_hsout) hsout_o <= 1'b1 ;
        end
        # t_hinterval ;
        join
    end
    end
    endtask //HSync ;

    task VSync ;
    integer maxframe ;
    begin
    vsout_o <= 1'b1 ;

    if( interlace ) begin
        maxframe = 2 ;
        oeout_o <= 1'b0 ;
    end // if
    else begin
        maxframe = 1 ;
        oeout_o <= 1'b1 ;
    end // if

    for( frame = 1 ; frame <= maxframe ; frame = frame + 1 ) begin
        fork
        begin
            # (vsync_delay * t_hinterval )
                vsout_o <= 1'b0 ;
            if( interlace ) begin
                oeout_o <= ~oeout_o ;
            end // if
            # (3 * t_hinterval )
            vsout_o <= 1'b1 ;
        end
        #( maxline/2.0 *  t_hinterval) ;
        join
    end // for
    end
    endtask // VSync

    task VFData ;
    integer frame, maxframe ;
    begin
    Data = 10'd0 ;
    if( interlace ) begin
        maxframe = 2 ;
    end // if
    else begin
        maxframe = 1 ;
    end // else
    for( frame = 1 ; frame <= maxframe ; frame = frame + 1 ) begin
        @(negedge vsout_o ) ;
        repeat(3)
        @(negedge hsout_o ) ;

        if ( interlace ) begin
        if( frame == 1 ) begin
            Data <= maxline /2 - 2 ;
        end // if
        else begin
            Data <= maxline /2 - 3 ;
        end // else
        end // if
        else begin
        Data <= maxline - 3 ;
        end // else
        repeat( 11 ) begin
        @(negedge hsout_o )
            Data <= Data << 1 ;
        end // repeat
    end // for
    end    
    endtask // VFData ;

    task Do1Frame ;
    begin
    fork
        HSync ;
        VSync ;
        VFData ;
    join
    end
    endtask // Do1Frame ;


    //
    //  Public task to control the model
    //
    task p1080 ;
    begin
    maxline = 1125 ;
    t_hinterval = 1_000_000_000 / maxline / 29.97 ;
    t_hsout = 475 ;
    interlace  = 1'b0 ; // false
    vsync_delay = 1   ; //  1 H
    
    Do1Frame ;
    end
    endtask // p1080 ;

    task p720 ;
    begin
    maxline = 750 ;
    t_hinterval = 1_000_000_000 / maxline / 29.97 ;
    t_hsout = 525 ;
    interlace  = 1'b0 ; // false
    vsync_delay = 1   ; //  1 H
    
    Do1Frame ;
    end
    endtask // p720 ;

    task p480 ;
    begin
    maxline = 525 ;
    t_hinterval = 1_000_000_000 / maxline / 29.97 ;
    t_hsout = 2300 ;
    interlace  = 1'b0 ; // false
    vsync_delay = 7   ; // 7 H
    
    Do1Frame ;
    end
    endtask // p480 ;

    task i1080 ;
    begin
    maxline = 1125 ;
    t_hinterval = 1_000_000_000 / maxline / 29.97 ;
    t_hsout = 475 ;
    interlace  = 1'b1 ; // true
    vsync_delay = 0.5 ; // 0.5 H
    
    Do1Frame ;
    end
    endtask // i1080 ;
    
    task i480 ;
    begin
    maxline = 525 ;
    t_hinterval = 1_000_000_000 / maxline / 29.97 ;
    t_hsout = 2500 ;
    interlace  = 1'b1 ; // true
    vsync_delay = 3.5  ; //  3.5 H
    
    Do1Frame ;
    end
    endtask // i480 ;

endmodule // LMH1981




FC2Ad

まとめ

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。