Remove conan dependency
This commit is contained in:
13
vp_components/CMakeLists.txt
Normal file
13
vp_components/CMakeLists.txt
Normal file
@ -0,0 +1,13 @@
|
||||
set(LIB_SOURCES
|
||||
initiator.cpp
|
||||
target.cpp
|
||||
clkgen.cpp
|
||||
resetgen.cpp
|
||||
)
|
||||
|
||||
# Define two variables in order not to repeat ourselves.
|
||||
set(LIBRARY_NAME vp_components)
|
||||
# Define the library
|
||||
add_library(${LIBRARY_NAME} SHARED ${LIB_SOURCES})
|
||||
target_link_libraries (${LIBRARY_NAME} LINK_PUBLIC scc)
|
||||
target_include_directories (${LIBRARY_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
|
23
vp_components/clkgen.cpp
Normal file
23
vp_components/clkgen.cpp
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* clkgen.cpp
|
||||
*
|
||||
* Created on: 02.01.2019
|
||||
* Author: eyck
|
||||
*/
|
||||
|
||||
#include <clkgen.h>
|
||||
#include <scc/utilities.h>
|
||||
|
||||
ClkGen::ClkGen(const sc_core::sc_module_name& nm)
|
||||
: sc_core::sc_module(nm)
|
||||
, clk_o("clk_o")
|
||||
{
|
||||
}
|
||||
|
||||
ClkGen::~ClkGen() {
|
||||
// TODO Auto-generated destructor stub
|
||||
}
|
||||
|
||||
void ClkGen::end_of_elaboration() {
|
||||
clk_o.write(10_ns);
|
||||
}
|
23
vp_components/clkgen.h
Normal file
23
vp_components/clkgen.h
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* clkgen.h
|
||||
*
|
||||
* Created on: 02.01.2019
|
||||
* Author: eyck
|
||||
*/
|
||||
|
||||
#ifndef VP_COMPONENTS_CLKGEN_H_
|
||||
#define VP_COMPONENTS_CLKGEN_H_
|
||||
|
||||
#include <systemc>
|
||||
|
||||
class ClkGen: public sc_core::sc_module {
|
||||
public:
|
||||
sc_core::sc_out<sc_core::sc_time> clk_o;
|
||||
|
||||
ClkGen(const sc_core::sc_module_name&);
|
||||
virtual ~ClkGen();
|
||||
protected:
|
||||
void end_of_elaboration() override;
|
||||
};
|
||||
|
||||
#endif /* VP_COMPONENTS_CLKGEN_H_ */
|
17
vp_components/components.h
Normal file
17
vp_components/components.h
Normal file
@ -0,0 +1,17 @@
|
||||
/*
|
||||
* components.h
|
||||
*
|
||||
* Created on: 02.12.2018
|
||||
* Author: eyck
|
||||
*/
|
||||
|
||||
#ifndef COMPONENTS_H_
|
||||
#define COMPONENTS_H_
|
||||
|
||||
#include "clkgen.h"
|
||||
#include "resetgen.h"
|
||||
#include "initiator.h"
|
||||
#include "router.h"
|
||||
#include "target.h"
|
||||
|
||||
#endif /* COMPONENTS_H_ */
|
140
vp_components/initiator.cpp
Normal file
140
vp_components/initiator.cpp
Normal file
@ -0,0 +1,140 @@
|
||||
/*
|
||||
* initiator.cpp
|
||||
*
|
||||
* Created on: 02.12.2018
|
||||
* Author: eyck
|
||||
*/
|
||||
|
||||
#include "initiator.h"
|
||||
|
||||
#include <scc/report.h>
|
||||
|
||||
|
||||
Initiator::Initiator(::sc_core::sc_module_name nm)
|
||||
: socket("socket") // Construct and name socket
|
||||
, clk_i("clk_i")
|
||||
, reset_i("reset_i")
|
||||
, dmi_ptr_valid(false)
|
||||
{
|
||||
// Register callbacks for incoming interface method calls
|
||||
socket.register_invalidate_direct_mem_ptr(this, &Initiator::invalidate_direct_mem_ptr);
|
||||
|
||||
SC_THREAD(thread_process);
|
||||
}
|
||||
|
||||
void Initiator::thread_process() {
|
||||
wait(reset_i.negedge_event());
|
||||
{
|
||||
// TLM-2 generic payload transaction, reused across calls to b_transport, DMI and debug
|
||||
tlm::tlm_generic_payload* trans = new tlm::tlm_generic_payload;
|
||||
sc_time delay = sc_time(10, SC_NS);
|
||||
|
||||
// Generate a random sequence of reads and writes
|
||||
for (int i = 256-64; i < 256+64; i += 4)
|
||||
{
|
||||
int data;
|
||||
tlm::tlm_command cmd = static_cast<tlm::tlm_command>(rand() % 2);
|
||||
if (cmd == tlm::TLM_WRITE_COMMAND) data = 0xFF000000 | i;
|
||||
|
||||
// Use DMI if it is available
|
||||
if (dmi_ptr_valid && sc_dt::uint64(i) >= dmi_data.get_start_address()
|
||||
&& sc_dt::uint64(i) <= dmi_data.get_end_address())
|
||||
{
|
||||
// Bypass transport interface and use direct memory interface
|
||||
// Implement target latency
|
||||
if ( cmd == tlm::TLM_READ_COMMAND )
|
||||
{
|
||||
assert( dmi_data.is_read_allowed() );
|
||||
memcpy(&data, dmi_data.get_dmi_ptr() + i - dmi_data.get_start_address(), 4);
|
||||
wait( dmi_data.get_read_latency() );
|
||||
}
|
||||
else if ( cmd == tlm::TLM_WRITE_COMMAND )
|
||||
{
|
||||
assert( dmi_data.is_write_allowed() );
|
||||
memcpy(dmi_data.get_dmi_ptr() + i - dmi_data.get_start_address(), &data, 4);
|
||||
wait( dmi_data.get_write_latency() );
|
||||
}
|
||||
|
||||
SCCDEBUG() << "DMI = { " << (cmd ? 'W' : 'R') << ", " << hex << i
|
||||
<< " } , data = " << hex << data << " at time " << sc_time_stamp();
|
||||
}
|
||||
else
|
||||
{
|
||||
trans->set_command( cmd );
|
||||
trans->set_address( i );
|
||||
trans->set_data_ptr( reinterpret_cast<unsigned char*>(&data) );
|
||||
trans->set_data_length( 4 );
|
||||
trans->set_streaming_width( 4 ); // = data_length to indicate no streaming
|
||||
trans->set_byte_enable_ptr( 0 ); // 0 indicates unused
|
||||
trans->set_dmi_allowed( false ); // Mandatory initial value
|
||||
trans->set_response_status( tlm::TLM_INCOMPLETE_RESPONSE ); // Mandatory initial value
|
||||
|
||||
|
||||
#ifdef INJECT_ERROR
|
||||
if (i > 90) trans->set_streaming_width(2);
|
||||
#endif
|
||||
|
||||
// Other fields default: byte enable = 0, streaming width = 0, DMI_hint = false, no extensions
|
||||
|
||||
socket->b_transport( *trans, delay ); // Blocking transport call
|
||||
|
||||
// Initiator obliged to check response status
|
||||
if ( trans->is_response_error() )
|
||||
{
|
||||
// Print response string
|
||||
char txt[100];
|
||||
sprintf(txt, "Error from b_transport, response status = %s",
|
||||
trans->get_response_string().c_str());
|
||||
SC_REPORT_ERROR("TLM-2", txt);
|
||||
|
||||
}
|
||||
|
||||
// Check DMI hint
|
||||
if ( trans->is_dmi_allowed() )
|
||||
{
|
||||
// *********************************************
|
||||
// Re-use transaction object for DMI. Reset the address because it could
|
||||
// have been modified by the interconnect on the previous transport call
|
||||
// *********************************************
|
||||
|
||||
trans->set_address( i );
|
||||
dmi_ptr_valid = socket->get_direct_mem_ptr( *trans, dmi_data );
|
||||
}
|
||||
|
||||
SCCDEBUG() << "trans = { " << (cmd ? 'W' : 'R') << ", " << hex << i
|
||||
<< " } , data = " << hex << data << " at time " << sc_time_stamp();
|
||||
}
|
||||
}
|
||||
|
||||
// Use debug transaction interface to dump memory contents, reusing same transaction object
|
||||
sc_dt::uint64 A = 128;
|
||||
trans->set_address(A);
|
||||
trans->set_read();
|
||||
trans->set_data_length(256);
|
||||
|
||||
unsigned char* data = new unsigned char[256];
|
||||
trans->set_data_ptr(data);
|
||||
|
||||
unsigned int n_bytes = socket->transport_dbg( *trans );
|
||||
|
||||
for (unsigned int i = 0; i < n_bytes; i += 4)
|
||||
{
|
||||
SCCTRACE() << "mem[" << (A + i) << "] = "
|
||||
<< *(reinterpret_cast<unsigned int*>( &data[i] ));
|
||||
}
|
||||
|
||||
A = 256;
|
||||
trans->set_address(A);
|
||||
trans->set_data_length(128);
|
||||
|
||||
n_bytes = socket->transport_dbg( *trans );
|
||||
|
||||
for (unsigned int i = 0; i < n_bytes; i += 4)
|
||||
{
|
||||
SCCTRACE() << "mem[" << (A + i) << "] = "
|
||||
<< *(reinterpret_cast<unsigned int*>( &data[i] ));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
43
vp_components/initiator.h
Normal file
43
vp_components/initiator.h
Normal file
@ -0,0 +1,43 @@
|
||||
#ifndef INITIATOR_H
|
||||
#define INITIATOR_H
|
||||
|
||||
#include "systemc"
|
||||
using namespace sc_core;
|
||||
using namespace sc_dt;
|
||||
using namespace std;
|
||||
|
||||
#include "tlm.h"
|
||||
#include "tlm_utils/simple_initiator_socket.h"
|
||||
#include <scc/utilities.h>
|
||||
|
||||
// Initiator module generating generic payload transactions
|
||||
|
||||
struct Initiator: sc_module
|
||||
{
|
||||
// TLM-2 socket, defaults to 32-bits wide, base protocol
|
||||
tlm_utils::simple_initiator_socket<Initiator> socket;
|
||||
|
||||
sc_core::sc_in<sc_core::sc_time> clk_i;
|
||||
sc_core::sc_in<sc_dt::sc_logic> reset_i;
|
||||
|
||||
SC_HAS_PROCESS(Initiator);
|
||||
|
||||
Initiator( ::sc_core::sc_module_name );
|
||||
|
||||
void thread_process();
|
||||
|
||||
// TLM-2 backward DMI method
|
||||
void invalidate_direct_mem_ptr(sc_dt::uint64 start_range, sc_dt::uint64 end_range){
|
||||
// Ignore range and invalidate all DMI pointers regardless
|
||||
dmi_ptr_valid = false;
|
||||
}
|
||||
|
||||
bool dmi_ptr_valid;
|
||||
tlm::tlm_dmi dmi_data;
|
||||
|
||||
void trace(sc_core::sc_trace_file* trf) const override {
|
||||
TRACE_VAR(trf, dmi_ptr_valid);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
25
vp_components/resetgen.cpp
Normal file
25
vp_components/resetgen.cpp
Normal file
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* resetgen.cpp
|
||||
*
|
||||
* Created on: 02.01.2019
|
||||
* Author: eyck
|
||||
*/
|
||||
|
||||
#include <resetgen.h>
|
||||
#include <scc/utilities.h>
|
||||
|
||||
ResetGen::ResetGen(const sc_core::sc_module_name& nm)
|
||||
: sc_core::sc_module(nm)
|
||||
, reset_o("reset_o")
|
||||
{
|
||||
SC_THREAD(thread);
|
||||
}
|
||||
|
||||
ResetGen::~ResetGen() {
|
||||
}
|
||||
|
||||
void ResetGen::thread() {
|
||||
reset_o=sc_dt::SC_LOGIC_1;
|
||||
wait(100_ns);
|
||||
reset_o=sc_dt::SC_LOGIC_0;
|
||||
}
|
26
vp_components/resetgen.h
Normal file
26
vp_components/resetgen.h
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* resetgen.h
|
||||
*
|
||||
* Created on: 02.01.2019
|
||||
* Author: eyck
|
||||
*/
|
||||
|
||||
#ifndef VP_COMPONENTS_RESETGEN_H_
|
||||
#define VP_COMPONENTS_RESETGEN_H_
|
||||
|
||||
#include <systemc>
|
||||
|
||||
class ResetGen: public sc_core::sc_module {
|
||||
public:
|
||||
SC_HAS_PROCESS(ResetGen);
|
||||
|
||||
sc_core::sc_out<sc_dt::sc_logic> reset_o;
|
||||
|
||||
ResetGen(const sc_core::sc_module_name&);
|
||||
virtual ~ResetGen();
|
||||
protected:
|
||||
|
||||
void thread();
|
||||
};
|
||||
|
||||
#endif /* VP_COMPONENTS_RESETGEN_H_ */
|
138
vp_components/router.h
Normal file
138
vp_components/router.h
Normal file
@ -0,0 +1,138 @@
|
||||
#ifndef ROUTER_H
|
||||
#define ROUTER_H
|
||||
|
||||
#include "systemc"
|
||||
using namespace sc_core;
|
||||
using namespace sc_dt;
|
||||
using namespace std;
|
||||
|
||||
#include "tlm.h"
|
||||
#include "tlm_utils/simple_initiator_socket.h"
|
||||
#include "tlm_utils/simple_target_socket.h"
|
||||
|
||||
|
||||
// *********************************************
|
||||
// Generic payload blocking transport router
|
||||
// *********************************************
|
||||
|
||||
template<unsigned int N_TARGETS>
|
||||
struct Router: sc_module
|
||||
{
|
||||
// TLM-2 socket, defaults to 32-bits wide, base protocol
|
||||
tlm_utils::simple_target_socket<Router> target_socket;
|
||||
|
||||
// *********************************************
|
||||
// Use tagged sockets to be able to distinguish incoming backward path calls
|
||||
// *********************************************
|
||||
|
||||
sc_core::sc_vector<tlm_utils::simple_initiator_socket_tagged<Router>> initiator_socket;
|
||||
|
||||
sc_core::sc_in<sc_core::sc_time> clk_i;
|
||||
sc_core::sc_in<sc_dt::sc_logic> reset_i;
|
||||
|
||||
SC_CTOR(Router)
|
||||
: target_socket("target_socket")
|
||||
, initiator_socket("socket", N_TARGETS)
|
||||
, clk_i("clk_i")
|
||||
, reset_i("reset_i")
|
||||
{
|
||||
// Register callbacks for incoming interface method calls
|
||||
target_socket.register_b_transport( this, &Router::b_transport);
|
||||
target_socket.register_get_direct_mem_ptr(this, &Router::get_direct_mem_ptr);
|
||||
target_socket.register_transport_dbg( this, &Router::transport_dbg);
|
||||
|
||||
for (unsigned int i = 0; i < N_TARGETS; i++)
|
||||
{
|
||||
char txt[20];
|
||||
sprintf(txt, "socket_%d", i);
|
||||
|
||||
// *********************************************
|
||||
// Register callbacks for incoming interface method calls, including tags
|
||||
// *********************************************
|
||||
initiator_socket[i].register_invalidate_direct_mem_ptr(this, &Router::invalidate_direct_mem_ptr, i);
|
||||
}
|
||||
}
|
||||
|
||||
// ****************
|
||||
// FORWARD PATH
|
||||
// ****************
|
||||
|
||||
// TLM-2 blocking transport method
|
||||
virtual void b_transport( tlm::tlm_generic_payload& trans, sc_time& delay )
|
||||
{
|
||||
sc_dt::uint64 address = trans.get_address();
|
||||
sc_dt::uint64 masked_address;
|
||||
unsigned int target_nr = decode_address( address, masked_address);
|
||||
|
||||
// Modify address within transaction
|
||||
trans.set_address( masked_address );
|
||||
|
||||
// Forward transaction to appropriate target
|
||||
initiator_socket[target_nr]->b_transport( trans, delay );
|
||||
}
|
||||
|
||||
// TLM-2 forward DMI method
|
||||
virtual bool get_direct_mem_ptr(tlm::tlm_generic_payload& trans,
|
||||
tlm::tlm_dmi& dmi_data)
|
||||
{
|
||||
sc_dt::uint64 masked_address;
|
||||
unsigned int target_nr = decode_address( trans.get_address(), masked_address );
|
||||
trans.set_address( masked_address );
|
||||
|
||||
bool status = initiator_socket[target_nr]->get_direct_mem_ptr( trans, dmi_data );
|
||||
|
||||
// Calculate DMI address of target in system address space
|
||||
dmi_data.set_start_address( compose_address( target_nr, dmi_data.get_start_address() ));
|
||||
dmi_data.set_end_address ( compose_address( target_nr, dmi_data.get_end_address() ));
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
// TLM-2 debug transaction method
|
||||
virtual unsigned int transport_dbg(tlm::tlm_generic_payload& trans)
|
||||
{
|
||||
sc_dt::uint64 masked_address;
|
||||
unsigned int target_nr = decode_address( trans.get_address(), masked_address );
|
||||
trans.set_address( masked_address );
|
||||
|
||||
// Forward debug transaction to appropriate target
|
||||
return initiator_socket[target_nr]->transport_dbg( trans );
|
||||
}
|
||||
|
||||
// ****************
|
||||
// BACKWARD PATH
|
||||
// ****************
|
||||
|
||||
// **************************
|
||||
// Tagged backward DMI method
|
||||
// **************************
|
||||
|
||||
virtual void invalidate_direct_mem_ptr(int id,
|
||||
sc_dt::uint64 start_range,
|
||||
sc_dt::uint64 end_range)
|
||||
{
|
||||
// Reconstruct address range in system memory map
|
||||
sc_dt::uint64 bw_start_range = compose_address( id, start_range );
|
||||
sc_dt::uint64 bw_end_range = compose_address( id, end_range );
|
||||
target_socket->invalidate_direct_mem_ptr(bw_start_range, bw_end_range);
|
||||
}
|
||||
|
||||
// ****************
|
||||
// ROUTER INTERNALS
|
||||
// ****************
|
||||
|
||||
// Simple fixed address decoding
|
||||
inline unsigned int decode_address( sc_dt::uint64 address, sc_dt::uint64& masked_address )
|
||||
{
|
||||
unsigned int target_nr = static_cast<unsigned int>( (address >> 10) % initiator_socket.size() );
|
||||
masked_address = address & 0x3FF;
|
||||
return target_nr;
|
||||
}
|
||||
|
||||
inline sc_dt::uint64 compose_address( unsigned int target_nr, sc_dt::uint64 address)
|
||||
{
|
||||
return (target_nr << 10) | (address & 0x3FF);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
105
vp_components/target.cpp
Normal file
105
vp_components/target.cpp
Normal file
@ -0,0 +1,105 @@
|
||||
/*
|
||||
* target.cpp
|
||||
*
|
||||
* Created on: 02.12.2018
|
||||
* Author: eyck
|
||||
*/
|
||||
|
||||
#include "target.h"
|
||||
|
||||
void Memory::b_transport(tlm::tlm_generic_payload& trans, sc_time& delay) {
|
||||
tlm::tlm_command cmd = trans.get_command();
|
||||
sc_dt::uint64 adr = trans.get_address() / 4;
|
||||
unsigned char* ptr = trans.get_data_ptr();
|
||||
unsigned int len = trans.get_data_length();
|
||||
unsigned char* byt = trans.get_byte_enable_ptr();
|
||||
unsigned int wid = trans.get_streaming_width();
|
||||
|
||||
// Obliged to check address range and check for unsupported features,
|
||||
// i.e. byte enables, streaming, and bursts
|
||||
// Can ignore extensions
|
||||
|
||||
// Generate the appropriate error response
|
||||
if (adr >= SIZE) {
|
||||
trans.set_response_status( tlm::TLM_ADDRESS_ERROR_RESPONSE );
|
||||
return;
|
||||
}
|
||||
if (byt != 0) {
|
||||
trans.set_response_status( tlm::TLM_BYTE_ENABLE_ERROR_RESPONSE );
|
||||
return;
|
||||
}
|
||||
if (len > 4 || wid < len) {
|
||||
trans.set_response_status( tlm::TLM_BURST_ERROR_RESPONSE );
|
||||
return;
|
||||
}
|
||||
|
||||
wait(delay);
|
||||
delay = SC_ZERO_TIME;
|
||||
|
||||
// Obliged to implement read and write commands
|
||||
if ( cmd == tlm::TLM_READ_COMMAND )
|
||||
memcpy(ptr, &mem[adr], len);
|
||||
else if ( cmd == tlm::TLM_WRITE_COMMAND )
|
||||
memcpy(&mem[adr], ptr, len);
|
||||
|
||||
// Set DMI hint to indicated that DMI is supported
|
||||
trans.set_dmi_allowed(true);
|
||||
|
||||
// Obliged to set response status to indicate successful completion
|
||||
trans.set_response_status( tlm::TLM_OK_RESPONSE );
|
||||
}
|
||||
|
||||
bool Memory::get_direct_mem_ptr(tlm::tlm_generic_payload& trans,
|
||||
tlm::tlm_dmi& dmi_data)
|
||||
{
|
||||
// Permit read and write access
|
||||
dmi_data.allow_read_write();
|
||||
|
||||
// Set other details of DMI region
|
||||
dmi_data.set_dmi_ptr( reinterpret_cast<unsigned char*>( &mem[0] ) );
|
||||
dmi_data.set_start_address( 0 );
|
||||
dmi_data.set_end_address( SIZE*4-1 );
|
||||
dmi_data.set_read_latency( LATENCY );
|
||||
dmi_data.set_write_latency( LATENCY );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Memory::Memory(sc_core::sc_module_name nm)
|
||||
: socket("socket")
|
||||
, clk_i("clk_i")
|
||||
, reset_i("reset_i")
|
||||
, LATENCY(10, SC_NS)
|
||||
{
|
||||
// Register callbacks for incoming interface method calls
|
||||
socket.register_b_transport( this, &Memory::b_transport);
|
||||
socket.register_get_direct_mem_ptr(this, &Memory::get_direct_mem_ptr);
|
||||
socket.register_transport_dbg( this, &Memory::transport_dbg);
|
||||
|
||||
// Initialize memory with random data
|
||||
for (int i = 0; i < SIZE; i++)
|
||||
mem[i] = 0xAA000000 | (mem_nr << 20) | (rand() % 256);
|
||||
|
||||
++mem_nr;
|
||||
}
|
||||
|
||||
// TLM-2 debug transaction method
|
||||
unsigned int Memory::transport_dbg(tlm::tlm_generic_payload& trans)
|
||||
{
|
||||
tlm::tlm_command cmd = trans.get_command();
|
||||
sc_dt::uint64 adr = trans.get_address() / 4;
|
||||
unsigned char* ptr = trans.get_data_ptr();
|
||||
unsigned int len = trans.get_data_length();
|
||||
|
||||
// Calculate the number of bytes to be actually copied
|
||||
unsigned int num_bytes = (len < (SIZE - adr) * 4) ? len : (SIZE - adr) * 4;
|
||||
|
||||
if ( cmd == tlm::TLM_READ_COMMAND )
|
||||
memcpy(ptr, &mem[adr], num_bytes);
|
||||
else if ( cmd == tlm::TLM_WRITE_COMMAND )
|
||||
memcpy(&mem[adr], ptr, num_bytes);
|
||||
|
||||
return num_bytes;
|
||||
}
|
||||
|
||||
|
49
vp_components/target.h
Normal file
49
vp_components/target.h
Normal file
@ -0,0 +1,49 @@
|
||||
#ifndef TARGET_H
|
||||
#define TARGET_H
|
||||
|
||||
// Needed for the simple_target_socket
|
||||
#define SC_INCLUDE_DYNAMIC_PROCESSES
|
||||
|
||||
#include "systemc"
|
||||
using namespace sc_core;
|
||||
using namespace sc_dt;
|
||||
using namespace std;
|
||||
|
||||
#include "tlm.h"
|
||||
#include "tlm_utils/simple_target_socket.h"
|
||||
|
||||
|
||||
// Target module representing a simple memory
|
||||
|
||||
struct Memory: sc_module
|
||||
{
|
||||
// TLM-2 socket, defaults to 32-bits wide, base protocol
|
||||
tlm_utils::simple_target_socket<Memory> socket;
|
||||
sc_core::sc_in<sc_core::sc_time> clk_i;
|
||||
sc_core::sc_in<sc_dt::sc_logic> reset_i;
|
||||
|
||||
|
||||
enum { SIZE = 256 };
|
||||
const sc_time LATENCY;
|
||||
|
||||
SC_HAS_PROCESS(Memory);
|
||||
|
||||
Memory(sc_core::sc_module_name nm);
|
||||
|
||||
protected:
|
||||
// TLM-2 blocking transport method
|
||||
void b_transport( tlm::tlm_generic_payload& trans, sc_time& delay );
|
||||
|
||||
// TLM-2 forward DMI method
|
||||
bool get_direct_mem_ptr(tlm::tlm_generic_payload& trans,
|
||||
tlm::tlm_dmi& dmi_data);
|
||||
// TLM-2 debug transaction method
|
||||
unsigned int transport_dbg(tlm::tlm_generic_payload& trans);
|
||||
|
||||
int mem[SIZE];
|
||||
static unsigned int mem_nr;
|
||||
};
|
||||
|
||||
unsigned int Memory::mem_nr = 0;
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user