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

Subversion Repositories s80186

[/] [s80186/] [trunk/] [tests/] [rtl/] [TestMicrocode.cpp] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 jamieiles
// Copyright Jamie Iles, 2017
2
//
3
// This file is part of s80x86.
4
//
5
// s80x86 is free software: you can redistribute it and/or modify
6
// it under the terms of the GNU General Public License as published by
7
// the Free Software Foundation, either version 3 of the License, or
8
// (at your option) any later version.
9
//
10
// s80x86 is distributed in the hope that it will be useful,
11
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
// GNU General Public License for more details.
14
//
15
// You should have received a copy of the GNU General Public License
16
// along with s80x86.  If not, see <http://www.gnu.org/licenses/>.
17
 
18
#include <gtest/gtest.h>
19
#include <VMicrocode.h>
20
#include <deque>
21
 
22
#include "VerilogTestbench.h"
23
#include "svdpi.h"
24
 
25
class MicrocodeTestbench : public VerilogTestbench<VMicrocode>,
26
                           public ::testing::Test
27
{
28
public:
29
    MicrocodeTestbench();
30
 
31
    void set_instruction(const std::vector<uint8_t> bytes)
32
    {
33
        stream.insert(stream.end(), bytes.begin(), bytes.end());
34
    }
35
 
36
    uint16_t current_address()
37
    {
38
        return this->dut.get_microcode_address();
39
    }
40
    bool underflowed;
41
 
42
private:
43
    std::deque<uint8_t> stream;
44
};
45
 
46
MicrocodeTestbench::MicrocodeTestbench() : underflowed(false), stream({})
47
{
48
    dut.fifo_empty = stream.size() == 0;
49
    dut.stall = 0;
50
 
51
    svSetScope(svGetScopeFromName("TOP.Microcode"));
52
 
53
    periodic(ClockSetup, [&] {
54
        this->dut.fifo_empty = this->stream.size() == 0;
55
        this->dut.fifo_rd_data = this->stream.size() > 0 ? this->stream[0] : 0;
56
        if (!this->dut.reset && this->dut.fifo_rd_en &&
57
            this->stream.size() > 0) {
58
            after_n_cycles(0, [&] { this->stream.pop_front(); });
59
        }
60
        if (!this->dut.reset && this->dut.fifo_rd_en &&
61
            this->stream.size() == 0)
62
            underflowed = true;
63
    });
64
 
65
    reset();
66
}
67
 
68
TEST_F(MicrocodeTestbench, JumpOpcode)
69
{
70
    reset();
71
    while (current_address() != 0x100)
72
        cycle();
73
 
74
    set_instruction({0x88});
75
 
76
    ASSERT_EQ(current_address(), 0x100);
77
 
78
    for (int i = 0; i < 16; ++i) {
79
        if (underflowed)
80
            FAIL() << "fifo underflow" << std::endl;
81
        if (current_address() == 0x88)
82
            return;
83
        cycle();
84
    }
85
 
86
    FAIL() << "Didn't hit 0x88 opcode" << std::endl;
87
}
88
 
89
TEST_F(MicrocodeTestbench, Stall)
90
{
91
    // Wait for reset to complete
92
    for (int i = 0; i < 128; ++i)
93
        cycle();
94
 
95
    for (int i = 0; i < 32; ++i) {
96
        cycle();
97
        EXPECT_EQ(0x100, current_address());
98
    }
99
 
100
    ASSERT_FALSE(underflowed);
101
}
102
 
103
TEST_F(MicrocodeTestbench, ExternalStall)
104
{
105
    reset();
106
    while (current_address() != 0x100)
107
        cycle();
108
 
109
    set_instruction({0x88});
110
 
111
    while (current_address() != 0x88)
112
        cycle();
113
 
114
    this->dut.stall = 1;
115
    cycle();
116
 
117
    auto held_address = current_address();
118
    ASSERT_NE(held_address, 0x88);
119
 
120
    for (int i = 0; i < 16; ++i) {
121
        EXPECT_EQ(current_address(), held_address);
122
        cycle();
123
    }
124
 
125
    this->dut.stall = 0;
126
    cycle(2);
127
    ASSERT_NE(current_address(), held_address);
128
}
129
 
130
TEST_F(MicrocodeTestbench, MovUnlocked)
131
{
132
    set_instruction({0x88});
133
 
134
    while (current_address() != 0x88)
135
        cycle();
136
 
137
    while (current_address() != 0x100) {
138
        ASSERT_FALSE(this->dut.lock);
139
        cycle();
140
    }
141
}
142
 
143
TEST_F(MicrocodeTestbench, LockPrefixMovIsLocked)
144
{
145
    set_instruction({0xf0, 0x88});
146
 
147
    while (current_address() != 0x88)
148
        cycle();
149
 
150
    while (current_address() != 0x100) {
151
        ASSERT_TRUE(this->dut.lock);
152
        cycle();
153
    }
154
}

powered by: WebSVN 2.1.0

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