「Tang Nano」にインテル系IDEで開発したオリジナルCPUのソースコードを移植するオリジナルCPUでバイナリコード入門(5)(2/2 ページ)

» 2023年06月23日 07時00分 公開
[今岡通博ITmedia]
前のページへ 1|2       

メモリ機能

 前ページで示したリストは、CPUにおける命令をフェッチしてデコードし実行するコードです。命令をフェッチするのはよいのですが、その命令はどこに格納されているのでしょうか。それはメモリですよね。このメモリ機能はCPU内には含まれませんので別途記述する必要があります。このようにCPUとメモリとは別モジュールとして記述しています。リスト3は、メモリをVerilog-HDLで記述したコードになります。

module ram(clk, we, r_addr, r_data, w_addr, w_data); 
    input clk, we;
    input  [7:0] r_addr, w_addr;
    input  [7:0] w_data;
    output [7:0] r_data;
    reg [7:0] mem [15:0];     
    initial begin
        mem[0] <= 8'b01100_110;// inc R6		
        mem[1] <= 8'b1001_0000;// jmp 0
    end
    always @(posedge clk) begin
        if(we) mem[w_addr] <= w_data; 
    end
    assign r_data = mem[r_addr];
endmodule
リスト3 メモリ機能のソースコード

 module行でこのモジュールの名前と入出力を定義しています。このメモリは読み書き可能な機能があるので、weやw_addr、w_dataがありますが、今回は読み出しのみの用途で使っていますので、これらの入出力インタフェースは使っていません。initial beginで囲まれている2行があらかじめこのメモリに書き込まれているコードです(これらについては後述します)。

トップモジュールとその役割

 リスト4はトップモジュールであるtestbenchのソースコードです。

module testbench( input clk, input rst, output [3:0]leds);
    wire  [7:0] w_data;
       wire  [7:0] r_data;
    wire  [3:0] adr;
    wire  [3:0] leds;
    wire  [3:0] led;
    assign leds[0] = !led[0];
    assign leds[1] = !led[1];
    assign leds[2] = !led[2];
    assign leds[3] = !led[3];
    reg [23:0] counter;
    ram ram1(counter[23], 0, {4'b0000,adr}, r_data, adr, w_data);  
    cpu cpu1(rst,counter[23],btn,led,adr,r_data);
    always @(posedge clk or negedge rst) begin
        if (!rst)
            counter <= 0;
        else counter <= counter + 1;
    end
endmodule
リスト4 testbenchのソースコード

 このモジュールは3つあるモジュールの中の最上位モジュールです。他の下位のモジュールで定義されている入出力の関連付けを行います。ここではCPUとメモリをつないでいます。

 もう1つの役割は、これらのコードを実装するハードウェア環境とのインタフェースを定義しています。この場合ですと、クロック入力、リセットボタン、それと4つのLEDへの接続です。Tang Nanoに搭載されている水晶発振器の周波数は27MHzでこれを基にクロック信号が生成されます。この発信周波数を24分周したものをCPUとメモリに提供しています。

 ですからCPUは1秒間に1サイクル前後のクロックで動作します。リセットボタンはUSBコネクター脇の白いタクトスイッチをアサインしています。CPUからの出力である4つのLEDはTang Nanoの基板に搭載されている6つのLEDの内4つを割り当てています。図1は、Tang Nanoのボード上のリセットボタンの位置とLEDの位置を示しています。

図1 「Tang Nano」のボード上におけるリセットボタンとLEDの位置 図1 「Tang Nano」のボード上におけるリセットボタンとLEDの位置[クリックで拡大]

物理制約条件ファイル

 リスト5は物理制約条件ファイル(Physical Constraints file)の中身を示しています。クロックのピン番号、リセットボタンのピン番号そして4つのLEDのピン番号を指定しています。

IO_LOC "clk" 52;
IO_LOC "rst" 4;
IO_LOC "leds[0]" 10;
IO_LOC "leds[1]" 11;
IO_LOC "leds[2]" 13;
IO_LOC "leds[3]" 14;
リスト5 物理制約条件ファイル

サンプルプログラムと動作確認

 リスト6はあらかじめメモリに書き込まれているサンプルプログラムです。CPUが起動するとこのプログラムが動作します。

mem[0] <= 8'b01100_110;// inc R6		
mem[1] <= 8'b1001_0000;// jmp 0
リスト6 サンプルプログラム

 このサンプルプログラムはメモリモジュール(ram.v)のinitial blockに定義されています。メモリの0番地にinc R6、メモリの1番地にjmp 0が書き込まれています。このプログラムが動作するとr6が0から15まで1つずつ加算されます。R6は4つのLEDに直結されるレジスタですので、クロックを刻むごとに加算された値がTang Nanoの基板上のLEDに反映されます。図2はこのサンプルプログラムが動作しているところです。R6の値を示すオレンジのLEDの幾つかが点灯しているのが分かります。

図2 「Tang Nano」でDL166のサンプルプログラムが動作している様子 図2 「Tang Nano」でDL166のサンプルプログラムが動作している様子[クリックで拡大]

おわりに

 今回はインテル系のFPGAのIDEでコーディングしたVerilog-HDLのソースコードをGOWINのIDEで開発できるよう移植作業を行いました。短いコードですがTang NanoでDL166が動作することが確認できました。本稿では言及していませんが、Tang Nano用に手を加えたソースコードはインテルのIDEに同梱されているModelSimでも動作を確認しています。

 そろそろTang Nanoでバイナリコーディングの演習を行いたいところですが、そのためにはもう少し機能を追加せねばなりません。あと少しお付き合いいただければと思います。

前のページへ 1|2       

Copyright © ITmedia, Inc. All Rights Reserved.