본문 바로가기

HDL(Verilog, VHDL, ...) 머든 실제 합성이 설계한 대로 되지 않으면 완전 무용지물이다.

코딩때 부터 신경써야 하는데, 많이 까먹었네. 따로 정리한 문서를 찾아보자.

 

일단 아래글을 찾아와서, 정리해보자. (지금 정리중...읽고 내 생각 넣고 머 이렇게)

예제나 설명에 대한 자세한 내용은 아래 해당 블로그 님의 글을 방문해서 보심이 맞는것 같습니다.

https://trts1004.tistory.com/12108949

 

일단은 제 개인 공부용으로 복사해서 정리중....

추가로 자료가 하나더 있다. 엄청 기본적인것인데 5분이면 읽어본다. 함 읽어보자.

coding_and_synthesis_with_verilog.pdf
0.07MB

 

1. 블록도를 그려라, 라벨을 붙이고, 시그널 적고, width 명기하자.

2. 타이밍도를 그려라 최대한 자세하게

3. 합성 가능한 코드 템플릿(첨부파일 내에 있음)을 보고 코딩해라

4. 일단 컴파일 해서, 블록, 인터페이스 연결도 이런것을 먼저 비교해라

  - 래치가 없어야 한다.

  - If not, latches are inferred in combinational procedures

  - the inferrence report tells you which combinational procedure and the name of the latch. Fully specify all variables in all cases to eliminate latches.

  Check the case statement inferrence. Was it full/parallel?

• Check any incomplete event list warnings?

• Check to see if there are any combinational feedback loops (typically only after a compile). Combinational feedback loops can be identified by the signal names in the timing loop.

• Check the schematic - any ports unconnected?

• Check to see if Designware and Ambitware components have been built correctly. Are these the components that you wanted? How many did you want?

• 워닝을 무시하지 말자. Never ignore any warning that the synthesis tool flags. All warnings need to be understood and typically signed off.

 

5. 시뮬레이션 후 검증, 10% 타이밍 마진은 두는 것이 좋다. 무조건 두자.

• If your design doesn’t meet timing by more than 10% of the clock period, then go back to the code. If you are within 10% of the clock period, then try a different compile strategy

 

기본 Verilog Tutorial 도 해당 블로그에 있어서 하나 더 추가. 2003년 자료인데 기본이 젤 중요하다!!

VerilogTutorial.pdf
4.87MB

코딩 스타일

(저자강추)

0. 위에서 언급한 래치가 발생하면 안된다고 배웠다. 래치가 생기지 않는 코딩을 해라. 조건문 전체 정의, 클럭베이스 F/F 디자인을 기본으로

0. 저는 컴비는 wire 클락베이스 플립플롭은 reg 이렇게 확실하게 구분합니다 - [출처] 시스템반도체 (8) verilog 코딩 가이드, 이렇게 코딩하면 양산 실패한다|작성자 사랑과생각

>> 그냥 combinational logic 은 wire 로 선언해서 사용하자. 요즘은 logic 을 많이 쓰는데 대충 쓰다보면 실수가 발생하므로 꼭 지키는 것이 좋겠다.

컴비네이셔널 로직에서는 반드시 wire 문장을 사용해야 한다.
wire my_and [7:0] ;
assign my_and [7:0] = ( and_condition ) ? my_and [7:0] && and_in [7:0] : 8'b1010_1010 ;
[출처] 시스템반도체 (8) verilog 코딩 가이드, 이렇게 코딩하면 양산 실패한다|작성자 사랑과생각

 

1) wire는 net 형식이다. net 형식은 연결을 위한 요소이다. wire는 continous assignment(assign)에 의하여 assign될 수 있다.
2) reg는 그 자체로 reg 형식이다. reg는 procedural assignment(always begin.. end)에 의하여 assign 될 수 있다. reg는 잠깐동안 값을 보관할 수도 있다. (보관이 필요없으면 combinational logic으로, 보관이 필요하면 storage element를 포함하는 logic으로 구현된다)
[출처] http://babyworm.net/archives/72 

 

0. 그냥 reg 사용하는 경우는 <= 만 사용하자.

0. sensitivity list 에는 clock 과 reset 만 사용한다. <= clock 은 항상 posedge 를 사용해서 설계하자.

만약, negedge 가 필요하면 clock을 외부에서 반전 클럭을 추가해서 받아서 로직 설계를 하는 것은 어떤지

클럭을 보면 2개가 들어오는 것을 나중에 회로 읽을때도 훨씬 판단하기 쉽다.

always @(posedge clock or negedge reset )
always @(posedge clk or negedge rst_x)  begin
  if (!rst_x) a = 1'b0;
  else a = in;
end

0. reg 시그널의 reset은 반드시 해주자. 기본이겠지만 해주자

아래 블로그 글에서 많은 노하우를 읽을 수 있다. 꼭 읽어보길 강추한다. 말투가 좀 거칠수 있지만

https://blog.naver.com/godinus123/221552331215

 

 

1. define을 쓰지 말고 parameter를 써라 => 강추

주의점) parameter integer x 이렇게 하면 signed표현이므로 아래처럼 한다.
parameter P = 3'd0;
안그러면 아래와 같은 warning을 받을 수 있다.
-> signed to unsigned assignment occurs. (VER-318)

Starting with the 200.11-1 release, the Presto Verilog reader treats Verilog 'integer' types as signed; .. (VER-314)

 

2. assignment시 intra-assignment delay for nonblocking assignment are ignored 를 쓰지 마라.  => 강추
>> 보통 딜레이 요소는 합성시에 무시된다. 아래 define 추천

추천: 시뮬레이션시에는 delay가 있어야 더 현실적이다. 따라서 define으로 정의하는게 좋을듯하다.
o_r1 <= `DFF 1'b1;

 

3. 반드시 width를 정해라.  => 강추
>> 1'b0, 2'd0 이렇게 써라.

 

4. TOP 모듈로 들어오는 input에 대해선 무조건 reg로 1 clock 채줘야 한다.
>> 이건 상황에 따라, 조절해야 할듯 사용하는 로직이 바로 써야 할 수도 있다.

 

5. 해당 모듈이 실제 사용하는 비트range만 입력으로 받는다.

>> 사실 합성 때 워닝이 나지만, 편하게 그냥 두기도 한다. 자동으로 없어지니깐

 

6. 가능하면 모듈에서 출력은 한번 reg로 받아서 보낸다. => 추천정도

>> 설계에 따라 다를 수 있다. 타이밍은 사실 모듈간의 약속이므로 상황에 따라 취하면 된다. 원칙으로 삼는 것은 좋다. STA를 위해서는

 

7. reset은 각 clock마다 마련해라.
>> 이렇게 해 본 적이 없는데, 한번 고려해보자.

 

8. Asnychronous FIFO 관련 

>> 해당 블로그 글을 읽어보세요. 저는 이런 경험이 없어서 코딩 스타일은 아닌듯 해서 일단 스킵

 

STA 방법

STA (Static Timing analysis) 방법 먼저 simulation test가 되면 synthesis를 해보고

우선, prime time을 사용하여 sta를 한다.

중요한 부분은 타이밍 에러가 발생한 것들 중에 type: max 인것들(setup타임 violation)만 보면 됨. Hold violation은 백엔드 작업에서 잡아준다고 믿자 :)

나중에 hold violation은 p&r에서 skew 컨트롤하면서 buffer를 넣어주면된다.


1. 만일 combinational logic이 FF간에 너무 많다면 적절히 끊어서 reg로 만든다. => 강추!! 강추!!
 - 이때 타이밍이 맞아야 하는 다른 병렬적인 data/control_path에 대해서도 reg버퍼링으로 타이밍을 맞춰줘야 한다.

2. even/odd 방식으로 병렬화 ==> 모르겠음

3. 만일 어떤 reg를 여러곳에서 쓴다면 fan out이 커져서 synthesis할때 버퍼(BUF, INV)가 많이 달리게 된다. 이를 방지하기 위해서는 reg와 동일한 쌍둥이 reg를 만든 후 rvalue로 사용될때 적절히 분배하도록 하면 된다. (생각보다 큰 효과를 볼 순 없음, 버퍼를 줄이는 효과) -> 추천

3. 만일 어떤 모듈을 여러 모듈에서 사용해도 해당 모듈의 출력의 fan out이 커질 수 있음 이때도 각 모듈마다 해당 모듈을 각자 생성해서 사용하도록 할 수 있다. => 추천
예) multi lane tx link를 설계 시 counter 모듈을 lane별로 생성해서 사용.

4. fifo는 word width를 줄이면 좋다. 40bit width라면 20bit width 두개의 병렬 fifo를 마련해도 동작엔 아무런 상관이 없다.=> 나중에 코드 읽을 때 복잡해 보일수 있다. 큰 문제 아니면 기능과 설계가 일치되어 있는게 좋을듯, 합성툴의 최적화를 믿자!!!!!

 

DFT 대비 코드

DFT scan test를 위한 코드
Spyglass_DFT를 사용할 수있다. scan test는 PNR과정에서 모든 route path가 잘동작하는지 확인하기 위하여 디자인내의 모든
dff reg의 데이터 출력 Q를 체인으로 데이터 입력에 연결하여 scan test시 제일 처음 dff에게
값을 주고 clock을 발생시켜 모든 dff reg에 원하는 값이 들어가 있는지 확인하는 test이다.


만일 clock domain이 다르면 각 domain별로 scan test를 해야 한다.

1. 가능한한 주어진 ref clk을 사용하여 모든 dff를 다루어라.
  - 만일 ref_clk의 div2_clk를 사용해야 한다면 ref_clk로 2분주된 div2_clk을
    always @ (posedge div2_clk로 쓰지말고
    always @ (posedge ref_clk .. ) if( div2_clk == 1 ) 인 경우로 사용하라.
    그러지 않으면 향후 scan test를 하는데 div2_clk를 사용하는 dff는 scan_test모드일 경우
    ref_clk를 받도록 mux하는 코드를 작성해야하는 불편함이 있다.
    안그러면 scan test가 div2_clk를 사용하는 dff는 scan test가 제대로 되지 않는다.
2. sw reset을 하는 경우 scan_test_mode및 scan_reset이 필요하다.
  - sw reset은 sw reset dff reg를 1로 만들면 내부적인 reset신호를 생성하는데 이 sw_reset
    dff가 scan test시 1이 되면 이와 관련된 sw_reset을 받는 모듈의 dff들이 reset이 되어
    제대로 scan test를 할 수 없다. 따라서 scan_test_mode가 1인 경우 sw_reset dff가 active
    되지 않도록 mux out해주어야 한다.
3. 만일 reset이 없는 dff reg는 scan_test_mode가 1일때 scan_resetn을 사용토록하게 하라.
  - scan test를 빨리하기 위해서 scan test시 reset을 하게 되는데 이 dff reg는 reset을 갖지
    못하므로 이 dff reg를 reset하려면 모두 연결된 scan chain만큼 scan clk을 먹여 초기화해야
    하므로 시간이 많이 걸리므로 scan test모드일 때는 이 reset이 없는 dff reg는
    regscan_resetn을 받도록 한다.


Test/Debug를 위한 코드
1. 가능하면 I2C나 APB의 SFR에 각 모듈별 enable, disable config하는 reg를 많이 두어라.
 - 다양한 모드를 지원한다는 개념이 아닌 chip debugging시 안되면 최악의 경우 다른 path로
   동작되는 최소한의 기능이라도 뚫수 있도록 하는 차원에서 만들어야 한다.
2. SFR에 최대한 많은 현재 모듈 내의 status를 볼 수 있는 내용을 넣어두어라.
 - chip test시 버그 발생시 어떤 상태인지라도 조금더 확인해 볼 수 있는 여지가 있다.


Timing Budget계산
100MHz라면 1clk이 10ns이다. 이 때 D-FF의 setup time, hold time을 감안하여 60%를 사용가능한 타이밍구간이라고 보게 되면, 6ns를 사용 가능한것이고, 기본 2 input-nand 하나의 지연이 1ns이라면 최대 6 level을 사용 가능하게 된다.

 

추가 자료

Synthesizable SystemVerilog Design 을 위한 이야기 - https://yhkwon6658.github.io/2023-02-06/Synthesizable-Systemverilog-Advantage 

 

Synthesizable SystemVerilog Design 을 위한 이야기

SystemVerilog 는 흔히 Verification 을 위한 언어로 취급되어 오고 있지만, 링크 에 따르면 합성에서도 여러가지 이점을 가지고 있다. Verilog 는 2005 년을 기점으로 새로운 IEEE 규약이 갱신되고 있지 않다

yhkwon6658.github.io

정리가 꼭 필요하다. 정독하자!!

 

https://thinkpiece.tistory.com/251

- Do not make assignments to the same variable from more than one always block.: 하나의 변수에 대해 여러 개의 always에서 대입하도록 작성하지 말자.
- Use $strobe to display values that have been assigned using nonblocking assignments.: nonblocking (<=)으로 대입된 변수를 simulation에서 확인하고자 할 때에는 $strobe를 이용해서 출력하자.
- Do not make assignment using #0 delays.: Simulation 시, zero-delay를 주지 말자. Verilog Simulation의 Event Queue에 해당하는 포스팅을 차후에 할 예정이지만 간단히 설명하면, 흔히 많은 이들이 #0을 이용해서 대입하면 time step의 가장 마지막에 assignment를 수행하도록 queuing 것이라 생각하지만, 실제로는 inactive events queue에 들어가게 된다. 즉, 같은 time step에서 non-blocking 보다 먼저 실행된다. 해당 time step의 최종 값을 보고싶다면, 굳이 #0 $display … 같은 걸 쓰지 말고, $strobe를 쓰자.
출처: https://thinkpiece.tistory.com/251 [A Think Piece:티스토리]

 

 

 

칩은 사실 나초칩이지 :)

나초와 맥주

 

B로그0간

개발 관련 글과 유용한 정보를 공유하는 공간입니다.