開発日記

Erlangをダラダラ書きます。

メモリとHexファイルの話

FPGAを触っていると,バイナリをHexファイルに変換して読み込みたいときがある.

(例えば,RISC-Vを自作しているときとか..FPGA内蔵メモリにHexファイルを埋め込みたい..

今回は32bit命令を扱うメモリを例に考える.

Hexファイルの形式

1. 1行4バイト

1行4バイトで作成したHexファイルをメモリに埋め込んだとき,このメモリにはどうアクセスする?

32bit命令の例:

命令1
0   00912a23
---------------------------------------
命令2
1   02010413
--------------------------------------
命令3
2   fea42623
--------------------------------------
3   fec42703
4   00100793
5   00e7c663
 .
 .

PCは基本的には4ずつカウントアップする.(ちなみにPCは現在実行している命令のメモリアドレスが格納されている.)

このPCに合わせてアクセスすると3行分の命令を毎回飛ばしてしまう.それは困る.

実装1
  • PCに格納されているアドレスの下位2ビットを無視することで,本来 0 -> 4 -> 8 -> 12 ... となるPCを 0 -> 1 -> 2 -> 3 ... と解釈できる.これでメモリ内の命令を読み飛ばすことはなくなる.よし.
inst <= mem[pc[ADDR_SIZE:2]];

2. 1行1バイト

1行1バイトで作成したHexファイルをメモリに埋め込んだとき,このメモリにはどうアクセスする?

32bit命令の例:

命令1
0   00
1   91
2   2a
3   23
---------------------------
命令2
4   02
5   01
6   04
7   13
 .
 .

PCは現在実行している命令のメモリアドレスの先頭を指している.0番地を指しているときは「0番地, 1番地, 2番地, 3番地」で32bit命令を作りたい.

実装2
  • PCからのオフセットを用いて32bit命令を作成する.

  • トルエンディアンの場合, メモリアドレスの先頭は「LSB」であることに注意.つまり3番地から順番にビット連接する.

リトルエンディアンの場合:
inst <= { mem[pc+3], mem[pc+2], mem[pc+1], mem[pc] };