Index: trunk/modules/vci_tty_tsar/caba/metadata/vci_tty_tsar.sd
===================================================================
--- trunk/modules/vci_tty_tsar/caba/metadata/vci_tty_tsar.sd	(revision 1054)
+++ trunk/modules/vci_tty_tsar/caba/metadata/vci_tty_tsar.sd	(revision 1054)
@@ -0,0 +1,44 @@
+
+# -*- python -*-
+
+
+Module('caba:vci_tty_tsar',
+    classname = 'soclib::caba::VciTtyTsar',
+
+    tmpl_parameters = [
+	    parameter.Module('vci_param',  default = 'caba:vci_param'),
+	],
+	   
+    header_files = [
+        '../source/include/vci_tty_tsar.h',
+    ],
+    
+    interface_files = [
+        '../../include/soclib/tty.h'
+    ],
+
+    implementation_files = [
+        '../source/src/vci_tty_tsar.cpp',
+    ],
+
+    ports = [
+	    Port('caba:vci_target', 'p_vci'),
+	    Port('caba:bit_in',     'p_resetn', auto = 'resetn'),
+	    Port('caba:bit_out',    'p_tx_irq', parameter.Reference('names', 'len')),
+	    Port('caba:bit_out',    'p_rx_irq', parameter.Reference('names', 'len')),
+	    Port('caba:clock_in',   'p_clk', auto = 'clock'),
+	],
+
+    uses = [
+	    Uses('caba:base_module'),
+	    Uses('common:process_wrapper'),
+	    Uses('common:tty_wrapper') ,
+	    Uses('caba:vci_target_fsm', default_target = 'true', support_llsc = 'false'),
+	],
+
+	instance_parameters = [
+		parameter.IntTab('ident'),
+        parameter.Module('mt', typename = 'common:mapping_table'),
+        parameter.StringArray('names'),
+	],
+)
Index: trunk/modules/vci_tty_tsar/caba/source/include/vci_tty_tsar.h
===================================================================
--- trunk/modules/vci_tty_tsar/caba/source/include/vci_tty_tsar.h	(revision 1054)
+++ trunk/modules/vci_tty_tsar/caba/source/include/vci_tty_tsar.h	(revision 1054)
@@ -0,0 +1,129 @@
+/* -*- 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) UPMC, Lip6, Asim
+ *         Nicolas Pouillon <nipo@ssji.net>, 2007
+ *
+ * Maintainers: alain
+ */
+
+#ifndef SOCLIB_VCI_TTY_TSAR_H
+#define SOCLIB_VCI_TTY_TSAR_H
+
+#include <systemc>
+#include "caba_base_module.h"
+#include "tty_wrapper.h"
+#include "mapping_table.h"
+#include "int_tab.h"
+#include "vci_target.h"
+
+namespace soclib {
+namespace caba {
+
+using namespace sc_core;
+using namespace soclib::common;
+
+///////////////////////////////////////////
+template<typename vci_param>
+class VciTtyTsar
+///////////////////////////////////////////
+	: public soclib::caba::BaseModule
+{
+public:
+
+    typedef typename vci_param::fast_addr_t  vci_addr_t;
+    typedef typename vci_param::fast_data_t  vci_data_t;
+    typedef typename vci_param::srcid_t      vci_srcid_t;
+    typedef typename vci_param::trdid_t      vci_trdid_t;
+    typedef typename vci_param::pktid_t      vci_pktid_t;
+
+
+    enum fsm_state_e
+    {
+        IDLE,
+        RSP_WRITE,
+        RSP_READ,
+        RSP_ERROR,
+    };
+
+    // Ports
+    sc_in<bool>                                 p_clk;
+    sc_in<bool>                                 p_resetn;
+    soclib::caba::VciTarget<vci_param>          p_vci;
+    sc_out<bool>*                               p_irq_rx;
+    sc_out<bool>*                               p_irq_tx;
+
+	VciTtyTsar( sc_module_name                  name,
+		        const IntTab                    &index,
+		        const MappingTable              &mt,
+                const std::vector<std::string>  &names );
+
+	VciTtyTsar( sc_module_name                  name, 
+                const IntTab                    &index,
+		        const MappingTable              &mt,
+                const char*                     first_name, ...);
+
+
+    ~VciTtyTsar();
+    
+
+private:
+
+    // Registers
+    sc_signal<int>                              r_fsm_state;
+    sc_signal<vci_data_t>                       r_rdata;
+    sc_signal<vci_srcid_t>                      r_srcid;
+    sc_signal<vci_trdid_t>                      r_trdid;
+    sc_signal<vci_pktid_t>                      r_pktid;
+    sc_signal<bool>                             r_rx_irq_enable[32];
+    sc_signal<bool>                             r_tx_irq_enable[32];
+      
+    std::vector<soclib::common::TtyWrapper*>    m_term;
+    std::list<soclib::common::Segment>          m_seglist;
+
+    void transition();
+    void genMoore();
+
+	void init(const std::vector<std::string> &names );
+
+protected:
+
+    SC_HAS_PROCESS(VciTtyTsar);
+
+public:
+
+    void print_trace( size_t channel );
+};
+
+}}
+
+#endif /* SOCLIB_VCI_TTY_TSAR_H */
+
+// 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
+
Index: trunk/modules/vci_tty_tsar/caba/source/src/vci_tty_tsar.cpp
===================================================================
--- trunk/modules/vci_tty_tsar/caba/source/src/vci_tty_tsar.cpp	(revision 1054)
+++ trunk/modules/vci_tty_tsar/caba/source/src/vci_tty_tsar.cpp	(revision 1054)
@@ -0,0 +1,334 @@
+/* -*- 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) UPMC, Lip6, Asim
+ *         Nicolas Pouillon <nipo@ssji.net>, 2007
+ *
+ * Maintainers: alain
+ */
+
+#include "../include/vci_tty_tsar.h"
+#include "tty.h"
+
+#include <stdarg.h>
+
+namespace soclib {
+namespace caba {
+
+#define tmpl(t) template<typename vci_param> t VciTtyTsar<vci_param>
+
+////////////////////////
+tmpl(void)::transition()
+{
+	if (!p_resetn) 
+    {
+		r_fsm_state  = IDLE;
+        for( size_t channel = 0 ; channel < m_term.size() ; channel++ ) 
+        {
+            r_rx_irq_enable[channel] = 0;
+            r_tx_irq_enable[channel] = 0;
+        }
+		return;
+	}
+
+    switch ( r_fsm_state.read() )
+    {
+        //////////
+        case IDLE:   // waiting a VCI command
+        {
+            if ( not p_vci.cmdval.read() ) break;
+
+            vci_addr_t address = p_vci.address.read();
+            size_t     cell      = (size_t)((address & 0xFFF)>>2);
+            size_t     reg       = cell % TTY_SPAN;
+            size_t     channel   = cell / TTY_SPAN;
+            bool       seg_error = true;
+
+            r_srcid = p_vci.srcid.read();
+            r_trdid = p_vci.trdid.read();
+            r_pktid = p_vci.pktid.read();
+
+            std::list<soclib::common::Segment>::iterator seg;
+            for ( seg = m_seglist.begin() ; seg != m_seglist.end() ; seg++ )
+            {
+                if ( seg->contains( address ) and p_vci.eop.read() )
+                {
+                    seg_error   = false;
+                    break;
+                }
+            }
+
+            /////////////////////////////////////////////////////////
+            if      ( not seg_error and            // write char
+                      (p_vci.cmd.read() == vci_param::CMD_WRITE) and
+                      (reg == TTY_WRITE ) and 
+                      channel < m_term.size() )
+            {
+                // suppose an infinite write buffer (never full)
+                m_term[channel]->putc( p_vci.wdata.read() );
+
+                r_fsm_state = RSP_WRITE;
+            }     
+            /////////////////////////////////////////////////////////
+            else if ( not seg_error and            // read char 
+                      (p_vci.cmd.read() == vci_param::CMD_READ) and
+                      (reg == TTY_READ) and 
+                      channel < m_term.size() )
+            {
+                vci_data_t  byte = m_term[channel]->getc();
+
+                // skip CR code
+                if ( byte == 0x0d ) r_rdata = m_term[channel]->getc();
+                else                r_rdata = byte;
+
+                r_fsm_state = RSP_READ;
+            }
+            /////////////////////////////////////////////////////////
+            else if ( not seg_error and            // read status
+                      (p_vci.cmd.read() == vci_param::CMD_READ) and
+                      (reg == TTY_STATUS) and 
+                      channel < m_term.size() )
+            {
+                // read buffer can be empty    => bit 0 can be 0 or 1
+                // write buffer is never full  => bit 1 is always 0
+                
+                r_rdata     = m_term[channel]->hasData();
+                r_fsm_state = RSP_READ;
+            }
+            /////////////////////////////////////////////////////////
+            else if ( not seg_error and            // set / reset rx_irq
+                      (p_vci.cmd.read() == vci_param::CMD_WRITE) and
+                      (reg == TTY_RX_IRQ_ENABLE) and
+                      channel < m_term.size() )
+            {
+                r_rx_irq_enable[channel] = p_vci.wdata.read();
+                r_fsm_state = RSP_WRITE;
+            }
+            /////////////////////////////////////////////////////////
+            else if ( not seg_error and            // set / reset tx_irq
+                      (p_vci.cmd.read() == vci_param::CMD_WRITE) and
+                      (reg == TTY_TX_IRQ_ENABLE) and 
+                      channel < m_term.size() )
+            {
+                r_tx_irq_enable[channel] = p_vci.wdata.read();
+                r_fsm_state = RSP_WRITE;
+            }
+            /////////////////////////////////////////////////////////
+            else if ( p_vci.eop.read() )
+            {
+                r_fsm_state = RSP_ERROR;
+            }
+            break;
+        }
+        ///////////////
+        case RSP_ERROR:   // return an error response
+        case RSP_READ:    // return a valid read response
+        case RSP_WRITE:   // return a valid write response
+        {
+            if ( p_vci.rspack.read() ) r_fsm_state = IDLE;
+            break;
+        }
+    }  // end switch r_fsm_state
+}
+
+//////////////////////
+tmpl(void)::genMoore()
+{
+    if ( r_fsm_state.read() == IDLE )
+    {
+        p_vci.cmdack  = true;
+        p_vci.rspval  = false;
+        p_vci.rdata   = 0;
+        p_vci.rsrcid  = 0;
+        p_vci.rtrdid  = 0;
+        p_vci.rpktid  = 0;
+        p_vci.rerror  = vci_param::ERR_NORMAL;
+        p_vci.reop    = true;
+    }
+    else if ( r_fsm_state.read() == RSP_WRITE )
+    {
+        p_vci.cmdack  = false;
+        p_vci.rspval  = true;
+        p_vci.rdata   = 0;
+        p_vci.rsrcid  = r_srcid.read();
+        p_vci.rtrdid  = r_trdid.read();
+        p_vci.rpktid  = r_pktid.read();
+        p_vci.rerror  = vci_param::ERR_NORMAL;
+        p_vci.reop    = true;
+    }
+    else if ( r_fsm_state.read() == RSP_READ )
+    {
+        p_vci.cmdack  = false;
+        p_vci.rspval  = true;
+        p_vci.rdata   = r_rdata.read();
+        p_vci.rsrcid  = r_srcid.read();
+        p_vci.rtrdid  = r_trdid.read();
+        p_vci.rpktid  = r_pktid.read();
+        p_vci.rerror  = vci_param::ERR_NORMAL;
+        p_vci.reop    = true;
+    }
+    else if ( r_fsm_state.read() == RSP_ERROR )
+    {
+        p_vci.cmdack  = false;
+        p_vci.rspval  = true;
+        p_vci.rdata   = 0;
+        p_vci.rsrcid  = r_srcid.read();
+        p_vci.rtrdid  = r_trdid.read();
+        p_vci.rpktid  = r_pktid.read();
+        p_vci.rerror  = vci_param::ERR_GENERAL_DATA_ERROR;
+        p_vci.reop    = true;
+    }
+
+    for ( size_t channel = 0; channel < m_term.size(); channel++ )
+    {
+        // activate RX_IRQ if RX buffer not empty and RX_IRQ enable
+        p_irq_rx[channel] = (bool)m_term[channel]->hasData() && 
+                            r_rx_irq_enable[channel].read();
+
+        // activate TX_IRQ if TX_IRQ enable ( TX buffer is never full )
+        p_irq_tx[channel] = r_tx_irq_enable[channel].read();
+    }
+}
+
+///////////////////////////////////////////////////////
+tmpl(void)::init(const std::vector<std::string> &names)
+{
+    size_t channel = 0;
+    
+    for ( std::vector<std::string>::const_iterator i = names.begin();
+          i != names.end();
+          ++i )
+    {
+        assert( (channel < 32) and "VCI_TTY_TSAR ERROR : no more than 32 channels");
+		m_term.push_back(soclib::common::allocateTty(*i));
+        channel++;
+    }
+
+	p_irq_rx = new sc_out<bool>[m_term.size()];
+	p_irq_tx = new sc_out<bool>[m_term.size()];
+    
+	SC_METHOD(transition);
+	dont_initialize();
+	sensitive << p_clk.pos();
+
+	SC_METHOD(genMoore);
+	dont_initialize();
+	sensitive << p_clk.neg();
+}
+
+/////////////////////////////////////////////////
+tmpl(/**/)::VciTtyTsar( sc_module_name     name,
+                        const IntTab       &index,
+                        const MappingTable &mt,
+                        const char *first_name, ...)
+    : soclib::caba::BaseModule(name),
+      p_clk("clk"),
+      p_resetn("resetn"),
+      p_vci("vci"),
+      m_seglist(mt.getSegmentList(index))
+{
+    std::cout << "  - Building VciTtyTsar " << name << std::endl;
+
+    std::list<soclib::common::Segment>::iterator seg;
+    for ( seg = m_seglist.begin() ; seg != m_seglist.end() ; seg++ )
+    {
+        std::cout << "    => segment " << seg->name()
+                  << " / base = " << std::hex << seg->baseAddress()
+                  << " / size = " << seg->size() << std::endl; 
+    }
+
+	va_list va_tty;
+
+	va_start (va_tty, first_name);
+    std::vector<std::string> args;
+	const char *cur_tty = first_name;
+	while (cur_tty) 
+    {
+        args.push_back(cur_tty);
+
+		cur_tty = va_arg( va_tty, char * );
+	}
+	va_end( va_tty );
+
+    init(args);
+}
+
+/////////////////////////////////////////////////////////////
+tmpl(/**/)::VciTtyTsar( sc_module_name                  name,
+                        const IntTab                    &index,
+                        const MappingTable              &mt,
+                        const std::vector<std::string>  &names )
+    : soclib::caba::BaseModule(name),
+      p_clk("clk"),
+      p_resetn("resetn"),
+      p_vci("vci"),
+      m_seglist(mt.getSegmentList(index))
+{
+    std::cout << "  - Building VciMultiTTy " << name << std::endl;
+
+    std::list<soclib::common::Segment>::iterator seg;
+    for ( seg = m_seglist.begin() ; seg != m_seglist.end() ; seg++ )
+    {
+        std::cout << "    => segment " << seg->name()
+                  << " / base = " << std::hex << seg->baseAddress()
+                  << " / size = " << seg->size() << std::endl; 
+    }
+
+    init(names);
+}
+
+/////////////////////////
+tmpl(/**/)::~VciTtyTsar()
+{
+	for (unsigned int i=0; i<m_term.size(); i++ )
+        delete m_term[i];
+
+	delete[] p_irq_rx;
+	delete[] p_irq_tx;
+}
+
+/////////////////////////////////////////
+tmpl(void)::print_trace( size_t channel )
+{
+    const char* state_str[] = { "IDLE",
+                                "RSP_WRITE",
+                                "RSP_READ",
+                                "RSP_ERROR", };
+
+    std::cout << "MULTI_TTY " << name()
+              << " : fsm = " << state_str[r_fsm_state.read()] << std::dec
+              << " / RX_IRQ[" << channel << "] = " << r_rx_irq_enable[channel].read()
+              << " / TX_IRQ[" << channel << "] = " << r_tx_irq_enable[channel].read()
+              << std::endl; 
+}
+
+}}
+
+// 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
+
Index: trunk/modules/vci_tty_tsar/include/soclib/tty.h
===================================================================
--- trunk/modules/vci_tty_tsar/include/soclib/tty.h	(revision 1054)
+++ trunk/modules/vci_tty_tsar/include/soclib/tty.h	(revision 1054)
@@ -0,0 +1,58 @@
+/*
+ * 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) UPMC, Lip6, Asim
+ *         Nicolas Pouillon <nipo@ssji.net>, 2006
+ *
+ * Maintainers: nipo
+ */
+#ifndef TTY_REGS_H
+#define TTY_REGS_H
+
+
+enum SoclibTtyRegisters 
+{
+    TTY_WRITE         = 0,
+    TTY_STATUS        = 1,
+    TTY_READ          = 2,
+    TTY_RX_IRQ_ENABLE = 3,
+    TTY_TX_IRQ_ENABLE = 4,
+    /**/
+    TTY_SPAN          = 8,
+};
+
+enum SoclibTtyStatus
+{
+    TTY_STATUS_RX_FULL      = 1,
+    TTY_STATUS_TX_FULL      = 2,
+};
+
+#endif /* TTY_REGS_H */
+
+// 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
+
