#ifndef XRAM_TRANSACTION_H_ #define XRAM_TRANSACTION_H_ #include #include #include #include "arithmetics.h" #define DEBUG_XRAM_TRANSACTION 0 //////////////////////////////////////////////////////////////////////// // A transaction tab entry //////////////////////////////////////////////////////////////////////// class TransactionTabEntry { typedef sc_dt::sc_uint<64> wide_data_t; typedef sc_dt::sc_uint<40> addr_t; typedef uint32_t data_t; typedef uint32_t be_t; public: bool valid; // entry valid bool xram_read; // read request to XRAM addr_t nline; // index (zy) of the requested line size_t srcid; // processor requesting the transaction size_t trdid; // processor requesting the transaction size_t pktid; // processor requesting the transaction bool proc_read; // read request from processor size_t read_length; // length of the read (for the response) size_t word_index; // index of the first read word (for the response) std::vector wdata; // write buffer (one cache line) std::vector wdata_be; // be for each data in the write buffer bool rerror; // error returned by xram data_t ll_key; // LL key returned by the llsc_global_table bool config; // transaction required by CONFIG FSM ///////////////////////////////////////////////////////////////////// // The init() function initializes the entry ///////////////////////////////////////////////////////////////////// void init() { valid = false; rerror = false; config = false; } ///////////////////////////////////////////////////////////////////// // The alloc() function initializes the vectors of an entry // Its arguments are : // - n_words : number of words per line in the cache ///////////////////////////////////////////////////////////////////// void alloc(size_t n_words) { wdata_be.reserve( (int)n_words ); wdata.reserve( (int)n_words ); for(size_t i=0; i &be, const std::vector &data) { assert((index < size_tab) and "MEMC ERROR: The selected entry is out of range in TRT write_data_mask()"); assert((be.size() == tab[index].wdata_be.size()) and "MEMC ERROR: Bad be size in TRT write_data_mask()"); assert((data.size() == tab[index].wdata.size()) and "MEMC ERROR: Bad data size in TRT write_data_mask()"); for (size_t i = 0; i < tab[index].wdata_be.size(); i++) { tab[index].wdata_be[i] = tab[index].wdata_be[i] | be[i]; data_t mask = be_to_mask(be[i]); tab[index].wdata[i] = (tab[index].wdata[i] & ~mask) | (data[i] & mask); } } ///////////////////////////////////////////////////////////////////// // The set() function registers a transaction (read or write) // to the XRAM in the transaction tab. // Arguments : // - index : index in the transaction tab // - xram_read : transaction type (read or write a cache line) // - nline : the index (zy) of the cache line // - srcid : srcid of the initiator that caused the transaction // - trdid : trdid of the initiator that caused the transaction // - pktid : pktid of the initiator that caused the transaction // - proc_read : does the initiator want a copy // - read_length : length of read (in case of processor read) // - word_index : index in the line (in case of single word read) // - data : the data to write (in case of write) // - data_be : the mask of the data to write (in case of write) // - ll_key : the ll key (if any) returned by the llsc_global_table // - config : transaction required by config FSM ///////////////////////////////////////////////////////////////////// void set(const size_t index, const bool xram_read, const addr_t nline, const size_t srcid, const size_t trdid, const size_t pktid, const bool proc_read, const size_t read_length, const size_t word_index, const std::vector &data_be, const std::vector &data, const data_t ll_key = 0, const bool config = false) { assert((index < size_tab) and "MEMC ERROR: The selected entry is out of range in TRT set()"); assert((data_be.size() == tab[index].wdata_be.size()) and "MEMC ERROR: Bad data_be argument in TRT set()"); assert((data.size() == tab[index].wdata.size()) and "MEMC ERROR: Bad data argument in TRT set()"); tab[index].valid = true; tab[index].xram_read = xram_read; tab[index].nline = nline; tab[index].srcid = srcid; tab[index].trdid = trdid; tab[index].pktid = pktid; tab[index].proc_read = proc_read; tab[index].read_length = read_length; tab[index].word_index = word_index; tab[index].ll_key = ll_key; tab[index].config = config; for (size_t i = 0; i < tab[index].wdata.size(); i++) { tab[index].wdata_be[i] = data_be[i]; tab[index].wdata[i] = data[i]; } } ///////////////////////////////////////////////////////////////////// // The write_rsp() function writes two 32 bits words of the response // to a XRAM read transaction. // The BE field in TRT is taken into account. // Arguments : // - index : index of the entry in TRT // - word : index of the 32 bits word in the line // - data : 64 bits value (first data right) ///////////////////////////////////////////////////////////////////// void write_rsp(const size_t index, const size_t word, const wide_data_t data, const bool rerror) { data_t value; data_t mask; assert((index < size_tab) and "MEMC ERROR: The selected entry is out of range in TRT write_rsp()"); assert((word < tab[index].wdata_be.size()) and "MEMC ERROR: Bad word index in TRT write_rsp()"); assert((tab[index].valid) and "MEMC ERROR: TRT entry not valid in TRT write_rsp()"); assert((tab[index].xram_read ) and "MEMC ERROR: TRT entry is not a GET in TRT write_rsp()"); if (rerror) { tab[index].rerror = true; return; } // first 32 bits word value = (data_t)data; mask = be_to_mask(tab[index].wdata_be[word]); tab[index].wdata[word] = (tab[index].wdata[word] & mask) | (value & ~mask); // second 32 bits word value = (data_t)(data >> 32); mask = be_to_mask(tab[index].wdata_be[word + 1]); tab[index].wdata[word + 1] = (tab[index].wdata[word + 1] & mask) | (value & ~mask); } ///////////////////////////////////////////////////////////////////// // The erase() function erases an entry in the transaction tab. // Arguments : // - index : the index of the request in the transaction tab ///////////////////////////////////////////////////////////////////// void erase(const size_t index) { assert((index < size_tab) and "MEMC ERROR: The selected entry is out of range in TRT erase()"); tab[index].valid = false; tab[index].rerror = false; } ///////////////////////////////////////////////////////////////////// // The is_config() function returns the config flag value. // Arguments : // - index : the index of the entry in the transaction tab ///////////////////////////////////////////////////////////////////// bool is_config(const size_t index) { assert((index < size_tab) and "MEMC ERROR: The selected entry is out of range in TRT is_config()"); return tab[index].config; } }; // end class TransactionTab #endif // Local Variables: // tab-width: 4 // c-basic-offset: 4 // c-file-offsets:((innamespace . 0)(inline-open . 0)) // indent-tabs-mode: nil // End: // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4