Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6a3c593444 | ||
|
|
4e8daa20bd | ||
|
|
691160d653 | ||
|
|
d70fb11d78 | ||
|
|
0fff028d26 |
@@ -0,0 +1,6 @@
|
|||||||
|
*/vish_stacktrace.vstf
|
||||||
|
*/.libwork
|
||||||
|
*/modelsim.ini
|
||||||
|
*/transcript
|
||||||
|
*/vsim.wlf
|
||||||
|
*/work/
|
||||||
@@ -14,17 +14,17 @@ end DataTypesExample;
|
|||||||
architecture Behavioral of DataTypesExample is
|
architecture Behavioral of DataTypesExample is
|
||||||
-- constant/signal Deklarationen
|
-- constant/signal Deklarationen
|
||||||
|
|
||||||
--Legen Sie ein Konstante DataWidth als integer mit Wert 8 an
|
--Legen Sie ein Konstante eight als integer mit Wert 8 an
|
||||||
|
|
||||||
--Legen Sie ein Konstante on als std_logic mit 1 an
|
--Legen Sie ein Konstante one als std_logic mit 1 an
|
||||||
|
|
||||||
--Legen Sie ein Konstante mask als std_logic_vector mit 5Ah an
|
--Legen Sie ein Konstante mask als std_logic_vector mit 5Ah an
|
||||||
|
|
||||||
--Legen Sie ein signal internal_int als integer mit Wertebreich -128 to 127 an
|
--Legen Sie ein signal internal_int als integer mit Wertebreich -128 to 127 an, initsialiseren Sie es mit 0
|
||||||
|
|
||||||
--Legen Sie ein signal internal_int als integer mit Wertebreich -128 to 127 an
|
--Legen Sie ein signal internal_int2 als integer mit Wertebreich -128 to 127 an, initsialiseren Sie es mit 0
|
||||||
|
|
||||||
--Legen Sie ein signal internal_slv als std_logic_vector mit Laenge 8 an
|
--Legen Sie ein signal internal_slv als std_logic_vector mit Laenge 8 an, initsialiseren Sie es mit 0
|
||||||
|
|
||||||
--Legen Sie ein signal internal_s als signed mit Laenge 8 an
|
--Legen Sie ein signal internal_s als signed mit Laenge 8 an
|
||||||
|
|
||||||
@@ -33,7 +33,7 @@ begin
|
|||||||
|
|
||||||
-- Maskieren (UND) Sie den Eingang input_slv mit der Maske mask und weisen Sie den Wert dem Ausgang output_slv_mask zu
|
-- Maskieren (UND) Sie den Eingang input_slv mit der Maske mask und weisen Sie den Wert dem Ausgang output_slv_mask zu
|
||||||
|
|
||||||
-- Der Wert des Ausgangs output_slv_set soll dem Eingang input_slv entsprechen wobei immer das 5 Bit (von 8 Bit) per Bitverkettung gesetzt sein soll
|
-- Der Wert des Ausgangs output_slv_set soll dem Eingang input_slv entsprechen wobei immer das 5 Bit (6 Stelle von 8 Bit) per Bitverkettung gesetzt sein soll
|
||||||
-- Koonstante one kann verwendet werden
|
-- Koonstante one kann verwendet werden
|
||||||
|
|
||||||
-- Weisen Sie dem signal internal_slv dein Eingang input_slv zu
|
-- Weisen Sie dem signal internal_slv dein Eingang input_slv zu
|
||||||
@@ -42,8 +42,10 @@ begin
|
|||||||
|
|
||||||
-- Rechnen Sie die Subtraktion internal_int - der Konstante eight und weisen Sie das Ergebnis internal_int2 zu
|
-- Rechnen Sie die Subtraktion internal_int - der Konstante eight und weisen Sie das Ergebnis internal_int2 zu
|
||||||
|
|
||||||
-- Weisen Sie dem signal das Signal internal_int2 zu (Datentypen beachten Konvetierung noetig)
|
-- Weisen Sie dem Signal internal_s das Signal internal_int2 zu (Datentypen beachten Konvetierung noetig)
|
||||||
|
|
||||||
-- Weisen Sie dem Ausgang output_slv_calc das signal internal_s zu (Datentypen beachten Konvetierung noetig)
|
-- Weisen Sie dem Ausgang output_slv_calc das signal internal_s zu (Datentypen beachten Konvetierung noetig)
|
||||||
|
|
||||||
|
|
||||||
end Behavioral;
|
end Behavioral;
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
|
|
||||||
vhdl_srcs = DataTypesExample.vhd \
|
vhdl_srcs = DataTypesExample.vhd \
|
||||||
test_DataTypesExample.vhd \
|
../scripts/test_utility.vhd \
|
||||||
|
test_DataTypesExample.vhd \
|
||||||
|
|
||||||
main = test_DataTypesExample
|
main = test_DataTypesExample
|
||||||
|
|
||||||
|
|||||||
@@ -4,8 +4,11 @@ library ieee;
|
|||||||
library std;
|
library std;
|
||||||
use std.env.all;
|
use std.env.all;
|
||||||
|
|
||||||
|
library work;
|
||||||
|
use work.test_utility.all;
|
||||||
|
|
||||||
entity test_DataTypesExample is
|
entity test_DataTypesExample is
|
||||||
generic( CHECK_RESULTS : boolean );
|
generic( GUI_MODE : boolean; CHECK_RESULTS : boolean );
|
||||||
end entity test_DataTypesExample;
|
end entity test_DataTypesExample;
|
||||||
|
|
||||||
architecture test of test_DataTypesExample is
|
architecture test of test_DataTypesExample is
|
||||||
@@ -27,7 +30,15 @@ begin
|
|||||||
delay : process
|
delay : process
|
||||||
begin
|
begin
|
||||||
wait for 100 ns;
|
wait for 100 ns;
|
||||||
stop;
|
assert_eq( output_slv_calc, x"52" );
|
||||||
|
assert_eq( output_slv_mask, x"5a" );
|
||||||
|
assert_eq( output_slv_set, x"7a" );
|
||||||
|
|
||||||
|
if ( GUI_MODE ) then
|
||||||
|
std.env.stop;
|
||||||
|
else
|
||||||
|
std.env.finish;
|
||||||
|
end if;
|
||||||
end process delay;
|
end process delay;
|
||||||
|
|
||||||
end architecture test;
|
end architecture test;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
|
|
||||||
vhdl_srcs = down_counter_int.vhd \
|
vhdl_srcs = down_counter_int.vhd \
|
||||||
|
../scripts/test_utility.vhd \
|
||||||
top_entity.vhd \
|
top_entity.vhd \
|
||||||
test_top_entity.vhd \
|
test_top_entity.vhd \
|
||||||
|
|
||||||
|
|||||||
@@ -4,8 +4,11 @@ library ieee;
|
|||||||
library std;
|
library std;
|
||||||
use std.env.all;
|
use std.env.all;
|
||||||
|
|
||||||
|
library work;
|
||||||
|
use work.test_utility.all;
|
||||||
|
|
||||||
entity test_top_entity is
|
entity test_top_entity is
|
||||||
generic( CHECK_RESULTS : boolean );
|
generic( GUI_MODE : boolean; CHECK_RESULTS : boolean );
|
||||||
end entity test_top_entity;
|
end entity test_top_entity;
|
||||||
|
|
||||||
architecture test of test_top_entity is
|
architecture test of test_top_entity is
|
||||||
@@ -31,12 +34,19 @@ begin
|
|||||||
|
|
||||||
p_run : process
|
p_run : process
|
||||||
begin
|
begin
|
||||||
wait until falling_edge( RESET );
|
wait until falling_edge( RESET );
|
||||||
for i in 0 to 128 loop
|
for i in 0 to 128 loop
|
||||||
wait until rising_edge( CLK );
|
wait until rising_edge( CLK );
|
||||||
end loop;
|
end loop;
|
||||||
wait until rising_edge( CLK );
|
wait until rising_edge( CLK );
|
||||||
stop;
|
|
||||||
|
assert_eq( CNT, "0111000" );
|
||||||
|
|
||||||
|
if ( GUI_MODE ) then
|
||||||
|
std.env.stop;
|
||||||
|
else
|
||||||
|
std.env.finish;
|
||||||
|
end if;
|
||||||
end process p_run;
|
end process p_run;
|
||||||
|
|
||||||
end architecture test;
|
end architecture test;
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
|
||||||
|
vhdl_srcs = ../scripts/test_utility.vhd \
|
||||||
|
alu.vhd \
|
||||||
|
test_alu.vhd \
|
||||||
|
|
||||||
|
main = test_alu
|
||||||
|
|
||||||
|
CHECK_RESULTS = true
|
||||||
|
|
||||||
|
include ../scripts/vhdl.mk
|
||||||
|
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
-- Importiere die notwendigen Bibliotheken
|
||||||
|
library IEEE;
|
||||||
|
use IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
use IEEE.NUMERIC_STD.ALL;
|
||||||
|
|
||||||
|
-- Definiere eine ALU-Entity mit zwei Operanden, einem Opcode und einem Ergebnisausgang
|
||||||
|
entity SimpleALU is
|
||||||
|
Port (
|
||||||
|
clk : in STD_LOGIC; -- Takt
|
||||||
|
reset : in STD_LOGIC; -- Reset
|
||||||
|
operand_a : in STD_LOGIC_VECTOR(3 downto 0); -- Erster Operand
|
||||||
|
operand_b : in STD_LOGIC_VECTOR(3 downto 0); -- Zweiter Operand
|
||||||
|
opcode : in STD_LOGIC_VECTOR(1 downto 0); -- Opcode, der die Operation bestimmt
|
||||||
|
result_out : out STD_LOGIC_VECTOR(3 downto 0); -- Ergebnis der Operation
|
||||||
|
flag_zero_out : out STD_LOGIC; -- Flag, das anzeigt, ob das Ergebnis null ist
|
||||||
|
flag_or_out : out STD_LOGIC -- Flag, das anzeigt, ob eine Oder Operation bei den Operanden stattgefunden hat
|
||||||
|
);
|
||||||
|
end SimpleALU;
|
||||||
|
|
||||||
|
-- Architekturdefinition der ALU
|
||||||
|
architecture Behavioral of SimpleALU is
|
||||||
|
|
||||||
|
-- Legen Sie das Signal STD_LOGIC_VECTOR reg_a an, in diesem soll spaeter der Eingang operand_a gespeichert werden
|
||||||
|
|
||||||
|
-- Legen Sie das Signal STD_LOGIC_VECTOR reg_b an, in diesem soll spaeter der Eingang operand_b gespeichert werden
|
||||||
|
|
||||||
|
-- Legen Sie das Signal STD_LOGIC_VECTOR reg_opcode an, in diesem soll spaeter der Eingang opcode gespeichert werden
|
||||||
|
|
||||||
|
-- Legen Sie ein Signal flag_zero als STD_LOGIC an
|
||||||
|
|
||||||
|
-- Legen Sie ein Signal result als STD_LOGIC_VECTOR der Laenge 4 an
|
||||||
|
|
||||||
|
-- Legen Sie ein Signal reg_flag_zero als STD_LOGIC
|
||||||
|
|
||||||
|
-- Legen Sie ein Signal reg_result als STD_LOGIC_VECTOR der Laenge von result an
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
-- Prozess fuer die Eingangsregister reg_a, reg_b, reg_c
|
||||||
|
-- Bei einem Reset sollen die Register den Wert 0 haben
|
||||||
|
-- Ansonsten soll bei einer steigenden Flanke von clk der entsprechnde Eingang (entity) gespeichert werden
|
||||||
|
input_register : process(reset,clk)
|
||||||
|
begin
|
||||||
|
|
||||||
|
end process input_register;
|
||||||
|
|
||||||
|
|
||||||
|
-- Prozess, der die ALU-Operationen durchfuehrt
|
||||||
|
alu_process: process(all)
|
||||||
|
begin
|
||||||
|
-- Anweisung fuer die Initialisierung fuer flag_zero mit dem Wert 0
|
||||||
|
|
||||||
|
-- Entscheide basierend auf dem Opcode, welche Operation durchgefuehrt wird
|
||||||
|
-- Wenn reg_opcode:
|
||||||
|
-- 00 -> result = reg_a + reg_b
|
||||||
|
-- 01 -> result = reg_a - reg_b
|
||||||
|
-- 10 -> result = reg_a and reg_b
|
||||||
|
-- 11 -> result = reg_a or reg_b
|
||||||
|
-- Fuer diese Realisierung soll die case-Anweisung verwendet werden
|
||||||
|
-- Anm. Bei Berechnungen Datentypen beachten (std_logic_vector kann nicht direkt verwendet werden sondern es muss erst gecastet werden - signed verwenden)
|
||||||
|
|
||||||
|
|
||||||
|
-- ueberpruefe, ob das Ergebnis result null ist, und setze das flag_zero entsprechend (result = 0 dann 1 ansonsten 0)
|
||||||
|
-- Fuer diese Realisierung soll die if-Anweisung verwendet werden
|
||||||
|
|
||||||
|
|
||||||
|
end process alu_process;
|
||||||
|
|
||||||
|
-- Prozess fuer die Ausgangssregister reg_result, reg_flag_zero
|
||||||
|
-- Bei einem Reset sollen die Register den Wert 0 haben
|
||||||
|
-- Ansonsten soll bei einer steigenden Flanke von clk das entsprechnde Signal aus dem alu_process zugewiesen werden
|
||||||
|
|
||||||
|
|
||||||
|
-- Anweisung um das Signal reg_result dem Ausgang result_out zu zuweisen
|
||||||
|
|
||||||
|
|
||||||
|
-- Anweisung um das Signal reg_flag_zero dem Ausgang flag_zero_out zu zuweisen
|
||||||
|
|
||||||
|
|
||||||
|
-- Bedingte Signalzuweisung fuer 'flag_or_out' außerhalb des Prozesses
|
||||||
|
-- Es soll anhand des Entity Eingang opcode mit einer With .. Select Anweisung der Ausgang flag_or_out gesetzt werden
|
||||||
|
-- opcode von or Operation dann 1 ansonsten 0
|
||||||
|
|
||||||
|
|
||||||
|
end Behavioral;
|
||||||
@@ -0,0 +1,105 @@
|
|||||||
|
library ieee;
|
||||||
|
use ieee.std_logic_1164.all;
|
||||||
|
|
||||||
|
library std;
|
||||||
|
use std.env.all;
|
||||||
|
use std.textio.all;
|
||||||
|
|
||||||
|
library work;
|
||||||
|
use work.test_utility.all;
|
||||||
|
|
||||||
|
entity test_alu is
|
||||||
|
generic( GUI_MODE : boolean; CHECK_RESULTS : boolean );
|
||||||
|
end entity test_alu;
|
||||||
|
|
||||||
|
architecture test of test_alu is
|
||||||
|
signal clk : std_logic := '0';
|
||||||
|
signal reset : std_logic := '1';
|
||||||
|
signal operand_a : std_logic_vector(3 downto 0);
|
||||||
|
signal operand_b : std_logic_vector(3 downto 0);
|
||||||
|
signal opcode : std_logic_vector(1 downto 0);
|
||||||
|
signal result_out : std_logic_vector(3 downto 0);
|
||||||
|
signal flag_zero_out : std_logic;
|
||||||
|
signal flag_or_out : std_logic;
|
||||||
|
begin
|
||||||
|
u_alu : entity work.SimpleALU
|
||||||
|
port map (
|
||||||
|
clk => clk,
|
||||||
|
reset => reset,
|
||||||
|
operand_a => operand_a,
|
||||||
|
operand_b => operand_b,
|
||||||
|
opcode => opcode,
|
||||||
|
result_out => result_out,
|
||||||
|
flag_zero_out => flag_zero_out,
|
||||||
|
flag_or_out => flag_or_out
|
||||||
|
);
|
||||||
|
|
||||||
|
clk <= not clk after 10 ns;
|
||||||
|
|
||||||
|
p_reset : process( clk )
|
||||||
|
begin
|
||||||
|
if falling_edge( clk ) then
|
||||||
|
reset <= '0';
|
||||||
|
end if;
|
||||||
|
end process p_reset;
|
||||||
|
|
||||||
|
p_run : process
|
||||||
|
begin
|
||||||
|
wait until falling_edge( reset );
|
||||||
|
-- Addition
|
||||||
|
write( output, "Test Addition ... " );
|
||||||
|
opcode <= "00";
|
||||||
|
operand_a <= x"a";
|
||||||
|
operand_b <= x"5";
|
||||||
|
wait until falling_edge( clk );
|
||||||
|
wait until falling_edge( clk );
|
||||||
|
assert_eq( result_out, x"f" );
|
||||||
|
assert_eq( flag_zero_out, '0' );
|
||||||
|
assert_eq( flag_or_out, '0' );
|
||||||
|
write( output, "done" & LF );
|
||||||
|
|
||||||
|
-- Subtraktion auf Null
|
||||||
|
write( output, "Test Subtraktion ... " );
|
||||||
|
opcode <= "01";
|
||||||
|
operand_a <= x"a";
|
||||||
|
operand_b <= x"a";
|
||||||
|
wait until falling_edge( clk );
|
||||||
|
wait until falling_edge( clk );
|
||||||
|
assert_eq( result_out, x"0" );
|
||||||
|
assert_eq( flag_zero_out, '1' );
|
||||||
|
assert_eq( flag_or_out, '0' );
|
||||||
|
write( output, "done" & LF );
|
||||||
|
|
||||||
|
-- UND-Operation
|
||||||
|
write( output, "Test UND-Operation ... " );
|
||||||
|
opcode <= "10";
|
||||||
|
operand_a <= x"a";
|
||||||
|
operand_b <= x"3";
|
||||||
|
wait until falling_edge( clk );
|
||||||
|
wait until falling_edge( clk );
|
||||||
|
assert_eq( result_out, x"2" );
|
||||||
|
assert_eq( flag_zero_out, '0' );
|
||||||
|
assert_eq( flag_or_out, '0' );
|
||||||
|
write( output, "done" & LF );
|
||||||
|
|
||||||
|
-- ODER-Operation
|
||||||
|
write( output, "Test ODER-Operation ... " );
|
||||||
|
opcode <= "11";
|
||||||
|
operand_a <= x"a";
|
||||||
|
operand_b <= x"3";
|
||||||
|
wait until falling_edge( clk );
|
||||||
|
wait until falling_edge( clk );
|
||||||
|
assert_eq( result_out, x"b" );
|
||||||
|
assert_eq( flag_zero_out, '0' );
|
||||||
|
assert_eq( flag_or_out, '1' );
|
||||||
|
write( output, "done" & LF );
|
||||||
|
|
||||||
|
wait until falling_edge( clk );
|
||||||
|
if ( GUI_MODE ) then
|
||||||
|
std.env.stop;
|
||||||
|
else
|
||||||
|
std.env.finish;
|
||||||
|
end if;
|
||||||
|
end process p_run;
|
||||||
|
|
||||||
|
end architecture test;
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
$ version 1.1
|
||||||
|
/test_DataTypesExample/u_DataTypesExample/*
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
$ version 1.1
|
||||||
|
/test_DataTypesExample/u_DataTypesExample/*
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
onerror {resume}
|
||||||
|
quietly WaveActivateNextPane {} 0
|
||||||
|
add wave -noupdate /test_alu/u_alu/*
|
||||||
+5
-4
@@ -1,9 +1,10 @@
|
|||||||
|
|
||||||
vhdl_srcs = down_counter_int.vhd \
|
vhdl_srcs = ../scripts/test_utility.vhd \
|
||||||
top_entity.vhd \
|
squareRoot_pipe.vhd \
|
||||||
test_top_entity.vhd \
|
fft_magnitude_calc.vhd \
|
||||||
|
test_fsm.vhd \
|
||||||
|
|
||||||
main = test_top_entity
|
main = tb_fft_magnitude_calc
|
||||||
|
|
||||||
CHECK_RESULTS = true
|
CHECK_RESULTS = true
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
@@ -0,0 +1,153 @@
|
|||||||
|
------------------------------------------------------------------------
|
||||||
|
-- fft_magnitude_calc
|
||||||
|
--
|
||||||
|
-- calculation of FFT magnitude sqrt(real_part²+im_part²)
|
||||||
|
-- Inputs:
|
||||||
|
-- input_re in: +-1 signed Fixpoint (0.5=0x40000000, -0.5=0xC0000000 (negative numbers in 2K)
|
||||||
|
-- input_im in: +-1 signed Fixpoint (0.5=0x40000000, -0.5=0xC0000000 (negative numbers in 2K)
|
||||||
|
-- input_valid: high = inputs are valid for data processing
|
||||||
|
-- Outputs
|
||||||
|
-- output_magnitude: Fixpoint 0.5=0x40000000 (always positive)
|
||||||
|
-- output_valid: high = magnitude data is valid
|
||||||
|
-----------------------------------------------------------------------
|
||||||
|
|
||||||
|
library ieee;
|
||||||
|
use ieee.std_logic_1164.all;
|
||||||
|
use ieee.numeric_std.all;
|
||||||
|
|
||||||
|
entity fft_magnitude_calc is
|
||||||
|
port (
|
||||||
|
clk : in std_logic; -- Takt
|
||||||
|
reset : in std_logic; -- Reset
|
||||||
|
input_valid: in std_logic; -- Eingangsdaten gueltig
|
||||||
|
input_re : in std_logic_vector( 31 downto 0 ); -- Realteil in Fixpoint
|
||||||
|
input_im : in std_logic_vector( 31 downto 0 ); -- Imaginaerteil in Fixpoint
|
||||||
|
output_valid : out std_logic; -- Ausgangsdaten gueltig
|
||||||
|
output_magnitude : out std_logic_vector( 31 downto 0 ) -- Berechnete magnitude
|
||||||
|
);
|
||||||
|
end entity fft_magnitude_calc;
|
||||||
|
|
||||||
|
architecture rtl of fft_magnitude_calc is
|
||||||
|
|
||||||
|
|
||||||
|
-- Zustaende fuer die Zustandsmaschine fuer die Berechnung
|
||||||
|
type CalcState is (
|
||||||
|
CALC_IDLE, -- Zustand Leerlauf
|
||||||
|
CALC_MULTIPLY, -- Zustand Berechnung real_part² und im_part²
|
||||||
|
CALC_ADD, -- Zustand Berecnung Addition real_part²+im_part²
|
||||||
|
CALC_SQRT, -- Zustand Berechnung der sqrt(real_part²+im_part²)
|
||||||
|
CALC_STORE_RESULT -- Zustand Setzen von output_valid und output_magnitude
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Legen Sie die Signale current_calc_state und next_calc_state fuer die Zustandsmaschine CalcState an
|
||||||
|
|
||||||
|
-- Legen Sie die Signale re_multiply_re und im_multiply_im als signed (63 downto 0) an
|
||||||
|
|
||||||
|
-- Legen Sie die Signal re2_add_im2 als signed (63 downto 0) an
|
||||||
|
|
||||||
|
-- Legen Sie die Signal output_sqrt als std_logic_vector (31 downto 0) an
|
||||||
|
|
||||||
|
-- Legen Sie die Signal output_sqrt als std_logic_vector (15 downto 0) an
|
||||||
|
|
||||||
|
-- Legen Sie das Signal start_sqrt_calc als std_logic an
|
||||||
|
|
||||||
|
-- Legen Sie das Signal sqrt_out_valid_flag als std_logic an
|
||||||
|
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
-- uebergangsschaltnetz der Zustandsmaschine fuer die Berechnung (Strukturvariante 2 Process Zustandsmaschine)
|
||||||
|
-- Beschreiben Sie den Prozess fuer das uebergangsschaltnetz (Case-Anweisung)
|
||||||
|
-- CALC_IDLE -> CALC_MULTIPLY wenn input_valid = 1
|
||||||
|
-- CALC_MULTIPLY -> CALC_ADD
|
||||||
|
-- CALC_ADD -> CALC_SQRT
|
||||||
|
-- CALC_SQRT -> CALC_STORE_RESULT wenn sqrt_out_valid_flag = 1
|
||||||
|
-- CALC_STORE_RESULT -> CALC_IDLE
|
||||||
|
calc_state_transitions : process ( all ) is
|
||||||
|
begin
|
||||||
|
|
||||||
|
end process calc_state_transitions;
|
||||||
|
|
||||||
|
-- Zustandsspeicher und Ausgangsschaltnetz zu der Steuerung der Berechnung (Strukturvariante 2 Process Zustandsmaschine)
|
||||||
|
sync : process ( clk, reset ) is
|
||||||
|
begin
|
||||||
|
-- Der Prozess steuert folgende Signale setzen Sie fuer alle passende Resetwerte
|
||||||
|
-- current_calc_state
|
||||||
|
-- re_multiply_re
|
||||||
|
-- im_multiply_im
|
||||||
|
-- re2_add_im2
|
||||||
|
-- input_sqrt
|
||||||
|
-- start_sqrt_calc
|
||||||
|
-- output_valid
|
||||||
|
-- output_magnitude
|
||||||
|
if ( reset = '1' ) then
|
||||||
|
|
||||||
|
elsif ( rising_edge( clk ) ) then
|
||||||
|
|
||||||
|
-- Machen Sie Anweisungen um start_sqrt_calc und output_valid auf 0 zu setzen
|
||||||
|
|
||||||
|
-- Realisieren Sie den Zustandsspeicher current_calc_state
|
||||||
|
|
||||||
|
-- Vervollstaendigen Sie das Ausgangsschaltnetz
|
||||||
|
case next_calc_state is
|
||||||
|
when CALC_IDLE=> null;
|
||||||
|
|
||||||
|
-- calculation of real_part² and im_part²
|
||||||
|
-- Anweisung fuer die Berechnung von re_multiply_re = input_re² (Datentypen beachten)
|
||||||
|
-- Anweisung fuer die Berechnung von im_multiply_im = input_im² (Datentypen beachten)
|
||||||
|
when CALC_MULTIPLY =>
|
||||||
|
|
||||||
|
-- calculation of real_part²*+im_part²
|
||||||
|
-- Anweisung fuer die Berechnung von re2_add_im2 = re_multiply_re + im_multiply_im
|
||||||
|
when CALC_ADD =>
|
||||||
|
|
||||||
|
-- calculation of sqrt(real_part²+im_part²)
|
||||||
|
-- Anweisung um input_sqrt mit den obersten 32-Bit von re2_add_im2 zu belegen (Datentypen beachten)
|
||||||
|
-- Anweisung um start_sqrt_calc mit 1 zu setzen
|
||||||
|
when CALC_SQRT =>
|
||||||
|
|
||||||
|
-- Setzen der Entity-Ausgaenge
|
||||||
|
-- Anweisung um die obersten 16 bit von output_magnitude mit output_sqrt zu setzen und die untern 16 Bit mit 0
|
||||||
|
-- Anweisung um output_valid mit 1 zu setzen
|
||||||
|
when CALC_STORE_RESULT =>
|
||||||
|
|
||||||
|
when others => NUll;
|
||||||
|
end case;
|
||||||
|
end if;
|
||||||
|
end process sync;
|
||||||
|
|
||||||
|
|
||||||
|
-- Instanziierung des SQRT Moduls fuer die Berechnung der Quardratwurzel
|
||||||
|
-- Weisen Sie die Signale output_sqrt, reset, input_sqrt und clk richtig zu
|
||||||
|
sqrt_module : entity work.squareRoot_pipe
|
||||||
|
generic map (
|
||||||
|
G_DATA_W => 32
|
||||||
|
)
|
||||||
|
port map (
|
||||||
|
clk => ,
|
||||||
|
rst => ,
|
||||||
|
iv_data => ,
|
||||||
|
ov_res =>
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Dieser Prozess sorgt dafuer, dass 16 Takte nachdem start_sqrt_calc 1 geworden ist sqrt_out_valid_flag zu 1 wird
|
||||||
|
-- Wird benoetigt um die Berechnungsdauer des sqrt_module anzueigen
|
||||||
|
-- Hier muss nichts veraendert werden
|
||||||
|
p_sqrt_out_valid_flag: process ( clk, reset ) is
|
||||||
|
variable delay_sqrt_out_valid_flag : std_logic_vector(14 downto 0);
|
||||||
|
begin
|
||||||
|
if ( reset = '1' ) then
|
||||||
|
sqrt_out_valid_flag <= '0';
|
||||||
|
delay_sqrt_out_valid_flag := (others => '0');
|
||||||
|
elsif ( rising_edge( clk ) ) then
|
||||||
|
sqrt_out_valid_flag <= delay_sqrt_out_valid_flag(14);
|
||||||
|
delay_sqrt_out_valid_flag := delay_sqrt_out_valid_flag(13 downto 0) & start_sqrt_calc;
|
||||||
|
if sqrt_out_valid_flag = '1' then
|
||||||
|
delay_sqrt_out_valid_flag := (others => '0');
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process p_sqrt_out_valid_flag;
|
||||||
|
|
||||||
|
|
||||||
|
end architecture rtl;
|
||||||
|
|
||||||
@@ -0,0 +1,119 @@
|
|||||||
|
----------------------------------------------------------------------------------------------------
|
||||||
|
-- Component : squareRoot_pipe
|
||||||
|
-- Author : pwkolas
|
||||||
|
----------------------------------------------------------------------------------------------------
|
||||||
|
-- File : squareRoot_pipe.vhd
|
||||||
|
-- Mod. Date : XX.XX.XXXX
|
||||||
|
-- Version : 1.00
|
||||||
|
----------------------------------------------------------------------------------------------------
|
||||||
|
-- Description : Square root calculator.
|
||||||
|
-- Based on
|
||||||
|
-- "A New Non-Restoring Square Root Algorithm and Its VLSI Implementations"
|
||||||
|
--
|
||||||
|
----------------------------------------------------------------------------------------------------
|
||||||
|
-- Modification History :
|
||||||
|
--
|
||||||
|
----------------------------------------------------------------------------------------------------
|
||||||
|
-- Comments :
|
||||||
|
--
|
||||||
|
----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
library ieee;
|
||||||
|
|
||||||
|
use ieee.std_logic_1164.all;
|
||||||
|
use ieee.numeric_std.all;
|
||||||
|
|
||||||
|
entity squareRoot_pipe is
|
||||||
|
generic (
|
||||||
|
G_DATA_W : integer := 32
|
||||||
|
);
|
||||||
|
port (
|
||||||
|
clk : in std_logic;
|
||||||
|
rst : in std_logic;
|
||||||
|
iv_data : in std_logic_vector(G_DATA_W-1 downto 0);
|
||||||
|
ov_res : out std_logic_vector((G_DATA_W/2)-1 downto 0)
|
||||||
|
);
|
||||||
|
end entity squareRoot_pipe;
|
||||||
|
|
||||||
|
architecture squareRoot_pipe_rtl of squareRoot_pipe is
|
||||||
|
|
||||||
|
constant C_ALU_W : integer := ((G_DATA_W/2) + 2);
|
||||||
|
constant C_PIPE_L : integer := G_DATA_W/2;
|
||||||
|
constant C_OFFSET : integer := 3; -- width of start vectors going to ALU
|
||||||
|
|
||||||
|
type t_arr_pipe_x_data is array (C_PIPE_L-1 downto 0) of unsigned(G_DATA_W-1 downto 0);
|
||||||
|
signal a_data : t_arr_pipe_x_data; -- (D)
|
||||||
|
signal a_R : t_arr_pipe_x_data; -- (R)
|
||||||
|
|
||||||
|
type t_arr_pipe_x_alu is array (C_PIPE_L-1 downto 0) of unsigned(C_ALU_W-1 downto 0);
|
||||||
|
|
||||||
|
type t_arr_pipe_x_res is array (C_PIPE_L-1 downto 0) of unsigned(G_DATA_W/2-1 downto 0);
|
||||||
|
signal a_Q : t_arr_pipe_x_res; -- (ALU Q out)
|
||||||
|
|
||||||
|
signal nextOp : std_logic_vector(C_PIPE_L-1 downto 0);
|
||||||
|
|
||||||
|
begin
|
||||||
|
sqrt_p : process (clk, rst)
|
||||||
|
variable va_AluInR : t_arr_pipe_x_alu; -- (ALU R in)
|
||||||
|
variable va_AluInQ : t_arr_pipe_x_alu; -- (ALU Q in)
|
||||||
|
variable va_AluOut : t_arr_pipe_x_alu; -- (ALU Q out)
|
||||||
|
begin
|
||||||
|
if (rst = '1') then
|
||||||
|
a_data <= (others => (others => '0'));
|
||||||
|
a_R <= (others => (others => '0'));
|
||||||
|
a_Q <= (others => (others => '0'));
|
||||||
|
va_AluInR := (others => (others => '0'));
|
||||||
|
va_AluInQ := (others => (others => '0'));
|
||||||
|
va_AluOut := (others => (others => '0'));
|
||||||
|
nextOp <= (others => '0');
|
||||||
|
elsif rising_edge(clk) then
|
||||||
|
-- stage 0 start conditions, ALU inputs
|
||||||
|
va_AluInR(0) := (others => '0');
|
||||||
|
va_AluInR(0)(1 downto 0) := unsigned(iv_data(G_DATA_W-1 downto G_DATA_W-1-1));
|
||||||
|
va_AluInQ(0) := (others => '0');
|
||||||
|
va_AluInQ(0)(0) := '1';
|
||||||
|
|
||||||
|
-- stage 0 calculations
|
||||||
|
va_AluOut(0) := va_AluInR(0) - va_AluInQ(0);
|
||||||
|
|
||||||
|
-- stage 0 result registers, ALU output
|
||||||
|
a_data(0) <= shift_left(unsigned(iv_data), 2);
|
||||||
|
a_R(0) <= (others => '0');
|
||||||
|
a_R(0)(G_DATA_W-1 downto G_DATA_W-1-1) <= va_AluOut(0)(1 downto 0);
|
||||||
|
a_Q(0) <= (others => '0');
|
||||||
|
a_Q(0)(0) <= not va_AluOut(0)(2);
|
||||||
|
nextOp(0) <= not va_AluOut(0)(2);
|
||||||
|
|
||||||
|
-- next stages
|
||||||
|
for i in 1 to C_PIPE_L-1 loop
|
||||||
|
-- prepare inputs for next stage
|
||||||
|
va_AluInR(i) := (others => '0');
|
||||||
|
va_AluInR(i)(C_OFFSET+i-1 downto 2) := a_R(i-1)(G_DATA_W-(i-1)-1 downto G_DATA_W-(2*i));
|
||||||
|
va_AluInR(i)(2-1 downto 0) := a_data(i-1)(G_DATA_W-1 downto G_DATA_W-1-1);
|
||||||
|
va_AluInQ(i) := (others => '0');
|
||||||
|
va_AluInQ(i)(C_OFFSET+(i-1)-1 downto 2) := a_Q(i-1)(i-1 downto 0);
|
||||||
|
va_AluInQ(i)(1) := not a_Q(i-1)(0);
|
||||||
|
va_AluInQ(i)(0) := '1';
|
||||||
|
|
||||||
|
-- ALU ADD/SUB
|
||||||
|
if (nextOp(i-1) = '1') then
|
||||||
|
va_AluOut(i) := va_AluInR(i) - va_AluInQ(i);
|
||||||
|
else
|
||||||
|
va_AluOut(i) := va_AluInR(i) + va_AluInQ(i);
|
||||||
|
end if;
|
||||||
|
|
||||||
|
-- result registers
|
||||||
|
a_data(i) <= shift_left(unsigned(a_data(i-1)), 2);
|
||||||
|
a_R(i) <= (others => '0');
|
||||||
|
a_R(i)(G_DATA_W-i-1 downto G_DATA_W-2*(i+1)) <= va_AluOut(i)(i+1 downto 0);
|
||||||
|
a_Q(i) <= shift_left(unsigned(a_Q(i-1)), 1);
|
||||||
|
a_Q(i)(0) <= not va_AluOut(i)(i+2);
|
||||||
|
nextOp(i) <= not va_AluOut(i)(i+2);
|
||||||
|
|
||||||
|
end loop;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
ov_res <= std_logic_vector(a_Q(C_PIPE_L-1));
|
||||||
|
|
||||||
|
end architecture squareRoot_pipe_rtl;
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
------------------------------------------------------------------------
|
||||||
|
-- fft_magnitude_calc
|
||||||
|
--
|
||||||
|
-- calculation of FFT magnitude sqrt(real_part²+im_part²)
|
||||||
|
-- Inputs:
|
||||||
|
-- input_re in: +-1 signed Fixpoint (0.5=0x40000000, -0.5=0xC0000000 (negative numbers in 2K)
|
||||||
|
-- input_im in: +-1 signed Fixpoint (0.5=0x40000000, -0.5=0xC0000000 (negative numbers in 2K)
|
||||||
|
-- input_valid: high = inputs are valid for data processing
|
||||||
|
-- Outputs
|
||||||
|
-- output_magnitude: Fixpoint 0.5=0x40000000 (always positive)
|
||||||
|
-- output_valid: high = magnitude data is valid
|
||||||
|
-----------------------------------------------------------------------
|
||||||
|
|
||||||
|
library ieee;
|
||||||
|
use ieee.std_logic_1164.all;
|
||||||
|
use ieee.numeric_std.all;
|
||||||
|
|
||||||
|
entity tb_fft_magnitude_calc is
|
||||||
|
generic( GUI_MODE : boolean; CHECK_RESULTS : boolean );
|
||||||
|
end entity tb_fft_magnitude_calc;
|
||||||
|
|
||||||
|
|
||||||
|
architecture rtl of tb_fft_magnitude_calc is
|
||||||
|
|
||||||
|
|
||||||
|
signal clk : std_logic := '0'; -- Takt
|
||||||
|
signal reset : std_logic := '1'; -- Reset
|
||||||
|
signal input_valid: std_logic := '0'; -- Eingangsdaten gültig
|
||||||
|
signal input_re : std_logic_vector( 31 downto 0 ) := X"40000000"; -- Realteil in Fixpoint
|
||||||
|
signal input_im : std_logic_vector( 31 downto 0 ):= X"40000000"; -- Imaginärteil in Fixpoint
|
||||||
|
signal output_valid : std_logic; -- Ausgangsdaten gültig
|
||||||
|
signal output_magnitude : std_logic_vector( 31 downto 0 );
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
clk <= not clk after 10 ns;
|
||||||
|
|
||||||
|
reset_release : process is
|
||||||
|
begin
|
||||||
|
wait for 435 ns;
|
||||||
|
reset <= '0';
|
||||||
|
wait;
|
||||||
|
end process reset_release;
|
||||||
|
|
||||||
|
-- Instanziierung des SQRT Moduls für die Berechnung der Quardratwurzel
|
||||||
|
-- Weisen Sie die Signale output_sqrt, reset, input_sqrt und clk richtig zu
|
||||||
|
fft_magnitude_calc_module : entity work.fft_magnitude_calc
|
||||||
|
port map (
|
||||||
|
clk => clk,
|
||||||
|
reset => reset,
|
||||||
|
input_valid => input_valid, -- Eingangsdaten gültig
|
||||||
|
input_re => input_re, -- Realteil in Fixpoint
|
||||||
|
input_im => input_im, -- Imaginärteil in Fixpoint
|
||||||
|
output_valid => output_valid, -- Ausgangsdaten gültig
|
||||||
|
output_magnitude => output_magnitude -- Berechnete magnitude
|
||||||
|
);
|
||||||
|
|
||||||
|
stimulus: process is
|
||||||
|
begin
|
||||||
|
wait until falling_edge( reset );
|
||||||
|
wait until falling_edge( clk );
|
||||||
|
input_valid <= '1';
|
||||||
|
wait until falling_edge( clk );
|
||||||
|
input_valid <= '0';
|
||||||
|
|
||||||
|
wait until falling_edge( output_valid );
|
||||||
|
|
||||||
|
wait for 200 ns;
|
||||||
|
|
||||||
|
wait until falling_edge( clk );
|
||||||
|
input_valid <= '1';
|
||||||
|
input_re <= X"20000000";
|
||||||
|
input_im <= X"20000000";
|
||||||
|
wait until falling_edge( clk );
|
||||||
|
input_valid <= '0';
|
||||||
|
|
||||||
|
wait until falling_edge( output_valid );
|
||||||
|
|
||||||
|
|
||||||
|
wait until falling_edge( clk );
|
||||||
|
if ( GUI_MODE ) then
|
||||||
|
std.env.stop;
|
||||||
|
else
|
||||||
|
std.env.finish;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
end process stimulus;
|
||||||
|
|
||||||
|
end architecture rtl;
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
onerror {resume}
|
||||||
|
quietly WaveActivateNextPane {} 0
|
||||||
|
add wave -noupdate /tb_fft_magnitude_calc/fft_magnitude_calc_module/*
|
||||||
@@ -23,11 +23,13 @@ assert_level := error
|
|||||||
|
|
||||||
gui: ${verilog_objs} ${vhdl_objs}
|
gui: ${verilog_objs} ${vhdl_objs}
|
||||||
@vsim \
|
@vsim \
|
||||||
|
-gGUI_MODE=true \
|
||||||
-gCHECK_RESULTS=$(CHECK_RESULTS) \
|
-gCHECK_RESULTS=$(CHECK_RESULTS) \
|
||||||
-voptargs=+acc work.${main} -do "do vsim.wave; run -all"
|
-voptargs=+acc work.${main} -do "do vsim.wave; run -all"
|
||||||
|
|
||||||
sim: ${verilog_objs} ${vhdl_objs}
|
sim: ${verilog_objs} ${vhdl_objs}
|
||||||
@vsim \
|
@vsim \
|
||||||
|
-gGUI_MODE=false \
|
||||||
-gCHECK_RESULTS=$(CHECK_RESULTS) \
|
-gCHECK_RESULTS=$(CHECK_RESULTS) \
|
||||||
-voptargs=+acc -c work.${main} -do "run -all" \
|
-voptargs=+acc -c work.${main} -do "run -all" \
|
||||||
| ../scripts/highlight_test_results.sh
|
| ../scripts/highlight_test_results.sh
|
||||||
|
|||||||
@@ -0,0 +1,80 @@
|
|||||||
|
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( a : in std_logic; b : in std_logic );
|
||||||
|
procedure assert_eq( a : in std_logic_vector; 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( a : in std_logic; b : in std_logic ) 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_eq( a : in std_logic_vector; 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;
|
||||||
|
|
||||||
Reference in New Issue
Block a user