Notice
Recent Posts
Recent Comments
Link
관리 메뉴

거북이처럼 천천히

Normal Clock 본문

RTL Design/Verilog 연습

Normal Clock

유로 청년 2024. 8. 4. 13:35

1. Normal Clock

 

Verilog RTL 설계(7월 17일 - 3, Clock Mode)

1. Clock Pulse를 이용하여 Clock 만들기basys3의 기본 클럭 펄스의 주기는 10ns이다. 이를 활용하여 시계를 만들고자 한다.다음과 같이 동작한다.- 4개의 FND를 이용하여 첫 번째, 두 번째 FND는 초 단위,

jbhdeve.tistory.com

 

 



< Source , Edge detector of Positive edge clk >

// Edge detector.
module edge_detector (
    input clk, reset_p,
    input cp,
    output p_edge, n_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

 

 

< Source, Decoder of 7-segment >

// Decoder of 7-Segment.
module decoder_seg7 (
    input [3:0] hex_value,
    output reg [7:0] seg_7);
    
    always @(hex_value) begin
        case(hex_value)
            0  : seg_7 = 8'b0000_0011; //common anode, 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'b0001_0001;  // 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

 

 

< Source, Ring counter of com of 7-segment >

// Ring Counter of com.
module ring_counter (
    input clk, reset_p,
    output reg [3:0] com );
    
    // Making 1ms One cycle pulse.
    wire clk_1usec, clk_1msec;
    clk_div_100 clk_div_100_0(.clk(clk), .reset_p(reset_p), .clk_div_100(clk_1usec));
    clk_div_1000 clk_div_1000_0(.clk(clk), .reset_p(reset_p), .clk_source(clk_1usec), .clk_div_1000_nedge(clk_1msec));
    
    // Shifting com value.
    always @(posedge clk or posedge reset_p) begin
        if(reset_p) com = 4'b1110;
        else if(clk_1msec) com = {com[0], com[3:1]};
    end
endmodule

 

 

 

< Source, Control FND Module > 

// Control FND
module fnd_cntr (
    input clk, reset_p,
    input [15:0] hex_value,
    output [3:0] com,
    output [7:0] seg_7 );
    
    // Shifting com value.
    ring_counter ring_counter_0 (.clk(clk), .reset_p(reset_p), .com(com));
    
    // Select hex value
    reg [3:0] value;
    
    always @(posedge clk or posedge reset_p) begin
        if(reset_p) value = 4'b0000;
        else begin
            case(com)
                4'b1110 : value = hex_value[3:0];
                4'b1101 : value = hex_value[7:4];
                4'b1011 : value = hex_value[11:8];
                4'b0111 : value = hex_value[15:12];
                default : value = value;
            endcase
        end
    end
    
    // Get fnd data.
    decoder_seg7 decoder_seg7_0 (.hex_value(value), .seg_7(seg_7));    
endmodule

 

 

< Source, Clock divider 60 >

// Prescaling 60
module clk_div_60 (
    input clk, reset_p,
    input clk_source,
    output clk_div_60,
    output clk_div_60_nedge, clk_div_60_pedge );
    
    wire clk_source_nedge;
    edge_detector edge_detector_0(.clk(clk), .reset_p(reset_p), .cp(clk_source), .n_edge(clk_source_nedge));   
    
    reg [6:0] clk_div_60_counter;
    always @(posedge clk or posedge reset_p) begin
        if(reset_p) clk_div_60_counter = 0;
        else if(clk_source_nedge) begin
            if(clk_div_60_counter >= 59) clk_div_60_counter = 0;
            else clk_div_60_counter = clk_div_60_counter + 1;
        end
    end
    
    assign clk_div_60 = (clk_div_60_counter < 30)? 0 : 1;
    
    edge_detector edge_detector_1(.clk(clk), .reset_p(reset_p), .cp(clk_div_60), .p_edge(clk_div_60_pedge), .n_edge(clk_div_60_nedge));   
endmodule

 

 

< Source, Clock divider 100 >

// Prescaling 100
module clk_div_100 (
    input clk, reset_p,
    output clk_div_100,
    output clk_div_100_nedge, clk_div_100_pedge );
    
    reg [6:0] clk_div_100_counter;
    always @(posedge clk or posedge reset_p) begin
        if(reset_p) clk_div_100_counter = 0;
        else begin
            if(clk_div_100_counter >= 99) clk_div_100_counter = 0;
            else clk_div_100_counter = clk_div_100_counter + 1;
        end
    end
    
    assign clk_div_100 = (clk_div_100_counter < 50)? 0 : 1;
    
    edge_detector edge_detector_0(.clk(clk), .reset_p(reset_p), .cp(clk_div_100), .p_edge(clk_div_100_pedge), .n_edge(clk_div_100_nedge));   
endmodule

 

 

< Source, Clock divider 1000 >

// Prescaling 1000
module clk_div_1000 (
    input clk, reset_p,
    input clk_source,
    output clk_div_1000,
    output clk_div_1000_nedge, clk_div_1000_pedge );
    
    wire clk_source_nedge;
    edge_detector edge_detector_0(.clk(clk), .reset_p(reset_p), .cp(clk_source), .n_edge(clk_source_nedge));   
    
    reg[9:0] clk_div_1000_count;
    always @(posedge clk or posedge reset_p) begin
        if(reset_p) clk_div_1000_count = 0;
        else begin if(clk_source_nedge)
            if(clk_div_1000_count >= 999) clk_div_1000_count = 0;
            else clk_div_1000_count = clk_div_1000_count + 1;
        end
    end
    
    assign clk_div_1000 = (clk_div_1000_count < 500)? 0 : 1;
    
    edge_detector edge_detector_1(.clk(clk), .reset_p(reset_p), .cp(clk_div_1000), .p_edge(clk_div_1000_pedge), .n_edge(clk_div_1000_nedge));   
endmodule

 

 

< Source, 60진 BCD Counter >

// BCD 60진 Counter.
module bcd_counter_60 (
    input clk, reset_p,
    input clk_source,
    output reg [4:0] bcd_10, bcd_1 );
    
    wire clk_source_nedge;
    edge_detector edge_detector_0(.clk(clk), .reset_p(reset_p), .cp(clk_source), .n_edge(clk_source_nedge));   
    
    always @(posedge clk or posedge reset_p) begin
        if(reset_p) begin
            bcd_10 = 0; bcd_1 = 0;
        end else if(clk_source_nedge) begin
            if(bcd_1 >= 9) begin
                bcd_1 = 0;    
                if(bcd_10 >= 5) bcd_10 = 0;
                else bcd_10 = bcd_10 + 1;
            end
            else bcd_1 = bcd_1 + 1;
        end
    end
endmodule

 

 

< Source, Top module of Normal clock >

// Top Module
module Normal_Clock(
    input clk, reset_p,
    output [3:0] com,
    output [7:0] seg_7 );
    
    // Get 1sec, 1min one cycle pulse.
    wire clk_1usec, clk_1msec, clk_1sec, clk_1min;
    clk_div_100 usec_clk (.clk(clk), .reset_p(reset_p), .clk_div_100(clk_1usec));
    clk_div_1000 msec_clk (.clk(clk), .reset_p(reset_p), .clk_source(clk_1usec), .clk_div_1000(clk_1msec));
    clk_div_1000 sec_clk (.clk(clk), .reset_p(reset_p), .clk_source(clk_1msec), .clk_div_1000(clk_1sec));
    clk_div_60 min_clk (.clk(clk), .reset_p(reset_p), .clk_source(clk_1sec), .clk_div_60(clk_1min));
    
    // BCD Counter
    wire [3:0] bcd_10_sec, bcd_1_sec, bcd_10_min, bcd_1_min;
    bcd_counter_60 bcd_60_second (.clk(clk), .reset_p(reset_p), .clk_source(clk_1sec), .bcd_10(bcd_10_sec), .bcd_1(bcd_1_sec) );
    bcd_counter_60 bcd_60_minute (.clk(clk), .reset_p(reset_p), .clk_source(clk_1min), .bcd_10(bcd_10_min), .bcd_1(bcd_1_min) );
    
    // Combine data.
    wire [15:0] hex_value;
    assign hex_value = {bcd_10_min, bcd_1_min, bcd_10_sec, bcd_1_sec};
    
    // Show clock to FND
    fnd_cntr control_fnd (.clk(clk), .reset_p(reset_p), .hex_value(hex_value), .com(com), .seg_7(seg_7));
endmodule

 

 

 

 

 

 

2. 구동 영상

 

 

 

 

 

3. 전체 소스 코드

// Top Module
module Normal_Clock(
    input clk, reset_p,
    output [3:0] com,
    output [7:0] seg_7 );
    
    // Get 1sec, 1min one cycle pulse.
    wire clk_1usec, clk_1msec, clk_1sec, clk_1min;
    clk_div_100 usec_clk (.clk(clk), .reset_p(reset_p), .clk_div_100(clk_1usec));
    clk_div_1000 msec_clk (.clk(clk), .reset_p(reset_p), .clk_source(clk_1usec), .clk_div_1000(clk_1msec));
    clk_div_1000 sec_clk (.clk(clk), .reset_p(reset_p), .clk_source(clk_1msec), .clk_div_1000(clk_1sec));
    clk_div_60 min_clk (.clk(clk), .reset_p(reset_p), .clk_source(clk_1sec), .clk_div_60(clk_1min));
    
    // BCD Counter
    wire [3:0] bcd_10_sec, bcd_1_sec, bcd_10_min, bcd_1_min;
    bcd_counter_60 bcd_60_second (.clk(clk), .reset_p(reset_p), .clk_source(clk_1sec), .bcd_10(bcd_10_sec), .bcd_1(bcd_1_sec) );
    bcd_counter_60 bcd_60_minute (.clk(clk), .reset_p(reset_p), .clk_source(clk_1min), .bcd_10(bcd_10_min), .bcd_1(bcd_1_min) );
    
    // Combine data.
    wire [15:0] hex_value;
    assign hex_value = {bcd_10_min, bcd_1_min, bcd_10_sec, bcd_1_sec};
    
    // Show clock to FND
    fnd_cntr control_fnd (.clk(clk), .reset_p(reset_p), .hex_value(hex_value), .com(com), .seg_7(seg_7));
endmodule

// BCD 60진 Counter.
module bcd_counter_60 (
    input clk, reset_p,
    input clk_source,
    output reg [4:0] bcd_10, bcd_1 );
    
    wire clk_source_nedge;
    edge_detector edge_detector_0(.clk(clk), .reset_p(reset_p), .cp(clk_source), .n_edge(clk_source_nedge));   
    
    always @(posedge clk or posedge reset_p) begin
        if(reset_p) begin
            bcd_10 = 0; bcd_1 = 0;
        end else if(clk_source_nedge) begin
            if(bcd_1 >= 9) begin
                bcd_1 = 0;    
                if(bcd_10 >= 5) bcd_10 = 0;
                else bcd_10 = bcd_10 + 1;
            end
            else bcd_1 = bcd_1 + 1;
        end
    end
endmodule


// Control FND
module fnd_cntr (
    input clk, reset_p,
    input [15:0] hex_value,
    output [3:0] com,
    output [7:0] seg_7 );
    
    // Shifting com value.
    ring_counter ring_counter_0 (.clk(clk), .reset_p(reset_p), .com(com));
    
    // Select hex value
    reg [3:0] value;
    
    always @(posedge clk or posedge reset_p) begin
        if(reset_p) value = 4'b0000;
        else begin
            case(com)
                4'b1110 : value = hex_value[3:0];
                4'b1101 : value = hex_value[7:4];
                4'b1011 : value = hex_value[11:8];
                4'b0111 : value = hex_value[15:12];
                default : value = value;
            endcase
        end
    end
    
    // Get fnd data.
    decoder_seg7 decoder_seg7_0 (.hex_value(value), .seg_7(seg_7));    
endmodule

// Ring Counter of com.
module ring_counter (
    input clk, reset_p,
    output reg [3:0] com );
    
    // Making 1ms One cycle pulse.
    wire clk_1usec, clk_1msec;
    clk_div_100 clk_div_100_0(.clk(clk), .reset_p(reset_p), .clk_div_100(clk_1usec));
    clk_div_1000 clk_div_1000_0(.clk(clk), .reset_p(reset_p), .clk_source(clk_1usec), .clk_div_1000_nedge(clk_1msec));
    
    // Shifting com value.
    always @(posedge clk or posedge reset_p) begin
        if(reset_p) com = 4'b1110;
        else if(clk_1msec) com = {com[0], com[3:1]};
    end
endmodule

// Prescaling 60
module clk_div_60 (
    input clk, reset_p,
    input clk_source,
    output clk_div_60,
    output clk_div_60_nedge, clk_div_60_pedge );
    
    wire clk_source_nedge;
    edge_detector edge_detector_0(.clk(clk), .reset_p(reset_p), .cp(clk_source), .n_edge(clk_source_nedge));   
    
    reg [6:0] clk_div_60_counter;
    always @(posedge clk or posedge reset_p) begin
        if(reset_p) clk_div_60_counter = 0;
        else if(clk_source_nedge) begin
            if(clk_div_60_counter >= 59) clk_div_60_counter = 0;
            else clk_div_60_counter = clk_div_60_counter + 1;
        end
    end
    
    assign clk_div_60 = (clk_div_60_counter < 30)? 0 : 1;
    
    edge_detector edge_detector_1(.clk(clk), .reset_p(reset_p), .cp(clk_div_60), .p_edge(clk_div_60_pedge), .n_edge(clk_div_60_nedge));   
endmodule

// Prescaling 100
module clk_div_100 (
    input clk, reset_p,
    output clk_div_100,
    output clk_div_100_nedge, clk_div_100_pedge );
    
    reg [6:0] clk_div_100_counter;
    always @(posedge clk or posedge reset_p) begin
        if(reset_p) clk_div_100_counter = 0;
        else begin
            if(clk_div_100_counter >= 99) clk_div_100_counter = 0;
            else clk_div_100_counter = clk_div_100_counter + 1;
        end
    end
    
    assign clk_div_100 = (clk_div_100_counter < 50)? 0 : 1;
    
    edge_detector edge_detector_0(.clk(clk), .reset_p(reset_p), .cp(clk_div_100), .p_edge(clk_div_100_pedge), .n_edge(clk_div_100_nedge));   
endmodule

// Prescaling 1000
module clk_div_1000 (
    input clk, reset_p,
    input clk_source,
    output clk_div_1000,
    output clk_div_1000_nedge, clk_div_1000_pedge );
    
    wire clk_source_nedge;
    edge_detector edge_detector_0(.clk(clk), .reset_p(reset_p), .cp(clk_source), .n_edge(clk_source_nedge));   
    
    reg[9:0] clk_div_1000_count;
    always @(posedge clk or posedge reset_p) begin
        if(reset_p) clk_div_1000_count = 0;
        else begin if(clk_source_nedge)
            if(clk_div_1000_count >= 999) clk_div_1000_count = 0;
            else clk_div_1000_count = clk_div_1000_count + 1;
        end
    end
    
    assign clk_div_1000 = (clk_div_1000_count < 500)? 0 : 1;
    
    edge_detector edge_detector_1(.clk(clk), .reset_p(reset_p), .cp(clk_div_1000), .p_edge(clk_div_1000_pedge), .n_edge(clk_div_1000_nedge));   
endmodule

// Decoder of 7-Segment.
module decoder_seg7 (
    input [3:0] hex_value,
    output reg [7:0] seg_7);
    
    always @(hex_value) begin
        case(hex_value)
            0  : seg_7 = 8'b0000_0011; //common anode, 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'b0001_0001;  // 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 (
    input clk, reset_p,
    input cp,
    output p_edge, n_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

 

 

 

'RTL Design > Verilog 연습' 카테고리의 다른 글

Stop Watch - 1  (0) 2024.08.07
Advanced Clock  (0) 2024.08.06
비동기식 카운터 (Asynchronous counter)  (0) 2024.07.11
T Flip Flop  (0) 2024.07.11
JK Flip Flop  (0) 2024.07.11