summaryrefslogblamecommitdiffstatshomepage
path: root/src/lib/netlist/devices/nlid_truthtable.h
blob: 311f5ebd8ca3e4bffbd25d938a7bd744a87a2874 (plain) (tree)
1
2
3
4
5
6
7
8
9

                               






                           

                          
 


                          
 





                                                                                        
                                                                                                 


                                                                                        
         
 
 



                         
 







                                                                                      

                                  
         
                              


                                               
                                                                 
                  
          
 
                                                     
                                                                            


                                                                            
      
 
                                                    
                                   
         
                
                                              

               

                                                                                                     



                                                                                    






                                              
                                              
                                                              



                                                     


                                                                                    

                                       

                                                

                            
                                   

                 
                                                            

                               
                 

                                     



                                                                          
                                                   
                 

                                
                 
                                        
                 
 
                                                      
                 
                                                                 



                                                         
                 
 
                                                      
                 


                                                                                          
                                                                                          

                                               
                                                                 






                                                                             
 

                                                                      
 
                  
 


                                    
                              
                 
                                                              
 
                                         
                                                                 
                         
                                                  



                                                                              
                                                                                    


                                                                                             
                                                                              


                                                                          
                                                                                    
                                                          
                                         
                         
                            
                         
                                           

                                                                              
                                                                                    

                                                                                             
                                    
                                                                              
                                                                                    
                         
 

                                                                    
 
                                                 
 


                                                                  
 
                                  

                                                                                 
                            

                                                                                   
 
                                                                 
                         

                                                                                    
                                                    
                                                                
                         
                 
 
                                        
                                          
                                             
                                          
          
 
                                                                           
         

                                                                                                
                                                                                     
 
                                                             
 
                                            

                                                    
 
                                                                                         
 

                             
 

 
                               
// license:GPL-2.0+
// copyright-holders:Couriersud
/*
 * nld_truthtable.h
 *
 *  Created on: 19 Jun 2014
 *      Author: andre
 */

#ifndef NLID_TRUTHTABLE_H_
#define NLID_TRUTHTABLE_H_

#include "../nl_setup.h"
#include "../nl_base.h"
#include "../plib/putil.h"

#define NETLIB_TRUTHTABLE(cname, nIN, nOUT)                                    \
	class NETLIB_NAME(cname) : public nld_truthtable_t<nIN, nOUT>              \
	{                                                                          \
	public:                                                                    \
		template <class C>                                                     \
		NETLIB_NAME(cname)(C &owner, const pstring &name)                      \
		: nld_truthtable_t<nIN, nOUT>(owner, name, family_TTL(), &m_ttbl, m_desc) { }   \
	private:                                                                   \
		static truthtable_t m_ttbl;                                            \
		static std::vector<pstring> m_desc;                                    \
	}


namespace netlist
{
	namespace devices
	{

#if 0
	template<unsigned bits> struct uint_for_size { typedef uint_least32_t type; };
	template<unsigned bits>
	struct need_bytes_for_bits
	{
		enum { value = 4 };
	};
#else
	template<unsigned bits>
	struct need_bytes_for_bits
	{
		enum { value =
			bits <= 8       ?   1 :
			bits <= 16      ?   2 :
			bits <= 32      ?   4 :
								8
		};
	};

	template<unsigned bits> struct uint_for_size;
	template<> struct uint_for_size<1> { typedef uint_least8_t  type; };
	template<> struct uint_for_size<2> { typedef uint_least16_t type; };
	template<> struct uint_for_size<4> { typedef uint_least32_t type; };
	template<> struct uint_for_size<8> { typedef uint_least64_t type; };
#endif

	template<std::size_t m_NI, std::size_t m_NO>
	NETLIB_OBJECT(truthtable_t)
	{
	private:
		detail::family_setter_t m_fam;
	public:

		typedef typename uint_for_size<need_bytes_for_bits<m_NO + m_NI>::value>::type type_t;

		static constexpr const std::size_t m_num_bits = m_NI;
		static constexpr const std::size_t m_size = (1 << (m_num_bits));
		static constexpr const type_t m_outmask = ((1 << m_NO) - 1);
		static constexpr const std::size_t m_min_devices_for_deactivate = 2;

		struct truthtable_t
		{
			truthtable_t()
			: m_initialized(false)
			{}
			bool m_initialized;
			type_t m_outs[m_size];
			uint_least8_t m_timing[m_size * m_NO];
			netlist_time m_timing_nt[16];
		};

		template <class C>
		nld_truthtable_t(C &owner, const pstring &name,
				const logic_family_desc_t *fam,
				truthtable_t &ttp, const std::vector<pstring> &desc)
		: device_t(owner, name)
		, m_fam(*this, fam)
		, m_ign(*this, "m_ign", 0)
		, m_active(*this, "m_active", 1)
		, m_ttp(ttp)
		{
			init(desc);
		}

		void init(const std::vector<pstring> &desc);

		NETLIB_RESETI()
		{
			m_active = 0;
			m_ign = 0;
			for (auto &i : m_I)
				i.activate();
			for (auto &q : m_Q)
				if (q.has_net() && q.net().num_cons() > 0)
					m_active++;
		}

		NETLIB_UPDATEI()
		{
			process<true>();
		}

		void inc_active() NL_NOEXCEPT override
		{
			if (m_NI >= m_min_devices_for_deactivate)
				if (++m_active == 1)
				{
					process<false>();
				}
		}

		void dec_active() NL_NOEXCEPT override
		{
			/* FIXME:
			 * Based on current measurements there is no point to disable
			 * 1 input devices. This should actually be a parameter so that we
			 * can decide for each individual gate whether it is beneficial to
			 * ignore deactivation.
			 */
			if (m_NI >= m_min_devices_for_deactivate)
				if (--m_active == 0)
				{
					for (std::size_t i = 0; i< m_NI; i++)
						m_I[i].inactivate();
					m_ign = (1<<m_NI)-1;
				}
		}

		plib::uninitialised_array_t<logic_input_t, m_NI> m_I;
		plib::uninitialised_array_t<logic_output_t, m_NO> m_Q;

	protected:

	private:

		template<bool doOUT>
		void process()
		{
			netlist_time mt(netlist_time::zero());

			type_t nstate(0);
			if (m_NI >= m_min_devices_for_deactivate)
			{
				type_t ign(m_ign);
				if (!doOUT)
					for (std::size_t i = 0; i < m_NI; i++)
					{
						m_I[i].activate();
						nstate |= (m_I[i]() ? (1 << i) : 0);
						mt = std::max(this->m_I[i].net().time(), mt);
					}
				else
					for (std::size_t i = 0; i < m_NI; i++)
					{
						if ((ign & 1))
							m_I[i].activate();
						nstate |= (m_I[i]() ? (1 << i) : 0);
						ign >>= 1;
					}
			}
			else
			{
				if (!doOUT)
					for (std::size_t i = 0; i < m_NI; i++)
					{
						nstate |= (m_I[i]() ? (1 << i) : 0);
						mt = std::max(this->m_I[i].net().time(), mt);
					}
				else
					for (std::size_t i = 0; i < m_NI; i++)
						nstate |= (m_I[i]() ? (1 << i) : 0);
			}

			const type_t outstate(m_ttp.m_outs[nstate]);
			type_t out(outstate & m_outmask);

			m_ign = outstate >> m_NO;

			const std::size_t timebase(nstate * m_NO);
			const auto *t(&m_ttp.m_timing[timebase]);
			const auto *tim = m_ttp.m_timing_nt;

			if (doOUT)
				for (std::size_t i = 0; i < m_NO; out >>= 1, ++i)
					m_Q[i].push(out & 1, tim[t[i]]);
			else
				for (std::size_t i = 0; i < m_NO; out >>= 1, ++i)
					m_Q[i].set_Q_time(out & 1, mt + tim[t[i]]);

			if (m_NI >= m_min_devices_for_deactivate)
			{
				type_t ign(m_ign);
				for (auto I = m_I.begin(); ign != 0; ign >>= 1, ++I)
					if (ign & 1)
						I->inactivate();
			}
		}

		/* FIXME: check width */
		state_var<type_t>   m_ign;
		state_var_s32       m_active;
		const truthtable_t &m_ttp;
	};

	class netlist_base_factory_truthtable_t : public factory::element_t
	{
	public:
		netlist_base_factory_truthtable_t(const pstring &name, const pstring &classname,
				const pstring &def_param, const pstring &sourcefile);

		virtual ~netlist_base_factory_truthtable_t();

		std::vector<pstring> m_desc;
		const logic_family_desc_t *m_family;
	};

	void tt_factory_create(setup_t &setup, tt_desc &desc, const pstring &sourcefile);

	} //namespace devices
} // namespace netlist



#endif /* NLID_TRUTHTABLE_H_ */