散歩師・漫画居士のくだらなクラブ日記

ども、散歩師・漫画居士っす。散歩したり実働模型作ったりが趣味なんで、その時に思いついたこととか書くッス

【電子サイコロ】code golf してみた【Verilog】

電子サイコロとは?

 電子サイコロは、電源を入れるとサイコロの目を模した1~6のパタンが、高速に変化して表示され、しばらくするといずれかの目を表示しながら止まる。という電子玩具です。
こんなカンジ。
www.elekit.co.jp


 ぼくが最初に見たのは、1978年ころ、多分「ラジオの製作」(現:電子工作マガジン)の記事で見た、嘉穂無線(現:EK_JAPAN)のエレキットのコロスケくん(だいすきット?サイコロン?)だったと思います。
上の写真は、同じメーカーの何代もあとの子孫になります。


 紹介のキットや、初代のキットは、多分4000番台を使ったCMOS ICを使ってると思います。
しかし、最近知古本市通いで知ったんですが、CMOS IC以前にも、回路が知られていた様です。
TTL ICや、バイポーラ・トランジスタ-フリップフロップ構成のものは想像がついてましたが、
それ以前の非線形部品でも、作例があった様です。


 まとめて本にしたいと思ってるんですが、ちゃんと詰めるのが難しいので、できそうな企画から、小出しにしてみます。

FPGA に code golf 実装してみた

 CMOS ICでは70年代後半から80年代前半の回路ですが、近代版を考えると、モシモシアプリ版ということになるんでしょう。
それ以外にもFPGA版というのもありそうですね。


 単にHDLで書いただけではつまらないので、今回はcode golfしてみました。
code

module D(input C,R,output X,output integer Q,L);always@(posedge C){L,Q}<={"N76321">>Q*8,R?Q:(Q+1)%6};assign X=~C;endmodule

122文字です。VHDLだと標準ライブラリのインクルードも終わらないかも?
C,R pinは シュミット指定してください。

BOM(部品表)とnet list(配線表)は以下
(説明のためのイメージです。実働試験はしていません)

== BOM :
FPGA: any
C0  :0.1uF
R0  :10kohm
C1  :10uF
R1  :1Mohm
PSW :push switch
LED0 :any
LED1 :any
LED2 :any
LED3 :any
LED4 :any
LED5 :any

== net list
FPGA.L[0],LE0.A
FPGA.L[1],LED1.A,LED6.A
FPGA.L[2],LED2.A,LED5.A
FPGA.L[3],LED3.A,LED4.A
FPGA.C,C0.A,R0.A
FPGA.X,R0.B
R1.B,PSW.B,C1.B
VCC,LED0.K,LED1.k,LED2.k,KLED3.k,LED4.K,LED5.K,LED6.K,R1.A
GND,C1.A,PSW.A,C0.B

結果

 Quartus prime Lite :18.1.0 625で、10M08DAF484C8G用にコンパイルして
LE:86 FF:32 fck max : 77.3MHzでした。んーかなり無理がある。

sim結果はこんなカンジです
f:id:mangakoji:20181122180119p:plain

テストベンチは以下。

`timescale 1ns/1ns
module TB (
) ;

    wire [31:0] Q ;
    wire [31:0] L ;
    wire        X ;
    wire #(1.0) C  = X ; //clock net feed, image CR delay
    reg         R ;
    D 
    D
    (
          .C    ( C )   //rise edge clock input schumit trigger
        , .R    ( R )   //H:dice stop L:dice roll ,schumit trigger
                        //connect pull up , and through push sw GND 
        , .X    ( X )   //invert out clock C
        , .Q    ( Q )   //dice face counter use [2:0] 0~5
        , .L    ( L )   //dice face use [6:0], H:On ,L:Off
                        // face patter,
                        // 1   2th bit
                        // 3 0 4
                        // 5   6
    ) ;
    wire [2:0] CTRs = Q[2:0] ;  //pick up dice face counter bit
    wire [6:0] LEDs = {         // dice face pattern make up 
          L[1]
        , L[2]
        , L[3]
        , L[3]
        , L[2]
        , L[1]
        , L[0]
    } ;
    // count light on LED dots
    function [31:0] f_count ;
        input [31:0] DATs ;
        integer i ;
    begin
        f_count = 0 ;
        for(i=0;i<32;i=i+1)
            f_count = f_count + DATs[i] ;
    end endfunction 
    wire [3:0] LIGHT_CTRs = f_count( LEDs ) ;


    initial
    begin
        R <= 1'b0 ;         // the dice roll on
        force C =1 ;        // innitial reg/wire , cancel unstable
        force D.C =1 ;      
        force D.Q = 0 ;
        #(2) 
        release C   ;       // auto running the circuit
        release D.C ;
        release D.Q ;
        #(100)
        R <= 1'b1 ;         // stop rolling 
        #(10)
        $stop ;
        $end ;
    end
endmodule

/* user radix face on Model sim
// copy after part to file DICE_FASE.tcl
// and load Modelsim.wave 
    // 1   2
    // 3 0 4
    // 5   6
8<----------cut from here -------------
radix define DICE_FACEs {
    6'b00_00_00_1 "1" -color red ,
    6'b01_00_10_0 "2" -color white ,
    6'b10_00_01_0 "2" -color white ,
    6'b01_00_10_1 "3" -color white ,
    6'b10_00_01_1 "3" -color white ,
    6'b11_00_11_0 "4" -color white ,
    6'b11_00_11_1 "5" -color white ,
    6'b11_11_11_0 "6" -color white ,
    -default binary
    -defaultcolor purple
} 
----------------- to here ----------->8
*/

simがmodelsimの場合後半のradix faceをインクルードすれば、それっぽい表示をしてくれます。

モジュロ(%)を6でなく12,48,96にして、LEDにつなぐpinをずらせば、すれば、動作中にサウンダーも鳴らせますね。1文字増えますが

問題

 このままだと、カウンタストップのR pinがマルチステーブル/ラッチミス問題を起こし、
変な表示をしそうですね。code GOLF hack版ということで。