13
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

FPGAでハードウェアアクセラレータを作る:①ワークメモリを作る

Last updated at Posted at 2017-10-21

まえおき

以前 投稿しました「Spartan6でmicroblaze mcs を動かす」にて、FPGA上でCPUを動作させることが可能になりました。

今後ハードウェアアクセラレータもどきを増築していきたいと思います。

#ハードウェアアクセラレータとは
ハードウェアアクセラレータとはCPUのバスにぶら下がっている専用の演算回路です。
特徴としては以下のようなメリットがあります。

  • 特定の演算処理をCPUに代わって行うハードウェア
  • CPUはアクセラレータに指示を投げて、結果だけをもう
  • アクセラレータが演算中、CPUは他の処理を行うことができる
  • 演算を並列処理できる(作り方次第)

構成

モジュールを以下のように構成します

IP_1.jpg

  • BUS I/F(バス信号のI/F)
  • メモリ(BlockRAM)のリードライトを行う
  • DualPortMEM
  • データを貯めるデュアルポートメモリ
  • AポートはCPUから読み書きできる
  • BポートはLogic部から読み書きできる
  • AポートとBポートは非同期クロック
  • Logic部(演算処理回路)
  • CPUからアクセスできる演算命令用のレジスタを実装する
  • 演算命令に応じてBRAMからデータを取り出し、演算結果をBRAMに書き戻す

今回作る回路

今回はBUS/Fとメモリの部分までを作成することとし、CPUからメモリに読み書きできることを目標にします。
(演算ロジック部分は次回の投稿にします)

CPU バス I/F

CPUバスからのシングルリード/ライトアクセスの概要
IP_2.jpg

Microblaze_MCSのポート名 図中の略称 機能 説明
IO_Addr_Strobe a_stb アドレスストローブ Hのときアドレスが有効
IO_Read_Strobe r_stb リードストローブ Hでリードを要求
IO_Write_Strobe w_stb ライトストローブ Hのときライトデータが有効
IO_Address adr アドレス アクセス先のアドレスを示す
Microblaze_mcsは0xC000_0000がバス空間の先頭アドレス
IO_Byte_Enable be バイトイネーブル 32bitバス(4Byte)のうちアクセス対象Byteを示す。
intでアクセス⇒1111
shortでアクセス⇒0011 or 1100
charでアクセス⇒0001 or 0010 or 0100 or 1000
IO_Write_Data w_dat ライトデータ 書き込みデータです
IO_Read_Data r_dat リードデータ リードストローブが来たらレディがHになる間だけ出力します。
そのほかはL固定(他のモジュールとワイヤーORで共有するので)
IO_Ready rdy レディ応答 リード時:有効なリードデータとともにアサート
ライト時:処理完了後アサート<※>Microblazeはレディが帰ってこないとハングアップするので要注意!!

RTL図

IP_3.jpg

ブロック 概要
入力FF バスの信号を一度叩くFFです
WriteContlorl ブロックRAMのライトイネーブル信号を生成します
上位アドレスがヒットしているBRAMに対してバイトイネーブルとライトストローブのANDを通します。
ReadContlorl 上位アドレスがヒットしているBRAMの出力を後段のセレクタでセレクトするための制御信号を生成します
BRAM メモリ本体です、BRAMを3面インスタンスしています。

VHDLコード

バスの信号を1つづつ毎回記述すると、回路を複製するときに記述が多くなるのは嫌です。
バスの信号はパッケージにユーザー定義型(C言語でいう構造体みたいなもの)に定義して記述しました。

BUS_IF_package.vhd
-----------------------------------------------------------
-- Microblaze_MCSのバス信号 型定義
-----------------------------------------------------------
library	ieee;
use	ieee.std_logic_1164.all;
	
package	BUS_IF_package is
	
	-------------------------------------------------------
	--バス リクエスト(CPU => IP)
	-------------------------------------------------------
	--型定義
	type t_BUS_REQ is record
		a_stb	:std_logic						;--Address Strobe
		adr		:std_logic_vector(31 downto 0)	;--Address
		w_stb	:std_logic						;--Write Strobe
		w_dat	:std_logic_vector(31 downto 0)	;--Write Data
		be		:std_logic_vector(3 downto 0)	;--Byte Enable
		r_stb	:std_logic						;--Read Strobe
	end record;
	
	--配列
	type ta_BUS_REQ
		is array(integer range <>) of t_BUS_REQ;
		
	--初期値
	constant t_BUS_REQ_ini	:t_BUS_REQ:=('0',x"00000000",'0',x"00000000","0000",'0');
		
	-------------------------------------------------------
	--バス レスポンス(COU <= IP)
	-------------------------------------------------------
	--型定義
	type t_BUS_RES is record
		rdy		:std_logic						;--Ready
		r_dat	:std_logic_vector(31 downto 0)	;--Read Data
	end record;
	
	--配列
	type ta_BUS_RES
		is array(integer range <>) of t_BUS_RES; 
	
	--初期値
	constant t_BUS_RES_ini	:t_BUS_RES	:=('0',x"00000000");
	
end package;
BUS_IF.vhd
--------------------------------------------------------------------
-- CPUバスにぶら下げるワークメモリ
-- DualPortRAM(32bit×512)を2面インスタンスしている
-- 
-- ※今後RAMのデータを演算するロジックを追加して演算アクセラレータにする
--	------------+--------------------
--	BA + 0x0800	|ワークメモリA面
--		:		|
--	BA + 0x07FF	|
--	------------+--------------------
--	BA + 0x0800	|ワークメモリB面
--		:		|
--	BA + 0x0FFF	|
--	------------+--------------------
--	BA + 0x1000	|ワークメモリC面
--		:		|
--	BA + 0x17FF	|
--	------------+--------------------
--	BA + 0x1000	|ロジック領域
--		:		|(演算命令レジスタ)
--	BA + 0x17FF	|※今後追加
--------------------------------------------------------------------
library	ieee;
use	ieee.std_logic_1164.all;
use	ieee.std_logic_unsigned.all;

use	work.BUS_IF_package.all;--CPUバスをまとめたType宣言を読み込む
	
	entity BUS_IF is
		generic(
		BASE_ADR	:std_logic_vector(31 downto 0)		);--ベースアドレス
		port(
		i_rst		:in		std_logic					;--リセット
		i_bus_clk	:in		std_logic					;--クロック
		i_bus		:in		t_BUS_REQ					;--CPU_BUS
		o_bus		:out	t_BUS_RES					);--CPU_BUS
	end	entity;
	
architecture rtl of BUS_IF is
	constant	N	:integer	:=2;--メモリインスタンス数-1
	-----------------------------------------------------------------
	-- Type
	-----------------------------------------------------------------
	--ライトイネーブルをアレイにした型定義
	type typ_WEA is 
		array(integer range <>) of std_logic_vector(3 downto 0);
	--BRAM出力データのアレイ型
	type typ_DOUT is 
		array(integer range <>) of std_logic_vector(31 downto 0);
	-----------------------------------------------------------------
	-- Signal
	-----------------------------------------------------------------
	--入力FF
	signal	be		:std_logic_vector(3 downto 0)	:=(others=>'0')	;
	signal	adr		:std_logic_vector(31 downto 0)	:=(others=>'0')	;
	signal	w_stb	:std_logic						:='0'			;
	signal	w_dat	:std_logic_vector(31 downto 0)	:=(others=>'0')	;
	signal	r_stb	:std_logic						:='0'			;
	--
	signal	rd_cnt	:std_logic_vector(0 to N)		:=(others=>'0')	;
	signal	r_valid	:std_logic_vector(0 to N)		:=(others=>'0')	;
	--
	signal	rdy_or	:std_logic										;
	signal	rdy		:std_logic						:='0'			;
	signal	r_dat	:std_logic_vector(31 downto 0)	:=(others=>'0')	;
	signal	hit_mem	:std_logic_vector(0 to N)						;
	--Memory I/F
	signal	rsta	:std_logic_vector(N downto 0)	:=(others=>'0')	;
	--Memory I/F(A side)
	signal	wea		:typ_WEA(0 to N)				:=(others=>x"0");
	signal	addra	:std_logic_vector(8 downto 0)					;
	signal	dina	:std_logic_vector(31 downto 0)					;
	signal	douta	:typ_DOUT(0 to N)							;
	--Memory I/F(B side)
	signal	web		:std_logic_vector(3 downto 0)	:=(others=>'0')	;
	signal	addrb	:std_logic_vector(8 downto 0)	:=(others=>'0')	;
	signal	dinb	:std_logic_vector(31 downto 0)	:=(others=>'0')	;
	signal	doutb	:typ_DOUT(0 to N)								;
	
begin	
	
	---------------------------------------
	--CPUバスインターフェース
	---------------------------------------
	process(i_bus_clk)begin
		if(Rising_edge(i_bus_clk))then
			------------------------
			--Stage1:入力信号受けFF
			------------------------
			--アドレス
			if(i_bus.a_stb='1')then
				adr	<=i_bus.adr;
			end if;
			--バイトイネーブル
			be(0)	<=i_bus.be(0);
			be(1)	<=i_bus.be(1);
			be(2)	<=i_bus.be(2);
			be(3)	<=i_bus.be(3);
			--ライトストローブ
			w_stb	<=i_bus.w_stb;
			--ライトデータ
			if(i_bus.w_stb='1')then
				w_dat	<=i_bus.w_dat;
			end if;
			--リードストローブ
			r_stb	<=i_bus.r_stb;
			
			--------------------------
			--Stage2:
			--------------------------
			--メモリリードデータ有効
			r_valid	<=rd_cnt;
			
			--------------------------
			--Stage3
			--------------------------
			--読み出しデータ
			case(r_valid)is
				when "100"	=>r_dat	<=douta(0);--A面
				when "010"	=>r_dat	<=douta(1);--B面
				when "001"	=>r_dat	<=douta(2);--C面
				when others	=>r_dat	<=(others=>'0');--応答時以外0固定
			end case;
			
			--レディ応答
			rdy		<=rdy_or;
		end if;
	end process;
	
	---------------------------------------
	--メモリアクセス制御
	---------------------------------------
	MEM_CONTLORL:for i in 0 to N generate
		--アドレス上位ヒット判定
		hit_mem(i)	<='1' when (adr(31 downto 11)=BASE_ADR(31 downto 11)+i)else '0';
		
		--ライトコントロール
		wea(i)	<=be when (hit_mem(i)='1') and (w_stb='1') else "0000";
		
		--リードコントロール
		rd_cnt(i)	<='1' when (hit_mem(i)='1') and (r_stb='1') else '0';
	end generate;
	
	--レディ応答条件
	rdy_or	<='1' when 
		(r_valid/="000" ) or
		(wea(0) /="0000") or
		(wea(1) /="0000") or
		(wea(2) /="0000") else '0';

	--BRAM物理アドレス:512word =>9bit分接続 (1word = 4Byteなので下位2bitは捨て)
	addra(8 downto 0)	<=adr(10 downto 2);
	
	--BRAMライトデータ:32bitそのまま接続
	dina(31 downto 0)	<=w_dat(31 downto 0);
	
	--2KByte(32bit×512)デュアルポートメモリ(2面インスタンス)
	MEM:for i in 0 to N generate
		mWORK_MEM:entity work.WORK_MEM
		port map
		--A port(CPU side)-------
		(clka	=>i_bus_clk
		,rsta	=>rsta(i)	
		,wea	=>wea(i)	
		,addra	=>addra		
		,dina	=>dina		
		,douta	=>douta(i)	
		--B port(Logic side)-----
		,clkb	=>i_bus_clk		--未使用
		,web	=>"0000"		--未使用
		,addrb	=>"000000000"	--未使用
		,dinb	=>x"00000000"	--未使用
		,doutb	=>doutb(i)		--未使用
		);
	end generate;
	
	--Output Port
	o_bus.rdy	<=rdy	;
	o_bus.r_dat	<=r_dat	;
	
end architecture;

検証用ソフト

検証用のCのコードを作成します。

検証内容|検証目的
---|---|---
char,short,int型のサイズを調べる| 32bbitバスなのでint=4Byteのはずだけど本当か?
BRAM3面分の初期値を読みだす|書き込む前の値を確認する
RAM-A面にcharでインクリメントデータを書き込む|1Byte毎にインクリメントしているはず
RAM-B面にshortでインクリメントデータを書き込む|2Byte毎にインクリメントしているはず
RAM-C面にintでインクリメントデータを書き込む|4Byte毎にインクリメントしているはず
3つのRAMをすべてcharで読みだす|上記3つの「~Byte毎にインクリメントしているはず」が正しいか確認

main.c
#include "platform.h"		//とりあえず必要
#include "mb_interface.h"	//とりあえず必要
#include "ADR_MAP.h"		//自前のヘッダファイル

//ASCIIコードのバイナリ定義
	#define	BS		0x08	//バックスペース
	#define	CR		0x0D	//復帰
	#define	LF		0x0A	//改行
	#define	ESC		0x1B	//エスケープ

//-----------------------------
//グローバル変数
//-----------------------------
	unsigned char g_led=0x7F;

//-------------------------------------------------------------------------------
//割込みハンドラ
//-------------------------------------------------------------------------------
void Int_Handl(void) {
	unsigned char msg;
	int i;
	unsigned char p=0;
	unsigned char n;
	
	//割り込みフラグ落とす
	IRQ_ACK = 0xFFFFFFFF;

	//受信文字を持ってくる
	msg=UART_RX;

	//エコーバック
	xil_printf("%c",msg);
	
	//受信文字に応じた処理
	switch(msg){
		case CR://エンター
			//LEDをインクリメント
			g_led++;
			GPO1=g_led;
			break;
		case BS://バックスペース
			//LEDをデクリメント
			g_led--;
			GPO1=g_led;
			break;
		default://
			//なにもしない
			break;
	}//switch
}
//============================================================
//256Byte読み出し:char型
//============================================================
void ReaderChar(unsigned char* StartPoint){
	unsigned int	i , j;
	unsigned char*	pt;

	pt = StartPoint;
	xil_printf("----------------------------------------------------------\r");
	xil_printf(" Char Read : Start Addres = 0x%08X\r",pt);
	xil_printf("----------------------------------------------------------\r");
	xil_printf("  Address |+0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F\r");
	for(i=0; i<16; i++){
		xil_printf("0x%04X|",pt);
		for(j=0; j<16; j++){
			xil_printf("%02X ",*pt);
			pt++;
		}
		xil_printf("\r");
	}
}
//============================================================
//256Byte読み出し:short型
//============================================================
void ReaderShort(unsigned short* StartPoint){
	unsigned int	i , j;
	unsigned short*	pt;

	pt = StartPoint;
	xil_printf("--------------------------------------------------\r");
	xil_printf(" Short Read : Start Addres = 0x%08X\r",pt);
	xil_printf("--------------------------------------------------\r");
	xil_printf("  Address | +0   +2   +4   +6   +8   +A   +C   +E \r");
	for(i=0; i<16; i++){
		xil_printf("0x%04X|",pt);
		for(j=0; j<8; j++){
			xil_printf("%04X ",*pt);
			pt++;
		}
		xil_printf("\r");
	}
}
//============================================================
//256Byte読み出し:int型
//============================================================
void ReaderInt(unsigned int* StartPoint){
	unsigned int	i , j;
	unsigned int*	pt;

	pt = StartPoint;
	xil_printf("----------------------------------------------\r");
	xil_printf(" Int Read : Start Addres = 0x%08X\r",pt);
	xil_printf("----------------------------------------------\r");
	xil_printf("  Address |   +0       +4       +8       +C\r");
	for(i=0; i<16; i++){
		xil_printf("0x%04X|",pt);
		for(j=0; j<4; j++){
			xil_printf("%08X ",*pt);
			pt++;
		}
		xil_printf("\r");
	}
}
//============================================================
//256Byteゼロフィル
//============================================================
void ZeroClear(unsigned int* StartPoint){
	unsigned int	i;
	unsigned int*	pt;
	pt = StartPoint;
	xil_printf("-----------------------------------------\r");
	xil_printf(" Zero clear : Start Addres = 0x%08X\r",pt);
	xil_printf("-----------------------------------------\r");
	for(i=0; i<256; i++){
		*pt=0;
		pt++;
	}
}
//============================================================
//メインループ
//============================================================
void main()
{
	unsigned int*		start_adr=0;
	unsigned int		i=0;
	unsigned char* 		pt_c;//
	unsigned short* 	pt_s;//
	unsigned int* 		pt_i;//

	//================================================
	//ハードの初期化
    	init_platform();
    //割込みハンドラの登録
    	microblaze_register_handler((XInterruptHandler)Int_Handl,(void*)0);
	//使用する割込み選択(bit[2]⇒UART割り込み)
    	IRQ_ENABLE = 0x00000004;
    //割り込みを有効にする
    	microblaze_enable_interrupts();
    //================================================
	
	xil_printf("*******************\r");
	xil_printf("Start!!\r");
	xil_printf("Size of char =%d\r",sizeof(unsigned char));
	xil_printf("Size of short=%d\r",sizeof(unsigned short));
	xil_printf("Size of int  =%d\r",sizeof(unsigned int));
	xil_printf("Size of long =%d\r",sizeof(unsigned long));
	xil_printf("*******************\r");

	//初期値読み出し
	start_adr=0xC0000000;
		ReaderChar(0xC0000000);		//A面
		ReaderShort(0xC0000800);	//B面
		ReaderInt(0xC0001000);		//C面
	///////////////////////////////////////
	//メモリAにキャラで書き込み
	xil_printf("Write increment dta\r");
	pt_c=0xC0000000;
	pt_s=0xC0000800;
	pt_i=0xC0001000;

	for(i=0; i<256; i++){
		*pt_c = (unsigned char)i;
		pt_c++;
	}
	//メモリBにショート型で書き込み
	for(i=0; i<128; i++){
		*pt_s = (unsigned short)i;
		pt_s++;
	}
	//メモリCにイントき込み
	for(i=0; i<64; i++){
		*pt_i = (unsigned int)i;
		pt_i++;
	}
	///////////////////////////////////////

	//読み出し(あえて全部キャラで読む)
		ReaderChar(0xC0000000);	//A面
		ReaderChar(0xC0000800);	//B面
		ReaderChar(0xC0001000);	//C面

	//--------------------------------------------
	//メインループ
	//--------------------------------------------
    while(1){

    }
	
}

実機検証結果

ターミナルのログを確認しました。

  • intは4byte、shortは2byteでした想定通りの動作でした。
  • charで読みだした結果、Byte単位でLSBファーストでした。
*******************
Start!!
Size of char =1
Size of short=2
Size of int  =4
Size of long =4
*******************
----------------------------------------------------------
 Char Read : Start Addres = 0xC0000000
----------------------------------------------------------
  Address |+0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F
0xC0000000|00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0xC0000010|00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0xC0000020|00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0xC0000030|00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0xC0000040|00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0xC0000050|00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0xC0000060|00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0xC0000070|00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0xC0000080|00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0xC0000090|00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0xC00000A0|00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0xC00000B0|00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0xC00000C0|00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0xC00000D0|00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0xC00000E0|00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0xC00000F0|00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
--------------------------------------------------
 Short Read : Start Addres = 0xC0000800
--------------------------------------------------
  Address | +0   +2   +4   +6   +8   +A   +C   +E
0xC0000800|0000 0000 0000 0000 0000 0000 0000 0000
0xC0000810|0000 0000 0000 0000 0000 0000 0000 0000
0xC0000820|0000 0000 0000 0000 0000 0000 0000 0000
0xC0000830|0000 0000 0000 0000 0000 0000 0000 0000
0xC0000840|0000 0000 0000 0000 0000 0000 0000 0000
0xC0000850|0000 0000 0000 0000 0000 0000 0000 0000
0xC0000860|0000 0000 0000 0000 0000 0000 0000 0000
0xC0000870|0000 0000 0000 0000 0000 0000 0000 0000
0xC0000880|0000 0000 0000 0000 0000 0000 0000 0000
0xC0000890|0000 0000 0000 0000 0000 0000 0000 0000
0xC00008A0|0000 0000 0000 0000 0000 0000 0000 0000
0xC00008B0|0000 0000 0000 0000 0000 0000 0000 0000
0xC00008C0|0000 0000 0000 0000 0000 0000 0000 0000
0xC00008D0|0000 0000 0000 0000 0000 0000 0000 0000
0xC00008E0|0000 0000 0000 0000 0000 0000 0000 0000
0xC00008F0|0000 0000 0000 0000 0000 0000 0000 0000
----------------------------------------------
 Int Read : Start Addres = 0xC0001000
----------------------------------------------
  Address |   +0       +4       +8       +C
0xC0001000|00000000 00000000 00000000 00000000
0xC0001010|00000000 00000000 00000000 00000000
0xC0001020|00000000 00000000 00000000 00000000
0xC0001030|00000000 00000000 00000000 00000000
0xC0001040|00000000 00000000 00000000 00000000
0xC0001050|00000000 00000000 00000000 00000000
0xC0001060|00000000 00000000 00000000 00000000
0xC0001070|00000000 00000000 00000000 00000000
0xC0001080|00000000 00000000 00000000 00000000
0xC0001090|00000000 00000000 00000000 00000000
0xC00010A0|00000000 00000000 00000000 00000000
0xC00010B0|00000000 00000000 00000000 00000000
0xC00010C0|00000000 00000000 00000000 00000000
0xC00010D0|00000000 00000000 00000000 00000000
0xC00010E0|00000000 00000000 00000000 00000000
0xC00010F0|00000000 00000000 00000000 00000000
Write increment dta
----------------------------------------------------------
 Char Read : Start Addres = 0xC0000000
----------------------------------------------------------
  Address |+0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F
0xC0000000|00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
0xC0000010|10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F
0xC0000020|20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F
0xC0000030|30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
0xC0000040|40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F
0xC0000050|50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F
0xC0000060|60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F
0xC0000070|70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F
0xC0000080|80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F
0xC0000090|90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F
0xC00000A0|A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF
0xC00000B0|B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF
0xC00000C0|C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF
0xC00000D0|D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF
0xC00000E0|E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF
0xC00000F0|F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF
----------------------------------------------------------
 Char Read : Start Addres = 0xC0000800
----------------------------------------------------------
  Address |+0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F
0xC0000800|00 00 01 00 02 00 03 00 04 00 05 00 06 00 07 00
0xC0000810|08 00 09 00 0A 00 0B 00 0C 00 0D 00 0E 00 0F 00
0xC0000820|10 00 11 00 12 00 13 00 14 00 15 00 16 00 17 00
0xC0000830|18 00 19 00 1A 00 1B 00 1C 00 1D 00 1E 00 1F 00
0xC0000840|20 00 21 00 22 00 23 00 24 00 25 00 26 00 27 00
0xC0000850|28 00 29 00 2A 00 2B 00 2C 00 2D 00 2E 00 2F 00
0xC0000860|30 00 31 00 32 00 33 00 34 00 35 00 36 00 37 00
0xC0000870|38 00 39 00 3A 00 3B 00 3C 00 3D 00 3E 00 3F 00
0xC0000880|40 00 41 00 42 00 43 00 44 00 45 00 46 00 47 00
0xC0000890|48 00 49 00 4A 00 4B 00 4C 00 4D 00 4E 00 4F 00
0xC00008A0|50 00 51 00 52 00 53 00 54 00 55 00 56 00 57 00
0xC00008B0|58 00 59 00 5A 00 5B 00 5C 00 5D 00 5E 00 5F 00
0xC00008C0|60 00 61 00 62 00 63 00 64 00 65 00 66 00 67 00
0xC00008D0|68 00 69 00 6A 00 6B 00 6C 00 6D 00 6E 00 6F 00
0xC00008E0|70 00 71 00 72 00 73 00 74 00 75 00 76 00 77 00
0xC00008F0|78 00 79 00 7A 00 7B 00 7C 00 7D 00 7E 00 7F 00
----------------------------------------------------------
 Char Read : Start Addres = 0xC0001000
----------------------------------------------------------
  Address |+0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F
0xC0001000|00 00 00 00 01 00 00 00 02 00 00 00 03 00 00 00
0xC0001010|04 00 00 00 05 00 00 00 06 00 00 00 07 00 00 00
0xC0001020|08 00 00 00 09 00 00 00 0A 00 00 00 0B 00 00 00
0xC0001030|0C 00 00 00 0D 00 00 00 0E 00 00 00 0F 00 00 00
0xC0001040|10 00 00 00 11 00 00 00 12 00 00 00 13 00 00 00
0xC0001050|14 00 00 00 15 00 00 00 16 00 00 00 17 00 00 00
0xC0001060|18 00 00 00 19 00 00 00 1A 00 00 00 1B 00 00 00
0xC0001070|1C 00 00 00 1D 00 00 00 1E 00 00 00 1F 00 00 00
0xC0001080|20 00 00 00 21 00 00 00 22 00 00 00 23 00 00 00
0xC0001090|24 00 00 00 25 00 00 00 26 00 00 00 27 00 00 00
0xC00010A0|28 00 00 00 29 00 00 00 2A 00 00 00 2B 00 00 00
0xC00010B0|2C 00 00 00 2D 00 00 00 2E 00 00 00 2F 00 00 00
0xC00010C0|30 00 00 00 31 00 00 00 32 00 00 00 33 00 00 00
0xC00010D0|34 00 00 00 35 00 00 00 36 00 00 00 37 00 00 00
0xC00010E0|38 00 00 00 39 00 00 00 3A 00 00 00 3B 00 00 00
0xC00010F0|3C 00 00 00 3D 00 00 00 3E 00 00 00 3F 00 00 00

今後は、演算処理を追加してゆきたいと思います。

13
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?