SystemVerilog では string 型が使え、文字列操作もできるよ、という話です。
Motorola S-record 形式ファイルは、 モトローラ S レコードフォーマット などを参照。
こういったファイルをリードしたい場面は、仕様にきちんと対応する必要性はおそらくほとんどなく、たまたま S レコードフォーマットのファイルがあり、ライトアドレスとデータさえ読めれば OK という感じだと思います。
次はファイルから、S1 レコードタイプからアドレスとデータの取得し、S9 で処理の終了だけ対応したものです(実際に使ったものじゃないので、万一使うときはチェックしてください)。
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 型変数を指定しかできません)。