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

📄 maxii_atoms.v

📁 BJ-EPM240V2实验例程以及说明文档实验之BJ-EPM整板测试用代码
💻 V
📖 第 1 页 / 共 4 页
字号:
        begin
            $display("Error! widthdata parameter must be equal to 16.");
        end

        addr_reg <= 0;

        for (n=0; n < widthdata; n=n+1)
            data_reg[n] <= 1'bx;

        program_pulse <= 0;
        erase_pulse <= 0;
        storage_output <= 0;

        // Initialize UFM
        numwords = 1 << address_width;
        if (init_file == "none")
            for (i=0; i<numwords; i=i+1)
                ufm_storage[i] = 16'hFFFF;   // UFM content is initially all 1's
        else
        begin
            // initialize UFM from memory initialization file (*.mif or *.hex)
            // the contents of the memory initialization file are passed in via the
            // mem* parameters
            ufm_initf_sec1 = {mem16, mem15, mem14, mem13, mem12, mem11, mem10, mem9};
            ufm_initf_sec0 = {mem8, mem7, mem6, mem5, mem4, mem3, mem2, mem1};

            for (mem_cnt = 1; mem_cnt <= sector0_range; mem_cnt = mem_cnt + 1)
            begin
                for (bit_cnt = 0; bit_cnt < widthdata; bit_cnt = bit_cnt + 1)
                begin
                    init_word0[bit_cnt] = ufm_initf_sec0[((mem_cnt-1)*widthdata) + bit_cnt];
                    init_word1[bit_cnt] = ufm_initf_sec1[((mem_cnt-1)*widthdata) + bit_cnt];
                end
                //sector 0
                ufm_storage[mem_cnt-1] = init_word0;
                //sector 1
                ufm_storage[(mem_cnt-1)+sector0_range] = init_word1;
            end
        end
    end

// ALWAYS CONSTRUCT BLOCKS

    // Produce oscillation clock to UFM
    always @(int_osc or i_oscena)
    begin
        if (i_oscena === 'b1)
        begin
            if (first_warning == 1)
            begin
                $display("Info : UFM oscillator can operate at any frequency between 3.33MHz to 5.56Mhz.");
                first_warning = 0;
            end

            if (int_osc === 'b0 || int_osc === 'b1)
                osc_str <= #TOSCMN_PW ~int_osc;
            else
                osc_str <= #TOSCMN_PW 0;
        end
        else
        begin
            osc_str <= #TOSCMN_PW 1;
        end
    end

    // Shift address from LSB to MSB when arshft is '1'; else increment address.
    // (Using block statement to avoid race condition warning; therefore, the
    // order of assignments must be taken care to ensure correct behaviour)
    always @(posedge gated_arclk or negedge devclrn or negedge devpor)
    begin
        if (devpor == 'b0)
            addr_reg = 0;
        else if (devclrn == 'b0)
            addr_reg = 0;
        else if (i_arshft == 'b1)
        begin
            for (i=address_width-1; i >= 1; i=i-1)
            begin
                addr_reg[i] = addr_reg[i-1];
            end
            addr_reg[0] = i_ardin;
        end
        else
            addr_reg = addr_reg + 1;
    end

    // Latest address
    always @(address_tmp)
    begin
        address_now <= address_tmp;
    end

    // Shift data from LSB to MSB when drshft is '1'; else load new data.
    // (Using block statement to avoid race condition warning; therefore, the
    // order of assignments must be taken care to ensure correct behaviour)
    always @(posedge gated_drclk or negedge devclrn or negedge devpor)
    begin
        if (devpor == 'b0)
            data_reg = 0;
        else if (devclrn == 'b0)
            data_reg = 0;
        else if (i_drshft == 'b1)
        begin
            for (j=widthdata-1; j >= 1; j=j-1)
            begin
                data_reg[j] = data_reg[j-1];
            end
            data_reg[0] = i_drdin;
        end
        else
            data_reg = storage_output;
    end

    // Latest data loaded from ufm
    always @(new_read_data)
    begin
        storage_output <= new_read_data;
    end

    // Latest data content in data register
    always @(data_tmp)
    begin
        data_now <= data_tmp;
    end

    always @(posedge int_osc)
    begin
        program_reg <= i_program;
       // PROGRAM has higher precedence than ERASE
        if(i_program !== 'b1)
            erase_reg <= i_erase;
    end

    // Pulse to indicate programing UFM for min of 20ms and max of 40ms
    // (must use blocking statement)
    always @(posedge program_reg)
    begin
        if (program_pulse !== 'b1)
        begin
            program_pulse = 1;
            program_pulse = #(TPPMX) 0;
        end
    end

    // Pulse to indicate erasing UFM for min of 20ms and max of 120ms
    // (must use blocking statement)
    always @(posedge erase_reg)
    begin
        if (erase_pulse !== 'b1)
        begin
            erase_pulse = 1;
            // Create a pulse of TEPMX * 1000 ps
            for (l=1; l < 1000; l=l+1)
            begin
                erase_pulse = #(TEPMX) 1;
            end
            erase_pulse = #(TEPMX) 0;
        end
    end

    // Start updating UFM
    always @(posedge program_pulse)
    begin
        // The write operation is the logical "AND" in UFM
        ufm_storage[address_now] <= data_now & ufm_storage[address_now];
    end


    // Start erasing UFM
    always @(posedge erase_pulse)
    begin
        if (address_now[address_width-1] == 'b0)
        begin
            for (k=0; k<sector0_range; k=k+1)
            begin
                ufm_storage[k] <= 16'hFFFF;  // Data in UFM is erased to all 1's
            end
        end
        else
        begin
            for (k=sector0_range; k<sector0_range*2; k=k+1)
            begin
                ufm_storage[k] <= 16'hFFFF;  // Data in UFM is erased to all 1's
            end
        end
    end

// CONTINUOUS ASSIGNMENT
    and(busy, sys_busy, 'b1);
    and(osc, int_osc, 'b1);
    and(sbdout, i_sbdin, 'b1);
    and(bgpbusy, ctrl_bgpbusy, 'b1);
    and(drdout, data_reg_msb, 'b1);

    assign data_reg_msb = data_tmp[(widthdata-1)];

    assign address_tmp = addr_reg;

    assign data_tmp = data_reg;

    assign new_read_data = ufm_storage[address_tmp];

    assign sys_busy = program_pulse | erase_pulse;

    assign int_osc = osc_str;

    assign gated_arclk = i_arclk & !sys_busy;
    assign gated_drclk = i_drclk & !sys_busy;

endmodule // maxii_ufm
///////////////////////////////////////////////////////////////////////////////
//
// MAXII IO Atom
//
///////////////////////////////////////////////////////////////////////////////
`timescale 1 ps/1 ps

module maxii_io (
                   datain, 
                   oe, 
                   padio, 
                   combout
                  );
   
    input datain;
    input oe;
    output combout;
    inout  padio;
   
    parameter operation_mode = "input";
    parameter bus_hold = "false";
    parameter open_drain_output = "false";
    parameter lpm_type = "maxii_io";
   
    reg prev_value;
    reg tmp_padio;
    reg tmp_combout;
    reg buf_control;

    reg iopen_drain; // open_drain: 1--true, 0--false
    reg ibus_hold; // bus_hold: 1--true, 0--false
    reg [1:0] iop_mode; // operation_mode: 1--input, 2--output, 3--bidir
   
    wire datain_in;
    wire oe_in;
   
    buf(datain_in, datain);
    buf(oe_in, oe);
   
    tri padio_tmp;
   
    specify
        (padio => combout) = (0,0);
        (datain => padio) = (0, 0);
        (posedge oe => (padio +: padio_tmp)) = (0, 0);
        (negedge oe => (padio +: 1'bz)) = (0, 0);
    endspecify
   
    initial
    begin
        prev_value = 'b0;
        tmp_padio = 'bz;

        if (operation_mode == "input")
            iop_mode = 1;
        else if (operation_mode == "output")
            iop_mode = 2;
        else if (operation_mode == "bidir")
            iop_mode = 3;
        else
        begin
            $display ("Error: Invalid operation_mode specified\n");
            iop_mode = 0;
        end

        if (bus_hold == "true" )
            ibus_hold = 1;
        else
            ibus_hold = 0;

        if (open_drain_output == "true" )
            iopen_drain = 1;
        else
            iopen_drain = 0;
    end
   
    always @(datain_in or oe_in or padio)
    begin
        if (ibus_hold == 1)
        begin
            buf_control = 'b1;
            if ( operation_mode == "input")
            begin
                if (padio == 1'bz)
                    tmp_combout = prev_value;
                else
                begin
                    prev_value = padio; 
                    tmp_combout = padio;
                end
                tmp_padio = 1'bz;
            end
            else
            begin
                if (iop_mode == 2 || iop_mode == 3)
                begin
                    if (oe_in == 1)
                    begin
                        if (iopen_drain == 1)
                        begin
                            if (datain_in == 0)
                            begin
                                tmp_padio =  1'b0;
                                prev_value = 1'b0;
                            end
                            else if (datain_in == 1'bx)
                            begin
                                tmp_padio = 1'bx;
                                prev_value = 1'bx;
                            end
                            else   // output of tri is 'Z'
                            begin
                                if (iop_mode == 3)
                                    prev_value = padio;

                                tmp_padio = 1'bz;
                            end
                        end  
                        else  // open_drain_output = false;
                        begin
                            tmp_padio = datain_in;
                            prev_value = datain_in;
                        end
                    end   
                    else if (oe_in == 0)
                    begin
                        if (iop_mode == 3)
                            prev_value = padio;

                        tmp_padio = 1'bz;
                    end
                    else   // oe == 'X' 
                    begin
                        tmp_padio = 1'bx;
                        prev_value = 1'bx;
                    end
                end
			
                if (iop_mode == 2)
                    tmp_combout = 1'bz;
                else
                    tmp_combout = padio;
            end
        end
        else    // bus hold is false
        begin
            buf_control = 'b0;
            if (iop_mode == 1)
            begin
                tmp_combout = padio;
            end
            else if (iop_mode == 2 || iop_mode == 3)
            begin
                if (iop_mode  == 3)
                    tmp_combout = padio;
				
                if (oe_in == 1)
                begin
                    if (iopen_drain == 1)
                    begin
                        if (datain_in == 0)
                            tmp_padio = 1'b0;
                        else if (datain_in == 1'bx)
                            tmp_padio = 1'bx;
                        else
                            tmp_padio = 1'bz;
                    end
                    else
                        tmp_padio = datain_in;
                end
                else if (oe_in == 0)
                    tmp_padio = 1'bz;
                else
                    tmp_padio = 1'bx;
            end
            else
                $display ("Error: Invalid operation_mode specified in MAXII io atom!\n");
            end
        end
   
    bufif1 (weak1, weak0) b(padio_tmp, prev_value, buf_control);  //weak value
    pmos (padio_tmp, tmp_padio, 'b0);
    pmos (combout, tmp_combout, 'b0);
    pmos (padio, padio_tmp, 'b0);

endmodule

//------------------------------------------------------------------
//
// Module Name : maxii_routing_wire
//
// Description : Simulation model for a simple routing wire
//
//------------------------------------------------------------------

`timescale 1ps / 1ps

module maxii_routing_wire (
                               datain,
                               dataout
                               );

    // INPUT PORTS
    input datain;

    // OUTPUT PORTS
    output dataout;

    // INTERNAL VARIABLES
    wire dataout_tmp;

    specify

        (datain => dataout) = (0, 0) ;

    endspecify

    assign dataout_tmp = datain;

    and (dataout, dataout_tmp, 1'b1);

endmodule // maxii_routing_wire

⌨️ 快捷键说明

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