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

Subversion Repositories riscv_vhdl

[/] [riscv_vhdl/] [trunk/] [debugger/] [src/] [socsim_plugin/] [gptimers.cpp] - Blame information for rev 4

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 4 sergeykhbr
/**
2
 * @file
3
 * @copyright  Copyright 2016 GNSS Sensor Ltd. All right reserved.
4
 * @author     Sergey Khabarov - sergeykhbr@gmail.com
5
 * @brief      General Purpose Timers model.
6
 */
7
 
8
#include "api_core.h"
9
#include "gptimers.h"
10
 
11
namespace debugger {
12
 
13
GPTimers::GPTimers(const char *name)  : IService(name) {
14
    registerInterface(static_cast<IMemoryOperation *>(this));
15
    registerAttribute("IrqControl", &irqctrl_);
16
    registerAttribute("ClkSource", &clksrc_);
17
 
18
    memset(&regs_, 0, sizeof(regs_));
19
    dbg_irq_cnt_ = 0;
20
}
21
 
22
GPTimers::~GPTimers() {
23
}
24
 
25
void GPTimers::postinitService() {
26
    iclk_ = static_cast<IClock *>(
27
        RISCV_get_service_iface(clksrc_.to_string(), IFACE_CLOCK));
28
    if (!iclk_) {
29
        RISCV_error("Can't find IClock interface %s", clksrc_.to_string());
30
    }
31
 
32
    iwire_ = static_cast<IWire *>(
33
        RISCV_get_service_port_iface(irqctrl_[0u].to_string(),
34
                                     irqctrl_[1].to_string(),
35
                                     IFACE_WIRE));
36
    if (!iwire_) {
37
        RISCV_error("Can't find IWire interface %s", irqctrl_[0u].to_string());
38
    }
39
}
40
 
41
ETransStatus GPTimers::b_transport(Axi4TransactionType *trans) {
42
    uint64_t mask = (length_.to_uint64() - 1);
43
    uint64_t off = ((trans->addr - getBaseAddress()) & mask) / 4;
44
    trans->response = MemResp_Valid;
45
    if (trans->action == MemAction_Write) {
46
        for (uint64_t i = 0; i < trans->xsize/4; i++) {
47
            if ((trans->wstrb & (0xf << 4*i)) == 0) {
48
                continue;
49
            }
50
            switch (off + i) {
51
            case 0:
52
                break;
53
            case 1:
54
                break;
55
            case 2:
56
                regs_.pending = trans->wpayload.b32[i];
57
                RISCV_info("Set pending = %08x", trans->wpayload.b32[i]);
58
                break;
59
            case 16 + 0:
60
                regs_.timer[0].control = trans->wpayload.b32[i];
61
                if (regs_.timer[0].control & TIMER_CONTROL_ENA) {
62
                    iclk_->registerStepCallback(
63
                        static_cast<IClockListener *>(this),
64
                        iclk_->getStepCounter() + regs_.timer[0].init_value);
65
                }
66
                RISCV_info("Set [0].control = %08x", trans->wpayload.b32[i]);
67
                break;
68
            case 16 + 2:
69
                regs_.timer[0].cur_value &= ~0xFFFFFFFFLL;
70
                regs_.timer[0].cur_value |= trans->wpayload.b32[i];
71
                RISCV_info("Set cur_value[31:0] = %x", trans->wpayload.b32[i]);
72
                break;
73
            case 16 + 3:
74
                regs_.timer[0].cur_value &= ~0xFFFFFFFF00000000LL;
75
                regs_.timer[0].cur_value |=
76
                    (static_cast<uint64_t>(trans->wpayload.b32[i]) << 32);
77
                RISCV_info("Set cur_value[63:32] = %x",
78
                            trans->wpayload.b32[i]);
79
                break;
80
            case 16 + 4:
81
                regs_.timer[0].init_value &= ~0xFFFFFFFFLL;
82
                regs_.timer[0].init_value |= trans->wpayload.b32[i];
83
                RISCV_info("Set init_value[31:0] = %x",
84
                            trans->wpayload.b32[i]);
85
                break;
86
            case 16 + 5:
87
                regs_.timer[0].init_value &= ~0xFFFFFFFF00000000LL;
88
                regs_.timer[0].init_value |=
89
                    (static_cast<uint64_t>(trans->wpayload.b32[i]) << 32);
90
                RISCV_info("Set init_value[63:32] = %x",
91
                            trans->wpayload.b32[i]);
92
                break;
93
            default:;
94
            }
95
        }
96
    } else {
97
        for (uint64_t i = 0; i < trans->xsize/4; i++) {
98
            switch (off + i) {
99
            case 0:
100
                regs_.highcnt = iclk_->getStepCounter();
101
                trans->rpayload.b32[i] = static_cast<uint32_t>(regs_.highcnt);
102
                break;
103
            case 1:
104
                regs_.highcnt = iclk_->getStepCounter();
105
                trans->rpayload.b32[i] =
106
                    static_cast<uint32_t>(regs_.highcnt >> 32);
107
                break;
108
            case 16 + 0:
109
                trans->rpayload.b32[i] = regs_.timer[0].control;
110
                RISCV_info("Get [0].control = %08x", trans->rpayload.b32[i]);
111
                break;
112
            default:
113
                trans->rpayload.b32[i] = ~0;
114
            }
115
        }
116
    }
117
    return TRANS_OK;
118
}
119
 
120
void GPTimers::stepCallback(uint64_t t) {
121
    iwire_->raiseLine();
122
    RISCV_info("Raise interrupt cnt=%d", dbg_irq_cnt_++);
123
    if (regs_.timer[0].control & TIMER_CONTROL_ENA) {
124
        iclk_->registerStepCallback(static_cast<IClockListener *>(this),
125
                                    t + regs_.timer[0].init_value);
126
    }
127
}
128
 
129
 
130
}  // namespace debugger
131
 

powered by: WebSVN 2.1.0

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