[998] | 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 | |
---|