고정 폭 flat bus에 배열 원소를 연결할 때는 각 원소의 시작 bit와 폭을 정해 매핑한다. SystemVerilog의 indexed part-select인 +:는 기준 bit부터 지정한 폭만큼 bit를 선택한다.
byte 단위 slice
내림차순으로 선언한 logic [31:0] data에서 네 byte를 나누려면 다음과 같이 쓸 수 있다.
logic [31:0] data;
logic [7:0] byte0, byte1, byte2, byte3;
always_comb begin
byte0 = data[0 +: 8]; // data[7:0]
byte1 = data[8 +: 8]; // data[15:8]
byte2 = data[16 +: 8]; // data[23:16]
byte3 = data[24 +: 8]; // data[31:24]
end
[base +: width]에서 두 번째 값은 끝 index가 아니라 선택할 bit 수다. 반대 방향으로 선택하려면 -:를 사용한다. 예제의 결과는 packed vector가 [31:0]으로 선언된 경우다.
배열을 flat bus로 묶기
배열 원소마다 bus의 연속된 WIDTH bit를 연결하면 된다.
module pack_bytes #(
parameter int unsigned COUNT = 4,
parameter int unsigned WIDTH = 8
) (
input logic [WIDTH-1:0] bytes [0:COUNT-1],
output wire [COUNT*WIDTH-1:0] flat
);
for (genvar i = 0; i < COUNT; i++) begin : gen_pack
assign flat[i*WIDTH +: WIDTH] = bytes[i];
end
endmodule
이 예제는 SystemVerilog의 unpacked array port를 사용한다. Verilog만 지원하는 경계나 외부 interface에는 flat vector를 port로 두고, 모듈 내부에서 같은 indexed part-select 규칙으로 원소를 풀어 쓴다.
bit 순서를 고정하기
위 mapping은 bytes[0]을 flat[WIDTH-1:0]에 둔다. 반대로 가장 높은 slice부터 첫 원소를 놓고 싶다면 mapping 식을 바꿔야 한다. 송신 측과 수신 측이 같은 byte 순서와 bit 순서를 사용하는지 interface 문서에 적는다.
확인 순서
- 배열 원소 수와 각 원소의 폭을 확인한다.
- flat vector 폭이
COUNT × WIDTH인지 확인한다. - 원소 0과 마지막 원소가 의도한 slice에 연결됐는지 확인한다.
- simulator와 synthesis tool에서 사용하는 SystemVerilog 문법을 지원하는지 확인한다.
공식 자료
원문 기록
한 줄 요약
배열과 flat bus를 변환할 때는 원소 폭, 시작 bit, byte 순서를 명시하고 indexed part-select의 두 번째 값은 bit 폭으로 쓴다.