[1009] | 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: |
---|