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

Subversion Repositories wb2axip

[/] [wb2axip/] [trunk/] [bench/] [cpp/] [aximemsim.cpp] - Blame information for rev 8

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

Line No. Rev Author Line
1 8 dgisselq
////////////////////////////////////////////////////////////////////////////////
2
//
3
// Filename:    aximemsim.cpp
4
//
5
// Project:     Pipelined Wishbone to AXI converter
6
//
7
// Purpose:     
8
//
9
// Creator:     Dan Gisselquist, Ph.D.
10
//              Gisselquist Technology, LLC
11
//
12
////////////////////////////////////////////////////////////////////////////////
13
//
14
// Copyright (C) 2016, Gisselquist Technology, LLC
15
//
16
// This program is free software (firmware): you can redistribute it and/or
17
// modify it under the terms of  the GNU General Public License as published
18
// by the Free Software Foundation, either version 3 of the License, or (at
19
// your option) any later version.
20
//
21
// This program is distributed in the hope that it will be useful, but WITHOUT
22
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
23
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
24
// for more details.
25
//
26
// You should have received a copy of the GNU General Public License along
27
// with this program.  (It's in the $(ROOT)/doc directory, run make with no
28
// target there if the PDF file isn't present.)  If not, see
29
// <http://www.gnu.org/licenses/> for a copy.
30
//
31
// License:     GPL, v3, as defined and found on www.gnu.org,
32
//              http://www.gnu.org/licenses/gpl.html
33
//
34
//
35
////////////////////////////////////////////////////////////////////////////////
36
//
37
//
38
#include <stdio.h>
39
 
40
#include "aximemsim.h"
41
 
42
class   ADRFIFO {
43
        typedef {
44
                int id; unsigned addr;
45
        } ADRFIFOELEMENT;
46
        int     m_head, m_tail, m_len;
47
        int     *m_mem;
48
public:
49
        ADRFIFO(int ln) {
50
                m_mem = new ADRFIFOELEMENT[ln];
51
                m_head = m_tail = 0;
52
                m_len = ln;
53
        }
54
 
55
        void    push(int id, unsigned addr) {
56
                int nhead = m_head + 1;
57
                if (nhead >= m_len)
58
                        nhead = 0;
59
                assert(nhead != m_tail);
60
                m_mem[m_head].id   = id;
61
                m_mem[m_head].addr = addr;
62
                m_head = nhead;
63
        }
64
 
65
        bool    full(void) {
66
                int nhead = m_head + 1;
67
                if (nhead >= m_len)
68
                        nhead = 0;
69
                return (nhead == m_tail);
70
        }
71
 
72
        bool    valid(void) {
73
                return (m_head != m_tail);
74
        }
75
 
76
        int     id(void)        { return m_mem[m_tail].id; }
77
        int     addr(void)      { return m_mem[m_tail].addr; }
78
        int     pop(void)       {
79
                if (m_tail == m_head)
80
                        return;
81
                m_tail++;
82
                if (m_tail >= m_len)
83
                        m_tail = 0;
84
        }
85
};
86
 
87
class   DATFIFO {
88
        typedef {
89
                unsigned data[4];
90
                int     strb;
91
        } DATAFIFOELEMENT;
92
        int     m_head, m_tail, m_len;
93
        int     *m_mem;
94
public:
95
        DATAFIFO(int ln) {
96
                m_mem = new DATAFIFOELEMENT[ln];
97
                m_head = m_tail = 0;
98
                m_len = ln;
99
        }
100
 
101
        void    push(int strb, unsigned dat0, unsigned dat1,
102
                        unsigned dat, unsigned dat3) {
103
                int nhead = m_head + 1;
104
                if (nhead >= m_len)
105
                        nhead = 0;
106
                assert(nhead != m_tail);
107
                m_mem[m_head].strb   = id;
108
                m_mem[m_head].data[0] = dat0;
109
                m_mem[m_head].data[1] = dat1;
110
                m_mem[m_head].data[2] = dat2;
111
                m_mem[m_head].data[3] = dat3;
112
                m_head = nhead;
113
        }
114
 
115
        bool    full(void) {
116
                int nhead = m_head + 1;
117
                if (nhead >= m_len)
118
                        nhead = 0;
119
                return (nhead == m_tail);
120
        }
121
 
122
        bool    valid(void) {
123
                return (m_head != m_tail);
124
        }
125
 
126
        int     strb(void)      { return m_mem[m_tail].strb; }
127
        unsigned *data(void)    { return &m_mem[m_tail].data[0]; }
128
        int     pop(void)       {
129
                if (m_tail == m_head)
130
                        return;
131
                m_tail++;
132
                if (m_tail >= m_len)
133
                        m_tail = 0;
134
        }
135
};
136
 
137
AXIMEMSIM::AXIMEMSIM(unsigned abits) {
138
        // abits is the number of bits in a memory address, referencing 8-bit
139
        // bytes, therefore we can size our memory properly.
140
        assert(abits>2);
141
        m_len = (1<<(abits-2));
142
        m_mask= m_len-1;
143
        m_mem = new unsigned[(1<<(abits-2))];
144
 
145
        memset(m_mem, 0, sizeof(unsigned)<<(abits-2));
146
}
147
 
148
void AXIMEMSIM::apply(AXIBUS &bus) {
149
        // First, let's validate our inputs ..., and queue up our outputs
150
        bus.ar.ready = (!m_readfifo.full());
151
        bus.aw.ready = (!m_writefifo.full());
152
        bus.w.ready  = (!m_wdata.full());
153
        if (bus.r.ready)
154
                bus.r.valid = false;
155
        if (bus.b.ready)
156
                bus.b.valid = false;
157
 
158
        if ((bus.ar.ready)&&(!m_readfifo.full())) {
159
                assert(bus.ar.len  == 0);
160
                assert(bus.ar.size  == 5);
161
                assert(bus.ar.burst == 1);
162
                assert(bus.ar.lock  == 0);
163
                assert(bus.ar.cache == 2);
164
                assert(bus.ar.prot  == 2);
165
                assert(bus.ar.qos   == 0);
166
 
167
                m_readfifo.push(bus.ar.id, bus.ar.addr);
168
        }
169
 
170
        if ((bus.aw.ready)&&(!m_writefifo.full())) {
171
                assert(bus.aw.len   == 0);
172
                assert(bus.aw.size  == 5);
173
                assert(bus.aw.burst == 1);
174
                assert(bus.aw.lock  == 0);
175
                assert(bus.aw.cache == 2);
176
                assert(bus.aw.prot  == 2);
177
                assert(bus.aw.qos   == 0);
178
 
179
                m_awfifo.push(bus.aw.id, bus.aw.addr);
180
        }
181
 
182
        if ((bus.w.ready)&&(!m_writedata.full())) {
183
                m_writefifo.push(bus.aw.strb, bus.aw.data[0], bus.aw.data[1],
184
                        bus.aw.data[2], bus.aw.data[3]);
185
 
186
        if (m_respfifo[m_now].valid) {
187
                if (m_respfifo[m_now].read) {
188
                        if ((!bus.r.valid)||(bus.r.ready)) {
189
                                bus.r.data[0] = m_respfifo[m_now].data[0];
190
                                bus.r.data[1] = m_respfifo[m_now].data[1];
191
                                bus.r.data[2] = m_respfifo[m_now].data[2];
192
                                bus.r.data[3] = m_respfifo[m_now].data[3];
193
                                bus.r.valid = true;
194
                                m_now++;
195
                        }
196
                } else if ((!bus.b.valid)||(bus.b.ready)) {
197
                        bus.b.resp = m_respfifo[m_now].resp;
198
                        bus.b.id = m_respfifo[m_now].id;
199
                        bus.b.valid = true;
200
                        m_now++;
201
                }
202
        }
203
}
204
 

powered by: WebSVN 2.1.0

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