Team 1 Lösung

This commit is contained in:
altjo87133
2026-01-13 09:57:40 +01:00
parent c90753aa23
commit f893162d89
243 changed files with 23106 additions and 114 deletions
+101 -7
View File
@@ -26,11 +26,36 @@ entity add is
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;
signal current_task_state : work.task.State;
signal next_task_state : work.task.State;
signal index : integer range 0 to work.task.STREAM_LEN;
signal fa_start: std_logic;
signal fa_done: std_logic;
signal fa_sum: std_logic_vector(31 downto 0);
signal a_value: std_logic_vector(31 downto 0);
signal b_value: std_logic_vector(31 downto 0);
signal sample_done: std_logic;
signal calc_cnt_int: integer range 0 to 15;
type calc_state_t is (
C_IDLE,
C_READ_A_REQ, C_READ_A_LATCH,
C_READ_B_REQ, C_READ_B_LATCH,
C_START_ADD, C_WAIT_ADD,
C_WRITE_RESULT
);
signal calc_state: calc_state_t:=C_IDLE;
begin
u_float_add : entity work.float_add
port map(
clk => clk,
reset => reset,
start => fa_start,
done => fa_done,
A => a_value,
B => b_value,
sum => fa_sum
);
task_state_transitions : process ( current_task_state, task_start, index ) is
begin
next_task_state <= current_task_state;
@@ -50,13 +75,33 @@ begin
end case;
end process task_state_transitions;
sync : process ( clk, reset ) is
begin
if ( reset = '1' ) then
current_task_state <= work.task.TASK_IDLE;
if ( reset = '1' ) then
current_task_state <= work.task.TASK_IDLE;
calc_state <= C_IDLE;
signal_a_read <= '0';
signal_b_read <= '0';
signal_write <= '0';
signal_writedata <= (others => '0');
calc_cnt_int <= 0;
fa_start <= '0';
a_value <= (others => '0');
b_value <= (others => '0');
sample_done <= '0';
index <= 0;
elsif ( rising_edge( clk ) ) then
current_task_state <= next_task_state;
fa_start <= '0';
signal_a_read <= '0';
signal_b_read <= '0';
signal_write <= '0';
sample_done <= '0';
case next_task_state is
when work.task.TASK_IDLE =>
index <= 0;
@@ -69,9 +114,58 @@ begin
index <= 0;
signal_write <= '0';
end case;
end if;
case calc_state is
when C_IDLE =>
if current_task_state = work.task.TASK_RUNNING then
calc_state <= C_READ_A_REQ;
end if;
when C_READ_A_REQ =>
signal_a_read <= '1';
calc_state <= C_READ_A_LATCH;
when C_READ_A_LATCH =>
a_value <= signal_a_readdata;
calc_state <= C_READ_B_REQ;
when C_READ_B_REQ =>
signal_b_read <= '1';
calc_state <= C_READ_B_LATCH;
when C_READ_B_LATCH =>
b_value <= signal_b_readdata;
calc_state <= C_START_ADD;
when C_START_ADD =>
fa_start <='1';
calc_state <= C_WAIT_ADD;
when C_WAIT_ADD =>
if ( fa_done = '1' ) then
calc_state <= C_WRITE_RESULT;
end if;
when C_WRITE_RESULT =>
signal_write <= '1' ;
signal_writedata <= fa_sum;
calc_cnt_int <= calc_cnt_int + 1;
end case;
end if;
end process sync;
task_state <= current_task_state;
end architecture rtl;
+240 -56
View File
@@ -1,77 +1,261 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library work;
use work.reg32.all;
use work.float.all;
use work.task.all;
use work.reg32.all;
use work.float.all;
use work.task.all;
entity sine is
port (
clk : in std_logic;
clk : in std_logic;
reset : in std_logic;
task_start : in std_logic;
task_state : out work.task.State;
task_start : in std_logic; --Startsignal
task_state : out work.task.State; --Ausgang
step_size : in work.reg32.word;
phase : in work.reg32.word;
amplitude : in work.reg32.word;
step_size : in work.reg32.word; --Winkelinkrement pro Sample
phase : in work.reg32.word; --Startwinkel
amplitude : in work.reg32.word; --Amplitude
signal_write : out std_logic;
signal_writedata : out std_logic_vector( 31 downto 0 )
signal_write : out std_logic;
signal_writedata : out std_logic_vector(31 downto 0)
);
end entity sine;
architecture rtl of sine 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;
--Task-FSM
signal current_task_state : work.task.State := work.task.TASK_IDLE;
signal next_task_state : work.task.State := work.task.TASK_IDLE;
signal index : integer range 0 to work.task.STREAM_LEN := 0;
--Flanken-Erkennung
signal task_start_d : std_logic := '0';
signal task_start_re : std_logic := '0';
--float_sine-IP-core
signal fs_data_valid : std_logic := '0'; --eingabe
signal fs_busy : std_logic; -- Steuerung
signal fs_result_valid : std_logic;
signal fs_angle : signed(31 downto 0) := (others => '0');
signal fs_sine : signed(31 downto 0); --Ausgabe
--Datenpfad
signal angle_reg : signed(31 downto 0) := (others => '0'); --aktueller Winkel
signal sine_raw_fp : std_logic_vector(31 downto 0) := (others => '0'); --Ergebnis des IP-Cores
signal sine_scaled_fp : std_logic_vector(31 downto 0) := (others => '0'); --skaliertes Ergebnis
--Calc-FSM
type calc_state_t is (
C_IDLE,
C_START,
C_WAIT,
C_SCALE,
C_WRITE
);
signal calc_state : calc_state_t := C_IDLE;
begin
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;
sync : process ( clk, reset ) is
begin
if ( reset = '1' ) then
current_task_state <= work.task.TASK_IDLE;
index <= 0;
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 =>
index <= index + 1;
signal_write <= '1';
signal_writedata <= ( others => '0' );
when work.task.TASK_DONE =>
index <= 0;
signal_write <= '0';
end case;
end if;
end process sync;
task_state <= current_task_state;
--------------------------------------------------------------------------
-- Task-FSM transitions
--------------------------------------------------------------------------
task_state_transitions : process(current_task_state, task_start_re, index, calc_state)
begin
next_task_state <= current_task_state;
case current_task_state is
when work.task.TASK_IDLE =>
if task_start_re = '1' then
next_task_state <= work.task.TASK_RUNNING;
end if;
when work.task.TASK_RUNNING =>
if (index = work.task.STREAM_LEN ) and (calc_state = C_WRITE) then
next_task_state <= work.task.TASK_DONE;
end if;
when work.task.TASK_DONE =>
if task_start_re = '1' then
next_task_state <= work.task.TASK_RUNNING;
end if;
end case;
end process;
--------------------------------------------------------------------------
-- float_sine instantiation
--------------------------------------------------------------------------
fs_angle <= angle_reg;
u_float_sine : entity work.float_sine
generic map (
ITERATIONS => 8
)
port map (
clk => clk,
reset => reset,
data_valid => fs_data_valid, --Eingabe starten
busy => fs_busy, --Core arbeitet
result_valid => fs_result_valid, --Ergebnis fertig
angle => fs_angle, --Eingabewinkel
sine => fs_sine --Ergebnis
);
--------------------------------------------------------------------------
-- Sync / Datenpfad
--------------------------------------------------------------------------
--Multiplikation über: neuer_exponent = sin_exp + (amp_exp -127)
sync : process(clk, reset)
variable sin_exp : unsigned(7 downto 0); --Speichern Sinuszahl
variable amp_exp : unsigned(7 downto 0); --Speichern Amplitude
variable new_exp : unsigned(7 downto 0); --Speichern neuen Exponenten
--Exponenten als Integerwerte für Berechnung
variable sin_e_i : integer range -255 to 511;
variable amp_e_i : integer range -255 to 511;
variable new_e_i : integer range -255 to 511;
begin
if reset = '1' then
current_task_state <= work.task.TASK_IDLE;
index <= 0;
task_start_d <= '0';
task_start_re <= '0';
calc_state <= C_IDLE;
angle_reg <= (others => '0');
sine_raw_fp <= (others => '0');
sine_scaled_fp <= (others => '0');
fs_data_valid <= '0';
signal_write <= '0';
signal_writedata <= (others => '0');
elsif rising_edge(clk) then
------------------------------------------------------------------
-- rising edge detect
------------------------------------------------------------------
task_start_re <= task_start and not task_start_d;
task_start_d <= task_start;
------------------------------------------------------------------
-- Defaults
------------------------------------------------------------------
signal_write <= '0';
fs_data_valid <= '0';
------------------------------------------------------------------
-- Task-FSM update
------------------------------------------------------------------
current_task_state <= next_task_state;
------------------------------------------------------------------
-- Berechnungs-FSM
------------------------------------------------------------------
case calc_state is
------------------------------------------------------------------
-- Start: Sofort mit erstem Winkel beginnen
------------------------------------------------------------------
when C_IDLE =>
if (current_task_state = work.task.TASK_RUNNING) then
angle_reg <= signed(phase);
calc_state <= C_START;
end if;
------------------------------------------------------------------
-- Wert in den Core laden, sobald busy='0'
------------------------------------------------------------------
when C_START =>
if fs_busy = '0' then --Wenn Core ist frei
fs_data_valid <= '1'; --Input-Latch im Core
calc_state <= C_WAIT;
end if;
------------------------------------------------------------------
-- Warten auf Ergebnis
------------------------------------------------------------------
when C_WAIT => --Warten auf Ergebnis
if fs_result_valid = '1' then
sine_raw_fp <= std_logic_vector(fs_sine);
calc_state <= C_SCALE;
end if;
------------------------------------------------------------------
-- Skalierung
------------------------------------------------------------------
when C_SCALE =>
sin_exp := unsigned(sine_raw_fp(30 downto 23)); --Liest die 8 Exponentenbits des Sinuswerts
amp_exp := unsigned(amplitude(30 downto 23)); --Liese die 8 der Amplitude
sin_e_i := to_integer(sin_exp); --Umwandlung in Integer
amp_e_i := to_integer(amp_exp);
new_e_i := sin_e_i + (amp_e_i - 127); --Eigentliche Multiplikation
if new_e_i < 0 then -- Falls Wert negativ
new_exp := (others => '0'); --Setze Wert auf 0
else
new_exp := to_unsigned(new_e_i, 8); --Zurückwandeln in 8-Bit-Exponent
end if;
--Berechnten Exponenten wieder zusammensetzen
sine_scaled_fp(31) <= sine_raw_fp(31);
sine_scaled_fp(30 downto 23) <= std_logic_vector(new_exp);
sine_scaled_fp(22 downto 0) <= sine_raw_fp(22 downto 0);
calc_state <= C_WRITE;
------------------------------------------------------------------
-- Schreiben + nächsten Winkel
------------------------------------------------------------------
when C_WRITE =>
signal_write <= '1';
signal_writedata <= sine_scaled_fp;
if index = work.task.STREAM_LEN then
calc_state <= C_IDLE;
else
angle_reg <= angle_reg + signed(step_size);
calc_state <= C_START;
end if;
end case;
------------------------------------------------------------------
-- Index update
------------------------------------------------------------------
case next_task_state is
when work.task.TASK_IDLE =>
index <= 0;
when work.task.TASK_RUNNING =>
if calc_state = C_WRITE then
if index < work.task.STREAM_LEN then
index <= index + 1;
end if;
end if;
when work.task.TASK_DONE =>
index <= 0;
end case;
end if;
end process;
end architecture rtl;