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

Subversion Repositories fwrisc

[/] [fwrisc/] [trunk/] [ve/] [fwrisc/] [tests/] [fwrisc_instr_tests.cpp] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 mballance
/*
2
 * fwrisc_instr_tests.cpp
3
 *
4
 *
5
 * Copyright 2018 Matthew Ballance
6
 *
7
 * Licensed under the Apache License, Version 2.0 (the
8
 * "License"); you may not use this file except in
9
 * compliance with the License.  You may obtain a copy of
10
 * the License at
11
 *
12
 * http://www.apache.org/licenses/LICENSE-2.0
13
 *
14
 * Unless required by applicable law or agreed to in
15
 * writing, software distributed under the License is
16
 * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
17
 * CONDITIONS OF ANY KIND, either express or implied.  See
18
 * the License for the specific language governing
19
 * permissions and limitations under the License.
20
 *
21
 *  Created on: Oct 28, 2018
22
 *      Author: ballance
23
 */
24
 
25
#include "fwrisc_instr_tests.h"
26
#include "AsmTestCompiler.h"
27
 
28
fwrisc_instr_tests::fwrisc_instr_tests(uint32_t max_instr) : m_max_instr(max_instr) {
29
        m_halt_addr = 0x80000004;
30
}
31
 
32
fwrisc_instr_tests::~fwrisc_instr_tests() {
33
        // TODO Auto-generated destructor stub
34
}
35
 
36
fwrisc_instr_tests *fwrisc_instr_tests::test = 0;
37
 
38
void fwrisc_instr_tests::SetUp() {
39
        BaseT::SetUp();
40
 
41
        Vfwrisc_tb_hdl *tbp = static_cast<Vfwrisc_tb_hdl *>(0);
42
        fprintf(stdout, "offset of clock: %d\n", &tbp->clock);
43
 
44
        test = this;
45
        m_icount = 0;
46
        m_end_of_test = false;
47
 
48
        for (uint32_t i=0; i<64; i++) {
49
                m_regs[i] = std::pair<uint32_t, bool>(0, false);
50
        }
51
 
52
        for (uint32_t i=0; i<1024; i++) {
53
                m_mem[i] = std::pair<uint32_t, bool>(0, false);
54
        }
55
 
56
        raiseObjection(this);
57
 
58
        addClock(top()->clock, 10);
59
}
60
 
61
void fwrisc_instr_tests::regwrite(uint32_t raddr, uint32_t rdata) {
62
        fprintf(stdout, "regwrite 0x%02x <= 0x%08x\n", raddr, rdata);
63
        if (raddr == 0) {
64
                fprintf(stdout, "ERROR: writing to $zero\n");
65
        }
66
        m_regs[raddr].first = rdata;
67
        m_regs[raddr].second = true;
68
}
69
 
70
void fwrisc_instr_tests::memwrite(uint32_t addr, uint8_t mask, uint32_t data) {
71
        fprintf(stdout, "memwrite 0x%08x=0x%08x mask=%02x\n", addr, data, mask);
72
        if ((addr & 0xFFFF8000) == 0x80000000) {
73
                uint32_t offset = ((addr & 0x0000FFFF) >> 2);
74
                fprintf(stdout, "offset=%d\n", offset);
75
                m_mem[offset].second = true; // accessed
76
 
77
                if (mask & 1) {
78
                        m_mem[offset].first &= ~0x000000FF;
79
                        m_mem[offset].first |= (data & 0x000000FF);
80
                }
81
                if (mask & 2) {
82
                        m_mem[offset].first &= ~0x0000FF00;
83
                        m_mem[offset].first |= (data & 0x0000FF00);
84
                }
85
                if (mask & 4) {
86
                        m_mem[offset].first &= ~0x00FF0000;
87
                        m_mem[offset].first |= (data & 0x00FF0000);
88
                }
89
                if (mask & 8) {
90
                        m_mem[offset].first &= ~0xFF000000;
91
                        m_mem[offset].first |= (data & 0xFF000000);
92
                }
93
                fprintf(stdout, "  mem=0x%08x\n", m_mem[offset].first);
94
        } else {
95
                fprintf(stdout, "Error: illegal access to address 0x%08x\n", addr);
96
                ASSERT_EQ((addr & 0xFFFFF000), 0x00000000);
97
        }
98
}
99
 
100
void fwrisc_instr_tests::exec(uint32_t addr, uint32_t instr) {
101
        fprintf(stdout, "EXEC: 0x%08x - 0x%08x\n", addr, instr);
102
        if (m_halt_addr != 0 && addr == m_halt_addr) {
103
                fprintf(stdout, "hit halt address 0x%08x\n", m_halt_addr);
104
                m_end_of_test = true;
105
                dropObjection(this);
106
        }
107
        if (++m_icount > m_max_instr) {
108
                fprintf(stdout, "test timeout\n");
109
                dropObjection(this);
110
        }
111
}
112
 
113
void fwrisc_instr_tests::runtest(
114
                const std::string               &program,
115
                reg_val_s                               *regs,
116
                uint32_t                                n_regs) {
117
        ASSERT_EQ(AsmTestCompiler::compile(testname(), program), true);
118
 
119
        run();
120
        check(regs, n_regs);
121
}
122
 
123
void fwrisc_instr_tests::check(reg_val_s *regs, uint32_t n_regs) {
124
        bool accessed[64];
125
        ASSERT_EQ(m_end_of_test, true); // Ensure we actually reached the end of the test
126
 
127
        memset(accessed, 0, sizeof(accessed));
128
 
129
        // First, display all registers that were written
130
        fprintf(stdout, "Written Registers:\n");
131
        for (uint32_t i=0; i<sizeof(m_regs)/sizeof(reg_val_s); i++) {
132
                if (m_regs[i].second) {
133
                        fprintf(stdout, "R[%d] = 0x%08x\n", i, m_regs[i].first);
134
                }
135
        }
136
        fprintf(stdout, "Expected Registers:\n");
137
        for (uint32_t i=0; i<n_regs; i++) {
138
                fprintf(stdout, "Expect R[%d] = 0x%08x\n", regs[i].addr, regs[i].val);
139
        }
140
 
141
        // Perform the affirmative test
142
        for (uint32_t i=0; i<n_regs; i++) {
143
                if (!m_regs[regs[i].addr].second) {
144
                        fprintf(stdout, "Error: reg %d was not written\n", regs[i].addr);
145
                }
146
                ASSERT_EQ(m_regs[regs[i].addr].second, true); // Ensure we wrote the register
147
                if (m_regs[regs[i].addr].first != regs[i].val) {
148
                        fprintf(stdout, "Error: reg %d regs.value='h%08x expected='h%08hx\n",
149
                                        regs[i].addr, m_regs[regs[i].addr].first, regs[i].val);
150
                }
151
                ASSERT_EQ(m_regs[regs[i].addr].first, regs[i].val);
152
                accessed[regs[i].addr] = true;
153
        }
154
 
155
        for (uint32_t i=0; i<63; i++) { // r63 is the CSR temp register
156
                if (m_regs[i].second != accessed[i]) {
157
                        fprintf(stdout, "Error: reg %d: regs.accessed=%s accessed=%s\n",
158
                                        i, (m_regs[i].second)?"true":"false",
159
                                        (accessed[i])?"true":"false");
160
                }
161
                ASSERT_EQ(m_regs[i].second, accessed[i]);
162
        }
163
}
164
 
165
extern "C" int unsigned fwrisc_tracer_bfm_register(const char *path) {
166
        fprintf(stdout, "register: %s\n", path);
167
        return 0;
168
}
169
 
170
extern "C" void fwrisc_tracer_bfm_regwrite(unsigned int id, unsigned int raddr, unsigned int rdata) {
171
        fwrisc_instr_tests::test->regwrite(raddr, rdata);
172
}
173
 
174
extern "C" void fwrisc_tracer_bfm_memwrite(unsigned int id, unsigned int addr, unsigned char mask, unsigned int data) {
175
        fwrisc_instr_tests::test->memwrite(addr, mask, data);
176
}
177
 
178
extern "C" void fwrisc_tracer_bfm_exec(unsigned int id, unsigned int addr, unsigned int instr) {
179
        fwrisc_instr_tests::test->exec(addr, instr);
180
}
181
 
182
 
183
TEST_F(fwrisc_instr_tests, lui) {
184
        reg_val_s exp[] = {
185
                        {1, 0x00005000}
186
        };
187
        const char *program = R"(
188
                entry:
189
                        lui             x1, 5
190
                        j               done
191
                        )";
192
 
193
        runtest(program, exp, sizeof(exp)/sizeof(reg_val_s));
194
}
195
 
196
 

powered by: WebSVN 2.1.0

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