112855Sgabeblack@google.com/*****************************************************************************
212855Sgabeblack@google.com
312855Sgabeblack@google.com  Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
412855Sgabeblack@google.com  more contributor license agreements.  See the NOTICE file distributed
512855Sgabeblack@google.com  with this work for additional information regarding copyright ownership.
612855Sgabeblack@google.com  Accellera licenses this file to you under the Apache License, Version 2.0
712855Sgabeblack@google.com  (the "License"); you may not use this file except in compliance with the
812855Sgabeblack@google.com  License.  You may obtain a copy of the License at
912855Sgabeblack@google.com
1012855Sgabeblack@google.com    http://www.apache.org/licenses/LICENSE-2.0
1112855Sgabeblack@google.com
1212855Sgabeblack@google.com  Unless required by applicable law or agreed to in writing, software
1312855Sgabeblack@google.com  distributed under the License is distributed on an "AS IS" BASIS,
1412855Sgabeblack@google.com  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
1512855Sgabeblack@google.com  implied.  See the License for the specific language governing
1612855Sgabeblack@google.com  permissions and limitations under the License.
1712855Sgabeblack@google.com
1812855Sgabeblack@google.com *****************************************************************************/
1912855Sgabeblack@google.com
2012855Sgabeblack@google.com/*****************************************************************************
2112855Sgabeblack@google.com
2212855Sgabeblack@google.com  star111004.cpp --
2312855Sgabeblack@google.com
2412855Sgabeblack@google.com  Original Author: Martin Janssen, Synopsys, Inc., 2002-02-15
2512855Sgabeblack@google.com
2612855Sgabeblack@google.com *****************************************************************************/
2712855Sgabeblack@google.com
2812855Sgabeblack@google.com/*****************************************************************************
2912855Sgabeblack@google.com
3012855Sgabeblack@google.com  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
3112855Sgabeblack@google.com  changes you are making here.
3212855Sgabeblack@google.com
3312855Sgabeblack@google.com      Name, Affiliation, Date:
3412855Sgabeblack@google.com  Description of Modification:
3512855Sgabeblack@google.com
3612855Sgabeblack@google.com *****************************************************************************/
3712855Sgabeblack@google.com
3812855Sgabeblack@google.com/*############################################################################
3912855Sgabeblack@google.com#  Siemens AG                        copyright 2000
4012855Sgabeblack@google.com#                                    All Rights Reserved
4112855Sgabeblack@google.com#
4212855Sgabeblack@google.com#  File name : io_controller.cpp
4312855Sgabeblack@google.com#
4412855Sgabeblack@google.com#  Title     : I/O-Controller
4512855Sgabeblack@google.com#
4612855Sgabeblack@google.com#  Purpose   : functionality for I/O-Controller-module
4712855Sgabeblack@google.com#
4812855Sgabeblack@google.com#  Author    : Hannes Muhr
4912855Sgabeblack@google.com#              PSE EZE MSA
5012855Sgabeblack@google.com#
5112855Sgabeblack@google.com##############################################################################
5212855Sgabeblack@google.com#  Modification History :
5312855Sgabeblack@google.com#
5412855Sgabeblack@google.com#
5512855Sgabeblack@google.com##############################################################################*/
5612855Sgabeblack@google.com
5712855Sgabeblack@google.com#include "systemc.h"
5812855Sgabeblack@google.com#include "io_controller.h"
5912855Sgabeblack@google.com
6012855Sgabeblack@google.com#define MII_FRAME_SIZE 400
6112855Sgabeblack@google.com
6212855Sgabeblack@google.com// ::semaphore(){
6312855Sgabeblack@google.com
6412855Sgabeblack@google.com//    value = false;
6512855Sgabeblack@google.com// }
6612855Sgabeblack@google.com
6712855Sgabeblack@google.comvoid io_controller_m::P(){
6812855Sgabeblack@google.com
6912855Sgabeblack@google.com   while (value) wait();
7012855Sgabeblack@google.com   value = true;
7112855Sgabeblack@google.com}
7212855Sgabeblack@google.com
7312855Sgabeblack@google.comvoid io_controller_m::V(){
7412855Sgabeblack@google.com
7512855Sgabeblack@google.com   /*if (!value) {
7612855Sgabeblack@google.com      cerr << "V-operation on semaphore that is not P'd\n";
7712855Sgabeblack@google.com      exit(-1);
7812855Sgabeblack@google.com   }*/
7912855Sgabeblack@google.com   value = false;
8012855Sgabeblack@google.com}
8112855Sgabeblack@google.com
8212855Sgabeblack@google.combool io_controller_m::get_value(){
8312855Sgabeblack@google.com
8412855Sgabeblack@google.com   return value;
8512855Sgabeblack@google.com}
8612855Sgabeblack@google.com
8712855Sgabeblack@google.com/*void sc_trace(sc_trace_file *tf, const semaphore& sem, const std::string& str){
8812855Sgabeblack@google.com
8912855Sgabeblack@google.com   sc_trace(tf, sem.get_value(), str);
9012855Sgabeblack@google.com}*/
9112855Sgabeblack@google.com
9212855Sgabeblack@google.comsc_uint<32> io_controller_m::read_from_memory(sc_uint<32> mp){
9312855Sgabeblack@google.com
9412855Sgabeblack@google.com   // read from mbdatm-memory over i486-IF
9512855Sgabeblack@google.com
9612855Sgabeblack@google.com   addr30_o = mp >> 2;
9712855Sgabeblack@google.com   ads_n_o = 0;
9812855Sgabeblack@google.com   wr_n_o = 0;
9912855Sgabeblack@google.com   wait();
10012855Sgabeblack@google.com   ads_n_o = 1;
10112855Sgabeblack@google.com   do { wait(); } while (rdy_n_i == 1);
10212855Sgabeblack@google.com   sc_uint<32> data = data32_i.read();
10312855Sgabeblack@google.com   wr_n_o = 1;
10412855Sgabeblack@google.com   addr30_o = 0;
10512855Sgabeblack@google.com   return data;
10612855Sgabeblack@google.com}
10712855Sgabeblack@google.com
10812855Sgabeblack@google.comvoid io_controller_m::write_into_memory(sc_uint<32> mp, sc_uint<32> data){
10912855Sgabeblack@google.com
11012855Sgabeblack@google.com   addr30_o = mp >> 2;
11112855Sgabeblack@google.com   ads_n_o = 0;
11212855Sgabeblack@google.com   wr_n_o = 1;
11312855Sgabeblack@google.com   wait();
11412855Sgabeblack@google.com   ads_n_o = 1;
11512855Sgabeblack@google.com   data32_o = data;
11612855Sgabeblack@google.com   do { wait(); } while (rdy_n_i == 1);
11712855Sgabeblack@google.com   wr_n_o = 1;
11812855Sgabeblack@google.com   addr30_o = 0;
11912855Sgabeblack@google.com   data32_o = 0;
12012855Sgabeblack@google.com}
12112855Sgabeblack@google.com
12212855Sgabeblack@google.comvoid io_controller_m::control_write(){
12312855Sgabeblack@google.com   sc_uint<32> word_cnt;
12412855Sgabeblack@google.com
12512855Sgabeblack@google.com   if (!res_n_i.read()){
12612855Sgabeblack@google.com      do { wait(); } while (!res_n_i);
12712855Sgabeblack@google.com
12812855Sgabeblack@google.com      // initialize
12912855Sgabeblack@google.com
13012855Sgabeblack@google.com      // wait for 1. AR (HWS-Daten)
13112855Sgabeblack@google.com      do { wait(); } while (!ar_i);
13212855Sgabeblack@google.com      sc_uint<32> hws = data32_i.read();
13312855Sgabeblack@google.com
13412855Sgabeblack@google.com      wait();
13512855Sgabeblack@google.com
13612855Sgabeblack@google.com      // wait for 2. AR (ACB-Pointer)
13712855Sgabeblack@google.com      do { wait(); } while (!ar_i);
13812855Sgabeblack@google.com      addr_tx_frame_ptr = data32_i.read();
13912855Sgabeblack@google.com
14012855Sgabeblack@google.com   }
14112855Sgabeblack@google.com  /* else if (mii_coll_det){
14212855Sgabeblack@google.com      out_fifo_reset = 1;
14312855Sgabeblack@google.com      out_fifo_en = 0;
14412855Sgabeblack@google.com      out_fifo_data32 = (sc_uint<32>) 0;
14512855Sgabeblack@google.com
14612855Sgabeblack@google.com      // reset i486-IF
14712855Sgabeblack@google.com      addr30_o = 0;
14812855Sgabeblack@google.com      data32_io = 0;
14912855Sgabeblack@google.com      ads_n_o = 1;
15012855Sgabeblack@google.com      wr_n_o = 1;
15112855Sgabeblack@google.com
15212855Sgabeblack@google.com      // release Semaphore if it is set
15312855Sgabeblack@google.com      sem.V();
15412855Sgabeblack@google.com
15512855Sgabeblack@google.com      wait();
15612855Sgabeblack@google.com      out_fifo_reset = 0;
15712855Sgabeblack@google.com   }*/
15812855Sgabeblack@google.com
15912855Sgabeblack@google.com   while(true){
16012855Sgabeblack@google.com      // normally Attention Request - Signal from MBDATM
16112855Sgabeblack@google.com      // would wake up IO-Controller to read data from the memory,
16212855Sgabeblack@google.com      // but the model from Hr. Wahl said: wait for some ms !!!
16312855Sgabeblack@google.com
16412855Sgabeblack@google.com     // wait(unsigned ((SCAN_INTERVAL NS)/40e-9));
16512855Sgabeblack@google.com      //do { wait(); } while (ar_i);
16612855Sgabeblack@google.com
16712855Sgabeblack@google.com      #ifdef LOGGING
16812855Sgabeblack@google.com         flog << sc_time_stamp()<<": "<<name()<<"::control_write - Attention Request" << endl;
16912855Sgabeblack@google.com      #endif
17012855Sgabeblack@google.com
17112855Sgabeblack@google.com      P();
17212855Sgabeblack@google.com      sc_uint<32> tx_frame_ptr = read_from_memory(addr_tx_frame_ptr);
17312855Sgabeblack@google.com      if (tx_frame_ptr != 0)
17412855Sgabeblack@google.com         word_cnt = read_from_memory(tx_frame_ptr+(MII_FIFO_SIZE+1)*4);
17512855Sgabeblack@google.com      V();
17612855Sgabeblack@google.com
17712855Sgabeblack@google.com      // check, if frame available and frame is full (word_cnt == MII_FRAME_SIZE)
17812855Sgabeblack@google.com
17912855Sgabeblack@google.com      while (tx_frame_ptr != 0 && word_cnt == MII_FRAME_SIZE){
18012855Sgabeblack@google.com         #ifdef LOGGING
18112855Sgabeblack@google.com            flog << sc_time_stamp()<<": "<<name()<<"::control_write - writing mii_frame into out_fifo" << endl;
18212855Sgabeblack@google.com         #endif
18312855Sgabeblack@google.com
18412855Sgabeblack@google.com
18512855Sgabeblack@google.com         for (int i = 0; i<MII_FIFO_SIZE; i++){
18612855Sgabeblack@google.com            // reading from i486-IF and writing into
18712855Sgabeblack@google.com            // out_fifo is mixed, so read_from_memory could not be applied
18812855Sgabeblack@google.com
18912855Sgabeblack@google.com            P();
19012855Sgabeblack@google.com            sc_uint<32> data = read_from_memory(tx_frame_ptr+i*4);
19112855Sgabeblack@google.com            V();
19212855Sgabeblack@google.com
19312855Sgabeblack@google.com            out_fifo_en = 1;
19412855Sgabeblack@google.com            out_fifo_data32 = data;
19512855Sgabeblack@google.com            wait();
19612855Sgabeblack@google.com            out_fifo_en = 0;
19712855Sgabeblack@google.com
19812855Sgabeblack@google.com         }
19912855Sgabeblack@google.com
20012855Sgabeblack@google.com         while (out_fifo_act.read() != 0) wait(2);
20112855Sgabeblack@google.com
20212855Sgabeblack@google.com         // write 0xFFFFFFFF (>MII_FRAME_SIZE) into tx_frame_ptr
20312855Sgabeblack@google.com         // to signal software in mbdatm that io-controller has
20412855Sgabeblack@google.com         // read out the frames and sent successfully
20512855Sgabeblack@google.com         P();
20612855Sgabeblack@google.com         write_into_memory(tx_frame_ptr+(MII_FIFO_SIZE+1)*4, 0xFFFFFFFF);
20712855Sgabeblack@google.com         V();
20812855Sgabeblack@google.com
20912855Sgabeblack@google.com         // read next frame_pointer and word_cnt from MBDATM
21012855Sgabeblack@google.com         P();
21112855Sgabeblack@google.com         tx_frame_ptr = read_from_memory(tx_frame_ptr+MII_FIFO_SIZE*4);
21212855Sgabeblack@google.com         if (tx_frame_ptr != 0)
21312855Sgabeblack@google.com            word_cnt = read_from_memory(tx_frame_ptr+(MII_FIFO_SIZE+1)*4);
21412855Sgabeblack@google.com         V();
21512855Sgabeblack@google.com
21612855Sgabeblack@google.com
21712855Sgabeblack@google.com      }
21812855Sgabeblack@google.com
21912855Sgabeblack@google.com   }
22012855Sgabeblack@google.com}
22112855Sgabeblack@google.com
22212855Sgabeblack@google.comvoid io_controller_m::control_read(){
22312855Sgabeblack@google.com
22412855Sgabeblack@google.com  int arr_ptr = 0;
22512855Sgabeblack@google.com
22612855Sgabeblack@google.com   while (true){
22712855Sgabeblack@google.com      do { wait(); } while (!control_en);
22812855Sgabeblack@google.com      #ifdef LOGGING
22912855Sgabeblack@google.com         flog << sc_time_stamp()<<": "<<name()<<"::control_read " << endl;
23012855Sgabeblack@google.com      #endif
23112855Sgabeblack@google.com
23212855Sgabeblack@google.com      // read rx_frame_ptr from MBDATM
23312855Sgabeblack@google.com      P();
23412855Sgabeblack@google.com      sc_uint<32> rx_frame_ptr = read_from_memory(rx_ptr_array+arr_ptr*4);
23512855Sgabeblack@google.com      V();
23612855Sgabeblack@google.com      /*if (rx_frame_ptr == 0){
23712855Sgabeblack@google.com         cerr << "\nIO-Controller has read NULL-ptr from rx_array in MBDATM\n";
23812855Sgabeblack@google.com         cerr << "MBDATM did not fill rx_array fast enough\n";
23912855Sgabeblack@google.com         exit(-1);
24012855Sgabeblack@google.com      }*/
24112855Sgabeblack@google.com      if (++arr_ptr == MII_FIFO_SIZE)
24212855Sgabeblack@google.com         arr_ptr = 0;
24312855Sgabeblack@google.com
24412855Sgabeblack@google.com      // write data from in_fifo into MBDATM-memory
24512855Sgabeblack@google.com      for (int i = 0; i < MII_FIFO_SIZE-1; i++){
24612855Sgabeblack@google.com         sc_uint<32> d = control_data32.read();
24712855Sgabeblack@google.com         // grab the semaphore
24812855Sgabeblack@google.com         P();
24912855Sgabeblack@google.com         write_into_memory(rx_frame_ptr + i*4, d);
25012855Sgabeblack@google.com         // release semaphore
25112855Sgabeblack@google.com         V();
25212855Sgabeblack@google.com         do { wait(); } while (!control_en);
25312855Sgabeblack@google.com
25412855Sgabeblack@google.com      }
25512855Sgabeblack@google.com      // separate last loop because we don't want to wait for
25612855Sgabeblack@google.com      // another control_en at this time
25712855Sgabeblack@google.com      sc_uint<32> d = control_data32.read();
25812855Sgabeblack@google.com      P();
25912855Sgabeblack@google.com      write_into_memory(rx_frame_ptr + (MII_FIFO_SIZE-1)*4, d);
26012855Sgabeblack@google.com      V();
26112855Sgabeblack@google.com
26212855Sgabeblack@google.com      // write 0xFFFFFFFF into word_cnt from frame
26312855Sgabeblack@google.com      // to indicate the software (MBDATM) that frame has been filled
26412855Sgabeblack@google.com      P();
26512855Sgabeblack@google.com      write_into_memory(rx_frame_ptr + (MII_FIFO_SIZE+1)*4, 0xFFFFFFFF);
26612855Sgabeblack@google.com      V();
26712855Sgabeblack@google.com   }
26812855Sgabeblack@google.com}
26912855Sgabeblack@google.com
270