[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [f-cpu] New snapshot for EU_INC and EU_CMP
On Tue, Jul 30, 2002 at 08:54:46PM +0200, Etienne LABARRE wrote:
[...]
> > Did you find source code or documentation for package std_logic_misc?
>
> ???? It's standard library. Packages std_logic_1164 and std_logic_misc
> are available with all vhdl tools.
> (For example, with Simili, in Simili_dir/lib/ieee/stdlogicmisc.vhd)
A `standard' is something people have agreed on. Not everything that
is found in library std or library ieee is a standard (especially if
you use Synopsys).
[...]
> ==> the code don't must depend to techno.
Therefore we only use elements that are supposed to be available
everywhere: and/or gates with 2...4 inputs, 2-input xor gates, inverters
and muxes. With the famous `6 Gate Rule', any of them count as 1 gate.
Bigger elements (like an 8-input and gate) count as 2 or more gates.
After the first synthesis experiences, I later added another rule:
2-input xors count as 2 gates, and the sum of gate delays must not
exceed 10. I call this the `6G/10T' rule.
[...]
> > I doubt that you can get away with 8 cycles. From my experience, 64-bit
> > CMP alone needs 1 level of 2-xor, 3 levels of 4-and, 1 level of 2-xor,
> > 1 level of 2-and plus 3 levels of 4-or, giving a total of 9 levels.
>
> Hmm, i have perhap's made an error. Can you look at my code ?
You have made many errors, according to my testbench for eu_cmp.
CMP is supposed to be either 0 or -1: cmp(a, b) = a < b ? -1 : 0.
MSB1 is supposed to return the *number* of the most significant `1'
bit: msb1(0xffffffff) = 64, msb1(0) = 0. Currently it returns some
strange bit mask. Likewise for MSB0.
I'll attach a testbench for eu_cmp.
--
Michael "Tired" Riepe <Michael.Riepe@stud.uni-hannover.de>
"All I wanna do is have a little fun before I die"
-- eu_cmp_test_mr.vhdl -- Testbench for eu_cmp
-- Copyright (C) 2001, 2002 Michael Riepe <michael@stud.uni-hannover.de>
--
-- 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
-- $Id: icmp64_test.vhdl,v 1.1 2002/07/26 16:58:20 michael Exp $
--pragma synthesis_off
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use std.textio.all;
use IEEE.std_logic_textio.all;
--use work.Bit_Manipulation.all;
entity eu_cmp_test is
end eu_cmp_test;
architecture Arch_1 of eu_cmp_test is
component eu_cmp
generic ( eu_cmp_width : natural := 6 );
port (
eu_cmp_A : in std_ulogic_vector(2**eu_cmp_width-1 downto 0);
eu_cmp_B : in std_ulogic_vector(2**eu_cmp_width-1 downto 0);
eu_cmp_simd : in std_ulogic_vector(eu_cmp_width-4 downto 0);
eu_cmp_mode : in std_ulogic_vector(2 downto 0);
eu_cmp_Y : out std_ulogic_vector(2**eu_cmp_width-1 downto 0);
eu_cmp_Z : out std_ulogic_vector(2**eu_cmp_width-1 downto 0)
);
end component;
constant WIDTH : natural := 64;
signal M : std_ulogic_vector(5 downto 0) := (others => '0');
signal A, B, Y, Z : std_ulogic_vector(WIDTH-1 downto 0) := (others => '0');
signal Clk : std_ulogic := '0';
signal Rst : std_ulogic := '0';
signal En : std_ulogic := '1';
procedure writestr (s : string) is
variable lout : line;
begin
write(lout, s);
writeline(output, lout);
end writestr;
procedure print_vector (lbl : string;
x : std_ulogic_vector;
des : string := " := ") is
variable lout : line;
begin
write(lout, lbl & des); write(lout, x); writeline(output, lout);
end print_vector;
procedure print_signals is
begin
print_vector("A", A);
print_vector("B", B);
print_vector("M", M);
print_vector("Y", Y);
print_vector("Z", Z);
end print_signals;
procedure do_error (lbl : string;
a_x, a_y : std_ulogic_vector) is
begin
writestr("WHOA THERE!!!");
print_signals;
print_vector(lbl, a_x);
print_vector(lbl, a_y, " /= ");
end do_error;
procedure check_numeric (lbl : string;
x : std_ulogic_vector;
y : natural) is
variable tmp : std_ulogic_vector(x'range);
variable lout : line;
begin
tmp := std_ulogic_vector(to_unsigned(y rem 2**x'length, x'length));
if x /= tmp then
do_error(lbl, x, tmp);
end if;
end check_numeric;
procedure check_logic (lbl : string;
a, b : std_ulogic_vector) is
alias x : std_ulogic_vector(a'length downto 1) is a;
alias y : std_ulogic_vector(b'length downto 1) is b;
variable lout : line;
begin
assert a'length = b'length
report "bad args in check_logic" severity failure;
for i in x'range loop
next when y(i) = '-';
next when x(i) = y(i);
do_error(lbl, x, y);
return;
end loop;
end check_logic;
begin
-- module under test
mut : eu_cmp
generic map (eu_cmp_width => 6)
port map (
eu_cmp_A => A,
eu_cmp_B => B,
eu_cmp_simd => M(5 downto 3),
eu_cmp_mode => M(2 downto 0),
eu_cmp_Y => Y,
eu_cmp_Z => Z
);
-- driver process
process
constant std_ulogic_0 : std_ulogic := '0';
constant std_ulogic_1 : std_ulogic := '1';
procedure do_clock is
begin
wait for 1 ns;
-- Clk <= '1';
-- wait for 1 ns;
-- Clk <= '0';
end do_clock;
procedure print_mode (simd : in natural) is
variable lout : line;
begin
write(lout, string'("*** testing "));
write(lout, simd);
write(lout, string'("-bit mode ***"));
writeline(output, lout);
end print_mode;
procedure test_ucmp is
variable av, bv, tmp : std_ulogic_vector(WIDTH-1 downto 0);
variable simd, left, right : natural;
begin
writestr("*** testing unsigned cmp ***");
for gran in 0 to 3 loop
simd := 8 * 2**gran;
print_mode(simd);
M <= "XXX000";
for i in 3 to 5 loop
if i < gran + 3 then
M(i) <= '1';
else
M(i) <= '0';
end if;
end loop;
for chunk in 0 to WIDTH/simd-1 loop
right := chunk*simd;
left := right + simd - 1;
av := (others => 'X');
bv := (others => 'X');
tmp := (others => '-');
for index in left downto right loop
av(index) := '0';
bv(index) := '1';
tmp(left downto right) := (left downto right => '1');
A <= av; B <= bv; do_clock;
check_logic("Y", Y, tmp);
av(index) := '1';
bv(index) := '0';
tmp(left downto right) := (left downto right => '0');
A <= av; B <= bv; do_clock;
check_logic("Y", Y, tmp);
av(index) := '0';
end loop;
end loop;
end loop;
end test_ucmp;
procedure test_scmp is
variable av, bv, tmp : std_ulogic_vector(WIDTH-1 downto 0);
variable simd, left, right : natural;
begin
writestr("*** testing signed cmp ***");
for gran in 0 to 3 loop
simd := 8 * 2**gran;
print_mode(simd);
M <= "XXX000";
for i in 3 to 5 loop
if i < gran + 3 then
M(i) <= '1';
else
M(i) <= '0';
end if;
end loop;
for chunk in 0 to WIDTH/simd-1 loop
right := chunk*simd;
left := right + simd - 1;
av := (others => 'X');
bv := (others => 'X');
tmp := (others => '-');
av(left) := '0';
bv(left) := '1';
tmp(left downto right) := (left downto right => '0');
A <= av; B <= bv; do_clock;
check_logic("Y", Y, tmp);
av(left) := '1';
bv(left) := '0';
tmp(left downto right) := (left downto right => '1');
A <= av; B <= bv; do_clock;
check_logic("Y", Y, tmp);
bv(left) := '1';
for index in left-1 downto right loop
av(index) := '0';
bv(index) := '1';
tmp(left downto right) := (left downto right => '1');
A <= av; B <= bv; do_clock;
check_logic("Y", Y, tmp);
av(index) := '1';
bv(index) := '0';
tmp(left downto right) := (left downto right => '0');
A <= av; B <= bv; do_clock;
check_logic("Y", Y, tmp);
av(index) := '0';
end loop;
end loop;
end loop;
end test_scmp;
procedure test_usort is
variable av, bv, tmp : std_ulogic_vector(WIDTH-1 downto 0);
variable simd, left, right : natural;
begin
writestr("*** testing unsigned sort ***");
for gran in 0 to 3 loop
simd := 8 * 2**gran;
print_mode(simd);
M <= "XXX011";
for i in 3 to 5 loop
if i < gran + 3 then
M(i) <= '1';
else
M(i) <= '0';
end if;
end loop;
for chunk in 0 to WIDTH/simd-1 loop
right := chunk*simd;
left := right + simd - 1;
av := (others => 'X'); -- XXX: should use random data
bv := (others => 'X'); -- XXX: should use random data
tmp := (others => '-');
for index in left downto right loop
av(index) := '0';
bv(index) := '1';
A <= av; B <= bv; do_clock;
tmp(left downto right) := av(left downto right);
check_logic("Y", Y, tmp);
tmp(left downto right) := bv(left downto right);
check_logic("Z", Z, tmp);
av(index) := '1';
bv(index) := '0';
A <= av; B <= bv; do_clock;
tmp(left downto right) := bv(left downto right);
check_logic("Y", Y, tmp);
tmp(left downto right) := av(left downto right);
check_logic("Z", Z, tmp);
av(index) := '0';
end loop;
end loop;
end loop;
end test_usort;
procedure test_ssort is
variable av, bv, tmp : std_ulogic_vector(WIDTH-1 downto 0);
variable simd, left, right : natural;
begin
writestr("*** testing signed sort ***");
for gran in 0 to 3 loop
simd := 8 * 2**gran;
print_mode(simd);
M <= "XXX011";
for i in 3 to 5 loop
if i < gran + 3 then
M(i) <= '1';
else
M(i) <= '0';
end if;
end loop;
for chunk in 0 to WIDTH/simd-1 loop
right := chunk*simd;
left := right + simd - 1;
av := (others => 'X'); -- XXX: should use random data
bv := (others => 'X'); -- XXX: should use random data
tmp := (others => '-');
av(left) := '0';
bv(left) := '1';
A <= av; B <= bv; do_clock;
tmp(left downto right) := bv(left downto right);
check_logic("Y", Y, tmp);
tmp(left downto right) := av(left downto right);
check_logic("Z", Z, tmp);
av(left) := '1';
bv(left) := '0';
A <= av; B <= bv; do_clock;
tmp(left downto right) := av(left downto right);
check_logic("Y", Y, tmp);
tmp(left downto right) := bv(left downto right);
check_logic("Z", Z, tmp);
bv(left) := '1';
for index in left-1 downto right loop
av(index) := '0';
bv(index) := '1';
A <= av; B <= bv; do_clock;
tmp(left downto right) := av(left downto right);
check_logic("Y", Y, tmp);
tmp(left downto right) := bv(left downto right);
check_logic("Z", Z, tmp);
av(index) := '1';
bv(index) := '0';
A <= av; B <= bv; do_clock;
tmp(left downto right) := bv(left downto right);
check_logic("Y", Y, tmp);
tmp(left downto right) := av(left downto right);
check_logic("Z", Z, tmp);
av(index) := '0';
end loop;
end loop;
end loop;
end test_ssort;
procedure test_msb (bit : in std_ulogic) is
variable av, bv, tmp : std_ulogic_vector(WIDTH-1 downto 0);
variable simd, left, right : natural;
variable lout : line;
begin
write(lout, string'("*** testing msb"));
write(lout, bit);
write(lout, string'(" ***"));
writeline(output, lout);
for gran in 0 to 3 loop
simd := 8 * 2**gran;
print_mode(simd);
M <= "XXX10X";
M(0) <= bit;
for i in 3 to 5 loop
if i < gran + 3 then
M(i) <= '1';
else
M(i) <= '0';
end if;
end loop;
for chunk in 0 to WIDTH/simd-1 loop
right := chunk*simd;
left := right + simd - 1;
av := (others => 'X');
av(left downto right) := (left downto right => not bit);
bv := (others => 'X');
tmp := (others => '-');
tmp(left downto right) := (left downto right => '0');
A <= av; B <= bv; do_clock;
check_logic("Y", Y, tmp);
for index in right to left loop
av(index) := bit;
tmp(left downto right) := std_ulogic_vector(
to_unsigned(index - right + 1, simd));
A <= av; B <= bv; do_clock;
check_logic("Y", Y, tmp);
av(index) := 'X';
end loop;
end loop;
end loop;
end test_msb;
begin
test_ucmp;
-- test_scmp;
test_usort;
-- test_ssort;
test_msb('0');
test_msb('1');
-- stop simulation
writestr("*** simulation complete ***");
wait;
end process;
end Arch_1;
--pragma synthesis_on
-- vi: set ts=4 sw=4 equalprg="fmt -72 -p--": please