본문 바로가기
Digital Design/환경 세팅

Test Vector 추출을 위한 시뮬레이터 설계

by RTLog 2024. 3. 25.
728x90
반응형

안녕하세요. 

 

오늘은 드디어 코딩을 해보려고 합니다. 해당 카테고리는 설계 목적보다, 환경 세팅이 목적이기 때문에 간단하게 어떤 모습으로 프로젝트를 진행할지 작성해보려고 합니다. 

Python Code

오늘 모델링할 하드웨어는 16 비트 곱셈기입니다. 

 

1. Input /Output Generation

 

먼저, 곱셈기의 입력으로 사용될 100개의 Test Vector를 생성하였습니다.

 

다음으로, 지난 포스트에서 설치했던 fxpmath 라이브러리를 사용할 차례인데요. Floating-Point 형식의 입력 데이터를 Fixed-Point 형태로 바꿔줍니다.

 

Q-Format 형식으로 데이터 형태를 나타내었는데, 이에 대한 포스트는 추후 작성할 예정입니다. (간단하게 말씀드리면, Sign Bit (1) + Integer Bit (7) + Fraction Bit (8) 의 형태입니다.)

 

2. HW Modeling

 

 Reference Value는 Python 연산자(Floating-Point 연산)를 사용하여 생성해주었습니다.

 

다음으로, HW를 모델링할 차례입니다. fxpmath 라이브러리는 연산에 의한 Bit Extention을 자동으로 적용하기 때문에, 곱셈 연산 결과는 Q(15.16) 형태인데요. 너무 커진 Bit Width를 다시 입력 데이터와 같게 맞춰주었습니다. 

 

결과적으로, 저희가 모델링한 하드웨어는 Fixed-Point 입력을 받아 곱셈을 수행하고, 그 결과에 Rounding & Clipping을 수행하는 하드웨어가 되는 겁니다.

 

설계할 하드웨어에 따라 2번 부분만 바꿔주면 됩니다. 

 

3. Evaluation 

 

곱셈기가 제대로 모델링 되었는지 평가를 진행해야 합니다.  SQNR(Signal-to-Quantization-Ratio)라는 지표를 통해 Floating-Point로 연산한 Reference 값과 Fixed-Point로 연산한 시뮬레이터 값을 비교해줍니다. dB 단위로 결과를 확인할 수 있고, 30dB를 기준으로 Test Vector 추출 여부를 결정하였습니다. 

SQNR

4. Test vector Extracting 

측정된 SQNR 값이 30dB가 넘는다면 Test Vector 추출을 진행합니다. Fixed-Point 형식의 입력 데이터와 출력 데이터를 텍스트 파일에 16진수 형태로 뽑아냈습니다. 

from fxpmath import Fxp
import numpy as np

np.random.seed(40)

# 1. Input/Output Generation (random array)
float_x1 = np.random.uniform(-1, 1, size=(100,))
float_x2 = np.random.uniform(-1, 1, size=(100,))

# Conversion to Fixed-Point Number Q(7.8) 
fixed_x1 = Fxp(float_x1, signed=True, n_word=16, n_frac=8) 
fixed_x2 = Fxp(float_x2, signed=True, n_word=16, n_frac=8)

# ===== 2. HW Modeling Start =========================================================
float_y = float_x1 * float_x2

# Multiplication -> Q(15.16) 
fixed_y = fixed_x1 * fixed_x2

# Clipping & Rounding -> Q(7.8)
CR_fixed_y = Fxp(fixed_y, signed=True, n_word=16, n_frac=8, overflow="saturate", rounding="around")

# ===== 3. Evaluation ================================================================
def sqnr(ref_data, test_data):

    raw = ref_data.flatten()
    dequant = test_data.get_val().flatten()

    Ps = np.mean(np.square(raw))
    Pn = np.mean(np.square(raw - dequant))

    sqnr = 10 * np.log10(Ps / (Pn + 1e-15))

    return sqnr

sqnr_t = sqnr(float_y, CR_fixed_y)

# ======= 4. Extracting Test Vector ==================================================
if sqnr_t>30:
    print("=== sqnr ===:", sqnr_t)
    print("Extracting TestVector ...")
    # Path to the output file
    input1_file = "FIXED_INPUT1.txt"
    input2_file = "FIXED_INPUT2.txt"
    output_file = "FIXED_OUTPUT.txt"

    # Write array values to a text file in one line
    with open(input1_file, 'w') as f:
      for value in fixed_x1.hex():
        f.write(str(value[2:]) + '\n')
    print("Input1 values have been written to", input1_file)
    with open(input2_file, 'w') as f:
      for value in fixed_x2.hex():
        f.write(str(value[2:]) + '\n')
    print("Input2 values have been written to", input2_file)
    with open(output_file, 'w') as f:
      for value in CR_fixed_y.hex():
        f.write(str(value[2:]) + '\n')
    print("output values have been written to", output_file)
    print("=========End=============")
else:
    print("sqnr:", sqnr_t)
    print("Redesign the simulator.")

 

왼쪽은 추출된 Output Test Vector , 오른쪽은 위에 작성된 코드입니다. 

Sample

 

시뮬레이터가 제대로 설계되었다면, 동일한 입력을 받아 동일한 결과를 출력하는 HW를 설계할 차례입니다.!

 

다음 포스트에는 C Shell Script를 작성해볼게요.

 

감사합니다. 

728x90
반응형

let textNodes = document.querySelectorAll("div.tt_article_useless_p_margin.contents_style > *:not(figure):not(pre)"); textNodes.forEach(function(a) { a.innerHTML = a.innerHTML.replace(/`(.*?)`/g, '$1'); });