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

Subversion Repositories riscv_vhdl

[/] [riscv_vhdl/] [trunk/] [debugger/] [src/] [libdbg64g/] [services/] [mem/] [memsim.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      ROM functional model implementation.
6
 */
7
 
8
#include "api_core.h"
9
#include "memsim.h"
10
#include <iostream>
11
#include <string.h>
12
 
13
namespace debugger {
14
 
15
/** Class registration in the Core */
16
REGISTER_CLASS(MemorySim)
17
 
18
MemorySim::MemorySim(const char *name)  : IService(name) {
19
    registerInterface(static_cast<IMemoryOperation *>(this));
20
    registerAttribute("InitFile", &initFile_);
21
    registerAttribute("ReadOnly", &readOnly_);
22
    registerAttribute("BaseAddress", &baseAddress_);
23
    registerAttribute("Length", &length_);
24
 
25
    initFile_.make_string("");
26
    readOnly_.make_boolean(false);
27
    baseAddress_.make_uint64(0);
28
    length_.make_uint64(0);
29
    mem_ = NULL;
30
}
31
 
32
MemorySim::~MemorySim() {
33
    if (mem_) {
34
        delete mem_;
35
    }
36
}
37
 
38
void MemorySim::postinitService() {
39
    // Get global settings:
40
    const AttributeType *glb = RISCV_get_global_settings();
41
    if ((*glb)["SimEnable"].to_bool() == false) {
42
        return;
43
    }
44
 
45
    mem_ = new uint8_t[static_cast<unsigned>(length_.to_uint64())];
46
    if (initFile_.size() == 0) {
47
        return;
48
    }
49
 
50
    std::string filename(initFile_.to_string());
51
    if (strstr(initFile_.to_string(), "..") != NULL ||
52
        strstr(initFile_.to_string(), "/") == NULL) {
53
        char path[1024];
54
        RISCV_get_core_folder(path, sizeof(path));
55
        std::string spath(path);
56
        filename = spath + std::string(initFile_.to_string());
57
    }
58
 
59
    FILE *fp = fopen(initFile_.to_string(), "r");
60
    if (fp == NULL) {
61
        for (uint64_t i = 0; i < length_.to_uint64()/4; i++) {
62
            // NOP isntruction
63
            reinterpret_cast<uint32_t *>(mem_)[i] = 0x00000013;  // intialize by NOPs
64
        }
65
        RISCV_error("Can't open '%s' file", initFile_.to_string());
66
        return;
67
    }
68
 
69
    bool bhalf = false;
70
    int rd_symb;
71
    uint8_t symb;
72
    int linecnt = 0;
73
    int symbinline = SYMB_IN_LINE - 1;
74
    while (!feof(fp)) {
75
        rd_symb = fgetc(fp);
76
        if (!chishex(rd_symb))
77
            continue;
78
 
79
        if (!bhalf) {
80
            bhalf = true;
81
            symb = chtohex(rd_symb) << 4;
82
            continue;
83
        }
84
 
85
        bhalf = false;
86
        symb |= chtohex(rd_symb) & 0xf;
87
 
88
        if ((SYMB_IN_LINE * linecnt + symbinline) >=
89
                    static_cast<int>(length_.to_uint64())) {
90
            RISCV_error("HEX file tries to write out "
91
                        "of allocated array\n", NULL);
92
            break;
93
        }
94
 
95
        mem_[SYMB_IN_LINE * linecnt + symbinline] = symb;
96
        if (--symbinline < 0) {
97
            linecnt++;
98
            symbinline = SYMB_IN_LINE - 1;
99
        }
100
    }
101
    fclose(fp);
102
}
103
 
104
void MemorySim::b_transport(Axi4TransactionType *trans) {
105
    uint64_t mask = (length_.to_uint64() - 1);
106
    uint64_t off = (trans->addr - getBaseAddress()) & mask;
107
    trans->response = MemResp_Valid;
108
    if (trans->action == MemAction_Write) {
109
        if (readOnly_.to_bool()) {
110
            RISCV_error("Write to READ ONLY memory", NULL);
111
            trans->response = MemResp_Error;
112
        } else {
113
            for (uint64_t i = 0; i < trans->xsize; i++) {
114
                if (((trans->wstrb >> i) & 0x1) == 0) {
115
                    continue;
116
                }
117
                mem_[off + i] = trans->wpayload.b8[i];
118
            }
119
        }
120
    } else {
121
        memcpy(trans->rpayload.b8, &mem_[off], trans->xsize);
122
    }
123
 
124
    const char *rw_str[2] = {"=>", "<="};
125
    uint32_t *pdata[2] = {trans->rpayload.b32, trans->wpayload.b32};
126
    RISCV_debug("[%08" RV_PRI64 "x] %s [%08x %08x]",
127
        trans->addr,
128
        rw_str[trans->action],
129
        pdata[trans->action][1], pdata[trans->action][0]);
130
}
131
 
132
bool MemorySim::chishex(int s) {
133
    bool ret = false;
134
    if (s >= '0' && s <= '9') {
135
        ret = true;
136
    } else if (s >= 'A' && s <= 'F') {
137
        ret = true;
138
    } else if (s >= 'a' && s <= 'f') {
139
        ret = true;
140
    }
141
    return ret;
142
}
143
 
144
uint8_t MemorySim::chtohex(int s) {
145
    if (s >= '0' && s <= '9') {
146
        s -= '0';
147
    } else if (s >= 'A' && s <= 'F') {
148
        s = s - 'A' + 10;
149
    } else if (s >= 'a' && s <= 'f') {
150
        s = s - 'a' + 10;
151
    }
152
    return static_cast<uint8_t>(s);
153
}
154
 
155
}  // namespace debugger
156
 

powered by: WebSVN 2.1.0

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