OpenCores
URL https://opencores.org/ocsvn/riscv_vhdl/riscv_vhdl/trunk

Subversion Repositories riscv_vhdl

[/] [riscv_vhdl/] [trunk/] [debugger/] [src/] [cpu_sysc_plugin/] [riverlib/] [cache/] [icache.cpp] - Diff between revs 3 and 4

Show entire file | Details | Blame | View Log

Rev 3 Rev 4
Line 1... Line 1...
/**
/*
 * @file
 *  Copyright 2018 Sergey Khabarov, sergeykhbr@gmail.com
 * @copyright  Copyright 2017 GNSS Sensor Ltd. All right reserved.
 *
 * @author     Sergey Khabarov - sergeykhbr@gmail.com
 *  Licensed under the Apache License, Version 2.0 (the "License");
 * @brief      Instruction Cache.
 *  you may not use this file except in compliance with the License.
 
 *  You may obtain a copy of the License at
 
 *
 
 *      http://www.apache.org/licenses/LICENSE-2.0
 
 *
 
 *  Unless required by applicable law or agreed to in writing, software
 
 *  distributed under the License is distributed on an "AS IS" BASIS,
 
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
 *  See the License for the specific language governing permissions and
 
 *  limitations under the License.
 */
 */
 
 
#include "icache.h"
#include "icache.h"
 
 
namespace debugger {
namespace debugger {
Line 16... Line 25...
    sensitive << i_req_ctrl_addr;
    sensitive << i_req_ctrl_addr;
    sensitive << i_resp_mem_data_valid;
    sensitive << i_resp_mem_data_valid;
    sensitive << i_resp_mem_data;
    sensitive << i_resp_mem_data;
    sensitive << i_resp_ctrl_ready;
    sensitive << i_resp_ctrl_ready;
    sensitive << i_req_mem_ready;
    sensitive << i_req_mem_ready;
    sensitive << r.iline_addr;
    sensitive << r.iline[0].addr;
    sensitive << r.iline_data;
    sensitive << r.iline[0].data;
    sensitive << r.iline_addr_hit;
    sensitive << r.iline[1].addr;
    sensitive << r.iline_data_hit;
    sensitive << r.iline[1].data;
    sensitive << r.iline_addr_req;
    sensitive << r.iline_addr_req;
    sensitive << r.hit_line;
    sensitive << r.addr_processing;
 
    sensitive << r.double_req;
 
    sensitive << r.delay_valid;
 
    sensitive << r.delay_data;
    sensitive << r.state;
    sensitive << r.state;
 
 
    SC_METHOD(registers);
    SC_METHOD(registers);
    sensitive << i_clk.pos();
    sensitive << i_clk.pos();
};
};
Line 43... Line 55...
        sc_trace(o_vcd, i_resp_mem_data, "/top/cache0/i0/i_resp_mem_data");
        sc_trace(o_vcd, i_resp_mem_data, "/top/cache0/i0/i_resp_mem_data");
        sc_trace(o_vcd, o_resp_ctrl_valid, "/top/cache0/i0/o_resp_ctrl_valid");
        sc_trace(o_vcd, o_resp_ctrl_valid, "/top/cache0/i0/o_resp_ctrl_valid");
        sc_trace(o_vcd, i_resp_ctrl_ready, "/top/cache0/i0/i_resp_ctrl_ready");
        sc_trace(o_vcd, i_resp_ctrl_ready, "/top/cache0/i0/i_resp_ctrl_ready");
        sc_trace(o_vcd, o_resp_ctrl_addr, "/top/cache0/i0/o_resp_ctrl_addr");
        sc_trace(o_vcd, o_resp_ctrl_addr, "/top/cache0/i0/o_resp_ctrl_addr");
        sc_trace(o_vcd, o_resp_ctrl_data, "/top/cache0/i0/o_resp_ctrl_data");
        sc_trace(o_vcd, o_resp_ctrl_data, "/top/cache0/i0/o_resp_ctrl_data");
        sc_trace(o_vcd, r.iline_addr, "/top/cache0/i0/r_iline_addr");
        sc_trace(o_vcd, r.iline[0].addr, "/top/cache0/i0/r_iline(0)_addr");
        sc_trace(o_vcd, r.iline_data, "/top/cache0/i0/r_iline_data");
        sc_trace(o_vcd, r.iline[0].data, "/top/cache0/i0/r_iline(0)_data");
        sc_trace(o_vcd, r.iline_addr_hit, "/top/cache0/i0/r_iline_addr_hit");
        sc_trace(o_vcd, r.iline[1].addr, "/top/cache0/i0/r_iline(1)_addr");
        sc_trace(o_vcd, r.iline_data_hit, "/top/cache0/i0/r_iline_data_hit");
        sc_trace(o_vcd, r.iline[1].data, "/top/cache0/i0/r_iline(1)_data");
        sc_trace(o_vcd, r.iline_addr_req, "/top/cache0/i0/r_iline_addr_req");
        sc_trace(o_vcd, r.iline_addr_req, "/top/cache0/i0/r_iline_addr_req");
        sc_trace(o_vcd, r.hit_line, "/top/cache0/i0/r_hit_line");
        sc_trace(o_vcd, r.addr_processing, "/top/cache0/i0/r_addr_processing");
 
        sc_trace(o_vcd, r.double_req, "/top/cache0/i0/double_req");
 
        sc_trace(o_vcd, r.delay_valid, "/top/cache0/i0/r_delay_valid");
 
        sc_trace(o_vcd, r.delay_data, "/top/cache0/i0/r_delay_valid");
        sc_trace(o_vcd, r.state, "/top/cache0/i0/r_state");
        sc_trace(o_vcd, r.state, "/top/cache0/i0/r_state");
        sc_trace(o_vcd, w_hit, "/top/cache0/i0/w_hit");
        sc_trace(o_vcd, w_need_mem_req, "/top/cache0/i0/w_need_mem_req");
        sc_trace(o_vcd, w_hit_line, "/top/cache0/i0/w_hit_line");
        sc_trace(o_vcd, wb_l[0].hit, "/top/cache0/i0/wb_l(0)_hit");
        sc_trace(o_vcd, w_hit_req, "/top/cache0/i0/w_hit_req");
        sc_trace(o_vcd, wb_l[1].hit, "/top/cache0/i0/wb_l(1)_hit");
        //sc_trace(o_vcd, wb_req_line, "/top/cache0/i0/wb_req_line");
        sc_trace(o_vcd, wb_l[0].hit_data, "/top/cache0/i0/wb_l(0)_hit_data");
        //sc_trace(o_vcd, wb_cached_addr, "/top/cache0/i0/wb_cached_addr");
        sc_trace(o_vcd, wb_l[1].hit_data, "/top/cache0/i0/wb_l(1)_hit_data");
        //sc_trace(o_vcd, wb_cached_data, "/top/cache0/i0/wb_cached_data");
        sc_trace(o_vcd, wb_hit_word, "/top/cache0/i0/wb_hit_word");
 
        sc_trace(o_vcd, wb_l[0].hit_hold, "/top/cache0/i0/wb_l(0).hit_hold");
 
        sc_trace(o_vcd, wb_l[1].hit_hold, "/top/cache0/i0/wb_l(1).hit_hold");
 
        sc_trace(o_vcd, w_reuse_lastline, "/top/cache0/i0/w_reuse_lastline");
 
        sc_trace(o_vcd, w_wait_response, "/top/cache0/i0/w_wait_response");
    }
    }
}
}
 
 
void ICache::comb() {
void ICache::comb() {
    // Instruction cache:
    // Instruction cache:
    bool w_o_req_ctrl_ready;
    bool w_o_req_ctrl_ready;
    bool w_o_req_mem_valid;
    bool w_o_req_mem_valid;
    sc_uint<BUS_ADDR_WIDTH> wb_o_req_mem_addr;
    sc_uint<BUS_ADDR_WIDTH> wb_o_req_mem_addr;
 
    bool w_req_ctrl_valid;
    bool w_req_fire;
    bool w_req_fire;
    bool w_o_resp_valid;
    bool w_o_resp_valid;
    sc_uint<BUS_ADDR_WIDTH> wb_o_resp_addr;
    sc_uint<BUS_ADDR_WIDTH> wb_o_resp_addr;
    sc_uint<32> wb_o_resp_data;
    sc_uint<32> wb_o_resp_data;
    sc_uint<BUS_ADDR_WIDTH - 3> wb_req_line;
    sc_uint<BUS_ADDR_WIDTH> wb_req_addr[2];
 
    sc_uint<BUS_ADDR_WIDTH> wb_hold_addr[2];
 
 
    v = r;
    v = r;
    w_hit_req = 0;
 
    w_hit_line = 0;
    w_wait_response = 0;
    w_hit = 0;
    if (r.state.read() == State_WaitResp && i_resp_mem_data_valid.read() == 0) {
 
        w_wait_response = 1;
    wb_req_line = i_req_ctrl_addr.read()(BUS_ADDR_WIDTH-1, 3);
    }
    if (i_resp_mem_data_valid.read()
    w_req_ctrl_valid = !w_wait_response
      && (wb_req_line == r.iline_addr_req.read()(BUS_ADDR_WIDTH-1, 3))) {
                    && (i_req_ctrl_valid.read() || r.double_req.read());
        w_hit_req = 1;
    wb_req_addr[0] = i_req_ctrl_addr.read();
    }
    wb_req_addr[1] = i_req_ctrl_addr.read() + 2;
    if (wb_req_line == r.iline_addr.read()) {
 
        w_hit_line = 1;
    wb_hold_addr[0] = r.addr_processing.read();
    }
    wb_hold_addr[1] = r.addr_processing.read() + 2;
    w_hit = w_hit_req || w_hit_line;
 
 
    for (int i = 0; i < ILINE_TOTAL; i++) {
    w_o_req_mem_valid = !w_hit & i_req_ctrl_valid.read();
        wb_l[i].hit = 0;
    wb_o_req_mem_addr = i_req_ctrl_addr.read()(BUS_ADDR_WIDTH-1, 3) << 3;
        wb_l[i].hit_data = 0;
    w_o_req_ctrl_ready = w_hit | i_req_mem_ready.read();
        if (wb_req_addr[i](BUS_ADDR_WIDTH-1, 3) == r.iline[0].addr.read()) {
    w_req_fire = i_req_ctrl_valid.read() && w_o_req_ctrl_ready;
            wb_l[i].hit[Hit_Line1] = w_req_ctrl_valid;
 
            wb_l[i].hit_data = r.iline[0].data.read();
 
        } else if (wb_req_addr[i](BUS_ADDR_WIDTH-1, 3) ==
 
                   r.iline[1].addr.read()) {
 
            wb_l[i].hit[Hit_Line2] = w_req_ctrl_valid;
 
            wb_l[i].hit_data = r.iline[1].data.read();
 
        } else if (wb_req_addr[i](BUS_ADDR_WIDTH-1, 3) ==
 
            r.iline_addr_req.read()(BUS_ADDR_WIDTH-1, 3)) {
 
            wb_l[i].hit[Hit_Response] = i_resp_mem_data_valid.read();
 
            wb_l[i].hit_data = i_resp_mem_data.read();
 
        }
 
 
 
        wb_l[i].hit_hold = 0;
 
        wb_l[i].hold_data = 0;
 
        if (wb_hold_addr[i](BUS_ADDR_WIDTH-1, 3) == r.iline[0].addr.read()) {
 
            wb_l[i].hit_hold[Hit_Line1] = 1;
 
            wb_l[i].hold_data = r.iline[0].data.read();
 
        } else if (wb_hold_addr[i](BUS_ADDR_WIDTH-1, 3) ==
 
                   r.iline[1].addr.read()) {
 
            wb_l[i].hit_hold[Hit_Line2] = 1;
 
            wb_l[i].hold_data = r.iline[1].data.read();
 
        } else if (wb_hold_addr[i](BUS_ADDR_WIDTH-1, 3) ==
 
            r.iline_addr_req.read()(BUS_ADDR_WIDTH-1, 3)) {
 
            wb_l[i].hold_data = i_resp_mem_data.read();
 
        }
 
    }
 
 
 
    wb_hit_word = 0;
 
    w_need_mem_req = 1;
 
    if (wb_l[0].hit != 0 && wb_l[1].hit != 0) {
 
        w_need_mem_req = 0;
 
    }
 
    switch (r.addr_processing.read()(2, 1)) {
 
    case 0:
 
        wb_hit_word = wb_l[0].hold_data(31, 0);
 
        break;
 
    case 1:
 
        wb_hit_word = wb_l[0].hold_data(47, 16);
 
        break;
 
    case 2:
 
        wb_hit_word = wb_l[0].hold_data(63, 32);
 
        break;
 
    default:
 
        wb_hit_word = (wb_l[1].hold_data(15, 0) << 16)
 
                     | wb_l[0].hold_data(63, 48);
 
    }
 
 
 
    if (w_req_ctrl_valid && !w_need_mem_req) {
 
        v.delay_valid = 1;
 
        switch (i_req_ctrl_addr.read()(2, 1)) {
 
        case 0:
 
            v.delay_data = wb_l[0].hit_data(31, 0);
 
            break;
 
        case 1:
 
            v.delay_data = wb_l[0].hit_data(47, 16);
 
            break;
 
        case 2:
 
            v.delay_data = wb_l[0].hit_data(63, 32);
 
            break;
 
        default:
 
            v.delay_data = (wb_l[1].hit_data(15, 0) << 16)
 
                            | wb_l[0].hit_data(63, 48);
 
        }
 
    } else if (i_resp_ctrl_ready.read()) {
 
        v.delay_valid = 0;
 
        v.delay_data = 0;
 
    }
 
 
 
    w_o_req_mem_valid = w_need_mem_req & w_req_ctrl_valid;
 
    if (r.double_req.read()) {
 
        if ((r.addr_processing.read()(BUS_ADDR_WIDTH-1, 3) ==
 
            r.iline_addr_req.read()(BUS_ADDR_WIDTH-1, 3))
 
            || (r.addr_processing.read()(BUS_ADDR_WIDTH-1, 3) ==
 
                wb_hold_addr[0](BUS_ADDR_WIDTH-1, 3))
 
            ) {
 
            wb_o_req_mem_addr = wb_hold_addr[1](BUS_ADDR_WIDTH-1, 3) << 3;
 
        } else {
 
            wb_o_req_mem_addr = wb_hold_addr[0](BUS_ADDR_WIDTH-1, 3) << 3;
 
        }
 
    } else if (wb_l[0].hit == 0) {
 
        wb_o_req_mem_addr = wb_req_addr[0](BUS_ADDR_WIDTH-1, 3) << 3;
 
    } else {
 
        wb_o_req_mem_addr = wb_req_addr[1](BUS_ADDR_WIDTH-1, 3) << 3;
 
    }
 
 
 
    w_o_req_ctrl_ready = !w_need_mem_req
 
                       | (i_req_mem_ready.read() & !w_wait_response);
 
    w_req_fire = w_req_ctrl_valid && w_o_req_ctrl_ready;
 
 
 
    if ((w_o_req_mem_valid && i_req_mem_ready.read() && !w_wait_response)
 
        || r.double_req.read()) {
 
        v.iline_addr_req = wb_o_req_mem_addr;
 
    }
 
 
    switch (r.state.read()) {
    switch (r.state.read()) {
    case State_Idle:
    case State_Idle:
        if (i_req_ctrl_valid.read()) {
        if (w_req_ctrl_valid) {
            if (w_hit_line) {
            if (!w_need_mem_req) {
                v.state = State_WaitAccept;
                v.state = State_WaitAccept;
            } else if (i_req_mem_ready.read()) {
            } else if (i_req_mem_ready.read()) {
                v.state = State_WaitResp;
                v.state = State_WaitResp;
            } else {
            } else {
                v.state = State_WaitGrant;
                v.state = State_WaitGrant;
Line 104... Line 218...
        }
        }
        break;
        break;
    case State_WaitGrant:
    case State_WaitGrant:
        if (i_req_mem_ready.read()) {
        if (i_req_mem_ready.read()) {
            v.state = State_WaitResp;
            v.state = State_WaitResp;
        } else if (w_hit) {
        } else if (!w_need_mem_req) {
            /** Fetcher can change request address while request wasn't
            /** Fetcher can change request address while request wasn't
             *  accepteed. */
             *  accepteed. */
            v.state = State_WaitAccept;
            v.state = State_WaitAccept;
        }
        }
        break;
        break;
    case State_WaitResp:
    case State_WaitResp:
        if (i_resp_mem_data_valid.read()) {
        if (i_resp_mem_data_valid.read()) {
            if (!i_resp_ctrl_ready.read()) {
            if (!i_resp_ctrl_ready.read()) {
                v.state = State_WaitAccept;
                v.state = State_WaitAccept;
            } else if (!i_req_ctrl_valid.read()) {
            } else if (!w_req_ctrl_valid) {
                v.state = State_Idle;
                v.state = State_Idle;
            } else {
            } else {
                // New request
                // New request
                if (w_hit) {
                if (!w_need_mem_req) {
                    v.state = State_WaitAccept;
                    v.state = State_WaitAccept;
                } else if (i_req_mem_ready.read()) {
                } else if (i_req_mem_ready.read()) {
                    v.state = State_WaitResp;
                    v.state = State_WaitResp;
                } else {
                } else {
                    v.state = State_WaitGrant;
                    v.state = State_WaitGrant;
Line 130... Line 244...
            }
            }
        }
        }
        break;
        break;
    case State_WaitAccept:
    case State_WaitAccept:
        if (i_resp_ctrl_ready.read()) {
        if (i_resp_ctrl_ready.read()) {
            if (!i_req_ctrl_valid.read()) {
            if (!w_req_ctrl_valid) {
                v.state = State_Idle;
                v.state = State_Idle;
            } else {
            } else {
                if (w_hit) {
                if (!w_need_mem_req) {
                    v.state = State_WaitAccept;
                    v.state = State_WaitAccept;
                } else if (i_req_mem_ready.read()) {
                } else if (i_req_mem_ready.read()) {
                    v.state = State_WaitResp;
                    v.state = State_WaitResp;
                } else {
                } else {
                    v.state = State_WaitGrant;
                    v.state = State_WaitGrant;
Line 147... Line 261...
        break;
        break;
    default:;
    default:;
    }
    }
 
 
    if (w_req_fire) {
    if (w_req_fire) {
        v.iline_addr_req = i_req_ctrl_addr;
        v.double_req = 0;
        v.hit_line = 0;
        if (i_req_ctrl_addr.read()(2, 1) == 0x3
        if (w_hit_line) {
            && wb_l[0].hit == 0 && wb_l[1].hit == 0
            v.hit_line = 1;
            && r.double_req.read() == 0) {
            v.iline_addr_hit = i_req_ctrl_addr;
            v.double_req = 1;
            if (i_req_ctrl_addr.read()[2] == 0) {
 
                v.iline_data_hit =  r.iline_data.read()(31, 0);
 
            } else {
 
                v.iline_data_hit =  r.iline_data.read()(63, 32);
 
            }
            }
 
        if (!r.double_req.read()) {
 
            v.addr_processing = i_req_ctrl_addr;
        }
        }
    }
    }
 
 
 
    w_reuse_lastline = 0;
 
 
    if (i_resp_mem_data_valid.read()) {
    if (i_resp_mem_data_valid.read()) {
        v.iline_addr = r.iline_addr_req.read()(BUS_ADDR_WIDTH-1, 3);
        /** Condition to avoid removing the last line:
        v.iline_data =  i_resp_mem_data;
            */
 
        if (i_resp_ctrl_ready.read()) {
 
            if ((wb_l[0].hit[Hit_Line2] || wb_l[1].hit[Hit_Line2]) == 1
 
                && r.iline[1].addr.read()
 
                    != i_req_ctrl_addr.read()(BUS_ADDR_WIDTH-1, 3)) {
 
                w_reuse_lastline = w_need_mem_req;
    }
    }
 
 
    wb_o_resp_addr = r.iline_addr_req;
 
    if (r.state.read() == State_WaitAccept) {
 
        w_o_resp_valid = 1;
 
        if (r.hit_line) {
 
            wb_o_resp_addr = r.iline_addr_hit;
 
            wb_o_resp_data = r.iline_data_hit;
 
        } else {
        } else {
            if (r.iline_addr_req.read()[2] == 0) {
            if ((wb_l[0].hit_hold[Hit_Line2] || wb_l[1].hit_hold[Hit_Line2]) == 1
                wb_o_resp_data = r.iline_data.read()(31, 0);
                && (wb_l[0].hit_hold[Hit_Line1] || wb_l[1].hit_hold[Hit_Line1]) == 0
            } else {
                && r.iline[1].addr.read()
                wb_o_resp_data = r.iline_data.read()(63, 32);
                    != r.iline_addr_req.read()(BUS_ADDR_WIDTH-1, 3)) {
 
                w_reuse_lastline = 1;
            }
            }
        }
        }
 
        if (!w_reuse_lastline) {
 
            v.iline[1].addr = r.iline[0].addr;
 
            v.iline[1].data = r.iline[0].data;
 
        }
 
 
 
        v.iline[0].addr = r.iline_addr_req.read()(BUS_ADDR_WIDTH-1, 3);
 
        v.iline[0].data = i_resp_mem_data;
 
    }
 
 
 
    if (r.state.read() == State_WaitAccept) {
 
        w_o_resp_valid = !r.double_req.read();
    } else {
    } else {
        w_o_resp_valid = i_resp_mem_data_valid;
        w_o_resp_valid = i_resp_mem_data_valid && !r.double_req.read();
        if (r.iline_addr_req.read()[2] == 0) {
 
            wb_o_resp_data = i_resp_mem_data.read()(31, 0);
 
        } else {
 
            wb_o_resp_data = i_resp_mem_data.read()(63, 32);
 
        }
        }
 
    if (r.delay_valid.read()) {
 
        wb_o_resp_data = r.delay_data.read();
 
    } else {
 
        wb_o_resp_data = wb_hit_word;
    }
    }
 
    wb_o_resp_addr = r.addr_processing;
 
 
 
 
    if (!i_nrst.read()) {
    if (!i_nrst.read()) {
 
        v.iline[0].addr = ~0;
 
        v.iline[0].data = 0;
 
        v.iline[1].addr = ~0;
 
        v.iline[1].data = 0;
        v.iline_addr_req = 0;
        v.iline_addr_req = 0;
        v.iline_addr = ~0;
        v.addr_processing = 0;
        v.iline_data = 0;
 
        v.iline_addr_hit = ~0;
 
        v.iline_data_hit = 0;
 
        v.hit_line = 0;
 
        v.state = State_Idle;
        v.state = State_Idle;
 
        v.double_req = 0;
 
        v.delay_valid = 0;
 
        v.delay_data = 0;
    }
    }
 
 
    o_req_ctrl_ready = w_o_req_ctrl_ready;
    o_req_ctrl_ready = w_o_req_ctrl_ready;
 
 
    o_req_mem_valid = w_o_req_mem_valid;
    o_req_mem_valid = w_o_req_mem_valid;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.