KONRAD Frederic
Builds for 1 pipeline passed in 4 minutes 27 seconds

Merge branch 'fixes' into 'master'

Fixes V2

This implements byte enable and add a test case for it.
It adds a minimal gitlab-ci file as well.
It fixes the DMI pointer.

See merge request !7
... ... @@ -20,3 +20,4 @@ Testing/
# Objects
test/simplememory-test
test/dualportmemory-test
test/byteenable-test
... ...
# Templates
.job_unix_makefile: &job_unix_makefile
before_script:
- mkdir greenlib-prefix
- git clone https://git.greensocs.com/greenlib/greenlib.git greenlib
- cd greenlib
- cmake . -DCMAKE_INSTALL_PREFIX=`pwd`/../greenlib-prefix
- make
- make install
- cd ..
script:
- cmake . -DGREENLIB_PREFIX=`pwd`/greenlib-prefix -DSYSTEMC_PREFIX=$SYSTEMC_HOME_2_3_1
- make
- make test
# Jobs
## Linux
Linux:
variables:
CC: "gcc"
CXX: "g++"
<<: *job_unix_makefile
... ...
... ... @@ -141,42 +141,89 @@ public:
return;
}
if (t->getMCmd() == gs::Generic_MCMD_RD)
if (!t->get_tlm_transaction()->get_byte_enable_ptr())
{
gs::GSDataType::dtype tmp(&(((uint8_t *)m_ptr)[offset]), size);
gs::MData mdata(tmp);
t->setSData(mdata);
}
else if (t->getMCmd() == gs::Generic_MCMD_WR)
{
/*
* FIXME: We should give a bad status for that...
*/
if (!m_ro)
if (t->getMCmd() == gs::Generic_MCMD_RD)
{
gs::GSDataType::dtype tmp(&(((uint8_t *)m_ptr)[offset]), size);
gs::MData mdata(tmp);
t->setSData(mdata);
}
else if (t->getMCmd() == gs::Generic_MCMD_WR)
{
/*
* FIXME: We should give a bad status for that...
*/
if (!m_ro)
{
memcpy(&(((uint8_t *)m_ptr)[offset]), &(t->getMData()[0]),
size);
}
}
else
{
memcpy(&(((uint8_t *)m_ptr)[offset]), &(t->getMData()[0]),
size);
std::cout << "Invalid command ..." << std::endl;
sc_core::sc_stop();
return;
}
}
else
{
std::cout << "Invalid command ..." << std::endl;
sc_core::sc_stop();
return;
unsigned int i;
unsigned char *mask =
t->get_tlm_transaction()->get_byte_enable_ptr();
unsigned int mask_len =
t->get_tlm_transaction()->get_byte_enable_length();
if (size > mask_len)
{
std::cout << "Invalid mask length ..." << std::endl;
sc_core::sc_stop();
return;
}
if (t->getMCmd() == gs::Generic_MCMD_RD)
{
for (i = 0; i < size; i++)
{
t->getMData()[i] = (mask[i] == 0xff)
? ((uint8_t *)m_ptr)[offset + i]
: 0;
}
}
else if (t->getMCmd() == gs::Generic_MCMD_WR)
{
if (!m_ro)
{
for (i = 0; i < size; i++)
{
((uint8_t *)m_ptr)[offset + i] = (mask[i] == 0xff)
? t->getMData()[i]
: ((uint8_t *)m_ptr)[offset + i];
}
}
}
else
{
std::cout << "Invalid command ..." << std::endl;
sc_core::sc_stop();
return;
}
}
}
/*
* XXX: What about Read Only??
*/
bool get_direct_mem_ptr(unsigned int from,
tlm::tlm_generic_payload& trans,
bool get_direct_mem_ptr(unsigned int from, uint64_t offset,
tlm::tlm_generic_payload& payload,
tlm::tlm_dmi& dmi_data)
{
dmi_data.set_dmi_ptr((unsigned char *)m_ptr);
dmi_data.set_start_address(0);
dmi_data.set_end_address(m_size * 1024 - 1);
trans.set_dmi_allowed(true);
dmi_data.set_start_address(offset);
dmi_data.set_end_address(offset + m_size * 1024 - 1);
payload.set_dmi_allowed(true);
return true;
}
... ...
... ... @@ -36,14 +36,14 @@ public:
this->targetPort0.register_transport_dbg(this,
&DualPortMemory::dbg_transact_0);
this->targetPort0.register_get_direct_mem_ptr(this,
&DualPortMemory::get_direct_mem_ptr);
&DualPortMemory::get_direct_mem_ptr_0);
wrap_2.register_b_transport(&DualPortMemory::b_transact_1, this);
this->targetPort1.bind_b_if(wrap_2);
this->targetPort1.register_transport_dbg(this,
&DualPortMemory::dbg_transact_1);
this->targetPort1.register_get_direct_mem_ptr(this,
&DualPortMemory::get_direct_mem_ptr);
&DualPortMemory::get_direct_mem_ptr_1);
}
unsigned int dbg_transact_0(unsigned int index,
... ... @@ -78,6 +78,27 @@ public:
BaseMemory::b_transact(t, offset);
}
bool get_direct_mem_ptr_0(unsigned int from,
tlm::tlm_generic_payload& payload,
tlm::tlm_dmi& dmi_data)
{
/* Wrap get_direct_mem_ptr() to get the port offset in BaseMemory */
return BaseMemory::get_direct_mem_ptr(from, targetPort0.base_addr,
payload, dmi_data);
}
bool get_direct_mem_ptr_1(unsigned int from,
tlm::tlm_generic_payload& payload,
tlm::tlm_dmi& dmi_data)
{
/* Wrap get_direct_mem_ptr() to get the port offset in BaseMemory */
return BaseMemory::get_direct_mem_ptr(from, targetPort1.base_addr,
payload, dmi_data);
}
void end_of_elaboration()
{
this->allocate_memory(m_size, m_ro);
... ...
... ... @@ -106,6 +106,16 @@ class Memory:
return BaseMemory::dbg_transport(payload, offset);
}
bool get_direct_mem_ptr(unsigned int from,
tlm::tlm_generic_payload& payload,
tlm::tlm_dmi& dmi_data)
{
/* Wrap get_direct_mem_ptr() to get the port offset in BaseMemory */
return BaseMemory::get_direct_mem_ptr(from, target_port.base_addr,
payload, dmi_data);
}
/*
* Socket for memory access.
*/
... ...
/*
* ByteEnableTest.cpp
*
* Copyright (C) 2016, GreenSocs Ltd.
*
* Developed by Konrad Frederic <fred.konrad@greensocs.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses>.
*
* Linking GreenSocs code, statically or dynamically with other modules
* is making a combined work based on GreenSocs code. Thus, the terms and
* conditions of the GNU General Public License cover the whole
* combination.
*
* In addition, as a special exception, the copyright holders, GreenSocs
* Ltd, give you permission to combine GreenSocs code with free software
* programs or libraries that are released under the GNU LGPL, under the
* OSCI license, under the OCP TLM Kit Research License Agreement or
* under the OVP evaluation license.You may copy and distribute such a
* system following the terms of the GNU GPL and the licenses of the
* other code concerned.
*
* Note that people who make modified versions of GreenSocs code are not
* obligated to grant this special exception for their modified versions;
* it is their choice whether to do so. The GNU General Public License
* gives permission to release a modified version without this exception;
* this exception also makes it possible to release a modified version
* which carries forward this exception.
*
*/
#include "SimpleMemory/simpleMemory.h"
#include <greencontrol/config.h>
#include <gsgpsocket/transport/GSGPMasterBlockingSocket.h>
#include <gsgpsocket/transport/GSGPSlaveSocket.h>
#include <gsgpsocket/transport/GSGPconfig.h>
#define TEST(str) std::cout << "testing: " << str << std::endl;
#define ERROR(str) std::cout << "failed: " << str << std::endl;
#define SUCCESS() std::cout << "success" << std::endl;
#define INFO(str) std::cout << "info: " << str << std::endl;
class TestMaster:
public sc_module,
public gs::payload_event_queue_output_if<gs::gp::master_atom>
{
public:
SC_HAS_PROCESS(TestMaster);
TestMaster(sc_module_name name):
sc_module(name),
master_socket("master_port")
{
master_socket.out_port(*this);
fail = false;
SC_THREAD(testing);
};
~TestMaster() {};
void notify(gs::gp::master_atom& tc) {};
void end_of_elaboration()
{
tHandle = master_socket.create_transaction();
}
typedef gs::gp::GenericMasterBlockingPort<32>::accessHandle
transactionHandle;
gs::gp::GenericMasterBlockingPort<32> master_socket;
bool fail;
private:
transactionHandle tHandle;
bool testResponse()
{
if (tHandle->getSResp() != gs::Generic_SRESP_DVA)
{
return false;
}
return true;
}
void write(uint64_t address, const uint32_t value,
unsigned char *byte_enable, unsigned int byte_enable_len)
{
gs::GSDataType::dtype data =
gs::GSDataType::dtype((unsigned char *)&value, sizeof(value));
tHandle->setMBurstLength(4);
tHandle->setMAddr(address);
tHandle->setMData(data);
tHandle->setMCmd(gs::Generic_MCMD_WR);
tHandle->get_tlm_transaction()->set_byte_enable_ptr(byte_enable);
tHandle->get_tlm_transaction()->set_byte_enable_length(byte_enable_len);
master_socket.Transact(tHandle);
if (!testResponse())
{
this->fail = true;
}
}
uint32_t read(uint64_t address, unsigned char *byte_enable,
unsigned int byte_enable_len)
{
uint32_t value = 0;
gs::GSDataType::dtype data =
gs::GSDataType::dtype((unsigned char *)&value, sizeof(value));
tHandle->setMBurstLength(4);
tHandle->setMAddr(address);
tHandle->setMData(data);
tHandle->setMCmd(gs::Generic_MCMD_RD);
tHandle->get_tlm_transaction()->set_byte_enable_ptr(byte_enable);
tHandle->get_tlm_transaction()->set_byte_enable_length(byte_enable_len);
master_socket.Transact(tHandle);
value = *((uint32_t *)data.getData());
if (!testResponse())
{
this->fail = true;
}
return value;
}
void testing()
{
uint32_t w_mask = 0xFF00FF00;
uint32_t r_mask = 0x0000FF00;
uint32_t value_w = 0xDEADBEEF;
uint32_t value_r = 0;
TEST("Writing 0xDEADBEEF with a 0xFF00FF00 masks.");
this->write(0, value_w, (unsigned char *)&w_mask, sizeof(w_mask));
if (this->fail)
{
ERROR("Failed to write to the memory.");
return;
}
value_r = this->read(0, NULL, 0);
if (this->fail)
{
ERROR("Failed to read from the memory.");
return;
}
if (value_r != (value_w & w_mask))
{
ERROR("The write masking failed: expected " << (value_w & w_mask)
<< " got " << value_r);
this->fail = true;
return;
}
value_r = this->read(0, (unsigned char *)&r_mask, sizeof(r_mask));
if (this->fail)
{
ERROR("Failed to read from the memory.");
this->fail = true;
return;
}
if (value_r != (value_w & w_mask & r_mask))
{
ERROR("The read masking failed: expected "
<< (value_w & w_mask & r_mask) << " got " << value_r);
this->fail = true;
return;
}
SUCCESS();
};
};
int sc_main(int argc, char *argv[])
{
Memory<32> *mem = new Memory<32>("mem");
TestMaster *initiator = new TestMaster("initiator");
initiator->master_socket(mem->target_port);
sc_start();
return initiator->fail;
}
... ...
... ... @@ -9,6 +9,7 @@
add_executable(simplememory-test SimpleMemoryTest.cpp)
add_executable(dualportmemory-test DualPortMemoryTest.cpp)
add_executable(byteenable-test ByteEnableTest.cpp)
set(TEST_LINK_LIBRARIES ${SystemC_LIBRARIES})
if(MINGW)
... ... @@ -17,6 +18,8 @@ endif(MINGW)
target_link_libraries(simplememory-test ${TEST_LINK_LIBRARIES})
target_link_libraries(dualportmemory-test ${TEST_LINK_LIBRARIES})
target_link_libraries(byteenable-test ${TEST_LINK_LIBRARIES})
add_test(NAME simplememory COMMAND ./simplememory-test)
add_test(NAME dualportmemory COMMAND ./dualportmemory-test)
add_test(NAME byteenable COMMAND ./byteenable-test)
... ...