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

📄 wb_master_behavioral.v

📁 人民邮电出版社出版的《FPGA硬件接口设计实践》一书的代码
💻 V
📖 第 1 页 / 共 2 页
字号:
    // check if task was called before previous call finished
    if ( in_use === 1 )
    begin
        $display("*E, wb_RMW_write routine re-entered! Time %t ", $time) ;
        return`TB_ERROR_BIT = 1'b1 ;
        disable main ;
    end

    in_use = 1 ;

    retry = 1 ;

    while (retry === 1)
    begin
        // synchronize operation to clock
        //@(posedge CLK_I) ;
        ok = 1 ;
        if (rty_count !== 0)
            wbm_low_level.start_cycle(cab, 1'b1, ok) ;

        if ( ok !== 1 )
        begin
            $display("*E, Failed to initialize cycle! Routine wb_single_write, Time %t ", $time) ;
            return`TB_ERROR_BIT = 1'b1 ;
            disable main ;
        end

        // first insert initial wait states
        cyc_count = write_flags`INIT_WAITS ;
        while ( cyc_count > 0 )
        begin
            @(posedge CLK_I) ;
            cyc_count = cyc_count - 1 ;
        end

        wbm_low_level.wbm_write(write_data, return) ;

        if ( return`CYC_ERR === 0 && return`CYC_ACK === 0 && return`CYC_RTY === 1 && write_flags`WB_TRANSFER_AUTO_RTY === 1 && return`TB_ERROR_BIT === 0)
        begin
            if ( rty_count === `WB_TB_MAX_RTY )
            begin
                 $display("*E, maximum number of retries received - access will not be repeated anymore! Routine wb_single_write, Time %t ", $time) ;
                 retry = 0 ;
            end
            else
            begin
                retry     = 1 ;
                rty_count = rty_count + 1 ;
            end
        end
        else
            retry = 0 ;

        // if test bench error bit is set, there is no meaning in introducing subsequent wait states
        if ( return`TB_ERROR_BIT !== 0 )
        begin
            @(posedge CLK_I) ;
            wbm_low_level.end_cycle ;
            disable main ;
        end

        cyc_count = write_flags`SUBSEQ_WAITS ;
        while ( cyc_count > 0 )
        begin
            @(posedge CLK_I) ;
            cyc_count = cyc_count - 1 ;
        end

        wbm_low_level.end_cycle ;
    end

    in_use = 0 ;

end //main
endtask // wb_RMW_write

task wb_block_write ;
    input  `WB_TRANSFER_FLAGS write_flags ;
    inout  `WRITE_RETURN_TYPE return ;

    reg in_use ;
    reg `WRITE_STIM_TYPE  current_write ;
    reg cab ;
    reg ok ;
    integer cyc_count ;
    integer rty_count ;
    reg end_blk ;
begin:main

    return`CYC_ACTUAL_TRANSFER = 0 ;
    rty_count = 0 ;

    // check if task was called before previous call finished
    if ( in_use === 1 )
    begin
        $display("*E, wb_block_write routine re-entered! Time %t ", $time) ;
        return`TB_ERROR_BIT = 1'b1 ;
        disable main ;
    end

    if (write_flags`WB_TRANSFER_SIZE > `MAX_BLK_SIZE)
    begin
        $display("*E, number of transfers passed to wb_block_write routine exceeds defined maximum transaction length! Time %t", $time) ;
        return`TB_ERROR_BIT = 1'b1 ;
        disable main ;
    end

    in_use = 1 ;
    @(posedge CLK_I) ;
    cab = write_flags`WB_TRANSFER_CAB ;
    wbm_low_level.start_cycle(cab, 1'b1, ok) ;
    if ( ok !== 1 )
    begin
        $display("*E, Failed to initialize cycle! Routine wb_block_write, Time %t ", $time) ;
        return`TB_ERROR_BIT = 1'b1 ;
        disable main ;
    end

    // insert initial wait states
    cyc_count = write_flags`INIT_WAITS ;
    while ( cyc_count > 0 )
    begin
        @(posedge CLK_I) ;
        cyc_count = cyc_count - 1 ;
    end

    end_blk = 0 ;
    while (end_blk === 0)
    begin
        // collect data for current data beat
        current_write = blk_write_data[return`CYC_ACTUAL_TRANSFER] ;
        wbm_low_level.wbm_write(current_write, return) ;

        // check result of write operation
        // check for severe test error
        if (return`TB_ERROR_BIT !== 0)
        begin
           @(posedge CLK_I) ;
           wbm_low_level.end_cycle ;
           disable main ;
        end

        // slave returned error or error signal had invalid value
        if (return`CYC_ERR !== 0)
            end_blk = 1 ;

        if (
            (return`CYC_RTY !== 0) && (return`CYC_RTY !== 1) ||
            (return`CYC_ACK !== 0) && (return`CYC_ACK !== 1) ||
            (return`CYC_ERR !== 0) && (return`CYC_ERR !== 1)
           )
        begin
            end_blk = 1 ;
            $display("*E, at least one slave response signal was invalid when cycle finished! Routine wb_block_write, Time %t ", $time) ;
            $display("ACK = %b \t RTY_O = %b \t ERR_O = %b \t", return`CYC_ACK, return`CYC_RTY, return`CYC_ERR) ;
        end

        if ((return`CYC_RTY === 1) && (write_flags`WB_TRANSFER_AUTO_RTY !== 1))
            end_blk = 1 ;

        if ((return`CYC_RTY === 1) && (write_flags`WB_TRANSFER_AUTO_RTY === 1))
        begin
            if ( rty_count === `WB_TB_MAX_RTY )
            begin
                 $display("*E, maximum number of retries received - access will not be repeated anymore! Routine wb_block_write, Time %t ", $time) ;
                 end_blk = 1 ;
            end
            else
            begin
                rty_count = rty_count + 1 ;
            end
        end
        else
            rty_count = 0 ;

        // check if slave responded at all
        if (return`CYC_RESPONSE === 0)
            end_blk = 1 ;

        // check if all intended data was transfered
        if (return`CYC_ACTUAL_TRANSFER === write_flags`WB_TRANSFER_SIZE)
            end_blk = 1 ;

        // insert subsequent wait cycles, if transfer is supposed to continue
        if ( end_blk === 0 )
        begin
            cyc_count = write_flags`SUBSEQ_WAITS ;
            while ( cyc_count > 0 )
            begin
                @(posedge CLK_I) ;
                cyc_count = cyc_count - 1 ;
            end
        end

        if ( (end_blk === 0) && (return`CYC_RTY === 1) )
        begin
            wbm_low_level.end_cycle ;
            @(posedge CLK_I) ;
            wbm_low_level.start_cycle(cab, 1'b1, ok) ;
            if ( ok !== 1 )
            begin
                $display("*E, Failed to initialize cycle! Routine wb_block_write, Time %t ", $time) ;
                return`TB_ERROR_BIT = 1'b1 ;
                end_blk = 1 ;
            end
        end
    end //while

    wbm_low_level.end_cycle ;
    in_use = 0 ;
end //main
endtask //wb_block_write

task wb_block_read ;
    input  `WB_TRANSFER_FLAGS      read_flags ;
    inout `READ_RETURN_TYPE       return ;

    reg in_use ;
    reg `READ_STIM_TYPE  current_read ;
    reg cab ;
    reg ok ;
    integer cyc_count ;
    integer rty_count ;
    reg end_blk ;
    integer transfered ;
begin:main

    return`CYC_ACTUAL_TRANSFER = 0 ;
    transfered = 0 ;
    rty_count = 0 ;

    // check if task was called before previous call finished
    if ( in_use === 1 )
    begin
        $display("*E, wb_block_read routine re-entered! Time %t ", $time) ;
        return`TB_ERROR_BIT = 1'b1 ;
        disable main ;
    end

    if (read_flags`WB_TRANSFER_SIZE > `MAX_BLK_SIZE)
    begin
        $display("*E, number of transfers passed to wb_block_read routine exceeds defined maximum transaction length! Time %t", $time) ;
        return`TB_ERROR_BIT = 1'b1 ;
        disable main ;
    end

    in_use = 1 ;
    @(posedge CLK_I) ;
    cab = read_flags`WB_TRANSFER_CAB ;

    wbm_low_level.start_cycle(cab, 1'b0, ok) ;

    if ( ok !== 1 )
    begin
        $display("*E, Failed to initialize cycle! Routine wb_block_read, Time %t ", $time) ;
        return`TB_ERROR_BIT = 1'b1 ;
        disable main ;
    end

    // insert initial wait states
    cyc_count = read_flags`INIT_WAITS ;
    while ( cyc_count > 0 )
    begin
        @(posedge CLK_I) ;
        cyc_count = cyc_count - 1 ;
    end

    end_blk = 0 ;
    while (end_blk === 0)
    begin
        // collect data for current data beat
        current_read = blk_read_data_in[return`CYC_ACTUAL_TRANSFER] ;

        wbm_low_level.wbm_read(current_read, return) ;

        if ( transfered !== return`CYC_ACTUAL_TRANSFER )
        begin
            blk_read_data_out[transfered] = return ;
            transfered = return`CYC_ACTUAL_TRANSFER ;
        end

        // check result of read operation
        // check for severe test error
        if (return`TB_ERROR_BIT !== 0)
        begin
           @(posedge CLK_I) ;
           wbm_low_level.end_cycle ;
           disable main ;
        end

        // slave returned error or error signal had invalid value
        if (return`CYC_ERR !== 0)
            end_blk = 1 ;

        if (
            (return`CYC_RTY !== 0) && (return`CYC_RTY !== 1) ||
            (return`CYC_ACK !== 0) && (return`CYC_ACK !== 1) ||
            (return`CYC_ERR !== 0) && (return`CYC_ERR !== 1)
           )
        begin
            end_blk = 1 ;
            $display("*E, at least one slave response signal was invalid when cycle finished! Routine wb_block_read, Time %t ", $time) ;
            $display("ACK = %b \t RTY_O = %b \t ERR_O = %b \t", return`CYC_ACK, return`CYC_RTY, return`CYC_ERR) ;
        end

        if ((return`CYC_RTY === 1) && (read_flags`WB_TRANSFER_AUTO_RTY !== 1))
            end_blk = 1 ;

        if ((return`CYC_RTY === 1) && (read_flags`WB_TRANSFER_AUTO_RTY === 1))
        begin
            if ( rty_count === `WB_TB_MAX_RTY )
            begin
                 $display("*E, maximum number of retries received - access will not be repeated anymore! Routine wb_block_read, Time %t ", $time) ;
                 end_blk = 1 ;
            end
            else
            begin
                rty_count = rty_count + 1 ;
            end
        end
        else
            rty_count = 0 ;

        // check if slave responded at all
        if (return`CYC_RESPONSE === 0)
            end_blk = 1 ;

        // check if all intended data was transfered
        if (return`CYC_ACTUAL_TRANSFER === read_flags`WB_TRANSFER_SIZE)
            end_blk = 1 ;

        // insert subsequent wait cycles, if transfer is supposed to continue
        if ( end_blk === 0 )
        begin
            cyc_count = read_flags`SUBSEQ_WAITS ;
            while ( cyc_count > 0 )
            begin
                @(posedge CLK_I) ;
                cyc_count = cyc_count - 1 ;
            end
        end

        if ( (end_blk === 0) && (return`CYC_RTY === 1) )
        begin
            wbm_low_level.end_cycle ;
            @(posedge CLK_I) ;
            wbm_low_level.start_cycle(cab, 1'b0, ok) ;
            if ( ok !== 1 )
            begin
                $display("*E, Failed to initialize cycle! Routine wb_block_read, Time %t ", $time) ;
                return`TB_ERROR_BIT = 1'b1 ;
                end_blk = 1 ;
            end
        end
    end //while

    wbm_low_level.end_cycle ;
    in_use = 0 ;
end //main
endtask //wb_block_read

endmodule

⌨️ 快捷键说明

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