Initial commit
This commit is contained in:
commit
f0ce9c44cc
43 files changed
+1815
No files matched your search
@@ -0,0 +1,47 @@
|
||||
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL; -- Bibliothek für std_logic und std_logic_vector
|
||||
use IEEE.NUMERIC_STD.ALL; -- Bibliothek für signed und unsigned Datentypen
|
||||
|
||||
entity AddDataTypes is
|
||||
port (
|
||||
operand_a : in std_logic_vector(7 downto 0); -- Eingang operand a (8 Bit std_logic_vector)
|
||||
operand_b : in std_logic_vector(7 downto 0); -- Eingang operand b (8 Bit std_logic_vector)
|
||||
result_1 : out std_logic_vector(7 downto 0); -- Ausgang Ergebnis der Operanden Addition mit signed (8 Bit std_logic_vector)
|
||||
result_2 : out std_logic_vector(7 downto 0) -- Ausgang Ergebnis der Operanden Addition mit signed (8 Bit std_logic_vector)
|
||||
);
|
||||
end AddDataTypes;
|
||||
|
||||
architecture Behavioral of AddDataTypes is
|
||||
-- constant/signal Deklarationen
|
||||
|
||||
-- Legen Sie ein Konstante eight_s als signed (Länge 8) mit Wert 8 an
|
||||
|
||||
-- Legen Sie ein Konstante eight_i als integer mit Wert 8 an
|
||||
|
||||
-- Legen Sie ein signal internal_operand_a_s als signed mit Laenge 8 an
|
||||
|
||||
-- Legen Sie ein signal internal_operand_a_int als integer mit Wertebreich -128 to 127 an
|
||||
|
||||
-- Legen Sie ein signal temp_result_s als signed mit Laenge 8 an
|
||||
|
||||
-- Legen Sie ein signal temp_result_int als integer mit Wertebreich -128 to 127 an
|
||||
|
||||
|
||||
begin
|
||||
|
||||
-- Weisen Sie dem signal internal_operand_a_s den Eingang operand_a zu (Datentypen beachten Konvertierung noetig)
|
||||
|
||||
-- Weisen Sie dem signal internal_operand_a_int den Eingang operand_a zu (Datentypen beachten Konvertierung noetig)
|
||||
|
||||
-- Rechnen Sie die Addition internal_operand_a_s + operand_b + eight_s und speichern es in temp_result_s (Datentypen beachten Konvertierung bei operand_b noetig)
|
||||
|
||||
-- Rechnen Sie die Addition internal_operand_a_int + operand_b + eight_i und speichern es in temp_result_int (Datentypen beachten Konvertierung bei operand_b noetig)
|
||||
|
||||
-- Weisen Sie dem Ausgang result_1 das signal temp_result_s zu (Datentypen beachten Konvertierung noetig)
|
||||
|
||||
-- Weisen Sie dem Ausgang result_2 das signal temp_result_int zu (Datentypen beachten Konvertierung noetig)
|
||||
|
||||
|
||||
end Behavioral;
|
||||
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
|
||||
vhdl_srcs = Add_DataTypes.vhd \
|
||||
test/test_utility.vhd \
|
||||
test/tb_Add_DataTypes.vhd \
|
||||
|
||||
main = tb_Add_DataTypes
|
||||
|
||||
CHECK_RESULTS = true
|
||||
|
||||
include scripts/vhdl.mk
|
||||
|
||||
Executable
+15
@@ -0,0 +1,15 @@
|
||||
#!/bin/bash
|
||||
script_dir=$(cd $(dirname "${BASH_SOURCE[0]}") && pwd)
|
||||
|
||||
if [ $# -ne 1 ]
|
||||
then
|
||||
echo Usage $0 test-output-file
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cat $1 | sed -z -e 's/\(py_.* \[\)/ \[/g' | ${script_dir}/highlight_test_results.sh
|
||||
|
||||
if grep -q FAIL $1
|
||||
then
|
||||
exit 1
|
||||
fi
|
||||
Executable
+14
@@ -0,0 +1,14 @@
|
||||
#!/bin/bash
|
||||
script_path="$( dirname "$( readlink -f "${BASH_SOURCE[0]}" )" )"
|
||||
|
||||
if [ $# -lt 1 ]
|
||||
then
|
||||
echo " usage: execute_and_highlight command arguments"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cmd=$1
|
||||
shift 1
|
||||
$cmd $@ | $script_path/highlight_test_results.sh
|
||||
test ${PIPESTATUS[0]} -eq 0
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
|
||||
# Make sure that the top level is assigned to main
|
||||
$(if $(main),,\
|
||||
$(error Assign top level entity name to variable "main"))
|
||||
|
||||
# Make sure that at least on vhdl source is assigned
|
||||
$(if $(vhdl_srcs),,\
|
||||
$(error Assign at least on vhdl source to variable "vhdl_srcs"))
|
||||
|
||||
# Append prefix -d to all generics
|
||||
generics = $(addprefix -g,$(generics))
|
||||
|
||||
# Add VHDL 2008 as default build standard
|
||||
vhdl_flags += --std=08
|
||||
vhdl_flags += -frelaxed-rules
|
||||
#vhdl_flags += --ieee-asserts=disable-at-0
|
||||
|
||||
vhdl_objs = $(vhdl_srcs:.vhd=.o)
|
||||
|
||||
assert_level := error
|
||||
|
||||
.PHONY: sim clean
|
||||
|
||||
sim: ${main}
|
||||
@scripts/execute_and_highlight.sh \
|
||||
ghdl \
|
||||
-r ${vhdl_flags} ${main} \
|
||||
--ieee-asserts=disable-at-0 \
|
||||
-gCHECK_RESULTS=${CHECK_RESULTS} \
|
||||
--read-wave-opt=test/${main}.wave \
|
||||
--assert-level=${assert_level}
|
||||
|
||||
gui: test/${main}.ghw
|
||||
@echo "Viewing $<"
|
||||
@gtkwave $< --script=test/gtkwave.view
|
||||
|
||||
test/${main}.ghw: ${main} test/${main}.wave
|
||||
@ghdl -r ${vhdl_flags} ${main} \
|
||||
--read-wave-opt=test/${main}.wave \
|
||||
--wave=$@
|
||||
|
||||
${main}: $(vhdl_objs)
|
||||
@echo "Elaborating ${main}"
|
||||
@ghdl -e ${vhdl_flags} ${main}
|
||||
|
||||
%.o: %.vhd
|
||||
@echo "Analysing $<"
|
||||
@ghdl -a ${vhdl_flags} $<
|
||||
|
||||
clean:
|
||||
@ghdl --clean
|
||||
@rm -rf ${main}.ghw work-obj08.cf ${vhdl_objs} ${main} ${artifacts}
|
||||
|
||||
help:
|
||||
@echo Use ghdl to simulate and synthesis a vhdl design.
|
||||
@echo
|
||||
@echo Build configuration variables:
|
||||
@echo main main entity
|
||||
@echo vhdl_flags
|
||||
@echo generics
|
||||
|
||||
Executable
+7
@@ -0,0 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
red=$(tput setaf 1)
|
||||
green=$(tput setaf 2)
|
||||
default=$(tput sgr0)
|
||||
|
||||
sed "s/FAIL/${red}FAIL${default}/" | sed "s/OK/${green}OK${default}/"
|
||||
@@ -0,0 +1,63 @@
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
|
||||
# Make sure that the top level is assigned to main
|
||||
$(if $(main),,\
|
||||
$(error Assign top level entity name to variable "main"))
|
||||
|
||||
# Make sure that at least on vhdl source is assigned
|
||||
$(if $(vhdl_srcs),,\
|
||||
$(error Assign at least on vhdl source to variable "vhdl_srcs"))
|
||||
|
||||
# Append prefix -d to all generics
|
||||
generics = $(addprefix -g,$(generics))
|
||||
|
||||
# Add VHDL 2008 as default build standard
|
||||
vhdl_flags += -2008
|
||||
|
||||
vhdl_objs = $(vhdl_srcs:.vhd=.vhdo)
|
||||
verilog_objs = $(verilog_srcs:.v=.vo)
|
||||
|
||||
assert_level := error
|
||||
|
||||
.PHONY: sim clean
|
||||
|
||||
sim: ${verilog_objs} ${vhdl_objs}
|
||||
@vsim -voptargs=+acc -c work.${main} -g CHECK_RESULTS=true -do "run -all" \
|
||||
| scripts/highlight_test_results.sh
|
||||
|
||||
gui: ${verilog_objs} ${vhdl_objs}
|
||||
@vsim -voptargs=+acc work.${main} -g CHECK_RESULTS=false -do "do test/vsim.wave; run -all"
|
||||
|
||||
%.vo: %.v .libwork
|
||||
@echo "Analysing $<"
|
||||
@vlog -work work ${verilog_flags} $<
|
||||
|
||||
%.vhdo: %.vhd .libwork
|
||||
@echo "Analysing $<"
|
||||
@vcom -work work ${vhdl_flags} $<
|
||||
|
||||
|
||||
.libwork:
|
||||
@vlib work && vmap work work && touch $@
|
||||
|
||||
clean:
|
||||
@rm -rf work \
|
||||
.libwork \
|
||||
transcript \
|
||||
modelsim.ini \
|
||||
vlog.opt \
|
||||
vsim.wlf \
|
||||
data.py \
|
||||
data.pyc \
|
||||
|
||||
help:
|
||||
@echo Use ghdl to simulate and synthesis a vhdl design.
|
||||
@echo
|
||||
@echo Build configuration variables:
|
||||
@echo main main entity
|
||||
@echo vhdl_flags
|
||||
@echo generics
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
|
||||
ghdl_version = $(shell ghdl --version 2> /dev/null)
|
||||
vsim_version = $(shell vsim -version 2> /dev/null)
|
||||
|
||||
# in case verilog is part of the build a verilog capable simulator is required
|
||||
ifdef verilog_srcs
|
||||
ifneq (${vsim_version},)
|
||||
include scripts/questa-sim.mk
|
||||
else
|
||||
$(error No HDL simulation tool found for verilog!)
|
||||
endif
|
||||
else
|
||||
ifneq (${vsim_version},)
|
||||
include scripts/questa-sim.mk
|
||||
else
|
||||
ifneq (${ghdl_version},)
|
||||
include scripts/ghdl.mk
|
||||
else
|
||||
$(error No HDL simulation tool found!)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
library std;
|
||||
use std.env.all;
|
||||
|
||||
library work;
|
||||
use work.test_utility.all;
|
||||
|
||||
entity tb_Add_DataTypes is
|
||||
generic( CHECK_RESULTS : boolean );
|
||||
end;
|
||||
|
||||
architecture test of tb_Add_DataTypes is
|
||||
signal operand_a : std_logic_vector( 7 downto 0 );
|
||||
signal operand_b : std_logic_vector( 7 downto 0 );
|
||||
signal result_1 : std_logic_vector( 7 downto 0 );
|
||||
signal result_2 : std_logic_vector( 7 downto 0 );
|
||||
begin
|
||||
u_AddDataTypes : entity work.AddDataTypes
|
||||
port map (
|
||||
operand_a => operand_a,
|
||||
operand_b => operand_b,
|
||||
result_1 => result_1,
|
||||
result_2 => result_2
|
||||
);
|
||||
|
||||
delay : process
|
||||
variable result : std_logic_vector( operand_a'range );
|
||||
variable expected : std_logic_vector( operand_a'range );
|
||||
begin
|
||||
operand_a <= x"05";
|
||||
operand_b <= x"07";
|
||||
wait for 10 ns;
|
||||
result := result_1;
|
||||
expected := x"14";
|
||||
assert_eq( result, expected );
|
||||
|
||||
result := result_2;
|
||||
expected := x"14";
|
||||
assert_eq( result, expected );
|
||||
|
||||
operand_a <= x"05";
|
||||
operand_b <= x"f5";
|
||||
wait for 10 ns;
|
||||
result := result_1;
|
||||
expected := x"02";
|
||||
assert_eq( result, expected );
|
||||
result := result_2;
|
||||
expected := x"02";
|
||||
assert_eq( result, expected );
|
||||
|
||||
operand_a <= x"f5";
|
||||
operand_b <= x"f7";
|
||||
wait for 10 ns;
|
||||
result := result_1;
|
||||
expected := x"f4";
|
||||
assert_eq( result, expected );
|
||||
|
||||
result := result_2;
|
||||
expected := x"f4";
|
||||
assert_eq( result, expected );
|
||||
|
||||
if CHECK_RESULTS = true then
|
||||
finish;
|
||||
else
|
||||
stop;
|
||||
end if;
|
||||
end process delay;
|
||||
|
||||
end architecture test;
|
||||
@@ -0,0 +1,2 @@
|
||||
$ version 1.1
|
||||
/tb_Add_DataTypes/u_AddDataTypes/*
|
||||
@@ -0,0 +1,71 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
use ieee.float_pkg.all;
|
||||
|
||||
library std;
|
||||
use std.textio.all;
|
||||
|
||||
package test_utility is
|
||||
constant TEST_FAIL : string := "[ FAIL ]";
|
||||
constant TEST_OK : string := "[ OK ]" & LF;
|
||||
|
||||
type real_array is array ( natural range <> ) of real;
|
||||
|
||||
procedure assert_eq( variable a : in std_logic_vector; variable b : in std_logic_vector );
|
||||
|
||||
procedure assert_near( variable a : in real;
|
||||
variable b : in real;
|
||||
variable abs_err : in real );
|
||||
|
||||
procedure assert_element_near( variable a : in real;
|
||||
variable b : in real;
|
||||
variable abs_err : in real;
|
||||
variable index : in integer );
|
||||
|
||||
end package test_utility;
|
||||
|
||||
package body test_utility is
|
||||
|
||||
procedure assert_eq( variable a : in std_logic_vector; variable b : in std_logic_vector ) is
|
||||
begin
|
||||
|
||||
assert( a = b )
|
||||
report TEST_FAIL & "assert_eq" & LF &
|
||||
" a: " & to_string( a ) & LF &
|
||||
" b: " & to_string( b ) & LF
|
||||
severity error;
|
||||
end procedure assert_eq;
|
||||
|
||||
procedure assert_near( variable a : in real;
|
||||
variable b : in real;
|
||||
variable abs_err : in real ) is
|
||||
variable abs_diff : real;
|
||||
begin
|
||||
abs_diff := abs( a - b );
|
||||
assert( abs_diff <= abs_err )
|
||||
report TEST_FAIL & "assert_near" & LF &
|
||||
" a: " & to_string( a ) & LF &
|
||||
" b: " & to_string( b ) & LF &
|
||||
" " & to_string( abs_diff ) & " > " & to_string( abs_err ) & LF
|
||||
severity error;
|
||||
end procedure assert_near;
|
||||
|
||||
procedure assert_element_near( variable a : in real;
|
||||
variable b : in real;
|
||||
variable abs_err : in real;
|
||||
variable index : in integer ) is
|
||||
variable abs_diff : real;
|
||||
begin
|
||||
abs_diff := abs( a - b );
|
||||
assert( abs_diff <= abs_err )
|
||||
report TEST_FAIL & "assert_element_near" & LF &
|
||||
" element: " & integer'image( index ) & LF &
|
||||
" a: " & to_string( a ) & LF &
|
||||
" b: " & to_string( b ) & LF &
|
||||
" " & to_string( abs_diff ) & " > " & to_string( abs_err ) & LF
|
||||
severity error;
|
||||
end procedure assert_element_near;
|
||||
|
||||
end package body test_utility;
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
onerror {resume}
|
||||
quietly WaveActivateNextPane {} 0
|
||||
add wave -noupdate /tb_add_datatypes/operand_a
|
||||
add wave -noupdate /tb_add_datatypes/operand_b
|
||||
add wave -noupdate /tb_add_datatypes/result_1
|
||||
add wave -noupdate /tb_add_datatypes/result_2
|
||||
TreeUpdate [SetDefaultTree]
|
||||
WaveRestoreCursors {{Cursor 1} {0 ns} 0}
|
||||
quietly wave cursor active 1
|
||||
configure wave -namecolwidth 150
|
||||
configure wave -valuecolwidth 100
|
||||
configure wave -justifyvalue left
|
||||
configure wave -signalnamewidth 0
|
||||
configure wave -snapdistance 10
|
||||
configure wave -datasetprefix 0
|
||||
configure wave -rowmargin 4
|
||||
configure wave -childrowmargin 2
|
||||
configure wave -gridoffset 0
|
||||
configure wave -gridperiod 1
|
||||
configure wave -griddelta 40
|
||||
configure wave -timeline 0
|
||||
configure wave -timelineunits ns
|
||||
update
|
||||
WaveRestoreZoom {0 ns} {135 ns}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
|
||||
vhdl_srcs = float_add.vhd \
|
||||
top_entity_float_add.vhd \
|
||||
test/test_utility.vhd \
|
||||
test/tb_top_entity_float_add.vhd \
|
||||
|
||||
main = tb_top_entity_float_add
|
||||
|
||||
CHECK_RESULTS = true
|
||||
|
||||
include scripts/vhdl.mk
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,133 @@
|
||||
library IEEE;
|
||||
use IEEE.std_logic_1164.all;
|
||||
use IEEE.numeric_std.all;
|
||||
entity float_add is
|
||||
port(A : in std_logic_vector(31 downto 0);
|
||||
B : in std_logic_vector(31 downto 0);
|
||||
clk : in std_logic;
|
||||
reset : in std_logic;
|
||||
start : in std_logic;
|
||||
done : out std_logic;
|
||||
sum : out std_logic_vector(31 downto 0)
|
||||
);
|
||||
end float_add;
|
||||
|
||||
architecture mixed of float_add is
|
||||
type ST is (WAIT_STATE, ALIGN_STATE, ADDITION_STATE, NORMALIZE_STATE, OUTPUT_STATE);
|
||||
signal state : ST := WAIT_STATE;
|
||||
|
||||
---Internal Signals latched from the inputs
|
||||
signal A_mantissa, B_mantissa : std_logic_vector (24 downto 0);
|
||||
signal A_exp, B_exp : std_logic_vector (8 downto 0);
|
||||
signal A_sgn, B_sgn : std_logic;
|
||||
|
||||
--Internal signals for Output
|
||||
signal sum_exp: std_logic_vector (8 downto 0);
|
||||
signal sum_mantissa : std_logic_vector (24 downto 0);
|
||||
signal sum_sgn : std_logic;
|
||||
|
||||
begin
|
||||
|
||||
Control_Unit : process (clk, reset) is
|
||||
variable diff : signed(8 downto 0);
|
||||
begin
|
||||
if(reset = '1') then
|
||||
state <= WAIT_STATE; --start in wait state
|
||||
done <= '0';
|
||||
elsif rising_edge(clk) then
|
||||
case state is
|
||||
when WAIT_STATE =>
|
||||
if (start = '1') then --wait till start request startes high
|
||||
A_sgn <= A(31);
|
||||
A_exp <= '0' & A(30 downto 23); --One bit is added for signed subtraction
|
||||
A_mantissa <= "01" & A(22 downto 0); --Two bits are added extra, one for leading 1 and other one for storing carry
|
||||
B_sgn <= B(31);
|
||||
B_exp <= '0' & B(30 downto 23);
|
||||
B_mantissa <= "01" & B(22 downto 0);
|
||||
state <= ALIGN_STATE;
|
||||
else
|
||||
state <= WAIT_STATE;
|
||||
end if;
|
||||
when ALIGN_STATE => --Compare exponent and align it
|
||||
--If any num is greater by 2**24, we skip the addition.
|
||||
if unsigned(A_exp) > unsigned(B_exp) then
|
||||
--B needs downshifting
|
||||
diff := signed(A_exp) - signed(B_exp); --Small Alu
|
||||
if diff > 23 then
|
||||
sum_mantissa <= A_mantissa; --B insignificant relative to A
|
||||
sum_exp <= A_exp;
|
||||
sum_sgn <= A_sgn;
|
||||
state <= OUTPUT_STATE; --start latch A as output
|
||||
else
|
||||
--downshift B to equilabrate B_exp to A_exp
|
||||
sum_exp <= A_exp;
|
||||
B_mantissa(24-to_integer(diff) downto 0) <= B_mantissa(24 downto to_integer(diff));
|
||||
B_mantissa(24 downto 25-to_integer(diff)) <= (others => '0');
|
||||
state <= ADDITION_STATE;
|
||||
end if;
|
||||
elsif unsigned(A_exp) < unsigned(B_exp) then --A_exp < B_exp. A needs downshifting
|
||||
diff := signed(B_exp) - signed(A_exp); -- Small Alu
|
||||
if diff > 23 then
|
||||
sum_mantissa <= B_mantissa; --A insignificant relative to B
|
||||
sum_sgn <= B_sgn;
|
||||
sum_exp <= B_exp;
|
||||
state <= OUTPUT_STATE; --start latch B as output
|
||||
else
|
||||
--downshift A to equilabrate A_exp to B_exp
|
||||
sum_exp <= B_exp;
|
||||
A_mantissa(24-to_integer(diff) downto 0) <= A_mantissa(24 downto to_integer(diff));
|
||||
A_mantissa(24 downto 25-to_integer(diff)) <= (others => '0');
|
||||
state <= ADDITION_STATE;
|
||||
end if;
|
||||
else -- Both exponent is equal. No need to mantissa shift
|
||||
sum_exp <= A_exp;
|
||||
state <= ADDITION_STATE;
|
||||
end if;
|
||||
when ADDITION_STATE => --Mantissa addition
|
||||
state <= NORMALIZE_STATE;
|
||||
if (A_sgn xor B_sgn) = '0' then --signs are the same. Just add them
|
||||
sum_mantissa <= std_logic_vector((unsigned(A_mantissa) + unsigned(B_mantissa))); --Big Alu
|
||||
sum_sgn <= A_sgn; --both nums have same sign
|
||||
--Else subtract smaller from larger and use sign of larger
|
||||
elsif unsigned(A_mantissa) >= unsigned(B_mantissa) then
|
||||
sum_mantissa <= std_logic_vector((unsigned(A_mantissa) - unsigned(B_mantissa))); --Big Alu
|
||||
sum_sgn <= A_sgn;
|
||||
else
|
||||
sum_mantissa <= std_logic_vector((unsigned(B_mantissa) - unsigned(A_mantissa))); --Big Alu
|
||||
sum_sgn <= B_sgn;
|
||||
end if;
|
||||
|
||||
when NORMALIZE_STATE => --Normalization.
|
||||
if unsigned(sum_mantissa) = TO_UNSIGNED(0, 25) then
|
||||
--The sum is 0
|
||||
sum_mantissa <= (others => '0');
|
||||
sum_exp <= (others => '0');
|
||||
state <= OUTPUT_STATE;
|
||||
elsif(sum_mantissa(24) = '1') then --If sum overflowed we downshift and are done.
|
||||
sum_mantissa <= '0' & sum_mantissa(24 downto 1); --shift the 1 down
|
||||
sum_exp <= std_logic_vector((unsigned(sum_exp)+ 1));
|
||||
state <= OUTPUT_STATE;
|
||||
elsif(sum_mantissa(23) = '0') then --in this case we need to upshift
|
||||
--This iterates the normalization shifts, thus can take many clocks.
|
||||
sum_mantissa <= sum_mantissa(23 downto 0) & '0';
|
||||
sum_exp <= std_logic_vector((unsigned(sum_exp)-1));
|
||||
state<= NORMALIZE_STATE; --keep shifting till leading 1 appears
|
||||
else
|
||||
state <= OUTPUT_STATE; --leading 1 already there. Latch output
|
||||
end if;
|
||||
when OUTPUT_STATE =>
|
||||
sum(22 downto 0) <= sum_mantissa(22 downto 0);
|
||||
sum(30 downto 23) <= sum_exp(7 downto 0);
|
||||
sum(31) <= sum_sgn;
|
||||
done <= '1'; -- signal done
|
||||
if (start = '0') then -- stay in the state till request ends i.e start is low
|
||||
done <= '0';
|
||||
state <= WAIT_STATE;
|
||||
end if;
|
||||
when others =>
|
||||
state <= WAIT_STATE; --Just in case.
|
||||
end case;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end mixed;
|
||||
Executable
+15
@@ -0,0 +1,15 @@
|
||||
#!/bin/bash
|
||||
script_dir=$(cd $(dirname "${BASH_SOURCE[0]}") && pwd)
|
||||
|
||||
if [ $# -ne 1 ]
|
||||
then
|
||||
echo Usage $0 test-output-file
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cat $1 | sed -z -e 's/\(py_.* \[\)/ \[/g' | ${script_dir}/highlight_test_results.sh
|
||||
|
||||
if grep -q FAIL $1
|
||||
then
|
||||
exit 1
|
||||
fi
|
||||
Executable
+14
@@ -0,0 +1,14 @@
|
||||
#!/bin/bash
|
||||
script_path="$( dirname "$( readlink -f "${BASH_SOURCE[0]}" )" )"
|
||||
|
||||
if [ $# -lt 1 ]
|
||||
then
|
||||
echo " usage: execute_and_highlight command arguments"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cmd=$1
|
||||
shift 1
|
||||
$cmd $@ | $script_path/highlight_test_results.sh
|
||||
test ${PIPESTATUS[0]} -eq 0
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
|
||||
# Make sure that the top level is assigned to main
|
||||
$(if $(main),,\
|
||||
$(error Assign top level entity name to variable "main"))
|
||||
|
||||
# Make sure that at least on vhdl source is assigned
|
||||
$(if $(vhdl_srcs),,\
|
||||
$(error Assign at least on vhdl source to variable "vhdl_srcs"))
|
||||
|
||||
# Append prefix -d to all generics
|
||||
generics = $(addprefix -g,$(generics))
|
||||
|
||||
# Add VHDL 2008 as default build standard
|
||||
vhdl_flags += --std=08
|
||||
vhdl_flags += -frelaxed-rules
|
||||
#vhdl_flags += --ieee-asserts=disable-at-0
|
||||
|
||||
vhdl_objs = $(vhdl_srcs:.vhd=.o)
|
||||
|
||||
assert_level := error
|
||||
|
||||
.PHONY: sim clean
|
||||
|
||||
sim: ${main}
|
||||
@scripts/execute_and_highlight.sh \
|
||||
ghdl \
|
||||
-r ${vhdl_flags} ${main} \
|
||||
--ieee-asserts=disable-at-0 \
|
||||
-gCHECK_RESULTS=${CHECK_RESULTS} \
|
||||
--read-wave-opt=test/${main}.wave \
|
||||
--assert-level=${assert_level}
|
||||
|
||||
gui: test/${main}.ghw
|
||||
@echo "Viewing $<"
|
||||
@gtkwave $< --script=test/gtkwave.view
|
||||
|
||||
test/${main}.ghw: ${main} test/${main}.wave
|
||||
@ghdl -r ${vhdl_flags} ${main} \
|
||||
--read-wave-opt=test/${main}.wave \
|
||||
--wave=$@
|
||||
|
||||
${main}: $(vhdl_objs)
|
||||
@echo "Elaborating ${main}"
|
||||
@ghdl -e ${vhdl_flags} ${main}
|
||||
|
||||
%.o: %.vhd
|
||||
@echo "Analysing $<"
|
||||
@ghdl -a ${vhdl_flags} $<
|
||||
|
||||
clean:
|
||||
@ghdl --clean
|
||||
@rm -rf ${main}.ghw work-obj08.cf ${vhdl_objs} ${main} ${artifacts}
|
||||
|
||||
help:
|
||||
@echo Use ghdl to simulate and synthesis a vhdl design.
|
||||
@echo
|
||||
@echo Build configuration variables:
|
||||
@echo main main entity
|
||||
@echo vhdl_flags
|
||||
@echo generics
|
||||
|
||||
Executable
+7
@@ -0,0 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
red=$(tput setaf 1)
|
||||
green=$(tput setaf 2)
|
||||
default=$(tput sgr0)
|
||||
|
||||
sed "s/FAIL/${red}FAIL${default}/" | sed "s/OK/${green}OK${default}/"
|
||||
@@ -0,0 +1,63 @@
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
|
||||
# Make sure that the top level is assigned to main
|
||||
$(if $(main),,\
|
||||
$(error Assign top level entity name to variable "main"))
|
||||
|
||||
# Make sure that at least on vhdl source is assigned
|
||||
$(if $(vhdl_srcs),,\
|
||||
$(error Assign at least on vhdl source to variable "vhdl_srcs"))
|
||||
|
||||
# Append prefix -d to all generics
|
||||
generics = $(addprefix -g,$(generics))
|
||||
|
||||
# Add VHDL 2008 as default build standard
|
||||
vhdl_flags += -2008
|
||||
|
||||
vhdl_objs = $(vhdl_srcs:.vhd=.vhdo)
|
||||
verilog_objs = $(verilog_srcs:.v=.vo)
|
||||
|
||||
assert_level := error
|
||||
|
||||
.PHONY: sim clean
|
||||
|
||||
sim: ${verilog_objs} ${vhdl_objs}
|
||||
@vsim -voptargs=+acc -c work.${main} -g CHECK_RESULTS=true -do "run -all" \
|
||||
| scripts/highlight_test_results.sh
|
||||
|
||||
gui: ${verilog_objs} ${vhdl_objs}
|
||||
@vsim -voptargs=+acc work.${main} -g CHECK_RESULTS=false -do "do test/vsim.wave; run -all"
|
||||
|
||||
%.vo: %.v .libwork
|
||||
@echo "Analysing $<"
|
||||
@vlog -work work ${verilog_flags} $<
|
||||
|
||||
%.vhdo: %.vhd .libwork
|
||||
@echo "Analysing $<"
|
||||
@vcom -work work ${vhdl_flags} $<
|
||||
|
||||
|
||||
.libwork:
|
||||
@vlib work && vmap work work && touch $@
|
||||
|
||||
clean:
|
||||
@rm -rf work \
|
||||
.libwork \
|
||||
transcript \
|
||||
modelsim.ini \
|
||||
vlog.opt \
|
||||
vsim.wlf \
|
||||
data.py \
|
||||
data.pyc \
|
||||
|
||||
help:
|
||||
@echo Use ghdl to simulate and synthesis a vhdl design.
|
||||
@echo
|
||||
@echo Build configuration variables:
|
||||
@echo main main entity
|
||||
@echo vhdl_flags
|
||||
@echo generics
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
|
||||
ghdl_version = $(shell ghdl --version 2> /dev/null)
|
||||
vsim_version = $(shell vsim -version 2> /dev/null)
|
||||
|
||||
# in case verilog is part of the build a verilog capable simulator is required
|
||||
ifdef verilog_srcs
|
||||
ifneq (${vsim_version},)
|
||||
include scripts/questa-sim.mk
|
||||
else
|
||||
$(error No HDL simulation tool found for verilog!)
|
||||
endif
|
||||
else
|
||||
ifneq (${vsim_version},)
|
||||
include scripts/questa-sim.mk
|
||||
else
|
||||
ifneq (${ghdl_version},)
|
||||
include scripts/ghdl.mk
|
||||
else
|
||||
$(error No HDL simulation tool found!)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
library std;
|
||||
use std.env.all;
|
||||
|
||||
library work;
|
||||
use work.test_utility.all;
|
||||
|
||||
entity tb_top_entity_float_add is
|
||||
generic( CHECK_RESULTS : boolean; GUI_MODE : boolean := true );
|
||||
end;
|
||||
|
||||
architecture test of tb_top_entity_float_add is
|
||||
signal clk : std_logic := '0';
|
||||
signal reset : std_logic := '1';
|
||||
signal run_calc : std_logic := '0';
|
||||
signal operand_a : std_logic_vector(31 downto 0) := ( others => '0' );
|
||||
signal operand_b : std_logic_vector(31 downto 0) := ( others => '0' );
|
||||
signal result : std_logic_vector(31 downto 0);
|
||||
signal calc_complete : std_logic;
|
||||
begin
|
||||
|
||||
u_top_entity_float_add : entity work.top_entity_float_add
|
||||
port map (
|
||||
clk => clk,
|
||||
reset => reset,
|
||||
run_calc => run_calc,
|
||||
operand_a => operand_a,
|
||||
operand_b => operand_b,
|
||||
result => result,
|
||||
calc_complete => calc_complete
|
||||
);
|
||||
|
||||
a_clk: clk <= not clk after 10 ns;
|
||||
|
||||
a_reset: process( clk )
|
||||
begin
|
||||
if falling_edge( clk ) then
|
||||
reset <= '0';
|
||||
end if;
|
||||
end process;
|
||||
|
||||
delay : process
|
||||
variable res : std_logic_vector( 31 downto 0 );
|
||||
variable expected : std_logic_vector( 31 downto 0 );
|
||||
begin
|
||||
|
||||
wait until falling_edge( reset );
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
wait until rising_edge( clk );
|
||||
run_calc <= '1';
|
||||
operand_a <= x"01000000";
|
||||
operand_b <= x"02000000";
|
||||
wait until rising_edge( calc_complete );
|
||||
run_calc <= '0';
|
||||
if ( CHECK_RESULTS ) then
|
||||
res := result;
|
||||
expected := x"02200000";
|
||||
assert_eq( res, expected );
|
||||
end if;
|
||||
wait until rising_edge( clk );
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
wait until rising_edge( clk );
|
||||
run_calc <= '1';
|
||||
operand_a <= x"4048f5c3"; -- 3.14
|
||||
operand_b <= x"402d70a4"; -- 2.71
|
||||
wait until rising_edge( calc_complete );
|
||||
if ( CHECK_RESULTS ) then
|
||||
res := result;
|
||||
expected := x"40bb3333"; -- 5.85
|
||||
assert_eq( res, expected );
|
||||
end if;
|
||||
wait until rising_edge( clk );
|
||||
|
||||
if GUI_MODE = true then
|
||||
finish;
|
||||
else
|
||||
stop;
|
||||
end if;
|
||||
end process delay;
|
||||
|
||||
end architecture test;
|
||||
@@ -0,0 +1,71 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
use ieee.float_pkg.all;
|
||||
|
||||
library std;
|
||||
use std.textio.all;
|
||||
|
||||
package test_utility is
|
||||
constant TEST_FAIL : string := "[ FAIL ]";
|
||||
constant TEST_OK : string := "[ OK ]" & LF;
|
||||
|
||||
type real_array is array ( natural range <> ) of real;
|
||||
|
||||
procedure assert_eq( variable a : in std_logic_vector; variable b : in std_logic_vector );
|
||||
|
||||
procedure assert_near( variable a : in real;
|
||||
variable b : in real;
|
||||
variable abs_err : in real );
|
||||
|
||||
procedure assert_element_near( variable a : in real;
|
||||
variable b : in real;
|
||||
variable abs_err : in real;
|
||||
variable index : in integer );
|
||||
|
||||
end package test_utility;
|
||||
|
||||
package body test_utility is
|
||||
|
||||
procedure assert_eq( variable a : in std_logic_vector; variable b : in std_logic_vector ) is
|
||||
begin
|
||||
|
||||
assert( a = b )
|
||||
report TEST_FAIL & "assert_eq" & LF &
|
||||
" a: " & to_string( a ) & LF &
|
||||
" b: " & to_string( b ) & LF
|
||||
severity error;
|
||||
end procedure assert_eq;
|
||||
|
||||
procedure assert_near( variable a : in real;
|
||||
variable b : in real;
|
||||
variable abs_err : in real ) is
|
||||
variable abs_diff : real;
|
||||
begin
|
||||
abs_diff := abs( a - b );
|
||||
assert( abs_diff <= abs_err )
|
||||
report TEST_FAIL & "assert_near" & LF &
|
||||
" a: " & to_string( a ) & LF &
|
||||
" b: " & to_string( b ) & LF &
|
||||
" " & to_string( abs_diff ) & " > " & to_string( abs_err ) & LF
|
||||
severity error;
|
||||
end procedure assert_near;
|
||||
|
||||
procedure assert_element_near( variable a : in real;
|
||||
variable b : in real;
|
||||
variable abs_err : in real;
|
||||
variable index : in integer ) is
|
||||
variable abs_diff : real;
|
||||
begin
|
||||
abs_diff := abs( a - b );
|
||||
assert( abs_diff <= abs_err )
|
||||
report TEST_FAIL & "assert_element_near" & LF &
|
||||
" element: " & integer'image( index ) & LF &
|
||||
" a: " & to_string( a ) & LF &
|
||||
" b: " & to_string( b ) & LF &
|
||||
" " & to_string( abs_diff ) & " > " & to_string( abs_err ) & LF
|
||||
severity error;
|
||||
end procedure assert_element_near;
|
||||
|
||||
end package body test_utility;
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
onerror {resume}
|
||||
quietly WaveActivateNextPane {} 0
|
||||
add wave -noupdate /tb_top_entity_float_add/clk
|
||||
add wave -noupdate /tb_top_entity_float_add/reset
|
||||
add wave -noupdate /tb_top_entity_float_add/run_calc
|
||||
add wave -noupdate /tb_top_entity_float_add/operand_a
|
||||
add wave -noupdate /tb_top_entity_float_add/operand_b
|
||||
add wave -noupdate /tb_top_entity_float_add/result
|
||||
add wave -noupdate /tb_top_entity_float_add/calc_complete
|
||||
TreeUpdate [SetDefaultTree]
|
||||
WaveRestoreCursors {{Cursor 1} {0 ns} 0}
|
||||
quietly wave cursor active 1
|
||||
configure wave -namecolwidth 150
|
||||
configure wave -valuecolwidth 100
|
||||
configure wave -justifyvalue left
|
||||
configure wave -signalnamewidth 0
|
||||
configure wave -snapdistance 10
|
||||
configure wave -datasetprefix 0
|
||||
configure wave -rowmargin 4
|
||||
configure wave -childrowmargin 2
|
||||
configure wave -gridoffset 0
|
||||
configure wave -gridperiod 1
|
||||
configure wave -griddelta 40
|
||||
configure wave -timeline 0
|
||||
configure wave -timelineunits ns
|
||||
update
|
||||
WaveRestoreZoom {242 ns} {377 ns}
|
||||
@@ -0,0 +1,68 @@
|
||||
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL; -- Bibliothek für std_logic und std_logic_vector
|
||||
use IEEE.NUMERIC_STD.ALL; -- Bibliothek für signed und unsigned Datentypen
|
||||
|
||||
entity top_entity_float_add is
|
||||
port (
|
||||
clk : in std_logic; -- Eingangssignal Systemtakt
|
||||
reset : in std_logic; -- Eingangssignal Reset zum Setzen der Default Werte
|
||||
run_calc: in std_logic; -- Eingangssignal wenn aktiv soll gerechnet werden
|
||||
operand_a : in STD_LOGIC_VECTOR(31 downto 0); -- Erster Operand in 32-bit float
|
||||
operand_b : in STD_LOGIC_VECTOR(31 downto 0); -- Zweiter Operand in 32-bit float
|
||||
result : out std_logic_vector(31 downto 0); -- Endergebnis Berechnung Addition (im slv ist ein 32-bit float gespeichert)
|
||||
calc_complete : out std_logic -- Flag das anzeiugt wann die Berechnung fertig ist (bei 1=high)
|
||||
);
|
||||
end top_entity_float_add;
|
||||
|
||||
architecture Behavioral of top_entity_float_add is
|
||||
|
||||
-- Legen Sie ein signal result_sum als std_logic_vector mit Laenge 32 Bit an
|
||||
|
||||
-- Legen Sie ein signal start als std_logic
|
||||
|
||||
-- Legen Sie ein signal done als std_logic
|
||||
|
||||
begin
|
||||
|
||||
-- Instanziieren Sie direkt die float_add Komponente
|
||||
-- Als Takt und Reset sollen die jeweiligen Eingaenge der top_entity_float_add uebergeben werden
|
||||
-- An den anderen Ports die jeweiligen zugehoerigen Signale (welche oben angelegt worden sind)
|
||||
u_float_add : entity work.float_add
|
||||
port map(
|
||||
-- Eingangssignal fuer den Takt
|
||||
clk => ,
|
||||
-- Eingangssignal zum Zuruecksetzen des Zaehlers
|
||||
reset => ,
|
||||
-- Eingang um die Berechnung zu starten
|
||||
start => ,
|
||||
-- Ausgang der anzeigt, dass die Berechnung fertig ist
|
||||
done => ,
|
||||
-- floating point operand a
|
||||
A => ,
|
||||
-- floating point operand b
|
||||
B => ,
|
||||
-- Ergebnis der Addition in floating point
|
||||
sum =>
|
||||
);
|
||||
|
||||
-- Realisieren Sie einen getakteten Prozess control mit folgenden Verhalten
|
||||
--
|
||||
-- Initialisierung der Signale bei Reset aktiv (reset=1):
|
||||
-- result soll=0 sein
|
||||
-- start soll=0 sein
|
||||
-- calc_complete soll=0 sein
|
||||
--
|
||||
-- bei steigende Flanke:
|
||||
-- Nur wenn run_calc gleich 1 ist:
|
||||
-- dann soll wenn done=1 und start=1 ist
|
||||
-- start=0, calc_complete=1 und result_sum dem Ausgang result zugewiesen werden
|
||||
-- ansonsten soll
|
||||
-- start=1, calc_complete=0 sein
|
||||
--
|
||||
control : process(reset,clk)
|
||||
begin
|
||||
|
||||
end process control;
|
||||
|
||||
end Behavioral;
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
|
||||
vhdl_srcs = test/float_add.vhd \
|
||||
fsm_add.vhd \
|
||||
test/float.vhd \
|
||||
test/test_utility.vhd \
|
||||
test/sine.vhd \
|
||||
test/cosine.vhd \
|
||||
test/sine_cosine.vhd \
|
||||
test/tb_fsm_add.vhd \
|
||||
|
||||
main = tb_fsm_add
|
||||
|
||||
CHECK_RESULTS = true
|
||||
|
||||
include scripts/vhdl.mk
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL; -- Bibliothek für std_logic und std_logic_vector
|
||||
use IEEE.NUMERIC_STD.ALL; -- Bibliothek für signed und unsigned Datentypen
|
||||
|
||||
entity fsm_add is
|
||||
port (
|
||||
clk : in std_logic; -- Eingangssignal fuer den Takt
|
||||
reset : in std_logic; -- Eingangssignal zum Zuruecksetzen des Zaehlers
|
||||
run_calc : in std_logic; -- Eingangssignal welches die Berechnungen startet
|
||||
calc_cnt: out std_logic_vector( 3 downto 0 ); -- Ausgang welcher die Anzahl der Berechnungen anzeigt
|
||||
|
||||
signal_a_read : out std_logic; -- Ausgang um Daten aus den FIFO A anzufordern
|
||||
signal_a_readdata : in std_logic_vector( 31 downto 0 ); -- Eingang der zuletzt gelesenen Daten aus dem FIFO A
|
||||
|
||||
signal_b_read : out std_logic; -- Ausgang um Daten aus den FIFO B anzufordern
|
||||
signal_b_readdata : in std_logic_vector( 31 downto 0 ); -- Eingang der zuletzt gelesenen Daten aus dem FIFO B
|
||||
|
||||
signal_write : out std_logic; -- Ausgang um Daten in den Ausgangsfifo zu schreiben
|
||||
signal_writedata : out std_logic_vector( 31 downto 0 ) -- Ausgang die Daten welche in den Ausgangsfifo geschrieben werden sollen
|
||||
);
|
||||
end entity fsm_add;
|
||||
|
||||
architecture rtl of fsm_add is
|
||||
|
||||
-- Es soll eine type AddState angelegt werden mit den Zuständen ADD_IDLE, ADD_READ_FIFO, ADD_CALC und ADD_STORE_RESULT
|
||||
|
||||
-- Es soll Signal current_add_state des oben angelegten Types AddState deklariert werden
|
||||
|
||||
-- Es soll Signal next_add_state des oben angelegten Types AddState deklariert werden
|
||||
|
||||
-- Es soll Signal start_calc als std_logic angelegt werden
|
||||
|
||||
-- Es soll Signal done als std_logic angelegt werden
|
||||
|
||||
-- Es soll Signal calc_cnt_int als Integer mit Bereich 0 bis 15 angelegt werden
|
||||
|
||||
-- Legen Sie ein signal result_sum als std_logic_vector mit Laenge 32 Bit an
|
||||
|
||||
begin
|
||||
|
||||
-- Instanzieren Sie direkt die float_add Komponente
|
||||
-- Als Takt und Reset sollen die jeweiligen Eingaenge der top_entity uebergeben werden
|
||||
-- Es sollen der Eingang
|
||||
-- Das Additonsergebnis soll dem Signal result_sum gespeichert werden
|
||||
u_float_add : entity work.float_add
|
||||
port map(
|
||||
-- Eingangssignal fuer den Takt
|
||||
clk => ,
|
||||
-- Eingangssignal zum Zuruecksetzen des Zaehlers
|
||||
reset => ,
|
||||
-- Eingang um die Berechnung zu starten
|
||||
start => ,
|
||||
-- Ausgang der anzeigt, dass die Berechnung fertig ist
|
||||
done => ,
|
||||
-- Gelesene Daten aus den FIFO A
|
||||
A => ,
|
||||
-- Gelesene Daten aus den FIFO B
|
||||
B => ,
|
||||
-- Ergebnis der Addition in floating point
|
||||
sum =>
|
||||
);
|
||||
|
||||
-- Der kombinatiorische Prozess add_state_transitions soll das Uebergangsschaltnezt steuern
|
||||
--
|
||||
-- Es soll der naechste Zustand next_add_state entsprechend der Zustandsmaschine angesteuert werden
|
||||
--
|
||||
add_state_transitions : process ( all ) is
|
||||
begin
|
||||
|
||||
end process add_state_transitions;
|
||||
|
||||
|
||||
-- Der Prozess sync soll den Zustandsspeicher und das Ausgangsschaltnetz steuern
|
||||
-- Alle gesteuerten Signale sollen bei Reset sinnvoll vorbelegt werden
|
||||
-- Es soll ein getakter Prozess welcher auf eine steigende Flanke reagiert genutzt werden
|
||||
--
|
||||
-- Folgende Signale sollen hier gesteuert werden
|
||||
-- current_add_state (Zusatandsspeicher)
|
||||
-- signal_a_read (Steuersignal um Daten aus den FIFO A zu lesen)
|
||||
-- signal_b_read (Steuersignal um Daten aus den FIFO B zu lesen)
|
||||
-- signal_write (Steuersignal um Daten in den Ausgangsfifo zu schreiben)
|
||||
-- calc_cnt_int (Zaehler welcher die Anzahl der berechneten Werrte abbilden soll)
|
||||
-- signal_writedata (Werte welcher in den Ausgangsfifo geschrieben werden soll = letzter berechneter Wert result_sum)
|
||||
--
|
||||
-- Die Signale sollen entsprechend der Zustandsmaschine angesteuert werden
|
||||
--
|
||||
sync : process ( clk, reset ) is
|
||||
begin
|
||||
|
||||
end process sync;
|
||||
|
||||
-- Weisen Sie dem Ausgang calc_cnt das signal calc_cnt_int zu (Datentypen beachten Konvertierung noetig)
|
||||
|
||||
|
||||
end architecture rtl;
|
||||
Executable
+15
@@ -0,0 +1,15 @@
|
||||
#!/bin/bash
|
||||
script_dir=$(cd $(dirname "${BASH_SOURCE[0]}") && pwd)
|
||||
|
||||
if [ $# -ne 1 ]
|
||||
then
|
||||
echo Usage $0 test-output-file
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cat $1 | sed -z -e 's/\(py_.* \[\)/ \[/g' | ${script_dir}/highlight_test_results.sh
|
||||
|
||||
if grep -q FAIL $1
|
||||
then
|
||||
exit 1
|
||||
fi
|
||||
Executable
+14
@@ -0,0 +1,14 @@
|
||||
#!/bin/bash
|
||||
script_path="$( dirname "$( readlink -f "${BASH_SOURCE[0]}" )" )"
|
||||
|
||||
if [ $# -lt 1 ]
|
||||
then
|
||||
echo " usage: execute_and_highlight command arguments"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cmd=$1
|
||||
shift 1
|
||||
$cmd $@ | $script_path/highlight_test_results.sh
|
||||
test ${PIPESTATUS[0]} -eq 0
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
|
||||
# Make sure that the top level is assigned to main
|
||||
$(if $(main),,\
|
||||
$(error Assign top level entity name to variable "main"))
|
||||
|
||||
# Make sure that at least on vhdl source is assigned
|
||||
$(if $(vhdl_srcs),,\
|
||||
$(error Assign at least on vhdl source to variable "vhdl_srcs"))
|
||||
|
||||
# Append prefix -d to all generics
|
||||
generics = $(addprefix -g,$(generics))
|
||||
|
||||
# Add VHDL 2008 as default build standard
|
||||
vhdl_flags += --std=08
|
||||
vhdl_flags += -frelaxed-rules
|
||||
#vhdl_flags += --ieee-asserts=disable-at-0
|
||||
|
||||
vhdl_objs = $(vhdl_srcs:.vhd=.o)
|
||||
|
||||
assert_level := error
|
||||
|
||||
.PHONY: sim clean
|
||||
|
||||
sim: ${main}
|
||||
@scripts/execute_and_highlight.sh \
|
||||
ghdl \
|
||||
-r ${vhdl_flags} ${main} \
|
||||
--ieee-asserts=disable-at-0 \
|
||||
-gCHECK_RESULTS=${CHECK_RESULTS} \
|
||||
--read-wave-opt=test/${main}.wave \
|
||||
--assert-level=${assert_level}
|
||||
|
||||
gui: test/${main}.ghw
|
||||
@echo "Viewing $<"
|
||||
@gtkwave $< --script=test/gtkwave.view
|
||||
|
||||
test/${main}.ghw: ${main} test/${main}.wave
|
||||
@ghdl -r ${vhdl_flags} ${main} \
|
||||
--read-wave-opt=test/${main}.wave \
|
||||
--wave=$@
|
||||
|
||||
${main}: $(vhdl_objs)
|
||||
@echo "Elaborating ${main}"
|
||||
@ghdl -e ${vhdl_flags} ${main}
|
||||
|
||||
%.o: %.vhd
|
||||
@echo "Analysing $<"
|
||||
@ghdl -a ${vhdl_flags} $<
|
||||
|
||||
clean:
|
||||
@ghdl --clean
|
||||
@rm -rf ${main}.ghw work-obj08.cf ${vhdl_objs} ${main} ${artifacts}
|
||||
|
||||
help:
|
||||
@echo Use ghdl to simulate and synthesis a vhdl design.
|
||||
@echo
|
||||
@echo Build configuration variables:
|
||||
@echo main main entity
|
||||
@echo vhdl_flags
|
||||
@echo generics
|
||||
|
||||
Executable
+7
@@ -0,0 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
red=$(tput setaf 1)
|
||||
green=$(tput setaf 2)
|
||||
default=$(tput sgr0)
|
||||
|
||||
sed "s/FAIL/${red}FAIL${default}/" | sed "s/OK/${green}OK${default}/"
|
||||
@@ -0,0 +1,63 @@
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
|
||||
# Make sure that the top level is assigned to main
|
||||
$(if $(main),,\
|
||||
$(error Assign top level entity name to variable "main"))
|
||||
|
||||
# Make sure that at least on vhdl source is assigned
|
||||
$(if $(vhdl_srcs),,\
|
||||
$(error Assign at least on vhdl source to variable "vhdl_srcs"))
|
||||
|
||||
# Append prefix -d to all generics
|
||||
generics = $(addprefix -g,$(generics))
|
||||
|
||||
# Add VHDL 2008 as default build standard
|
||||
vhdl_flags += -2008
|
||||
|
||||
vhdl_objs = $(vhdl_srcs:.vhd=.vhdo)
|
||||
verilog_objs = $(verilog_srcs:.v=.vo)
|
||||
|
||||
assert_level := error
|
||||
|
||||
.PHONY: sim clean
|
||||
|
||||
sim: ${verilog_objs} ${vhdl_objs}
|
||||
@vsim -voptargs=+acc -c work.${main} -g CHECK_RESULTS=true -do "run -all" \
|
||||
| scripts/highlight_test_results.sh
|
||||
|
||||
gui: ${verilog_objs} ${vhdl_objs}
|
||||
@vsim -voptargs=+acc work.${main} -g CHECK_RESULTS=false -do "do test/vsim.wave; run -all"
|
||||
|
||||
%.vo: %.v .libwork
|
||||
@echo "Analysing $<"
|
||||
@vlog -work work ${verilog_flags} $<
|
||||
|
||||
%.vhdo: %.vhd .libwork
|
||||
@echo "Analysing $<"
|
||||
@vcom -work work ${vhdl_flags} $<
|
||||
|
||||
|
||||
.libwork:
|
||||
@vlib work && vmap work work && touch $@
|
||||
|
||||
clean:
|
||||
@rm -rf work \
|
||||
.libwork \
|
||||
transcript \
|
||||
modelsim.ini \
|
||||
vlog.opt \
|
||||
vsim.wlf \
|
||||
data.py \
|
||||
data.pyc \
|
||||
|
||||
help:
|
||||
@echo Use ghdl to simulate and synthesis a vhdl design.
|
||||
@echo
|
||||
@echo Build configuration variables:
|
||||
@echo main main entity
|
||||
@echo vhdl_flags
|
||||
@echo generics
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
|
||||
ghdl_version = $(shell ghdl --version 2> /dev/null)
|
||||
vsim_version = $(shell vsim -version 2> /dev/null)
|
||||
|
||||
# in case verilog is part of the build a verilog capable simulator is required
|
||||
ifdef verilog_srcs
|
||||
ifneq (${vsim_version},)
|
||||
include scripts/questa-sim.mk
|
||||
else
|
||||
$(error No HDL simulation tool found for verilog!)
|
||||
endif
|
||||
else
|
||||
ifneq (${vsim_version},)
|
||||
include scripts/questa-sim.mk
|
||||
else
|
||||
ifneq (${ghdl_version},)
|
||||
include scripts/ghdl.mk
|
||||
else
|
||||
$(error No HDL simulation tool found!)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
library work;
|
||||
use work.test_utility.all;
|
||||
|
||||
package cosine_data is
|
||||
constant expected : real_array( 0 to 1023 ) := (2.000000e+00,1.999013e+00,1.996053e+00,1.991124e+00,1.984229e+00,1.975377e+00,1.964574e+00,1.951833e+00,1.937166e+00,1.920587e+00,1.902113e+00,1.881762e+00,1.859553e+00,1.835509e+00,1.809654e+00,1.782013e+00,1.752613e+00,1.721484e+00,1.688656e+00,1.654161e+00,1.618034e+00,1.580310e+00,1.541026e+00,1.500222e+00,1.457937e+00,1.414214e+00,1.369094e+00,1.322624e+00,1.274848e+00,1.225814e+00,1.175570e+00,1.124167e+00,1.071653e+00,1.018083e+00,9.635071e-01,9.079807e-01,8.515583e-01,7.942955e-01,7.362492e-01,6.774759e-01,6.180341e-01,5.579823e-01,4.973798e-01,4.362865e-01,3.747626e-01,3.128689e-01,2.506664e-01,1.882165e-01,1.255809e-01,6.282137e-02,-1.748456e-07,-6.282172e-02,-1.255808e-01,-1.882164e-01,-2.506667e-01,-3.128692e-01,-3.747630e-01,-4.362864e-01,-4.973797e-01,-5.579821e-01,-6.180344e-01,-6.774758e-01,-7.362491e-01,-7.942958e-01,-8.515586e-01,-9.079811e-01,-9.635074e-01,-1.018083e+00,-1.071654e+00,-1.124167e+00,-1.175571e+00,-1.225814e+00,-1.274848e+00,-1.322624e+00,-1.369094e+00,-1.414213e+00,-1.457937e+00,-1.500222e+00,-1.541026e+00,-1.580310e+00,-1.618034e+00,-1.654161e+00,-1.688656e+00,-1.721484e+00,-1.752613e+00,-1.782013e+00,-1.809654e+00,-1.835509e+00,-1.859553e+00,-1.881761e+00,-1.902113e+00,-1.920587e+00,-1.937166e+00,-1.951833e+00,-1.964574e+00,-1.975377e+00,-1.984229e+00,-1.991124e+00,-1.996053e+00,-1.999013e+00,-2.000000e+00,-1.999013e+00,-1.996053e+00,-1.991124e+00,-1.984229e+00,-1.975377e+00,-1.964574e+00,-1.951833e+00,-1.937166e+00,-1.920587e+00,-1.902113e+00,-1.881761e+00,-1.859553e+00,-1.835509e+00,-1.809654e+00,-1.782013e+00,-1.752614e+00,-1.721484e+00,-1.688656e+00,-1.654161e+00,-1.618034e+00,-1.580310e+00,-1.541026e+00,-1.500222e+00,-1.457937e+00,-1.414214e+00,-1.369094e+00,-1.322624e+00,-1.274848e+00,-1.225814e+00,-1.175571e+00,-1.124167e+00,-1.071653e+00,-1.018083e+00,-9.635074e-01,-9.079810e-01,-8.515586e-01,-7.942958e-01,-7.362491e-01,-6.774758e-01,-6.180339e-01,-5.579821e-01,-4.973796e-01,-4.362863e-01,-3.747624e-01,-3.128687e-01,-2.506662e-01,-1.882164e-01,-1.255807e-01,-6.282119e-02,3.496911e-07,6.282189e-02,1.255814e-01,1.882161e-01,2.506660e-01,3.128684e-01,3.747622e-01,4.362870e-01,4.973803e-01,5.579827e-01,6.180345e-01,6.774764e-01,7.362489e-01,7.942955e-01,8.515584e-01,9.079808e-01,9.635072e-01,1.018083e+00,1.071653e+00,1.124167e+00,1.175571e+00,1.225814e+00,1.274848e+00,1.322624e+00,1.369094e+00,1.414214e+00,1.457937e+00,1.500222e+00,1.541027e+00,1.580310e+00,1.618034e+00,1.654161e+00,1.688656e+00,1.721484e+00,1.752614e+00,1.782013e+00,1.809654e+00,1.835509e+00,1.859553e+00,1.881762e+00,1.902113e+00,1.920587e+00,1.937166e+00,1.951833e+00,1.964575e+00,1.975377e+00,1.984229e+00,1.991124e+00,1.996053e+00,1.999013e+00,2.000000e+00,1.999013e+00,1.996053e+00,1.991124e+00,1.984229e+00,1.975377e+00,1.964574e+00,1.951833e+00,1.937166e+00,1.920587e+00,1.902113e+00,1.881762e+00,1.859553e+00,1.835509e+00,1.809654e+00,1.782013e+00,1.752613e+00,1.721484e+00,1.688656e+00,1.654161e+00,1.618034e+00,1.580310e+00,1.541026e+00,1.500222e+00,1.457937e+00,1.414214e+00,1.369094e+00,1.322624e+00,1.274848e+00,1.225814e+00,1.175570e+00,1.124167e+00,1.071653e+00,1.018083e+00,9.635071e-01,9.079807e-01,8.515583e-01,7.942955e-01,7.362492e-01,6.774759e-01,6.180341e-01,5.579823e-01,4.973798e-01,4.362865e-01,3.747626e-01,3.128689e-01,2.506664e-01,1.882165e-01,1.255809e-01,6.282137e-02,-1.748456e-07,-6.282172e-02,-1.255808e-01,-1.882164e-01,-2.506667e-01,-3.128692e-01,-3.747630e-01,-4.362864e-01,-4.973797e-01,-5.579821e-01,-6.180344e-01,-6.774758e-01,-7.362491e-01,-7.942958e-01,-8.515586e-01,-9.079811e-01,-9.635074e-01,-1.018083e+00,-1.071654e+00,-1.124167e+00,-1.175571e+00,-1.225814e+00,-1.274848e+00,-1.322624e+00,-1.369094e+00,-1.414213e+00,-1.457937e+00,-1.500222e+00,-1.541026e+00,-1.580310e+00,-1.618034e+00,-1.654161e+00,-1.688656e+00,-1.721484e+00,-1.752613e+00,-1.782013e+00,-1.809654e+00,-1.835509e+00,-1.859553e+00,-1.881761e+00,-1.902113e+00,-1.920587e+00,-1.937166e+00,-1.951833e+00,-1.964574e+00,-1.975377e+00,-1.984229e+00,-1.991124e+00,-1.996053e+00,-1.999013e+00,-2.000000e+00,-1.999013e+00,-1.996053e+00,-1.991124e+00,-1.984229e+00,-1.975377e+00,-1.964574e+00,-1.951833e+00,-1.937166e+00,-1.920587e+00,-1.902113e+00,-1.881761e+00,-1.859553e+00,-1.835509e+00,-1.809654e+00,-1.782013e+00,-1.752614e+00,-1.721484e+00,-1.688656e+00,-1.654161e+00,-1.618034e+00,-1.580310e+00,-1.541026e+00,-1.500222e+00,-1.457937e+00,-1.414214e+00,-1.369094e+00,-1.322624e+00,-1.274848e+00,-1.225814e+00,-1.175571e+00,-1.124167e+00,-1.071653e+00,-1.018083e+00,-9.635074e-01,-9.079810e-01,-8.515586e-01,-7.942958e-01,-7.362491e-01,-6.774758e-01,-6.180339e-01,-5.579821e-01,-4.973796e-01,-4.362863e-01,-3.747624e-01,-3.128687e-01,-2.506662e-01,-1.882164e-01,-1.255807e-01,-6.282119e-02,3.496911e-07,6.282189e-02,1.255814e-01,1.882161e-01,2.506660e-01,3.128684e-01,3.747622e-01,4.362870e-01,4.973803e-01,5.579827e-01,6.180345e-01,6.774764e-01,7.362489e-01,7.942955e-01,8.515584e-01,9.Line truncated
|
||||
end package cosine_data;
|
||||
@@ -0,0 +1,144 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
package float is
|
||||
constant SIGN : std_logic_vector( 31 downto 31 ) := ( others => '0' );
|
||||
constant EXP : std_logic_vector( 30 downto 23 ) := ( others => '0' );
|
||||
constant MANTISSA : std_logic_vector( 22 downto 0 ) := ( others => '0' );
|
||||
|
||||
function find_leftmost( arg : unsigned; value : std_ulogic ) return integer;
|
||||
|
||||
function count_leading_digits( arg : unsigned; value : std_ulogic ) return integer;
|
||||
|
||||
function to_float( arg : std_logic_vector ) return std_logic_vector;
|
||||
|
||||
function to_fixed( arg : std_logic_vector ) return std_logic_vector;
|
||||
|
||||
end package float;
|
||||
|
||||
package body float is
|
||||
function find_leftmost( arg : unsigned; value : std_ulogic ) return integer is
|
||||
begin
|
||||
for i in arg'left downto arg'right loop
|
||||
if ( arg( i ) = value ) then
|
||||
return i;
|
||||
end if;
|
||||
end loop;
|
||||
|
||||
return -1;
|
||||
end function find_leftmost;
|
||||
|
||||
function count_leading_digits( arg : unsigned; value : std_ulogic ) return integer is
|
||||
variable left_most_value : integer range -1 to arg'high;
|
||||
variable leading_values : integer range 0 to arg'high;
|
||||
begin
|
||||
left_most_value := find_leftmost( arg, not value );
|
||||
leading_values := 0;
|
||||
|
||||
if ( left_most_value /= -1 ) then
|
||||
leading_values := arg'high - left_most_value;
|
||||
end if;
|
||||
|
||||
return leading_values;
|
||||
end function count_leading_digits;
|
||||
|
||||
function to_float( arg : std_logic_vector ) return std_logic_vector is
|
||||
variable y : std_logic_vector( 31 downto 0 );
|
||||
variable s : std_logic;
|
||||
variable e : unsigned( 7 downto 0 );
|
||||
variable m : unsigned( 22 downto 0 );
|
||||
variable value : unsigned( 30 downto 0 );
|
||||
|
||||
variable leading_sign_digits : integer range 0 to value'high;
|
||||
variable reminding : integer range 0 to value'high;
|
||||
begin
|
||||
s := arg( 31 );
|
||||
|
||||
if ( s = '0' ) then
|
||||
value := unsigned( arg( 30 downto 0 ) );
|
||||
else
|
||||
value := not unsigned( arg( 30 downto 0 ) );
|
||||
value := value +1;
|
||||
end if;
|
||||
leading_sign_digits := count_leading_digits( value, '0' );
|
||||
reminding := value'high - leading_sign_digits;
|
||||
e := to_unsigned( 126 - leading_sign_digits, e'length );
|
||||
|
||||
if ( reminding > m'length ) then
|
||||
m := value( reminding - 1 downto reminding - m'length );
|
||||
elsif ( reminding > 1 ) then
|
||||
m := ( others => '0' );
|
||||
m( m'high downto m'high - reminding + 1 ) := value( reminding - 1 downto 0 );
|
||||
else
|
||||
m := ( others => '0' );
|
||||
end if;
|
||||
|
||||
if (arg = x"00000000") then
|
||||
y := (others => '0');
|
||||
else
|
||||
y := s & std_logic_vector( e ) & std_logic_vector( m );
|
||||
end if;
|
||||
|
||||
return y;
|
||||
end function to_float;
|
||||
|
||||
function to_fixed( arg : std_logic_vector ) return std_logic_vector is
|
||||
variable y : unsigned( 31 downto 0 );
|
||||
variable s : std_logic;
|
||||
variable e : unsigned( 7 downto 0 );
|
||||
variable m_index_max : integer range -127 to 128;
|
||||
|
||||
begin
|
||||
s := arg( 31 );
|
||||
e := unsigned(arg(30 downto 23));
|
||||
m_index_max := to_integer(signed(30-(126-e)));
|
||||
|
||||
if (arg = x"00000000") then
|
||||
y := (others => '0');
|
||||
else
|
||||
y := (others => '0');
|
||||
case m_index_max is
|
||||
when 30 => y(30 downto 7):= '1' & unsigned( arg(22 downto 0) );
|
||||
when 29 => y(29 downto 6):= '1' & unsigned( arg(22 downto 0) );
|
||||
when 28 => y(28 downto 5):= '1' & unsigned( arg(22 downto 0) );
|
||||
when 27 => y(27 downto 4):= '1' & unsigned( arg(22 downto 0) );
|
||||
when 26 => y(26 downto 3):= '1' & unsigned( arg(22 downto 0) );
|
||||
when 25 => y(25 downto 2):= '1' & unsigned( arg(22 downto 0) );
|
||||
when 24 => y(24 downto 1):= '1' & unsigned( arg(22 downto 0) );
|
||||
when 23 => y(23 downto 0):= '1' & unsigned( arg(22 downto 0) );
|
||||
when 22 => y(22 downto 0):= '1' & unsigned( arg(22 downto 1) );
|
||||
when 21 => y(21 downto 0):= '1' & unsigned( arg(22 downto 2) );
|
||||
when 20 => y(20 downto 0):= '1' & unsigned( arg(22 downto 3) );
|
||||
when 19 => y(19 downto 0):= '1' & unsigned( arg(22 downto 4) );
|
||||
when 18 => y(18 downto 0):= '1' & unsigned( arg(22 downto 5) );
|
||||
when 17 => y(17 downto 0):= '1' & unsigned( arg(22 downto 6) );
|
||||
when 16 => y(16 downto 0):= '1' & unsigned( arg(22 downto 7) );
|
||||
when 15 => y(15 downto 0):= '1' & unsigned( arg(22 downto 8) );
|
||||
when 14 => y(14 downto 0):= '1' & unsigned( arg(22 downto 9) );
|
||||
when 13 => y(13 downto 0):= '1' & unsigned( arg(22 downto 10) );
|
||||
when 12 => y(12 downto 0):= '1' & unsigned( arg(22 downto 11) );
|
||||
when 11 => y(11 downto 0):= '1' & unsigned( arg(22 downto 12) );
|
||||
when 10 => y(10 downto 0):= '1' & unsigned( arg(22 downto 13) );
|
||||
when 9 => y(9 downto 0):= '1' & unsigned( arg(22 downto 14) );
|
||||
when 8 => y(8 downto 0):= '1' & unsigned( arg(22 downto 15) );
|
||||
when 7 => y(7 downto 0):= '1' & unsigned( arg(22 downto 16) );
|
||||
when 6 => y(6 downto 0):= '1' & unsigned( arg(22 downto 17) );
|
||||
when 5 => y(5 downto 0):= '1' & unsigned( arg(22 downto 18) );
|
||||
when 4 => y(4 downto 0):= '1' & unsigned( arg(22 downto 19) );
|
||||
when 3 => y(3 downto 0):= '1' & unsigned( arg(22 downto 20) );
|
||||
when 2 => y(2 downto 0):= '1' & unsigned( arg(22 downto 21) );
|
||||
when 1 => y(1 downto 0):= '1' & unsigned( arg(22 downto 22) );
|
||||
when 0 => y(0):= '1';
|
||||
when others => null;
|
||||
end case;
|
||||
if ( s = '1' ) then
|
||||
y := not(y);
|
||||
y:= y + x"00000001";
|
||||
end if;
|
||||
end if;
|
||||
|
||||
return std_logic_vector( y );
|
||||
end function to_fixed;
|
||||
|
||||
end package body float;
|
||||
@@ -0,0 +1,133 @@
|
||||
library IEEE;
|
||||
use IEEE.std_logic_1164.all;
|
||||
use IEEE.numeric_std.all;
|
||||
entity float_add is
|
||||
port(A : in std_logic_vector(31 downto 0);
|
||||
B : in std_logic_vector(31 downto 0);
|
||||
clk : in std_logic;
|
||||
reset : in std_logic;
|
||||
start : in std_logic;
|
||||
done : out std_logic;
|
||||
sum : out std_logic_vector(31 downto 0)
|
||||
);
|
||||
end float_add;
|
||||
|
||||
architecture mixed of float_add is
|
||||
type ST is (WAIT_STATE, ALIGN_STATE, ADDITION_STATE, NORMALIZE_STATE, OUTPUT_STATE);
|
||||
signal state : ST := WAIT_STATE;
|
||||
|
||||
---Internal Signals latched from the inputs
|
||||
signal A_mantissa, B_mantissa : std_logic_vector (24 downto 0);
|
||||
signal A_exp, B_exp : std_logic_vector (8 downto 0);
|
||||
signal A_sgn, B_sgn : std_logic;
|
||||
|
||||
--Internal signals for Output
|
||||
signal sum_exp: std_logic_vector (8 downto 0);
|
||||
signal sum_mantissa : std_logic_vector (24 downto 0);
|
||||
signal sum_sgn : std_logic;
|
||||
|
||||
begin
|
||||
|
||||
Control_Unit : process (clk, reset) is
|
||||
variable diff : signed(8 downto 0);
|
||||
begin
|
||||
if(reset = '1') then
|
||||
state <= WAIT_STATE; --start in wait state
|
||||
done <= '0';
|
||||
elsif rising_edge(clk) then
|
||||
case state is
|
||||
when WAIT_STATE =>
|
||||
if (start = '1') then --wait till start request startes high
|
||||
A_sgn <= A(31);
|
||||
A_exp <= '0' & A(30 downto 23); --One bit is added for signed subtraction
|
||||
A_mantissa <= "01" & A(22 downto 0); --Two bits are added extra, one for leading 1 and other one for storing carry
|
||||
B_sgn <= B(31);
|
||||
B_exp <= '0' & B(30 downto 23);
|
||||
B_mantissa <= "01" & B(22 downto 0);
|
||||
state <= ALIGN_STATE;
|
||||
else
|
||||
state <= WAIT_STATE;
|
||||
end if;
|
||||
when ALIGN_STATE => --Compare exponent and align it
|
||||
--If any num is greater by 2**24, we skip the addition.
|
||||
if unsigned(A_exp) > unsigned(B_exp) then
|
||||
--B needs downshifting
|
||||
diff := signed(A_exp) - signed(B_exp); --Small Alu
|
||||
if diff > 23 then
|
||||
sum_mantissa <= A_mantissa; --B insignificant relative to A
|
||||
sum_exp <= A_exp;
|
||||
sum_sgn <= A_sgn;
|
||||
state <= OUTPUT_STATE; --start latch A as output
|
||||
else
|
||||
--downshift B to equilabrate B_exp to A_exp
|
||||
sum_exp <= A_exp;
|
||||
B_mantissa(24-to_integer(diff) downto 0) <= B_mantissa(24 downto to_integer(diff));
|
||||
B_mantissa(24 downto 25-to_integer(diff)) <= (others => '0');
|
||||
state <= ADDITION_STATE;
|
||||
end if;
|
||||
elsif unsigned(A_exp) < unsigned(B_exp) then --A_exp < B_exp. A needs downshifting
|
||||
diff := signed(B_exp) - signed(A_exp); -- Small Alu
|
||||
if diff > 23 then
|
||||
sum_mantissa <= B_mantissa; --A insignificant relative to B
|
||||
sum_sgn <= B_sgn;
|
||||
sum_exp <= B_exp;
|
||||
state <= OUTPUT_STATE; --start latch B as output
|
||||
else
|
||||
--downshift A to equilabrate A_exp to B_exp
|
||||
sum_exp <= B_exp;
|
||||
A_mantissa(24-to_integer(diff) downto 0) <= A_mantissa(24 downto to_integer(diff));
|
||||
A_mantissa(24 downto 25-to_integer(diff)) <= (others => '0');
|
||||
state <= ADDITION_STATE;
|
||||
end if;
|
||||
else -- Both exponent is equal. No need to mantissa shift
|
||||
sum_exp <= A_exp;
|
||||
state <= ADDITION_STATE;
|
||||
end if;
|
||||
when ADDITION_STATE => --Mantissa addition
|
||||
state <= NORMALIZE_STATE;
|
||||
if (A_sgn xor B_sgn) = '0' then --signs are the same. Just add them
|
||||
sum_mantissa <= std_logic_vector((unsigned(A_mantissa) + unsigned(B_mantissa))); --Big Alu
|
||||
sum_sgn <= A_sgn; --both nums have same sign
|
||||
--Else subtract smaller from larger and use sign of larger
|
||||
elsif unsigned(A_mantissa) >= unsigned(B_mantissa) then
|
||||
sum_mantissa <= std_logic_vector((unsigned(A_mantissa) - unsigned(B_mantissa))); --Big Alu
|
||||
sum_sgn <= A_sgn;
|
||||
else
|
||||
sum_mantissa <= std_logic_vector((unsigned(B_mantissa) - unsigned(A_mantissa))); --Big Alu
|
||||
sum_sgn <= B_sgn;
|
||||
end if;
|
||||
|
||||
when NORMALIZE_STATE => --Normalization.
|
||||
if unsigned(sum_mantissa) = TO_UNSIGNED(0, 25) then
|
||||
--The sum is 0
|
||||
sum_mantissa <= (others => '0');
|
||||
sum_exp <= (others => '0');
|
||||
state <= OUTPUT_STATE;
|
||||
elsif(sum_mantissa(24) = '1') then --If sum overflowed we downshift and are done.
|
||||
sum_mantissa <= '0' & sum_mantissa(24 downto 1); --shift the 1 down
|
||||
sum_exp <= std_logic_vector((unsigned(sum_exp)+ 1));
|
||||
state <= OUTPUT_STATE;
|
||||
elsif(sum_mantissa(23) = '0') then --in this case we need to upshift
|
||||
--This iterates the normalization shifts, thus can take many clocks.
|
||||
sum_mantissa <= sum_mantissa(23 downto 0) & '0';
|
||||
sum_exp <= std_logic_vector((unsigned(sum_exp)-1));
|
||||
state<= NORMALIZE_STATE; --keep shifting till leading 1 appears
|
||||
else
|
||||
state <= OUTPUT_STATE; --leading 1 already there. Latch output
|
||||
end if;
|
||||
when OUTPUT_STATE =>
|
||||
sum(22 downto 0) <= sum_mantissa(22 downto 0);
|
||||
sum(30 downto 23) <= sum_exp(7 downto 0);
|
||||
sum(31) <= sum_sgn;
|
||||
done <= '1'; -- signal done
|
||||
if (start = '0') then -- stay in the state till request ends i.e start is low
|
||||
done <= '0';
|
||||
state <= WAIT_STATE;
|
||||
end if;
|
||||
when others =>
|
||||
state <= WAIT_STATE; --Just in case.
|
||||
end case;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end mixed;
|
||||
@@ -0,0 +1,9 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
library work;
|
||||
use work.test_utility.all;
|
||||
|
||||
package sine_data is
|
||||
constant expected : real_array( 0 to 1023 ) := (0.000000e+00,7.803613e-01,1.530734e+00,2.222281e+00,2.828427e+00,3.325878e+00,3.695518e+00,3.923141e+00,4.000000e+00,3.923141e+00,3.695518e+00,3.325879e+00,2.828427e+00,2.222281e+00,1.530734e+00,7.803612e-01,-3.496911e-07,-7.803610e-01,-1.530734e+00,-2.222281e+00,-2.828427e+00,-3.325878e+00,-3.695518e+00,-3.923141e+00,-4.000000e+00,-3.923141e+00,-3.695518e+00,-3.325879e+00,-2.828428e+00,-2.222281e+00,-1.530734e+00,-7.803609e-01,0.000000e+00,7.803613e-01,1.530734e+00,2.222281e+00,2.828427e+00,3.325878e+00,3.695518e+00,3.923141e+00,4.000000e+00,3.923141e+00,3.695518e+00,3.325879e+00,2.828427e+00,2.222281e+00,1.530734e+00,7.803612e-01,-3.496911e-07,-7.803610e-01,-1.530734e+00,-2.222281e+00,-2.828427e+00,-3.325878e+00,-3.695518e+00,-3.923141e+00,-4.000000e+00,-3.923141e+00,-3.695518e+00,-3.325879e+00,-2.828428e+00,-2.222281e+00,-1.530734e+00,-7.803609e-01,0.000000e+00,7.803613e-01,1.530734e+00,2.222281e+00,2.828427e+00,3.325878e+00,3.695518e+00,3.923141e+00,4.000000e+00,3.923141e+00,3.695518e+00,3.325879e+00,2.828427e+00,2.222281e+00,1.530734e+00,7.803612e-01,-3.496911e-07,-7.803610e-01,-1.530734e+00,-2.222281e+00,-2.828427e+00,-3.325878e+00,-3.695518e+00,-3.923141e+00,-4.000000e+00,-3.923141e+00,-3.695518e+00,-3.325879e+00,-2.828428e+00,-2.222281e+00,-1.530734e+00,-7.803609e-01,0.000000e+00,7.803613e-01,1.530734e+00,2.222281e+00,2.828427e+00,3.325878e+00,3.695518e+00,3.923141e+00,4.000000e+00,3.923141e+00,3.695518e+00,3.325879e+00,2.828427e+00,2.222281e+00,1.530734e+00,7.803612e-01,-3.496911e-07,-7.803610e-01,-1.530734e+00,-2.222281e+00,-2.828427e+00,-3.325878e+00,-3.695518e+00,-3.923141e+00,-4.000000e+00,-3.923141e+00,-3.695518e+00,-3.325879e+00,-2.828428e+00,-2.222281e+00,-1.530734e+00,-7.803609e-01,0.000000e+00,7.803613e-01,1.530734e+00,2.222281e+00,2.828427e+00,3.325878e+00,3.695518e+00,3.923141e+00,4.000000e+00,3.923141e+00,3.695518e+00,3.325879e+00,2.828427e+00,2.222281e+00,1.530734e+00,7.803612e-01,-3.496911e-07,-7.803610e-01,-1.530734e+00,-2.222281e+00,-2.828427e+00,-3.325878e+00,-3.695518e+00,-3.923141e+00,-4.000000e+00,-3.923141e+00,-3.695518e+00,-3.325879e+00,-2.828428e+00,-2.222281e+00,-1.530734e+00,-7.803609e-01,0.000000e+00,7.803613e-01,1.530734e+00,2.222281e+00,2.828427e+00,3.325878e+00,3.695518e+00,3.923141e+00,4.000000e+00,3.923141e+00,3.695518e+00,3.325879e+00,2.828427e+00,2.222281e+00,1.530734e+00,7.803612e-01,-3.496911e-07,-7.803610e-01,-1.530734e+00,-2.222281e+00,-2.828427e+00,-3.325878e+00,-3.695518e+00,-3.923141e+00,-4.000000e+00,-3.923141e+00,-3.695518e+00,-3.325879e+00,-2.828428e+00,-2.222281e+00,-1.530734e+00,-7.803609e-01,0.000000e+00,7.803613e-01,1.530734e+00,2.222281e+00,2.828427e+00,3.325878e+00,3.695518e+00,3.923141e+00,4.000000e+00,3.923141e+00,3.695518e+00,3.325879e+00,2.828427e+00,2.222281e+00,1.530734e+00,7.803612e-01,-3.496911e-07,-7.803610e-01,-1.530734e+00,-2.222281e+00,-2.828427e+00,-3.325878e+00,-3.695518e+00,-3.923141e+00,-4.000000e+00,-3.923141e+00,-3.695518e+00,-3.325879e+00,-2.828428e+00,-2.222281e+00,-1.530734e+00,-7.803609e-01,0.000000e+00,7.803613e-01,1.530734e+00,2.222281e+00,2.828427e+00,3.325878e+00,3.695518e+00,3.923141e+00,4.000000e+00,3.923141e+00,3.695518e+00,3.325879e+00,2.828427e+00,2.222281e+00,1.530734e+00,7.803612e-01,-3.496911e-07,-7.803610e-01,-1.530734e+00,-2.222281e+00,-2.828427e+00,-3.325878e+00,-3.695518e+00,-3.923141e+00,-4.000000e+00,-3.923141e+00,-3.695518e+00,-3.325879e+00,-2.828428e+00,-2.222281e+00,-1.530734e+00,-7.803609e-01,0.000000e+00,7.803613e-01,1.530734e+00,2.222281e+00,2.828427e+00,3.325878e+00,3.695518e+00,3.923141e+00,4.000000e+00,3.923141e+00,3.695518e+00,3.325879e+00,2.828427e+00,2.222281e+00,1.530734e+00,7.803612e-01,-3.496911e-07,-7.803610e-01,-1.530734e+00,-2.222281e+00,-2.828427e+00,-3.325878e+00,-3.695518e+00,-3.923141e+00,-4.000000e+00,-3.923141e+00,-3.695518e+00,-3.325879e+00,-2.828428e+00,-2.222281e+00,-1.530734e+00,-7.803609e-01,0.000000e+00,7.803613e-01,1.530734e+00,2.222281e+00,2.828427e+00,3.325878e+00,3.695518e+00,3.923141e+00,4.000000e+00,3.923141e+00,3.695518e+00,3.325879e+00,2.828427e+00,2.222281e+00,1.530734e+00,7.803612e-01,-3.496911e-07,-7.803610e-01,-1.530734e+00,-2.222281e+00,-2.828427e+00,-3.325878e+00,-3.695518e+00,-3.923141e+00,-4.000000e+00,-3.923141e+00,-3.695518e+00,-3.325879e+00,-2.828428e+00,-2.222281e+00,-1.530734e+00,-7.803609e-01,0.000000e+00,7.803613e-01,1.530734e+00,2.222281e+00,2.828427e+00,3.325878e+00,3.695518e+00,3.923141e+00,4.000000e+00,3.923141e+00,3.695518e+00,3.325879e+00,2.828427e+00,2.222281e+00,1.530734e+00,7.803612e-01,-3.496911e-07,-7.803610e-01,-1.530734e+00,-2.222281e+00,-2.828427e+00,-3.325878e+00,-3.695518e+00,-3.923141e+00,-4.000000e+00,-3.923141e+00,-3.695518e+00,-3.325879e+00,-2.828428e+00,-2.222281e+00,-1.530734e+00,-7.803609e-01,0.000000e+00,7.803613e-01,1.530734e+00,2.222281e+00,2.828427e+00,3.325878e+00,3.695518e+00,3.923141e+00,4.000000e+00,3.923141e+00,3.695518e+00,3.325879e+00,2.828427e+00,2.222281e+00,1.530734e+00,Line truncated
|
||||
end package sine_data;
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
library work;
|
||||
use work.test_utility.all;
|
||||
|
||||
package sine_cosine_data is
|
||||
constant expected : real_array( 0 to 1023 ) := (2.000000e+00,2.779374e+00,3.526787e+00,4.213405e+00,4.812656e+00,5.301255e+00,5.660092e+00,5.874974e+00,5.937166e+00,5.843728e+00,5.597631e+00,5.207640e+00,4.687980e+00,4.057790e+00,3.340388e+00,2.562374e+00,1.752613e+00,9.411229e-01,1.579220e-01,-5.681200e-01,-1.210393e+00,-1.745568e+00,-2.154491e+00,-2.422919e+00,-2.542063e+00,-2.508927e+00,-2.326424e+00,-2.003255e+00,-1.553580e+00,-9.964672e-01,-3.551633e-01,3.438057e-01,1.071653e+00,1.798444e+00,2.494241e+00,3.130262e+00,3.679986e+00,4.120174e+00,4.431767e+00,4.600617e+00,4.618034e+00,4.481123e+00,4.192898e+00,3.762165e+00,3.203190e+00,2.535150e+00,1.781400e+00,9.685777e-01,1.255806e-01,-7.175396e-01,-1.530734e+00,-2.285103e+00,-2.954008e+00,-3.514094e+00,-3.946185e+00,-4.236010e+00,-4.374763e+00,-4.359427e+00,-4.192897e+00,-3.883861e+00,-3.446462e+00,-2.899757e+00,-2.266983e+00,-1.574657e+00,-8.515586e-01,-1.276198e-01,5.672264e-01,1.204198e+00,1.756773e+00,2.201711e+00,2.519947e+00,2.697327e+00,2.725152e+00,2.600517e+00,2.326424e+00,1.911665e+00,1.370490e+00,7.220587e-01,-1.029217e-02,-7.999491e-01,-1.618035e+00,-2.434522e+00,-3.219390e+00,-3.943765e+00,-4.581040e+00,-5.107891e+00,-5.505172e+00,-5.758650e+00,-5.859553e+00,-5.804903e+00,-5.597631e+00,-5.246466e+00,-4.765594e+00,-4.174115e+00,-3.495308e+00,-2.755738e+00,-1.984229e+00,-1.210763e+00,-4.653196e-01,2.232679e-01,8.284271e-01,1.326865e+00,1.699465e+00,1.932017e+00,2.015770e+00,1.947764e+00,1.730944e+00,1.374045e+00,8.912609e-01,3.016934e-01,-3.713790e-01,-1.101400e+00,-1.859553e+00,-2.615870e+00,-3.340388e+00,-4.004294e+00,-4.581040e+00,-5.047362e+00,-5.384174e+00,-5.577302e+00,-5.618033e+00,-5.503450e+00,-5.236544e+00,-4.826100e+00,-4.286365e+00,-3.636495e+00,-2.899828e+00,-2.102985e+00,-1.274848e+00,-4.454529e-01,3.551632e-01,1.098114e+00,1.756774e+00,2.307796e+00,2.732011e+00,3.015160e+00,3.148441e+00,3.128845e+00,2.959269e+00,2.648403e+00,2.210393e+00,1.664299e+00,1.033354e+00,3.440749e-01,-3.747628e-01,-1.093230e+00,-1.781400e+00,-2.410498e+00,-2.954008e+00,-3.388699e+00,-3.695518e+00,-3.860319e+00,-3.874418e+00,-3.734925e+00,-3.444852e+00,-3.013011e+00,-2.453665e+00,-1.785994e+00,-1.033353e+00,-2.223782e-01,6.180345e-01,1.457838e+00,2.266983e+00,3.016577e+00,3.679986e+00,4.233859e+00,4.659025e+00,4.941224e+00,5.071653e+00,5.047308e+00,4.871089e+00,4.551693e+00,4.103275e+00,3.544904e+00,2.899828e+00,2.194575e+00,1.457937e+00,7.198612e-01,1.029289e-02,-6.419711e-01,-1.210393e+00,-1.671717e+00,-2.006862e+00,-2.201657e+00,-2.247386e+00,-2.141128e+00,-1.885864e+00,-1.490369e+00,-9.688745e-01,-3.405195e-01,3.713791e-01,1.140226e+00,1.937166e+00,2.732195e+00,3.495308e+00,4.197658e+00,4.812656e+00,5.317002e+00,5.691571e+00,5.922154e+00,6.000000e+00,5.922154e+00,5.691572e+00,5.317002e+00,4.812656e+00,4.197658e+00,3.495308e+00,2.732195e+00,1.937166e+00,1.140226e+00,3.713793e-01,-3.405197e-01,-9.688740e-01,-1.490369e+00,-1.885864e+00,-2.141128e+00,-2.247387e+00,-2.201657e+00,-2.006862e+00,-1.671718e+00,-1.210394e+00,-6.419711e-01,1.029277e-02,7.198613e-01,1.457937e+00,2.194575e+00,2.899828e+00,3.544905e+00,4.103275e+00,4.551692e+00,4.871089e+00,5.047307e+00,5.071653e+00,4.941224e+00,4.659025e+00,4.233860e+00,3.679986e+00,3.016576e+00,2.266983e+00,1.457837e+00,6.180337e-01,-2.223787e-01,-1.033354e+00,-1.785995e+00,-2.453664e+00,-3.013009e+00,-3.444852e+00,-3.734925e+00,-3.874419e+00,-3.860320e+00,-3.695518e+00,-3.388700e+00,-2.954008e+00,-2.410498e+00,-1.781400e+00,-1.093230e+00,-3.747630e-01,3.440749e-01,1.033354e+00,1.664299e+00,2.210393e+00,2.648403e+00,2.959269e+00,3.128845e+00,3.148441e+00,3.015160e+00,2.732011e+00,2.307796e+00,1.756773e+00,1.098114e+00,3.551632e-01,-4.454526e-01,-1.274849e+00,-2.102985e+00,-2.899828e+00,-3.636495e+00,-4.286364e+00,-4.826100e+00,-5.236544e+00,-5.503451e+00,-5.618034e+00,-5.577302e+00,-5.384174e+00,-5.047363e+00,-4.581041e+00,-4.004294e+00,-3.340388e+00,-2.615870e+00,-1.859553e+00,-1.101400e+00,-3.713791e-01,3.016937e-01,8.912607e-01,1.374045e+00,1.730944e+00,1.947764e+00,2.015770e+00,1.932017e+00,1.699465e+00,1.326866e+00,8.284271e-01,2.232677e-01,-4.653195e-01,-1.210763e+00,-1.984230e+00,-2.755738e+00,-3.495308e+00,-4.174115e+00,-4.765593e+00,-5.246465e+00,-5.597631e+00,-5.804903e+00,-5.859553e+00,-5.758650e+00,-5.505172e+00,-5.107892e+00,-4.581041e+00,-3.943766e+00,-3.219390e+00,-2.434522e+00,-1.618034e+00,-7.999483e-01,-1.029229e-02,7.220592e-01,1.370490e+00,1.911665e+00,2.326424e+00,2.600517e+00,2.725152e+00,2.697327e+00,2.519948e+00,2.201712e+00,1.756774e+00,1.204198e+00,5.672265e-01,-1.276198e-01,-8.515589e-01,-1.574657e+00,-2.266983e+00,-2.899757e+00,-3.446461e+00,-3.883860e+00,-4.192898e+00,-4.359427e+00,-4.374763e+00,-4.236010e+00,-3.946184e+00,-3.514095e+00,-2.954008e+00,-2.285102e+00,-1.530733e+00,-7.175391e-01,1.255814e-01,9.685774e-01,1.781400e+00,2.535149e+00,3.203189e+00,3.762165e+00,4.192898e+00,4.481124e+00,4.618034e+00,4.600617e+00,4.431767e+00,4.120174e+00,3.679986e+00,3.130261e+00,2.49424Line truncated
|
||||
end package sine_cosine_data;
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,115 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.float_pkg.all;
|
||||
|
||||
library work;
|
||||
use work.test_utility.all;
|
||||
use work.sine_data.all;
|
||||
use work.cosine_data.all;
|
||||
use work.sine_cosine_data.all;
|
||||
|
||||
library std;
|
||||
use std.env.all;
|
||||
use std.textio.all;
|
||||
|
||||
entity tb_fsm_add is
|
||||
generic( CHECK_RESULTS : boolean; GUI_MODE : boolean := true );
|
||||
end;
|
||||
|
||||
architecture test of tb_fsm_add is
|
||||
signal clk : std_logic := '0';
|
||||
signal reset : std_logic := '1';
|
||||
signal run_calc : std_logic;
|
||||
signal calc_cnt : std_logic_vector( 3 downto 0 );
|
||||
|
||||
signal signal_a_read : std_logic;
|
||||
signal signal_a_readdata : std_logic_vector( 31 downto 0 );
|
||||
|
||||
signal signal_b_read : std_logic;
|
||||
signal signal_b_readdata : std_logic_vector( 31 downto 0 );
|
||||
|
||||
signal signal_write : std_logic;
|
||||
signal signal_writedata : std_logic_vector( 31 downto 0 );
|
||||
|
||||
begin
|
||||
|
||||
u_fsm_add : entity work.fsm_add
|
||||
port map (
|
||||
clk => clk,
|
||||
reset => reset,
|
||||
run_calc => run_calc,
|
||||
calc_cnt => calc_cnt,
|
||||
|
||||
signal_a_read => signal_a_read,
|
||||
signal_a_readdata => signal_a_readdata,
|
||||
|
||||
signal_b_read => signal_b_read,
|
||||
signal_b_readdata => signal_b_readdata,
|
||||
|
||||
signal_write => signal_write,
|
||||
signal_writedata => signal_writedata
|
||||
);
|
||||
|
||||
a_clk: clk <= not clk after 10 ns;
|
||||
|
||||
a_reset: process( clk )
|
||||
begin
|
||||
if falling_edge( clk ) then
|
||||
reset <= '0';
|
||||
end if;
|
||||
end process;
|
||||
|
||||
input_data_a_simulus: process is
|
||||
variable index : integer := 0;
|
||||
begin
|
||||
while true loop
|
||||
signal_a_readdata <= to_std_logic_vector( to_float( work.sine_data.expected( index ) ) );
|
||||
wait until rising_edge( signal_a_read );
|
||||
if ( index < 1023 ) then
|
||||
index := index + 1;
|
||||
end if;
|
||||
end loop;
|
||||
end process input_data_a_simulus;
|
||||
|
||||
input_data_b_simulus: process is
|
||||
variable index : integer := 0;
|
||||
begin
|
||||
while true loop
|
||||
signal_b_readdata <= to_std_logic_vector( to_float( work.cosine_data.expected( index ) ) );
|
||||
wait until rising_edge( signal_b_read );
|
||||
if ( index < 1023 ) then
|
||||
index := index + 1;
|
||||
end if;
|
||||
end loop;
|
||||
end process input_data_b_simulus;
|
||||
|
||||
stimulus: process is
|
||||
variable expected : real;
|
||||
variable float_value : float32;
|
||||
variable real_value : real;
|
||||
variable abs_err : real := 0.5e-1;
|
||||
begin
|
||||
std.textio.write( std.textio.OUTPUT, "--------------------------------------------------------------------------------" & LF );
|
||||
std.textio.write( std.textio.OUTPUT, "Starting tb_fsm_add" & LF );
|
||||
wait until falling_edge( reset );
|
||||
|
||||
wait until falling_edge( clk );
|
||||
run_calc <= '1';
|
||||
wait until falling_edge( clk );
|
||||
|
||||
for i in 0 to 16 loop
|
||||
wait until rising_edge( signal_write );
|
||||
expected := work.sine_cosine_data.expected( i + 1 );
|
||||
float_value := to_float( signal_writedata );
|
||||
real_value := to_real( float_value );
|
||||
assert_near( real_value, expected, abs_err );
|
||||
end loop;
|
||||
|
||||
if GUI_MODE = true then
|
||||
finish;
|
||||
else
|
||||
stop;
|
||||
end if;
|
||||
end process stimulus;
|
||||
|
||||
end architecture test;
|
||||
@@ -0,0 +1,3 @@
|
||||
$ version 1.1
|
||||
/tb_fsm_add/*
|
||||
/tb_fsm_add/u_fsm_add/*
|
||||
@@ -0,0 +1,71 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
use ieee.float_pkg.all;
|
||||
|
||||
library std;
|
||||
use std.textio.all;
|
||||
|
||||
package test_utility is
|
||||
constant TEST_FAIL : string := "[ FAIL ]";
|
||||
constant TEST_OK : string := "[ OK ]" & LF;
|
||||
|
||||
type real_array is array ( natural range <> ) of real;
|
||||
|
||||
procedure assert_eq( variable a : in std_logic_vector; variable b : in std_logic_vector );
|
||||
|
||||
procedure assert_near( variable a : in real;
|
||||
variable b : in real;
|
||||
variable abs_err : in real );
|
||||
|
||||
procedure assert_element_near( variable a : in real;
|
||||
variable b : in real;
|
||||
variable abs_err : in real;
|
||||
variable index : in integer );
|
||||
|
||||
end package test_utility;
|
||||
|
||||
package body test_utility is
|
||||
|
||||
procedure assert_eq( variable a : in std_logic_vector; variable b : in std_logic_vector ) is
|
||||
begin
|
||||
|
||||
assert( a = b )
|
||||
report TEST_FAIL & "assert_eq" & LF &
|
||||
" a: " & to_string( a ) & LF &
|
||||
" b: " & to_string( b ) & LF
|
||||
severity error;
|
||||
end procedure assert_eq;
|
||||
|
||||
procedure assert_near( variable a : in real;
|
||||
variable b : in real;
|
||||
variable abs_err : in real ) is
|
||||
variable abs_diff : real;
|
||||
begin
|
||||
abs_diff := abs( a - b );
|
||||
assert( abs_diff <= abs_err )
|
||||
report TEST_FAIL & "assert_near" & LF &
|
||||
" a: " & to_string( a ) & LF &
|
||||
" b: " & to_string( b ) & LF &
|
||||
" " & to_string( abs_diff ) & " > " & to_string( abs_err ) & LF
|
||||
severity error;
|
||||
end procedure assert_near;
|
||||
|
||||
procedure assert_element_near( variable a : in real;
|
||||
variable b : in real;
|
||||
variable abs_err : in real;
|
||||
variable index : in integer ) is
|
||||
variable abs_diff : real;
|
||||
begin
|
||||
abs_diff := abs( a - b );
|
||||
assert( abs_diff <= abs_err )
|
||||
report TEST_FAIL & "assert_element_near" & LF &
|
||||
" element: " & integer'image( index ) & LF &
|
||||
" a: " & to_string( a ) & LF &
|
||||
" b: " & to_string( b ) & LF &
|
||||
" " & to_string( abs_diff ) & " > " & to_string( abs_err ) & LF
|
||||
severity error;
|
||||
end procedure assert_element_near;
|
||||
|
||||
end package body test_utility;
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
onerror {resume}
|
||||
quietly WaveActivateNextPane {} 0
|
||||
add wave -noupdate /tb_top_entity_float_add/clk
|
||||
add wave -noupdate /tb_top_entity_float_add/reset
|
||||
add wave -noupdate /tb_top_entity_float_add/run_calc
|
||||
add wave -noupdate /tb_top_entity_float_add/operand_a
|
||||
add wave -noupdate /tb_top_entity_float_add/operand_b
|
||||
add wave -noupdate /tb_top_entity_float_add/result
|
||||
add wave -noupdate /tb_top_entity_float_add/calc_complete
|
||||
TreeUpdate [SetDefaultTree]
|
||||
WaveRestoreCursors {{Cursor 1} {0 ns} 0}
|
||||
quietly wave cursor active 1
|
||||
configure wave -namecolwidth 150
|
||||
configure wave -valuecolwidth 100
|
||||
configure wave -justifyvalue left
|
||||
configure wave -signalnamewidth 0
|
||||
configure wave -snapdistance 10
|
||||
configure wave -datasetprefix 0
|
||||
configure wave -rowmargin 4
|
||||
configure wave -childrowmargin 2
|
||||
configure wave -gridoffset 0
|
||||
configure wave -gridperiod 1
|
||||
configure wave -griddelta 40
|
||||
configure wave -timeline 0
|
||||
configure wave -timelineunits ns
|
||||
update
|
||||
WaveRestoreZoom {242 ns} {377 ns}
|
||||
Reference in new issue
Block a user