111819SChristian.Menard@tu-dresden.de/*
211819SChristian.Menard@tu-dresden.de * Copyright (c) 2016, Dresden University of Technology (TU Dresden)
311819SChristian.Menard@tu-dresden.de * All rights reserved.
411819SChristian.Menard@tu-dresden.de *
511819SChristian.Menard@tu-dresden.de * Redistribution and use in source and binary forms, with or without
611819SChristian.Menard@tu-dresden.de * modification, are permitted provided that the following conditions are
711819SChristian.Menard@tu-dresden.de * met:
811819SChristian.Menard@tu-dresden.de *
911819SChristian.Menard@tu-dresden.de * 1. Redistributions of source code must retain the above copyright notice,
1011819SChristian.Menard@tu-dresden.de *    this list of conditions and the following disclaimer.
1111819SChristian.Menard@tu-dresden.de *
1211819SChristian.Menard@tu-dresden.de * 2. Redistributions in binary form must reproduce the above copyright
1311819SChristian.Menard@tu-dresden.de *    notice, this list of conditions and the following disclaimer in the
1411819SChristian.Menard@tu-dresden.de *    documentation and/or other materials provided with the distribution.
1511819SChristian.Menard@tu-dresden.de *
1611819SChristian.Menard@tu-dresden.de * 3. Neither the name of the copyright holder nor the names of its
1711819SChristian.Menard@tu-dresden.de *    contributors may be used to endorse or promote products derived from
1811819SChristian.Menard@tu-dresden.de *    this software without specific prior written permission.
1911819SChristian.Menard@tu-dresden.de *
2011819SChristian.Menard@tu-dresden.de * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2111819SChristian.Menard@tu-dresden.de * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2211819SChristian.Menard@tu-dresden.de * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2311819SChristian.Menard@tu-dresden.de * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
2411819SChristian.Menard@tu-dresden.de * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
2511819SChristian.Menard@tu-dresden.de * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
2611819SChristian.Menard@tu-dresden.de * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
2711819SChristian.Menard@tu-dresden.de * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
2811819SChristian.Menard@tu-dresden.de * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
2911819SChristian.Menard@tu-dresden.de * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3011819SChristian.Menard@tu-dresden.de * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3111819SChristian.Menard@tu-dresden.de *
3211819SChristian.Menard@tu-dresden.de * Authors: Christian Menard
3311819SChristian.Menard@tu-dresden.de */
3411819SChristian.Menard@tu-dresden.de
3511819SChristian.Menard@tu-dresden.de#include "base/random.hh"
3611819SChristian.Menard@tu-dresden.de#include "traffic_generator.hh"
3711819SChristian.Menard@tu-dresden.de
3811819SChristian.Menard@tu-dresden.deTrafficGenerator::TrafficGenerator(sc_core::sc_module_name name)
3911819SChristian.Menard@tu-dresden.de  : sc_core::sc_module(name),
4011819SChristian.Menard@tu-dresden.de    requestInProgress(0),
4111819SChristian.Menard@tu-dresden.de    peq(this, &TrafficGenerator::peq_cb)
4211819SChristian.Menard@tu-dresden.de{
4311819SChristian.Menard@tu-dresden.de    socket.register_nb_transport_bw(this, &TrafficGenerator::nb_transport_bw);
4411819SChristian.Menard@tu-dresden.de    SC_THREAD(process);
4511819SChristian.Menard@tu-dresden.de}
4611819SChristian.Menard@tu-dresden.de
4711819SChristian.Menard@tu-dresden.devoid
4811819SChristian.Menard@tu-dresden.deTrafficGenerator::process()
4911819SChristian.Menard@tu-dresden.de{
5011819SChristian.Menard@tu-dresden.de    auto rnd = Random(time(NULL));
5111819SChristian.Menard@tu-dresden.de
5211819SChristian.Menard@tu-dresden.de    unsigned const memSize = (1 << 10); // 512 MB
5311819SChristian.Menard@tu-dresden.de
5411819SChristian.Menard@tu-dresden.de    while (true) {
5511819SChristian.Menard@tu-dresden.de
5611819SChristian.Menard@tu-dresden.de        wait(sc_core::sc_time((double)rnd.random(1,100), sc_core::SC_NS));
5711819SChristian.Menard@tu-dresden.de
5811819SChristian.Menard@tu-dresden.de        auto trans = mm.allocate();
5911819SChristian.Menard@tu-dresden.de        trans->acquire();
6011819SChristian.Menard@tu-dresden.de
6111819SChristian.Menard@tu-dresden.de        std::string cmdStr;
6211819SChristian.Menard@tu-dresden.de        if (rnd.random(0,1)) // Generate a write request?
6311819SChristian.Menard@tu-dresden.de        {
6411819SChristian.Menard@tu-dresden.de            cmdStr = "write";
6511819SChristian.Menard@tu-dresden.de            trans->set_command(tlm::TLM_WRITE_COMMAND);
6611819SChristian.Menard@tu-dresden.de            dataBuffer = rnd.random(0,0xffff);
6711819SChristian.Menard@tu-dresden.de        } else {
6811819SChristian.Menard@tu-dresden.de            cmdStr = "read";
6911819SChristian.Menard@tu-dresden.de            trans->set_command(tlm::TLM_READ_COMMAND);
7011819SChristian.Menard@tu-dresden.de        }
7111819SChristian.Menard@tu-dresden.de
7211819SChristian.Menard@tu-dresden.de        trans->set_data_ptr(reinterpret_cast<unsigned char*>(&dataBuffer));
7311819SChristian.Menard@tu-dresden.de        trans->set_address(rnd.random(0, (int)(memSize-1)));
7411819SChristian.Menard@tu-dresden.de        trans->set_data_length(4);
7511819SChristian.Menard@tu-dresden.de        trans->set_streaming_width(4);
7611819SChristian.Menard@tu-dresden.de        trans->set_byte_enable_ptr(0);
7711819SChristian.Menard@tu-dresden.de        trans->set_dmi_allowed(0);
7811819SChristian.Menard@tu-dresden.de        trans->set_response_status(tlm::TLM_INCOMPLETE_RESPONSE);
7911819SChristian.Menard@tu-dresden.de
8011819SChristian.Menard@tu-dresden.de        // honor the BEGIN_REQ/END_REQ exclusion rule
8111819SChristian.Menard@tu-dresden.de        if (requestInProgress)
8211819SChristian.Menard@tu-dresden.de            sc_core::wait(endRequestEvent);
8311819SChristian.Menard@tu-dresden.de
8411819SChristian.Menard@tu-dresden.de        std::stringstream ss;
8511819SChristian.Menard@tu-dresden.de        ss << "Send " << cmdStr << " request @0x" << std::hex
8611819SChristian.Menard@tu-dresden.de           << trans->get_address();
8711819SChristian.Menard@tu-dresden.de        SC_REPORT_INFO("Traffic Generator", ss.str().c_str());
8811819SChristian.Menard@tu-dresden.de
8911819SChristian.Menard@tu-dresden.de        // send the request
9011819SChristian.Menard@tu-dresden.de        requestInProgress = trans;
9111819SChristian.Menard@tu-dresden.de        tlm::tlm_phase phase = tlm::BEGIN_REQ;
9211819SChristian.Menard@tu-dresden.de        auto delay = sc_core::SC_ZERO_TIME;
9311819SChristian.Menard@tu-dresden.de
9411819SChristian.Menard@tu-dresden.de        auto status = socket->nb_transport_fw(*trans, phase, delay);
9511819SChristian.Menard@tu-dresden.de
9611819SChristian.Menard@tu-dresden.de        // Check status
9711819SChristian.Menard@tu-dresden.de        if (status == tlm::TLM_UPDATED) {
9811819SChristian.Menard@tu-dresden.de            peq.notify(*trans, phase, delay);
9911819SChristian.Menard@tu-dresden.de        } else if (status == tlm::TLM_COMPLETED) {
10011819SChristian.Menard@tu-dresden.de            requestInProgress = 0;
10111819SChristian.Menard@tu-dresden.de            checkTransaction(*trans);
10211819SChristian.Menard@tu-dresden.de            SC_REPORT_INFO("Traffic Generator", "request completed");
10311819SChristian.Menard@tu-dresden.de            trans->release();
10411819SChristian.Menard@tu-dresden.de        }
10511819SChristian.Menard@tu-dresden.de    }
10611819SChristian.Menard@tu-dresden.de}
10711819SChristian.Menard@tu-dresden.de
10811819SChristian.Menard@tu-dresden.devoid
10911819SChristian.Menard@tu-dresden.deTrafficGenerator::peq_cb(tlm::tlm_generic_payload& trans,
11011819SChristian.Menard@tu-dresden.de                         const tlm::tlm_phase& phase)
11111819SChristian.Menard@tu-dresden.de{
11211819SChristian.Menard@tu-dresden.de    if (phase == tlm::END_REQ ||
11311819SChristian.Menard@tu-dresden.de        (&trans == requestInProgress && phase == tlm::BEGIN_RESP)) {
11411819SChristian.Menard@tu-dresden.de        // The end of the BEGIN_REQ phase
11511819SChristian.Menard@tu-dresden.de        requestInProgress = 0;
11611819SChristian.Menard@tu-dresden.de        endRequestEvent.notify();
11711819SChristian.Menard@tu-dresden.de    } else if (phase == tlm::BEGIN_REQ || phase == tlm::END_RESP)
11811819SChristian.Menard@tu-dresden.de        SC_REPORT_FATAL("TLM-2",
11911819SChristian.Menard@tu-dresden.de                        "Illegal transaction phase received by initiator");
12011819SChristian.Menard@tu-dresden.de
12111819SChristian.Menard@tu-dresden.de    if (phase == tlm::BEGIN_RESP) {
12211819SChristian.Menard@tu-dresden.de        checkTransaction(trans);
12311819SChristian.Menard@tu-dresden.de        SC_REPORT_INFO("Traffic Generator", "received response");
12411819SChristian.Menard@tu-dresden.de
12511819SChristian.Menard@tu-dresden.de        // Send end response
12611819SChristian.Menard@tu-dresden.de        tlm::tlm_phase fw_phase = tlm::END_RESP;
12711819SChristian.Menard@tu-dresden.de
12811819SChristian.Menard@tu-dresden.de        // stress the retry mechanism by deferring the response
12911819SChristian.Menard@tu-dresden.de        auto delay = sc_core::sc_time(5.0, sc_core::SC_NS);
13011819SChristian.Menard@tu-dresden.de        socket->nb_transport_fw(trans, fw_phase, delay);
13111819SChristian.Menard@tu-dresden.de        trans.release();
13211819SChristian.Menard@tu-dresden.de    }
13311819SChristian.Menard@tu-dresden.de}
13411819SChristian.Menard@tu-dresden.de
13511819SChristian.Menard@tu-dresden.devoid
13611819SChristian.Menard@tu-dresden.deTrafficGenerator::checkTransaction(tlm::tlm_generic_payload& trans)
13711819SChristian.Menard@tu-dresden.de{
13811819SChristian.Menard@tu-dresden.de    if (trans.is_response_error()) {
13911819SChristian.Menard@tu-dresden.de        std::stringstream ss;
14011819SChristian.Menard@tu-dresden.de        ss << "Transaction returned with error, response status = %s"
14111819SChristian.Menard@tu-dresden.de           << trans.get_response_string();
14211819SChristian.Menard@tu-dresden.de        SC_REPORT_ERROR("TLM-2", ss.str().c_str());
14311819SChristian.Menard@tu-dresden.de    }
14411819SChristian.Menard@tu-dresden.de}
14511819SChristian.Menard@tu-dresden.de
14611819SChristian.Menard@tu-dresden.detlm::tlm_sync_enum
14711819SChristian.Menard@tu-dresden.deTrafficGenerator::nb_transport_bw(tlm::tlm_generic_payload& trans,
14811819SChristian.Menard@tu-dresden.de                                  tlm::tlm_phase& phase,
14911819SChristian.Menard@tu-dresden.de                                  sc_core::sc_time& delay)
15011819SChristian.Menard@tu-dresden.de{
15111819SChristian.Menard@tu-dresden.de    trans.acquire();
15211819SChristian.Menard@tu-dresden.de    peq.notify(trans, phase, delay);
15311819SChristian.Menard@tu-dresden.de    return tlm::TLM_ACCEPTED;
15411819SChristian.Menard@tu-dresden.de}
155