SystemVerilog는 기존의 Verilog에 아주 많은 프로그래밍 능력을 추가했다. 이러한 향상을 의도한 목적은 다음 3가지로 볼 수 있다.
- 코드 간결화
- 설계시 기능적 결함 줄이기
- 시뮬레이션과 합성이 동일하게 동작하도록 만들기
Procedural blocks
기존의 Verilog에서는 always문을 사용하여, combinational, latch 와 sequential logic을 생성하였다.
여기서 문제는 합성 툴과 시뮬레이션 툴이 설계자의 어떤 종류의 logic을 표현할려고 헀는지 알 방법이 없다는 것이었다. 이러한 툴들은 procedural block안에 있는 코드를 해석할 수 있었고, 설계자의 의도를 nice한 방식으로 추측하는 것 뿐이었다.
combinational logic에서 간단한 코딩 오류가 latch를 생성하게 되는데, 합성툴이 실제로 report를 하기전에는 latch가 나오는지 확인할 수 없었다. 따라서, 합성후 결과를 보고 설계는 다시 반복하는 과정들이 빈번히 일어났다.
SystemVerilog는 always 문을 3개의 새로운 타입으로 추가했고, 이에 관련된 합성 규칙을 검사하도록 제공하고 있다. 이들은 always_comb, always_latch, always_ff이다.
시뮬레이터, lint checkers, 합성 컴파일러들은 이러한 새로운 procedural blocks내의 코드들이 원래 의도한 형식과 일치하는지 검사하고 오류 보고할 수 있게 되었다. 이러한 오류 보고는 선택적이라서, 시뮬레이션 툴들은 오류보고를 하지 않고, link checker와 합성 컴파일러들은 오류 리포르를 한다.
1. always_comb
always_comb procedural block은 설계자의 의도가 combinational logic을 표현하는 것을 의미한다.
다음 예에서 기존의 Verilog용 always 문을 사용을 때와 SystemVerilog용 always_comb 문을 사용했을 때를 비교해 본다.
// (a)
always @(a or b or sel) begin
if (sel) y = a;
else y = b;
end
// (b)
always_comb begin
if (sel) y = a;
else y = b;
end
SystemVeriog의 always_comb를 사용하는 것이, 기존의 Verilog always를 사용하는 것보다 장점이 있다.
가장 큰 장점은, 툴이 (b) 에서 combinational sensitivity list를 추정할 수 있다는 것이다. 이는 툴이 procedural block의 목적을 알고 있기 때문에 가능하다. Verilog에서 가장 흔한 실수중 하나가 불완전한 sensitivity list를 만드는 것이었다. 이는 syntax error가 아니어서, 이상 동작을 하는 것 뿐이었다. 이를 해결하기 위해 Verilog-2001에서는 always @* 을 추가했고, 자동으로 complete sensitivity list를 만들게 되었다. SystemVerilog의 always_comb 블럭도 always @*과 같이 동작한다고 보면 된다.
두번째 중요한 장점은, 툴이 설계자의 의도가 combinational logic을 만드는 것임을 알고 있기 때문에, 이러한 의도가 맞는지 툴이 검증할 수 있다는 것이다. 다음 코드는 always_comb 블럭을 사용하는 procedural block을 보여준다. 하지만, combinational logic처럼 동작하지 않는다. 다음 예제에서는 DC 합성 툴이 오류를 발생시킨다.
module always_comb_test
( input logic a, b,
output logic c);
always_comb
if(a) c = b;
endmodule
===========================================================================
| Register Name | Type | Width | Bus | MB | AR | AS | SR | SS | ST |
===========================================================================
| c_reg | Latch | 1 | N | N | N | N | - | - | - |
===========================================================================
Warning: test.sv:5: Netlist for always_comb block contains a latch. (ELAB-
974)
DC 합성툴이 이 코드를 읽어들이면, Latch 형태의 register 를 나타내는 Register Table을 생성한다.
또한, elaboration 경고가 발생하고, latch가 always_comb 블럭에서 생성됨을 알려준다.
따라서, 설계자의 의도가 combination logic을 만들기 위해 always_comb 블럭을 사용했는데, 설계자의 의도와 달리 결과적으로 latch가 생성되었으므로, DC 합성툴은 오류를 보고하게 된다.
2. always_latch
좀더 특별한 always_latch procedural block은 always_comb와 매우 유사하다. 단지, 설계자의 의도가 latch 를 만들려고 한다는 것을 명시하는 것이다. 합성 툴은 이 목적에 맞게 설계되었는지 확인하게 된다. 다음 예는 always_latch를 사용하는 것이지만, 실제 combination logic을 생성한다.
module always_latch_test
( input logic a, b, c
output logic d);
always_latch
if(a) d = b;
else d = c;
endmodule
Warning: /test.sv:7: Netlist for always_latch block does not contain a latch. (ELAB-975)
DC 합성툴이 이 코드를 읽어들이면, elaboration 경고가 발생하고, latch가 always_latch 블럭에서 생성되지 않았음을 알려준다.
따라서, 설계자의 의도가 latch를 만들기 위해 always_latch 블럭을 사용했는데, 설계자의 의도와 달리 결과적으로 combination logic이 생성되었으므로, DC 합성툴은 오류를 보고하게 된다.
3. always_ff
always_ff 는 설계자가 flip-flop behavior를 표현하기 위해 사용한다.
always_ff는 always_comb와 달리, sensitivity list를 포함해야 한다. 이는 툴이 자동으로 clock이름과 clock edge를 추정할 수 없기 때문이고, 설계자가 synchronous reset을 의도한 건지 asynchronous reset을 사용할건지 알 수 없다. 따라서, 이러한 정보는 sensitivity list에 명시되어야 한다.
여전히 합성 툴은 설계자의 의도가 flip-flop를 만들려고 한건지 확인하고, 오류를 발생시킬 수 있다. 다음 예에서 always_ff는 flip-flop를 생성하지 않으므로, DC 합성툴은 오류를 발생시키게 된다.
module always_latch_test
( input logic a, b, c
output logic d);
always_ff @(a,b,c)
if(a) d = b;
else d = c;
endmodule
Warning: test.sv:5: Netlist for always_ff block does not contain a flipflop. (ELAB-976)
4. Additional advantages
사용자의 의도를 알 수 있는 always_comb, always_latch, always_ff를 사용하면, 더불어 SystemVerilog는 RTL 코드가 gate-level로 제대로 구현되는지 확인할 수 있는 장점도 있다.
- LHS의 변수들은 다른 process들에 의해도 쓰일 수 없다.
- always_comb와 always_latch는 시뮬레이션 0시간에 execute되므로, time 0에서 제대로 연결되었는지 확인할 수 있다.
- always_comb와 always_latch는 signal 변화에 sensitive히다.
5. 추천
always_comb, always_latch, always_ff를 모든 RTL 코드에서 사용하고, always는 합성할 목적이 아닌 기타 모듈들에서만 사용한다.
예를 들면, functional 모델, abstract RAM 모델, 검증용 테스트벤치들에서만 사용한다.
'SoC 설계 > Verilog, SystemVerilog' 카테고리의 다른 글
Modelsim Warning (vsim-PLI-3691) (0) | 2024.04.18 |
---|---|
Converting logic to real or real to logic (0) | 2024.04.12 |
SystemVerilog: Casting (0) | 2023.03.18 |
SystemVerilog: Parameterized task/functions (0) | 2023.03.18 |
SystemVerilog: Arrays (0) | 2023.03.10 |