Esempio n. 1
0
 //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;
 }
Esempio n. 2
0
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;
    }
}
Esempio n. 3
0
 void receiver()
 {
     next_trigger( e );
     if( receiver_first ) {
         receiver_first = false;
         return;
     }
     write( "receiver" );
 }
Esempio n. 4
0
 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;
     }
 }
Esempio n. 5
0
  //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++;
  }
Esempio n. 6
0
 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;
 }
Esempio n. 7
0
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;
}
Esempio n. 8
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--;
	}
Esempio n. 9
0
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--;
    }

}
Esempio n. 10
0
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--;
	}