1 | /* -*- c++ -*- |
---|
2 | * SOCLIB_LGPL_HEADER_BEGIN |
---|
3 | * |
---|
4 | * This file is part of SoCLib, GNU LGPLv2.1. |
---|
5 | * |
---|
6 | * SoCLib is free software; you can redistribute it and/or modify it |
---|
7 | * under the terms of the GNU Lesser General Public License as published |
---|
8 | * by the Free Software Foundation; version 2.1 of the License. |
---|
9 | * |
---|
10 | * SoCLib is distributed in the hope that it will be useful, but |
---|
11 | * WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
---|
13 | * Lesser General Public License for more details. |
---|
14 | * |
---|
15 | * You should have received a copy of the GNU Lesser General Public |
---|
16 | * License along with SoCLib; if not, write to the Free Software |
---|
17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
---|
18 | * 02110-1301 USA |
---|
19 | * |
---|
20 | * SOCLIB_LGPL_HEADER_END |
---|
21 | * |
---|
22 | * Authors : alain.greiner@lip6.fr |
---|
23 | * Date : july 2010 |
---|
24 | * Copyright: UPMC - LIP6 |
---|
25 | * |
---|
26 | * Modified by: Cesar Fuguet Tortolero |
---|
27 | */ |
---|
28 | |
---|
29 | #include "../include/dspin_packet_generator.h" |
---|
30 | #include <cassert> |
---|
31 | |
---|
32 | namespace soclib { namespace caba { |
---|
33 | |
---|
34 | using namespace soclib::caba; |
---|
35 | using namespace soclib::common; |
---|
36 | |
---|
37 | #define tmpl(x) template<int cmd_width, int rsp_width> x DspinPacketGenerator<cmd_width, rsp_width> |
---|
38 | |
---|
39 | |
---|
40 | ////////////////////////////////////////////////////// |
---|
41 | tmpl(/**/)::DspinPacketGenerator( sc_module_name name, |
---|
42 | const size_t srcid, // srcid for random |
---|
43 | const size_t length, // packet length (flits) |
---|
44 | const size_t load, // requested load * 1000 |
---|
45 | const size_t fifo_depth, // Fifo depth |
---|
46 | const size_t bcp, // broadcast period |
---|
47 | const size_t x_width, |
---|
48 | const size_t y_width, |
---|
49 | const size_t x_size, |
---|
50 | const size_t y_size, |
---|
51 | const size_t max_packets) |
---|
52 | : BaseModule(name), |
---|
53 | |
---|
54 | p_clk( "clk" ), |
---|
55 | p_resetn( "resetn" ), |
---|
56 | p_in( "p_in" ), |
---|
57 | p_out( "p_out" ), |
---|
58 | |
---|
59 | r_cycles( "r_cycles" ), |
---|
60 | |
---|
61 | r_posted_bc_packets( "r_posted_bc_packets" ), |
---|
62 | r_posted_packets( "r_posted_packets" ), |
---|
63 | |
---|
64 | r_send_fsm( "r_send_fsm" ), |
---|
65 | r_send_length( "r_send_length" ), |
---|
66 | r_send_dest( "r_send_dest" ), |
---|
67 | r_send_packets( "r_send_packets" ), |
---|
68 | r_send_bc_packets( "r_send_bc_packets" ), |
---|
69 | |
---|
70 | r_receive_fsm( "r_receive_fsm" ), |
---|
71 | r_receive_packets( "r_receive_packets" ), |
---|
72 | r_receive_latency( "r_receive_latency" ), |
---|
73 | r_receive_bc_packets( "r_receive_bc_packets" ), |
---|
74 | r_receive_bc_latency( "r_receive_bc_latency" ), |
---|
75 | |
---|
76 | r_transaction_fifo( "r_transaction_fifo", fifo_depth ), |
---|
77 | |
---|
78 | m_length( length ), |
---|
79 | m_load( load ), |
---|
80 | m_bcp( bcp ), |
---|
81 | m_srcid( srcid ), |
---|
82 | m_x_width( x_width ), |
---|
83 | m_y_width( y_width ), |
---|
84 | m_x_size( x_size ), |
---|
85 | m_y_size( y_size ), |
---|
86 | m_max_packets( max_packets ) |
---|
87 | { |
---|
88 | assert( (load <= 1000 ) and |
---|
89 | "DSPIN PACKET GENERATOR ERROR: The load should be between 0 and 1000" ); |
---|
90 | |
---|
91 | assert( (cmd_width >= 33) and |
---|
92 | "DSPIN PACKET GENERATOR ERROR: CMD flit width smaller than 33 bits"); |
---|
93 | |
---|
94 | assert( (length > 1 ) and |
---|
95 | "DSPIN PACKET GENERATOR ERROR: Packet length smaller than 2 flits"); |
---|
96 | |
---|
97 | SC_METHOD (transition); |
---|
98 | dont_initialize(); |
---|
99 | sensitive << p_clk.pos(); |
---|
100 | |
---|
101 | SC_METHOD (genMoore); |
---|
102 | dont_initialize(); |
---|
103 | sensitive << p_clk.neg(); |
---|
104 | } // end constructor |
---|
105 | |
---|
106 | //////////////////////// |
---|
107 | tmpl(void)::transition() |
---|
108 | { |
---|
109 | if ( not p_resetn.read() ) |
---|
110 | { |
---|
111 | r_send_fsm = SEND_IDLE; |
---|
112 | r_receive_fsm = RECEIVE_IDLE; |
---|
113 | r_cycles = 0; |
---|
114 | r_posted_date = 0; |
---|
115 | r_posted_packets = 0; |
---|
116 | r_posted_bc_packets = 0; |
---|
117 | r_send_packets = 0; |
---|
118 | r_send_bc_packets = 0; |
---|
119 | r_receive_packets = 0; |
---|
120 | r_receive_latency = 0; |
---|
121 | r_receive_bc_packets = 0; |
---|
122 | r_receive_bc_latency = 0; |
---|
123 | return; |
---|
124 | } |
---|
125 | |
---|
126 | // default values |
---|
127 | bool fifo_put = false; |
---|
128 | bool fifo_get = false; |
---|
129 | |
---|
130 | uint32_t alea = random(); |
---|
131 | |
---|
132 | ///////////////////////// GENERATOR FSM |
---|
133 | size_t bcast_flits = r_posted_bc_packets.read() * 2; |
---|
134 | size_t ucast_flits = r_posted_packets.read() * m_length; |
---|
135 | size_t posted_flits = bcast_flits + ucast_flits; |
---|
136 | size_t accepted_load = posted_flits * 1000 / (r_cycles.read() + 1); |
---|
137 | size_t total_packets = r_posted_bc_packets.read() + r_posted_packets.read(); |
---|
138 | bool is_broadcast = ((m_bcp != 0) && (((total_packets + 1) % m_bcp) == 0)); |
---|
139 | |
---|
140 | if( ((accepted_load + ((alea >> 16) & 0xF)) < m_load) ) |
---|
141 | { |
---|
142 | size_t total_packets = r_posted_packets.read() + r_posted_bc_packets.read(); |
---|
143 | bool max_not_reached = (total_packets < m_max_packets); |
---|
144 | if ( (m_max_packets == 0) || max_not_reached ) |
---|
145 | { |
---|
146 | fifo_put = true ; |
---|
147 | if( r_transaction_fifo.wok() ) |
---|
148 | { |
---|
149 | if (is_broadcast) |
---|
150 | { |
---|
151 | r_posted_bc_packets = r_posted_bc_packets.read() + 1; |
---|
152 | } |
---|
153 | else |
---|
154 | { |
---|
155 | r_posted_packets = r_posted_packets.read() + 1; |
---|
156 | } |
---|
157 | } |
---|
158 | } |
---|
159 | } |
---|
160 | |
---|
161 | /////////////////////////// CMD FSM |
---|
162 | switch( r_send_fsm.read() ) |
---|
163 | { |
---|
164 | case SEND_IDLE: |
---|
165 | if ( r_transaction_fifo.rok() ) |
---|
166 | { |
---|
167 | fifo_get = true; |
---|
168 | r_posted_date = (r_transaction_fifo.read() >> 1); |
---|
169 | |
---|
170 | // broadcast transaction |
---|
171 | if ( (r_transaction_fifo.read() & 1) == 1 ) |
---|
172 | { |
---|
173 | r_send_length = 2; |
---|
174 | r_send_fsm = SEND_BROADCAST; |
---|
175 | r_send_bc_packets = r_send_bc_packets.read() + 1; |
---|
176 | break; |
---|
177 | } |
---|
178 | |
---|
179 | // unicast transaction |
---|
180 | int x_dest = ((alea >> 8) & 0xFF) % m_x_size; |
---|
181 | int y_dest = ((alea ) & 0xFF) % m_y_size; |
---|
182 | |
---|
183 | r_send_length = m_length; |
---|
184 | r_send_fsm = SEND_UNICAST; |
---|
185 | r_send_packets = r_send_packets.read() + 1; |
---|
186 | r_send_dest = (x_dest << m_y_width) | y_dest; |
---|
187 | } |
---|
188 | break; |
---|
189 | case SEND_UNICAST: |
---|
190 | case SEND_BROADCAST: |
---|
191 | if( p_out.read.read() ) |
---|
192 | { |
---|
193 | r_send_length = r_send_length.read() - 1; |
---|
194 | if( r_send_length.read() == 1 ) |
---|
195 | { |
---|
196 | r_send_fsm = SEND_IDLE; |
---|
197 | } |
---|
198 | } |
---|
199 | break; |
---|
200 | } // end SEND FSM |
---|
201 | |
---|
202 | ////////////////////////////// RECEIVE FSM |
---|
203 | switch( r_receive_fsm.read() ) |
---|
204 | { |
---|
205 | case RECEIVE_IDLE: |
---|
206 | if ( p_in.write.read() ) |
---|
207 | { |
---|
208 | if ( ((p_in.data.read() & 1) == 1) ) |
---|
209 | { |
---|
210 | r_receive_fsm = RECEIVE_BROADCAST; |
---|
211 | } |
---|
212 | else |
---|
213 | { |
---|
214 | r_receive_fsm = RECEIVE_UNICAST; |
---|
215 | } |
---|
216 | } |
---|
217 | break; |
---|
218 | case RECEIVE_BROADCAST: |
---|
219 | if ( p_in.write.read() ) |
---|
220 | { |
---|
221 | uint32_t latency = r_cycles.read() - (uint32_t)p_in.data.read(); |
---|
222 | r_receive_bc_packets = r_receive_bc_packets.read() + 1; |
---|
223 | r_receive_bc_latency = r_receive_bc_latency.read() + latency ; |
---|
224 | r_receive_fsm = RECEIVE_IDLE; |
---|
225 | } |
---|
226 | break; |
---|
227 | case RECEIVE_UNICAST: |
---|
228 | if ( p_in.write.read() ) |
---|
229 | { |
---|
230 | uint32_t latency = r_cycles.read() - (uint32_t)p_in.data.read(); |
---|
231 | r_receive_packets = r_receive_packets.read() + 1; |
---|
232 | r_receive_latency = r_receive_latency.read() + latency; |
---|
233 | if ( p_in.eop.read() ) |
---|
234 | { |
---|
235 | r_receive_fsm = RECEIVE_IDLE; |
---|
236 | } |
---|
237 | else |
---|
238 | { |
---|
239 | r_receive_fsm = RECEIVE_WAIT_EOP; |
---|
240 | } |
---|
241 | } |
---|
242 | break; |
---|
243 | case RECEIVE_WAIT_EOP: |
---|
244 | if ( p_in.write.read() and p_in.eop.read() ) |
---|
245 | { |
---|
246 | r_receive_fsm = RECEIVE_IDLE; |
---|
247 | } |
---|
248 | break; |
---|
249 | } // end RECEIVE FSM |
---|
250 | |
---|
251 | // increment date |
---|
252 | r_cycles = r_cycles.read() + 1; |
---|
253 | |
---|
254 | // update fifos |
---|
255 | uint32_t fifo_data = (r_cycles.read() << 1) | (is_broadcast ? 1 : 0); |
---|
256 | r_transaction_fifo.update( fifo_get, fifo_put, fifo_data ); |
---|
257 | |
---|
258 | } // end transition |
---|
259 | |
---|
260 | ////////////////////// |
---|
261 | tmpl(void)::genMoore() |
---|
262 | { |
---|
263 | // p_out |
---|
264 | sc_uint<cmd_width> data = 0; |
---|
265 | bool write = false; |
---|
266 | bool eop = false; |
---|
267 | |
---|
268 | if ( r_send_fsm.read() == SEND_UNICAST ) |
---|
269 | { |
---|
270 | write = true; |
---|
271 | if ( r_send_length.read() == m_length ) // first flit |
---|
272 | { |
---|
273 | sc_uint<cmd_width> dest = r_send_dest.read(); |
---|
274 | data = dest << (cmd_width - m_x_width - m_y_width); |
---|
275 | } |
---|
276 | else if ( r_send_length.read() == (m_length-1) ) // second flit |
---|
277 | { |
---|
278 | data = (sc_uint<cmd_width>)r_posted_date.read(); |
---|
279 | } |
---|
280 | eop = (r_send_length.read() == 1); |
---|
281 | } |
---|
282 | else if ( r_send_fsm.read() == SEND_BROADCAST ) |
---|
283 | { |
---|
284 | write = true; |
---|
285 | if ( r_send_length.read() == 2 ) // first flit |
---|
286 | { |
---|
287 | sc_uint<cmd_width> boundaries = 0x07C1F; |
---|
288 | data = (boundaries << (cmd_width - 20)) | 1; |
---|
289 | } |
---|
290 | else // second flit |
---|
291 | { |
---|
292 | data = (sc_uint<cmd_width>)r_posted_date.read(); |
---|
293 | } |
---|
294 | eop = (r_send_length.read() == 1); |
---|
295 | } |
---|
296 | p_out.data = data; |
---|
297 | p_out.eop = eop; |
---|
298 | p_out.write = write; |
---|
299 | |
---|
300 | p_in.read = true; |
---|
301 | } // end genMoore |
---|
302 | |
---|
303 | ///////////////////////// |
---|
304 | tmpl(void)::print_trace() |
---|
305 | { |
---|
306 | const char* cmd_str[] = { "IDLE", "SEND_UNICAST", "SEND_BROADCAST" }; |
---|
307 | const char* rsp_str[] = { "IDLE", "RECEIVE_UNICAST", "RECEIVE_BROADCAST", "RECEIVE_WAIT" }; |
---|
308 | |
---|
309 | std::cout << "DSPIN_GENERATOR " << name() |
---|
310 | << " : send_fsm = " << cmd_str[r_send_fsm.read()] |
---|
311 | << " / recv_fsm = " << rsp_str[r_receive_fsm.read()] |
---|
312 | << " / fifo_content = " << r_transaction_fifo.filled_status() << std::endl; |
---|
313 | } // end print_trace |
---|
314 | |
---|
315 | ///////////////////////// |
---|
316 | tmpl(void)::print_stats() |
---|
317 | { |
---|
318 | size_t bcast_flits = r_send_bc_packets.read() * 2; |
---|
319 | size_t ucast_flits = r_send_packets.read() * m_length; |
---|
320 | size_t load = (bcast_flits + ucast_flits * 1000) / r_cycles.read(); |
---|
321 | uint32_t latency = r_receive_latency.read() / (r_receive_packets.read() + 1); |
---|
322 | uint32_t bc_latency = r_receive_bc_latency.read() / (r_receive_bc_packets.read() + 1); |
---|
323 | |
---|
324 | std::cout << "DSPIN_GENERATOR " << name() << std::dec |
---|
325 | << "\n - offered load = " << m_load |
---|
326 | << "\n - accepted load = " << load |
---|
327 | << "\n - unicast sent packets = " << r_send_packets.read() |
---|
328 | << "\n - unicast received packets = " << r_receive_packets.read() |
---|
329 | << "\n - unicast latency = " << latency |
---|
330 | << "\n - broadcast sent packets = " << r_send_bc_packets.read() |
---|
331 | << "\n - broadcast received packets = " << r_receive_bc_packets.read() |
---|
332 | << "\n - broadcast latency = " << bc_latency |
---|
333 | << std::endl; |
---|
334 | } // end print_stats |
---|
335 | |
---|
336 | |
---|
337 | }} // end namespaces :w |
---|
338 | |
---|