Category Archives: SoC & IP design

[verilog] wire와 reg

예전에는 verilog동호회니 asic동호회니 나름대로 활발히 활동했었는데, 점점 숙제도와주기 동호회가 되가서 잘 안가게 되었습니다.

정말 오랫만에 오늘 verilog동호회에 갔는데, 위의 질문이 있더군요. 저 질문은 제가 대답한 것만 한 3번 정도이고.. 자세히 정리해서 쓴적도 한번 있을 정도로 verilog를 배우시는 분들에게 있어서 이해가 어려운 부분이듯 합니다. (이제와서야 이렇게 이야기하지만, 되집어 생각해보면 저도 처음 배울때 위의 것의 차이를 잘 몰랐던것 같구요.)

사실 verilog라는 언어자체보다는 설계가 우선인 것이고, verilog는 도구에 불과하지만, 도구를 잘 아는 것도 많은 도움이 되는 것이 사실입니다. 또한, verilog의 timing 정의라던지 신호의 driving에 대해서 어느정도 명확히 이해하면 PLI programming으로 좀 정교한 모델을 만들때 크게 도움이 됩니다.
저 역시도 프로세서 모델의 PLI모델을 만들면서 많은 부분을 좀더 정확히 알게 되었으니까요..

여하튼. 오늘 이야기 할 부분은 바로 wire와 reg, 정확히 이야기하자면 net과 reg라고 부르는 것이 더 맞을 듯 합니다.

우선, verilog를 정의하고 있는 IEEE 1364-2001 표준을 보면 net에 대해서(특히 wire에 대해서)는 다음과 같이 기술하고 있습니다.

The wire and tri nets connect elements. The net types wire and tri shall be identical in their syntax and functions; two names are provided so that the name of a net can indicate the purpose of the net in that model. A wire net can be used for nets that are driven by a single gate or continuous assignment. The tri net type can be used where multiple drivers drive a net.

위에서는 wire와 tri를 기술하고 있는데, 우리의 주된 관심은 wire이므로 이쪽만 살펴보죠.. (사실 tri는 tri-state wire를 기술하고 있는 것으로 속성상 wire와 같습니다. 단, multiple-driver가 허용된다는 것만 다르죠. 혹시 driver가 신호를 보내주는 요소, 즉 게이트 출력, tr의 출력 같은 넘이라는 건 다 아시죠?)
wire는 기본적으로 “연결”을 위한 요소입니다. 그리고, 이것은 단일 게이트 혹은 continuous assignment의 출력을 연결하기 위한 목적으로 사용됩니다.
continous assignment로 대표적인 것이 assign문이므로 다음과 같이 여러분이 일상적으로 쓰는 구문이 가능한 것입니다.

wire out = a & b & c & d;

이 문장이 다음과 같은 문장이라는 건 아시죠?

wire out;
assign out = a & b & c & d

보통 이런식의 문장에서 wire가 가능한 것입니다. wire는 개념적으로 “선을 연결한다“라고 생각하십시요.
출력포트에 어떤 표현식의 출력을 연결할때 사용되는 것 처럼요..

이제 reg에 대해 알아봅시다. 역시 표준 문서의 정의를 먼저 보겠습니다.

Assignments to a reg are made by procedural assignments (see 6.2 and 9.2). Since the reg holds a value between assignments, it can be used to model hardware registers. Edge-sensitive (i.e., flip-flops) and level sensitive (i.e., RS and transparent latches) storage elements can be modeled. A reg needs not represent a hardware storage element since it can also be used to represent combinatorial logic.

위의 정의에 따르면, reg는 procedural assignment(절차적 assignment는 소위 always begin.. end, initial begin.. end사이에 사용되는 모든 표현식으로 생각하십시요..)에 의하여 assign되는 요소입니다. 또한, assign사이에 값을 저장할 수 있습니다. 이런 속성을 이용해서 flip-flop이나 latch를 만들수 있다고 되어 있습니다. 많은 초보자분들이 헷깔리시는 부분이 바로 이 속성때문일 것입니다. 보통 플립플롭 즉, 순차 회로를 만들때 reg문을 많이 사용하다보니, 많은 분들이 reg문을 사용하면 register(즉 플립플롭)이 생성될 것이라는 생각을 가지고 있습니다.
하지만, 표준의 마지막 문장에서 이건 절대 아니라고 명시하고 있으며, 실제로도 그렇습니다.
그래서, ‘reg는 register가 나오는 것이다’라고 생각하시는 많은 분들이 ‘reg이면 register가 나와야 하는건데.. 왜 안나오지? 그럼 wire랑 뭐가 다른거야?’ 라는 궁금증을 가지십니다.

이제부터 차근 차근 설명 드리지요..

procedural assignment를 수행하는 과정(begin에서부터 end까지)에서 이 값은 임시로 보관 될 수 있습니다.
비유를 하자면 reg문은 그릇같은 것이라 할수 있습니다. 입력이 들어오면 그걸 가지고 생성된 임시값을 일단 그릇에 담습니다. 그리고, 어떤 경우에던지간에  입력에 의하여 결과의 변화를 end문을 만나기 전까지 기술할 수 있다면, 그건 더 이상 그릇에 담을 필요가 없이 최종결과로 보고 쏟아버리면 됩니다.
이런 경우는 reg문장이 더이상 그릇의 형태를 지닐 필요가 없겠습니다.
따라서, storage element로 구현되지 않습니다. 과거를 기억할 필요가 없으니까요..

always @(a or b or x) begin
  if (a == b) out = 1'b0;
  else if (x) out = 1'b1;
  else         out = 1'b0;
end

이 예에서는 모든 가능한 경우에 대해서 출력이 정의되어 있지요? 그래서, 이 예의 문장은 조합회로로 구현됩니다.

하지만, 입력에 따라서 그 결과의 변화를 나타낼 수 없는 경우가 생긴다면, 이전에 내가 가지고 있던..즉, 예전에 그릇안에 있던 값이 유지되어야 할 조건이 되는 것이므로, reg는 그릇의 형태를 가지고 예전에 결과를 담을 수 있어야 합니다.
이 경우에, reg는 storage element로 구현됩니다. 과거를 알아야 하니까요..

always @(a or b or x) begin
  if (a == b) out = 1'b0;
  else if (x) out = 1'b1;
end

위의 예에서 위의 경우에서 if문이나 else if에 만족 하지 않으면, 예전 값을 그대로 가져 가겠다는 거죠? 그래서, 과거의 값을 기억할 필요성이 생겼습니다. 그래서 저장장치인 래치로 구현됩니다.

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

이 코드는 언듯 입력에 대한 모든 경우가 표시된 것 같습니다만.. always문에서 clk의 상승엣지 혹은 rst_x의 하강엣지까지 “기다려”라고 선언했기 때문에 입력에 따른 변화값이 “기억되어야 합니다”. 그래서 기억할 필요성으로 인하여 저장장치(플립플롭)로 구현됩니다.

요약하자면,
1) reg가 과거값을 알아야 할 경우가 생긴다면(입력에 의한 출력이 모두 기술되지 않거나, 특정 입력을 기다려야 하는 경우), reg는 storage element로 구현된다.
2) reg가 과거값을 알아야 할 경우가 없다면, 일반적인 combinational logic으로 구현된다.

이해가 가시런지요?

두번째 요약!

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으로 구현된다)

이렇습니다.
초보분들께 도움이 되셨으면 좋겠습니다.

p.s.
ASIC으로 밥먹고 사는 저도 verilog에 대해 속속들이 다알고 쓰는것은 아닙니다. 권장할 만한 사항도 아니구요(필요한 정도만 속속들이 알아야죠..).. 어짜피 verilog 자체로 ART를 하는 것도 아니고, 최종적으로 회로가 나와야 하는데, 일정 수준 이상의 문법은 CAD툴에서 안전하지 못하거든요..

그래서, verlog HDL에서는 coding style이라는 guide line이 있습니다.
말하자면, 이런 경우에는 이렇게 쓰면 좋다. 이런 문장은 왠만하면 쓰지 말아라.. 뭐 이런 지침 같은 것입니다. 가장 유명한 책이 바로 아래의 RMM이라는 책인데, 이쪽 계통을 지망하시는 분께는 아마도 “필독서”가 아닐까 생각합니다. 개인적으로 공부삼아 번역도 좀 해본적이 있고.. (실제로는 귀찮아서 번역은 하다 말았고, 정독한번 잘했다~ 정도로 생각하고 있습니다.)

하다보니, 겸사 겸사 책 소개도 되었군요.. 나중에 기회되면 RMM에 대해서는 좀더 자세히 소개해 드릴 기회가 있겠지요.

perl 과 tcl.. 개인적인 느낌..

 아마도 ASIC 엔지니어,그리고 경력이 좀 된다면 다들 간단한 쉘 프로그래밍이나, perl이나 tcl 정도는 다룰줄 아시리라 생각합니다.

부끄럽게도 저는 정말 간단한 정도의 할 줄 알다가, 1~2년 전부터 TCL을.. 1년전부터 perl을 좀 제대로 쓰고 있습니다.
예전에 했던 TCL은 사실 TK때문에 했던 것이라 상당히 간단한 수준이었고, 요즘에는 synopsys툴을 비롯한 많은 CAD툴에서 TCL 기반의 scripting을 지원하는 관계로 자주 쓰게 되었습니다.
잘쓰던건 아니지만, 예전에 했던 가닥이 있어서 그나마 쉽게 적응했지요.

TCL은 말 그대로 많은 툴에서 지원되고, 툴내에서 프로그래밍에도 편하고, 거기다가 TK라는 강력한 원군의 도움으로 ASIC 엔지니어에게는 이제 “필수”언어가 되었다고 생각합니다.
혹, ASIC 엔지니어를 지망하신다면, tcl은 배워두시는 것이 편하실 겁니다.

perl은 reporting language라는 이름 그대로, 문자 처리에 있어서는 발군!입니다.
사실 예전에는 노가다성 코드를 C로 작성해서 test bech같은것을 만드는 일이 많았는데, 요즘엔 대부분 perl로 처리합니다.
perl에 한번 물들고 나니, 왠만한 작업도 그냥 쉘 프로그래밍 안짜고 perl 기반으로 작업을 하게 된다는 엄청난 중독성이 있더군요.
강력한 정규식의 지원뿐만 아니라 수많은 확장과 간단한 문자열 처리!

설계자들에게는 정말 좋은 언어라고 생각됩니다.
perl과 verilog와의 조합을 위한 여러가지 준비도 http://www.veripool.com/에 상당한 수준으로 되어있으므로, 사용하시기에 어려움이 없으실 듯 합니다.

웍에서 perl 가지고 작업하다가.. perl을 찬미하고픈 마음에 갑자기 씁니다.

국산 마이크로 프로세서

얼마전에 다나와라는 사이트에서 국산 마이크로 프로세서에 대한 이야기가 오고 간적이 있습니다.
이런 저런 이야기가 많이 오고 갔지만, 물끄러미 보고 있자니 사용자들의 국산 프로세서에 대한 열망이 느껴지더군요..

저도 그리 깊이 아는 것은 아니지만, 제가 아는 한도내에서 국산 마이크로 프로세서에 대해서 이야기해 보고자 합니다.

국산 마이크로 프로세서에 대한 연구는 대학 연구실과 국가 연구소들에서 지속적으로 관심의 대상이었습니다만, 상용화 된 경우는 제가 알고 있기로 없습니다.

국내 연구실중에서 상용 수준에 가장 근접했던 곳은 아마도 KAIST에서 수행된 x86 호환칩(펜티엄 호환칩까지 나왔습니다)이 아닌가 생각됩니다. 물론, 이를 후원하던 현대전자가 사라지면서 이 프로젝트는 사실상 사라졌습니다만…

KAIST 경종민 교수님 연구실에서 개발한 Marcia 프로세서(펜티엄 호환칩)

사실상 데스크탑이나 서버용도의 프로세서에 있어서는 큰 격차가 있는 상태이므로 이를 따라 잡기는 쉽지 않을 것이라 생각됩니다. 게다가, 데스크탑과 서버 시장 모두 x86기반의 아키텍쳐가 거의 통일하고 있는 상태이므로, 다른 아키텍쳐가 나온다해도 이미 강력하게 구축된 소프트웨어 지원을 따라잡기는 어려울 것이라 생각됩니다.

기업체로 눈을 돌렸을때 역시 가장 상용수준에 근접했던 곳은 삼성전자 프로세서 연구실입니다.
삼성-알파라는 프로세서로 세계최초로 1GHz의 벽을 뛰어넘은 프로세서를 만든 곳이죠.
아쉬운 점은 알파라는 기존의 프로세서를 받아서(제가 알기로는 backend까지 끝난.. 즉, 거의 다 설계된 도면이라고 해야 겠지요..), 이를 삼성 공정에 circuit수준에서 최적화시키는 공정을 한것으로 알고 있습니다.
그렇다해도, 이 circuit 이하 수준의 최적화 기술이 매우 어려운 기술이므로 절대로 낮추어 볼만한 일은 아닙니다.
아쉽게 알파 프로세서가 사양길로 접어들면서, 삼성에서도 이 프로젝트를 접게 되었습니다.
이후에 리누스가 있는 것으로 유명한 트랜스메타의 칩에 대한 도입이 검토되었지만 무산되었으며, 서버/데스크탑 시장은 접게 됩니다. 그리고, 눈을 내장형 프로세서로 돌려서 ARM 프로세서 아키텍쳐를 받아서 역시 세계 최고속도의 ARM을 만들고 있습니다. (best cond.에서 1GHz를 넘고 있는 프로세서니 대단합니다.)

이제 국내 기술만으로 만들어진 자체 프로세서에 대한 이야기를 해봅시다.

우선, 잠시 프로세서에 대한 이야기를 하겠습니다.
프로세서라는 것은 프로세서 기술이라는 것이 한 20%정도 밖에 차지하지 않습니다. 광범위한 컴파일러 기술, OS 기술, 시스템 프로그래밍 기술.. 이런 것이 필요하죠..

프로세서가 높은 성능을 발휘한다는 것은 이러한 모든 것이 집결되었을때 가능한 것입니다.
그런데, 아쉽게도 국내에는 컴파일러, OS, 시스템 프로그래밍이라는 분야가 아주 취약합니다.
삼성과 같이 능력있는 기업에서 자체 아키텍쳐를 개발한 적이 있으나, 이를 사장시키고 ARM 기반의 프로세서를 채택한 것도 바로 이미 구축되어 있는 ARM의 강력한 인프라를 사용할 수 있다는 장점때문입니다.
한마디로, 프로세서를 만드는 것보다 프로세서를 제대로 운용하는데 필요한 프로그램을 얻기가 더 어렵다.. 그래서, 되도록이면 기존의 것을 쓰려고 한다..  이것입니다.

하지만, 이는 여러 소프트웨어의 강력한 지원이 필요한 시장에서의 이야기이고, 소프트웨어의 호환성이라던지 지원에 대한 의미가 약간 적은 내장형 프로세서 시장에서는 여러가지 의미 있는 시도들이 존재했는데..(아직도 존재합니다요..)

가장 큰 것이 System IC 2010과제(시스템 IC를 2010년까지 선진국 수준으로 끌어올리자는 대형 국책 프로젝트입니다.)에서 두개의 의미 있는 프로세서가 개발되었다는 점입니다.

CalmRISC 이미지 컷[삼성전자

첫번째는 삼성의 calmRISC입니다. 지금은 조용히 사장되었습니다만, 삼성 특유의 공격적인 투자로 좋은 출발을 했었습니다. 삼성 전자 공정 특유의 저전력 소모라던지.. 몇몇 연구실과 연계해서 캐쉬 구조나 컴파일러, OS모두 좋은 방향으로 가고 있었습니다만.. 너무 특색없는 RISC였던것이 문제였던것 같습니다.
개발환경도 너무 과하게 큰 BDM기반의 기술을 채택했구요..
현재는 이름만 남아 있는듯 합니다만, 빨리 되살아나길 바랍니다.

두번째는 ADChips의 EISC 프로세서입니다. 현재 제가 만들고 있는 CPU이기도 합니다. RISC기반의 프로세서인데 CISC적인 요소가 많은 유별난 아키텍쳐를 가지고 있으며, 그래서 EISC라고 이름 붙여진 프로세서입니다. system IC 2010에서 삼성 calmRISC와 경쟁 과제로 선정되어 최종적으로 과제에서 더 높은 평점을 받으며 아주 좋은 출발을 했습니다.
(아마도, 조금 더 큰 기업에서 공격적인 투자를 진행했다면 EISC의 현재 모습은 좀 더 다른 모습이 아닐까 생각됩니다.. 아쉽기는 하지만, 현재의 EISC의 모습이 이정도되는 것도 중소기업으로 하기 힘든 투자를 계속하고 있는 회사 결단의 산물이겠습니다.)

EISC가 탑재된 그래픽 프로세서, 게임기에서 많이 사용됩니다.

현재도 EISC 프로세서는 지속적으로 개발과정에 있고, 여러 대학과의 연계를 통해서 컴파일러도 재 정비되고 있습니다. uCLinux가 포팅되어 현재 사용가능하고, Linux포팅도 곧 될 예정이지요.
현재 SoC Robotwar(레이저를 탑재한 전차형 로봇간의 2:2 전투, 게임 시작 이후에는 참가자가 프로그래밍한 인공지능 프로그램에 의해서만 게임이 진행되며, 사용자가 조작할 수 없다는 점이 특징입니다. http://www.u-socrobot.org/)에서 메인 프로세서로 사용중입니다.  (음 유비쿼터스 SoC 로봇워로 이름이 바뀌었군요..)

SoC 로봇워 경기장면, 원통의 색이나, 벽의 패턴을 인식해서 공격이나 동작을 선택합니다.

그 이외에 국내에서의 프로세서들중에서 눈길을 끄는 부분은 8051기반의 프로세서들이 아직도 잘 팔리고 있다는 점이고, 이를 이용해서 돈을 벌고 있는 회사가 있다는 점입니다. 개발자들은 아무래도 익숙한 것을 계속 고집하는 경향이 있지요.. 하지만, 그 이상으로 8051의 저력이 무섭습니다.

위에 이야기 한것 처럼 국산 프로세서가 전무한것은 아닙니다.
단, 외산 프로세서 아키텍쳐에 국산 기술을 입혀서 만들고 있는 경우가 대부분이라 잘 인식하지 못할 뿐이지요(ARM을 이용한 삼성-ARM, 8051기반의 프로세서들).
국산 기술만의 프로세서의 경우 아직 시장에서 크게 두각을 나타내지 못하고 있다는 점도 있구요 (EISC).
대학과 국책 연구실에서는 오늘도 수많은 시도가 있을것입니다. 아직 일반인의 눈에 보이지 않을뿐이지요.

제가 만들고 있는 EISC의 경우만 이야기하자면,
EISC의 경우 그 개발 키트가 공개되어 있으니, 곧 공개 개발자들에서도 재미있는 시도들이 이루어지지 않을까 생각됩니다.
저희도 좀 공격적으로 알릴 필요가 있구요. (사실 회사에서는 인력 부족이라 공개 커뮤니티에 너무 알려지면 공개 커뮤니티를 지원할 인력 문제에 대한 고민도 없잖아 있습니다만…)

EISC 뿐만 아니라 여러 국산 프로세서에 대한 관심을 계속 가져 주시기 바랍니다.