재사용 모듈의 폭이나 설정값은 parameter로 선언하고 인스턴스에서 named override로 바꾼다. 내부 계산에만 쓰는 값은 localparam으로 두며, 새 코드에서 defparam은 피한다.
parameter로 모듈 폭 열기
module register_bank #(
parameter int unsigned DATA_WIDTH = 8
) (
input logic clk,
input logic [DATA_WIDTH-1:0] data_in,
output logic [DATA_WIDTH-1:0] data_out
);
always_ff @(posedge clk)
data_out <= data_in;
endmodule
인스턴스마다 필요한 폭을 이름으로 지정한다.
register_bank #(
.DATA_WIDTH(16)
) u_register_bank (
.clk (clk),
.data_in (data_in),
.data_out (data_out)
);
named override는 parameter 선언 순서를 기억할 필요가 없고, 인스턴스의 설정 의도를 바로 보여준다.
parameter와 localparam 구분
parameter: 모듈 사용자에게 설정을 열어 둔다.localparam: 모듈 내부에서 계산하거나 고정할 상수를 둔다.
외부에서 바꾸면 안 되는 내부 폭이나 상태 인코딩 값은 localparam으로 둔다. 폭이 0이 되거나 배열 범위가 뒤집히지 않도록 parameter의 허용 범위도 점검한다.
defparam을 새 코드에서 피하는 이유
defparam은 인스턴스 계층 경로를 별도로 지정해 값을 바꾼다. 계층 구조가 달라지면 설정 위치도 찾아 바꿔야 해 읽기와 유지보수가 어렵다. 인스턴스 선언에서 named override를 쓰면 변경 대상과 값이 함께 보인다.
확인 순서
- 기본값이 유효한 폭과 범위인지 확인한다.
- 인스턴스에서 named override가 실제로 적용되는지 elaboration 결과를 확인한다.
DATA_WIDTH-1:0같은 벡터 범위가 0 이하가 되지 않는지 확인한다.- 필요한 경우 여러 parameter 조합으로 elaboration과 simulation을 검사한다.
parameter는 elaboration 때 하드웨어 구조를 정하는 상수다. 실행 중 바뀌는 값이 필요하다면 parameter가 아니라 입력이나 register로 설계한다.
공식 자료
원문 기록
한 줄 요약
모듈 밖에서 바꿀 값은 parameter, 내부 상수는 localparam으로 구분하고 인스턴스 설정은 이름이 있는 override로 표시한다.