Commit cae24b3c authored by Ludovic Apvrille's avatar Ludovic Apvrille
Browse files

Merge branch 'master' of gitlab.enst.fr:mbe-tools/TTool

parents dcb951b1 4aa402ed
......@@ -73,10 +73,14 @@ MEMORY
mem_rom (RXAL): ORIGIN = CONFIG_ROM_ADDR, LENGTH = CONFIG_ROM_SIZE
#endif
mem_ram (RWAL): ORIGIN = CONFIG_RAM_ADDR, LENGTH = CONFIG_RAM_SIZE
//ajoute DG provisiore
//mwmr_ram (RWAL): ORIGIN = 0xA0200000, LENGTH = 0x00001000
//mwmrd_ram (RWAL): ORIGIN = 0xB0200000, LENGTH = 0x00003000
//19.05. une seule RAMLOCKS en cas de besoin (actually unused)
//DG 7.9.
#if defined(MWMR_RAM0_NAME)
mwmr_ram0 (RWAL): ORIGIN = 0xA0200000, LENGTH = 0x00001000
#endif
#if defined(MWMR_RAM1_NAME)
mwmr_ram1 (RWAL): ORIGIN = 0xA1200000, LENGTH = 0x00001000
#endif
vci_locks (RWAL): ORIGIN = 0xC0200000, LENGTH = 0x100
//ajout CD
......
Module('caba:MyHWA0',
classname = 'dsx::caba::MyHWA0',
header_files = [
"my_hwa0.h",
],
interface_files = [
],
implementation_files = [
"my_hwa0.cpp",
],
ports = [
],
uses = [
Uses('caba:fifo_virtual_copro_wrapper'),
],
instance_parameters = [
],
tmpl_parameters = [
],
extensions = [
],
)
#ifndef _HWA0_H
#define _HWA0_H
#include <systemc>
#include "fifo_virtual_copro_wrapper.h"
namespace dsx { namespace caba {
class MyHWA0
: public dsx::caba::FifoVirtualCoprocessorWrapper
{
public:
~MyHWA0();
MyHWA0(sc_core::sc_module_name insname);
private:
void * task_func(); // Task code
};
}}
#endif
/* -*- c++ -*-
*
* SOCLIB_LGPL_HEADER_BEGIN
*
* This file is part of SoCLib, GNU LGPLv2.1.
*
* SoCLib is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; version 2.1 of the License.
*
* SoCLib 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with SoCLib; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA
*
* SOCLIB_LGPL_HEADER_END
*
*
* Copyright (c) CEA-LETI, MINATEC, 2008
*
* Authors :
*
* History :
*
* Comment :
*
*/
#include "anoc_copro_wrapper.h"
namespace soclib { namespace caba {
using soclib::common::alloc_elems;
using soclib::common::dealloc_elems;
/*******************************************************************************/
/*******************************************************************************/
/// Constructor
anoc_copro_wrapper::anoc_copro_wrapper(sc_module_name module_name_,
t_uint16 nb_cores_,
t_uint16 nb_fifo_in_,
t_uint16 nb_fifo_out_,
t_uint16 n_config_,
t_uint16 n_status_,
t_uint32 clk_period_) :
sc_module(module_name_),
p_from_MWMR(alloc_elems<FifoInput<uint32_t> >("p_from_MWMR", nb_fifo_in_)),
p_to_MWMR(alloc_elems<FifoOutput<uint32_t> >("p_to_MWMR", nb_fifo_out_ )),
p_config(alloc_elems<sc_in<uint32_t> >("p_config", n_config_)),
p_status(alloc_elems<sc_out<uint32_t> >("p_status", n_status_)),
nb_cores(nb_cores_),
nb_fifo_in(nb_fifo_in_),
nb_fifo_out(nb_fifo_out_),
clk_period(clk_period_)
{
core_fifo_in = new t_uint16[nb_fifo_in];
for(int i=0; i<nb_fifo_in; i++) {
if(nb_cores>1) {
// core_fifo_in[i] = core_fifo_in_[i];
} else {
core_fifo_in[i] = 0; // monocore, core_fifo_in_=NULL
}
}
core_fifo_out = new t_uint16[nb_fifo_out];
for(int i=0; i<nb_fifo_out; i++) {
if(nb_cores>1) {
// core_fifo_out[i] = core_fifo_out_[i];
} else {
core_fifo_out[i] = 0; // monocore, core_fifo_out_=NULL
}
}
cfg_flag_core_finished = new bool [nb_cores];
for(int i = 0; i < nb_cores; i++) {
cfg_flag_core_finished[i]=true;
}
// create ni => core ports
#ifdef TLM_TRANS_RECORD
char port_in[80];
char port_out[80];
char port_debug[80];
#endif
char port_out_name[80];
char port_in_name[80];
#ifdef TLM_TRANS_RECORD
sprintf(port_in,"%s_IN", basename());
sprintf(port_out,"%s_OUT", basename());
sprintf(port_debug,"%s_DEBUG", basename());
#endif // TLM_TRANS_RECORD
ni_exec_out = new ni_exec_out_port*[nb_cores];
for(int i=0;i<nb_cores;i++) {
sprintf(port_out_name,"ni_exec_out_port_%i", i);
ni_exec_out[i] = new ni_exec_out_port((char *) port_out_name, "exec", "eoc");
ni_exec_out[i]->put_if_bind(*this); // for the status target sub-port
}
ni_cfg_dump_out = new ni_cfg_dump_out_port("ni_cfg_dump_out_port", "cfg_dump", "dump_data");
ni_cfg_dump_out->put_if_bind(*this); // for the status target sub-port
t_uint16 fifo_id[nb_cores];
for (int i=0; i<nb_cores; i++) {
fifo_id[i]=0;
}
ni_input_fifo_out = new ni_data_out_port*[nb_fifo_in];
for(int i=0;i<nb_fifo_in;i++) {
sprintf(port_out_name,"ni_input_fifo_out_port_%i", i);
#ifdef TLM_TRANS_RECORD
sprintf(port_out,"%s_input_fifo_out_%i", basename(), i);
ni_input_fifo_out[i] = new ni_data_out_port((char *) port_out_name, (char *)port_out, fifo_id[core_fifo_in[i]]);
#else
ni_input_fifo_out[i] = new ni_data_out_port((char *) port_out_name, fifo_id[core_fifo_in[i]]);
#endif // TLM_TRANS_RECORD
fifo_id[core_fifo_in[i]]++;
ni_input_fifo_out[i]->put_if_bind(*this); // for the status target sub-port
}
// create core => ni ports
for (int i=0; i<nb_cores; i++) {
fifo_id[i]=0;
}
ni_output_fifo_in = new ni_data_in_port*[nb_fifo_out];
for(int i=0;i<nb_fifo_out;i++) {
sprintf(port_in_name,"ni_output_fifo_in_port_%i", i);
#ifdef TLM_TRANS_RECORD
sprintf(port_in,"%s_output_fifo_in_%i", basename(), i);
ni_output_fifo_in[i] = new ni_data_in_port((char *) port_in_name, (char *)port_in, fifo_id[core_fifo_out[i]]);
#else
ni_output_fifo_in[i] = new ni_data_in_port((char *) port_in_name, fifo_id[core_fifo_out[i]]);
#endif // TLM_TRANS_RECORD
fifo_id[core_fifo_out[i]]++;
ni_output_fifo_in[i]->put_if_bind(*this); // for the status target sub-port
}
ni_released_in = new ni_released_in_port*[nb_fifo_in];
for(int i=0;i<nb_fifo_in;i++) {
sprintf(port_in_name,"ni_released_in_port_%i", i);
#ifdef TLM_TRANS_RECORD
sprintf(port_in,"%s_released_in_%i", basename(), i);
ni_released_in[i] = new ni_released_in_port((char *) port_in_name, (char *)port_in);
#else
ni_released_in[i] = new ni_released_in_port((char *) port_in_name);
#endif // TLM_TRANS_RECORD
ni_released_in[i]->put_if_bind(*this); // for the status target sub-port
}
ni_available_in = new ni_available_in_port*[nb_fifo_out];
for(int i=0;i<nb_fifo_out;i++) {
sprintf(port_in_name,"ni_available_in_port_%i", i);
#ifdef TLM_TRANS_RECORD
sprintf(port_in,"%s_available_in_%i", basename(), i);
ni_available_in[i] = new ni_available_in_port((char *) port_in_name, (char *)port_in);
#else
ni_available_in[i] = new ni_available_in_port((char *) port_in_name);
#endif // TLM_TRANS_RECORD
ni_available_in[i]->put_if_bind(*this); // for the status target sub-port
}
ni_status_in = new ni_status_in_port*[nb_cores];
for(int i=0;i<nb_cores;i++) {
sprintf(port_in_name,"ni_status_in_port_%i", i);
#ifdef TLM_TRANS_RECORD
sprintf(port_in,"%s_status_in_%i", basename(), i);
ni_status_in[i] = new ni_status_in_port((char *) port_in_name, (char *)port_in);
#else
ni_status_in[i] = new ni_status_in_port((char *) port_in_name);
#endif // TLM_TRANS_RECORD
ni_status_in[i]->put_if_bind(*this); // for the status target sub-port
}
/***********************************************/
// internal programmation
/***********************************************/
// internal state variables
last_status = new t_uint32[nb_cores];
for(int i=0; i<nb_cores; i++) {
last_status[i] = 0;
}
tab_out_data_fifo_out = new t_uint32[nb_fifo_out];
flag_tab_out_data_fifo_out = new bool[nb_fifo_out];
tab_available_data_fifo_out = new t_uint32[nb_fifo_out];
for (int i = 0; i < nb_fifo_out; i++) {
tab_out_data_fifo_out[i] = 0;
flag_tab_out_data_fifo_out[i] = false;
tab_available_data_fifo_out[i]=0;
}
tab_fifo_in_accept = new bool[nb_fifo_in];
for (int i = 0; i < nb_fifo_in; i++) {
// fifo accept is initialised to true: ready to accept a new value
tab_fifo_in_accept[i] = true;
}
/***********************************************/
// threads & methods
SC_METHOD(rtl_to_tlm);
sensitive << rtl_to_tlm_event;
dont_initialize();
SC_METHOD(tlm_to_rtl);
sensitive << p_clk.neg();
dont_initialize();
EXPRINT(ni, 2,"anoc_copro_wrapper CREATED");
}
/*******************************************************************************/
/*******************************************************************************/
/// Destructor
anoc_copro_wrapper::~anoc_copro_wrapper() {
cout << "-------------- DELETE " << name() << " -------------- " << endl;
delete core_fifo_in;
delete core_fifo_out;
for(int i=0;i<nb_cores;i++) {
delete ni_exec_out[i];
}
delete ni_exec_out;
delete ni_cfg_dump_out;
for(int i=0;i<nb_fifo_in;i++) {
delete ni_input_fifo_out[i];
}
delete ni_input_fifo_out;
for(int i=0;i<nb_fifo_out;i++) {
delete ni_output_fifo_in[i];
}
delete ni_output_fifo_in;
for(int i=0;i<nb_fifo_in;i++) {
delete ni_released_in[i];
}
delete ni_released_in;
for(int i=0;i<nb_fifo_out;i++) {
delete ni_available_in[i];
}
delete ni_available_in;
for(int i=0;i<nb_cores;i++) {
delete ni_status_in[i];
}
delete ni_status_in;
}
/*******************************************************************************/
/*******************************************************************************/
/// Receive DUMP DATA transaction (remote call)
void anoc_copro_wrapper::put(const ni_dump_data_transaction &transaction) {
//Not yet implemented
#ifdef _ANOC_COPRO_DEBUG
printf("DUMP DATA transaction\n");
#endif
}
/*******************************************************************************/
/*******************************************************************************/
/// Receive RELEASED transaction (remote call)
void anoc_copro_wrapper::put(const ni_released_transaction &transaction) {
#ifdef _ANOC_COPRO_DEBUG
printf("RELEASED transaction\n");
#endif
t_uint16 fifo_id = 0;
t_uint16 source_id;
t_uint16 core_id;
t_uint32 size_released;
bool fifo_ok = false;
source_id = transaction.get_source_id();
core_id = transaction.get_core_id();
size_released = transaction.get_data();
int j=0;
for(int i=0; i<nb_fifo_in; i++) {
if(core_fifo_in[i]==core_id) {
if(j==source_id) {
fifo_id = i;
fifo_ok=true;
}
j++;
}
}
if(fifo_ok) {
EXPRINT(ni, 1,"Receive released ("<< size_released <<") from fifo: " << fifo_id);
// tab_available_size_fifo_in[fifo_id]+=size_released;
} else {
EXPRINT(ni, 0,"ERROR : invalid source id " << source_id << " for released from CORE " << core_id);
exit(0);
}
}
/*******************************************************************************/
/*******************************************************************************/
/// Receive AVAILABLE transaction (remote call)
void anoc_copro_wrapper::put(const ni_available_transaction &transaction) {
#ifdef _ANOC_COPRO_DEBUG
printf("AVAILABLE transaction\n");
#endif
t_uint16 fifo_id = 0;
t_uint16 source_id;
t_uint16 core_id;
t_uint32 available_data;
bool fifo_ok = false;
source_id = transaction.get_source_id();
core_id = transaction.get_core_id();
available_data = transaction.get_data();
int j=0;
for(int i=0; i<nb_fifo_out; i++) {
if(core_fifo_out[i]==core_id) {
if(j==source_id) {
fifo_id = i;
fifo_ok=true;
}
j++;
}
}
if(fifo_ok) {
EXPRINT(ni, 1,"Receive available (" << available_data << ") from fifo: " << fifo_id);
tab_available_data_fifo_out[fifo_id] = available_data;
} else {
EXPRINT(ni, 0,"ERROR : invalid source id " << source_id << " for avaivable from CORE " << core_id);
exit(0);
}
}
/*******************************************************************************/
/*******************************************************************************/
/// Receive WRITE DATA transaction (remote call)
void anoc_copro_wrapper::put(const ni_write_data_transaction &transaction) {
#ifdef _ANOC_COPRO_DEBUG
printf("Received DATA transaction\n");
#endif
t_uint16 fifo_id = 0;
t_uint16 source_id;
t_uint16 core_id;
t_uint32 data;
bool fifo_ok = false;
source_id = transaction.get_source_id();
core_id = transaction.get_core_id();
data = transaction.get_data();
int j=0;
for(int i=0; i<nb_fifo_out; i++) {
if(core_fifo_out[i]==core_id) {
if(j==source_id) {
fifo_id = i;
fifo_ok=true;
}
j++;
}
}
if(fifo_ok) {
EXPRINT(ni, 1,"Receive write data: " << data << " from fifo: " << fifo_id);
tab_out_data_fifo_out[fifo_id] = data;
flag_tab_out_data_fifo_out[fifo_id] = true;
//Requires a data update on the RTL ports
write_data_update = true;
} else {
EXPRINT(ni, 0,"ERROR : invalid source id " << source_id << " for write data from CORE " << core_id);
exit(0);
}
}
/*******************************************************************************/
/*******************************************************************************/
/// Write DATA ACCEPT transaction for fifo out
void anoc_copro_wrapper::write_data_accept_fifo_out(int num_fifo) {
#ifdef _ANOC_COPRO_DEBUG
printf("DATA ACCEPT transaction\n");
#endif
ni_accept_data_transaction accept_trans;
ni_output_fifo_in[num_fifo]->put(&accept_trans);
}
/*******************************************************************************/
/*******************************************************************************/
/// Receive ACCEPT DATA transaction (remote call)
void anoc_copro_wrapper::put(const ni_accept_data_transaction &transaction) {
#ifdef _ANOC_COPRO_DEBUG
printf("ACCEPT DATA transaction\n");
#endif
t_uint16 source_id;
t_uint16 fifo_id = 0;
t_uint16 core_id;
bool fifo_ok=false;
source_id = transaction.get_source_id();
core_id = transaction.get_core_id();
int j=0;
for(int i=0; i<nb_fifo_in; i++) {
if(core_fifo_in[i]==core_id) {
if(j==source_id) {
fifo_id = i;
fifo_ok=true;
}
j++;
}
}
if(fifo_ok) {
EXPRINT(ni, 1,"Receive accept data from fifo: " << fifo_id); //FIXPRINT
tab_fifo_in_accept[fifo_id] = true;
//Requires to update the accept_data (Ivan)
accept_data_update = true;
} else {
EXPRINT(ni, 0,"ERROR : invalid source id " << source_id << " for accept data from CORE " << core_id );
exit(0);
}
}
/*******************************************************************************/
/*******************************************************************************/
/// Write WRITE DATA transaction for fifo in
void anoc_copro_wrapper::write_data_fifo_in(int num_fifo, t_uint32 data) {
#ifdef _ANOC_COPRO_DEBUG
printf("WRITE DATA transaction\n");
#endif
ni_write_data_transaction data_trans;
data_trans.set_data(data);
EXPRINT(ni, 1,"Write data " << data << " in fifo_in[" << num_fifo << "]"); //FIXPRINT
ni_input_fifo_out[num_fifo]->put(&data_trans);
}
/*******************************************************************************/
/*******************************************************************************/
/// Receive STATUS transaction (remote call)
void anoc_copro_wrapper::put(const ni_status_transaction &transaction) {
#ifdef _ANOC_COPRO_DEBUG
printf("STATUS transaction\n");
#endif
t_uint16 core_id;
core_id = transaction.get_core_id();
if(core_id>=nb_cores) {
EXPRINT(ni, 0,"ERROR : Invalid core id for status");
exit(0);
}
last_status[core_id] = transaction.get_status();
//Requires to update the status port
status_update = true;
EXPRINT(ni, 0,"New status from CORE " << core_id <<" : " << last_status[core_id]); //FIXPRINT
}
/*******************************************************************************/
/*******************************************************************************/
/// Receive EOC transaction (remote call)
void anoc_copro_wrapper::put(const ni_eoc_transaction &transaction) {
#ifdef _ANOC_COPRO_DEBUG
printf("EOC transaction\n");
#endif
t_uint16 core_id;
core_id = transaction.get_core_id();
if(core_id>=nb_cores) {
EXPRINT(ni, 0,"ERROR : Invalid core_id for eoc");
exit(0);
}
EXPRINT(ni, 0,"CORE " << core_id << " has finished"); //FIXPRINT
cfg_flag_core_finished[core_id] = true;
//Requires to update the eoc
eoc_update = true;
}
/*******************************************************************************/
/*******************************************************************************/