우리는 제일 먼저 논리 회로에서 and, or, not 게이트를 먼저 배우고 그 다음에 nand, nor 게이트를 배우게 됩니다. and, or의 기능을 가지면 nand와 nor를 설명하기 쉽기 때문입니다.

그러나 실제 회로에서는 그 개념이 아닙니다. 회로의 최적화를 이루기 위해서는 and나 or보다는 nand와 nor 게이트를 가지고 설계하는 것이 가장 최적화 되어 있는 회로입니다. 집적회로의 입장에서 보면, PNP Junction에서 Nmos와 Pmos를 가지고 설계할 수 있는 가장 기본의 형태가 Nand, Nor 게이트입니다.(집적회로까지 설명하면 너무 깊이 들어가야 함으로 간단하게 설명하겠습니다. 궁금한 점이 있는 집적회로를 공부하는 것이 도움이 될 것입니다. Spice Tool을 이용하여 간단한 Layout 설계를 해보시면 알 것입니다.) nand 게이트는 and 게이트에 not 게이트를 붙여서 설계한 회로입니다. 그러니 nand, nor, not가 회로의 기본입니다. nand만 보면 pmos 두 개를 병렬로 연결하고 nmos 두 개를 직렬로 연결한 것이 nand 회로입니다. 참고로 말씀드리면 설계의 기본은 Layout 과정입니다. 배워두시면 도움이 될 것이라 생각은 들지만 시간이 많이 걸린다는 것이 단점입니다.(?)

그럼 Asic 설계에서 가장 기본적으로 알아야 하는 것은 무엇일까요? 아마도 DFF이라고 저는 생각하는 데요. 이제 설계자의 입장에서 말씀드리겠습니다. 기본적인 회로의 설계가 끝나면 여러분은 설계자 입장에서 모든 것을 생각하고 설계를 해야 합니다. 하드웨어 디자이너가 되는 것입니다. 기쁘겠죠.

디자이너가 가장 중요하게 생각해야 하는 Factor가 네가지 있습니다. 아니 더 많을 수도 있지만 기본적인 4가지가 있습니다. 그 중에 한 가지인 Area(yield and pcakageing cost) 문제가 있습니다. 그 문제가 인해 회로 면적이 작게 차지하는 DFF을 이용하는 것입니다. 그래서 VHDL 코딩을 하면 컴파일을 하고 synthesis를 하고 나서 logic으로 구현된 설계도를 보면 메모리 소자를 DFF으로 설계된 것을 확인할 수 있을 것입니다. 지금 살펴 볼 문제는 아니지만 설계시 고려해야 할 4가지요소에 대해서 설명드리면 다음과 같습니다.

Performance :

□ Delay and cycle-time.

- Latency.

- Throughput ( for pipeline application).

Area ( yield and pcakageing cost).

Testability

Power

기분 나쁘게 전부 영어로 적었죠. 다른 사람과 설계에 대해서 이야기를 한다면 영어로 말을 해야죠. 다른 사람이 성능이 어때? 라고 묻지는 않을 것입니다. Performance가 어때라고 묻지. 위의 설명은 여러분이 디자이너가 되면 시작할 것입니다. 그 때를 기대하세요.

그렇게 어려운 용어가 아닌지 대강은 감을 잡을 수 있을 것입니다.

지난 시간에 DFF과 latch에 차이에 대해서 알아보셨나요. 부지런한 디자이너는 조사해서 알아있을 것이고, 귀찮은 사람은 그냥 기다리겠죠. 그러나 이런 단순한 이론에서 오는 차이가 크다는 것을 알아야 합니다. 그만큼 회로 설계 시간의 단축을 가져올 수 있습니다.

□□ 조합회로 (Combinational logic)

디지털 회로 □                  □□ 동기형 순서회로 (synchronous)

□□ 순서회로       □

(Sequential logic)   □□ 비동기형 순서회로 (Asynchronous)

이 시간을 이해하기 위해서는 조합회로가 무엇이고 순서회로가 무엇인지 알아야 합니다.

Inputs                  Combinational                   Outputs

circuit

조합회로의 블럭선도

Inputs               Combinational                                    Outputs

circuit                     Memory

elements

순서논리회로의 블럭선도

조합회로는 임의의 시간에서 출력이 이전의 입력에는 관계없이 현재의 입력조합으로부터 직접 결정되는 논리회로를 말합니다. 반면 순서회로는 출력은 외부로부터의 입력이 기억상태를 바꾸게 된다. 즉 순서회로의 입력, 출력 그리고 내부상태의 시간에 따른 순서로서 규정된다.  쉽게 말하면 조합논리의 결과가 출력이 되는 것이 아니라 메모리 요소에 저장되어 있는 변화된 값이 다시 조합회로로 궤환되어 결과 값이 출력되는 것이다. 이것은 다시 두 가지로 나누어진다. 클럭펄스가 들어오는 시점에서 입력신호로부터 그 동작을 정의할 수 있는 시스템이 동기형(synchronous) 순서논리회로이다. 비동기형(Asynchronous) 순서회로의 동작은 입력신호가 변화하는 순서에 따라 언제라도 영향을 받을 수 있다.

Flip-flop이나 latch는 one-bit 메모리 소자입니다. 클럭이 있는 순서논리회로에 쓰이는 기억소자를 플립플롭이라고 한다.  FF은 edge-triggered memory device라고 합니다. 이 말은 플립플롭의 상태는 입력신호의 순간적인 변화에 따라 바뀌기 때문입니다. 순간적인 입력 변화를 트리거(trigger)라고 합니다. FF을 흔히 레지스터라고도 합니다.

비동기식 순서회로에서는 클럭펄스를 사용하지 않는다. 비동기식 순서회로에서의 기억소자로는 클럭이 없는 플립플롭(latch)이거나 시간지연소자(time-delay element)를 사용한다. 비동기식 순서회로의 설계는 타이밍문제 때문에 설계가 더 어렵습니다.

latch는 level-sensitive memory device입니다. 그 말은 클럭을 사용하지 않기 때문에, 입력이 변화되는 즉시 시스템의 상태가 변화할 수 있게 되어야 한다는 뜻이죠.

클럭이 있는 동기식 시스템의 예를 많이 보았을 것이고, 비동기식 회로에서는 빠른 동작속도가 요구될 때 사용합니다. 예를 들자면 그 자체에 독립적인 클럭을 가진 각각의 장치가 있는 2개의 시스템간의 교신은 비동기식 회로로 이루어져야 합니다.

적절한 시스템 설계를 위해서는 동기식의 일부가 비동기식 특성을 갖는 혼합된 시스템을 설계해야 합니다.

그럼 간단히 정리하죠. 동기식 순서회로에서 사용되는 기억소자는 플립플롭이고, 비동기식 순서회로에서 사용되는 기억소자는 래치입니다. 플립플롭은 클럭이 있고, 래치는 클럭이 없습니다. 좀 어렵게 설명하면 펄스지속시간에 민감한 플립플롭군을 래치라고 하고, 펄스에 전이에 민감한 플립플롭군을 레지스터라고 합니다.

이 부분은 조금 중요한 부분이라 조금 길게 설명이 됐는데 되도록 논리회로의 설명은 자제하는 방향으로 하겠습니다.

오늘은 예제가 조금 많습니다. 플립플롭과 래치에 관계된 예제입니다. 이 부분은 Actel 매뉴얼에서 인용했습니다. 인터넷 Actel 홈페이지에 가서 다운 받을 수도 있고, 사용자 등록을 하시고 매뉴얼 신청을 하시면 구할 수 있을 것입니다.  http://www.actel.com

오늘 예제는 모두 DFF으로 구현된 예제입니다. 다른 플립플롭으로 구현은 아마 힘들겁니다. 칩 설계를 위해서 그런 것이니 JKFF, RSFF, TFF 등을 구현하고자 한다면 Logic에서 설계된 것을 이용하시면 될 것입니다.

ex1) Rising Edge Flip-Flop library ieee; use ieee.std_logic_1164.all; entity dff is port ( data, clk : in std_logic; q : out std_logic); end dff; architecture behav of dff is begin process(clk) begin if (clk='1' and clk'event) then q <= data; end if; end process; end behav;	ex2) D-Latch with Data and Enable library ieee; use ieee.std_logic_1164.all; entity d_latch is port ( data, enable : in std_logic; y : out std_logic); end d_latch; architecture behav of d_latch is begin process(enable, data) begin if (enable='1') then y <= data; end if; end process; end behav;

생각보다 구현은 간단하죠. process 문안에 재미있는 표현이 있군요.

if (clk='1' and clk'event) then

q <= data;

이 구문은 어떤 의미일까요? 플립플롭에서는 Trigger 방법을 이용한다고 했는데 말이죠.

event를 이용해서 상승 에지를 표현한 것입니다. 외우세요.

그럼 그 반대로 하강에지를 표현하면 어떻게 될까요? 1을 0으로 바꾸면 되겠죠.

if (clk='0□ and clk'event) then

q <= data;

설명할 것은 이것뿐이네요. 다음 예제로 넘어가지 전에 결과를 비교해 볼까요.

그림에서 보듯이 클럭의 입력에 따라 출력이 변한다는 것을 알 수 있습니다.

래치는 입력에 따라 값이 변한다는 것을 알 수 있을 것입니다.

그림이 조금 정확하게 보이지 않는데 주의해서 보시면 될 것입니다.

ex3) Rising Edge Flip-Flop with Asynchronous Reset

library ieee;

use ieee.std_logic_1164.all;

entity dff is

port ( data, clk, reset : in std_logic;

q           : out std_logic);

end dff;

architecture behav of dff is

begin

process(clk, reset)

begin

if (reset='0') then

q <= '0';

elsif (clk='1' and clk'event) then

q <= data;

end if;

end process;

end behav;

설명할 것이 없네요. 말 그래로입니다. reset을 가진 플립플롭입니다. 다만 reset이 0일 때 플립플롭의 기능을 수행하겠죠. 코딩은 reset이 1일 때라고 의문을 가지는 분은 위의 그림을 유심히 보시면 됩니다. reset에 not가 붙어있죠.

ex4) Rising Edge Flip-Flop with Asynchronous Preset

library ieee;

use ieee.std_logic_1164.all;

entity dff is

port ( data, clk, preset : in std_logic;

q           : out std_logic);

end dff;

architecture behav of dff is

begin

process(clk, preset)

begin

if (preset='0') then

q <= '0';

elsif (clk='1' and clk'event) then

q <= data;

end if;

end process;

end behav;

C 언어에서 if-else 구문이 있죠. 이것과 사용법은 거의 비슷합니다. 다만 C 언어에서는

else if 라고 쓰지만, VHDL에서는 elsif 라고 씁니다. 다른 언어와 틀리니 주의하세요.

다른 언어에서처럼 if 구문 속에 if 문이 계속해서 들어갈 수 있습니다. 나중에 예제에서 보겠죠.

ex5) Rising Edge Flip-Flop with Asynchronous Reset and Preset

library ieee;

use ieee.std_logic_1164.all;

entity dff is

port ( data, clk, reset, preset : in std_logic;

q                  : out std_logic);

end dff;

architecture behav of dff is

begin

process(clk, reset, preset)

begin

if (reset='0') then

q <= '0';

elsif (preset='0') then

q <= '0';

elsif (clk='1' and clk'event) then

q <= data;

end if;

end process;

end behav;

Asynchronous Reset and Preset은 시스템이 불안정할 수 도 있다는 것을 알고 있어야 합니다. Asynchronous Reset and Preset보다는 Synchronous Reset and Preset이 안정적이라는 것을 알고 있어야 합니다. 다시 말하면 Asynchronous Reset은 클럭에 관계없이 Reset이 1이면 모든 것을 리셋시키는 기능을 합니다. 그렇지만 시스템 회로 설계에는 Asynchronous Reset이 더 많이 사용되고 있습니다.

ex6) Rising Edge Flip-Flop with Synchronous Reset

library ieee;

use ieee.std_logic_1164.all;

entity dff is

port ( data, clk, reset : in std_logic;

q          : out std_logic);

end dff;

architecture behav of dff is

begin

process(clk)

begin

if (clk='1' and clk'event) then

if (reset='0') then

q <= '0';

else

q <= data;

end if;

end if;

end process;

end behav;

위 그림을 보면 어떤 의미인지 알 수 있을 것입니다.

Synchronous Reset을 사용하므로 훨씬 안정적인 회로이겠죠.

ex7) Rising Edge Flip-Flop with Synchronous Preset

library ieee;

use ieee.std_logic_1164.all;

entity dff is

port ( data, clk, preset : in std_logic;

q          : out std_logic);

end dff;

architecture behav of dff is

begin

process(clk)

begin

if (clk='1' and clk'event) then

if (preset='0') then

q <= '0';

else

q <= data;

end if;

end if;

end process;

end behav;

ex8) Rising Edge Flip-Flop with Asynchronous Reset and Clock Enable

library ieee;

use ieee.std_logic_1164.all;

entity dff is

port ( data, clk, reset, en : in std_logic;

q              : out std_logic);

end dff;

architecture behav of dff is

begin

process(clk, reset)

begin

if (reset='0') then

q <= '0';

elsif (clk='1' and clk'event) then

if (en ='1') then

q <= data;

end if;

end if;

end process;

end behav;

Asynchronous Reset과 Clock이 Enable 될 때 data에 있던 값이 q로 assign 되는 것입니다. 한 가지 예제를 알면 응용하는 범위가 VHDL은 굉장히 넓기 때문에 많은 회로를 쉽세 만들 수 있다는 잇점이 있습니다. 우리가 설계한 회로를 라이브러리에 저장해 그것을 불러서 사용할 수도 있습니다. REUSE 가능한 언어가 VHDL입니다.

ex9) D-Latch with Gated Asynchronous Data

library ieee;

use ieee.std_logic_1164.all;

entity d_latch is

port ( data, enable, gate : in std_logic;

q            : out std_logic);

end d_latch;

architecture behav of d_latch is

begin

process(enable, data, gate)

begin

if (enable='1') then

q <= data and gate;

end if;

end process;

end behav;

래치의 간단한 변형입니다. 그렇게 어려운 것은 없고 출력값이 변하는 것을 유심히 살펴보기를 바랍니다. 클럭이 시작될 때 변하는 것이 아니라 enable이 1인 영역에서 data와 gate가 둘다 1인 시점에서 변한다는 점을 시뮬레이션 결과에서 잘 살펴보기를 바랍니다.

ex10) D-Latch with Gated Enable

library ieee;

use ieee.std_logic_1164.all;

entity d_latch is

port ( data, enable, data : in std_logic;

q            : out std_logic);

end d_latch;

architecture behav of d_latch is

begin

process(enable, data, gate)

begin

if ((enable and gate)='1') then

q <= data;

end if;

end process;

end behav;

if 구문안에 어떤 것이 변하는지 잘 보면 될 것입니다. 그냥 넘어갑니다.

ex11) D-Latch with Asynchronous Reset

library ieee;

use ieee.std_logic_1164.all;

entity d_latch is

port ( data, enable, data : in std_logic;

q            : out std_logic);

end d_latch;

architecture behav of d_latch is

begin

process(enable, data, reset)

begin

if (reset='0') then

q <= '0';

elsif (enable='1') then

q <= data;

end if;

end process;

end behav;

간단한 예제들을 중심으로 플립플롭과 래치에 대해서 알아보았습니다. 8비트 레지스터를 설계하다보면 이 부분에 대해서 다시 한번 살펴볼 기회가 있을 것이라 생각됩니다. 위 예제들을 직접보고 코딩하지 마시고, 이런 기능을 가지고 있으므로 어떤 식의 설계가 들어가야 한다라고 자꾸 생각하시면서 직접 설계해 보시는 것이 기억에 오래 남을 것입니다. 전에도 말씀드렸지만 자기 자신의 고유의 코딩 방식을 절대로 잊지 마십시오. 잘못된 부분이 있으면 저에게 메일주시면 감사하겠습니다. 그럼 이만.