산업 제조
산업용 사물 인터넷 | 산업자재 | 장비 유지 보수 및 수리 | 산업 프로그래밍 |
home  MfgRobots >> 산업 제조 >  >> Industrial programming >> verilog

Verilog 클록 생성기

클록은 서로 다른 블록이 서로 동기화될 수 있도록 하므로 디지털 회로를 구축하는 데 기본입니다.

시계의 속성

디지털 시계의 주요 속성은 주파수입니다. 시계 주기를 결정합니다. , 듀티 사이클시계 단계 다른 시계와 관련하여.

시계 기간

빈도는 특정 기간에 몇 개의 사이클을 찾을 수 있는지 나타냅니다. 따라서 시계 주기는 1주기를 완료하는 데 걸리는 시간입니다.

<노스크립트>

클록 듀티 사이클

클록이 해당 기간에 비해 높은 시간이 듀티 사이클을 정의합니다.

<노스크립트>

시계 단계

시계의 한 주기를 360도의 완전한 원으로 볼 수 있다면 다른 시계는 다른 위상을 차지하는 원의 다른 위치에 상대적으로 배치할 수 있습니다. 예를 들어, 같은 주기의 다른 클록이 그 주기의 1/4만큼 오른쪽으로 이동하면 위상차가 90도라고 할 수 있습니다.

<노스크립트>

Verilog 클록 생성기

timescale 지시문에 지정된 대로 제한된 정밀도를 갖는 주어진 시간 척도에서 작동하려면 시뮬레이션이 필요합니다. 따라서 시간 척도의 정밀도가 클록 주기를 나타낼 만큼 충분히 좋은 것이 중요합니다. 예를 들어, 클록의 주파수가 640000kHz로 설정되면 클록 주기는 1.5625ns가 되며, 표시할 추가 포인트가 있기 때문에 1ps의 시간 척도 정밀도로는 충분하지 않습니다. 따라서 시뮬레이션은 마지막 숫자를 반올림하여 3포인트 시간 척도 정밀도에 맞춥니다. 이것은 실제로 639795kHz를 나타내는 1.563으로 클록 주기를 증가시킬 것입니다!

다음 Verilog 클록 생성기 모듈에는 위에서 설명한 세 가지 다른 속성을 조정하는 세 가지 매개변수가 있습니다. 모듈에는 필요에 따라 클록을 비활성화 및 활성화할 수 있는 입력 활성화가 있습니다. 여러 클록이 공통 인에이블 신호로 제어되는 경우 상대적으로 쉽게 위상을 조정할 수 있습니다.

  
  
`timescale 1ns/1ps

module clock_gen (	input      enable,
  					output reg clk);
  
  parameter FREQ = 100000;  // in kHZ
  parameter PHASE = 0; 		// in degrees
  parameter DUTY = 50;  	// in percentage 
  
  real clk_pd  		= 1.0/(FREQ * 1e3) * 1e9; 	// convert to ns
  real clk_on  		= DUTY/100.0 * clk_pd;
  real clk_off 		= (100.0 - DUTY)/100.0 * clk_pd;
  real quarter 		= clk_pd/4;
  real start_dly     = quarter * PHASE/90;
  
  reg start_clk;
  
  initial begin    
    $display("FREQ      = %0d kHz", FREQ);
    $display("PHASE     = %0d deg", PHASE);
    $display("DUTY      = %0d %%",  DUTY);
    
    $display("PERIOD    = %0.3f ns", clk_pd);    
    $display("CLK_ON    = %0.3f ns", clk_on);
    $display("CLK_OFF   = %0.3f ns", clk_off);
    $display("QUARTER   = %0.3f ns", quarter);
    $display("START_DLY = %0.3f ns", start_dly);
  end
  
  // Initialize variables to zero
  initial begin
    clk <= 0;
    start_clk <= 0;
  end
  
  // When clock is enabled, delay driving the clock to one in order
  // to achieve the phase effect. start_dly is configured to the 
  // correct delay for the configured phase. When enable is 0,
  // allow enough time to complete the current clock period
  always @ (posedge enable or negedge enable) begin
    if (enable) begin
      #(start_dly) start_clk = 1;
    end else begin
      #(start_dly) start_clk = 0;
    end      
  end
  
  // Achieve duty cycle by a skewed clock on/off time and let this
  // run as long as the clocks are turned on.
  always @(posedge start_clk) begin
    if (start_clk) begin
      	clk = 1;
      
      	while (start_clk) begin
      		#(clk_on)  clk = 0;
    		#(clk_off) clk = 1;
        end
      
      	clk = 0;
    end
  end 
endmodule

  

클럭 주파수가 다른 테스트벤치

  
  
module tb;
  wire clk1;
  wire clk2;
  wire clk3;
  wire clk4;
  reg  enable;
  reg [7:0] dly;
  
  clock_gen u0(enable, clk1);
  clock_gen #(.FREQ(200000)) u1(enable, clk2);
  clock_gen #(.FREQ(400000)) u2(enable, clk3);
  clock_gen #(.FREQ(800000)) u3(enable, clk4);
  
  initial begin
    enable <= 0;
    
    for (int i = 0; i < 10; i= i+1) begin
      dly = $random;
      #(dly) enable <= ~enable;      
      $display("i=%0d dly=%0d", i, dly);
      #50;
    end
    
    #50 $finish;
  end
endmodule

  
<노스크립트> 시뮬레이션 로그
xcelium> run
FREQ      = 100000 kHz
PHASE     = 0 deg
DUTY      = 50 %
PERIOD    = 10.000 ns
CLK_ON    = 5.000 ns
CLK_OFF   = 5.000 ns
QUARTER   = 2.500 ns
START_DLY = 0.000 ns
FREQ      = 200000 kHz
PHASE     = 0 deg
DUTY      = 50 %
PERIOD    = 5.000 ns
CLK_ON    = 2.500 ns
CLK_OFF   = 2.500 ns
QUARTER   = 1.250 ns
START_DLY = 0.000 ns
FREQ      = 400000 kHz
PHASE     = 0 deg
DUTY      = 50 %
PERIOD    = 2.500 ns
CLK_ON    = 1.250 ns
CLK_OFF   = 1.250 ns
QUARTER   = 0.625 ns
START_DLY = 0.000 ns
FREQ      = 800000 kHz
PHASE     = 0 deg
DUTY      = 50 %
PERIOD    = 1.250 ns
CLK_ON    = 0.625 ns
CLK_OFF   = 0.625 ns
QUARTER   = 0.312 ns
START_DLY = 0.000 ns
i=0 dly=36
i=1 dly=129
i=2 dly=9
i=3 dly=99
i=4 dly=13
i=5 dly=141
i=6 dly=101
i=7 dly=18
i=8 dly=1
i=9 dly=13
Simulation complete via $finish(1) at time 1110 NS + 0

클록 단계가 다른 테스트벤치

  
  
module tb;
  wire clk1;
  wire clk2;
  reg  enable;
  reg [7:0] dly;
  
  clock_gen u0(enable, clk1);
  clock_gen #(.FREQ(50000), .PHASE(90)) u1(enable, clk2);
  
  initial begin
    enable <= 0;
    
    for (int i = 0; i < 10; i=i+1) begin
      dly = $random;
      #(dly) enable <= ~enable;      
      $display("i=%0d dly=%0d", i, dly);
    end
    
    #50 $finish;
  end

endmodule

  
<노스크립트> 시뮬레이션 로그
xcelium> run
FREQ      = 100000 kHz
PHASE     = 0 deg
DUTY      = 50 %
PERIOD    = 10.000 ns
CLK_ON    = 5.000 ns
CLK_OFF   = 5.000 ns
QUARTER   = 2.500 ns
START_DLY = 0.000 ns
FREQ      = 100000 kHz
PHASE     = 90 deg
DUTY      = 50 %
PERIOD    = 10.000 ns
CLK_ON    = 5.000 ns
CLK_OFF   = 5.000 ns
QUARTER   = 2.500 ns
START_DLY = 2.500 ns
FREQ      = 100000 kHz
PHASE     = 180 deg
DUTY      = 50 %
PERIOD    = 10.000 ns
CLK_ON    = 5.000 ns
CLK_OFF   = 5.000 ns
QUARTER   = 2.500 ns
START_DLY = 5.000 ns
FREQ      = 100000 kHz
PHASE     = 270 deg
DUTY      = 50 %
PERIOD    = 10.000 ns
CLK_ON    = 5.000 ns
CLK_OFF   = 5.000 ns
QUARTER   = 2.500 ns
START_DLY = 7.500 ns
i=0 dly=36
i=1 dly=129
i=2 dly=9
i=3 dly=99
i=4 dly=13
i=5 dly=141
i=6 dly=101
i=7 dly=18
i=8 dly=1
i=9 dly=13
Simulation complete via $finish(1) at time 1110 NS + 0

듀티 사이클이 다른 테스트벤치

  
  
module tb;
  wire clk1;
  wire clk2;
  wire clk3;
  wire clk4;
  reg  enable;
  reg [7:0] dly;
  
  clock_gen u0(enable, clk1);
  clock_gen #(.DUTY(25)) u1(enable, clk2);
  clock_gen #(.DUTY(75)) u2(enable, clk3);
  clock_gen #(.DUTY(90)) u3(enable, clk4);
  
  initial begin
    enable <= 0;
    
    for (int i = 0; i < 10; i= i+1) begin
      dly = $random;
      #(dly) enable <= ~enable;      
      $display("i=%0d dly=%0d", i, dly);
      #50;
    end
    
    #50 $finish;
  end
endmodule

  
<노스크립트> 시뮬레이션 로그
xcelium> run
FREQ      = 100000 kHz
PHASE     = 0 deg
DUTY      = 50 %
PERIOD    = 10.000 ns
CLK_ON    = 5.000 ns
CLK_OFF   = 5.000 ns
QUARTER   = 2.500 ns
START_DLY = 0.000 ns
FREQ      = 100000 kHz
PHASE     = 0 deg
DUTY      = 25 %
PERIOD    = 10.000 ns
CLK_ON    = 2.500 ns
CLK_OFF   = 7.500 ns
QUARTER   = 2.500 ns
START_DLY = 0.000 ns
FREQ      = 100000 kHz
PHASE     = 0 deg
DUTY      = 75 %
PERIOD    = 10.000 ns
CLK_ON    = 7.500 ns
CLK_OFF   = 2.500 ns
QUARTER   = 2.500 ns
START_DLY = 0.000 ns
FREQ      = 100000 kHz
PHASE     = 0 deg
DUTY      = 90 %
PERIOD    = 10.000 ns
CLK_ON    = 9.000 ns
CLK_OFF   = 1.000 ns
QUARTER   = 2.500 ns
START_DLY = 0.000 ns
i=0 dly=36
i=1 dly=129
i=2 dly=9
i=3 dly=99
i=4 dly=13
i=5 dly=141
i=6 dly=101
i=7 dly=18
i=8 dly=1
i=9 dly=13
Simulation complete via $finish(1) at time 1110 NS + 0

시계 시작/중지 활성화

아래 파형은 Enable이 Low일 때 클럭이 멈추고 Enable이 High일 때 클럭이 시작되는 것을 보여줍니다.

<노스크립트>

verilog

  1. Verilog 튜토리얼
  2. Verilog 연결
  3. Verilog 할당
  4. Verilog 차단 및 비 차단
  5. Verilog 기능
  6. Verilog 작업
  7. Verilog 수학 함수
  8. Verilog 시간 형식
  9. Verilog 타임스케일 범위
  10. Verilog 파일 IO 작업