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 Armando Fuguet Tortolero |
---|
27 | * Date : july 2015 |
---|
28 | */ |
---|
29 | |
---|
30 | #include "../include/dspin_broadcast_generator.h" |
---|
31 | #include <cassert> |
---|
32 | |
---|
33 | namespace soclib { namespace caba { |
---|
34 | |
---|
35 | using namespace soclib::caba; |
---|
36 | using namespace soclib::common; |
---|
37 | |
---|
38 | #define tmpl(x) template<int cmd_width, int rsp_width> x \ |
---|
39 | DspinBroadcastGenerator<cmd_width, rsp_width> |
---|
40 | |
---|
41 | |
---|
42 | ////////////////////////////////////////////////////// |
---|
43 | tmpl(/**/)::DspinBroadcastGenerator( sc_module_name name, |
---|
44 | const size_t x_size, |
---|
45 | const size_t y_size, |
---|
46 | const size_t srcid, // srcid for random |
---|
47 | const size_t load, // requested load * 1000 |
---|
48 | const size_t fifo_depth) // Fifo depth |
---|
49 | : BaseModule(name), |
---|
50 | |
---|
51 | p_clk( "clk" ), |
---|
52 | p_resetn( "resetn" ), |
---|
53 | p_in( "p_in" ), |
---|
54 | p_out( "p_out" ), |
---|
55 | |
---|
56 | r_cycles( "r_cycles" ), |
---|
57 | r_fifo_posted( "r_fifo_posted" ), |
---|
58 | |
---|
59 | r_send_fsm( "r_send_fsm" ), |
---|
60 | r_send_length( "r_send_length" ), |
---|
61 | r_send_dest( "r_send_dest" ), |
---|
62 | r_send_date( "r_send_date" ), |
---|
63 | r_send_bc_packets( "r_send_bc_packets" ), |
---|
64 | |
---|
65 | r_receive_fsm( "r_receive_fsm" ), |
---|
66 | r_receive_bc_packets( "r_receive_bc_packets" ), |
---|
67 | r_receive_bc_latency( "r_receive_bc_latency" ), |
---|
68 | r_receive_bc_max_latency( "r_receive_bc_max_latency" ), |
---|
69 | |
---|
70 | r_max_fill_status( "r_max_fill_status" ), |
---|
71 | |
---|
72 | r_date_fifo( "r_date_fifo", fifo_depth ), |
---|
73 | |
---|
74 | m_x_size ( x_size ), |
---|
75 | m_y_size ( y_size ), |
---|
76 | m_load( load ), |
---|
77 | m_srcid( srcid ) |
---|
78 | { |
---|
79 | assert( (load <= 1000 ) and |
---|
80 | "DSPIN PACKET GENERATOR ERROR: The load should be between 0 and 1000" ); |
---|
81 | |
---|
82 | assert( (cmd_width >= 33) and |
---|
83 | "DSPIN PACKET GENERATOR ERROR: CMD flit width smaller than 33 bits"); |
---|
84 | |
---|
85 | SC_METHOD (transition); |
---|
86 | dont_initialize(); |
---|
87 | sensitive << p_clk.pos(); |
---|
88 | |
---|
89 | SC_METHOD (genMoore); |
---|
90 | dont_initialize(); |
---|
91 | sensitive << p_clk.neg(); |
---|
92 | } // end constructor |
---|
93 | |
---|
94 | //////////////////////// |
---|
95 | tmpl(void)::transition() |
---|
96 | { |
---|
97 | if ( not p_resetn.read() ) |
---|
98 | { |
---|
99 | r_send_fsm = SEND_IDLE; |
---|
100 | r_receive_fsm = RECEIVE_IDLE; |
---|
101 | r_cycles = 0; |
---|
102 | r_fifo_posted = 0; |
---|
103 | r_send_bc_packets = 0; |
---|
104 | r_receive_bc_packets = 0; |
---|
105 | r_receive_bc_latency = 0; |
---|
106 | r_receive_bc_max_latency = 0; |
---|
107 | r_max_fill_status = 0; |
---|
108 | srandom( m_srcid + cmd_width ); |
---|
109 | return; |
---|
110 | } |
---|
111 | |
---|
112 | // default values |
---|
113 | bool fifo_put = false; |
---|
114 | bool fifo_get = false; |
---|
115 | |
---|
116 | uint32_t alea = random(); |
---|
117 | |
---|
118 | ///////////////////////// GENERATOR FSM |
---|
119 | const size_t nflits = r_fifo_posted.read() * m_x_size * m_y_size * 2; |
---|
120 | size_t accepted_load = (nflits * 1000) / (r_cycles.read() + 1); |
---|
121 | |
---|
122 | if( (accepted_load + (alea>>16 & 0xF)) < (m_load) ) |
---|
123 | { |
---|
124 | fifo_put = true ; |
---|
125 | if( r_date_fifo.wok() ) r_fifo_posted = r_fifo_posted.read() + 1; |
---|
126 | } |
---|
127 | |
---|
128 | /////////////////////////// CMD FSM |
---|
129 | switch( r_send_fsm.read() ) |
---|
130 | { |
---|
131 | case SEND_IDLE: |
---|
132 | if ( r_date_fifo.rok() ) |
---|
133 | { |
---|
134 | fifo_get = true; |
---|
135 | |
---|
136 | r_send_length = 2; |
---|
137 | r_send_date = r_date_fifo.read(); |
---|
138 | r_send_bc_packets = r_send_bc_packets.read() + 1; |
---|
139 | r_send_fsm = SEND_BROADCAST; |
---|
140 | } |
---|
141 | break; |
---|
142 | case SEND_BROADCAST: |
---|
143 | if( p_out.read.read() ) |
---|
144 | { |
---|
145 | r_send_length = r_send_length.read() - 1; |
---|
146 | if( r_send_length.read() == 1 ) r_send_fsm = SEND_IDLE; |
---|
147 | } |
---|
148 | break; |
---|
149 | } // end SEND FSM |
---|
150 | |
---|
151 | ////////////////////////////// RECEIVE FSM |
---|
152 | switch( r_receive_fsm.read() ) { |
---|
153 | case RECEIVE_IDLE: |
---|
154 | if ( p_in.write.read() ) { |
---|
155 | assert (p_in.data.read() & sc_uint<rsp_width>(1)); |
---|
156 | r_receive_fsm = RECEIVE_BROADCAST; |
---|
157 | } |
---|
158 | break; |
---|
159 | case RECEIVE_BROADCAST: |
---|
160 | if ( p_in.write.read() ) { |
---|
161 | uint32_t latency = r_cycles.read() - (uint32_t)p_in.data.read(); |
---|
162 | r_receive_bc_packets = r_receive_bc_packets.read() + 1; |
---|
163 | r_receive_bc_latency = r_receive_bc_latency.read() + latency; |
---|
164 | if (latency > r_receive_bc_max_latency.read()) |
---|
165 | r_receive_bc_max_latency = latency; |
---|
166 | |
---|
167 | r_receive_fsm = RECEIVE_IDLE; |
---|
168 | } |
---|
169 | break; |
---|
170 | } // `end RECEIVE FSM |
---|
171 | |
---|
172 | // increment date |
---|
173 | r_cycles = r_cycles.read() + 1; |
---|
174 | |
---|
175 | // update fifos |
---|
176 | r_date_fifo.update( fifo_get, fifo_put, r_cycles.read() ); |
---|
177 | |
---|
178 | if (r_date_fifo.filled_status() > r_max_fill_status.read()) |
---|
179 | r_max_fill_status.write(r_date_fifo.filled_status()); |
---|
180 | |
---|
181 | } // end transition |
---|
182 | |
---|
183 | ////////////////////// |
---|
184 | tmpl(void)::genMoore() |
---|
185 | { |
---|
186 | // p_out |
---|
187 | sc_uint<cmd_width> data; |
---|
188 | bool write; |
---|
189 | bool eop; |
---|
190 | |
---|
191 | if ( r_send_fsm.read() == SEND_IDLE ) { |
---|
192 | data = 0; |
---|
193 | eop = false; |
---|
194 | write = false; |
---|
195 | } |
---|
196 | else { // SEND_BROADCAST (two flits) |
---|
197 | write = true; |
---|
198 | if ( r_send_length.read() == 2 ) { // first flit |
---|
199 | data = sc_uint<cmd_width>(0x07C1F) << (cmd_width - 20) | |
---|
200 | sc_uint<cmd_width>(1); |
---|
201 | eop = false; |
---|
202 | } |
---|
203 | else { // second flit |
---|
204 | data = (sc_uint<cmd_width>)r_send_date.read() | |
---|
205 | (sc_uint<cmd_width>(1)<<(cmd_width-1)); |
---|
206 | eop = true; |
---|
207 | } |
---|
208 | } |
---|
209 | p_out.data = data; |
---|
210 | p_out.eop = eop; |
---|
211 | p_out.write = write; |
---|
212 | |
---|
213 | p_in.read = true; |
---|
214 | |
---|
215 | } // end genMoore |
---|
216 | |
---|
217 | ///////////////////////// |
---|
218 | tmpl(void)::print_trace() |
---|
219 | { |
---|
220 | const char* cmd_str[] = { "IDLE", "SEND_BROADCAST" }; |
---|
221 | const char* rsp_str[] = { "IDLE", "RECEIVE_BROADCAST" }; |
---|
222 | |
---|
223 | std::cout << "DSPIN_GENERATOR " << name() |
---|
224 | << " : send_fsm = " << cmd_str[r_send_fsm.read()] |
---|
225 | << " / recv_fsm = " << rsp_str[r_receive_fsm.read()] |
---|
226 | << " / fifo_content = " << r_date_fifo.filled_status() << std::endl; |
---|
227 | } // end print_trace |
---|
228 | |
---|
229 | ///////////////////////// |
---|
230 | tmpl(void)::print_stats() |
---|
231 | { |
---|
232 | const size_t nflits = r_send_bc_packets.read() * m_x_size * m_y_size * 2; |
---|
233 | const size_t load = (nflits * 1000) / r_cycles.read(); |
---|
234 | const uint32_t bc_latency = r_receive_bc_latency.read() / (r_receive_bc_packets.read() + 1); |
---|
235 | |
---|
236 | std::cout << "DSPIN_GENERATOR " << name() << std::dec << std::endl |
---|
237 | << " - broadcast sent packets = " << r_send_bc_packets.read() << std::endl |
---|
238 | << " - offered load = " << m_load << std::endl |
---|
239 | << " - accepted load = " << load << std::endl |
---|
240 | << " - fifo max fill status = " << r_max_fill_status.read() << std::endl |
---|
241 | << " - broadcast received packets = " << r_receive_bc_packets.read() << std::endl |
---|
242 | << " - broadcast latency = " << bc_latency << std::endl |
---|
243 | << " - broadcast max latency = " << r_receive_bc_max_latency.read() << std::endl; |
---|
244 | } // end print_stats |
---|
245 | |
---|
246 | |
---|
247 | }} // end namespaces |
---|
248 | |
---|
249 | // Local Variables: |
---|
250 | // tab-width: 4 |
---|
251 | // c-basic-offset: 4 |
---|
252 | // c-file-offsets:((innamespace . 0)(inline-open . 0)) |
---|
253 | // indent-tabs-mode: nil |
---|
254 | // End: |
---|