Verilog_Counter

공이지·2024년 7월 17일

비동기 카운터는 문제가 발생하기 때문에 앞으로 동기식 회로만 만들기때문인데 always문에는 clk과 reset_p 만 사용할 것! 따로 synchronous 안붙여준 이유는 앞으로 무조건 동기식을 사용할것이기 때문

이전 정리

RTL을 설계하기 위해서는 Register(F/F)를 잘알아야한다.
구조적 모델링을 사용하지만 Gate Level로 모델링하는 방법은 사용하지 않는다.

  • 인스턴스 : 다른 모듈에서 정의한 모델을 다른모듈에서 가져와서 커스텀? 해서 사용하는 것.
    ex.반가산기 2개로 전가산기를 만들 때 전가산기의 모듈에 반가산기 모듈 2개를 인스턴스함.)
  • wire에도 pdt가 무시할 정도로 적게 존재하지만 반도체의 나노공정으로 들어가면 이를 무시하지 못한다. 그래서 pdt를 방지하기 위해 Ripple Carry Adder(캐리예측가산기)를 사용한다.
  • 비교기에서 32bit까지는 만들어지는 칩의 크기는 같다!
    왜? 1비트와 32비트 비교기의 기본적인 회로 구조는 유사합니다.
    32비트 비교기는 1비트 비교기 회로를 32개 병렬로 연결한 형태입니다.
    이렇게 단순한 구조로 인해 회로 복잡도 증가가 크지 않습니다.

mux : 데이터 선택기
demux : 데이터 분배기

SL(Sequnetial Logic)
D F/F 이 중요!(1bit memory)
LUT(Look Up Table) : MUX로 만든다.

  • 모든 TruthTable이 존재하면 MUX를 이용해서 접지와 VCC에 연결할 수 있다. 그렇다면 TruthTable로 작동하는 논리회로가 만들어진다 (Ex. And Gate동작을 하는 MUX )

T F/F : T 가 0 이면 출력을 유지. T가 1이면 출력을 반전.

  • elobrate로 로직을 구현하면 Gate Level로 구현하여서 T F/F을 D F/F의 출력이 입력으로연결되고 거기에 NOT gate가 붙는다. synthesis로 구현하면 LUT으로 구현한다. (위 그림 참고!)

    결국에는 vivado가 다 최적화 해줘서 사용하는데는
    카운터에서 업카운트 될때 0000 -> 0001 이 될때 비동식카운트는 0000 -> 0001이 단번에 바뀌지 않고 PDT시간만큼 잠깐 중간에 0000이 되는 문제가 발생될 수 있다. 즉 동기식카운터를 사용해야한다~~!!!

동기 업카운터(상승엣지)

  • 동기식 카운터에서 AND Gate가 존재하는 이유는 동기이므로 같은 클럭을 서로 갖는데 기본적인 카운터방식이랑 유사하지만 T F/F을 사용하면서 두번째 F/F은 첫번째의 F/F의 출력이 1일때 2번째 F/F의 입력이 반전된다. 3번째 F/F은 첫번째, 두번째 F/F이 모두 1이되면서 Falling edge일때 세번째 출력이 반전된다. 이를 위해 And Gate로 첫번째, 두번째 출력을 And gate한 연산을 3번째 입력과 함께 들어간다.
  • enable이 1이면 0~16(4비트이므로) 까지 카운팅한다.
    시작은 당연히 초기값인 0부터 + 1이므로 1,2,3,4 ...~ 15,16 까지 카운팅한다
  • reset_p 가 1이면 count값은 0으로 초기화합니다.

동기 다운카운터(상승엣지,하강엣지)

  • 상승엣지
  • 하강엣지
  • 상승엣지 시뮬레이션 결과
  • 하강엣지 시뮬레이션 결과
  • enable이 1이면 다운카운팅을한다. 동기식이므로 상승엣지트리거링이든 하강엣지트리거링이든 관계없이 다운카운팅을한다. 초기값을 0으로 초기화해주고 enable이 1일때 count - 1 을 실행한다. 0~16까지가 최대 카운팅 할 수 있는 범위기에 0에서 -1 을하면 16이 초기값이 되면서 15,14,13... ~ ...3,2,1 순으로 다운카운팅을 한다.

BCD Counter

  • BCD카운터의 상태도와 회로도

UP Counter


  • 동작설명 : 0~9까지 카운트하고 9(1001)보다 커지면 0으로 되돌아간다!
    따로 enable을 입력으로 두지 않았으므로 enable은 언제나 1이다 하지만 enable이 0이 된다면 업카운터가 동작하지 않을것이다.
    이는 4비트지만 10 진수 0 ~ 9까지를 2진수로 변환하는 회로이다. 이는 만약 12를 2진수로 바꾼다고하면 1 => 0001 , 2 => 0010 으로 하여 0001(1), 0010(2) 이런식으로 10진수를 표현한다. 하지만 연산을하면 3 이되므로 연산은 하지않고 그저 12라는 10진수를 2진수로 표현해주기 위함이다! 그래서 0~9 까지로만 표현을 제한해주기 위해 count가 9 이상의 값이 나오게 되면 count는 다시 0으로 되돌아가도록 코드를 작성했다.

Down Counter

  • 동작설명 : 9 ~ 0 순으로 카운트를한다. 0이 카운팅되면 9로 돌아간다. 이때 9보다 큰 값이 나오지 않게 하기 위해서 >= 10 과 0일때 9로 돌아가기위해 == 0 다음과 같은 조건을 작성해주었다. 위의 bcd 업카운터와 같은 원리를 사용한다!!

UP&Down Counter

  • 동작설명 : up_down이라는 enable신호가 1이면 상승카운터, 0이면 다운카운터로 동작합니다. 만약 상승카운터일때 9를 넘기는 값이 나오면 0으로 되돌아가고 다운카운터일때 0 이하의 값을 만나면 다시 9로 돌아간다.

Ring Counter

  • 계수 카운터하는 동작보단, 일련의 동작을 제어할때 더욱 유용하다. 보면 카운터가 아니라 비트 단위로 1이 이동하는 것을 볼 수 있습니다.
  • 동작설명
  • shift연산자로 작성한 링카운터.

    else q[3:0] = {q[2:0],1'b0};
    다음 코드를 설명한 자료! 4비트짜리 q출력에 하위 3비트에 + 1'b0(0)을 할당한다. 즉 하위 3비트를 한칸씩밀어넣고 마지막에 0을 밀어넣어준다.

Edge Detector

상승엣지 동작

하강엣지 동작

  • 동작설명 : CP첫번째 F/F의 입력이다!(clk주기와 관계 없음) 이 후 내가 설정한 트리거링에 따라서 reg로 선언한 데이터 변수 currentold첫번째 F/Fcurrent가 1이되고 다음 clock에서 old가 1이될 것이다. 이때 출력으로 선언한 p_edge,n_edge에 이 currentoldclock 펄스 차이로 출력을 결정한다. current가 1이고 old가 0일때 p_edge가 1이되고 old가 1이고 current가 0일 때 n_edge가 1이된다
profile
화이팅..!

0개의 댓글