Tạo Đồng hồ 100 Hz từ Đồng hồ 50 MHz trong Verilog


7

Tôi có một bảng DE0 với đồng hồ 50 Mhz mà tôi đang cố gắng giảm xuống 100 Hz trong Verilog. Bất cứ ai có thể giúp tôi với mã để làm điều này?


Bạn có thể sử dụng một pll (ví dụ trong Qsys) để tạo đồng hồ mà bạn cần.
Qiu

Câu trả lời:


15

Xây dựng bộ đếm 18 bit. Mỗi khi nó đạt 250.000, hãy lật một cái lật. 50 MHz / 250.000 = 200 Hz. Việc bấm một pin ở 200 Hz mang lại cho bạn 100 Hz với chu kỳ nhiệm vụ 50 phần trăm. Nếu bạn chỉ cần một xung có tần số lặp lại 100 Hz, thì hãy xây dựng bộ đếm 19 bit và tạo xung khi nó đạt 500.000.

May mắn thay, 250.000 và 500.000 đều là số nguyên. Tạo ra một chu kỳ nhiệm vụ 50 phần trăm hoàn hảo với một ước số lẻ có nghĩa là bạn cần phải lật đầu ra trên một cạnh tăng và tắt trên một cạnh giảm. Trên một Xilinx FPGA, điều này có thể được thực hiện với ODDR / ODDR2 và bộ đếm có một chút gãi đầu để có được các đầu vào D0 / D1 được đặt chính xác. Tuy nhiên, điều này chỉ hoạt động để gửi tín hiệu ra khỏi chip thông qua chân I / O, vì đầu ra của ODDR / ODDR2 không thể được sử dụng trong một thiết kế. Một xung thực sự là tất cả những gì bạn cần trong một thiết kế, mặc dù.

Tạo bất cứ thứ gì có tỷ lệ không nguyên sẽ phức tạp hơn. Nếu đó là một phần hợp lý, bạn có thể sử dụng PLL hoặc DDS để trợ giúp, một mình hoặc kết hợp với bộ đếm. Nếu nó không phải là một phần hợp lý, thì bạn ít nhiều gặp may mắn trừ khi bạn có thể ước chừng nó với một phần hợp lý. Nếu PLL không khả dụng, sẽ không đủ thấp hoặc bạn không thể có tỷ lệ đúng từ kết hợp PLL và bộ đếm, thì bạn có thể sử dụng DDS phân đoạn. Ý tưởng với DDS phân đoạn là bạn thêm hằng số vào bộ tích lũy trên mỗi chu kỳ đồng hồ và chuyển đổi đầu ra khi bộ tích lũy cuộn qua. Điều này sẽ tạo ra một đầu ra với một chút jitter, nhưng nó có thể tạo ra một tần số trung bình chính xác. Để tạo ra sóng vuông 100 Hz 50 phần trăm với bộ tích lũy 32 bit, tất cả những gì bạn cần làm là thêm 100 * 2 ^ 32 / 50e6 = 8589. 93459 ~ = 8590 mỗi chu kỳ đồng hồ. MSB của bộ tích lũy sẽ chuyển đổi ở mức 50e6 / (2 ^ 32 * 8590) = 100.00076145 Hz. Tích lũy càng lớn, điều này sẽ càng chính xác. Độ phân giải tần số của bộ tích lũy 32 bit khá tốt - nếu bạn tăng hoặc giảm 1 LSB, bạn sẽ nhận được 98.989119 hoặc 100.012403 Hz. Tuy nhiên, bạn sẽ nhận được khoảng thời gian +/- 1 của cái được gọi là jitter xác định. Nói cách khác, các cạnh được lượng tử hóa theo thời gian đồng hồ và do đó có thể lên đến 1/2 thời gian đồng hồ sớm hoặc muộn. Không giống như jitter thông thường, nếu bạn xem jitter xác định trên máy hiện sóng, bạn sẽ thấy phân phối rất đơn giản của thời gian chu kỳ với hai hoặc nhiều trung bình riêng biệt, trái ngược với một phân phối trơn tru. Ngoài ra, vì .00076145 là phần bù và không phải là mức trung bình, nên pha sẽ dần thay đổi theo đồng hồ hệ thống.

Ví dụ Verilog để tạo 100 Hz từ 50 MHz với chu kỳ nhiệm vụ 50%:

// generate 100 Hz from 50 MHz
reg [17:0] count_reg = 0;
reg out_100hz = 0;

always @(posedge clk_50mhz or posedge rst_50mhz) begin
    if (rst_50mhz) begin
        count_reg <= 0;
        out_100hz <= 0;
    end else begin
        if (count_reg < 249999) begin
            count_reg <= count_reg + 1;
        end else begin
            count_reg <= 0;
            out_100hz <= ~out_100hz;
        end
    end
end

Ví dụ Verilog để tạo ra xung 10 Hz lặp lại 100 Hz từ xung nhịp 50 MHz:

// generate 100 Hz pulse chain from 50 MHz
reg [18:0] count_reg = 0;
reg out_100hz = 0;

always @(posedge clk_50mhz or posedge rst_50mhz) begin
    if (rst_50mhz) begin
        count_reg <= 0;
        out_100hz <= 0;
    end else begin
        out_100hz <= 0;
        if (count_reg < 499999) begin
            count_reg <= count_reg + 1;
        end else begin
            count_reg <= 0;
            out_100hz = 1;
        end
    end
end

Ví dụ Verilog để tạo đầu ra 10 MHz với chu kỳ nhiệm vụ 50% từ đồng hồ 250 MHz với ODDR2 trên Spartan 6:

// generate 10 MHz from 250 MHz
// 25 cycle counter, falling edge interpolated
reg [4:0] count_reg = 0;
reg q0 = 0;
reg q1 = 0;

always @(posedge clk_250mhz or posedge rst_250mhz) begin
    if (rst_250mhz) begin
        count_reg <= 0;
        q0 <= 0;
        q1 <= 0;
    end else begin
        if (count_reg < 24) begin
            count_reg <= count_reg + 1;
        end else begin
            count_reg <= 0;
        end
        q0 <= count_reg < 12;
        q1 <= count_reg < 13;
    end
end

ODDR2
clk_10mhz_out_oddr2_inst
(
    .Q(clk_10mhz_out),
    .C0(clk_250mhz),
    .C1(~clk_250mhz),
    .CE(1),
    .D0(q0),
    .D1(q1),
    .R(0),
    .S(0)
);

Ví dụ mã Verilog để tạo 100 Hz từ 50 MHz với chu kỳ nhiệm vụ 50% bằng cách sử dụng bộ tích lũy:

// generate 100 Hz from 50 MHz
reg [31:0] count_reg = 0;
wire out_100hz = count_reg[31];

always @(posedge clk_50mhz or posedge rst_50mhz) begin
    if (rst_50mhz) begin
        count_reg <= 0;
    end else begin
        count_reg <= count_reg + 8590; //(((100 * 1 << 32) + 50000000/2) / 50000000)
    end
end

Tôi khá chắc chắn rằng một DDS được giới hạn ở bội số hợp lý của các tham chiếu giống như PLL. Nếu chỉ vì các thanh ghi được sử dụng để lập trình thì nó không có cách nào để biểu thị các số vô tỷ. Độ chính xác khả dụng có thể lớn hơn trên DDS, nhưng ngay cả PLL N phân số với mẫu số 16 bit cho độ chính xác cao hơn 20 ppm, tốt hơn độ chính xác tham chiếu sẽ có trong nhiều thiết kế.
Photon

Bạn có thể làm bất cứ điều gì bạn muốn với DDS nếu không cần chính xác. Một DDS 32 bit tạo ra 100 Hz từ 50 MHz sẽ cung cấp cho bạn 100.00076145 Hz. Đó là 7.6 ppm. Bây giờ, đây là một giá trị bù và không phải là trung bình, do đó có thể có hoặc không có vấn đề tùy thuộc vào ứng dụng - giai đoạn sẽ rất chậm trôi. bộ dao động tham chiếu.
alex.forencich

Vâng, nhưng nó vẫn là một bội số hợp lý của tài liệu tham khảo, phải không? Câu trả lời của bạn ngụ ý rằng DDS không giới hạn ở bội số hợp lý. Nếu có cách lập trình DDS để cófref/2 hoặc là fref/πtần số đầu ra, tôi rất muốn nghe nó.
Photon

À vâng, bây giờ tôi thấy những gì bạn đang nhận được. Một DDS vẫn là một phân số hợp lý, nhưng thông thường bạn có thể nhận được nhiều bit phân đoạn hơn với một DDS so với PLL phân đoạn dựa trên nền tảng đồ họa.
alex.forencich
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.