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

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

1bit CPU BPU(Bit Processor Unit) 1984年エレクトロニクス実務シリーズ復刻版より

先日、アキバの書泉ブックタワーで見かけた復刻版です。中が見えなかったんですが、誘われてる気がしたので衝動買しました。結果的には当たりでしたね。

shop.cqpub.co.jp

 

本書には、「ビット処理システム」(BPU)言うなれば、1bit CPUとも言うべきシーケンサ、コントローラが載ってます。

曰く「小規模なディジタル・システムを設計するとき,データの流れや演算,メモリといった部分は比較的すんなり行っても,全体のコントロール・タイミングを作るのには苦労します.一様な動きならまだしも、複雑に条件がからむ動作は、特に一筋縄ではいきません。ゲートとFFをあちこちに繋いで何度も更新しても、ちゃんと動いてくれないという経験は筆者だけではないと思います。

 ランダム・ゲートとFFで順序回路を組んでいたら大変だということで、PLAが出現しました。しかし、市場に出回っているPLAは入出力が少なく、小さなシステムでも数個使用したり、外部にデコーダ、カウンタ、ラッチなどを必要とし、容量を超えたら、お手上げ、というわけで、2~30bitの入力と出力をbit単位で制御出来る、統一手法はないものかと長年考えていました。その結果がここに紹介するビット処理システムです。」

ということで、最小構成と、何種類かの拡張システムが紹介されいます。

 

基本システムで8bit x 128wordのプログラムROMにつながる7bitカウンタと

フラグと呼ばれるAND項を持ったアキュムレータ、最大64bit入力セレクタ、最大64bitのセレクトラッチを持つシステムで、

オペコードはたったの3種類、入力/出力/ジャンプだけです。

 

実際の構成をVerilogHDLで書き起こすとこんなカンジ。

//BPU(Bit Processor Unit)
// form 復刻版 ディジタル回路設計ノウハウ【オンデマンド版】CQ出版
// https://shop.cqpub.co.jp/hanbai/books/52/52181.html
//write VerilogHDL 2023-10-28sa
//
`default_nettype none
module BPU
(    input wire         CLK_H_i
    ,input wire         INIT_L_i
    ,input wire [31:0]  GPIs_i 
    ,output wire[31:0]  GPOs_o
) ;
    wire[ 4:0]  PAs ;
    wire IND_H = GPIs_i[ PAs ] ;
    wire[ 7:0]  MDs ;
    wire[ 6:0]  MAs ;
    wire        OUTD_H ;
    wire        STB_L ;
    BPU_CORE
        BPU_CORE
        (    .CLK_H_i                   ( CLK_H_i   )
            ,.INIT_L_i                  ( INIT_L_i  )
            ,.IND_H_i                   ( IND_H     )
            ,.MDs_i                     ( MDs       )
            ,.MAs_o                     ( MAs       )
            ,.PAs_o                     ( PAs       )
            ,.OUTD_H_o                  ( OUTD_H    )
            ,.STB_L_o                   ( STB_L     )
        ) 
    ;
    reg[31:0]GPOs ;
    always@(posedge CLK_H_i or negedge INIT_L_i)
        if( ~ INIT_L_i )    GPOs <= 0 ;
        else
            if( ~ STB_L )   GPOs[ PAs ] <= OUTD_H ;
    assign GPOs_o = GPOs ;
    BPU_PGMEM
        BPU_PGMEM
        (    .ADRs_i                    ( MAs       )
            ,.DATs_o                    ( MDs       )
        )
    ;
endmodule

module BPU_CORE
(    input wire         CLK_H_i
    ,input wire         INIT_L_i
    ,input wire         IND_H_i
    ,input wire [ 7:0]  MDs_i
    ,output wire[ 6:0]  MAs_o
    ,output wire[ 4:0]  PAs_o
    ,output wire        OUTD_H_o
    ,output wire        STB_L_o
) ;
    reg[ 6:0]   MAs_a   ;
    reg[ 6:0]   MAs     ;
    reg         FLG_a   ;
    reg         FLG     ;
    wire PP = MDs_i[5]  ;
    assign OUTD_H_o = PP;
    reg         STB_L ;
    assign STB_L_o = STB_L ;
    always@(MAs,MDs_i,FLG,PP,IND_H_i)
    begin
                                MAs_a = MAs + 1 ;
                                FLG_a = FLG;
                                STB_L = 1'b1 ;
        casex( MDs_i[7:6] )
            2'b00:  //out cmd
                    if( ~ FLG )   STB_L = 1'b0 ;
            2'b01:  //in cmd
                    if(PP!=IND_H_i) FLG_a = 1'b1 ;
            2'b1x:  //jp cmd
                begin
                                FLG_a = 1'b0 ;
                    if(~ FLG)   MAs_a = MDs_i[ 6:0] ;
                end
        endcase
    end
    always@(posedge CLK_H_i or negedge INIT_L_i)
    if( ~ INIT_L_i)
    begin   FLG <= 1'b0 ;
            MAs <= 0 ;
    end else
    begin
            FLG <= FLG_a ;
            MAs <= MAs_a ;
    end
    assign MAs_o = MAs ;
    assign PAs_o = MDs_i[ 4:0];
endmodule


module BPU_PGMEM            //8bit x 128 word (1024bit)
(    input wire [ 6:0] ADRs_i
    ,output wire[ 7:0] DATs_o
) ;
    reg[ 7:0]DATs ;
    always@( ADRs_i )
        case( ADRs_i )
            7'h00: DATs  = 8'b00_10_0000 ;
            7'h01: DATs  = 8'b00_10_0001 ;
            7'h02: DATs  = 8'b00_10_0010 ;
            7'h03: DATs  = 8'b00_10_0011 ;
            7'h04: DATs  = 8'b00_10_0100 ;
            7'h05: DATs  = 8'b00_10_0101 ;
            7'h06: DATs  = 8'b00_10_0110 ;
            7'h07: DATs  = 8'b00_10_0111 ;
            7'h08: DATs  = 8'b00_10_1000 ;
            7'h09: DATs  = 8'b00_10_1001 ;
            7'h0A: DATs  = 8'b00_10_1010 ;
            7'h0B: DATs  = 8'b00_10_1011 ;
            7'h0C: DATs  = 8'b00_10_1100 ;
            7'h0D: DATs  = 8'b00_10_1101 ;
            7'h0E: DATs  = 8'b00_10_1110 ;
            7'h0F: DATs  = 8'b00_10_1111 ;
            7'h10: DATs  = 8'b00_00_0000 ;
            7'h11: DATs  = 8'b00_00_0001 ;
            7'h12: DATs  = 8'b00_00_0010 ;
            7'h13: DATs  = 8'b00_00_0011 ;
            7'h14: DATs  = 8'b00_00_0100 ;
            7'h15: DATs  = 8'b00_00_0101 ;
            7'h16: DATs  = 8'b00_00_0110 ;
            7'h17: DATs  = 8'b00_00_0111 ;
            7'h18: DATs  = 8'b00_00_1000 ;
            7'h19: DATs  = 8'b00_00_1001 ;
            7'h1A: DATs  = 8'b00_00_1010 ;
            7'h1B: DATs  = 8'b00_00_1011 ;
            7'h1C: DATs  = 8'b00_00_1100 ;
            7'h1D: DATs  = 8'b00_00_1101 ;
            7'h1E: DATs  = 8'b00_00_1110 ;
            7'h1F: DATs  = 8'b00_00_1111 ;
            7'h20: DATs  = 8'b01_00_0000 ;//GPI[0]!=0->F<=1
            7'h21: DATs  = 8'b10_10_0000 ;//~F?jump $20
            7'h22: DATs  = 8'b10_00_0000 ;//jp 0
            default: DATs  = 8'b10_00_0000 ;
        endcase
    assign DATs_o = DATs ;
endmodule