aboutsummaryrefslogtreecommitdiffstats
path: root/src/grt/grt-vcdz.ads
blob: 353612f8db24d7bacb45bb1ef7d97b604a9d9a90 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
--  GHDL Run Time (GRT) - VCD .gz module.
--  Copyright (C) 2005 - 2014 Tristan Gingold
--
--  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 <gnu.org/licenses>.
--
--  As a special exception, if other files instantiate generics from this
--  unit, or you link this unit with other files to produce an executable,
--  this unit does not by itself cause the resulting executable to be
--  covered by the GNU General Public License. This exception does not
--  however invalidate any other reasons why the executable file might be
--  covered by the GNU Public License.

package Grt.Vcdz is
   procedure Register;
end Grt.Vcdz;
f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
/*
 *  yosys -- Yosys Open SYnthesis Suite
 *
 *  Copyright (C) 2012  Clifford Wolf <clifford@clifford.at>
 *  
 *  Permission to use, copy, modify, and/or distribute this software for any
 *  purpose with or without fee is hereby granted, provided that the above
 *  copyright notice and this permission notice appear in all copies.
 *  
 *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 */

#ifndef BITPATTERN_H
#define BITPATTERN_H

#include "kernel/log.h"
#include "kernel/rtlil.h"

struct BitPatternPool
{
	int width;
	typedef std::vector<RTLIL::State> bits_t;
	std::set<bits_t> pool;

	BitPatternPool(RTLIL::SigSpec sig)
	{
		width = sig.width;
		if (width > 0) {
			std::vector<RTLIL::State> pattern(width);
			sig.optimize();
			for (int i = 0; i < width; i++) {
				RTLIL::SigSpec s = sig.extract(i, 1);
				s.optimize();
				assert(s.chunks.size() == 1);
				if (s.chunks[0].wire == NULL && s.chunks[0].data.bits[0] <= RTLIL::State::S1)
					pattern[i] = s.chunks[0].data.bits[0];
				else
					pattern[i] = RTLIL::State::Sa;
			}
			pool.insert(pattern);
		}
	}

	BitPatternPool(int width)
	{
		this->width = width;
		if (width > 0) {
			std::vector<RTLIL::State> pattern(width);
			for (int i = 0; i < width; i++)
				pattern[i] = RTLIL::State::Sa;
			pool.insert(pattern);
		}
	}

	bits_t sig2bits(RTLIL::SigSpec sig)
	{
		sig.optimize();
		assert(sig.is_fully_const());
		assert(sig.chunks.size() == 1);
		bits_t bits = sig.chunks[0].data.bits;
		for (auto &b : bits)
			if (b > RTLIL::State::S1)
				b = RTLIL::State::Sa;
		return bits;
	}

	bool match(bits_t a, bits_t b)
	{
		assert(int(a.size()) == width);
		assert(int(b.size()) == width);
		for (int i = 0; i < width; i++)
			if (a[i] <= RTLIL::State::S1 && b[i] <= RTLIL::State::S1 && a[i] != b[i])
				return false;
		return true;
	}

	bool has_any(RTLIL::SigSpec sig)
	{
		bits_t bits = sig2bits(sig);
		for (auto &it : pool)
			if (match(it, bits))
				return true;
		return false;
	}

	bool has_all(RTLIL::SigSpec sig)
	{
		bits_t bits = sig2bits(sig);
		for (auto &it : pool)
			if (match(it, bits)) {
				for (int i = 0; i < width; i++)
					if (bits[i] > RTLIL::State::S1 && it[i] <= RTLIL::State::S1)
						goto next_pool_entry;
				return true;
	next_pool_entry:;
			}
		return false;
	}

	bool take(RTLIL::SigSpec sig)
	{
		bool status = false;
		bits_t bits = sig2bits(sig);
		std::vector<bits_t> pattern_list;
		for (auto &it : pool)
			if (match(it, bits))
				pattern_list.push_back(it);
		for (auto pattern : pattern_list) {
			pool.erase(pattern);
			for (int i = 0; i < width; i++) {
				if (pattern[i] != RTLIL::State::Sa || bits[i] == RTLIL::State::Sa)
					continue;
				bits_t new_pattern = pattern;
				new_pattern[i] = bits[i] == RTLIL::State::S1 ? RTLIL::State::S0 : RTLIL::State::S1;
				pool.insert(new_pattern);
			}
			status = true;
		}
		return status;
	}

	bool take_all()
	{
		if (pool.empty())
			return false;
		pool.clear();
		return true;
	}

	bool empty()
	{
		return pool.empty();
	}
}; 

#endif