[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [f-cpu] about the ongoing work for the "stable" release
On Wed, Jan 02, 2002 at 04:14:34AM +0100, Yann Guidon wrote:
[...]
> can anybody have a look at "fanout_linear.vhdl" ?
> who can figure why it doesn't work with vanilla ?
It says:
# -- Failure: t: signal has multiple drivers with no resolution function.
This is not true, of course - but vanilla doesn't grok it. This happens
when certain combinations of range attributes are used (in particular,
'high and 'low seem to cause problems). If you use explicit ranges,
e.g. `WIDTH-1 downto 0', everything is fine again.
I'll attach a fixed version that works for me. But the recursive version
will have to wait (BTW: did you mean a recursive entity, or a recursive
version of the binary_tree_index function?)
CU,
--
Michael "Tired" Riepe <Michael.Riepe@stud.uni-hannover.de>
"All I wanna do is have a little fun before I die"
--------------------------------------------------------------------------
-- f-cpu/vhdl/common/fanout_linear.vhdl - fanout tree (2**n) for the F-CPU
-- Copyright (C) 2001 Yann GUIDON (whygee@f-cpu.org)
--
-- created sam dec 1 00:39:05 GMT 2001
-- version jeu dec 6 16:28:31 GMT 2001 : stripped from fanout_tree.vhdl
--
-- changed Thu Jan 3 02:49:09 CET 2002 (Michael Riepe):
-- added workaround for broken 'low and 'high attributes in Vanilla VHDL
--
--------------------------BEGIN-VHDL-LICENCE-----------------------------
-- 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, write to the Free Software
-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
---------------------------END-VHDL-LICENCE------------------------------
--
-- This component implements a balanced fanout tree, for use when a signal
-- must be sent to more than 2**n inputs, where n > 2.
--
-- This version is a binary tree for synthesis. It tries to trick the
-- "dumb" optimizers into thinking that the whole tree contains different
-- signals and values, so that the nets won't be tied dumbly together
-- (which would void the use of this component). Using inverters,
-- which are somewhat faster than buffers that are probably not inferred,
-- we can break the net into sub-levels. This means that one inverter
-- level must be added if log2_width is odd.
-- Depending on the software, this will be more or less efficient. Try each
-- implementation to be sure.
--
-- This code is not yet suitable for Vanilla VHDL and is taken apart.
-- With Simili or other tools, compile this architecture AFTER work.fanout
-- in order to replace the default "simple" architecture.
--
--------------------------------------------------------------------------
-- some standard librairies
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.all;
-- text i/o
use IEEE.std_logic_textio.all;
use std.textio.all;
-- where the component interface is declared :
use work.fanout;
-- more sophisticated version :
Architecture linear of fanout is
constant verbose : natural := 0;
constant WIDTH : natural := 2 ** log2_width;
signal t : Std_ulogic_vector(WIDTH-1 downto 0);
function binary_tree_index (
index : integer)
return integer is
variable i, j : integer;
variable lout : line;
begin -- binary_tree_index
-- 1 ) count the number of LSB that are set to 1
-- (the loop could be avoided but requires a XOR which
-- is not defined for integers :-( )
i := index;
j := 4;
while (i mod 2) = 1 loop
i := i / 2;
j := j * 2;
end loop;
-- 2) the incredible magic formula !
-- don't ask me where it comes, it was built from observation.
i := (j - 1) / 2;
if verbose > 0 then
write(lout, string'(" * index : "));
write(lout, index);
write(lout, string'(" * result : "));
write(lout, i);
writeline(output,lout);
end if;
return ((index / j)*j) + i;
end binary_tree_index;
-- avoid the ugly `if ... generate / if not ... generate'
function invert_if (A : in std_ulogic; F : boolean) return std_ulogic is
variable Y : std_ulogic;
begin
if F then
Y := not A;
else
Y := A;
end if;
return Y;
end invert_if;
begin
assert (log2_width > 2) and (log2_width < 10)
report "wrong size range for the binary tree"
severity FAILURE;
assert (leaf'low) = 0
report "array index should start with 0"
severity FAILURE;
-- compensation for the odd/even cases.
t(WIDTH-1) <= invert_if(root, log2_width mod 2 = 0);
-- build nodes
saturate: for i in WIDTH-2 downto 0 generate
t(i) <= not t(binary_tree_index(i)); -- map the binary tree to a linear vector.
end generate saturate;
-- add leaves
i_loop: for i in leaf'range generate
leaf(i) <= not t((i/2) *2); -- connect to the even numbered temporary nodes.
end generate i_loop;
end;