Notice
Recent Posts
Recent Comments
Link
관리 메뉴

거북이처럼 천천히

Verilog RTL 설계(7월 17일 - 2, FND 동시 출력) 본문

RTL Design/Verilog RTL 설계

Verilog RTL 설계(7월 17일 - 2, FND 동시 출력)

유로 청년 2024. 7. 19. 13:58

1. 서로 다른 숫자들을 FND을 통해 동시 출력하기

  • 이번에는 4자리 16진수 데이터를 FND을 통해 한 번에 동시 출력 되도록 설계해보도록 하겠다.
  • 이번 구현 동작은 다음과 같이 동작한다.
    - 16개의 Switch를 활성화시켜 0 ~ 3번째 Switch는 첫 번째 FND, 4 ~ 7번째 Switch는 두 번째 FND, 8 ~ 11번째 Switch는 세 번째 FND, 12 ~ 15번째 Switch는 네 번째 FND를 컨트롤 한다.
    - 해당 FND의 스위치로 16진수 값을 표현하면 해당 16진수 값이 해당 FND에 출력된다

 

 

1.1. 한 번에 동시 출력하도록 만들기 위해서는 몇 초를 주기로 Shifting 시켜야 하는가?

  • 사람 눈을 속이기 위해서는 최대 10ms 정도 FND Shifting해야 사람의 눈으로 보았을 때, 4개의 FND에서 서로 다른 숫자들이 동시 출력되는 것 처럼 보이게 설계할 수 있다,
  • 따라서 1ms 주기로 FND Shifing되도록 설계하겠다.

 

1.2. 16개의 Switch를 4개의 구간으로 나누어 각 구간 마다 해당 FND에 16진수 값이 출력되도록 설계하겠다.

  •  0 ~ 3번째 Switch :  첫 번째 FND를 컨트롤한다.
  • 4 ~ 7번째 Switch :  두 번째 FND를 컨트롤한다.
  • 8 ~ 11번째 Switch :  세 번째 FND를 컨트롤한다.
  • 12 ~ 15번째 Switch :  네 번째 FND를 컨트롤한다.

 

 

 

 

2.  구현 

2.1. Edge detector

// 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 @(negedge 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 n_edge = ({flip_flop_current, flip_flop_old} == 2'b10)? 1 : 0;
    assign p_edge = ({flip_flop_current, flip_flop_old} == 2'b01)? 1 : 0;
    
endmodule

 

 

 

2.2. 100000 분주

// Prescaler 100 * 1000 = 100000
module clk_div_100000 (
    input clk, reset_p,
    input clk_source,
    output clk_div_100000,
    output clk_div_100000_nedge );
    
    reg [17:0] count;
    
    always @(posedge clk or posedge reset_p) begin
           if(reset_p) count = 0;
           else begin
                if(count >= 99999) count = 0;
                else count = count +1;
           end
    end
    
    assign clk_div_100000 = (count < 50000)? 0 : 1;
    
    edge_detector_n edge_detector (.clk(clk), .reset_p(reset_p), .cp(clk_div_100000), .n_edge(clk_div_100000_nedge));
    
endmodule
  • clk_div_100000 : 1ms 주기를 갖고, duty cycle이 50%인 펄스파
  • clk_div_100000_nedge : 1ms 주기를 갖는 One Cycle Pulse

 

 

2.3. Decoder of 7-Segment

// Decoder 7 - Segment.
module decoder_7_seg (
    input [3:0] hex_value,
    output reg [7:0] seg_7  );
    
    always @(hex_value) begin
        case(hex_value)
             // 0 ~ F 까지 Segment  출력 
            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
  • 4bit 크기를 갖는 데이터인 hex_value를 입력 받는다. hex_value는 16진 데이터를 갖는다.

 

 

2.4. Main code

module Output_Number_at_the_number(
    input clk, reset_p,
    input [15:0] sw,
    output reg [3:0] com,
    output [7:0] seg_7 );
    
    // Get 10ms One Cycle Pulse
    wire clk_1ms;
    clk_div_100000(.clk(clk), .clk_source(clk), .reset_p(reset_p), .clk_div_100000_nedge(clk_ms));
    
    // Shifting com 
    always @(posedge clk or posedge reset_p) begin
           if(reset_p) com = 4'b1110;
           else if(clk_ms) begin
                  if(com == 4'b0111) com = 4'b1110;
                  else com = {com[2:0], 1'b1};
           end
    end
    
    // Get hex_value
    reg [3:0] hex_value;   
    
    always @(*) begin
        case(com)
            4'b1110 : hex_value = sw[3:0];
            4'b1101 : hex_value = sw[7:4];
            4'b1011 : hex_value = sw[11:8];
            4'b0111 : hex_value = sw[15:12];
            default : hex_value = hex_value;
        endcase
    end
    
    // Get Info of FND,
    decoder_7_seg(.hex_value(hex_value), .seg_7(seg_7));
    
endmodule
  • 1ms 주기를 갖는 One Cycle Pulse (clk_1ms)가 활성화 될 때마다 FND가 Left Shifting한다.
  • hex_value는 현재 켜져 있는 FND을 컨트롤하는 switch로 부터 데이터를 입력받아 저장하는 변수이다.

 

 

 

 

 

3. 구현 사진