//read from channel void read( ){ int j; next_trigger(10, SC_NS, write_event_1 | write_event_2); j = data; cout <<"simulation time" << ":" << sc_time_stamp(); cout<<" reading "<<j<<" from channel" << endl; }
void Wishbone2TLM::transact() { wb_ack_o = false; wb_rty_o = false; wb_err_o = false; if (rst) { return; } switch (m_state) { case IDLE: wb_ack_o = false; if (wb_stb_i && wb_cyc_i) { m_payload.set_address(wb_adr_i); if (wb_we_i) { cout << "Write" << endl; m_payload.set_command(tlm::TLM_WRITE_COMMAND); m_data = wb_dat_i; } else { cout << "Read" << endl; m_payload.set_command(tlm::TLM_READ_COMMAND); } m_byte_enable = wb_sel_i & 0xf; tlm_socket->nb_transport_fw(m_payload,m_phase,m_delay); m_state = WAIT; next_trigger(m_done_event); } else { next_trigger(clk.negedge_event()); } break; case WAIT: wb_dat_o = m_data; wb_ack_o = true; if (clk.negedge()) { next_trigger(clk.negedge_event()); m_state = IDLE; } else { next_trigger(clk.negedge_event()); m_state = WAIT; } break; default: throw "Cannot happen"; break; } }
void receiver() { next_trigger( e ); if( receiver_first ) { receiver_first = false; return; } write( "receiver" ); }
void dynamic_method() { static int state = 0; switch ( state ) { case 0: next_trigger( m_clk.posedge_event() ); cout << sc_time_stamp() << ": dynamic method (" << __LINE__ << "," << state << ") initialization call " << endl; state = 1; break; default: case 1: next_trigger( m_event1 & m_event2 ); cout << sc_time_stamp() << ": dynamic method (" << __LINE__ << "," << state << ") after wait on m_clk.posedge() " << endl; break; } }
//write to channel void write(){ static int i = 0; next_trigger(10, SC_NS); data = i; cout <<"simulation time" << ":" << sc_time_stamp()<<" "; cout<<"writting "<< data <<" to channel" << endl; if(i < 3){ write_event_1.notify(20, SC_NS); } else if(3 <= i && i < 6) { write_event_1.notify(5, SC_NS); } else{ write_event_2.notify(6, SC_NS); } i++; }
void dynamic_method() { static int state = 0; switch ( state ) { case 0: m_dynamic_method = sc_get_current_process_handle(); next_trigger( m_clk.posedge_event() ); cout << sc_time_stamp() << ": dynamic method (" << __LINE__ << "," << state << ") initialization call " << endl; break; case 1: next_trigger( m_clk.posedge_event() ); cout << sc_time_stamp() << ": dynamic method (" << __LINE__ << "," << state << ") after wait on m_clk.posedge_event() " << endl; break; case 2: next_trigger( m_clk.negedge_event() ); cout << sc_time_stamp() << ": dynamic method (" << __LINE__ << "," << state << ") after wait on m_clk.posedge_event() " << endl; break; case 3: next_trigger( m_event1 & m_event2 ); cout << sc_time_stamp() << ": dynamic method (" << __LINE__ << "," << state << ") after wait on m_clk.negedge() " << endl; break; case 4: next_trigger( m_clk.posedge_event() ); cout << sc_time_stamp() << ": dynamic method (" << __LINE__ << "," << state << ") after wait on m_event1 & m_event2 " << endl; break; default: next_trigger( m_clk.posedge_event() ); cout << sc_time_stamp() << ": dynamic method (" << __LINE__ << "," << state << ") after wait on m_clk.posedge_event() " << endl; break; } state = state + 1; if ( state == 5 ) state = 1; }
int sc_main (int argc, char *argv[]) { sc_signal<bool> clk, reset, clear; wait(); wait (clk.posedge_event()); wait (reset.negedge_event()); // negedge_event() and posedge_event() methods can // be applied to a signal or a port to identify the // specific event. wait (clk.posedge_event() | reset.negedge_event() | clear.value_changed_event()); // A value_changed_event() method is true when any // value change occu sc_signal<sc_uint<4> > ready; sc_signal<bool> data; wait (clk.value_changed_event() & data.posedge_event() & ready.value_changed_event()); // The events can span over multiple simulation // cycles. For example, if clk changes at 5ns, // a positive edge on data occurs at 8ns and ready // changes at 10ns, then the wait is triggered at // time 10ns. wait (20, SC_NS); // does NOT work with sc_bit or sc_logic: sc_signal<bool> speed_ctrl; wait (10, SC_NS, speed_ctrl.posedge_event()); // Waits for positive edge to occur on speed_ctrl // for 10ns and then times out. wait (SC_ZERO_TIME); wait (0, SC_NS); sc_signal<sc_logic> sac; // sc_in<sc_logic> sync_reset; sc_signal<sc_logic> sync_reset; wait (sac.posedge_event()); wait (sync_reset.negedge_event()); sc_event write_back; // sensitive << write_back; wait (write_back); write_back.notify(); write_back.notify (20, SC_NS); write_back.notify(SC_ZERO_TIME); // Trigger event in next delta cycle. write_back.cancel(); // Cancels a delayed notification. sc_out<bool> out_port; out_port.initialize(0); sc_time t_res; t_res = sc_get_time_resolution(); cout << "The time resolution is " << sc_get_time_resolution() << endl; double time_in_dbl; sc_time time_res = sc_get_time_resolution(); sc_time curr_time = sc_time_stamp(); time_in_dbl = curr_time / time_res; cout << "Time as a double value is " << time_in_dbl << endl; time_in_dbl = sc_simulation_time(); cout << "Time is " << time_in_dbl; sc_set_default_time_unit (100, SC_PS); sc_time t_unit (10, SC_NS); // NOT WORKING: // sc_set_default_time_unit (t_unit); sc_set_default_time_unit (100, SC_PS); sc_time tf_unit; tf_unit = sc_get_default_time_unit(); // Wake up SC_METHOD process after 10ns: next_trigger (10, SC_NS); // Wake up SC_METHOD process on a rising edge // of reset: next_trigger (reset.posedge_event()); return 0; }
void CM_LSU::lsu_tx_method(void ) { ////cout<<"CM_LSU::"<<__func__<<" : "<<__LINE__<<endl; cout<<dec; LSU_STATE st = IDLE; LSU_STATE first_st =IDLE,second_st =IDLE; int i=3; // while (i!=0) { switch (st) { case IDLE: { //l2 side if(ce_to_dir_l2 == true || ex_to_dir_l2 == true || cl_evt_info_to_dir_l2 == true || flush_ack_to_dir_l2 == true) { st = L2CEEXEVT; //cout<<"CM_LSU::"<<__func__<<" : "<< __LINE__<<endl; first_st = L2CEEXEVT; } else if(address_to_l3_en_l2 == true){ st = L2DATA_TO_L3MEM; //cout<<"CM_LSU::"<<__func__<<" : "<< __LINE__<<" addr:"<<hex<< address_to_l3_l2<<dec<<endl; first_st = L2DATA_TO_L3MEM; } //dir side if(inv_to_node_dir == true) { //cout<<"CM_LSU::"<<__func__<<" : "<< __LINE__<<endl; if (first_st != IDLE) second_st = DIRINV; else { first_st = DIRINV; st = DIRINV; } } else if(ack_to_node_dir == true) { //cout<<"CM_LSU::"<<__func__<<" : "<< __LINE__<<endl; if (first_st != IDLE) second_st = DIRACK; else { first_st = DIRACK; st = DIRACK; } } else if(ce_to_l3_dir == true) { //cout<<"CM_LSU::"<<__func__<<" : "<< __LINE__<<endl; if (first_st != IDLE) second_st = DIRCE_TO_L3MEM; else { first_st = DIRCE_TO_L3MEM; st = DIRCE_TO_L3MEM; } } if(first_st == IDLE && second_st == IDLE) { st = IDLE; //wait(); } } break; // check or find node address and see if that belongs to local node. case L2CEEXEVT: { //cout<<"CM_LSU::"<<__func__<<" : "<< __LINE__<<endl; //decode address to destination node unsigned int cl_address = address_to_dir_l2>>(OFFSET_LENGTH); unsigned int dst_node = ((unsigned int)cl_address )&( (unsigned int)(NO_OF_NODES-1)); /*0x11 & address will give the dst dir bank address*/ if(dst_node == inode) { local_l2_st = st; local_l2P.en = ce_to_dir_l2; local_l2P.ex = ex_to_dir_l2; local_l2P.rw = rd_wr_to_dir_l2; local_l2P.evt = cl_evt_info_to_dir_l2; local_l2P.ack = flush_ack_to_dir_l2; local_l2P.address = address_to_dir_l2; local_l2P.srcnode = inode; local_l2P.dstnode = dst_node; local_l2P.type = st; local_l2P.req_count = req_count_to_dir_l2; l2_e.notify(); } else { //make packet and put in the queue NoCCommPacket pkt; pkt.en = ce_to_dir_l2; pkt.ex = ex_to_dir_l2; pkt.rw = rd_wr_to_dir_l2; pkt.evt = cl_evt_info_to_dir_l2; pkt.ack = flush_ack_to_dir_l2; pkt.address = address_to_dir_l2; pkt.req_count = req_count_to_dir_l2; pkt.srcnode = inode; pkt.dstnode = dst_node; pkt.type = st; NoCtxQ.push(pkt); } first_st = IDLE; st = second_st; if(second_st == IDLE) {//wait(); st = IDLE; i = 1; next_trigger(1, SC_NS); } }break; case L2DATA_TO_L3MEM: { //cout<<"CM_LSU::"<<__func__<<" : "<< __LINE__<<" address:0x"<< hex<<address_to_l3_l2<<dec <<endl; //decode address to destination node unsigned int cl_address = address_to_l3_l2>>(OFFSET_LENGTH); unsigned int dst_node , dnode = ((unsigned int)cl_address )&( (unsigned int)(NO_OF_NODES-1)); #ifdef L3_TRUE_1 if(((cl_address >> NO_OF_NODES_2) & 0x01) == 0) // 7 = 5(offset) + 2(inode) { dst_node = dnode;//cout<<"1"<<endl; } else { if((dnode & 0x01) == 0x0) { dst_node = dnode+1;//cout<<"2"<<endl; } else { dst_node = dnode-1;//cout<<"3"<<endl; } } #else #ifdef L3_TRUE_0 dst_node = dnode; #else dst_node = NODE_WITH_SDRAM; #endif #endif //cout<<"dst_node: L2data to L3mem: "<<dst_node<<" dnode:"<<dnode<<" address:0x"<< hex<<address_to_l3_l2<<dec <<endl; if(dst_node == inode) { local_l2_st = st; (data_to_l3_l2)->read_data(&local_l2P.data); local_l2P.address = address_to_l3_l2; local_l2P.req_count = req_count_to_l3_l2; local_l2P.en = address_to_l3_en_l2; local_l2P.srcnode = inode; local_l2P.dstnode = dst_node; local_l2P.type = st; local_l2P.rw = true; cout<<"error !! as l2 and mem cant be in the same node"<<endl; //l2_e.notify(); } else { //make packet and put in the queue NoCCommPacket pkt; (data_to_l3_l2)->read_data(&pkt.data); pkt.address = address_to_l3_l2; pkt.req_count = req_count_to_l3_l2; pkt.en = address_to_l3_en_l2; pkt.rw = true; pkt.srcnode = inode; pkt.dstnode = dst_node; pkt.type = st; NoCtxQ.push(pkt); } first_st = IDLE; st = second_st; if(second_st == IDLE) { st = IDLE; i = 1; next_trigger(1, SC_NS); } }break; case DIRINV: { //cout<<"CM_LSU::"<<__func__<<" : "<< __LINE__<<endl; if(nodeaddr_to_lru_dir == inode) { local_dir_st = st; local_dirP.inv = inv_to_node_dir; local_dirP.address = inv_addr_to_node_dir; local_dirP.req_count = req_count_from_dir_dir; local_dirP.srcnode = inode; local_dirP.dstnode = nodeaddr_to_lru_dir; local_dirP.type = st; dir_e.notify(); } else { //make packet and put in the queue NoCCommPacket pkt; pkt.inv = inv_to_node_dir; pkt.address = inv_addr_to_node_dir; pkt.req_count = req_count_from_dir_dir; pkt.srcnode = inode; pkt.dstnode = nodeaddr_to_lru_dir; pkt.type = st; NoCtxQ.push(pkt); } if ( first_st == st) first_st = IDLE; else second_st = IDLE; st = IDLE; i = 1; next_trigger(1, SC_NS); }break; case DIRACK: { //cout<<"CM_LSU::"<<__func__<<" : "<< __LINE__<<endl; if(nodeaddr_to_lru_dir == inode) { // local transfer local_dir_st = st; local_dirP.ack = ack_to_node_dir; local_dirP.address = address_from_dir_dir; local_dirP.req_count = req_count_from_dir_dir; local_dirP.srcnode = inode; local_dirP.dstnode = nodeaddr_to_lru_dir; local_dirP.type = st; dir_e.notify(); } else { //make packet and put in the queue NoCCommPacket pkt; pkt.ack = ack_to_node_dir; pkt.req_count = req_count_from_dir_dir; pkt.address = address_from_dir_dir; pkt.srcnode = inode; pkt.dstnode = nodeaddr_to_lru_dir; pkt.type = st; NoCtxQ.push(pkt); } if ( first_st == st) first_st = IDLE; else second_st = IDLE; st = IDLE; i = 1; next_trigger(1, SC_NS); }break; case DIRCE_TO_L3MEM: { //cout<<"CM_LSU::"<<__func__<<" : "<< __LINE__<< "from dir to l3:" <<nodeaddr_to_lru_dir <<dec <<endl; if(nodeaddr_to_lru_dir == inode) { // local transfer this can be filled in only once we have L3 or mem added to the lsu local_dir_st = st; cout<<"Error CMLSU doesnt have memory"<<endl; dir_e.notify(); } else { //make packet and put in the queue NoCCommPacket pkt; pkt.en = ce_to_l3_dir; pkt.rw = rd_wr_to_l3_dir; pkt.req_count = req_count_to_l3_dir; pkt.address = addr_to_l3_dir; pkt.srcnode = inode; pkt.dstnode = nodeaddr_to_lru_dir; pkt.redirectionnode = dst_nodeaddr_to_l3_dir; pkt.type = st; NoCtxQ.push(pkt); // wait(); } if ( first_st == st) first_st = IDLE; else second_st = IDLE; st = IDLE; next_trigger(1, SC_NS); } break; default: cout<<"ERROR: "<<st; cout<<"CM_LSU::"<<__func__<<" : "<< __LINE__<<endl; // wait(); } i--; }
void MEM_LSU::lsu_tx_method(void ) { ////cout<<"MEM_LSU::"<<__func__<<" : "<< __LINE__<<endl; //cout<<dec; LSU_STATE st = IDLE; LSU_STATE first_st =IDLE,second_st =IDLE; int i=3; // while (i!=0) { switch (st) { case IDLE: { //mem side if(ack_from_dir_mem == true) { st = MEMDIRACK; //cout<<"MEM_LSU::"<<__func__<<" : "<< __LINE__<<endl; first_st = MEMDIRACK; } else if(ack_to_l2_mem == true) { st = MEML2ACK; //cout<<"MEM_LSU::"<<__func__<<" : "<< __LINE__<<endl; first_st = MEML2ACK; } //dir side if((inv_to_node_dir == true) || (flush_frm_npc_dir == true)) { //cout<<"MEM_LSU::"<<__func__<<" : "<< __LINE__<<endl; if (first_st != IDLE) second_st = DIRINV; else { first_st = DIRINV; st = DIRINV; } } else if(ack_to_node_dir == true) { //cout<<"MEM_LSU::"<<__func__<<" : "<< __LINE__<<endl; if (first_st != IDLE) second_st = DIRACK; else { first_st = DIRACK; st = DIRACK; } } else if(ce_to_l3_dir == true) { //cout<<"MEM_LSU::"<<__func__<<" : "<< __LINE__<<endl; if (first_st != IDLE) second_st = DIRCE_TO_L3MEM; else { first_st = DIRCE_TO_L3MEM; st = DIRCE_TO_L3MEM; } } if(first_st == IDLE && second_st == IDLE) { st = IDLE; } } break; // check or find node address and see if that belongs to local node. case MEMDIRACK: { //cout<<"MEM_LSU::"<<__func__<<" : "<< __LINE__<<" "<<node_address_to_lru_mem<<" address:0x"<<hex<<addr_to_dir_mem<<dec<<endl; int dst_node = node_address_to_lru_mem; /*0x11 & address will give the dst dir bank address*/ if(dst_node == inode) { // local transfer NoCCommPacket local_memP; local_memP.ack = ack_from_dir_mem; local_memP.srcnode = inode; local_memP.dstnode = dst_node; local_memP.address = addr_to_dir_mem; local_memP.req_count = req_count_to_dir_mem; local_memP.type = st; local_dirQ.push(local_memP); } else { //make packet and put in the queue LisNocPacket packet; double now = (int) (sc_time_stamp().to_double() / 1000); packet.make(inode, 0, now, 1); packet.type = st; packet.req_count = req_count_to_dir_mem; packet.src_id = inode; packet.ack = ack_from_dir_mem; packet.dst_id = dst_node; packet.size = 2; packet.address.push_back(addr_to_dir_mem); packet.flit_left = packet.size; NoCtxQ->push(packet); txQ_ready->notify(SC_ZERO_TIME); } first_st = IDLE; st = second_st; if(st == IDLE) next_trigger(1,SC_NS); } break; case MEML2ACK: { //cout<<"MEM_LSU::"<<__func__<<" : "<< __LINE__<<" "<<node_address_to_lru_mem<<endl; int dst_node = node_address_to_lru_mem; /*0x11 & address will give the dst dir bank address*/ if(dst_node == inode) { // local transfer cout<<"MEM_LSU::"<<inode<<", "<<__func__<<" : "<< __LINE__<<"Error memory node doesnt contain l2" << endl; } else { //make packet and put in the queue LisNocPacket packet; double now = (int) (sc_time_stamp().to_double() / 1000); packet.make(inode, 0, now, 1); datatype temp; data_to_l2_mem->read_data(&temp); packet.type = st; packet.req_count = req_count_to_l2_mem; packet.src_id = inode; packet.ack = ack_to_l2_mem; packet.address.push_back(address_to_l2_mem); packet.dst_id = dst_node; packet.read_or_write = ack_rw_to_l2_mem; if (packet.read_or_write == false) { for (int i=0; i<CL_SIZE_WORDWISE; i++) packet.data.push_back(temp.data[i]); //packet.size = 10; //TODO: if packet size > 31 flits then split the data into 2 packets and push them into NoCtxQ seperately ensuring each // contains upto 31 flits at max packet.size = CL_SIZE_WORDWISE+2; } else packet.size = 2; packet.flit_left = packet.size; NoCtxQ->push(packet); txQ_ready->notify(SC_ZERO_TIME); //cout<<"MEM_LSU::"<<__func__<<" : "<< __LINE__<<" pushed the packet with data[0]: "<<pkt.data.data[0]<<endl; } first_st = IDLE; st = second_st; if(st == IDLE) next_trigger(1,SC_NS); } break; case DIRINV: { //cout<<"MEM_LSU::"<<__func__<<" : "<< __LINE__<<" DIRINV sending to l2:"<< nodeaddr_to_lru_dir <<endl; if(nodeaddr_to_lru_dir == inode) { // local transfer cout<<"MEM_LSU::"<<inode<<", "<<__func__<<" : "<< __LINE__<<"error!! "<<endl; } else { //make packet and put in the queue LisNocPacket packet; double now = (int) (sc_time_stamp().to_double() / 1000); packet.make(inode, 0, now, 1); packet.type = st; packet.req_count = req_count_from_dir_dir; packet.src_id = inode; if ((flush_frm_npc_dir == true) && (inv_to_node_dir == false)) { packet.inv = true; packet.evt = false; } else if ((flush_frm_npc_dir == false) && (inv_to_node_dir == true)) { packet.evt = true; packet.inv = true; } packet.address.push_back(inv_addr_to_node_dir); packet.dst_id = nodeaddr_to_lru_dir; packet.size = 2; packet.flit_left = packet.size; NoCtxQ->push(packet); txQ_ready->notify(SC_ZERO_TIME); } if ( first_st == st) first_st = IDLE; else second_st = IDLE; st = IDLE; next_trigger(1,SC_NS); } break; case DIRACK: { //cout<<"MEM_LSU::"<<__func__<<" : "<< __LINE__<<endl; if(nodeaddr_to_lru_dir == inode) { cout<<"MEM_LSU::"<<inode<<", "<<__func__<<" : "<< __LINE__<<"error!! "<<endl; } else { //make packet and put in the queue LisNocPacket packet; double now = (int) (sc_time_stamp().to_double() / 1000); packet.make(inode, 0, now, 1); packet.type = st; packet.req_count = req_count_from_dir_dir; packet.src_id = inode; packet.ack = ack_to_node_dir; packet.evt = false; packet.address.push_back(address_from_dir_dir); packet.dst_id = nodeaddr_to_lru_dir; packet.size = 2; packet.flit_left = packet.size; NoCtxQ->push(packet); txQ_ready->notify(SC_ZERO_TIME); } if ( first_st == st) first_st = IDLE; else second_st = IDLE; st = IDLE; next_trigger(1,SC_NS); } break; case DIRCE_TO_L3MEM: { //cout<<"MEM_LSU::"<<inode<<", "<<__func__<<" : "<< __LINE__<<endl; if(nodeaddr_to_lru_dir == inode) { NoCCommPacket local_dirP ; local_dirP.en = ce_to_l3_dir; local_dirP.ex = false; local_dirP.rw = rd_wr_to_l3_dir; local_dirP.address = addr_to_l3_dir; local_dirP.req_count = req_count_to_l3_dir; local_dirP.srcnode = inode; local_dirP.dstnode = nodeaddr_to_lru_dir; local_dirP.redirectionnode = dst_nodeaddr_to_l3_dir; local_dirP.type = st; local_memQ.push(local_dirP); } else { //make packet and put in the queue LisNocPacket packet; double now = (int) (sc_time_stamp().to_double() / 1000); packet.make(inode, 0, now, 1); packet.type = st; packet.req_count = req_count_to_l3_dir; packet.src_id = inode; packet.read_or_write = rd_wr_to_l3_dir; packet.burst = 0; packet.offset = 0; packet.address.push_back(addr_to_l3_dir); packet.ex = false; packet.en = ce_to_l3_dir; packet.redirectionnode = dst_nodeaddr_to_l3_dir; packet.dst_id = nodeaddr_to_lru_dir; packet.size = 2; packet.flit_left = packet.size; NoCtxQ->push(packet); txQ_ready->notify(SC_ZERO_TIME); } if ( first_st == st) first_st = IDLE; else second_st = IDLE; st = IDLE; next_trigger(1,SC_NS); } break; default: cout<<"ERROR: "; cout<<"MEM_LSU::"<<inode<<", "<<__func__<<" : "<< __LINE__<<endl; } i--; } }
void CM_LSU::lsu_tx_method(void ) { ////cout<<"CM_LSU::"<<inode<<" , "<<__func__<<" : "<<__LINE__<<endl; cout<<dec; LSU_STATE st = IDLE; LSU_STATE first_st =IDLE,second_st =IDLE; int i=3; // while (i!=0) { switch (st) { case IDLE: { //l2 side if(ce_to_dir_l2 == true || ex_to_dir_l2 == true || cl_evt_info_to_dir_l2 == true || inv_ack_to_dir_l2 == true) { st = L2CEEXEVT; //cout<<"CM_LSU::"<<inode<<" , "<<__func__<<" : "<< __LINE__<<endl; first_st = L2CEEXEVT; } else if((address_to_l3_en_l2 == true) && (generate_wr_req_npc_l2 == false)){ st = L2DATA_TO_L3MEM; //cout<<"CM_LSU::"<<inode<<" , "<<__func__<<" : "<< __LINE__<<" addr:"<<hex<< address_to_l3_l2<<dec<<endl; first_st = L2DATA_TO_L3MEM; } else if ((address_to_l3_en_l2 == true) && (generate_wr_req_npc_l2 == true)) { // direct WB from NPC to SC st = L2DATA_WB_TO_L3MEM; first_st = L2DATA_WB_TO_L3MEM; } //dir side if((inv_to_node_dir == true) || (flush_frm_npc_dir == true)) { //cout<<"CM_LSU::"<<inode<<" , "<<__func__<<" : "<< __LINE__<<endl; if (first_st != IDLE) second_st = DIRINV; else { first_st = DIRINV; st = DIRINV; } } else if(ack_to_node_dir == true) { //cout<<"CM_LSU::"<<inode<<" , "<<__func__<<" : "<< __LINE__<<endl; if (first_st != IDLE) second_st = DIRACK; else { first_st = DIRACK; st = DIRACK; } } else if(ce_to_l3_dir == true) { //cout<<"CM_LSU::"<<inode<<" , "<<__func__<<" : "<< __LINE__<<endl; if (first_st != IDLE) second_st = DIRCE_TO_L3MEM; else { first_st = DIRCE_TO_L3MEM; st = DIRCE_TO_L3MEM; } } if(first_st == IDLE && second_st == IDLE) { st = IDLE; } } break; // check or find node address and see if that belongs to local node. case L2CEEXEVT: { //cout<<"CM_LSU::"<<inode<<" @"<<__func__<<" : "<<__LINE__<<endl; //decode address to destination node unsigned int cl_address = address_to_dir_l2>>(OFFSET_LENGTH); unsigned int dst_node = ((unsigned int)cl_address )&( (unsigned int)(NO_OF_NODES-1)); /*0x11 & address will give the dst dir bank address*/ if(dst_node == inode) { NoCCommPacket local_l2P; local_l2P.en = ce_to_dir_l2; local_l2P.ex = ex_to_dir_l2; local_l2P.rw = rd_wr_to_dir_l2; local_l2P.evt = cl_evt_info_to_dir_l2; local_l2P.ack = inv_ack_to_dir_l2; local_l2P.address = address_to_dir_l2; local_l2P.srcnode = inode; local_l2P.dstnode = dst_node; local_l2P.type = st; local_l2P.req_count = req_count_to_dir_l2; local_dirQ.push(local_l2P); } else { //make packet and put in the queue LisNocPacket packet; double now = (int) (sc_time_stamp().to_double() / 1000); packet.make(inode, 0, now, 1); packet.type = st; packet.src_id = inode; packet.read_or_write = rd_wr_to_dir_l2; packet.burst = 0; packet.offset = 0; packet.ex = ex_to_dir_l2; packet.evt = cl_evt_info_to_dir_l2; packet.en = ce_to_dir_l2; packet.ack = inv_ack_to_dir_l2; packet.dst_id = dst_node; packet.size = 2; packet.address.push_back(address_to_dir_l2); packet.req_count = req_count_to_dir_l2; packet.flit_left = packet.size; NoCtxQ->push(packet); } first_st = IDLE; st = second_st; if(second_st == IDLE) {//wait(); st = IDLE; i = 1; next_trigger(1, SC_NS); } }break; case L2DATA_WB_TO_L3MEM: case L2DATA_TO_L3MEM: { //cout<<"CM_LSU::"<<inode<<" , "<<__func__<<" : "<< __LINE__<<" address:0x"<< hex<<address_to_l3_l2<<dec <<endl; //decode address to destination node unsigned int cl_address = address_to_l3_l2>>(OFFSET_LENGTH); unsigned int dst_node , dnode = ((unsigned int)cl_address )&( (unsigned int)(NO_OF_NODES-1)); #ifdef L3_TRUE_1 if(((cl_address >> NO_OF_NODES_2) & 0x01) == 0) // 7 = 5(offset) + 2(inode) { dst_node = dnode;//cout<<"1"<<endl; } else { if((dnode & 0x01) == 0x0) { dst_node = dnode+1;//cout<<"2"<<endl; } else { dst_node = dnode-1;//cout<<"3"<<endl; } } #else #ifdef L3_TRUE_0 dst_node = dnode; #else dst_node = NODE_WITH_SDRAM; #endif #endif //cout<<"dst_node: L2data to L3mem: "<<dst_node<<" dnode:"<<dnode<<" address:0x"<< hex<<address_to_l3_l2<<dec <<endl; if(dst_node == inode) { #if 0 NoCCommPacket local_l2P; (data_to_l3_l2)->read_data(&local_l2P.data); local_l2P.address = address_to_l3_l2; local_l2P.req_count = req_count_to_l3_l2; local_l2P.en = address_to_l3_en_l2; local_l2P.srcnode = inode; local_l2P.dstnode = dst_node; local_l2P.type = st; local_l2P.rw = true; local_l3Q.push(local_l2P); #else cout<<"error !! as l2 and mem cant be in the same node"<<endl; #endif } else { //make packet and put in the queue LisNocPacket packet; double now = (int) (sc_time_stamp().to_double() / 1000); packet.make(inode, 0, now, 1); datatype temp; if(st == L2DATA_TO_L3MEM) { (data_to_l3_l2)->read_data(&temp); packet.type = st; packet.src_id = inode; packet.burst = 0; packet.evt = false; packet.offset = 0; packet.en = address_to_l3_en_l2; packet.address.push_back(address_to_l3_l2); packet.read_or_write = true; packet.size = 10; for (int i=0;i<CL_SIZE_WORDWISE;i++) packet.data.push_back(temp.data[i]); packet.dst_id = dst_node; packet.req_count = req_count_to_l3_l2; packet.flit_left = packet.size; } else if (st == L2DATA_WB_TO_L3MEM) { packet.type = DIRCE_TO_L3MEM; packet.src_id = dnode; packet.read_or_write = true; packet.evt = false; packet.inv = false; packet.ex = true; packet.en = address_to_l3_en_l2; packet.address.push_back(address_to_l3_l2); packet.redirectionnode = inode; packet.dst_id = dst_node; packet.size = 2; packet.req_count = req_count_to_l3_l2; packet.flit_left = packet.size; } NoCtxQ->push(packet); } first_st = IDLE; st = second_st; if(second_st == IDLE) { st = IDLE; i = 1; next_trigger(1, SC_NS); } }break; case DIRINV: { //cout<<"CM_LSU::"<<inode<<" , "<<__func__<<" : "<< __LINE__<<endl; if(nodeaddr_to_lru_dir == inode) { NoCCommPacket local_dirP; local_dirP.address = inv_addr_to_node_dir; local_dirP.req_count = req_count_from_dir_dir; local_dirP.srcnode = inode; local_dirP.dstnode = nodeaddr_to_lru_dir; local_dirP.type = st; if((flush_frm_npc_dir == true) && (inv_to_node_dir == false)){ local_dirP.evt = false; local_dirP.inv = true; } else if ((flush_frm_npc_dir == false) && (inv_to_node_dir == true)){ local_dirP.evt = true; local_dirP.inv = true; } local_l2Q.push(local_dirP); } else { //make packet and put in the queue LisNocPacket packet; double now = (int) (sc_time_stamp().to_double() / 1000); packet.make(inode, 0, now, 1); packet.type = st; packet.src_id = inode; if ((flush_frm_npc_dir == true) && (inv_to_node_dir == false)) { packet.inv = true; packet.evt = false; } else if ((flush_frm_npc_dir == false) && (inv_to_node_dir == true)) { packet.evt = true; packet.inv = true; } packet.address.push_back(inv_addr_to_node_dir); packet.dst_id = nodeaddr_to_lru_dir; packet.size = 2; packet.req_count = req_count_from_dir_dir; packet.flit_left = packet.size; NoCtxQ->push(packet); } if ( first_st == st) first_st = IDLE; else second_st = IDLE; st = IDLE; i = 1; next_trigger(1, SC_NS); }break; case DIRACK: { //cout<<"CM_LSU::"<<inode<<" , "<<__func__<<" : "<< __LINE__<<endl; if(nodeaddr_to_lru_dir == inode) { // local transfer NoCCommPacket local_dirP; local_dirP.ack = ack_to_node_dir; local_dirP.address = address_from_dir_dir; local_dirP.req_count = req_count_from_dir_dir; local_dirP.srcnode = inode; local_dirP.dstnode = nodeaddr_to_lru_dir; local_dirP.type = st; local_l2Q.push(local_dirP); } else { //make packet and put in the queue LisNocPacket packet; double now = (int) (sc_time_stamp().to_double() / 1000); packet.make(inode, 0, now, 1); packet.type = st; packet.src_id = inode; packet.ack = ack_to_node_dir; packet.evt = false; packet.address.push_back(address_from_dir_dir); packet.dst_id = nodeaddr_to_lru_dir; packet.size = 2; packet.req_count = req_count_from_dir_dir; packet.flit_left = packet.size; NoCtxQ->push(packet); } if ( first_st == st) first_st = IDLE; else second_st = IDLE; st = IDLE; i = 1; next_trigger(1, SC_NS); }break; case DIRCE_TO_L3MEM: { //cout<<"CM_LSU::"<<inode<<" , "<<__func__<<" : "<< __LINE__<< "from dir to l3:" <<nodeaddr_to_lru_dir <<dec <<endl; if(nodeaddr_to_lru_dir == inode) { // local transfer this can be filled in only once we have L3 or mem added to the lsu cout<<"Error CMLSU doesnt have memory"<<endl; } else { //make packet and put in the queue LisNocPacket packet; double now = (int) (sc_time_stamp().to_double() / 1000); packet.make(inode, 0, now, 1); packet.type = st; packet.src_id = inode; packet.read_or_write = rd_wr_to_l3_dir; packet.evt = false; packet.inv = false; packet.ex = false; packet.en = ce_to_l3_dir; packet.address.push_back(addr_to_l3_dir); packet.redirectionnode = dst_nodeaddr_to_l3_dir; packet.dst_id = nodeaddr_to_lru_dir; packet.size = 2; packet.req_count = req_count_to_l3_dir; packet.flit_left = packet.size; NoCtxQ->push(packet); } if ( first_st == st) first_st = IDLE; else second_st = IDLE; st = IDLE; next_trigger(1, SC_NS); } break; default: cout<<"ERROR: "<<st; cout<<"CM_LSU::"<<inode<<" , "<<__func__<<" : "<< __LINE__<<endl; // wait(); } i--; }