SystemVerilog では string 型が使え、文字列操作もできるよ、という話です。
Motorola S-record 形式ファイルは、 モトローラ S レコードフォーマット などを参照。
こういったファイルをリードしたい場面は、仕様にきちんと対応する必要性はおそらくほとんどなく、たまたま S レコードフォーマットのファイルがあり、ライトアドレスとデータさえ読めれば OK という感じだと思います。
次はファイルから、S1 レコードタイプからアドレスとデータの取得し、S9 で処理の終了だけ対応したものです(実際に使ったものじゃないので、万一使うときはチェックしてください)。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
initial begin | |
int fd, ret; | |
string line; | |
int type_no, size; | |
bit [31:0] addr; | |
bit [7:0] data []; // dynamic array | |
fd = $fopen("./hexfile", "r"); | |
while (!$feof(fd)) begin | |
ret = $fgets(line, fd); // 1行リード | |
if (line.substr(0, 0) != "S") begin // S から始まらない場合次の行へ | |
continue; | |
end | |
type_no = line.substr(1, 1).atoi(); // レコードタイプ | |
size = line.substr(2, 3).atohex(); // レコード長 | |
case (type_no) | |
1: begin // S1 | |
// アドレス | |
addr = line.substr(4, 7).atohex(); | |
// データを 1byte ずつ処理 | |
data = new [size – 3]; // MEMO: データ長は (アドレス2byte + チェックサム1byte) を引いたサイズ | |
for (int i = 0; i < size – 3; i++) begin | |
data[i] = line.substr(8 + i * 2, 9 + i * 2).atohex(); // MEMO: 9文字目から2文字ずつ | |
end | |
$display("S1 addr: %2h", addr); | |
end | |
9: begin // S9 | |
$display("S9"); | |
break; | |
end | |
endcase | |
end | |
$fclose(fd); | |
end |
ポイントは、一部分の文字列の取得(substr)、文字列から数値へ変換(atoi、atohex など)や、$fgets で1行の長さ分だけの文字列が取得できてます(Verilog HDL では、string 型がなく固定長の reg 型変数を指定しかできません)。