2023-10-31 07:47:27 +01:00
library ieee ;
use ieee.std_logic_1164. all ;
use ieee.numeric_std. all ;
library work ;
use work.reg32. all ;
use work.task. all ;
entity add is
port (
clk : in std_logic ;
reset : in std_logic ;
task_start : in std_logic ;
task_state : out work . task . State ;
2024-11-20 09:27:56 +01:00
signal_a_read : out std_logic ; --signal_read wird als Bestätigung gesetzt, dass die Daten gelesen wurden, d.h. bei der nächsten rising edge werden die nächsten Daten angelegt.
2023-10-31 07:47:27 +01:00
signal_a_readdata : in std_logic_vector ( 31 downto 0 ) ;
signal_b_read : out std_logic ;
signal_b_readdata : in std_logic_vector ( 31 downto 0 ) ;
signal_write : out std_logic ;
signal_writedata : out std_logic_vector ( 31 downto 0 )
) ;
end entity add ;
architecture rtl of add is
signal current_task_state : work . task . State ;
signal next_task_state : work . task . State ;
signal index : integer range 0 to work . task . STREAM_LEN ;
2024-11-13 11:19:20 +01:00
--hier noch einige Signale anlegen
signal done_flag : std_logic ;
signal start_flag : std_logic ;
--Zustände für die Zustandsmaschine für die Berechnung
type CalcState is (
CALC_IDLE ,
CALC_ADD ,
CALC_STORE_RESULT
) ;
--Signale für die Zustandsmaschine für die Berechnung
signal current_calc_state : CalcState ;
signal next_calc_state : CalcState ;
2024-11-20 09:27:56 +01:00
signal ergebnis : signed ( 31 downto 0 ) ; --das hier vielleicht zu std_logic_vector oder float
2024-11-13 11:19:20 +01:00
signal ergebnis_valid : std_logic ;
2023-10-31 07:47:27 +01:00
begin
2024-11-13 11:19:20 +01:00
2024-11-20 09:27:56 +01:00
u_float_add : entity work . float_add --Das hier ist der IP Core !!!
2024-11-13 11:19:20 +01:00
port map (
clk = > clk ,
reset = > reset ,
start = > start_flag ,
done = > done_flag ,
A = > signal_a_readdata ,
B = > signal_b_readdata ,
sum = > signal_writedata
) ;
--task_state_transitions wird nicht geaendert
--Übergangsschaltnetz der Zustandsmaschine zu Steuerung der Tasks
2023-10-31 07:47:27 +01:00
task_state_transitions : process ( current_task_state , task_start , index ) is
begin
next_task_state < = current_task_state ;
case current_task_state is
when work . task . TASK_IDLE = >
if ( task_start = '1' ) then
next_task_state < = work . task . TASK_RUNNING ;
end if ;
when work . task . TASK_RUNNING = >
if ( index = work . task . STREAM_LEN - 1 ) then
next_task_state < = work . task . TASK_DONE ;
end if ;
when work . task . TASK_DONE = >
if ( task_start = '1' ) then
next_task_state < = work . task . TASK_RUNNING ;
end if ;
end case ;
end process task_state_transitions ;
2024-11-20 09:27:56 +01:00
--Übergangsschaltnetz der Zustandsmaschine für die Berechnung ###Fertig
calc_state_transitions : process ( all ) is
begin
next_calc_state < = current_calc_state ;
case current_calc_state is
when CALC_IDLE = >
if ( current_task_state = work . task . TASK_RUNNING ) then
next_calc_state < = CALC_ADD ;
end if ;
when CALC_ADD = >
if ( done_flag = '1' ) then
next_calc_state < = CALC_STORE_RESULT ;
end if ;
when CALC STORE RESULT = >
next_calc_state < = CALC_IDLE ;
end case ;
end process calc state transitions ;
--Zustandsspeicher und Ausgangsschaltnetz zu der Steuerung der Tasks
task_sync : process ( clk , reset ) is
begin
if ( reset = '1' ) then
current_task_state < = work . task . TASK_IDLE ;
elsif ( rising_edge ( clk ) ) then
current_task_state < = next_task_state ;
case next_task_state is
when work . task . TASK IDLE = > null ;
when work . task . TASK_RUNNING = > null ;
when work . task . TASK_DONE = > null ;
end case ;
end if ;
end process task_sync ;
--Zustandsspeicher und Ausgangsschaltnetz zu Berechnung
sync : process ( clk , reset ) is
begin
if ( reset = '1' ) then
index < = 0 ;
current_calc_state < = CALC_IDLE ;
ergebnis < = ( others = > '0' ) ;
ergebnis_valid < = '0' ;
signal_write < = '0' ;
signal_writedata < = ( others = > '0' ) ;
elsif ( rising_edge ( clk ) ) then
current_calc_state < = next_calc_state ;
ergebnis_valid < = '0' ;
case next_calc_state is
when CALC_IDLE = >
start_flag < = '0' ;
signal_read < = '0' ; --Daten wurden noch nicht verwendet.
signal_write < = '0' ;
when CALC_ADD = > --hier Berechnung mit IP Core?
start_flag < = '1' ;
when CALC_STORE_RESULT = >
start_flag < = '0' ;
index < = index + 1 ;
signal_write < = '1' ;
--signal_writedata <= std_logic_vector( ergebnis ); --Ergebnis schreiben, ergebnis direkt aus IP Core anschliessen
signal_read < = '1' --mitteilen, dass die Daten gelesen wurden und jetzt neue Daten angelegt werden sollen
end case ;
end if ;
end process sync ;
task_state < = current_task_state ;
--signal_read anlegen. im nächsten Takt kann gelesen werden.
--Werte holen, addieren, wieder ablegen
--running gibt start-signal an add-StateMachine
--IP Core macht nur eine Rechnung
--wenn done signal kommt -> summe lesen
--
2024-11-13 11:19:20 +01:00
-- Zustandsspeicher und Ausgangsschaltnetz zu Berechnung
2023-10-31 07:47:27 +01:00
sync : process ( clk , reset ) is
begin
2024-11-13 11:19:20 +01:00
-- Ablaufsteuerung ueberlegen
2023-10-31 07:47:27 +01:00
if ( reset = '1' ) then
current_task_state < = work . task . TASK_IDLE ;
index < = 0 ;
2024-11-13 11:19:20 +01:00
--hier alle Signale zuruecksetzen/initialisieren
start_flag < = '0' ;
done_flag < = '0' ;
2023-10-31 07:47:27 +01:00
elsif ( rising_edge ( clk ) ) then
current_task_state < = next_task_state ;
case next_task_state is
when work . task . TASK_IDLE = >
index < = 0 ;
signal_write < = '0' ;
when work . task . TASK_RUNNING = >
2024-11-13 11:19:20 +01:00
--starten
--wenn: start = 0
--A und B Signale anlegen
--start Signal auf 1 setzen
--done Signal auf 0 setzen
if ( task_start = '0' ) then
--do starten
elsif ( task_start = '1' and done = '0' ) then
--do warten
elsif ( task_start = '1' and done = '1' ) then
--do Ergebnis lesen
end if ;
--warten
--wenn: start = 1, done = 0
--Ergebnis lesen
--wenn: done = 1, start = 1
--wenn done kommt, wert aus sum lesen
--start nach einem Takt auf 0 setzen?
2024-11-20 09:27:56 +01:00
index < = index + 1 ; --inkrement nach erfolgreicher Berechnung. Abbruchbedingung index==1024
signal_write < = '1' ; --hier wird in den Speicher geschrieben
signal_writedata < = ( others = > '0' ) ; --eigenes Ergebnis zuweisen
2023-10-31 07:47:27 +01:00
when work . task . TASK_DONE = >
index < = 0 ;
signal_write < = '0' ;
end case ;
end if ;
end process sync ;
2024-11-13 11:19:20 +01:00
--● Sie müssen sich eine Ablaufsteuerung
--überlegen mit, welcher Sie den IP-Core die von
--den Datenquellen gelesenen Werte zuführen
--und die berechneten Additionen in der
--Datensenke speichern
--● Timing Diagramm des IP-Cors beachten (start
--und done Signale des IP-Cores)
--● Die vom FIFO gelesenen Werte und auch das
--Format in welchen die Werte im FIFO
--gespeichert werden ist float (muss hier nichts
--extra beachtet werden)
--● Es wird eine Berechnung der Addition
--durchgeführt und dann die nächste gestartet bis
--alle 1024 Werte aus den FIFOs bearbeitet
--wurden
2023-10-31 07:47:27 +01:00
task_state < = current_task_state ;
end architecture rtl ;