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

powered by: WebSVN 2.1.0

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