6. Sequential Logic_ Counter
논리회로 포스팅에서 Sequential logic을 다뤄서 해당 내용에 대해 베릴로그 코딩을 할 생각이 있는데 뭐를 먼저 할지 마땅히 생각이 안나서 gpt한테 물어보았다.
따라서 이번 포스팅에서는 Counter 설계를 해볼까 한다.
앞으로 어떤 것들을 설계하던지간에 처음에 큰 틀을 잡아야한다.
Counter를 어떻게 설계할 것인가? 매 clk cycle마다 count횟수가 1씩 높아지며, reset 신호를 주면 초기화시키고, input값으로 일정 값을 주면 해당 값까지 count횟수가 높아지다가 같아지면 stop 또는 초기화를 시켜주게끔 만들자.
처음에 input값을 넣어주고, 그다음 current state와 이 값을 비교하고 출력으로 up 또는 stop, next state update 이런 과정이 들어가야 할 것이다.
그림으로 나타내면 다음과 같다.
100까지 세는 카운터를 설계해보자.
위 그림은 내가 처음에 설계를 해야겠다고 생각하고 그린 카운터의 top module을 나타낸 그림이다.
좀 더 생각을해보자.
카운터 동작을 하는 core가 하나 필요할 것이고 이 core를 동작할지 말지 필요한 controller(FSM) 이 필요하다.
그 위에 testbench로 두개를 감싸고 연결해줘야하는데 그림으로 나타내면 다음과 같다.
Sequential logic을 어떻게 베릴로그 코딩하는지는 아직 내가 관련 포스팅을 하나도 올리지 않았긴한데 우선 코딩한것을 보고나서 설명을 이어가보겠다.
![]() |
Counter 역할을 수행하는 모듈이다.
![]() |
![]() |
controller역할을 수행하는 모듈
![]() |
![]() |
testbench
코드를 다 짜고 시뮬레이션까지 돌린 후 생각을 해보았는데 문법자체를 0부터 끝까지 다 설명할필요는 없어보인다. 위 코드를 보고 이해가 안되는 부분은 각자 구글링을 하거나 질문을 남겨주시면 제가 친절하게 답변드리는걸로 하는게 더 좋아보인다.
대신, 몇가지 팁(?)을 주자면, FSM을 만들때 3가지를 생각하자.
1. Current state 할당
2. Next state 할당
3. output할당
위 코드를 보면 always 한 block당 위 3가지 과정을 코딩한것을 볼 수 있다.
4. 그리고 output의 경우 only depends on current state임을 잊지말자.
module을 정의할때 (port list)를 쓴 후,
port 정의 (input, output)
net/ varaible정의
...
순으로 이어나가는데
5. 사용할 wire 및 reg가 여러 bit를 사용하고 그거를 input/output으로 사용할때 port 정의할때 multi bit을 사용해줘야한다는것 또한 잊지말자.
6. FSM 그림을 꼭 그리고나서 코딩을 하자.
필자가 처음에 FSM diagram을 다음과 같이 그리고 코딩을 시작하였다.
combination logic을 베릴로그할때 truth table -> k-map으로 최적화한것을 보고 코딩을 하였는데, sequential logic같은 경우도 미리 FSM을 다 그려놓고 그대로 코딩해야 나중에 헷갈리지않고 마무리할 수 있다.
좌우지간, 위에 짠 코드를 시뮬레이션 돌려보면 다음과같다.
잘안보이므로 처음과 마지막 부분을 확대해보면,
다음과 같다.
여기서 cnt가 103까지 올라간것을 볼 수 있다.
뭐지? 싶은데 이거는 Sequential logic이기 때문에 어쩔수 없다.
c_state와 n_state를 scope를 추가해서 함께 살펴보자.
그럼 다음과 같은 시뮬레이션 결과를 볼 수 있는데,
100이 되자마자 n_state는 STOP state가 되지만, c_state는 다음 clk posedge에서 n_state가되므로 cnt가 102가 될때 STOP상태가 되고, en신호와 stop신호는 c_state에 의해 결정되므로 다음 clk posedge에서 이 상황을 인지하기 때문에 103까지 올라가게되는것이다.