Verilog Guide 1

허가은·2022년 9월 15일
0

Verilog Guide

목록 보기
2/3
  • Gate Level
  • Behavioral Level
  • Dataflow level

베릴로그에서 코드를 짜는데는 세 가지 방법이 있다.
Gate Level의 작성, Behaviral level의 작성, Dataflow level의 작성.
사실 엄밀한 분류인것같진 않은데... (검색해보면 좀 다양하게나옴)
디지털시스템을 처음 가르쳐주신 교수님이 이렇게 구분해서 과제해오라 시키셨다.

이 글은 full adder를 각각 gate level, behavioral level, dataflow level로 작성하여 각각의 특성을 보고자 한다.

1. Gate Level

일단 Gate Level부터 알아보자.

code

module full_adder (
    input a, b, c_in,
    output sum, c_out
);
    wire s1, c1, s2;

    xor g1(s1, a, b);
    and g2(c1, a, b);
    xor g3(sum, s1, c_in);
    and g4(s2, s1, c_in);
    or g5(c_out, s2, c1);
endmodule

위의 코드가 Gate Level로 작성된 full adder이다. 모두가 알다시피 full adder는 다음과 같이 생겼는데, 각각의 wire와 gate를 열심히 이어서 만들어주면 된다.

설명

gatelevel modeling의 코드를 좀 더 뜯어보자.
코드는 다음과 같이 작성하면 된다.

'사용하는 모듈' '모듈이름' ('output', 'input1', 'input2', ... 'input n') ;

위에서는 다음과 같이 작성한것이다.

and g2(c1, a, b);

and는 입력이 한개, 출력이 두 개인 게이트이며 베릴로그는 and, or, xor, nand, nor, xnor등을 제공한다.

2. Behavioral model

behavioral modeling이 제일 많이 쓰인다. 회로의 기능이 복잡해지면 일일히 게이트단계로 그려낼 수 없다. 우리가 C-like문법으로 디지털 회로의 기능을 description해주면 컴파일러가 열심히 일해서 회로를 짜잔~ 뽑아줄것이다. 그것이 베릴로그와 같은 HDL(Hardware Description Language)의 의의인것이다.

code

module full_adder (
	input a, b, c_in,
    output sum, c_out
);
    reg sum, c_out;
    always @(a, b, c_in) begin
        {c_out, sum} = a + b + c_in;
    end
endmodule

코드가 베릴로그 초짜가 이해하기엔 좀 거시기하다. 이 글에서 스타일을 이해하려하기보다 그냥 adder는 gate level로 짜고 다음 글에 있을 mux나 decoder 코드를 보고 이해해보는 것이 좋다.

설명

behavioral modeling의 가장 큰 특징은 always문을 사용하는 것 같다.
always문은 지정된 이벤트(변화)가 감지될 때 마다, begin - end 구문으로 묶인 사이의 행동을 하도록 한다. always문은 다음과 같이 사용한다.

awlays @('event') begin
	'변수' = '할당식';
end

위의 코드의 경우 a, b, c_in이 변화할 때 마다, a+b+c_in의 2bit 값을 각각 c_out과 sum에 할당한다.
always문에서 할당될 왼쪽의 변수들은 꼭 reg로 선언되어야 한다. 이 reg와 wire의 선택이 굉장히 많이 헷갈리는데... always문 안에 들어갈거면 reg를 써보자.

3. Dataflow level

사실 이 dataflow level이 정확히 어디 쓰여야하는지 아직 잘 모르겠다. 이름이 왜 dataflow인지도 모르겠다. 그렇지만 교수님이 그걸로 구현해오라고 하면 하는게 학부생인거다.

code

module full_adder(
	input a, b, c_in,
    output s, c_out
);
    assign s = a^b^c_in;
    assign c_out = (a&b)|((a^b)&c_in);
endmodule

설명

약간... gatelevel과 뭐가 다른지 모르겠다. 그렇지만 분명 생긴게 다르다. dataflow level은 저 assign문을 사용한다. assign문은 다음과 같이 쓴다.

assign '변수' = '할당식';

할당식은 ^로 xor, &로 and, |로 or을 표현하여 각 변수를 사용한 논리연산을 해 줄 수 있고, 4'b0000;과 같은 값이 들어갈수도 있다. 할당받는 변수는 wire로 선언되어있어야 한다. (input, output으로 선언된 wire들은 추가적인 reg 선언이 없다면 wire이다.)

4. 닫으며

베릴로그로 프로젝트를 해본지 세달쯤 지나니까 사실 좀 가물가물하다. 근데 대충 맞을거다. 틀린거나 모르겠는거 있으면 댓글로 얘기해주세요...

0개의 댓글