[Harman 세미콘 아카데미] Day_20(Verilog)
오늘도 verilog 배운 것을 작성해 보겠습니다.
교수님께서 저번에 숙제로 내주신 8bit adder에 대한 활용입니다.
저번에 학습했던 7segment 출력을 위한 모듈들에 8bit Adder, Digital Splitter, 4X1 MUX를 추가하였습니다.
8bit Adder의 연산으로 8bit의 Sum과 1bit의 Carry를 하나의 9bit output으로 출력하게 됩니다. 그리고 Digital Splitter를 거치게 됩니다.
Digital Splitter는 숫자의 각 자릿수를 4개의 FND에 차례대로 표현하기 위해 생성한 모듈입니다. 이 모듈을 걸쳐 나오게 되는 4개의 값들은 기존에 생성한 BCD Decoder에 들어가야 합니다. 하지만, 생성한 Decoder는 입력 단자가 하나로 설정되어 있기 때문에, 4X1 MUX를 설계하여 하나의 출력을 만들어 낼 수 있도록 하였습니다.
아래의 코드에서, 8bit의 Sum값과 1bit의 Carry에 대한 와이어들을 .bcd({w_carry, sum2seg})로 9bit를 전송할 수 있도록 설계하였습니다. (이때, { }은 연결 연산자로 여러 신호를 묶습니다.)
mux 4x1 부분에서 default = 4'bx는 미정의 상태를 나타내는 것으로, 값을 결정하기 힘들때 사용합니다.
Schematic 결과:
위의 그림과 같이 8bit Adder의 결과인 C와 S가 합쳐져 하나의 결과로 FND Controller에 들어갑니다.
그림이 깨져서 잘 안보이지만(죄송합니다 ..ㅜ) FND Controller 내부에 4X1MUX와 Digital Splitter가 잘 들어가 있음을 확인할 수 있습니다. 저희가 처음 그렸던 블록도와 같이 Schematic이 나옴을 확인합니다.
이제, Clock과 Reset을 사용할 것입니다. Clock은 순차 논리회로를 동작하기 위한 신호입니다. 우리가 여태껏 공부한 Half, Full, 4bit, 8bit Adder들과 Decoder, MUX 등등은 모두 조합 논리회로 입니다. 모두 현재 입력 값으로 출력을 결정하는 구조이죠. 즉, 자동화가 어렵습니다. 하지만, 순차 논리회로는 현재의 입력값과 저장된 과거의 메모리를 통해 출력을 결정하게 됩니다. 클럭의 신호가 0->1, 1->0으로 변하는 순간을 edge라고 하는데, 이 타이밍을 이용하여 동작을 제어합니다.
이를 구현하기 위해, clk와 reset 그리고 4bit counter 을 추가하여 블록도를 그렸습니다.
4bit counter를 추가한 이유는, clk와 reset에 대해 배우면서 4X1 MUX에 들어갈 2bit Sel와 2X4의 input에 들어갈 2bit 신호를 만들기 위해서 입니다.
4bit counter는 clk와 reset의 상승 에지일때를 항상 감지하여, r_counter라는 값이 0->1->2->3->0으로 계속 순환하는 형태입니다. 0부터 3까지 증가한 후, 오버플로우에 의해 0으로 다시 돌아와 순환합니다. 그리고 reset이 상승 에지가 되는경우, r_counter 값은 0으로 초기화 되는 그런 형태입니다.
실습 보드로 결과를 확인하였을 때, 클럭이 너무 빠르게 돌아 우리 눈에는 불이 계속 나오는 것으로 보였습니다.
이에, 정확히 보기 위해 분주비 라는 개념을 이용하여 클럭의 주파수를 낮추도록 설계하였습니다. 우리 눈에 잘 보이기 위해 200Hz로 설정하였고, 10ns 주기의 입력 clk를 500_000이라는 분주비로 나눠 200Hz의 clk를 출력하도록 하였습니다.
이때, 출력과 있는 레지스터는 r_clk 입니다. 우리가 분주하는 신호를 담은 레지스터로, r_clk가 계속 0으로 있다가, 1씩 증가하는 r_counter가 특정 값에 도달하게 되면 r_clk가 1로 변하며 하나의 주기를 만들어 내는 형태입니다.
** 이때, $clog2(그냥 원하는 숫자)를 사용하면 번거롭게 계산을 안해도 됩니다 .ㅎㅎ **
Schematic 결과로, fnd Controller에 clk_diviser가 추가됨을 확인할 수 있습니다.
이에 대한 강화 학습으로 10000진 카운터를 붙혀넣는 실습을 진행하였습니다.
기존에 작성하였던 FND Controller 모듈만을 가지고, 10000진 카운터와 연결하여 사용하도록 하는 것 이였습니다.
숫자 10000은 14비트를 사용하였고, 14비트의 출력값은 Digital Splitter로 들어가도록 설계하였습니다.
10,000bit Counter의 경우 외부의 clk와 reset을 가져와 0~9,999까지 증가하는 r_counter를 설계하여 만들었습니다. 또한, count라는 14bit의 출력을 FND Controller의 Digital Splitter에 입력하도록 설계합니다.
Schematic 결과:
그리고, 이를 활용한 숙제도 있었습니다.
바로, 10Hz의 clk Divider를 만들어 10,000bit counter와 연결하고, 0번 버튼의 스위치를 통해 r_counter stop/count 하도록 설정하고, 1번 버튼으로 r_count값을 reset 시키는 것입니다.
10Hz의 경우, 아까 사용하였던 clk_divider에서 분주비를 10,000,000으로 설정하여 10Hz를 출력하도록 하였다.
각각 보드의 0번,1번 스위치를 담당하는 bit1과 bit2라는 버튼의 입력을 추가하여, 0번 스위치가 1일경우 reset을 시키도록 하였다. 또한, 1번 스위치인 bit2는 HIGH(1) 상태일 때, r_counter를 계속 출력하다가 LOW(0) 상태일 때는 멈추도록 구현하였다.
결과: Schematic도 이쁘게 나오고, 모든 기능들 또한 동작을 잘 하였다. 자세한 부분은 교수님의 review와 함께 내일 또 다뤄보겠다.
어제보단 오늘이 더 verilog 문법에 익숙해 질 수 있었던 것 같다. 확실히 많이 보다 보면 실력이 조금씩 늘어나는 것 같다. 아직은 남들보다 잘 못하고 어려움이 있지만, 꾸준히 복습하고 노력하다보면 언젠간 나도 Verilog를 잘해질 날이 올 거라고 믿는다. 지금은 블록도를 보면서 설계하는게 편한 초보이지만, 언젠간 머리속으로 그리고 생각해서 촤라락(?) 작성해나가는 멋쟁이가 되고싶다 ㅋㅋㅋ