verilog(6) - 카운터(1)

유사인간·2023년 5월 3일
0
post-thumbnail

카운터 만들기

컴퓨터 cpu에는 여러가지 게이트 구조들이 있다. 예, 아니오를 판별하는 논리 게이트의 무한정 분기를 허용하여 프로그램과 데이터를 읽기도 한다. 그 중, 우리로 하여금 2진수를 읽지 않고, 10진수를 사용할 수 있게 하며 덧셈과 뺄셈, 나눗셈, 곱셈을 할 수 있게 해주는 기초인 카운터에 대해서 소개하고자 한다.

카운터의 논리구조

카운터는 기본적으로, 이전 상태라고 하는 state라는 개념으로 출발해야 한다. 카운터는 여러 개의 FlipFlop으로 구성되어 있으며, 이들은 1bit의 정보를 저장할 수 있다. 이들을 참고하여 카운터는 다음 숫자를 셀 수 있는 것이다.

3bit 카운터의 설계

다음 코드를 보면 어떤 사실을 알 수 있다.

module	cnt8	(clk, rst, en, q, tco);
	input		clk, rst, en;
	output	[2:0]	q;
 	output		tco;

	reg	[2:0]	q;
	reg		tco;

	always @ (posedge	clk	or	posedge	rst)	
	if (rst)
	begin
		q 	<= 3'b000;
		tco	<= 1'b0;
	end
	else if	(en)
		if	(q == 3'b110)
		begin
			q	<= q + 1'b1;
			tco	<= 1'b1;
		end

		else if	(q == 3'b111)
		begin
			q	<= 3'b000;
			tco	<= 1'b0;
		end

		else
		begin
			q	<= q + 1'b1;
			tco	<= 1'b0;
		end
endmodule	

카운터는 기본적으로 rst 신호와 en 신호를 받고 동작하며, clk의 상승엣지마다 동작함을 확인할 수 있다. 또한 이 카운터는 3bit짜리 카운터이므로, 한 자리에서 0~7까지 셀 수 있다. 6까지 세면, 이 카운터는 다음과 같은 행동을 한다.

	else if	(en)
		if	(q == 3'b110)
		begin
			q	<= q + 1'b1;
			tco	<= 1'b1;
		end

		else if	(q == 3'b111)
		begin
			q	<= 3'b000;
			tco	<= 1'b0;
		end

7을 세었을 때, 0으로 초기화하는 행동과 다음 캐리를 내보내는 행동을 진행하지 않고 6부터 이 행동을 시작하는 것을 관찰할 수 있다. 이것은 카운터의 확장성과 관련이 있다. 카운터가 확장을 용이하게 하려면 동기형으로 진행되어야 하는데, 카운터가 만약 비동기형이라면 clk 신호가 따로따로 주어져야 하고, 3개가 연속으로 비동기형 카운터가 연결되었을 시, 신호가 한 템포 느려지는 현상이 발생하기 때문이다.

TB_cnt8

TestBench와 Gragh를 통해 확인해보자.

`timescale	1ns/1ps

module	TB_cnt8;
	reg				clk, rst, en;
	wire	[2:0]	q;
 	wire				tco;

	cnt8	U0	(.clk(clk), .rst(rst), .en(en), .q(q), .tco(tco));

	always	#5	clk = ~clk;

	initial begin
		clk	= 1'b0;
		rst 	= 1'b0;
		en	= 1'b1; 
	end
	
	initial begin
		rst 	= 1'b1; #20; rst	= 1'b0;
	end

	initial begin
		#50;	en	= 1'b0;	#20;	en	= 1'b1;
	end
endmodule	

en은 여기서 이전 캐리가 넘어왔을 시, 동작할 수 있게 하는 tco의 명시적 연결형이다. 따라서, 다음 en은 tco이어야만 en이 1으로 진행하였을 때 동작하여 다음 카운터가 캐리를 받을 수 있다.

  1. en이 0이었을 때, 카운트 동작을 멈추는지 살펴본다.
  2. rst 신호가 카운터를 정상적으로 RESET시키는지 살펴본다.
  3. clk의 상승엣지마다 카운트가 진행되는지 살펴본다.

TB_cnt8의 결과/고찰

  1. 첫 주기의 카운트가 011일때, en신호를 2clk(20ns)동안 0으로 인가하였다. 그러자 정확히 2clk동안 카운트가 진행되지 않았다.
  2. rst신호를 초기 20ns동안 인가하였다. q가 000으로 리셋되는 것을 확인할 수 있다.
  3. q가 111에서 tco를 넘기는 것을 확인할 수 있다. 신호가 clk이 상승할때만 항상 동작하기에 동작이 1clk 늦어져 반영되는 것을 확인할 수 있다.

따라서 2주기 전에 tco를 1로 넘겨야 1주기 전에 tco에 반영되고, 다음 카운터의 en에 정확한 타이밍에 전달된다는 사실을 알 수 있다.

profile
유사 인간에 주의하세요.

0개의 댓글