⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 altera_primitives.v

📁 CPLD/FPGA常用模块与综合系统设计实例光盘程序
💻 V
📖 第 1 页 / 共 3 页
字号:
    output q;
    wire q;
    tri1 prn, clrn;

    prim_gtff inst (q, t, clk, 1'b1, !clrn, !prn);

endmodule

`timescale 1 ps / 1 ps
module tffe (t, clk, ena, clrn, prn,q );
    input t,clk,ena,clrn,prn;
    output q;
    wire q;
    tri1 prn, clrn, ena;

    prim_gtff inst (q, t, clk, ena, !clrn, !prn);

endmodule

`timescale 1 ps / 1 ps
module prim_gjkff (q, j, k, clk, ena, clr, pre );
    input j,k,clk,ena,clr,pre;
    output q;
    reg q;
    reg clk_pre;
    initial q = 1'b0;

    always@ (clk or clr or pre)
    begin
        if (clr)
            q <= 1'b0;
        else if (pre)
            q <= 1'b1;
        else if ((clk == 1'b1) && (clk_pre == 1'b0))
        begin
            if (ena == 1'b1)
            begin
                if (j && !k)
                    q <= 1'b1;
                else if (!j && k)
                    q <= 1'b0;
                else if (k && j)
                    q <= ~q;
            end
        end
        clk_pre <= clk;
    end
endmodule

`timescale 1 ps / 1 ps
module jkff (j, k, clk, clrn, prn, q );
    input j,k,clk,clrn,prn;
    output q;
    wire q;
    tri1 prn, clrn;

    prim_gjkff inst (q, j, k, clk, 1'b1, !clrn, !prn);

endmodule

`timescale 1 ps / 1 ps
module jkffe (j, k, clk, ena, clrn, prn,q );
    input j,k,clk,ena,clrn,prn;
    output q;
    wire q;
    tri1 prn, clrn, ena;

    prim_gjkff inst (q, j, k, clk, ena, !clrn, !prn);

endmodule

`timescale 1 ps / 1 ps
module prim_gsrff (q, s, r, clk, ena, clr, pre );
    input s,r,clk,ena,clr,pre;
    output q;
    reg q;
    reg clk_pre;
    initial q = 1'b0;

    always@ (clk or clr or pre)
    begin
        if (clr)
            q <= 1'b0;
        else if (pre)
            q <= 1'b1;
        else if ((clk == 1'b1) && (clk_pre == 1'b0))
        begin
            if (ena == 1'b1)
            begin
                if (s && !r)
                    q <= 1'b1;
                else if (!s && r)
                    q <= 1'b0;
                else if (s && r)
                    q <= ~q;
            end
        end
        clk_pre <= clk;
    end
endmodule

`timescale 1 ps / 1 ps
module srff (s, r, clk, clrn, prn, q );
    input s,r,clk,clrn,prn;
    output q;
    wire q;
    tri1 prn, clrn;

    prim_gsrff inst (q, s, r, clk, 1'b1, !clrn, !prn);

endmodule

`timescale 1 ps / 1 ps
module srffe (s, r, clk, ena, clrn, prn,q );
    input s,r,clk,ena,clrn,prn;
    output q;
    wire q;
    tri1 prn, clrn, ena;

    prim_gsrff inst (q, s, r, clk, ena, !clrn, !prn);

endmodule

`timescale 1 ps / 1 ps

// MODULE DECLARATION
module clklock (
    inclk,     // input reference clock
    outclk     // output clock
);

// GLOBAL PARAMETER DECLARATION
parameter input_frequency = 10000;  // units in ps
parameter clockboost = 1;

// INTERNAL PARAMETER DECLARATION
parameter valid_lock_cycles = 1;
parameter invalid_lock_cycles = 2;

// INPUT PORT DECLARATION
input inclk;

// OUTPUT PORT DECLARATION
output outclk;

// INTERNAL VARIABLE/REGISTER DECLARATION
reg outclk;

reg start_outclk;
reg outclk_tmp;
reg pll_lock;
reg clk_last_value;
reg violation;
reg clk_check;
reg [1:0] next_clk_check;

reg init;
    
real pll_last_rising_edge;
real pll_last_falling_edge;
real actual_clk_cycle;
real expected_clk_cycle;
real pll_duty_cycle;
real inclk_period;
real expected_next_clk_edge;
integer pll_rising_edge_count;
integer stop_lock_count;
integer start_lock_count;
integer clk_per_tolerance;


// variables for clock synchronizing
time last_synchronizing_rising_edge_for_outclk;
time outclk_synchronizing_period;
integer input_cycles_per_outclk;
integer outclk_cycles_per_sync_period;
integer input_cycle_count_to_sync0;

// variables for shedule_outclk
reg schedule_outclk;
reg output_value0;
time sched_time0;
integer rem0;
integer tmp_rem0;
integer clk_cnt0;
integer cyc0;
integer inc0;
integer cycle_to_adjust0;
time tmp_per0;
time ori_per0;
time high_time0;
time low_time0;


// INITIAL BLOCK
initial
begin

    // check for invalid parameters
    if (input_frequency <= 0)
    begin
        $display("ERROR: The period of the input clock (input_frequency) must be greater than 0");
        $stop;
    end

    if ((clockboost != 1) && (clockboost != 2))
    begin
        $display("ERROR: The clock multiplication factor (clockboost) must be a value of 1 or 2.");
        $stop;
    end


    stop_lock_count = 0;
    violation = 0;

    // clock synchronizing variables
    last_synchronizing_rising_edge_for_outclk = 0;
    outclk_synchronizing_period = 0;
    input_cycles_per_outclk = 1;
    outclk_cycles_per_sync_period = clockboost;
    input_cycle_count_to_sync0 = 0;
    inc0 = 1;
    cycle_to_adjust0 = 0;

    outclk_cycles_per_sync_period = clockboost;
    input_cycles_per_outclk = 1;

    clk_per_tolerance = 0.1 * input_frequency;
end

always @(next_clk_check)
begin
    if (next_clk_check == 1)
    begin
        if ((clk_check === 1'b1) || (clk_check === 1'b0))
            #((inclk_period+clk_per_tolerance)/2) clk_check = ~clk_check;
        else
            #((inclk_period+clk_per_tolerance)/2) clk_check = 1'b1;
    end
    else if (next_clk_check == 2)
    begin
        if ((clk_check === 1'b1) || (clk_check === 1'b0))
            #(expected_next_clk_edge - $realtime) clk_check = ~clk_check;
        else
            #(expected_next_clk_edge - $realtime) clk_check = 1'b1;
    end
    next_clk_check = 0;
end

always @(inclk or clk_check)
begin

    if(init !== 1'b1)
    begin
        start_lock_count = 0;
        pll_rising_edge_count = 0;
        pll_last_rising_edge = 0;
        pll_last_falling_edge = 0;
        pll_lock = 0;
        init = 1'b1;
    end

    if ((inclk == 1'b1) && (clk_last_value !== inclk))
    begin
        if (pll_lock === 1)
            next_clk_check = 1;

        if (pll_rising_edge_count == 0)   // this is first rising edge
        begin
            inclk_period = input_frequency;
            pll_duty_cycle = inclk_period/2;
            start_outclk = 0;
        end
        else if (pll_rising_edge_count == 1) // this is second rising edge
        begin
            expected_clk_cycle = inclk_period;
            actual_clk_cycle = $realtime - pll_last_rising_edge;
            if (actual_clk_cycle < (expected_clk_cycle - clk_per_tolerance) ||
                actual_clk_cycle > (expected_clk_cycle + clk_per_tolerance))
            begin
                $display($realtime, "ps Warning: Inclock_Period Violation");
                violation = 1;
                if (pll_lock == 1'b1)
                begin
                    stop_lock_count = stop_lock_count + 1;
                    if ((pll_lock == 1'b1) && (stop_lock_count == invalid_lock_cycles))
                    begin
                        pll_lock = 0;
                        $display ($realtime, "ps Warning: altclklock out of lock.");
                        
                        start_lock_count = 1;
                        stop_lock_count = 0;
                        outclk_tmp = 1'bx;
                    end
                end
                else begin
                    start_lock_count = 1;
                end
            end
            else
            begin
                if (($realtime - pll_last_falling_edge) < (pll_duty_cycle - clk_per_tolerance/2) ||
                    ($realtime - pll_last_falling_edge) > (pll_duty_cycle + clk_per_tolerance/2))
                begin
                    $display($realtime, "ps Warning: Duty Cycle Violation");
                    violation = 1;
                end
                else
                    violation = 0;
            end
        end
        else if (($realtime - pll_last_rising_edge) < (expected_clk_cycle - clk_per_tolerance) ||
                ($realtime - pll_last_rising_edge) > (expected_clk_cycle + clk_per_tolerance))
        begin
            $display($realtime, "ps Warning: Cycle Violation");
            violation = 1;
            if (pll_lock == 1'b1)
            begin
                stop_lock_count = stop_lock_count + 1;
                if (stop_lock_count == invalid_lock_cycles)
                begin
                    pll_lock = 0;
                    $display ($realtime, "ps Warning: altclklock out of lock.");
                    
                    start_lock_count = 1;
                    stop_lock_count = 0;
                    outclk_tmp = 1'bx;
                end
            end
            else
            begin
                start_lock_count = 1;
            end
        end
        else
        begin
            violation = 0;
            actual_clk_cycle = $realtime - pll_last_rising_edge;
        end
        pll_last_rising_edge = $realtime;
        pll_rising_edge_count = pll_rising_edge_count + 1;
        if (!violation)
        begin
            if (pll_lock == 1'b1)
            begin
                input_cycle_count_to_sync0 = input_cycle_count_to_sync0 + 1;
                if (input_cycle_count_to_sync0 == input_cycles_per_outclk)
                begin
                    outclk_synchronizing_period = $realtime - last_synchronizing_rising_edge_for_outclk;
                    last_synchronizing_rising_edge_for_outclk = $realtime;
                    schedule_outclk = 1;
                    input_cycle_count_to_sync0 = 0;
                end
            end
            else
            begin
                start_lock_count = start_lock_count + 1;
                if (start_lock_count >= valid_lock_cycles)
                begin
                    pll_lock = 1;
                    input_cycle_count_to_sync0 = 0;
                    outclk_synchronizing_period = actual_clk_cycle * input_cycles_per_outclk;
                    last_synchronizing_rising_edge_for_outclk = $realtime;
                    schedule_outclk = 1;
                end
            end
        end
        else
            start_lock_count = 1;
    end
    else if ((inclk == 1'b0) && (clk_last_value !== inclk))
    begin
        if (pll_lock == 1)
        begin
            next_clk_check = 1;
            if (($realtime - pll_last_rising_edge) < (pll_duty_cycle - clk_per_tolerance/2) ||
                ($realtime - pll_last_rising_edge) > (pll_duty_cycle + clk_per_tolerance/2))
            begin
                $display($realtime, "ps Warning: Duty Cycle Violation");
                violation = 1;
                if (pll_lock == 1'b1)
                begin
                    stop_lock_count = stop_lock_count + 1;
                    if (stop_lock_count == invalid_lock_cycles)
                    begin
                        pll_lock = 0;
                        $display ($realtime, "ps Warning: clklock out of lock.");
                        
                        start_lock_count = 0;

                        stop_lock_count = 0;
                        outclk_tmp = 1'bx;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -