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 2

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 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("BaseAddress", &baseAddress_);
16
    registerAttribute("Length", &length_);
17
    registerAttribute("IrqLine", &irqLine_);
18
    registerAttribute("IrqControl", &irqctrl_);
19
    registerAttribute("ClkSource", &clksrc_);
20
 
21
    baseAddress_.make_uint64(0);
22
    length_.make_uint64(0);
23
    irqLine_.make_uint64(0);
24
    irqctrl_.make_string("");
25
    clksrc_.make_string("");
26
 
27
 
28
    memset(&regs_, 0, sizeof(regs_));
29
}
30
 
31
GPTimers::~GPTimers() {
32
}
33
 
34
void GPTimers::postinitService() {
35
    iclk_ = static_cast<IClock *>(
36
        RISCV_get_service_iface(clksrc_.to_string(), IFACE_CLOCK));
37
    if (!iclk_) {
38
        RISCV_error("Can't find IClock interface %s", clksrc_.to_string());
39
    }
40
 
41
    iwire_ = static_cast<IWire *>(
42
        RISCV_get_service_iface(irqctrl_.to_string(), IFACE_WIRE));
43
    if (!iwire_) {
44
        RISCV_error("Can't find IWire interface %s", irqctrl_.to_string());
45
    }
46
}
47
 
48
void GPTimers::b_transport(Axi4TransactionType *trans) {
49
    uint64_t mask = (length_.to_uint64() - 1);
50
    uint64_t off = ((trans->addr - getBaseAddress()) & mask) / 4;
51
    trans->response = MemResp_Valid;
52
    if (trans->action == MemAction_Write) {
53
        for (uint64_t i = 0; i < trans->xsize/4; i++) {
54
            if ((trans->wstrb & (0xf << 4*i)) == 0) {
55
                continue;
56
            }
57
            switch (off + i) {
58
            case 0:
59
                break;
60
            case 1:
61
                break;
62
            case 2:
63
                regs_.pending = trans->wpayload.b32[i];
64
                RISCV_info("Set pending = %08x", trans->wpayload.b32[i]);
65
                break;
66
            case 16 + 0:
67
                regs_.timer[0].control = trans->wpayload.b32[i];
68
                if (regs_.timer[0].control & TIMER_CONTROL_ENA) {
69
                    iclk_->registerStepCallback(
70
                        static_cast<IClockListener *>(this),
71
                        iclk_->getStepCounter() + regs_.timer[0].init_value);
72
                }
73
                RISCV_info("Set [0].control = %08x", trans->wpayload.b32[i]);
74
                break;
75
            case 16 + 2:
76
                regs_.timer[0].cur_value &= ~0xFFFFFFFFLL;
77
                regs_.timer[0].cur_value |= trans->wpayload.b32[i];
78
                RISCV_info("Set cur_value[31:0] = %x", trans->wpayload.b32[i]);
79
                break;
80
            case 16 + 3:
81
                regs_.timer[0].cur_value &= ~0xFFFFFFFF00000000LL;
82
                regs_.timer[0].cur_value |=
83
                    (static_cast<uint64_t>(trans->wpayload.b32[i]) << 32);
84
                RISCV_info("Set cur_value[63:32] = %x",
85
                            trans->wpayload.b32[i]);
86
                break;
87
            case 16 + 4:
88
                regs_.timer[0].init_value &= ~0xFFFFFFFFLL;
89
                regs_.timer[0].init_value |= trans->wpayload.b32[i];
90
                RISCV_info("Set init_value[31:0] = %x",
91
                            trans->wpayload.b32[i]);
92
                break;
93
            case 16 + 5:
94
                regs_.timer[0].init_value &= ~0xFFFFFFFF00000000LL;
95
                regs_.timer[0].init_value |=
96
                    (static_cast<uint64_t>(trans->wpayload.b32[i]) << 32);
97
                RISCV_info("Set init_value[63:32] = %x",
98
                            trans->wpayload.b32[i]);
99
                break;
100
            default:;
101
            }
102
        }
103
    } else {
104
        for (uint64_t i = 0; i < trans->xsize/4; i++) {
105
            switch (off + i) {
106
            case 0:
107
                regs_.highcnt = iclk_->getStepCounter();
108
                trans->rpayload.b32[i] = static_cast<uint32_t>(regs_.highcnt);
109
                break;
110
            case 1:
111
                regs_.highcnt = iclk_->getStepCounter();
112
                trans->rpayload.b32[i] =
113
                    static_cast<uint32_t>(regs_.highcnt >> 32);
114
                break;
115
            case 16 + 0:
116
                trans->rpayload.b32[i] = regs_.timer[0].control;
117
                RISCV_info("Get [0].control = %08x", trans->rpayload.b32[i]);
118
                break;
119
            default:
120
                trans->rpayload.b32[i] = ~0;
121
            }
122
        }
123
    }
124
}
125
 
126
void GPTimers::stepCallback(uint64_t t) {
127
    iwire_->raiseLine(irqLine_.to_int());
128
    if (regs_.timer[0].control & TIMER_CONTROL_ENA) {
129
        iclk_->registerStepCallback(static_cast<IClockListener *>(this),
130
                                    t + regs_.timer[0].init_value);
131
    }
132
}
133
 
134
 
135
}  // namespace debugger
136
 

powered by: WebSVN 2.1.0

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