-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathBus.hh
112 lines (100 loc) · 3.59 KB
/
Bus.hh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
/*
* Bus.h -- classes and other stuff relating to bus accesses.
*
* Requires goodies.h.
*
* The following classes are declared in this file:
* Bus_master a module which can access the bus
* Bus_slave a module which can be accessed over the bus
* Single_master_bus a module which allows one master to talk to many slaves
* Bus_tracer a module which traces bus activity
* Access_info a collection of info about the access
* Access_status info about how the access went
*
* A Bus_master is always directly connected to a Bus_slave. In most cases
* this is a 1-1 connection and there is no explicit bus -- just the master
* and slave. However, by attaching the Bus_master to a Single_master_bus
* (which is actually a special form of Bus_slave) and connecting the latter
* to many slaves, a master can talk to multiple slaves based on the addresses
* it emits. A multi-master, multi-slave bus remains to be written.
*
* A Bus_slave may be asked to do the following things:
* read initiate a read request for some # of words
* write initiate a write request for some # of words
* write_part initiate a write request for part of a word
*
* A Single_master_bus may be asked to do any of those and:
* add_slave add a Bus_slave at a particular address range
*/
enum Asi {PROG, DATA}; // address space identifier
enum Access_result {FAULT=-1, OK=0}; // how the access went
typedef Ulong Address; // address
typedef Uchar Byte; // smallest addressible memory unit
typedef Ushort Half;
typedef Uint Word;
// Information common to all access types.
struct Access_info {
Asi asi;
Address addr;
};
// Extra info for a read() or write().
struct Read_write_info : public Access_info {
Word* buff; // ptr to master's buffer
int count; // # of words to read into or write from buffer
};
// Extra info for a write_part().
struct Write_part_info : public Access_info {
Word word; // word containing data to write
Word mask; // mask of bits the slave should affect
};
// Values for write_mask. Index into arrays with low bits of address.
extern const Word word_mask;
extern const Word half_masks[];
extern const Word byte_masks[];
class Bus_tracer;
class Access_status {
Ulong when;
public:
Access_result result;
void set(Ulong delay, Access_result result) {// for callee to set status
this->when = cycle + delay;
this->result = result;
}
Bool done(void) { // returns TRUE when caller may look at status
return cycle == when;
}
friend class Bus_tracer;
};
class Bus_master;
class Bus_slave : public Module {
public:
virtual void read (Read_write_info&, Access_status&) = 0;
virtual void write(Read_write_info&, Access_status&) = 0;
virtual void write_part(Write_part_info&, Access_status&) = 0;
};
class Bus_master : public Module {
public:
Bus_slave* slave;
Bus_master(Bus_slave& slave) {
this->slave = &slave;
}
};
class Single_master_bus : public Bus_slave {
List slaves;
public:
void add_slave(Bus_slave&, Asi, Address mask, Address match);
void read (Read_write_info&, Access_status&);
void write(Read_write_info&, Access_status&);
void write_part(Write_part_info&, Access_status&);
};
class Bus_tracer : public Bus_slave {
const char* label;
std::ostream* out;
Bus_slave* slave;
void trace_status(const char*, Access_status&);
public:
Bus_tracer(Bus_slave& slave, const char* label = _, const char* trace_file = _);
void read (Read_write_info&, Access_status&);
void write(Read_write_info&, Access_status&);
void write_part(Write_part_info&, Access_status&);
};