SystemVerilog는 하드웨어 설계 및 검증을 위한 강력한 언어입니다. 기본 문법부터 차근차근 알아보겠습니다.
1. 모듈 정의
SystemVerilog의 기본 구성 요소는 모듈(module)입니다. 모듈은 하드웨어 설계의 기능적 단위를 나타냅니다.
module counter(
input logic clk, // 클록 입력
input logic reset, // 리셋 입력
output logic [7:0] count // 8비트 카운터 출력
);
// 모듈 내부 로직 구현
endmodule : counter // 모듈 이름으로 종료 가능
2. 데이터 타입
SystemVerilog는 Verilog의 reg
, wire
보다 더 명확한 데이터 타입을 제공합니다.
logic [7:0] counter; // 8비트 논리 신호 (reg/wire 대체)
bit flag; // 단일 비트 (0,1만 가능)
byte value; // 8비트 부호 있는 정수
shortint short_val; // 16비트 부호 있는 정수
int int_val; // 32비트 부호 있는 정수
longint long_val; // 64비트 부호 있는 정수
// 부호 없는 정수형
bit [7:0] unsigned_byte;
logic [15:0] unsigned_short;
3. 항상 블록 (Always Blocks)
SystemVerilog에서는 목적에 따라 세 가지 항상 블록을 사용합니다.
// 순차 로직(플립플롭)을 위한 always_ff
always_ff @(posedge clk or posedge reset) begin
if (reset)
counter <= 8'h00;
else
counter <= counter + 1;
end
// 조합 로직을 위한 always_comb
always_comb begin
if (counter == 8'hFF)
overflow = 1'b1;
else
overflow = 1'b0;
end
// 래치를 위한 always_latch (일반적으로 피해야 함)
always_latch begin
if (enable)
latch_data <= data_in;
end
4. 할당 연산자
SystemVerilog에서는 두 가지 할당 유형을 사용합니다.
// 블로킹 할당 (=): 순차적으로 즉시 실행, 주로 조합 로직에 사용
always_comb begin
temp = a + b; // 이 할당은 즉시 발생
sum = temp; // temp 값이 먼저 계산된 후 할당됨
end
// 논블로킹 할당 (<=): 병렬로 사이클 끝에 실행, 주로 순차 로직에 사용
always_ff @(posedge clk) begin
a <= b; // 모든 우변이 계산된 후
b <= a; // 모든 좌변에 동시에 할당됨
end
5. 매개변수 (Parameters)
매개변수를 사용하여 재사용 가능한 모듈을 만들 수 있습니다.
module counter #(
parameter WIDTH = 8, // 기본값이 8인 매개변수
parameter [WIDTH-1:0] INIT = 0 // 매개변수는 다른 매개변수를 참조할 수 있음
)(
input logic clk, reset,
output logic [WIDTH-1:0] count
);
// 모듈 내부에서 매개변수 사용
always_ff @(posedge clk or posedge reset) begin
if (reset)
count <= INIT;
else
count <= count + 1;
end
endmodule
6. 인터페이스 (Interfaces)
인터페이스는 관련 신호를 그룹화하고 모듈 간 통신을 단순화합니다.
// 인터페이스 정의
interface bus_if;
logic [7:0] data;
logic valid;
logic ready;
// 인터페이스 내에 모듈러 태스크 정의 가능
task automatic transfer(input logic [7:0] d);
valid = 1'b1;
data = d;
wait(ready);
#1 valid = 1'b0;
endtask
endinterface
// 인터페이스 사용
module sender(bus_if bus);
// 인터페이스의 신호에 접근
always_ff @(posedge clk) begin
bus.valid <= data_ready;
bus.data <= transmit_data;
end
endmodule
module receiver(bus_if bus);
always_ff @(posedge clk) begin
if (bus.valid && bus.ready)
received_data <= bus.data;
end
endmodule
답글 남기기