Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- FND
- ATMEGA128A
- stop watch
- Algorithm
- verilog
- atmega 128a
- DHT11
- Edge Detector
- Linked List
- half adder
- D Flip Flop
- Recursion
- dataflow modeling
- test bench
- BASYS3
- LED
- ring counter
- Pspice
- pwm
- uart 통신
- hc-sr04
- behavioral modeling
- soc 설계
- prescaling
- gpio
- java
- i2c 통신
- structural modeling
- vivado
- KEYPAD
Archives
- Today
- Total
거북이처럼 천천히
Verilog RTL 설계(7월 17일 - 3, Clock Mode) 본문
1. Clock Pulse를 이용하여 Clock 만들기
- basys3의 기본 클럭 펄스의 주기는 10ns이다. 이를 활용하여 시계를 만들고자 한다.
- 다음과 같이 동작한다.
- 4개의 FND를 이용하여 첫 번째, 두 번째 FND는 초 단위, 세 번째, 네 번째 FND는 분 단위를 출력한다.
- 초 단위는 0 ~ 59초 까지 Counting이 가능하며, 60초가 되면 0초로 초기화되며, 분 값이 1씩 증가한다.
- 분 단위도 0 ~ 59분 까지 Counting이 가능하며, 60분이 되면 0분으로 초기화된다.
1.1. 동시에 서로 다른 숫자들을 동시에 출력하기
- 시간을 분의 십의 자리, 분의 일의 자리, 초의 십의 자리, 초의 일의 자리로 나눈다.
- 각각의 시간의 데이터를 Ring Counter를 이용하여 com 변수 값들을 빠르게 Shifting하면서 해당 위치의 FND에 출력하면 동시에 서로 다른 숫자들을 출력할 수 있다.
- 10ms 이하의 주기를 갖고, com 변수 값들을 Shifting 한다면 사람의 눈으로는 Shifting한다는 사실을 인지할 수 없이 동시에 출력되는 것을 착각하게 만들 수 있다.
- 따라서 이번에는 1ms 주기를 갖고, com 변수 값을 Left Shifting하도록 하겠다.
- 자세한 원리 및 구현 방법은 아래 게시글을 참고 바란다.
Verilog RTL 설계(7월 17일 - 2, FND 동시 출력) (tistory.com)
1.2. 10ns 주기를 갖는 기본 클럭 펄스를 가지고, 분과 초를 얻을 수 있는가?
- 분과 초 값을 얻기 위해서 Counter를 이용할 것이다.
- 초를 기준으로 설명하자면 다음과 같이 생각할 수 있다.
- 어떤 주기가 1초인 신호가 있는데, 이 신호는 1초마다 Counter에게 "1초 지났어. 카운터 값을 1씩 증가해." 알려준다.
- Counter는 해당 신호를 받고, 현재 Counter가 현재까지 Counting한 값을 1씩 증가시킨다.
- 이 때, 필요한 신호가 "1초가 지났음을 알려주는 신호"이며, 해당 신호의 역활 수행할 수 있는 것이 "주기가 1sec인 One Cycle Pulse" 이다.
- 즉, Counter는 외부에서 발생한 One Cycle Pulse를 감지하고, 현재까지 Counting한 값을 1씩 증가하는 것이다.
- 초 값은 0 ~ 59까지만 존재하기 때문에 Counter가 60까지 카운팅하면 다시 0으로 초기화 된다. - 분 또한 초와 마찬가지로 움직인다. 다만, 분을 카운터하는 Counter 같은 경우에는 "주기가 1min인 One Cycle Pulse"를 받아야 올바른 시점에 카운터 값을 1씩 증가 시킬 수 있다.
1.3. 어떻게 1sec, 1min인 One Cycle Pulse를 만들 것인가?
- 바로 분주비를 통해 원하는 주기를 갖는 Pulse wave와 One Cycle Pulse를 생성할 수 있다.
- 분주비는 여러 개의 Pulse를 하나로 묶어 하나의 Pulse로 생각하는 방식이다.
- 따라서 분주비를 통해 10ns인 펄스파를 묶어서 원하는 주기인 1sec, 1min One Cycle Pulse와 Pulse wave를 얻을 수 있다.
- 주기가 1sec, 1min인 One Cycle Pulse를 다음과 같은 과정을 통해 얻을 것이다.
- 먼저, 10ns인 CP를 100분주를 통해 주기가 1usec인 Pulse wave를 얻을 수 있다.
- 1use인 Pulse wave를 1000분주를 통해 주기가 1msec인 Pulse wave를 얻을 수 있다.
- 1msec인 Pulse wave를 1000분주를 통해 주기가 1sec인 Pulse wave를 얻을 수 있다.
- 1sec인 Pulse wave를 60분주를 통해 주기가 1min인 Pulse wave을 얻을 수 있다.
2. 구현
- 일반적인 클럭을 구현하기 위해 다음과 같은 모듈을 만들었다.
- edge_detector_n : 임의의 펄스를 입력받아서 edge를 감지한 One Cycle Pulse를 출력으로 내보내는 모듈
- decoder_seg_7 : 16진수 데이터를 입력받아서 FND에 출력하기 위한 8bit 데이터를 출력으로 내보내는 모듈
- ring_counter_fnd : FND의 Common anode 값을 이용하여 1ms 주기로 출력으로 내보낼 FND를 Shifting하는 모듈
- fnd_cntr : FND Control 및 입력 받은 데이터를 FND로 출력으로 내보내는 모듈
- clk_div_60 : 입력 받은 펄스를 60분주시켜 새로운 펄스 파와 One Cycle Pulse를 출력으로 내보내는 모듈
- clk_div_100 : CP를 100분주시켜 새로운 펄스 파와 One Cycle Pulse를 출력으로 내보내는 모듈
- clk_div_1000 : 입력 받은 펄스를 1000분주시켜 새로운 펄스 파와 One Cycle Pulse를 출력으로 내보내는 모듈
- counter_bcd_60 : BCD Code 형태로 0 ~ 59까지 카운트할 수 있는 모듈
- Normal_Clock_0 : Root of module
2.1. Source, Edge Detector
- D Flip Flop 2개를 직렬로 이어 구현한 Negative edge Detector이다.
- edge를 감지하게 되면 감지했음을 One Cycle Pulse 출력시켜 알리게 된다.
// Edge detector
module edge_detector_n (
input clk, reset_p,
input cp,
output n_edge, p_edge );
reg flip_flop_current, flip_flop_old;
always @(posedge clk or posedge reset_p) begin
if(reset_p) begin
flip_flop_current <= 0;
flip_flop_old <= 0;
end
else begin
flip_flop_current <= cp;
flip_flop_old <= flip_flop_current;
end
end
assign p_edge = ({flip_flop_current, flip_flop_old} == 2'b10)? 1 : 0;
assign n_edge = ({flip_flop_current, flip_flop_old} == 2'b01)? 1 : 0;
endmodule
2.2. Source, decoder_seg_7
- 4bit 크기를 갖는 16진 데이터를 입력받으면 해당 데이터를 FND로 출력하기 위한 8bit 데이터로 만들어 반환한다.
- 해당 모듈은 Decoder로 구현되며, 입력 값으로 16진 데이터, 출력 값으로 FND 데이터를 갖게 된다.
// Decoder of FND
module decoder_seg_7 (
input [3:0] hex_value,
output reg [7:0] seg_7);
always @(hex_value) begin
case(hex_value)
0 : seg_7 = 8'b0000_0011; // 0
1 : seg_7 = 8'b1001_1111; // 1
2 : seg_7 = 8'b0010_0101; // 2
3 : seg_7 = 8'b0000_1101; // 3
4 : seg_7 = 8'b1001_1001; // 4
5 : seg_7 = 8'b0100_1001; // 5
6 : seg_7 = 8'b0100_0001; // 6
7 : seg_7 = 8'b0001_1111; // 7
8 : seg_7 = 8'b0000_0001; // 8
9 : seg_7 = 8'b0000_1001; // 9
10 : seg_7 = 8'b0000_0101; // A
11 : seg_7 = 8'b1100_0001; // b
12 : seg_7 = 8'b0110_0011; // C
13 : seg_7 = 8'b1000_0101; // d
14 : seg_7 = 8'b0110_0001; // E
15 : seg_7 = 8'b0111_0001; // F
endcase
end
endmodule
2.3. Source, ring_counter_fnd
- 0 ~ 99999 까지 Counting을 할 수 있어야 하기 때문에 17bit 크기를 갖는 Counter여야 한다.
- counter를 통해 주기가 0.5ms이고, Duty cycle이 50%인 Pulse wave (clk_div_100000) 생성하며,
edge detector를 통해 주기가 0.5ms인 One Cycle Pulse (clk_div_100000_nedge)를 생성한다. - clk_div_100000_nedge 가 활성화되는 순간에 com 변수 값을 Left Shifting하게 된다.
// Ring Counter
module ring_counter_fnd (
input clk, reset_p,
output reg [3:0] com);
// prescale 100000
reg[16:0] counter;
always @(posedge clk or posedge reset_p) begin
if(reset_p) counter = 0;
else begin
if(counter >= 99999) counter =0;
else counter = counter + 1;
end
end
// clk_div_100000 : 주기가 0.5ms이고, Duty cycle이 50%인 Pulse wave
// clk_div_100000_nedge : 주기가 0.5ms인 One Cycle Pulse
wire clk_div_100000, clk_div_100000_nedge;
assign clk_div_100000 = (counter < 50000)? 0 : 1;
edge_detector_n edge_detector_0 (.clk(clk), .reset_p(reset_p), .cp(clk_div_100000), .n_edge(clk_div_100000_nedge));
// clk_div_100000_nedge이 활성화되면 com 변수 값을 Left Shifting한다.
always @(posedge clk or posedge reset_p) begin
if(reset_p) com = 4'b1110;
else if(clk_div_100000_nedge) begin
if(com == 4'b0111) com = 4'b1110;
else com = {com[2:0], 1'b1};
end
end
endmodule
2.4. Source, fnd_cntr
- ring_counter_fnd 모듈을 통해 com 변수를 정한 뒤, com 변수를 통해 해당 FND에 출력되어야 하는 hex_value를 얻는다.
- 16bit 크기를 갖는 value 변수는 "분의 십의 자리, 분의 일의 자리, 초의 십의 자리, 초의 일의 자리" 로 구성된 데이터이다.
- decoder_seg_7 모듈에 hex_value를 전달해줌으로서 해당 모듈로부터 FND에 출력을 위한 데이터(seg_7)을 얻을 수 있다.
// 7-Segment Control
module fnd_cntr (
input clk, reset_p,
input [15:0] value,
output [3:0] com,
output [7:0] seg_7 );
// Get One Cycle Pulse of 1ms
ring_counter_fnd fnd (.clk(clk), .reset_p(reset_p), .com(com));
// Select the hex_value.
reg [3:0] hex_value;
always @(posedge clk) begin
case(com)
4'b1110 : hex_value = value[3:0];
4'b1101 : hex_value = value[7:4];
4'b1011 : hex_value = value[11:8];
4'b0111 : hex_value = value[15:12];
default : hex_value = hex_value;
endcase
end
decoder_seg_7 decoder (.hex_value(hex_value), .seg_7(seg_7));
endmodule
2.5. Source, clk_div_1000
- clk_div_1000 모듈은 입력 받은 클럭파를 1000분주하여 새로운 펄스파와 One Cycle Pulse를 출력으로 내보낸다.
- 입력으로 받은 clk_source 펄스파는 One Cycle Pulse가 아닌 펄스 파형이다.
- 0 ~ 999까지 Counting하기 위해서는 10bit 크기를 갖는 Counter를 가져야 한다.
- clk_source_nedge 변수는 edge detector로부터 얻은 negative edge를 알려주는 One Cycle Pulse이며, clk_source_nedge 변수가 활성화 될 때마다 카운터 값을 1씩 증가 시킨다.
- 출력으로 내보내는 clk_div_1000 펄스 파는 1000분주하여 만들어진 새로운 파형이며, Duty Cycle은 50%를 갖는다.
- clk_div_1000_nedge 변수는 clk_div_1000 펄스 파를 edge detector를 통해 얻은 One Cycle Pulse이다.
// prescaler 1000
module clk_div_1000 (
input clk, reset_p,
input clk_source,
output clk_div_1000,
output clk_div_1000_nedge );
wire clk_source_nedge;
edge_detector_n edge_detector_0 (.clk(clk), .reset_p(reset_p), .cp(clk_source), .n_edge(clk_source_nedge));
reg [9:0] counter;
always @(posedge clk or posedge reset_p) begin
if(reset_p) counter = 0;
else if(clk_source_nedge) begin
if(counter >= 999) counter = 0;
else counter = counter + 1;
end
end
assign clk_div_1000 = (counter < 500)? 0 : 1;
edge_detector_n edge_detector_1 (.clk(clk), .reset_p(reset_p), .cp(clk_div_1000), .n_edge(clk_div_1000_nedge));
endmodule
2.6. Source, clk_div_60
- clk_div_1000 모듈과 동일하게 동작한다.
- clk_div_60 모듈을 통해 1sec 주기를 갖는 펄스파를 60분주하여 1min 주기를 갖는 펄스파를 생성하게 된다.
// prescaler 60
module clk_div_60 (
input clk, reset_p,
input clk_source,
output clk_div_60,
output clk_div_60_nedge );
wire clk_source_nedge;
edge_detector_n edge_detector_0 (.clk(clk), .reset_p(reset_p), .cp(clk_source), .n_edge(clk_source_nedge));
reg[5:0] counter;
always @(posedge clk or posedge reset_p) begin
if(reset_p) counter = 0;
else if(clk_source_nedge) begin
if(counter >= 59) counter = 0;
else counter = counter + 1;
end
end
assign clk_div_60 = (counter < 30) ? 0 : 1;
edge_detector_n edge_detector_1 (.clk(clk), .reset_p(reset_p), .cp(clk_div_60), .n_edge(clk_div_60_nedge));
endmodule
2.7. Source, clk_div_100
- CP(Clock Pulse, Period = 10ns)를 100분주하여 1usec 주기를 갖는 펄스파를 생성하는 모듈
// Prescaler 100
module clk_div_100 (
input clk, reset_p,
output clk_div_100,
output clk_div_100_nedge );
reg [6:0] counter;
always @(posedge clk or posedge reset_p) begin
if(reset_p) counter = 0;
else begin
if(counter >= 99) counter = 0;
else counter = counter + 1;
end
end
assign clk_div_100 = (counter < 50)? 0 : 1;
edge_detector_n edge_detector_1 (.clk(clk), .reset_p(reset_p), .cp(clk_div_100), .n_edge(clk_div_100_nedge));
endmodule
2.8. Source, counter_bcd_60
- 입력 받은 clk_time 펄스를 Edge detector를 거쳐 clk_time의 One Cycle Pulse인 clk_time_nedge를 만든 뒤, clk_time_nedge 값이 활성화된 순간마다 카운트 값을 1씩 증가 시키는 BCD 60진 카운터이다.
- 60진 카운터이기 때문에 0 ~ 59까지만 카운트 할 수 있다.
- bcd1 : 분 / 초의 일의 자리를 값을 BCD 형태로 나타낸다.
- bcd10 : 분 / 초의 십의 자리를 값을 BCD 형태로 나타낸다.
// BCD 60 Counter
module counter_bcd_60 (
input clk, reset_p,
input clk_time,
output reg [3:0] bcd1, bcd10 );
// Get One Cycle Pulse of clk_time.
wire clk_time_nedge;
edge_detector_n edge_detector (.clk(clk), .reset_p(reset_p), .cp(clk_time), .n_edge(clk_time_nedge));
// Counting
always @(posedge clk or posedge reset_p) begin
if(reset_p) begin
bcd1 = 0;
bcd10 = 0;
end
else if(clk_time_nedge) begin
if(bcd1 >= 9 ) begin
bcd1 = 0;
if(bcd10 >= 5) bcd10 = 0;
else bcd10 = bcd10 + 1;
end
else bcd1 = bcd1 + 1;
end
end
endmodule
2.9. Source, Normal_Clock_0
- 10ns 주기를 갖는 clk를 가지고, 100분주화, 1000분주화, 60분주화를 통해 주기가 1sec, 1min인 Pulse wave를 얻는다. ( 주기가 1sec인 펄스파 : clk_sec , 주기가 1min인 펄스파 : clk_min )
- counter_bcd_60 모듈의 argument 값으로 clk_sec, clk_min을 전달함으로서 counter_bcd_60는 각각의 기준 펄스를 가지고, Countng한 뒤, FND에 표시할 분과 초 값을 십의 자리와 일의 자리로 나누어 return 한다.
- 그리고 난 뒤, 결합 연산자를 통해 분과 초를 결합하여 16bit 데이터로 만든 뒤, fnd_cntr 모듈에게 전달하여 출력하도록 한다.
module Normal_Clock_0(
input clk, reset_p,
output [3:0] com,
output [7:0] seg_7 );
// Get Pulse of second, minute
wire clk_usec, clk_msec, clk_sec, clk_min;
clk_div_100 clk_div_usec (.clk(clk), .reset_p(reset_p), .clk_div_100(clk_usec));
clk_div_1000 clk_div_msec (.clk(clk), .reset_p(reset_p), .clk_source(clk_usec), .clk_div_1000(clk_msec));
clk_div_1000 clk_div_sec (.clk(clk), .reset_p(reset_p), .clk_source(clk_msec), .clk_div_1000(clk_sec));
clk_div_60 clk_div_min (.clk(clk), .reset_p(reset_p), .clk_source(clk_sec), .clk_div_60(clk_min));
// BCD 60 Counter
wire [3:0] min10, min1, sec10, sec1;
counter_bcd_60 counter_sec (.clk(clk), .reset_p(reset_p), .clk_time(clk_sec), .bcd1(sec1), .bcd10(sec10));
counter_bcd_60 counter_min (.clk(clk), .reset_p(reset_p), .clk_time(clk_min), .bcd1(min1), .bcd10(min10));
// Combine data of second and minute.
wire [15:0] value;
assign value = {min10, min1, sec10, sec1};
// Print the FND
fnd_cntr fnd (.clk(clk), .reset_p(reset_p), .value(value), .com(com), .seg_7(seg_7));
endmodule
2.10. Total Source
module Normal_Clock_0(
input clk, reset_p,
output [3:0] com,
output [7:0] seg_7 );
// Get Pulse of second, minute
wire clk_usec, clk_msec, clk_sec, clk_min;
clk_div_100 clk_div_usec (.clk(clk), .reset_p(reset_p), .clk_div_100(clk_usec));
clk_div_1000 clk_div_msec (.clk(clk), .reset_p(reset_p), .clk_source(clk_usec), .clk_div_1000(clk_msec));
clk_div_1000 clk_div_sec (.clk(clk), .reset_p(reset_p), .clk_source(clk_msec), .clk_div_1000(clk_sec));
clk_div_60 clk_div_min (.clk(clk), .reset_p(reset_p), .clk_source(clk_sec), .clk_div_60(clk_min));
// BCD 60 Counter
wire [3:0] min10, min1, sec10, sec1;
counter_bcd_60 counter_sec (.clk(clk), .reset_p(reset_p), .clk_time(clk_sec), .bcd1(sec1), .bcd10(sec10));
counter_bcd_60 counter_min (.clk(clk), .reset_p(reset_p), .clk_time(clk_min), .bcd1(min1), .bcd10(min10));
// Combine data of second and minute.
wire [15:0] value;
assign value = {min10, min1, sec10, sec1};
// Print the FND
fnd_cntr fnd (.clk(clk), .reset_p(reset_p), .value(value), .com(com), .seg_7(seg_7));
endmodule
// BCD 60 Counter
module counter_bcd_60 (
input clk, reset_p,
input clk_time,
output reg [3:0] bcd1, bcd10 );
wire clk_time_nedge;
edge_detector_n edge_detector (.clk(clk), .reset_p(reset_p), .cp(clk_time), .n_edge(clk_time_nedge));
always @(posedge clk or posedge reset_p) begin
if(reset_p) begin
bcd1 = 0;
bcd10 = 0;
end
else if(clk_time_nedge) begin
if(bcd1 >= 9 ) begin
bcd1 = 0;
if(bcd10 >= 5) bcd10 = 0;
else bcd10 = bcd10 + 1;
end
else bcd1 = bcd1 + 1;
end
end
endmodule
// Prescaler 100
module clk_div_100 (
input clk, reset_p,
output clk_div_100,
output clk_div_100_nedge );
reg [6:0] counter;
always @(posedge clk or posedge reset_p) begin
if(reset_p) counter = 0;
else begin
if(counter >= 99) counter = 0;
else counter = counter + 1;
end
end
assign clk_div_100 = (counter < 50)? 0 : 1;
edge_detector_n edge_detector_1 (.clk(clk), .reset_p(reset_p), .cp(clk_div_100), .n_edge(clk_div_100_nedge));
endmodule
// prescaler 1000
module clk_div_1000 (
input clk, reset_p,
input clk_source,
output clk_div_1000,
output clk_div_1000_nedge );
wire clk_source_nedge;
edge_detector_n edge_detector_0 (.clk(clk), .reset_p(reset_p), .cp(clk_source), .n_edge(clk_source_nedge));
reg [9:0] counter;
always @(posedge clk or posedge reset_p) begin
if(reset_p) counter = 0;
else if(clk_source_nedge) begin
if(counter >= 999) counter = 0;
else counter = counter + 1;
end
end
assign clk_div_1000 = (counter < 500)? 0 : 1;
edge_detector_n edge_detector_1 (.clk(clk), .reset_p(reset_p), .cp(clk_div_1000), .n_edge(clk_div_1000_nedge));
endmodule
// prescaler 60
module clk_div_60 (
input clk, reset_p,
input clk_source,
output clk_div_60,
output clk_div_60_nedge );
wire clk_source_nedge;
edge_detector_n edge_detector_0 (.clk(clk), .reset_p(reset_p), .cp(clk_source), .n_edge(clk_source_nedge));
reg[5:0] counter;
always @(posedge clk or posedge reset_p) begin
if(reset_p) counter = 0;
else if(clk_source_nedge) begin
if(counter >= 59) counter = 0;
else counter = counter + 1;
end
end
assign clk_div_60 = (counter < 30) ? 0 : 1;
edge_detector_n edge_detector_1 (.clk(clk), .reset_p(reset_p), .cp(clk_div_60), .n_edge(clk_div_60_nedge));
endmodule
// 7-Segment Control
module fnd_cntr (
input clk, reset_p,
input [15:0] value,
output [3:0] com,
output [7:0] seg_7 );
// Get One Cycle Pulse of 1ms
ring_counter_fnd fnd (.clk(clk), .reset_p(reset_p), .com(com));
// Select the hex_value.
reg [3:0] hex_value;
always @(posedge clk) begin
case(com)
4'b1110 : hex_value = value[3:0];
4'b1101 : hex_value = value[7:4];
4'b1011 : hex_value = value[11:8];
4'b0111 : hex_value = value[15:12];
default : hex_value = hex_value;
endcase
end
decoder_seg_7 decoder (.hex_value(hex_value), .seg_7(seg_7));
endmodule
// Ring Counter
module ring_counter_fnd (
input clk, reset_p,
output reg [3:0] com);
// prescale 100000
reg[16:0] counter;
always @(posedge clk or posedge reset_p) begin
if(reset_p) counter = 0;
else begin
if(counter >= 99999) counter =0;
else counter = counter + 1;
end
end
wire clk_div_100000, clk_div_100000_nedge;
assign clk_div_100000 = (counter < 50000)? 0 : 1;
edge_detector_n edge_detector_0 (.clk(clk), .reset_p(reset_p), .cp(clk_div_100000), .n_edge(clk_div_100000_nedge));
always @(posedge clk or posedge reset_p) begin
if(reset_p) com = 4'b1110;
else if(clk_div_100000_nedge) begin
if(com == 4'b0111) com = 4'b1110;
else com = {com[2:0], 1'b1};
end
end
endmodule
// Decoder of FND
module decoder_seg_7 (
input [3:0] hex_value,
output reg [7:0] seg_7);
always @(hex_value) begin
case(hex_value)
0 : seg_7 = 8'b0000_0011; // 0
1 : seg_7 = 8'b1001_1111; // 1
2 : seg_7 = 8'b0010_0101; // 2
3 : seg_7 = 8'b0000_1101; // 3
4 : seg_7 = 8'b1001_1001; // 4
5 : seg_7 = 8'b0100_1001; // 5
6 : seg_7 = 8'b0100_0001; // 6
7 : seg_7 = 8'b0001_1111; // 7
8 : seg_7 = 8'b0000_0001; // 8
9 : seg_7 = 8'b0000_1001; // 9
10 : seg_7 = 8'b0000_0101; // A
11 : seg_7 = 8'b1100_0001; // b
12 : seg_7 = 8'b0110_0011; // C
13 : seg_7 = 8'b1000_0101; // d
14 : seg_7 = 8'b0110_0001; // E
15 : seg_7 = 8'b0111_0001; // F
endcase
end
endmodule
// Edge detector
module edge_detector_n (
input clk, reset_p,
input cp,
output n_edge, p_edge );
reg flip_flop_current, flip_flop_old;
always @(posedge clk or posedge reset_p) begin
if(reset_p) begin
flip_flop_current <= 0;
flip_flop_old <= 0;
end
else begin
flip_flop_current <= cp;
flip_flop_old <= flip_flop_current;
end
end
assign p_edge = ({flip_flop_current, flip_flop_old} == 2'b10)? 1 : 0;
assign n_edge = ({flip_flop_current, flip_flop_old} == 2'b01)? 1 : 0;
endmodule
3. 구현 영상
'RTL Design > Verilog RTL 설계' 카테고리의 다른 글
Verilog RTL 설계(7월 17일 - 6, Advanced Clock Mode - 3) (0) | 2024.07.21 |
---|---|
Verilog RTL 설계(7월 17일 - 5, Advanced Clock Mode - 2) (1) | 2024.07.20 |
Verilog RTL 설계(7월 17일 - 2, FND 동시 출력) (0) | 2024.07.19 |
Verilog RTL 설계(7월 17일 - 1, FND Shifting) (0) | 2024.07.18 |
Verilog RTL 설계(7월 16일 - 5, 16진수 값을 FND로 출력) (0) | 2024.07.18 |