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

Subversion Repositories wbscope

[/] [wbscope/] [trunk/] [sw/] [scopecls.h] - Blame information for rev 13

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 12 dgisselq
////////////////////////////////////////////////////////////////////////////////
2
//
3
// Filename:    scopecls.h
4
//
5
// Project:     WBScope, a wishbone hosted scope
6
//
7
// Purpose:     After rebuilding the same code over and over again for every
8
//              "scope" I tried to interact with, I thought it would be simpler
9
//      to try to make a more generic interface, that other things could plug
10 13 dgisselq
//      into.  This file defines and describes that more generic interface.
11 12 dgisselq
//
12 13 dgisselq
//      More recent updates have added to this interface those things necessary
13
//      to create a .VCD file for viewing in GTKWave.
14
//
15 12 dgisselq
// Creator:     Dan Gisselquist, Ph.D.
16
//              Gisselquist Technology, LLC
17
//
18
////////////////////////////////////////////////////////////////////////////////
19
//
20
// Copyright (C) 2015-2017, Gisselquist Technology, LLC
21
//
22
// This program is free software (firmware): you can redistribute it and/or
23
// modify it under the terms of  the GNU General Public License as published
24
// by the Free Software Foundation, either version 3 of the License, or (at
25
// your option) any later version.
26
//
27
// This program is distributed in the hope that it will be useful, but WITHOUT
28
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
29
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
30
// for more details.
31
//
32
// You should have received a copy of the GNU General Public License along
33
// with this program.  (It's in the $(ROOT)/doc directory.  Run make with no
34
// target there if the PDF file isn't present.)  If not, see
35
// <http://www.gnu.org/licenses/> for a copy.
36
//
37
// License:     GPL, v3, as defined and found on www.gnu.org,
38
//              http://www.gnu.org/licenses/gpl.html
39
//
40
//
41
////////////////////////////////////////////////////////////////////////////////
42
//
43
//
44
#ifndef SCOPECLS_H
45
#define SCOPECLS_H
46
 
47
#include <vector>
48
#include "devbus.h"
49
 
50 13 dgisselq
 
51
/*
52
 * TRACEINFO
53
 *
54
 * The TRACEINFO class describes a wire (or set of wires) internal to the
55
 * scope data word.  These wires are assumed to be contiguous, and given by:
56
 * ((data_word>>m_nshift)&((1<<m_nbits)-1).  That is, there are m_nbits bits
57
 * to this value, and a shift of m_nshift is required to bring them down to
58
 * zero.
59
 *
60
 * Other key pieces include the human readable name given to the signal, m_name,
61
 * as well as the VCD name, m_key.
62
 *
63
 */
64 12 dgisselq
class   TRACEINFO {
65
public:
66
        const char      *m_name;
67
        char            m_key[4];
68
        unsigned        m_nbits, m_nshift;
69
};
70
 
71 13 dgisselq
/*
72
 * SCOPE
73
 *
74
 * This class is designed to be a generic SCOPE class, one which has all of the
75
 * logic other scopes will require.  Hence, if more than one scope needs this
76
 * logic, I stuff it in here for all scopes to use.
77
 */
78 12 dgisselq
class   SCOPE {
79 13 dgisselq
        DEVBUS          *m_fpga;        // Access to the FPGA
80
        DEVBUS::BUSW    m_addr;         // The address of the scope control reg
81
                        // Set m_compressed to be true if the scope is a
82
                        // compressed scope, that is if it uses the wbscopc.v
83
                        // core.
84
        bool            m_compressed,
85
                        // Set m_vector_read if you trust the bus enough to
86
                        // issue vector reads (multiple words at once)
87
                        m_vector_read;
88
        unsigned        m_scoplen,      // Number of words in the scopes memory
89
                        m_holdoff;      // The bias, or samples since trigger
90
        unsigned        *m_data;        // Data read from the scope
91
        unsigned        m_clkfreq_hz;
92
 
93
        // The m_traces variable holds a list of all of the various wire
94
        // definitions within the scope data word.
95 12 dgisselq
        std::vector<TRACEINFO *> m_traces;
96
 
97
public:
98
        SCOPE(DEVBUS *fpga, unsigned addr,
99
                        bool compressed=false, bool vecread=true)
100
                : m_fpga(fpga), m_addr(addr),
101
                        m_compressed(compressed), m_vector_read(vecread),
102 13 dgisselq
                        m_scoplen(0), m_data(NULL) {
103
                //
104
                // First thing we want to do upon allocating a scope, is to
105
                // define the traces for that scope.  Sad thing is ... we can't
106
                // call it here, since the class inheriting from us isn't
107
                // defined yet.
108
                // define_traces();
109 12 dgisselq
 
110 13 dgisselq
 
111
                // Default clock frequency: 100MHz.
112
                m_clkfreq_hz = 100000000;
113
        }
114
 
115
        // Free up any of our allocated memory.
116
        ~SCOPE(void) {
117
                for(unsigned i=0; i<m_traces.size(); i++)
118
                        delete m_traces[i];
119
                if (m_data) delete[] m_data;
120
        }
121
 
122
        // Query the scope: Is it ready?  Has it primed, triggered, and stopped?
123
        // If so, this routine returns true, false otherwise.
124 12 dgisselq
        bool    ready();
125 13 dgisselq
 
126
        // Read the control word from the scope, and send to the standard output
127
        // a description of that.
128 12 dgisselq
        void    decode_control(void);
129 13 dgisselq
 
130
        // Read the scope's control word, decode the memory size of the scope,
131
        // and return that to our caller.
132 12 dgisselq
        int     scoplen(void);
133 13 dgisselq
 
134
        // Set the clock speed that we are referencing
135
        void    set_clkfreq_hz(unsigned clkfreq_hz) {
136
                m_clkfreq_hz = clkfreq_hz;
137
        }
138
 
139
        // Read any previously set clock speed.
140
        unsigned get_clkfreq_hz(void) { return m_clkfreq_hz; }
141
 
142
        // Read the data from the scope and place it into our m_data array.
143
        // Nothing more is done with it beyond that.
144 12 dgisselq
        virtual void    rawread(void);
145 13 dgisselq
 
146
        // Walk through the data, and print out to the standard output, what is
147
        // in it.  If multiple lines have the same data, print() will avoid
148
        // printing those lines for the purpose of keeping the output from
149
        // getting cluttered, but it will print a **** spacer, so you know
150
        // lines were skipped.
151 12 dgisselq
                void    print(void);
152 13 dgisselq
 
153
        // decode() works together with print() above.  The print() routine
154
        // calls decode() for every memory word within the scope's buffer.
155
        // More than that, the print() routine starts each line with the
156
        // clock number of the item, followed by the 32-bit data word in hex and
157
        // a colon.  Then it calls decode() to fill in the line with whatever
158
        // useful information was in the scope's data word.  Then it prints
159
        // a "\n" and continues.  Hence ... the purpose of the decode()
160
        // function--and why it needs to be scope specific.
161
        virtual void    decode(DEVBUS::BUSW v) const = 0;
162
 
163
        //
164
        //
165
        // The following routines are provided to enable the creation and
166
        // writing of VCD files.
167
        //
168
        //
169
 
170
        // Write the timescale line to a VCD file.
171 12 dgisselq
        virtual void    write_trace_timescale(FILE *fp);
172 13 dgisselq
 
173
        // Write the offset from the time within the file, to the time of the
174
        // trigger, into the file.
175
        virtual void    write_trace_timezero(FILE *fp, int offset);
176
 
177
        // Write the VCD file's header
178
        virtual void    write_trace_header(FILE *fp, int offset = 0);
179
 
180
        // Given a value, and the number of bits required to define that value,
181
        // write a single line to our VCD file.
182
        //
183
        // This is an internal call that you are not likely to need to modify.
184 12 dgisselq
                void    write_binary_trace(FILE *fp, const int nbits,
185
                                unsigned val, const char *str);
186 13 dgisselq
 
187
        // Same as write_binary_trace above, but this time we are given the
188
        // trace definition and the un-decomposed word to decompose first before
189
        // writing to the file.
190
        //
191
        // This is also an internal call that you are not likely to need to
192
        // modify.
193 12 dgisselq
                void    write_binary_trace(FILE *fp, TRACEINFO *info,
194
                                unsigned value);
195 13 dgisselq
 
196
        // This is the user entry point.  When you know the scope is ready,
197
        // you may call writevcd to start the VCD generation process.
198 12 dgisselq
                void    writevcd(const char *trace_file_name);
199 13 dgisselq
        // This is an alternate entry point, useful if you already have a
200
        // FILE *.  This will write the data to the file, but not close the
201
        // file.
202
                void    writevcd(FILE *fp);
203
 
204
        // Calculate the number of points the scope covers.  Nominally, this
205
        // will be m_scopelen, the length of the scope.  However, if the
206
        // scope is compressed, this could be greater.
207
        //
208
        unsigned        getaddresslen(void);
209
 
210
        // Your program needs to define a define_traces() function, which will
211
        // then be called before trying to write the VCD file.  This function
212
        // must call register_trace for each of the traces within your data
213
        // word.
214
        virtual void    define_traces(void);
215
 
216
        // Register_trace() defines the elements of a TRACEINFO structure
217
        // above.  These are then inserted into the list of TRACEINFO
218
        // structures, for reference when writing the VCD file.
219 12 dgisselq
                void    register_trace(const char *varname,
220
                                unsigned nbits, unsigned shift);
221 13 dgisselq
 
222
        unsigned operator[](unsigned addr) {
223
                if ((m_data)&&(m_scoplen > 0))
224
                        return m_data[(addr)&(m_scoplen-1)];
225
                return 0;
226
        }
227 12 dgisselq
};
228
 
229
#endif  // SCOPECLS_H

powered by: WebSVN 2.1.0

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