PVT variation

오늘 회사에서 이런 저런 이야기하다가, TSMC28HPC 공정에서 junction temp =0 보다 125에서 합성 속도가 빠르더라..는 이야기를 들었습니다.

이게 보통의 경우와는 차이가 있어서 ‘왜??’ 라는 생각이 들었고, 혹시 측정 잘못이 아닌지 싶어서 라이브러리의 SS HVT의 NLDM  lib 파일을 뒤졌는데 정말 그렇더군요.

지금까지 junction temp.가 높아지면 느려진다는 것이 제가 가지고 있던 상식이었거든요. (물론, 제가 공정쪽을 안해서 그냥 frontend engineer가 가진 상식선에서 말이죠..)

제 상식으로는 보통 process corner라 이야기하는 부분에서 process에서 doping 정도에 따라 N/P carrier mobility가 변해서 SS, TT, FF 같은 조건에 따라 성능이 바뀝니다. 이건 당연하죠. 당연히 mobility가 큰 경우가 빠릅니다.

공급 전압에서 따라 성능이 바뀐다는 것도 당연하죠. 전압이 높으면 빨라집니다.
참고로, 가끔 공급전압을 칩에 공급되는 전압으로 생각하시는 분들이 있는데, Cell로 들어가는 전압이죠. front-end만 하다보면 IR drop을 가끔 잊으시는데, power rail을 촘촘히 깔지 않으면 중간에 전압 강하가 너무 심해지죠. 물론, 이것도 동시에  천이되는 로직의 수에 따라 달라지니 backend engineer 분들이 고생하시는 거죠.

마지막으로 온도. 요게 문제인데 보통은 온도가 증가함에 따라 비저항(resistivity던가..)이 증가하면서 mobility가 낮아지게 되면서 속도가 느려집니다.

요기까지가 지금까지 제가 알고 있던 PVT (Process, Voltage, Temperature)  variation인데요.

그래서, 보통의 cell library의 databook(일단 구글에서 나오는 Verisilicon의 GSMC 공정을 보죠.. https://www.google.co.kr/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=verisilicon+GSMC+0.18)에는 보통 아래와 같은 수식이 들어 있는 경우가 많습니다.

뭐 식은 다르지만, 보통 delay는 process의 derating factor, 전압 factor, 온도 factor의 함수라는 거고..

tP = Kp * [ 1 + ( KVolt * ∆Vdd ) ] * [ 1 + ( KTemp * ∆T ) ] * tp0

 

위의 식에서 아래와 같은 factor를 가지기 때문에 전압에 반비례, 온도에 비례하는 관계를 가지는 거죠.

ScreenShot001

즉, 이게 제가 보통 생각하는 factor인데요.

위에서 첫번째 이야기한 부분의 원인은 뭘까요?

바로 간과한게 하나 있는데, 사실 온도의 경우 조금 더 많은 부분에 영향을 준다는 거죠.

조금 더 많은 부분을 살펴보자면,

  1. 온도가 올라가면 비저항이 올라가니까 capacitance도 올라가겠죠.  그런데, 요건 cap을 충전시키는데 더 많은 전하가 필요하다는 의미가 되기 때문에 속도를 느리게 많드는데 기여합니다. (위의 것과 관계 없다는 이야기죠.)
  2. 온도가 올라가면 threshold voltage가 낮아지는 효과가 있습니다. 단 이 부분은 load cap, 원래의 Vth, slew rate에 따라 효과가 다르다고 합니다.
    ‘합니다.. ‘ 라고 앞의 부분은 들어서 알고 있었지만 사실 원인을 저도 잘 몰라서 그럽니다.  그냥 이해하는 바로는 온도가 올라가면서 excitation(여기.. 상태라고 했던거 같은데.. 뭐라 번역하죠? 흥분상태? ㅋㅋ 여튼,)상태로 갈 확률이 증가하고, 따라서 carrier가 gate를 뛰어넘을 확률이 높아지기 때문에 실질적으로 leakage도 늘어나고 vth도 실질적으로 낮아지는 것과 비슷한 효과가 있다고 ‘대충’ 이해하고 넘어갔었습니다.  뭐 digital 하는 사람이 이정도면 충분하죠.. ㅎㅎ

즉, 2번 부분의 효과가 증가하는 것이 아닌가 생각됩니다. 관련 부분에 대해서 일단 논문을 좀 읽고는 있는데, 음.. 쉽지 않네요. (그냥 current to voltage conversion 특성이 바뀌면서 오히려 느려지는 거야.. 라고 써있는 논문을 읽고 있는 바람에 ㅎ)

다른 걸 좀 더 찾아서 읽어보겠습니다만, 일단 DSM에서는 2번의 효과가 많이 커져서 mobility가 떨어지는 효과를 넘어서는 것이다.. 로 정리하고 있습니다. (혹 공정쪽에 계신 분 있다면 조언을..)

이전의 0.18um 정도까지는 이런 부분을 간단히 무시할 수 있었지만(사실 제 기억이 맞다면 90nm까지도.. ), 적어도 지금 확인헀던 TSMC28HPC HVT SS 라이브러리에서는 무시할 수 없다는 거네요.

여하튼, 중요한 사실은 “예전에 상식선으로 알고 있던 것이 지금은 사실이 아닐 수 있다”는 중요한 교훈을 얻었습니다. (더불어 예전 지식으로 먹고 살 생각하다는 큰일 날 수 있다는 교훈도…)

 

 

 

Cygwin1.7에서 Eclipse CDT 사용하기

요즘 뭐 좀 할일이 있어서 깔아 쓰고 있는데요..

예전에 eclipse CDT를 사용했을 때는 eclipse따로 CDT를 따로 설치해야 했고, CDT도 멋지기는 했어도 아주 매력적인 툴은 아니었는데, 새로 깔아본 CDT는 그때보다 더 멋진 툴이 되어 있군요.
그런데, 문제는 CDT가 cygwin 1.7버전(요즘 배포되는 windows7 호환 버전이죠.)을 사용하면서 cygwin gcc를 정상적으로 인식하지 못한다는 점입니다.
gcc를 인식하더라도, gdb와 연동에 문제가 생긴다거나 하는 문제도 약간씩 있구요.

지금 공식 배포되고 있는 Eclipse Galileo 버전에 붙는 CDT 6.x 버전은 cygwin 1.7 버전과 여러 가지 문제가 있다는 거죠. 

이 문제의 해결 방법(?)을 결론적으로 말씀 드리자면,
이 문제는 CDT의 다음버전인 7.x대 버전, 즉 Eclipse Helios버전에 들어가는 CDT에서 해결되어 정상적으로 동작할 것입니다. (아.. 이거 무슨 허무개그도 아니고..)

여하튼, Helios는 6월에 공개를 목표로 한창 작업이 진행중이죠. 지금 받아 볼 수 있는 버전은 milestone 6 버전(Eclipse Helios M6)입니다. (물론, nightly build도 받을 수 있지만 testing에 문제가 있을 수 있으니 아무래도 milestone 버전을 받는 것이 안전하겠죠)

Cygwin1.7이 깔려 있는 것을 가정하고 말씀 드리죠.

  1. http://www.eclipse.org/downloads/ 에서 development build 탭을 선택하시고, Eclipse IDE for C/C++ Developers (83 MB) 를 선택합니다. (이 링크는 몇 일만 지나도 구 버전을 가르키고 있겠죠. 되도록이면 직접 들어가셔서 최신 버전을 다운로드 받으세요)
  2. GDB를 정상적으로 사용하시려면 Eclipse의 RSE를 받으셔야 합니다. (이걸 몰라서 한참 동안 고생했습니다.) http://download.eclipse.org/dsdp/tm/downloads/drops/R-3.1.2-201002152323/ 요기 들어가면 최신까지는 아니더라도 사용하는데 큰 지장 없는 버전을 받으실 수 있습니다.
  3. 이제 eclipse의 압축을 푸시고, 같은 디렉토리에서 RSE도 압축을 풀어주세요 (음.. 압축 파일 디렉토리 구조를 보시면 아시겠지만, 둘다 eclipse 부터 시작하는 디렉토리 구조를 가지고 있어서 같은 디렉토리에서 풀어 주면 알아서 적절한 위치로 들어갑니다. )
  4. eclipse를 실행시키고 workplace(작업할 디렉토리죠)를 지정하고 실행하면 됩니다.
  5. 즐기세요

아주 간단하죠.

아.. 혹시 cygwin1.dll이 있는 [cygwin설치디렉토리]/bin 디렉토리를 윈도우 환경변수상에 path로 지정하지 않았다면 정상적으로 프로그램을 수행시킬 수 없을 수 있습니다. 되도록이면 환경변수상에 path로 설정하세요. (물론 다른 방법도 있지만.. 흠.. 말하는 것이 더 혼동을 드릴지도)

참고로 Eclipse Galileo버전에 붙는 CDT 6.x를 cygwin 1.7에서 동작하게 하려면 약간 작업이 필요합니다.

느낌상으로는 디버깅이 정상적으로 될 때도 있고, 잘 연결이 안될 때도 있더군요.. 여하튼.

여기에 써 있는 것과 같이 레지스트리에 cygwin의 파일 정보를 써 넣어줍니다. http://dreamlayers.blogspot.com/2010/01/eclipse-incompatibility-with-cygwin-17.html . cygwin에서 예전에는 레지스트리를 통해서 파일 위치에 대한 정보를 전달했는데, cygwin 1.7에서는 mount를 이용하는 방법으로 변경되면서 이 레지스트리가 사라졌다고 합니다. CDT에서 이 부분을 못 찾는 거죠.

수행을 위한 방법
  1. 위와 마찬가지로 RSE를 설치하시고 windows에서 eclipse를 수행시키세요. 끝. 가끔(많이?) 디버깅이 안되고 thread가 죽을 때가 있습니다. (저만 그런지도.. )
  2. cygwin상에서 eclipse를 수행시키세요. compile과 debugging이 쉽게 이루어지는데, 중간 중간 귀찮은 일이 생깁니다.
    1. cygwin상의 directory와 윈도우의 directory 이름이 달라서 디버깅시에 소스를 찾을 수 없는 경우가 있는데, windows->preference->C/C++->Debug->Common Source Lookup Path에 가서 Add Path Mapping에서 /cygdrive/c/ … 이렇게 되어 있는 것을 c:\라고 주시면 됩니다.
    2. clean이 정상적으로 동작하지 않는데, makefile을 확인해보시면 del로 설정되어 있어서 그렇습니다. 별로 큰 일은 아니니
    3. 가끔 잘 안 될때는 그냥 cygwin console에서 직접 해당 디렉토리에 가서 make해 주면 간단하게 해결되는 경우도 많습니다.

에고.. cygwin 1.7은 머 그렇게 변한게 많은지 쉽지 않군요.

cygwin 1.7의 gcc는 exe파일이 아닌 gcc-4.exe를 가르키는 symbolic link죠. 만일 minGW 형태로 컴파일하려면 예전에는 gcc –mno-cygwin 이라는 좋은 옵션이 있었는데, 아직 gcc 4 용 minGW가 없어서 해당 옵션이 정상동작하지 않습니다. cygwin에서 minGW로 컴파일하려는 경우에는 gcc-3 –mno-cygwin 명령을 주셔야 하는 거죠.

쩝.. 대략 귀찮음

합성할 때 시뮬레이션에 사용한 list을 이용하기

합성 스크립트 만들다가 얼마전에 모 선배가 합성에 필요한 파일 리스트 만드는 거 귀찮다고 한 것이 기억나서 만들어봤습니다.
뭐, TCL을 사용하시는 분들이면 다들 생각하실 만한 것이라 팁이라고 할 것 까지야 없겠습니다만, 처음 접하시는 분들에게는 도움이 될 것 같아서 올립니다.
보통 ncverilog로 시뮬레이션 할때 (다른 것도 마찬가지지만…), .f 파일로 불리는 파일리스트를 만들어서 사용하는데, 합성할때 이걸 왠만하면 사용할 수 있습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
set LIST_FILE "../../vlist.f"
set RTL_FILES ""
if [ catch { open $LIST_FILE r } fileID ] {
      puts stderr "ERROR: $fileID"
      puts stderr "Can not open file ${LIST_FILE}"
      quit
  } else {
   while { [gets $fileID lbuffer] >= 0 } {
      if {[ regexp {(^/{2})} $lbuffer test1 ]} { continue }
      if {$lbuffer == ""} { continue }
      lappend RTL_FILES $lbuffer
    }
  }
  close $fileID
  foreach design $RTL_FILES {
    analyze -format verilog $design
  }
  elaborate $DESIGN_TOP
set LIST_FILE "../../vlist.f"
set RTL_FILES ""
if [ catch { open $LIST_FILE r } fileID ] {
      puts stderr "ERROR: $fileID"
      puts stderr "Can not open file ${LIST_FILE}"
      quit
  } else {
   while { [gets $fileID lbuffer] >= 0 } {
      if {[ regexp {(^/{2})} $lbuffer test1 ]} { continue }
      if {$lbuffer == ""} { continue }
      lappend RTL_FILES $lbuffer
    }
  }
  close $fileID
  foreach design $RTL_FILES {
    analyze -format verilog $design
  }
  elaborate $DESIGN_TOP
위의 코드 보시면 아시겠지만, 파일을 읽어서 리스트에 넣는 것 이외에는 특별한 것이 없습니다.
단지, 공백행 처리와 주석 처리 부분이 들어가 있습니다.
만일 f 파일에서 ++ 옵션을 사용하시는 분은 여기에 대한 처리를 추가해 주시면 편합니다. (필요하시다면 해당 부분에 간단한 parser를 걸어도 되구요)
요즘은 directory단위로 읽을 수 있는 acs_read_hdl가 더 널리 사용되는 추세입니다. list 파일이 없다면 이것이 절대적으로 편하지요. 디렉토리만 지정하면 subdirectory 뒤져서 파일을 끌고 오니까요.
단, 필요없는 파일은 EXCLUDE_LIST로 지정해야 되어서 약간 귀찮을 때가 있긴합니다.
list가 있다면 위의 코드를 사용하는 것이 더 편하시겠지요.
여하튼.. 도움이 되면 좋겠습니다.
참고적으로 list file에 $MY_HOME/aaa/aaa.v 와 같은 형태로 지정된 경우 위와 같은 analyze를 사용할 수 없습니다. 이때는 간단하게 subfunction을 하나 만들고 synopsys에서 제공하는 parse_proc_arguments 함수를 이용해서 이걸 처리하면 됩니다.[1]더 간단하게는 eval을 사용하면 됩니다만 복잡해지면 subfunction이 더 편하죠
이 방법은 나중에 설명하죠 ^^;
참고적으로 합성 과정에서 define할 것이 없다면 analyze 대신 read_verilog를 사용하셔서 위의 문제를 쉽게 해결 할 수 있습니다. read_verilog는 이미 parse_proc_arguments 를 사용하고 있거든요

References   [ + ]

1. 더 간단하게는 eval을 사용하면 됩니다만 복잡해지면 subfunction이 더 편하죠