ARM이야기(2): ARM 프로세서의 탄생

최초의 상용 RISC프로세서
1999~2001년에 ARM7, ARM9호환 프로세서를 설계하면서 느꼈던 의구심은 “과연 ARM이 아키텍쳐관점에서 좋은가?” 였다. Instruction Set도 뭔가 허술하고, RISC라고 하기엔 다중싸이클(multi-cycle) 동작도 많고, 뭔가 부족한 느낌을 지울 수 없었기 때문이다.

이 후 ARM은 엄청난 성장을 이루어냈지만, 개인적으론 어떻게 ARM의 아키텍쳐가 만들어졌는지가 더 궁금하다.

관련자료를 찾던 중 몇가지 새로운 사실을 알게 되었다.
먼저 ARM이 최초의 상용 RISC 마이크로프로세서라는 것이다. 그동안 RISC프로세서의 효시는 Berkeley RISC-I(1981)이고 최초의 상용 RISC는 MIPS R2000(1985)로 알고 있었던 사실을 뒤집는 것이었다. 이 부분은 이견이 있을 수 있는데 RISC는 관점에 따라 1970년대에도 존재했기 때문이다.

어째됐건 최초의 ARM이 80년대 초반에 만들어졌다는 것은 상당히 놀라운 일이다. 8비트 컴퓨터가 대부분이고 16비트 마이크로프로세서인 인텔 80286이 막 개발된 1983년에 32비트 마이크로프로세서를 만들려고 했다는 시도 자체가 매우 놀랍다.

어떻게 ARM프로세서가 만들어졌는가?
ARM 프로세서는 Acorn Computers에서 개발하였다. Acorn Computers는 1979년에 영국에서 만들어진 회사로 애플컴퓨터에 사용했던 6502프로세서를 이용한 BBC Micro란 컴퓨터를 1982년 개발하여 큰 성공을 거두었다.

Acorn BBC Micro (1982)

1983년 BBC Micro로 성공 거둔 Acorn Computers는 보다 높은 성능의 컴퓨터를 개발하기 위해 ARM(Acorn RISC Machine, ARM의 현재 이름인 Advanced RISC Machine과 다르다)프로세서를 개발하기 시작한다.

애플 매킨토시에 사용되었던 Motorola 68000이 이미 1979년에 만들어졌고, IBM PC에 사용된 Intel 80286도 1982년에 출시되어 사용할 수 있었는데도 불구하고 새로이 프로세서를 만들 생각을 한 배경이 궁금하지않을 수 없다.

Acorn으 BBC Micro는 애플1, 애플2와 같이 MOS Technology의 8비트 6502프로세서를 사용하고 있었으므로 이들의 기준은 6502였다. 이들은 80286을 사용한 IBM-PC가 8비트 컴퓨터인 BBC Micro보다 오히려 더 느리다는 사실을 발견했다. 특히 80286의 인터럽트가 6502의 인터럽트에 비해 엄청 느리다는 것을 알게 되었는데 그것은 사실 6502의 interrupt latency는 8비트 프로세서중에서도 가장 빠르기 때문에 그렇게 느끼는 것도 당연했다.

인터럽트의 개념 (출처: 6502.org)

당시의 16비트 프로세서의 성능에 크게 실망한 Acorn은 획기적인 시도로 32비트 프로세서를 개발하기로 결정하였다.

지금과 같이 클록주파수나 MIPS(Million Instruction per Second)와 같은 프로세서의 성능을 나타내는 기준이 없던 시절에 이들이 세운 목표는 “BASIC으로 작성한 프로그램이 6502에서 기계어로 작성한 프로그램의 속도로 동작하는 것”이었다.

하지만 가장 큰 문제는 Acorn은 마이크로프로세서를 개발할 능력을 갖고 있지 않았다. 프로세서를 개발한 경험도 없었을 뿐만아니라 당시 마이크로프로세서를 만들던 회사들 처럼 수백명의 개발인력을 프로세서 개발에 투입할 수 있었던 것도 아니었다. ARM을 개발했던 Steve Furber와 Sophie Wilson이 주목한 것은 대학원생 몇명이 1년만에 개발한 Berkeley RISC-I이었다.

Acorn의 사장이었던 Hermann Hauser는 ARM 프로세서의 성공비결은 당시 돈도 없었고 개발인력도 없었기 때문에 단순한 구조로 개발 할 수 밖에 없었기 때문이라고 회고한다.

ARM설계에 대한 내용은 추후 연재글에서 다시 한번 자세히 다뤄보도록 하겠다.
7명이 1년반동은 첫번째 ARM프로세서를 설계하였고, 당시 ARM의 기술에 관심을 가졌던 VLSI Technology에서도 칩셋개발을 지원하였다. 첫번째 ARM프로세서 역시 VLSI Technology에서 제작되었다.

첫번째 ARM프로세서(1985)

1985년 첫번째 ARM프로세서 개발이 성공하고, 1987년에는 ARM2를 이용한 Acorn Archimedes도 출시한다. 애플의 매킨토시(1984) 보다 시기적으로 늦긴 했으나 GUI환경을 갖추고 있는 것이 인상적이다.

Acorn Archimedes (1987)

Acorn의 Desktop PC는 Unix와 유사한 강력한 OS인 ARX를 개발하는데 너무 많은 시간을 소비하여 뒤늦게 출시되어 80년대 말 IBM PC, 매킨토시와 경쟁에서 뒤쳐져 자취를 감추었다.

그동안 Acorn을 창립한 Hermann Hauser는 1988년에 Active Book이라는 PDA개발 사업을 시작했다. 그리고 ARM2 Processor를 개선하여 저전력 프로세서인 ARM2aS를 개발하였다. 빠른 처리속도에 저전력 기능까지 추가된 ARM프로세서는 당시 PDA개발을 하던 애플 컴퓨터의 관심을 사게 되었고 애플의 뉴튼 메시지패드에 사용되게 되었다.

애플 뉴튼 메시지패드(1994)

애플 뉴튼은 본래 AT&T의 Hobbit 프로세서를 사용할 계획이었으나 속도, 저전력, 저가이고 커스텀 설계가 가능한 ARM을 채택한 것은 어쩌면 당연한 일이었다. 애플의 뉴튼은 실패로 끝났으나 결국 아이폰으로 재탄생하였고 여전히 ARM프로세서를 사용하고 있다.

ARM의 독립 그리고 발전
애플이 뉴튼을 개발하는 동안 상당히 많은 영향을 만들었는데, 첫번째는 ARM프로세서를 Acorn 컴퓨터로부터 독립시킨 것이다. 앞서 설명한 것처럼 당시 Acorn 컴퓨터는 애플의 경쟁사였기 때문이었고, ARM의 약자도 Acorn RISC Machine에서 Advanced RISC Machine으로 바뀌게 된다. 1990년에 ARM이 창립되게 되고 애플과 VLSI Technology의 지원을 받게 된다.

ARM610 (1993)

애플의 지원을 받기 시작하며, 애플 뉴튼에 사용하기 위한 프로세서를 본격적으로 개발하기 시작한 ARM은 ARM3 프로세서의 성능을 개선한 ARM6를 만들고 캐쉬메모리와 메모리관리기능(MMU)을 추가한 ARM610을 개발하여 뉴튼에 탑재하게 된다.

애플 뉴튼에 사용된 ARM프로세서에 관심을 갖게된 DEC(Digital Equipment Corportation)에서는 1995년 ARM 명령어를 license하여 StrongARM을 개발하기 시작한다. 1995년에 개발된 StrongARM SA-110은 최대 200MHz까지 동작했다. DEC의 경영위기로 인해 StrongARM은 1997년 인텔에 매각되었으며 인텔은 StrongARM을 바탕으로 StrongARM-2와 XScale을 개발한다. 하지만 인텔은 XScale을 제대로 활용하지 못하고 결국 2006년 Marvell에 다시 매각한다.

DEC에서 개발한 StrongARM(1995)

한편 뉴튼에 사용된 ARM6는 훗날 백억개이상 판매한 ARM7TDMI로 발전하고 애플 iPod에 사용되기 시작했으며, ARM9, ARM11, Cortex아키텍쳐로 발전하여 아이폰, 아이패드까지 ARM 프로세서를 사용하기에 이른다. 그리고 머지않아 ARM프로세서를 사용한 맥킨토시를 볼 수 있을 것이라 예상해본다.

ARM Cortex-A8을 사용한 A4프로세서(2010)

ARM이야기(1): ARM과 인텔 x86 아키텍쳐

지난 15년간 ARM에 대해 가졌던 여러가지 생각들, 기술적인 내용, 개인적인 추억 등을 ARM 호환 프로세서를 설계했던 설계자 입장에서 써보려고 합니다. 2010.11. 0donny

ARM과의 첫 만남

ARM(Advanced RISC Machine)에 대해 처음 알게 된 것은 1996년이었다. 당시 GEC-Plessey의 GPS Chipset과 호환 되는 칩셋 개발에 참여했었는데 ARM60이라는 생소한 프로세서를 사용하는 것을 알게 되었다. 아주 작은 칩이었는데 인텔 80386 보다 빠르다는 것이었다.

임베디드(embedded)라는 개념조차 없던 시절. 당시에 추측하기론 80386의 인터럽트 반응이 느리기 때문에 반응이 빠른 ARM60의 성능이 높은 것뿐이지 복잡한 연산은 당연히 386이나 486이 빠를 것이라고 생각했었다. 불과 조금 전까지…

혹시나 해서 자료를 찾아보니 ARM60의 성능이 80386 보다 높고, ARM60에 4K cache를 추가한 ARM610486 초기 제품과 동등한 수준이었다. 회로적인 복잡도의 차이를 생각하면 이것은 엄청난 성능이다. 게다가 인터럽트 반응은 ARM이 월등히 빠르니 이후 리얼타임 임베디드 분야(real-time embedded application)에 ARM이 승승장구한 것은 자연스러운 일이었다.

초기 ARM코어(ARM1 ~ ARM6)는 겨우 트랜지스터 3만개로 이루어져있다.
트랜지스터 7만개의 모토롤라 68000의 절반, 27만개가 넘는 80386의 10분의 1밖에 안되니 ARM Architecture는 상당히 간결하다는 사실을 짐작할 수 있다.

ARM1의 구조(1985)

80386의 구조(1985)

ARM1과 80386의 실제 칩 내부를 비교해보면, ARM Core에는 없는 MMU(Memory Management Unit)가 존재한다. 본래 x86은 16-bit 구조이었기 때문에 64Kbyte(=2^16) 보다 큰 메모리의 접근을 위해 MMU가 불가피한 반면, ARM은 32-bit 구조(초기엔 26-bit 주소)라 MMU가 없어도 4Gbyte까지 메모리 접근이 가능했다.

MMU를 배제하고 Core부분만 비교해도 ARM1의 면적은 80386의 4분의 1정도밖에 되지않는다.
RISC 명령의 간결함이 명령어 디코더(Instruction Decoder)의 크기와 명령어 시퀀서(Instruction Sequencer)의 크기에 얼마나 큰 차이를 만드는 지 알 수 있다. ARM1은 PLA한개를 이용해 명령어 를 해석(decode)하고 또다른 PLA하나로 실행(sequence)하는 반면, 80386은 3개의 PLA로 명령어를 해석하고 커다란 Microcode ROM을 이용하여 명령어를 실행하도록 설계되어있다.

ARM초기설계에 대한 상세한 내용은 The History of ARM Architecture를 참고하기 바란다.

15년이 지난 지금…

놀랍게도 ARM은 Intel과 전쟁을 벌이고 있다.
작년 11월 ARM Technical Symposium에 참석했을 때, ARM은 Intel과의 전면전을 선언한 듯 보였다. “꿈에도 생각 못한 상황이 벌어진다”, “게임의 법칙이 바뀌고 있다”며 Windows/Intel를 상대로 승산이 있다고 했다.

Smartphone의 붐과 Android와 Chrome OS의 선전을 바탕으로 Smartphone과 Netbook의 중간에 새로운 시장이 생길 것으로 보고 이를 선점하기 위한 Ecosystem을 구축하기 위해 막대한 투자를 하고 있는 것으로 보였다.

ARM과 Intel중 누가 승리할 것인가에 대해 많은 추측들이 있고 ([1],[2],[3],[4],[5])
ARM이 Mobile Market에서 승리할 것이라고 예견하는 견해도 적지않다.([1],[2],[3]) 개인적으로는 ARM의 승리를 응원한다.

지난 9월 ARM은 최신 프로세서 아키텍쳐인 Cortex A-15를 발표했다.
이미 ARM의 Cortex-A8과 Cortex-A9이 동일 클록주파수 기준으로는 Intel의 Atom 프로세서보다 성능이 빠르지만, 2.5GHz까지 동작하는 Cortex-A15의 발표로 Intel에 확실한 비교 우위를 차지하려는 것으로 보인다.

마이크로프로세서, ASIC, 설계방법론의 역사

어제 발견한 Computer History Museum에 재미있는 내용들이 있어서 소개합니다.

공교롭게도 어제가 부울(Boole)이 태어난지 195년째 되는 날이었군요. 컴퓨터를 포함한 모든 논리회로는 부울 연산(Boolean Algebra)을 사용하죠.

이전 글에서 언급했듯, 1970년대에 이미 지금의 마이크로프로세서 설계기술이 거의 완성이 되었습니다.

1979년에 만들어진 M68000 프로세서의 각 기능블록들을 표시해보았습니다. Anceau의 책을 보고 직접 표시해 본 것입니다.

모토롤라 M68000 Die Photo 및 각 기능블록 [크게보기]

공정기술의 한계로 복잡도가 제한되었지만 2000년대에 만들고 있는 프로세서에 비해 그 설계기술은 크게 떨어져보이지 않습니다.

그렇다면 저 당시에는 어떤 방법으로 저런 설계를 했을까요?
지금은 당연시 사용하고 있는 설계방법론, 설계툴은 언제부터 존재 했던 것일까요?

그 해답도 Computer History Museum에서 찾을 수 있었습니다. (1960년에 강대원 박사의 이름도 찾아볼 수 있습니다)

EDA (Electronic Design Automation) 툴은 처음부터 IC를 위해 개발한 것은 아니고, 1950년대 후반부터 IBM에서 연구하기 시작했습니다. 60년대에 Logic Simulator도 개발되고 P&R(Place & Route) 소프트웨어도 만들었다고 합니다.

1967년 Fairchild의 CAD시스템

그리고 1967년에 드디어 게이트어레이와 Standard Cell이 처음 개발되었다고 합니다. 그리고 UC버클리에서 60년대에 SPICE 시뮬레이터도 개발 되었습니다.

당시 EDA툴이 어떤 것인지 또 어떻게 설계를 했는지 궁금해서 자료를 찾다가 발견한 1978 MIT의 VLSI System Design 수업자료로 당시의 모습을 상상해볼 수 있습니다.

Layout: CAD 환경이라고는 하지만 Layout 좌표를 일일히 CIF format에 맞춰 입력한 다음, 펜 플로터로 출력해서 확인해보는 것입니다.

Layout

DRC(Design Rule Check): 잘은 몰라도 자(ruler)를 가지고 Design Rule을 Check했을 것 같습니다.

Design Rule Check

Floorplan: 블록의 크기별로 종이를 잘라서 배치했었군요.

Floorplaning

참, 펜 플로터가 뭔지 잘 모르시는 분들도 계실 것 같네요.

Pen Plotter

90년대엔 VLSI를 개발하는 회사나 연구실엔 꼭 Plotter로 출력한 Layout이 벽에 걸려있었습니다. 저는 이게 그냥 장식용인 줄 알았는데, 원래는 마지막으로 전체 칩을 출력하여 문제가 있는지 확인하기 위한 절차였네요. 인텔에서 큰 방 가득하게 레이아웃을 출력해놓고 검토했다는 말도 생각납니다.

Final sanity check

한가지 더 놀라운 사실은 MIT에서 1979년과 1980년에 MPC(Multi-Project Chip)을 만들었다는 것입니다. 그리고 나중에 MOSIS로 발전하게 됩니다.

최초의 MPC(Multi-Project Chip)

MOSIS는 적은 비용으로 좋은 공정에서 칩을 만들 수 있는 MPW(Multi-Project Wafer)를 운영하고 있습니다. 반도체교육센터(IDEC)에서 운영하고 있는 MPW도 MOSIS를 모델로 한 것입니다.

Xerox PARC의 EDA환경

MIT의 교과 수업환경은 아무래도 회사보다 열악할테고, 당시(1979년) Xerox PARC에서 MPW용 DB들을 Merge하고 있는 것으로 보이는 사진을 보면 회사의 EDA환경은 Layout을 마우스와 GUI환경으로 하는 것처럼 보입니다. (Xerox PARC의 마우스와 GUI환경은 애플 Machintosh가 채택한 것으로 유명하죠)

설계환경은 열악하지만 당시 강의자료를 살펴보면 그 내용만큼은 정말 훌륭합니다.
The MIT’78 VLSI System Design Course: A Guidebook for the Instructor of VLSI System Design

지금은 거의 찾아볼 수 없는 직접 글씨를 쓰고 그림을 그려가며 만든 강의자료도 인상적이지만, 그 내용은 지금 대학원 강의교재로 써도 전혀 손색이 없겠네요.

당시 수업을 했던 Lynn Conway의 저서 “Introduction to VLSI Systems“는 김보관교수님이 갖고 계신걸 본 기억이 있는데, 그저 오래된 책이라 생각하고 지나쳤었습니다. 책 내용(draft)을 살펴보니 1979년 책이라고는 상상할 수 없는 그 방대한 지식에 놀랐습니다.

그리고 Computer Architecture에 대한 내용도 눈에 띄어 Lynn Conway의 경력을 살펴보니 Supercomputer/Superscalar의 원조겪인 IBM ACS의 Architect였더군요. Dynamic Instruction Scheduling, Multithreading 등의 자료를 보면 지금의 컴퓨터 구조는 정말 70년대에 이미 완성 되었다는 생각이 듭니다.

1979년에 Single Chip DSP(Digital Signal Processor)도 등장합니다.

로직 합성(Logic Synthesis)는 1980년대에 UC버클리의 SIS, UCLS의 RASP 그리고 콜로라도대학의 BOLD 등의 연구가 기반이 되었습니다. UC버클리의 espresso는 상당히 성능이 좋았고, 저도 예전에 PLA설계에 사용했었습니다.

이러한 연구의 영향을 받아 1986년에 Synopsys가 창립하고 케이던스의 전신인 Automated Integrated Design Systems(1983년창림, 1985년에 Gatewaey Design Automation으로 개명)에 의해서 1984년에 Verilog언어가 만들어 졌습니다.

1984년으로의 시간여행 (CPU, 애플, 카라테카)

요새 다시금 CPU의 역사를 되돌아보는 중입니다. 구글로 검색하다보니 시간 가는 줄 모르겠네요.

어제는 1974년부터 2004년까지의 CPU들을 체계적으로 정리해 놓은 cpu-collection.de를 발견했었는데, 오늘은 각종 CPU의 칩사진(die photo)까지 정리 해 놓은 CPU World를 발견했습니다.
인터넷에는 참 좋은 자료가 많이 있군요.

제가 컴퓨터 구조를 공부할 때 보던 책이 Francois AnceauThe Architecture of Microprocessors (Addison-Wesley 1986) 였습니다. 이 책을 보면 모토롤라의 M68000이 개발된 1979년에 이미 마이크로프로세서 설계기술이 거의 완성이 되었다는 사실을 알 수 있습니다.

Anceau책과 M68000 die photo

CPU World에서 M68000을 비롯한 70~80년대에 개발한 CPU들의 die photo를 보면서 현재 사용되고 있는 CPU/마이크로프로세서들이 공정기술을 제외하고 80년대의 프로세서보다 더 나은게 과연 무엇인가… 하는 생각을 했습니다.

다가 문득 Apple ][에 사용되었던 MOS Technology 6502 프로세서가 궁금해져서 찾아보니, 이 40년된 프로세서에 아직도 애착을 갖고 있는 분들이 많다는 사실을 발견했습니다. www.6502.org 에 많은 자료들이 있습니다.

이 자료들을 찾다가 애플2의 에뮬레이터가 있다는 것도 알게 되었고 애플2 컴퓨터를 Java로 구현해놓은 virtualapple.org 도 발견하였습니다. 그 중에서도 제일 반가웠던 것은 바로 초등학생때 하던 카라테카를 그대로 다시할 수 있었던 것입니다. 25년이 지났는데 아직까지 기억이 생생하다는 사실에 놀랐습니다.

그런데 주인공캐릭터의 모습과 움직임에서 IBM XT게임인 페르시아의 왕자가 겹쳐보이기 시작하는 것이었습니다. 특히 달려가는 모습… 결정적으로 문에서 철창에 찍혀죽는 모습(위 사진 중 마지막)에선 확신을 갖게 되었습니다. 문을 통과하면서.. “어 여기 그냥 지나가면 칼날이 나와서 잘려죽을 것 같은데? 아참? 그건 페르시아의 왕자인가?”하면서 지나가다 찔려 죽었습니다. ^^;;

게임이 끝나고 나오는 화면을 보니 “Broderbund Software”라는 이름도 굉장히 익숙해 보이더군요. 검색을 시작했고 카라테카나 페르시아왕자가 모두 동일 개발자 Jordan Mechner 의 작품이었습니다. 그리고 페르시아의 왕자가 Apple 2 용으로 개발되었다가 IBM XT용으로 컨버젼 됐다는 사실도 알게 되었습니다. (Apple2 버젼도 virtualapple.org에서 실행가능합니다.) 애플2버젼은 그래픽이 다소 떨어지지만, 자연스러운 움직임은 그대로네요. 애플에서 이정도의 움직임을 구현하다니 정말 대단합니다.

Apple2용 페르시아의 왕자

왜 어릴적에는 같은 사람이 만든 게임이란 사실을 몰랐을까 생각해보았습니다. 지금이야 1984년이나 1989년이나 그때가 그때 같지만, 당시엔 카라테카를 했던 것은 초등학생 시절이었고, 페르시아의 왕자는 고등학생때 였으니 중간에 큰 시간적 공백이 있었던 것이죠. 페르시아의 왕자를 처음보고 카라테카를 떠올렸던 것은 같습니다만, 구글이 없이 검색해 볼 방법도 없고 애플컴퓨터를 다시 찾아 실행해서 제작자 이름을 비교해볼 수도 없었던 것이죠.

아무튼 컴퓨터의 역사를 공부하다 기억속에 끊어진 연결 고리를 발견하니 참 재미있군요.

[Verilog] 새로 컴파일하지 않고 테스트 입력/조건을 바꾸는 방법

Compiled-code방식 Verilog 시뮬레이터는 크게 세단계로 동작합니다.

  1. Compile: Verilog Code의 문법을 체크하고, 해석하고(parse/analyze)하고 Compile한다.
  2. Elaboration: 계층구조(design hierarchy)를 구축하고 신호들을 연결하고 초기값을 계산한다.
  3. Simulation: 회로의 동작을 시뮬레이션한다.

복잡하게 나누어 생각하고 싶지 않은 분들도 계실텐데, C프로그램을 해보신 분들이라면 쉽게 이해할 수 있습니다.

  1. Compiler: C컴파일러를 이용해서 C 코드를 Object코드로 만드는 것과 유사합니다.
  2. Elaboration: Object코드를 Linker로 연결해서 실행화일(Executable)을 만드는 것과 유사합니다. C Code건, 어셈블리코드건 언어에 관계없이 Object코드는 동일한 것과 같이 Elaboration은 VHDL와 Verilog를 구분하지 않습니다.
  3. Simulation: 실행화일(Executable)을 실행하는 것과 같습니다.

여기서 주목할 부분은 프로그램을 실행할때 매번 새로 컴파일하지 않고 실행화일만 실행하듯이, 시뮬레이션도 컴파일 과정을 생략할 수가 있다는 것입니다.

컴파일에 소요되는 시간이 전체 시뮬레이션에서 차지하는 시간이 크지 않은 경우도 많지만, 설계가 복잡하고 매우 다양한 경우에 대해서 시뮬레이션(regression)을 할 경우, 이 시간을 줄이는 것이 적지않은 효과가 있습니다.

물론 Verilog 소스코드가 변경된 경우라면 새로 컴파일을 해야합니다만, 사진이 바뀌고 모니터 해상도가 바뀌었다고 포토샵을 새로 컴파일하지 않듯이, 시뮬레이션 입력, 조건만 바뀌었을 경우엔 새로 컴파일 할 필요가 없습니다.

Cadence NC-Verilog를 기준으로 설명해보겠습니다.
NC-Verilog는 두가지 방법으로 실행이 가능한 데 single-step으로 실행하는 command인 ncverilog과 3-step으로 실행하는 command인 ncvlog, ncelab, ncsim이 있습니다.

3-step으로 실행하는 경우엔 마지막 단계인 ncsim만 반복적으로 실행하면 됩니다.

$ ncvlog subblock1.v subblock2.v topmodule.v
$ ncelab topmodule
$ ncsim topmodule
$ ncsim topmodule (재실행)

ncverilog를 사용하는 경우엔 ncverilog -R 옵션을 이용하면 마지막 simulation단계만 실행하게 됩니다.
3-step으로 실행하는 경우엔 마지막 단계인 ncsim만 반복적으로 실행하면 됩니다.

$ ncverilog subblock1.v subblock2.v topmodule.v
$ ncverilog -R (재실행)

이렇게 컴파일을 하지 않고 시뮬레이션만 다시 실행하면서 입력을 바꾸는 방법은 다음과 같습니다.
1. 외부파일을 사용하는 방법
Image processing을 하는 회로라고 가정하면 입력은 주로 사진 데이터입니다. 시뮬레이션 중에 사진 파일을 읽어서 사용하도록 만들면, 사진 파일만 바꿔주면 컴파일과정없이 시뮬레이션을 할 수 있습니다. 대신 외부파일을 읽어들이는 부분(parser)를 Verilog나 C언어로 구현해야합니다.

Verilog로 구현하는 경우엔 C언어와 유사한 $fopen, $fscanf을 이용하면 됩니다. 단, 텍스트파일만 읽을 수 있으므로 PPM과 같은 ASCII 데이터의 파일 format을 사용해야합니다.

C언어를 이용하는 경우 원하는대로 프로그램을 작성하여 decoding이 필요없는 BMP를 비롯, 다양한 입력을 읽어들일 수 있습니다. Verilog의 PLI(Programing Language Interface)나 SystemVerilog의 DPI(Direct Programming Interface)를 이용하면 됩니다.

2. $test$plusargs, $value$plusargs 를 이용하는 방법

$test$plusargs()는 Verilog-1995에도 존재했던 기능이고, $value$plusargs()는 Verilog-2001에서 확장된 기능입니다.

간단한 예로 시뮬레이션 결과를 waveform으로 저장하면 시뮬레이션 속도가 상당히 느려지고, 저장공간을 많이 차지할 수 있습니다. 따라서 필요한 경우에만 signal dump를 받게 되는데 이를 위해 대개 사용하는 방법은 다음과 같습니다.,

1. Verilog코드를 수정해서 $dumpvars와 같은 구문을 주석으로 처리한 뒤 새로 컴파일합니다.

initial
begin
      // $dumpvars;
end

2. `ifdef / `ifndef 를 이용하는 방법. command line에서 설정이 가능하므로 보다 깔끔한 방법이지만, 이 방법 역시 새로 컴파일을 해야합니다.

initial
begin
     `ifndef nodump
            $dumpvars;
     `endif
end

$ncverilog +define+nodump …..

이런 경우 $test$plusargs를 이용하면 됩니다. +define을 사용하는 것과 유사하지만 새로이 컴파일을 할 필요가 없습니다. (-R 옵션에 주목)

initial
begin
      if(!$test$plusargs(“nodump”))
             $dumpvars;
end

$ ncverilog -R  (dump파일 생성)
$ ncverilog -R +nodump (dump파일 생성 안함)

참고로, 간단히 설명하기 위해 dumpvars를 사용했는데, vcd형식보다 shm이나 fsdb형식을 사용하면 속도,용량에 개선 효과가 있습니다.

$value$plusargs 를 이용하면 command line에서 10진수, 16진수, 2진수, 실수 등 보다 상세한 입력이 가능합니다.

$value$plusargs (string, variable)
%b – binary conversion
%d – decimal conversion
%e – real exponential conversion
%f – real decimal conversion
%g – real decimal or exponential conversion
%h – hexadecimal conversion
%o – octal conversion
%s – string (no conversion)
%x – (undergound equivalent for %h)

예제로 클럭 주파수를 바꾸는 경우를 살펴봅시다.

filename: test.v

module test;

reg     clock = 0;
real    clock_h_period;
always #clock_h_period
       clock = !clock;
initial begin
       if(!$value$plusargs(“clock_h=%F”, clock_h_period)) begin
               clock_h_period = 10;
       end
       $monitor(“%t %b”, $time, clock);
       #100 $finish;
end
endmodule

$ ncverilog test.v +nocopyright
Loading snapshot worklib.test:v ……………….. Done
ncsim> source …/tools/inca/files/ncsimrc
ncsim> run
                  0 1
                 10 0
                 20 1
                 30 0
                 40 1
                 50 0
                 60 1
                 70 0
                 80 1
                 90 0
Simulation complete via $finish(1) at time 100 NS + 0
./test.v:15     #100 $finish;
ncsim> exit
$ ncverilog -R +clock_h=20 +nocopyright
Loading snapshot worklib.test:v ……………….. Done
ncsim> source …/tools/inca/files/ncsimrc
ncsim> run
                  0 1
                 20 0
                 40 1
                 60 0
                 80 1
Simulation complete via $finish(1) at time 100 NS + 0
./test.v:15     #100 $finish;
ncsim> exit

반복 회수를 입력하거나, Random 값 생성에 사용할 seed입력(@KyonghoKim의 코멘트)하거나 다양한 환경적인 변수에 대한 반복적인 시뮬레이션(regression)을 수행할 때 유용할 것입니다.

Computer Architecture 공개 강의 추천

1년 전 David Harris교수의 강의자료를 추천드린 적이 있었는데, 오늘 우연히 또 발견한 강의가  상당히 좋아서 추천드립니다.

인도 IIT의 S. Raman교수의 컴퓨터 구조론 동영상 강의입니다. (따라서 인도식 영어 엑센트는 감안하시고 보셔야합니다)
http://nptel.iitm.ac.in/video.php?courseId=1050

Flip-flop보다 마이크로아키텍쳐를 먼저 가르치는 상식 파괴의 접근법이 놀랍습니다. 그리고, Textbook없이 모든 그림을 직접 그리면서 설명하는 것도 멋지군요. 슥슥 컴퓨터 구조를 그리면서 별것 아니라는 듯 가르치는게 KAIST 조규형 교수님을 떠올립니다.

Raman교수의 Datapath 구조 강의 중

제가 작년에 사용했던 강의 자료 중

Youtube 검색 중 저 Datapath그림이 썸네일에 눈에 띄어서 살펴본 것인데요. 작년에 제가 충남대에서 강의할때 이해를 돕기위해 고민해서 만든 자료와 상당히 유사합니다. 같은 접근방식을 사용한다는게 반가웠고, 한학기 컴퓨터 구조 강의가 모두 제가 추구하는 방식으로 설명되어있을 것을 생각하니 벌써 행복해지네요. 아직 몇시간 분량 밖에 못보았는데 틈틈이 다 봐야겠습니다.

NPTel이 무엇인가 찾아보니 인도 정부에서 지원하는 “국가 기술향상 교육 프로그램”이라고 합니다.
다른 과목에 대한 강의도 공개되어있습니다. (모두 동영상 강의가 있는 것은 아니더군요)
http://nptel.iitm.ac.in/courses.php?branch=Comp

내친김에 공개 강의 정보를 검색해보았더니 잘 정리해 둔 글이 있네요.
http://blog.naver.com/csps2010/130093140514

국내에도 KOCW라는 싸이트에 공개 강의가 많이 있습니다. 최근 TED/TEDx로 인해 공개 강의에 관심이 많아지는 것 같습니다.

이제 의지만 있다면 인터넷에 공개된 강의자료 만으로도 상당한 수준의 지식을 얻을 수 있을 것 같습니다. 저도 유용한 자료들을 찾아 틈틈히 공부를 하고 또 공유해야겠다는 다짐을 해봅니다.

OpenSparc Coding Style

OpenSparc을 좀 들여다 보기로 하고선 진도가 잘 안나가네요.

제가 OpenSparc에서 관심 가졌던 부분은 몇가지가 있습니다. 그중 한가지가 코딩 스타일입니다.
참고로, 소스코드를 다운로드하지 않아도 Web으로도 간단히 T1T2의 코드를 직접 확인하실 수 있습니다.

먼저 Naming Convention입니다.
방대한 분량 (T1의 경우 33만6천라인)의 설계를 하기 위해선 분명 적지않은 개발자가 참여했으므로 체계적이고 명확하고 효율적인 Naming Convention이 존재하리라 기대했으나 기대했던 수준은 아닌 것 같습니다.

인상적인 부분 몇가지는 signal name과 module name이 상당히 깁니다. 특히 module name이 긴데 ‘sparc_exu_aluadder64′ 정도의 길이는 보통입니다. 명확한 대신 한눈에 안들어온다는 단점, module name을 입력할 때 수동으로 입력하면 틀리기 십상이라 반드시 자동완성 기능을 사용해야 되겠더군요.

특징적인 부분은 always문이 매우 적은 빈도로 사용되어있습니다.
flip-flop이 필요한 곳은 아래와 같이 D flip-flop을 가져다가 사용하고 있기 때문이긴 하지만 상당히 의외네요. 그렇다면 FSM(Finite State Machin)을 어떻게 구현했나 찾아보니, 일반적인 FSM 형태로 구현된 부분은 Thread State Machine과 Miss Instruction List State Machine 두개 밖에 없군요.

wire [1:0] thrid_m, thrid_g ;
dff #(2)  stgm_thrid (
       .din    (
ifu_tlu_thrid_e[1:0]),
       .q      (thrid_m[1:0]),
       .clk    (
clk),
       .se     (1′b0),       .si (),         
.so ()
       );

dff  #(2) stgg_thrid (
       .din    (
thrid_m[1:0]),
       .q      (thrid_g[1:0]),
       .clk    (
clk),
       .se     (1′b0),       .si (),         
.so ()
       );

dff  stgw_ivld (
       .din    (
flush_w_inst_vld_m),
       .q      (lsu_inst_vld_tmp),
       .clk    (
clk),
       .se     (1′b0),       .si (),         
.so ()
       );

이렇게 버스 단위로 D flip-flop을 instanciation하거나

dff  #(4) ivld_stgw2 (
       .din    ({
ld0_inst_vld_g,ld1_inst_vld_g,ld2_inst_vld_g,ld3_inst_vld_g}),
       .q    ({ld0_inst_vld_w2,ld1_inst_vld_w2,ld2_inst_vld_w2,ld3_inst_vld_w2}),
       .clk  (
clk),
       .se     (1′b0),       .si (),         
.so ()
  );

dff  #(4) th_stgm (
       .din    ({
thread0_e,thread1_e,thread2_e,thread3_e}),
       .q      ({thread0_m,thread1_m,thread2_m,thread3_m}),
       .clk  (
clk),
       .se     (1′b0),       .si (),         
.so ()
  );

dff  #(4) th_stgg (
       .din    ({
thread0_m,thread1_m,thread2_m,thread3_m}),
       .q      ({thread0_g,thread1_g,thread2_g,thread3_g}),
       .clk  (
clk),
       .se     (1′b0),       .si (),         
.so ()
  );

dff  #(4) th_stgw2 (
       .din    ({
thread0_g,thread1_g,thread2_g,thread3_g}),
       .q      ({thread0_w2,thread1_w2,thread2_w2,thread3_w2}),
       .clk  (
clk),
       .se     (1′b0),       .si (),         
.so ()
  );

이렇게 concatenation해서 flip-flop을 연결합니다.

이런 coding style은 datapath의 pipeline register를 기술할때 특히 효과적이겠네요.

OpenSparc T2는 어떤가 하고 조금 살펴보니, T1보다 훨씬 module name이 길고 직접 dff을 가져다 쓰는게 아니라 module을 한겹 덧씌워서 unique하게 만들어 사용하는군요.

module spc_lb_ctlmsff_ctl_macro__width_15Index (
 
din,
 
l1clk,
 
scan_in,
 
siclk,
 
soclk,
 
dout,
 
scan_out);
wire [14:0] fdin;
wire [13:0] so;

  input [14:0] din;
  input l1clk;
  input scan_in;

  input siclk;
  input soclk;

  output [14:0] dout;
  output scan_out;

assign
fdin[14:0] = din[14:0];

dff #(15)  d0_0 (
.l1clk(
l1clk),
.siclk(
siclk),
.soclk(
soclk),
.d(
fdin[14:0]),
.si({
scan_in,so[13:0]}),
.so({
so[13:0],scan_out}),
.q(
dout[14:0])
);

endmodule

또 한가지, T2는 제가 알고 있던 상식을 깨고 있었는데, 위의 macro module을 잘 보면 scan input, scan output까지 연결하고 있습니다.

네 그렇습니다. 이런 식의 register macro들을 모두 연결하여 RTL상에서 scan chain을 구성하고 있었습니다. T1만 하더라도 scan chain은 합성단계에서 auto insertion하고 있었던 것으로 보이는데, 다음 세대인 T2는 RTL에서 scan chain을 모두 stich해두었는데… 이것 참 어떻게 받아들여야할지?(T1, T2가 모두 그렇다면 Sun의 전통(?)이겠거니 할텐데 그것도 아니고 말입니다.)

혹시 수십,수백만 게이트 짜리 디자인의 scan-chain을 manual stitch한다는 얘기 들어보신분?

아이폰 게임을 좋아하는 4살 재희

오랜만에 올리는 재희 동영상입니다.

재희는 아이폰으로 게임하는 것을 무척 좋아합니다.
며칠전 앱스토어 전체 1위인 Cut the Rope를 @velvio님의 도움으로 설치했습니다.

2010년 10월 앱스토어 순위

재희한텐 알려주지도 않았는데 다음날 아침에 보니 당연한 듯 컷더로프를 하고 있더군요.
게임을 잘 만들어서 그런지 방법을 알려주지 않아도 대충 하더군요.
며칠 지나서 보니 이제 제법 어려운 단계도 잘 합니다. 고사리 손으로 꼼지락거리면서 하는게 귀엽네요.

재희는 아이폰 게임은 거의 다 좋아합니다. (사실 아이폰의 모든 기능을 게임화 해서 가지고 놉니다만…)
그중에서도 재희가 좋아하는 게임은 Finger Physics, Stackus, Block Exit와 같은 머리쓰는 게임과, Space Ball(아이폰 기울여 공움직이기), Paper Toss(쓰레기 넣기), 핀볼 같은 단순한 것들입니다.

재희 전용 게임들

그중에서도 블록엑시트는 상당히 잘하는 편이었는데 Easy, Medium, Hard, Extreme 중에 Hard까지 모두 깨고, Extreme단계는 몇단계하다가 너무 어려웠는지 포기했습니다.

사실 저는 Hard단계도 어렵더군요. 재희가 혼자서 Hard단계 몇판을 깨고 잘안되면 들고와서 “어떻게 해?”하고 물어봅니다. 이리저리하다가 해결해주면 또 들고가서 한참하고.. 그러더니 어느새 최고난이도인 Extreme단계를 하고 있더군요.

너무 어려워서 그냥 쉬운거 하라고 하면 한번 깼던 판은 다시 안하고 화면에 “Your Record: None”으로 나온 것만 골라서 “유어 레코드 논이야~”하면서 그것들만하려고 하더군요. ^^;;;

아래는 재희가 Easy단계 할때 동영상입니다.

Medium단계입니다. 직접 배경음악으로 “뽀삐뽀삐”를 깔아주는 센스 ^^;
제일 잘 할때였던 Hard단계는 동영상을 안찍어놨네요.

아이폰 LCD와 갤럭시S AMOLED 현미경 비교

LCD와 AMOLED Display를 비교하는 글들이 국내 및 국외 싸이트에 많이 있습니다.
특히 iPhone 4의 Retina Display와 Galaxy S의 Super AMOLED의 화질을 비교하는 글들이 많이 있습니다.
스마트폰별 디스플레이 특성 비교해 놓은 자료 중 http://www.displaymate.com/Smartphone_ShootOut_1.htm 가 매우 상세하고 객관적이니 참고하시기 바랍니다.

화질에 대한 평가는 개개인의 선호도에 따라 다른 부분이고, 저는 디스플레이 업계에 몸담고 있는 입장에서 각 패널들의 실제 Pixel구조가 궁금해서 비교해 보았습니다.

iPhone 3Gs는 @KyonghoKim 님, iPhone4는 @OyPark 님, Galaxy S는 @LimGyuHo 님께서 빌려주셨습니다. 촬영하려고 보니 Galaxy S는 AMOLED를 사용한 폰들이 그렇듯 UI화면이 모두 Black이라 살짝 고민하다가 Google 웹싸이트에 접속했습니다.

본래 계획은 15배율의 LUPE에 대고 아이폰으로 찍으려고 했는데, 15배로 픽셀구조가 보이는 3Gs와 Galaxy S에 비해 iPhone 4는 전혀 픽셀구조가 보이지않아서, Probe Station에 있는 현미경을 사용하였습니다.

아래는 각 패널을 모두 같은 배율로 촬영하고 한눈에 비교가되도록 배치한 것입니다. 척보기에도 차이가 많이 납니다.

각각 좀더 자세히 살펴보겠습니다.
먼저 iPhone 3Gs는 가장 보편적인(보통의 LCD 모니터와도 동일한) RGB Stripe구조입니다.
그중에서도 IPS LCD(In Plane Switching Liquid Crystal Displays) 방식을 사용하고 있습니다.
백색LED 백라이트가 있고 Color Filter로 붉은색, 녹색, 푸른색 성분을 선택적으로 투과시키는 방식입니다.

다음으로 Galaxy S는 이제는 많은 분들이 알고 계신대로 PenTile구조라 한개의 pixel이 RGB sub-pixel로 구성된 것이 아니라 red+green과 blue+green이 교대로 픽셀을 구성하는 방식입니다.
AMOLED(Active Matrix Organic Light Emitting Diodes)는 유기물질이 자체발광하는 방식입니다.
픽셀구조를 보면 녹색 sub-pixel의 면적이 제일작고, 붉은 색은 중간, 푸른색이 가장 면적이 큰 것을 알 수 있습니다.

붉은색과 푸른색은 두 pixel마다 하나씩 있지만, 녹색은 모든 pixel에 존재하므로 모든 sub-pixel이 빛을 발할 때 흰색이 되기 위해선 각각의 녹색 sub-pixel은 50%의 밝기를 가져야합니다. 따라서 녹색의 면적이 제일 작아야할 것이고, 자체발광하는 유기물질의 휘도 특성에 차이가 있어서 면적이 다른 것 같습니다. 즉, 푸른색을 내는 유기물질의 휘도(밝기)가 제일 낮다는 말이지요. 사실 제가 패널 엔지니어가 아니라 정확히는 모릅니다. 그리고, 유기물질이 동일한 휘도를 낸다고 하더라도 사람의 눈이 받아들이는 빛의 양은 색상마다 차이가 있는 것도 고려했을 것입니다.

3Gs의 LCD Panel에 비해 빛을 내는 부분이 상대적으로 적습니다. 즉 개구율(Aperture Ratio)가 상대적으로 작은데 이것은 AMOLED에 상대적으로 회로가 많이 필요하거나 아니면 필요이상의 전류소비를 막기 위한 것 같습니다. 지금도 AMOLED가 밝다고 하지만, 배터리문제만 극복한다면 더 밝게 만드는 것도 가능해보입니다.

참고로, AMOLED보다 LCD방식이 어둡다고 말하는 이유는 위에서 잠시 설명한 color filter, 편광판 등을 통과하면서 본래의 흰색 광원보다는 어두워질 수 밖에 없고, AMOLED는 자체적으로 색상을 발광이기 때문에 밝기가 감소되지 않고 그대로 보이기 때문입니다. 하지만, AMOLED는 밝은 화면에서 소비전류가 커지므로 밝기를 제한하기 때문에 AMOLED가 LCD보다 더 밝다고 말하긴 어렵습니다.

다음으로 iPhone 4의 Pixel구조는 이런저런 추측이 있었는데 3Gs와 마찬가지로 IPS 패널이고 Pixel구조자체도 큰 차이가 없어보이나 Pixel크기가 3Gs의 1/4밖에 되지않습니다.

한가지 특이한 점을 발견했는데, 군데군데 푸른색 sub-pixel 한쪽에 까만 점이 보입니다. 어떤 회로를 추가했다는 의미인데 그게 무엇인지는 모르겠습니다. 같이 사진을 살펴보던 @starrida 님은 포토센서(밝기 센서)가 들어갔을 거 같다고 하셨습니다.

마지막으로 패널별로 픽셀크기를 비교해 보겠습니다.
픽셀크기는 해상도와 화면크기만으로 계산이 가능하고 또 자료를 찾아보면 iPhone 3gs: 163ppi, Galaxy S: 233ppi, iPhone 4: 326ppi (ppi: Pixel Per Inch)인 것을 알 수 있지만 직관적으로 비교할 수 있는 그림을 그려보았습니다.
당연한 얘기지만 픽셀크기가 작을 수록 화면이 더 조밀하고 또렷하게 보입니다.

iPhone 3gs, iPhone3, Galaxy S의 화면 구조에 대하여 비교해보았습니다.
서두에 말한 것 처럼 어느 제품의 화질이 더 나은지는 언급하지 않겠습니다. 각각 장점도 있고 단점도 있으니까요. 색재현률, 시야각, 소비전력, 명도 대비 등의 비교는 이 곳 자료를 참고하세요.

여담이지만 2010년에 휴대폰에 960×640 해상도가 사용될 것이란 것은 디스플레이용 반도체를 만드는 저도 정말 상상하지 못했던 일이었습니다. 작년에 거의 같은 해상도의 제품을 만들긴 했지만…
“설마 이렇게 고해상도가 필요하겠어? 패널수율도 안나오는데… 만들어도 얼마나 팔릴까?” 라고 생각하고 있었습니다. 이거 머잖아 정말 핸드폰에 HD화면이 들어갈 상황입니다.

이러한 경쟁으로 인해 눈부시게 빠른 기술발전이 되면 소비자들은 행복합니다. 대개 성능차이에 비해 가격차이는 적은 편이거든요. 날로 높아지는 눈높이 맞추느라 고생하시는 개발자 분들 힘내시란 말로 마무리하겠습니다.

@0donny

Building OpenSPARC T1

둘째아이도 퇴원하고나니 이제 마음에 여유가 좀 생겼습니다.

지금 다니고 있는 회사는 곧 퇴사할 예정이고 10월부터 새로운 곳으로 이동할 계획이었는데, 일정에 변화가 생겨서 시간이 생겼네요.

몇년만에 찾아온 휴식시간인 셈인데… 무엇을 할까 생각하다가 그동안 미루던 ‘취미활동(?)’을 하기로 했습니다.

오래전에 babyworm님 블로그에서 OpenSPARC을 알게되어, 당시 download만 받아놓고 살펴보지 못하고 있었는데 이번 기회에 한번 들여다 보려고 합니다. 회사에서 웹서핑하고 노는 것도 금방 질리고 하고 놀만한 일도 마땅이 없는 지금 상황에서 아주 적당한 놀거리입니다. 공부도 되고요.

박사학위과정에선 마이크로프로세서 설계를 공부했으나 실제 졸업 후에는 마이크로프로세서 관련된 업무와는 다소 거리가 있는 일을 하고 있었습니다. 마이크로프로세서 설계는 원래 좋아하던 일이니 취미활동이라고 봐야지요..

작심삼일이 될 가능성이 농후하지만 시작이 반이라고 일단 시작은 했습니다.

www.opensparc.net 에서 최근 release의 OpenSPARC T1을 받아서, 제가 사용하는 계정에 옮겼습니다. 제 환경이 Solaris 9이라 Sun Studio 11 도 새로 설치했습니다.

NC-Verilog환경으로 Setup하려고 했는데 Compile중에 Error가 발생하여, VCS환경으로 설정했습니다.

압축파일에 담겨있는 OpenSPARCT1_DVGuide.pdf를 보고 그대로 따라하니 큰 문제 없이 진도가 나가네요.

$ sims -sim_type=vcs -group=core1_mini -novera_build -novera_run

첫번째 단계로 single core에 minimum regression으로 돌렸는데 꽤 오래걸리네요.

일단 시동은 걸었으니 조금씩 뜯어보고 눈에 띄는 내용은 블로그에 메모할 예정입니다.