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

📄 220model.v

📁 FIFO(先进先出队列)通常用于数据的缓存和用于容纳异步信号的频率或相位的差异。本FIFO的实现是利用 双口RAM 和读写地址产生模块来实现的.FIFO的接口信号包括异步的写时钟(wr_clk)和读
💻 V
📖 第 1 页 / 共 5 页
字号:
            for (i = 0; i <= lpm_pipeline; i = i + 1)
            begin
                tmp_aeb2[i] = 'b0;
                tmp_agb2[i] = 'b0;
                tmp_alb2[i] = 'b0;
                tmp_aleb2[i] = 'b0;
                tmp_aneb2[i] = 'b0;
                tmp_ageb2[i] = 'b0;
            end
        else
        begin
            tmp_aeb2[lpm_pipeline] = (dataa == datab);
            tmp_aneb2[lpm_pipeline] = (dataa != datab);

            if ((lpm_representation == "SIGNED") &&
                (dataa[lpm_width-1] ^ datab[lpm_width-1]) == 1)
            begin
                // create latency
                tmp_alb2[lpm_pipeline] = (dataa > datab);
                tmp_agb2[lpm_pipeline] = (dataa < datab);
                tmp_aleb2[lpm_pipeline] = (dataa >= datab);
                tmp_ageb2[lpm_pipeline] = (dataa <= datab);
            end
            else
            begin
                // create latency
                tmp_alb2[lpm_pipeline] = (dataa < datab);
                tmp_agb2[lpm_pipeline] = (dataa > datab);
                tmp_aleb2[lpm_pipeline] = (dataa <= datab);
                tmp_ageb2[lpm_pipeline] = (dataa >= datab);
            end
        end
    end

    // pipelining process
    always @(posedge i_clock)
    begin
        if ((!i_aclr) && (i_clken == 1))
            for (i = 0; i < lpm_pipeline; i = i + 1)
            begin
                tmp_alb2[i] <= tmp_alb2[i+1];
                tmp_aeb2[i] <= tmp_aeb2[i+1];
                tmp_agb2[i] <= tmp_agb2[i+1];
                tmp_aleb2[i] <= tmp_aleb2[i+1];
                tmp_aneb2[i] <= tmp_aneb2[i+1];
                tmp_ageb2[i] <= tmp_ageb2[i+1];
            end
    end

// CONTINOUS ASSIGNMENT
    assign alb = tmp_alb2[0];
    assign aeb = tmp_aeb2[0];
    assign agb = tmp_agb2[0];
    assign aleb = tmp_aleb2[0];
    assign aneb = tmp_aneb2[0];
    assign ageb = tmp_ageb2[0];

endmodule // lpm_compare

//START_MODULE_NAME------------------------------------------------------------
//
// Module Name     :  lpm_mult
//
// Description     :  Parameterized multiplier megafunction.
//
// Limitation      :  n/a
//
// Results expected:  dataa[] * datab[] + sum[].
//
//END_MODULE_NAME--------------------------------------------------------------

// BEGINNING OF MODULE
`timescale 1 ps / 1 ps

// MODULE DECLARATION
module lpm_mult ( 
    dataa,  // Multiplicand. (Required)
    datab,  // Multiplier. (Required)
    sum,    // Partial sum.
    aclr,   // Asynchronous clear for pipelined usage.
    clock,  // Clock for pipelined usage.
    clken,  // Clock enable for pipelined usage.
    result  // result = dataa[] * datab[] + sum. The product LSB is aligned with the sum LSB.
);

// GLOBAL PARAMETER DECLARATION
    parameter lpm_widtha = 1; // Width of the dataa[] port. (Required)
    parameter lpm_widthb = 1; // Width of the datab[] port. (Required)
    parameter lpm_widthp = 1; // Width of the result[] port. (Required)
    parameter lpm_widths = 1; // Width of the sum[] port. (Required)
    parameter lpm_representation  = "UNSIGNED"; // Type of multiplication performed
    parameter lpm_pipeline  = 0; // Number of clock cycles of latency 
    parameter lpm_type = "lpm_mult";
    parameter lpm_hint = "UNUSED";

// INPUT PORT DECLARATION    
    input  [lpm_widtha-1:0] dataa;
    input  [lpm_widthb-1:0] datab;
    input  [lpm_widths-1:0] sum;
    input  aclr;
    input  clock;
    input  clken;
    
// OUTPUT PORT DECLARATION    
    output [lpm_widthp-1:0] result;

// INTERNAL REGISTER/SIGNAL DECLARATION
    reg [lpm_widthp-1:0] resulttmp [lpm_pipeline:0];
    reg [lpm_widthp-1:0] i_prod;
    reg [lpm_widthp-1:0] t_p;
    reg [lpm_widths-1:0] i_prod_s;
    reg [lpm_widths-1:0] t_s;
    reg [lpm_widtha+lpm_widthb-1:0] i_prod_ab;
    reg [lpm_widtha-1:0] t_a;
    reg [lpm_widthb-1:0] t_b;
    reg sign_ab;
    reg sign_s;

// LOCAL INTEGER DECLARATION
    integer i;

// INTERNAL TRI DECLARATION
    tri0 aclr;
    tri0 clock;
    tri1 clken;

    buf (i_aclr, aclr);
    buf (i_clock, clock);
    buf (i_clken, clken);

// INITIAL CONSTRUCT BLOCK
    initial
    begin
        // check if lpm_widtha > 0
        if (lpm_widtha <= 0)
        begin
            $display("Error!  lpm_widtha must be greater than 0.\n");
            $finish;
        end    
        // check if lpm_widthb > 0
        if (lpm_widthb <= 0)
        begin
            $display("Error!  lpm_widthb must be greater than 0.\n");
            $finish;
        end
        // check if lpm_widthp > 0
        if (lpm_widthp <= 0)
        begin
            $display("Error!  lpm_widthp must be greater than 0.\n");
            $finish;
        end
        // check if lpm_widthp > 0
        if (lpm_widths <= 0)
        begin
            $display("Error!  lpm_widths must be greater than 0.\n");
            $finish;
        end
        // check for valid lpm_rep value
        if ((lpm_representation != "SIGNED") && (lpm_representation != "UNSIGNED"))
        begin
            $display("Error!  lpm_representation value must be \"SIGNED\" or \"UNSIGNED\".", $time);
            $finish;
        end
    end

// ALWAYS CONSTRUCT BLOCK
    always @(dataa or datab or sum or i_aclr)
    begin
        if (i_aclr) // clear the pipeline for result to 0
            for (i = 0; i <= lpm_pipeline; i = i + 1)
                resulttmp[i] = 'b0;
        else
        begin
            t_a = dataa;
            t_b = datab;
            t_s = sum;
            sign_ab = 0;
            sign_s = 0;

            // if inputs are sign number    
            if (lpm_representation == "SIGNED")
            begin
                sign_ab = dataa[lpm_widtha-1] ^ datab[lpm_widthb-1];
                sign_s = sum[lpm_widths-1];

                // if negative number, represent them as 2 compliment number.
                if (dataa[lpm_widtha-1] == 1)
                    t_a = (~dataa) + 1;
                if (datab[lpm_widthb-1] == 1)
                    t_b = (~datab) + 1;
                if (sum[lpm_widths-1] == 1)
                    t_s = (~sum) + 1;
            end
    
            // if sum port is not used
            if (sum === {lpm_widths{1'bz}})
            begin
                t_s = 0;
                sign_s = 0;
            end

            if (sign_ab == sign_s)
            begin
                i_prod = (t_a * t_b) + t_s;
                i_prod_s = (t_a * t_b) + t_s;
                i_prod_ab = (t_a * t_b) + t_s;
            end
            else
            begin
                i_prod = (t_a * t_b) - t_s;
                i_prod_s = (t_a * t_b) - t_s;
                i_prod_ab = (t_a * t_b) - t_s;
            end

            // if dataa[] * datab[] produces negative number, compliment the result
            if (sign_ab)
            begin
                i_prod = (~i_prod) + 1;
                i_prod_s = (~i_prod_s) + 1;
                i_prod_ab = (~i_prod_ab) + 1;
            end

            if ((lpm_widthp < lpm_widths) || (lpm_widthp < lpm_widtha+lpm_widthb))
                for (i = 0; i < lpm_widthp; i = i + 1)
                    i_prod[lpm_widthp-1-i] = (lpm_widths > lpm_widtha+lpm_widthb)
                                             ? i_prod_s[lpm_widths-1-i]
                                             : i_prod_ab[lpm_widtha+lpm_widthb-1-i];
                                             
            // pipelining the result
            resulttmp[lpm_pipeline] = i_prod;
        end
    end

    always @(posedge i_clock)
    begin
        if (!i_aclr && i_clken == 1)
            for (i = 0; i < lpm_pipeline; i = i + 1)
                resulttmp[i] <= resulttmp[i+1];
    end

// CONTINOUS ASSIGNMENT
    assign result = resulttmp[0];

endmodule // lpm_mult
// END OF MODULE

//START_MODULE_NAME------------------------------------------------------------
//
// Module Name     :  lpm_divide
//
// Description     :  Parameterized divider megafunction. This function performs a
//                    divide operation such that denom * quotient + remain = numer
//                    The function allows for all combinations of signed(two's 
//                    complement) and unsigned inputs. If any of the inputs is 
//                    signed, the output is signed. Otherwise the output is unsigned.
//                    The function also allows the remainder to be specified as
//                    always positive (in which case remain >= 0); otherwise remain
//                    is zero or the same sign as the numerator
//                    (this parameter is ignored in the case of purely unsigned
//                    division). Finally the function is also pipelinable.
//
// Limitation      :  n/a
//
// Results expected:  Return quotient and remainder. 
//
//END_MODULE_NAME--------------------------------------------------------------

// BEGINNING OF MODULE
`timescale 1 ps / 1 ps

// MODULE DECLARATION
module lpm_divide ( 
    numer,  // The numerator (Required)
    denom,  // The denominator (Required)
    clock,  // Clock input for pipelined usage
    aclr,   // Asynchronous clear signal
    clken,  // Clock enable for pipelined usage.
    quotient, // Quotient (Required)
    remain    // Remainder (Required)
);

// GLOBAL PARAMETER DECLARATION
    parameter lpm_widthn = 1;  // Width of the numer[] and quotient[] port. (Required)
    parameter lpm_widthd = 1;  // Width of the denom[] and remain[] port. (Required)
    parameter lpm_nrepresentation = "UNSIGNED";  // The representation of numer
    parameter lpm_drepresentation = "UNSIGNED";  // The representation of denom
    parameter lpm_pipeline = 0; // Number of Clock cycles of latency
    parameter lpm_type = "lpm_divide";
    parameter lpm_hint = "LPM_REMAINDERPOSITIVE=TRUE";

// INPUT PORT DECLARATION
    input  [lpm_widthn-1:0] numer;
    input  [lpm_widthd-1:0] denom;
    input  clock;
    input  aclr;
    input  clken;

// OUTPUT PORT DECLARATION
    output [lpm_widthn-1:0] quotient;
    output [lpm_widthd-1:0] remain;

// INTERNAL REGISTER/SIGNAL DECLARATION
    reg [lpm_widthn-1:0] tmp_quotient [lpm_pipeline:0];
    reg [lpm_widthd-1:0] tmp_remain [lpm_pipeline:0];
    reg [lpm_widthn-1:0] ONES, ZEROS, UNKNOWN, HiZ;
    reg [lpm_widthd-1:0] DZEROS, DUNKNOWN;
    reg [lpm_widthn-1:0] NUNKNOWN;
    reg [lpm_widthd-1:0] RZEROS;
    reg [lpm_widthn-1:0] not_numer, int_numer;
    reg [lpm_widthd-1:0] not_denom, int_denom;
    reg [lpm_widthn-1:0] t_numer, t_q;
    reg [lpm_widthd-1:0] t_denom, t_r;
    reg sign_q, sign_r, sign_n, sign_d;
    reg [2:0] tsig;
    reg [8*5:1] lpm_remainderpositive;


// LOCAL INTEGER DECLARATION
    integer i;
    integer rsig;

// INTERNAL TRI DECLARATION
    tri0 aclr;
    tri0 clock;
    tri1 clken;

    buf (i_aclr, aclr);
    buf (i_clock, clock);
    buf (i_clken, clken);

// COMPONENT INSTANTIATIONS
    LPM_HINT_EVALUATION eva();


// INITIAL CONSTRUCT BLOCK
    initial
    begin
        // check if lpm_widthn > 0
        if (lpm_widthn <= 0)
        begin
            $display("Error!  LPM_WIDTHN must be greater than 0.\n");
            $finish;
        end
        // check if lpm_widthd > 0
        if (lpm_widthd <= 0)
        begin
            $display("Error!  LPM_WIDTHD must be greater than 0.\n");
            $finish;
        end
        // check for valid lpm_nrepresentation value
        if ((lpm_nrepresentation != "SIGNED") && (lpm_nrepresentation != "UNSIGNED"))
        begin
            $display("Error!  LPM_NREPRESENTATION value must be \"SIGNED\" or \"UNSIGNED\".");
            $finish;
        end
        // check for valid lpm_drepresentation value
        if ((lpm_drepresentation != "SIGNED") && (lpm_drepresentation != "UNSIGNED"))
        begin
            $display("Error!  LPM_DREPRESENTATION value must be \"SIGNED\" or \"UNSIGNED\".");
            $finish;
        end
        // check for valid lpm_remainderpositive value
        lpm_remainderpositive = eva.GET_PARAMETER_VALUE(lpm_hint, "LPM_REMAINDERPOSITIVE");
        if ((lpm_remainderpositive == "TRUE") && 
            (lpm_remainderpositive == "FALSE"))
        begin
            $display("Error!  LPM_REMAINDERPOSITIVE value must be \"TRUE\" or \"FALSE\".");
            $finish;
        end
     
        for (i=0; i < lpm_widthn; i=i+1)
        begin
            ONES[i] = 1'b1;
            ZEROS[i] = 1'b0;
            UNKNOWN[i] = 1'bx;
            HiZ[i] = 1'bz;
        end
    
        for (i=0; i < lpm_widthd; i=i+1)
            DUNKNOWN[i] = 1'bx;
        for (i=0; i < lpm_widthn; i=i+1)
            NUNKNOWN[i] = 1'bx;
        for (i=0; i < lpm_widthd; i=i+1)
            RZEROS[i] = 1'b0;
    end

// ALWAYS CONSTRUCT BLOCK
    always @(numer or denom or i_aclr)
    begin
        if (i_aclr)
        begin
            for (i = 0; i <= lpm_pipeline; i = i + 1)
                tmp_quotient[i] = ZEROS;
            tmp_remain[i] = RZEROS;
        end
        else
        begin
            sign_q = 0;
            sign_r = 0;
            sign_n = 0;
            sign_d = 0;
            t_numer = numer; 
            t_denom = denom;

⌨️ 快捷键说明

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