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 할때 사용합니다.
즐공하세요 :)
'개발 편의성을 위한 소소한 Tips > 04 질의 응답 정리' 카테고리의 다른 글
[Verilog HDL Q/A. 006] verilog 특성 관련 질문 (동작 관련) (0) | 2021.09.14 |
---|---|
[Verilog HDL Q/A. 005] High impedance 출력 (0) | 2021.09.11 |
[Verilog HDL Q/A. 004] 비메모리 설계시, 리눅스 환경을 사용하는 이유 (3) | 2021.09.10 |
[Verilog HDL Q/A. 003] 시뮬레이션에서 클럭 rising edge 순간 판단 대상이 되는 신호도 함께 천이 됩니다. 이런 경우 논리 상태에 대해 궁금합니다. (0) | 2021.09.09 |
[Verilog HDL Q/A. 001] testbench 의 input, output, reg, wire ?? (0) | 2021.09.07 |