Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / verif / model / vendor / TLM-2006-11-29 / tlm / tlm_annotated / tlm_annotated_channels / tlm_peq.h
CommitLineData
86530b38
AT
1
2#ifndef TLM_PEQ_HEADER
3#define TLM_PEQ_HEADER
4
5#include <map>
6
7#include "analysis.h"
8
9using std::multimap;
10using std::pair;
11
12using analysis::delayed_analysis_if;
13using analysis::analysis_port;
14
15//
16// No lt_sctime operator required, since we have operator< defined for
17// sc_time ?
18//
19// struct lt_sc_time {
20// bool operator<( const sc_time &a , const sc_time &b ) {
21// return a < b;
22// }
23// };
24//
25//
26//
27
28//
29// This peq implements a delayed write and has an analysis port
30//
31// If you post many transactions to the same time slot, this will result in
32// many transactions coming out of the analysis port in a single delta
33//
34// If you want event driven semantics, stuff the output of the analysis port
35// into an analysis fifo ( if you want to guarantee no losses ) or
36// analysis buffer ( if you don't mind losses but you can't be bothered or are
37// not able to clear the fifo out ).
38//
39// For example, you can arrive at a blocking get interface by doing get on
40// an analysis fifo attached to the analysis port shown below
41//
42// We could even design a tlm_peq_fifo and/or tlm_peq_buffer with these
43// channels built in
44//
45
46template< typename T>
47class tlm_peq :
48 public sc_module ,
49 public virtual delayed_analysis_if< T >
50{
51 public:
52 sc_export< delayed_analysis_if< T > > delayed_analysis_export;
53 analysis_port< T > ap;
54
55 SC_HAS_PROCESS( tlm_peq );
56
57 tlm_peq( sc_module_name nm ) : sc_module( nm ) , ap("ap") {
58
59 delayed_analysis_export( *this );
60
61 SC_METHOD( wake_up_method );
62 dont_initialize();
63 sensitive << m_wake_up;
64
65 }
66
67 int size() const { return m_map.size(); }
68
69 int posted_before( const sc_time &time ) const {
70
71 int i = 0;
72
73 for( typename multimap< sc_time , T>::const_iterator iter = m_map.begin();
74 iter != m_map.end();
75 ++iter ) {
76
77 if( (*iter).first < time ) {
78 i++;
79 }
80
81 }
82
83 return i;
84
85 }
86
87 int posted_at( const sc_time &time ) const {
88 return m_map.count( time );
89 }
90
91 void write( const T &transaction , const sc_time &time ) {
92
93 m_map.insert( pair_type( time + sc_time_stamp() , transaction ) );
94 m_wake_up.notify( time );
95
96 }
97
98 private:
99 typedef pair<sc_time,T> pair_type;
100
101 void wake_up_method() {
102
103 pair_type p;
104 sc_time now = sc_time_stamp();
105
106 // must be something there, and it must be scheduled for now
107
108 assert( m_map.size() > 0 );
109 assert( (*(m_map.begin())).first == now );
110
111 for( p = *(m_map.begin());
112 p.first == now;
113 p = *(m_map.begin()) )
114 {
115
116 ap.write( p.second );
117 m_map.erase( m_map.begin() );
118
119 if( m_map.size() == 0 ) {
120 return;
121 }
122
123 p = *(m_map.begin());
124
125 }
126
127 m_wake_up.notify( p.first - now );
128
129 }
130
131 sc_event m_wake_up;
132 multimap< sc_time , T> m_map;
133
134};
135
136#endif