Notice
Recent Posts
Recent Comments
Link
관리 메뉴

거북이처럼 천천히

Verilog RTL 설계(7월 16일 - 3, Basys3 입문) 본문

RTL Design/Verilog RTL 설계

Verilog RTL 설계(7월 16일 - 3, Basys3 입문)

유로 청년 2024. 7. 18. 08:42

1. Counter의 비트 수 (크기)와 분주비의 상관 관계

  • Counter의 크기는 N bit 를 갖는다면 Counter는 0 ~ 2^N-1 까지 Counting이 가능하다.
  • ex) Counter가 21bit 크기를 갖는다면 0 ~ 2^21 -1까지 Counting이 가능하다.
  • 따라서 Basys3의 기본 클럭 펄스의 주기는 10ns를 갖기 때문에 10bit Counter으로 분주화하게 되면 10ns * 1024 = 10240ns = 10us 을 주기를 갖는 새로운 펄스파를 생성시킬 수 있다.

    => Basys3의 기본 Clock Pulse의 주기는 10ns를 갖는다.
    => 10bit Counter로 1024분주하면 10us 주기를 갖는 펄스파형을 생성시킬 수 있다,
    => 21bit Counter로 2^21분주하면 10ns * 2,097,152 = 20.97152ms 주기를 갖는 펄스파형을 생성시킬 수 있다.


  • 여기에 Edge Detector를 설치하게 되면 일정한 주기를 갖는 One Cycle Pulse 를 얻을 수 있다.

 

 

 

 

2. 스위치 상단에 있는 LED를 일정한 주기를 갖고 Shift 시키기.

  • 하나씩 하나씩 처음부터 설계해보자.
  • 다음 질문에 대해서 하나씩 생각해보자.
    Q) 몇 초 마다 Shift 할 것이며, 10ns 보다 긴 주기로 Shift한다면 어떻게 할 것인가?
    Q) LED Shift를 반복적으로 어떻게 할 것인가?

 

 

 

 

2.1. 몇 초 마다 Shift  할 것인가?

  • Shift 주기가 짧을 경우, Shift가 너무 빨라 LED의 변화를 눈으로 확인할 수 없다.
  • 따라서 LED Shift를 감지하기 위해 넉넉하게 10ms마다 Shift하게끔 할 것이다.

 

2.2. 기본 클럭 주파수는 10ns인데, 어떻게 주기가 10ms인 펄스파를 만들어 줄 것인가?

  • Counter와 Negative edge detector를 사용하여 Prescaler 방식을 이용하는 것이다.
  • 10ms / 10ns = 1,000,000이기 때문에 Counter는 최소 1,000,000이상을 Counting 할 수 있어야 한다.
    따라서 Counter의 크기는 최소 1,000,000이상 카운트 할 수 있는 20bit를 가져야 한다.
  • 10ms를 주기로 Shift하기 위해서는 펄스파형이 아닌 10ms를 주기로 10ns 동안 활성화 되는 One cycle pulse가 필요하다.

 

2.3. LED Shift를 반복적으로 어떻게 할 것인가?

  • LED Shift는 Shift 연산을 통해 수행이 가능하지만, 무한 반복을 수행해야 하기 때문에 (무한 반복 + Shift 연산)을 수행할 수 있는 Ring Counter를 사용하는 것이 효율적일 것이다.
  • 10ms를 주기로 Shifting 해야 하기 때문에 Ring Counter에 20bit Counter를 추가하여 counter[19] 비트 값이 0 → 1로 변화하는 순간을 Edge detector로 감지하도록 한다.
  • counter[19] 비트 값이 0 → 1로 변화하는 순간을 Edge detector는 One Cycle Pulse를 발생시킨다.
  • 이때, 발생시키는 One Cycle Pulse는 10ms 주기를 갖는다.

 

 

 

 

 

2.4. 10ns 주기를 갖는 Clock Pulse를 5,000,000 분주시켜 50ms 주기를 갖는 Pulse 를 생성

 

< Source , Edge Detector >

module edge_detector_n (
    input clk, reset_p,
    input cp,
    output n_dege, 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 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, Ring Counter of Shifting LED >

//  Ring Counter 
module ring_counter_LED (
    input clk, reset_p,
    output reg [15:0] led);
    
    reg [19:0] counter;
            
     always @(posedge clk or posedge reset_p)
              if (reset_p) counter <= 0;
              else counter <= counter + 1;
    
    // Detect negative edge of counter
    wire counter_nedge;
    edge_detector_n detector_nedge(.clk(clk), .reset_p(reset_p), .cp(counter[19]), .p_edge(counter_nedge));
    
    // Shifting
    always @(posedge clk or posedge reset_p) begin
        if(reset_p) led = 16'b0000_0000_0000_0001;
        else if(counter_nedge) begin
            if(led == 16'b1000_0000_0000_0000) led = 16'b0000_0000_0000_0001;
            else led = {led[14:0], 1'b0};
        end
    end
    
endmodule

 

 

 

< Basys3 >

  • Basys3의 LED는 10ms 주기로 Left Shifting 하게 된다.