[HARMAN] 세미콘 아카데미/공부내용

[Harman 세미콘 아카데미] Day_23(Verilog)

uiop1716 2025. 3. 7. 22:46

오늘도 간단하게 책에서 배운 개념을 소개하고 넘어가겠습니다.

 

행위수준 모델링 : 조합회로와 순차회로의 설계, 설계된 회로의 시뮬레이션을 위한 Testbench에 작성
     -- always, initial, 태스크, 함수 내부에 사용

     always 구문: initial과 독립적으로 시행

          ㄴ Testbench에서 주로 clk 설정에 사용


     initial 구문 : 시뮬레이션 진행동안 한 번 실행

순차회로 모델링
 - 동기식(Synchronus) 셋/리셋을 갖는 경우 : 클럭 신호만 포함

 - 비동기식(Asynchronus) 셋/리셋을 갖는 경우 : 클럭, 셋, 리셋신호를 포함
      ㄴ ex) always @ (posedge clk, posedge reset)
           ㄴ 이렇게 설정하는 경우, 감시 대상을 두개로 설정했으니깐 비동기
              ㄴ reset과 clk는 서로 상관관계 없이 다르게 동작하기 때문에

 

 

이론은 많이 하지 않아서 이정도로 하고, tick이라는 개념에 대해 배웠습니다. 이번 실습은 100Hz로 분주된 clk를 이용하여 타이머를 만들기 위함입니다. 0부터 9999까지 계속 증가하는 counter에서 tick이라는 특정 신호를 통해 Run/Stop/Clear의 동작들을 할 수 있다고 생각하면 됩니다. 그리고, 이런 동작들을 제어하는 것이 Control Unit 입니다.

tick 예제 그림
tick을 세기 위한 코드

 

틱을 1000개 count 하는 코드를 설명하자면,  counter_reg는 state, counter_next는 next와 같다고 생각하면 됩니다. 이전 포스트에서 Moore 모델을 사용할때 사용하던 것 처럼 말이죠.
counter_reg가 0이면 next = 1  ->  next의 값을 다시 reg에 넣어 reg가 1, 그럼 next가 2로 되는 방식으로 쭉쭉쭉쭉 진행하며 counter_reg가 9999가 된다면 counter_next가 초기화 되고, 다음 tick에 counter_reg 또한 0이 되며 초기화 됩니다.

 

즉, 100Hz clk를 통해 10ms의 주기를 가지고 나오는 tick을 만들고, 이 tick을 10000번 나타내면 초기화 하고 다시 증가하는 싸이클을 돌며, 전체적으로 100초 주기 동작을 수행하도록 합니다. 우리가 10000진 카운터를 설계한 이유도 결국엔 100초 주기의 제어 가능한 카운터를 만들기 위함 입니다. 추후, 100초 카운터에서 발생하는 tick을 통해 60초 카운터도 만들며, 타이머를 만들기 위한 빌드업 중 하나입니다.

 

100Hz clk를 이용해 tick을 만든 모습

 

 

또한 이번 그림에는 나오지 않지만, SW0, SW1을 각각 RUN/STOP 동작, Clear 동작을 하도록 설정하였습니다.

아래 그림의 경우, clear를 위한 조건을 추가하여 동작 중 값을 모두 지우는 동작을 추가하였습니다.

Clear 동작을 위한 조건 추가
100Hz의 clk을 받는 tick_counter가 추가된 모습

 

 

이렇게, 버튼을 눌러 Run/Stop/Clear 동작을 수행하면 버튼을 누르고 때는 과정에서 노이즈가 생성됩니다. 이를 제거하기 위해 Debouncing이 필요합니다.

버튼을 눌렀다 떼며 발생하는 노이즈

 

Debouncing의 경우, 플립플랍 여러개를 이어붙여 시프트 레지스터 방식을 사용해 제거합니다.

아래 그림을 예로 들면, 1011111... 이라는 신호가 q0로 들어오게 되면, shift register를 통해 다음 플립플롭에 값을 밀어 넘깁니다. 파행을 보면, 다음 출력들인 q1, q2, q3의 값들이 한 칸씩 밀려 늦게 들어와 있는 것을 볼 수 있습니다. 그리하여, 각 플립플롭의 출력값들을 AND를 통해 한 곳에 모으게 됩니다. 그러면, q4가 1이 되는 시점부터 모든 출력들이 1이기 때문에 AND 연산을 통해 만들어진 and4의 값은 D Flip Flop에 또 들어가게 됩니다. 이때, D Flip Flop은 동일한 클럭을 사용하여 Q4라는 출력값은 다음 clk에 출력됩니다. D Flip Flop을 거친 한 클럭 늦는 값은 반전되어 기존의 and4 값과 또한 번의 연산을 통해 p1이라는 짧은 주기의 에지를 검출합니다.

이렇게 발생하는 정교한 에지의 상승 또는 하강으로 정확한 입력을 감지하여 Debouncing을 제거하게 됩니다.

Debouncing 을 위한 에지를 위한 설명

 

이러한 내용으로 기존에 설계 하였던 SW or Button으로 타이머의 Run/Stop/Clear를 담당하는 Control unit에 Debouncing Logic을 추가하여 정교한 입력을 구현할 것입니다.

Control Unit에 Debouncing을 추가한 회로

 

 

구현한 코드는 다음과 같습니다. 코드는 위에 있는 엣지에 관한 회로와 동일하게 설계하였습니다.

Debouncing 구현 코드

 

 

결과 : Run/Stop버튼과 Clear의 두 버튼에 Button_Debouncing 로직을 Control Unit에 추가해 놓은 모습

Debouncing Schematic

 

 

숙제로는 다음과 같은 회로를 구성하였습니다. 앞으로 타이머에 사용될 회로를 작성하였습니다.

앞으로 사용할 타이머는 10ms 주기의 clk에서 나오는 tick으로 Millisecond(밀리초)에 사용하고, 다시 밀리초에 대한 Tick으로 60초 카운터를 만들어야 합니다. 하지만, 이번 실습은 교수님께서 개념을 이해하는데 초점을 두라고 하셔서 밀리초, 초에 대한 로직을 각각 l00Hz clk를 사용하여 각각의 모델로 생성하고 7segment를 반으로 나눠 출력하여 6000까지 찍고 초기화 되는 로직을 설계하였습니다. (결과론적으로 6000진 카운터와 동일한 결과를 냅니다...)

 

타이머의 Run/Stop/Clear를 담당하는 Debouncing이 추가된 Control Unit은 그대로 사용하고, 10ms 주기의 Tick을 생성하는 100Hz clk도 그대로 사용합니다. 이를 통해 타이머의 Millisecond(밀리초) 로직과 Second(초) 로직을 설계하고 FND를 통해 출력하는 것입니다.

밀리초의 경우는 100까지 증가하면 초가 1 증가하고, 초는 60을 찍으면 초기화 됩니다. (이것도 결과론적으로 보면 6000bit couter와 동일합니다...)

회로도

 

 

코드 입니다. 우리는 100Hz clk의 10ms 주기의 틱을 사용하여 Millisecond, Second를 나타낼 것이기 때문에, Tick을 활용한 주기 생성에서 Millisecond의 경우에는 100까지, Second의 경우에는 6000까지 하였습니다.

이렇게 설정하여 Segment를 반으로 갈라서 보면 초와 밀리초가 타이머처럼 동작하는 것을 볼 수 있습니다.

Millisecond를 구현하기 위해 tick이 100번 돌고 초기화되도록 설정
Second를 설정하기 위해 6000번의 tick을 주기로 사용

 

이에 대해, 세그먼트에 출력하기 위한 FND Controller도 손봐주었습니다.

100개의 틱이 필요한 밀리초는 7bit, 6000개의 틱이 필요한 초는 (원래 13bit)로 입력을 받고 segment로 출력합니다
Splitter를 두개로 나눠 밀리초, 초를 각각 출력하도록 설정
Splitter를 두개로 나눠 밀리초, 초를 각각 출력하도록 설정

 

결과: 

Schmatic을 출력해보면, 잘 보이지는 않지만 Counter_tick_100 모듈과 Counter_tick_6000 모듈은 100hz의 클럭에서 발생하는 Tick을 사용합니다. 이를 통해 100까지 순환하는 밀리초, 6000까지 순환하는 초를 FND Controller에 값을 전달하여, 밀리초는 세그먼트의 뒷부분에, 초는 세그먼트의 앞부분에 출력되도록 합니다. 

Schematic

 

동작 영상이 짤리긴 했지만, Debouncing 로직이 추가된 Run/Stop 버튼을 누르면 밀리초, 초가 증가하고 Reset 버튼 또는 Clear 버튼을 통해 값을 초기화 하는 것을 볼 수 있었습니다. 결과적으로, 값이 6000까지 증가하고 초기화 되는 모습을 볼 수 있습니다.

HW.mp4
6.16MB

 

 

분주한 클럭에서 발생하는 틱에 대한 개념이 많이 부족하여, 공부하는데 어려움이 있었습니다. 숙제를 하는데 시간도 꽤 걸렸구요... 덕분에 집에 늦게 가긴 했습니다만 ㅎㅎ, 모르는 부분들을 여러 친구들이 같이 도와줘서 많이 배울 수 있었습니다. 고생한 만큼 머리에도 오래 남을 것 같다라는 생각이 들었고 공부를 더 열심히 해야겠다는 생각을 많이 하게 되었습니다. 복습 철저히 해서 Verilog 팀 프로젝트를 진행할때 많은 부분에 기여하여 수월하게 진행하고 싶습니다.