Positive 업 카운터
module up_counter_p(
input clk, reset_p, enable,
output reg [3:0] count);
always @(posedge clk or posedge reset_p)begin
if(reset_p)count=0;
else if(enable)count=count + 1;
end
endmodule
Vivado에서는 C언어와 같이 증감 연산자를 사용할 수 없기 때문에 count = count + 1과 같이 코딩한다.
시뮬레이션을 진행할 때, Reset 값에 1을 인가한 뒤 0으로 인가해주어야만 정상적인 동작을 수행한다.
Reset을 하지 않으면, 그전에 어떤 값이 들어있는지 모르기 때문에 초기화를 한번 진행해 주는 것이다.
Rising Edge일 때마다 출력값이 1씩 증가하는 것을 확인할 수 있다.
Positive 다운 카운터
module down_counter_p(
input clk, reset_p, enable,
output reg [3:0] count);
always @(posedge clk or posedge reset_p)begin
if(reset_p)count=0;
else if(enable)count=count - 1;
end
endmodule
다운카운터 할 때에는 count = count - 1로 변경하여 진행한다.
Rising Edge 때마다 출력값이 1씩 감소하는 것을 확인할 수 있다.
Negative 업 카운터
module up_counter_n(
input clk, reset_p, enable,
output reg [3:0] count);
always @(negedge clk or posedge reset_p)begin
if(reset_p)count=0;
else if(enable)count = count + 1;
end
endmodule
Positive 때와는 달리, Falling Edge일 때마다 출력값이 1씩 증가하는 것을 확인할 수 있다.
Negative 다운 카운터
module down_counter_n(
input clk, reset_p, enable,
output reg [3:0] count);
always @(negedge clk or posedge reset_p)begin
if(reset_p)count=0;
else if(enable)count=count - 1;
end
endmodule
Falling Edge일 때마다 값이 1씩 감소하는 것을 확인할 수 있다.
동기식 BCD 업 카운터
module bcd_upcounter_p(
input clk, reset_p,
output reg [3:0] count);
always @(posedge clk or posedge reset_p)begin
if(reset_p) count = 0;
else begin
if(count >= 9) count = 0;
else count = count + 1;
end
end
endmodule
출력값이 0부터 1씩 증가하다가, 9를 넘어가서는 10으로 되지 않고 0으로 다시 초기화되는 것을 확인할 수 있다.
동기식 BCD 다운 카운터
module bcd_downcounter_p(
input clk, reset_p,
output reg [3:0] count);
always @(posedge clk or posedge reset_p)begin
if(reset_p) count = 9;
else begin
if(count >= 10 | count == 0) count = 9;
else count = count - 1;
end
end
endmodule
BCD 업 카운터와는 달리, 9부터 1씩 작아지는 모습을 띤다. 0이 되었을 시 다시 9로 초기화되는 모습을 볼 수 있다.
3비트 동기식 카운터
구현할 카운터는 업 다운 카운터로, up_down이 1일 시에는 0부터 9까지 증가, 0일 시에는 9부터 1까지 감소하는 동작을 수행한다.
module up_downcount_p1(
input clk, reset_p,
input up_down,
output reg [3:0] count);
// 1 = up counter, 0 = down counter
always @(posedge clk or posedge reset_p)begin
if(reset_p) count = 0;
else begin
if(up_down)begin
if(count >= 9) count = 0;
else count = count + 1;
end
else begin
if(count == 0) count = 9;
else count = count - 1;
end
end
end
endmodule
출력 결과를 확인해 보면 up_down이 0일 시에는 1씩 감소하는 모양을 보이며, up_down이 1일 시에는 1씩 증가하는 모습을 볼 수 있다.
링카운터
module ring_counter(
input clk, reset_p,
output reg [3:0] q);
always @(posedge clk or posedge reset_p)begin
if(reset_p) q = 4'b0000;
else begin
case(q)
4'b0001: q = 4'b0010;
4'b0010: q = 4'b0100;
4'b0100: q = 4'b1000;
4'b1000: q = 4'b0001;
default: q = 4'b0001;
endcase
end
end
endmodule
결과는 2진수로 1, 2, 4, 8씩 반복되는 것을 확인할 수 있다.
시프트 연산자를 사용하여 링카운터 코드를 작성하면 아래와 같다.
module ring_counter_shift(
input clk, reset_p,
output reg [3:0] q);
always @(posedge clk or posedge reset_p)begin
if(reset_p) q = 4'b0001;
else begin
if(q == 4'b1000) q = 4'b0001;
else q = q << 1;
end
end
endmodule
배선을 따로 연결하여 결합 연산자를 사용해 (시프트 연산자를 사용하지 않고) 시프트 연산을 구현하면 아래의 코드와 같다.
module ring_counter_shift(
input clk, reset_p,
output reg [3:0] q);
always @(posedge clk or posedge reset_p)begin
if(reset_p) q = 4'b0001;
else begin
if(q == 4'b1000) q = 4'b0001;
else q = {q[2:0], 1'b0};
end
end
endmodule
'Language > Verilog' 카테고리의 다른 글
Vivado : Basys3 7segment (0) | 2024.07.16 |
---|---|
Vivado : Edge Detector, Shift Register(SISO, SIPO, PISO, PIPO) (2) | 2024.07.16 |
Vivado : Decoder, Encoder (2) | 2024.06.25 |
Vivado : 4bit 가산기 (0) | 2024.06.16 |
Vivado : 전가산기(Full-adder) 구현 (0) | 2024.06.13 |