ExplicitATTarget.h revision 12922
1955SN/A/***************************************************************************** 2955SN/A 31762SN/A Licensed to Accellera Systems Initiative Inc. (Accellera) under one or 4955SN/A more contributor license agreements. See the NOTICE file distributed 5955SN/A with this work for additional information regarding copyright ownership. 6955SN/A Accellera licenses this file to you under the Apache License, Version 2.0 7955SN/A (the "License"); you may not use this file except in compliance with the 8955SN/A License. You may obtain a copy of the License at 9955SN/A 10955SN/A http://www.apache.org/licenses/LICENSE-2.0 11955SN/A 12955SN/A Unless required by applicable law or agreed to in writing, software 13955SN/A distributed under the License is distributed on an "AS IS" BASIS, 14955SN/A WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 15955SN/A implied. See the License for the specific language governing 16955SN/A permissions and limitations under the License. 17955SN/A 18955SN/A *****************************************************************************/ 19955SN/A 20955SN/A#ifndef __EXPLICIT_AT_TARGET_H__ 21955SN/A#define __EXPLICIT_AT_TARGET_H__ 22955SN/A 23955SN/A#include "tlm.h" 24955SN/A#include "tlm_utils/simple_target_socket.h" 25955SN/A//#include <systemc> 26955SN/A#include <cassert> 27955SN/A#include <vector> 282665Ssaidi@eecs.umich.edu#include <queue> 294762Snate@binkert.org//#include <iostream> 30955SN/A 315522Snate@binkert.orgclass ExplicitATTarget : public sc_core::sc_module 324762Snate@binkert.org{ 335522Snate@binkert.orgpublic: 34955SN/A typedef tlm::tlm_generic_payload transaction_type; 355522Snate@binkert.org typedef tlm::tlm_phase phase_type; 36955SN/A typedef tlm::tlm_sync_enum sync_enum_type; 375522Snate@binkert.org typedef tlm_utils::simple_target_socket<ExplicitATTarget> target_socket_type; 384202Sbinkertn@umich.edu 395742Snate@binkert.orgpublic: 40955SN/A target_socket_type socket; 414381Sbinkertn@umich.edu 424381Sbinkertn@umich.edupublic: 43955SN/A SC_HAS_PROCESS(ExplicitATTarget); 44955SN/A ExplicitATTarget(sc_core::sc_module_name name) : 45955SN/A sc_core::sc_module(name), 464202Sbinkertn@umich.edu socket("socket"), 47955SN/A mCurrentTransaction(0) 484382Sbinkertn@umich.edu { 494382Sbinkertn@umich.edu // register nb_transport method 504382Sbinkertn@umich.edu socket.register_nb_transport_fw(this, &ExplicitATTarget::myNBTransport); 516108Snate@binkert.org socket.register_transport_dbg(this, &ExplicitATTarget::transport_dbg); 525517Snate@binkert.org 534762Snate@binkert.org SC_THREAD(beginResponse) 544762Snate@binkert.org } 554762Snate@binkert.org 564762Snate@binkert.org sync_enum_type myNBTransport(transaction_type& trans, phase_type& phase, sc_core::sc_time& t) 574762Snate@binkert.org { 584762Snate@binkert.org if (phase == tlm::BEGIN_REQ) { 594762Snate@binkert.org sc_dt::uint64 address = trans.get_address(); 604762Snate@binkert.org assert(address < 400); 614762Snate@binkert.org 624762Snate@binkert.org // This target only supports one transaction at a time 635522Snate@binkert.org // This will only work with LT initiators 645604Snate@binkert.org assert(mCurrentTransaction == 0); 655604Snate@binkert.org 665604Snate@binkert.org unsigned int& data = *reinterpret_cast<unsigned int*>(trans.get_data_ptr()); 674762Snate@binkert.org if (trans.get_command() == tlm::TLM_WRITE_COMMAND) { 684762Snate@binkert.org std::cout << name() << ": Received write request: A = 0x" 694762Snate@binkert.org << std::hex << (unsigned int)address << ", D = 0x" << data 705522Snate@binkert.org << std::dec << " @ " << sc_core::sc_time_stamp() 715522Snate@binkert.org << std::endl; 725522Snate@binkert.org 735522Snate@binkert.org *reinterpret_cast<unsigned int*>(&mMem[address]) = data; 745604Snate@binkert.org 755604Snate@binkert.org // Synchronization on demand (eg need to assert an interrupt) 764762Snate@binkert.org mResponseEvent.notify(t); 774762Snate@binkert.org mCurrentTransaction = &trans; 784762Snate@binkert.org 794762Snate@binkert.org // End request phase 805522Snate@binkert.org phase = tlm::END_REQ; 814762Snate@binkert.org return tlm::TLM_UPDATED; 824762Snate@binkert.org 835604Snate@binkert.org } else { 845604Snate@binkert.org std::cout << name() << ": Received read request: A = 0x" 855604Snate@binkert.org << std::hex << (unsigned int)address 865604Snate@binkert.org << std::dec << " @ " << sc_core::sc_time_stamp() 875604Snate@binkert.org << std::endl; 885604Snate@binkert.org 894762Snate@binkert.org data = *reinterpret_cast<unsigned int*>(&mMem[address]); 904762Snate@binkert.org trans.set_response_status(tlm::TLM_OK_RESPONSE); 914762Snate@binkert.org 924762Snate@binkert.org // Finish transaction (use timing annotation) 935604Snate@binkert.org t += sc_core::sc_time(100, sc_core::SC_NS); 944762Snate@binkert.org return tlm::TLM_COMPLETED; 955522Snate@binkert.org } 965522Snate@binkert.org 975522Snate@binkert.org } else if (phase == tlm::END_RESP) { 984762Snate@binkert.org 994382Sbinkertn@umich.edu // Transaction finished 1004762Snate@binkert.org mCurrentTransaction = 0; 1014382Sbinkertn@umich.edu return tlm::TLM_COMPLETED; 1025522Snate@binkert.org } 1034381Sbinkertn@umich.edu 1045522Snate@binkert.org // Not possible 1054762Snate@binkert.org assert(0); exit(1); 1064762Snate@binkert.org// return tlm::TLM_COMPLETED; //unreachable code 1074762Snate@binkert.org } 1085522Snate@binkert.org 1095522Snate@binkert.org void beginResponse() 1105522Snate@binkert.org { 1115522Snate@binkert.org while (true) { 1125522Snate@binkert.org // Wait for next synchronization request 1135522Snate@binkert.org wait(mResponseEvent); 1145522Snate@binkert.org 1155522Snate@binkert.org assert(mCurrentTransaction); 1165522Snate@binkert.org // start response phase 1174762Snate@binkert.org phase_type phase = tlm::BEGIN_RESP; 1184762Snate@binkert.org sc_core::sc_time t = sc_core::SC_ZERO_TIME; 1194762Snate@binkert.org 1204762Snate@binkert.org // Set response data 1214762Snate@binkert.org mCurrentTransaction->set_response_status(tlm::TLM_OK_RESPONSE); 1224762Snate@binkert.org assert(mCurrentTransaction->get_command() == tlm::TLM_WRITE_COMMAND); 1234762Snate@binkert.org 1244762Snate@binkert.org sc_dt::uint64 address = mCurrentTransaction->get_address(); 1254762Snate@binkert.org assert(address < 400); 1264762Snate@binkert.org *reinterpret_cast<unsigned int*>(mCurrentTransaction->get_data_ptr()) = 1274762Snate@binkert.org *reinterpret_cast<unsigned int*>(&mMem[address]); 1284762Snate@binkert.org 1294762Snate@binkert.org // We are synchronized, we can read/write sc_signals, wait,... 1304762Snate@binkert.org // Wait before sending the response 1314762Snate@binkert.org wait(50, sc_core::SC_NS); 1324762Snate@binkert.org 1334762Snate@binkert.org if (socket->nb_transport_bw(*mCurrentTransaction, phase, t) == tlm::TLM_COMPLETED) { 1344762Snate@binkert.org mCurrentTransaction = 0; 1354762Snate@binkert.org 1364762Snate@binkert.org } else { 1374762Snate@binkert.org // Initiator will call nb_transport(trans, END_RESP, t) 1384762Snate@binkert.org } 1394762Snate@binkert.org } 1404762Snate@binkert.org } 1414762Snate@binkert.org 1424762Snate@binkert.org unsigned int transport_dbg(transaction_type& r) 1434762Snate@binkert.org { 1444762Snate@binkert.org if (r.get_address() >= 400) return 0; 1454762Snate@binkert.org 1464762Snate@binkert.org unsigned int tmp = (int)r.get_address(); 1474762Snate@binkert.org unsigned int num_bytes; 1484762Snate@binkert.org if (tmp + r.get_data_length() >= 400) { 1494762Snate@binkert.org num_bytes = 400 - tmp; 1504762Snate@binkert.org 1514762Snate@binkert.org } else { 152955SN/A num_bytes = r.get_data_length(); 1535584Snate@binkert.org } 1545584Snate@binkert.org if (!r.is_read() && !r.is_write()) { 1555584Snate@binkert.org return 0; 1565584Snate@binkert.org } 1575584Snate@binkert.org if (r.is_read()) { 1585584Snate@binkert.org for (unsigned int i = 0; i < num_bytes; ++i) { 1595584Snate@binkert.org r.get_data_ptr()[i] = mMem[i + tmp]; 1605584Snate@binkert.org } 1615584Snate@binkert.org 1625584Snate@binkert.org } else { 1635584Snate@binkert.org for (unsigned int i = 0; i < num_bytes; ++i) { 1645584Snate@binkert.org mMem[i + tmp] = r.get_data_ptr()[i]; 1655584Snate@binkert.org } 1664382Sbinkertn@umich.edu } 1674202Sbinkertn@umich.edu return num_bytes; 1685522Snate@binkert.org } 1694382Sbinkertn@umich.edu 1704382Sbinkertn@umich.eduprivate: 1714382Sbinkertn@umich.edu unsigned char mMem[400]; 1725584Snate@binkert.org sc_core::sc_event mResponseEvent; 1734382Sbinkertn@umich.edu transaction_type* mCurrentTransaction; 1744382Sbinkertn@umich.edu}; 1754382Sbinkertn@umich.edu 1765192Ssaidi@eecs.umich.edu#endif 1775192Ssaidi@eecs.umich.edu