개발 편의성을 위한 소소한 Tips/04 질의 응답 정리

[Verilog HDL Q/A. 002] $readmemh 의 사용방법과 사용처

반응형

readmemh 문법에 대해 알아보도록 하겠습니다.

다음 링크를 적극 참고하여 작성하였습니다.

https://projectf.io/posts/initialize-memory-in-verilog/

http://www.testbench.in/TB_03_FILE_IO_TB.html

Verilog에서의 메모리 초기화

시뮬레이션이나 펌웨어는 memory array, RAM 또는 ROM에 데이터를 로드해야 하는 것이 일반적입니다.

다행히 Verilog는 바로 이 목적을 위해 $readmemh 및 $readmemb 기능을 제공합니다. 

 

Verilog Syntax

Verilog를 사용하면 16진수 또는 2진수 값으로 텍스트 파일에서 메모리를 초기화할 수 있습니다.

  • $readmemh("hex_memory_file.mem", memory_array, [start_address], [end_address])
  • $readmemb("bin_memory_file.mem", memory_array, [start_address], [end_address])

 

Function Arguments

  • hex_memory_file.mem - 공백으로 구분된 16진수 값을 포함하는 텍스트 파일
  • bin_memory_file.mem - 공백으로 구분된 이진 값을 포함하는 텍스트 파일
  • memory_array - Verilog 메모리 배열 이름 reg [n:0] memory_array [0:m]
  • start_address - 데이터 로드를 시작할 메모리 배열의 위치(선택 사항)
  • end_address - 메모리 배열에서 데이터 로드를 중지할 위치(선택 사항)

다음은 $readmemh를 사용하는 매우 간단한 시뮬레이션 모듈을 보여줍니다.

module readmemh_tb();
    reg [7:0] test_memory [0:15];
    initial begin
        $display("Loading rom.");
        $readmemh("rom_image.mem", test_memory);
    end
endmodule

Memory File Syntax

hex_memory_file.mem 또는 bin_memory_file.mem 파일은 공백으로 구분된 텍스트 16진/2진 값으로 구성됩니다.

공백, 탭 및 개행은 모두 작동합니다. 하나의 파일에서 공백 유형을 혼합할 수 있습니다.

주석은 일반 Verilog 파일과 동일합니다. // 주석을 시작합니다.

파일에 있는 데이터 값의 너비는 배열의 데이터 너비보다 넓어서는 안 됩니다.

그렇지 않으면 해당 값이 잘립니다. Vivado에서는 WARNING: Datafile을 읽는 동안 데이터가 잘림(Truncated) 로그에 경고가 표시됩니다.

 

Verilog Examples

다음 예는 다양한 초기화 파일이 있는 $readmemh 및 $readmemb를 보여줍니다.

일부 오래된 tool 들은 정말 까다롭습니다. 문제가 있는 경우 주석을 피하고 공백을 혼합해야 할 수도 있습니다.

 

1) Four 16-bit data values in hex

reg [15:0] ex1_memory [0:3];
$readmemh("ex1.mem", ex1_memory);
dead
beef
0a0a
1234

2) Sixteen 8-bit data values in hex (mixing spaces and newlines)

reg [7:0] ex2_memory [0:15];
$readmemh("ex2.mem", ex2_memory);
ab cd ef 01  // this is a comment
ef 22 1e 00
9f ff 13 e6
ce b7 28 8f

3) Six 3-bit values in binary

reg [2:0] ex3_memory [0:5];
$readmemb("ex3.mem", ex3_memory);
001 101 111 111 101 001

4) Six 16-bit values in hex starting at array position 4

reg [15:0] ex4_memory [0:255];
$readmemh("ex4.mem", ex4_memory, 4);
dead beef 0a0a 1234 abab 987e

 

 

Q

Verilog 문법을 공부하다가, $readmemh 라는 문법을 본적이있는데, 이것또한 메모리에 접근하는 문법이라고 알고있습니다. 그렇다면 이 문법과, 오늘 배운 bram을 컨트롤하는 모듈은 차이가있는건가요?

 

A

$readmemh 는 data 파일의 내용을 메모리로 읽을 때 사용하구요.

Testbench 에서도 사용 가능하고, 합성 가능한 RTL 에서도 사용가능합니다.

Testbench 에서는 자유롭게, data file 을 읽고 싶을 때 사용가능하구요. (Test 용이니까, 회로가 아니라는 뜻입니다.)

다만 합성 가능한 RTL 에서 사용 할때는 memory 의 초기값 (initial value) 을 정할때 사용합니다.

실제 회로에 초기값이 fix 되어 있습니다. (Testbench 하고는 그 의미가 다릅니다.)

 

Verilog 문법을 공부하다가, $readmemh 라는 문법을 본적이있는데, 이것또한 메모리에 접근하는 문법이라고 알고있습니다. 그렇다면 이 문법과, 오늘 배운 bram을 컨트롤하는 모듈은 차이가있는건가요?

다음과 같은 차이가 있다 라고 생각해요 :)

저랑 같이 배우신 BRAM Control 모듈은, Cycle 을 소모 (시간을 소모하는 실제 동작) 하여 BRAM 을 Read 하였습니다.

Testbench 에서의 $readmemh 는, cycle 을 소모하지 않고 read 합니다.

합성 가능한 RTL 에서의 $readmemh 는 회로상의 초기값으로 fix 할때 사용합니다.

 

즐공하세요 :)

 

반응형