@@ -19,30 +19,17 @@ library work; | |||
use work.task.all; | |||
use work.float.all; | |||
entity fft is | |||
generic ( | |||
-- input data width of real/img part | |||
input_data_width : integer := 32; | |||
-- output data width of real/img part | |||
output_data_width : integer := 32 | |||
); | |||
port ( | |||
clk : in std_logic; | |||
reset : in std_logic; | |||
task_start : in std_logic; | |||
task_state : out work.task.State; | |||
signal_read : out std_logic; | |||
signal_readdata : in std_logic_vector( 31 downto 0 ); | |||
signal_write : out std_logic; | |||
signal_writedata : out std_logic_vector( 31 downto 0 ) | |||
); | |||
end entity fft; | |||
architecture rtl of fft is | |||
@@ -50,7 +37,87 @@ architecture rtl of fft is | |||
signal next_task_state : work.task.State; | |||
signal index : integer range 0 to work.task.STREAM_LEN; | |||
--own signals: | |||
--signal input_re : float(31 downto 0); | |||
--use xxx.lib?; --componenteninstanziierung FFT IP-Core r22sdf | |||
--component foo is | |||
--generic (...) | |||
--port(...); | |||
--end component; | |||
component fftmain is | |||
generic ( | |||
-- input data width of real/img part | |||
input_data_width : integer := 32; | |||
-- output data width of real/img part | |||
output_data_width : integer := 32 | |||
); | |||
port ( | |||
clk : in std_logic; | |||
reset : in std_logic; | |||
di_en : in std_logic; | |||
di_re : in std_logic_vector(input_data_width-1 downto 0); | |||
di_im : in std_logic_vector(input_data_width-1 downto 0); | |||
do_en : in std_logic; | |||
do_re : in std_logic_vector(input_data_width-1 downto 0); | |||
do_im : in std_logic_vector(input_data_width-1 downto 0) | |||
--task_start : in std_logic; | |||
--task_state : out work.task.State; | |||
--signal_read : out std_logic; | |||
--signal_readdata : in std_logic_vector( 31 downto 0 ); | |||
--signal_write : out std_logic; | |||
--signal_writedata : out std_logic_vector( 31 downto 0 ) | |||
); | |||
end component fftmain; | |||
---State machine ---------------------------------- | |||
TYPE State_type IS (A, B, C, D); -- Define the states | |||
SIGNAL State : State_Type; -- Create a signal that uses | |||
-- the different states | |||
begin | |||
u_fft : fftmain | |||
port map ( | |||
clock => clk, | |||
reset => fft_reset, | |||
di_en => fft_input_data_enable, | |||
di_re => diata_in_re, | |||
di_im => data_in_im, | |||
do_en => fft_output_valid, | |||
do_re => data_out_re, | |||
do_im => data_out_im | |||
); | |||
u_fft_mag_calc : entity work.fft_magnitude_calc | |||
port map ( | |||
clk => clk, | |||
reset => reset, | |||
input_valid => fft_output_valid, | |||
input_re => data_out_re, | |||
input_im => data_out_im, | |||
output_valid => fft_mag_calc_valid, | |||
output_magnitude => fft_mag_calc_result | |||
); | |||
task_state_transitions : process ( current_task_state, task_start, index ) is | |||
begin | |||
next_task_state <= current_task_state; |
@@ -15,9 +15,9 @@ entity sine is | |||
task_start : in std_logic; | |||
task_state : out work.task.State; | |||
step_size : in work.reg32.word; | |||
phase : in work.reg32.word; | |||
amplitude : in work.reg32.word; | |||
step_size : in work.reg32.word; --Parameter, übergeben aus task_sine | |||
phase : in work.reg32.word; --Parameter, übergeben aus task_sine | |||
amplitude : in work.reg32.word; --Parameter, übergeben aus task_sine | |||
signal_write : out std_logic; | |||
signal_writedata : out std_logic_vector( 31 downto 0 ) | |||
@@ -29,8 +29,139 @@ 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; | |||
--own signals: | |||
signal data_valid : std_logic; | |||
signal busy : std_logic; | |||
signal angle : signed(31 downto 0); | |||
signal result_valid : std_logic; | |||
signal sine_value : signed(31 downto 0); | |||
signal output_value : signed(31 downto 0); | |||
signal output_flag : std_logic; | |||
--signal exp : signed(7 downto 0); | |||
--signal tmp : signed(7 downto 0); | |||
---State machine ---------------------------------- | |||
TYPE State_type IS (A, B, C, D); -- Define the states | |||
SIGNAL State : State_Type; -- Create a signal that uses | |||
-- the different states | |||
begin | |||
u_float_sine : entity work.float_sine | |||
generic map ( | |||
ITERATIONS => 8 | |||
) | |||
port map( | |||
clk => clk, | |||
reset => reset, | |||
data_valid => data_valid, | |||
angle => angle, | |||
busy => busy, | |||
result_valid => result_valid, | |||
sine => sine_value | |||
); | |||
PROCESS (clk, reset) | |||
BEGIN | |||
If (reset = '1') THEN --RESET: State to A | |||
data_valid <= '0'; | |||
output_flag <= '0'; | |||
angle <= x"00000000";--x"1FFFFFFF"; | |||
State <= A; | |||
ELSIF rising_edge(clk) THEN -- if there is a rising edge of the | |||
-- clock, then do the stuff below | |||
-- The CASE statement checks the value of the State variable, | |||
-- and based on the value and any other control signals, changes | |||
-- to a new state. | |||
CASE State IS | |||
-- If the current state is A and P is set to 1, then the | |||
-- next state is B | |||
WHEN A => --set data_valid to 1 for one clock cycle | |||
IF index = 0 THEN | |||
angle <= signed(phase); | |||
ELSE | |||
--angle <= angle;--x"1FFFFFFF"; --debug: 1,5 --> should result in sin() = 1 | |||
END IF; | |||
IF data_valid ='0' AND current_task_state = TASK_RUNNING THEN | |||
data_valid <= '1'; | |||
State <= B; | |||
END IF; | |||
-- If the current state is B and P is set to 1, then the | |||
-- next state is C | |||
WHEN B => | |||
IF data_valid ='1' THEN | |||
data_valid <= '0'; | |||
State <= C; | |||
END IF; | |||
-- If the current state is C and P is set to 1, then the | |||
-- next state is D | |||
WHEN C => | |||
IF result_valid = '1' AND busy = '0' THEN | |||
--sine_value <= sine; | |||
output_flag <= '1'; | |||
data_valid <= '0'; | |||
angle <= angle + signed(step_size); --winkel neu zuweisen | |||
State <= D; | |||
END IF; | |||
-- If the current state is D and P is set to 1, then the | |||
-- next state is B. | |||
-- If the current state is D and P is set to 0, then the | |||
-- next state is A. | |||
WHEN D=> | |||
IF data_valid = '0' THEN | |||
output_flag <= '0'; | |||
State <= A; | |||
--ELSE | |||
--State <= A; | |||
END IF; | |||
--WHEN others => | |||
--State <= A; | |||
END CASE; | |||
END IF; | |||
END PROCESS; | |||
--end of state machine______________________________________ | |||
--do not change | |||
task_state_transitions : process ( current_task_state, task_start, index ) is | |||
begin | |||
next_task_state <= current_task_state; | |||
@@ -40,17 +171,20 @@ begin | |||
next_task_state <= work.task.TASK_RUNNING; | |||
end if; | |||
when work.task.TASK_RUNNING => | |||
if ( index = work.task.STREAM_LEN - 1 ) then | |||
if ( index = work.task.STREAM_LEN ) then -- changed from index = work.task.STREAM_LEN - 1 | |||
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; | |||
--end of no not change | |||
sync : process ( clk, reset ) is | |||
sync : process ( clk, reset , signal_writedata) is | |||
begin | |||
if ( reset = '1' ) then | |||
current_task_state <= work.task.TASK_IDLE; | |||
@@ -61,17 +195,37 @@ begin | |||
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' ); | |||
--output: | |||
IF output_flag = '1' THEN | |||
index <= index + 1; | |||
signal_write <= '1'; | |||
output_value <= sine_value; | |||
output_value(30 downto 23) <= sine_value(30 downto 23) + (signed(amplitude(30 downto 23)) - 127); --change from +2 to correct exponent | |||
--wenn 1: +0, wenn 2: +1, wenn 4:2, wenn 8: 3 = Bit | |||
ELSE | |||
signal_write <= '0'; | |||
END IF; | |||
--signal_writedata <= std_logic_vector(to_unsigned(2, signal_writedata'length)); --test | |||
when work.task.TASK_DONE => | |||
index <= 0; | |||
signal_write <= '0'; | |||
signal_write <= '0'; | |||
end case; | |||
end if; | |||
end process sync; | |||
task_state <= current_task_state; | |||
signal_writedata <= std_logic_vector(output_value);--x"40800000";--( others => '0' ); | |||
end architecture rtl; |
@@ -2,9 +2,72 @@ | |||
#include "system/data_channel.h" | |||
#include "system/float_word.h" | |||
#include <math.h> | |||
#include <stdio.h> | |||
typedef struct { | |||
float value; | |||
} Result; | |||
void generateSinusCurve(float samples_per_period, float phase, float amplitude, Result res[]) { | |||
float delta_phase = 2.0 * M_PI / samples_per_period; | |||
float current_phase = phase; | |||
for (int i = 0; i < DATA_CHANNEL_DEPTH; ++i) { | |||
res[i].value = amplitude * sinf(current_phase); | |||
current_phase += delta_phase; | |||
} | |||
} | |||
int task_sine_run( void * data ) { | |||
// TODO | |||
sine_config * task = (sine_config *) data; | |||
uint32_t data_channel_base = task -> base.sink; | |||
data_channel_clear( data_channel_base ); | |||
float_word res; | |||
//float samples_per_period = 32.0; | |||
float samples_per_period = task ->samples_per_periode; | |||
float phase = task-> phase; | |||
float amplitude = task -> amplitude; | |||
Result results[DATA_CHANNEL_DEPTH]; | |||
generateSinusCurve(samples_per_period, phase, amplitude, results); | |||
for (int i = 0; i < DATA_CHANNEL_DEPTH; ++i) { | |||
//printf("Wert %d: %f\n", i, results[i].value); | |||
res.value = results[i].value; | |||
data_channel_write( data_channel_base, res.word); | |||
} | |||
return 0; | |||
} | |||
@@ -24,7 +24,7 @@ sine_config SINE_CONFIG = { | |||
.sink = DATA_CHANNEL_0_BASE, | |||
.cycle_count = 0 }, | |||
.samples_per_periode = 32, | |||
.phase = 0.0, | |||
.phase = 0, | |||
.amplitude = 4.0 }; | |||
sine_config COSINE_CONFIG = { |
@@ -25,8 +25,8 @@ assert_level := error | |||
.PHONY: sim clean | |||
sim: ${verilog_objs} ${vhdl_objs} | |||
@vsim -gCHECK_RESULTS=${CHECK_RESULTS} -voptargs=+acc -c work.${main} -do "set StdArithNoWarnings 1; set NumericStdNoWarnings 1; run -all" \ | |||
| ../../scripts/highlight_test_results.sh | |||
@vsim -gCHECK_RESULTS=${CHECK_RESULTS} -voptargs=+acc -c work.${main} -do "set StdArithNoWarnings 1; set NumericStdNoWarnings 1; run -all" | |||
#| ../../scripts/highlight_test_results.sh | |||
gui: ${verilog_objs} ${vhdl_objs} | |||
@vsim -gCHECK_RESULTS=${CHECK_RESULTS} -gGUI_MODE=true -voptargs=+acc work.${main} -do "do vsim.wave; set StdArithNoWarnings 1; set NumericStdNoWarnings 1; run -all" |
@@ -10,8 +10,9 @@ verilog_srcs = \ | |||
vhdl_srcs = \ | |||
../../../hardware/system/reg32.vhd \ | |||
../test_utility.vhd \ | |||
../test_avalon_slave.vhd \ | |||
../../../hardware/system/avalon_slave.vhd \ | |||
../../hardware/test_data_channel.vhd \ | |||
../../../hardware/system/avalon_slave_transitions.vhd \ | |||
../../../hardware/system/task.vhd \ | |||
../../../hardware/system/hardware_task_control.vhd \ | |||
@@ -24,6 +25,7 @@ vhdl_srcs = \ | |||
../test_utility.vhd \ | |||
../test_avalon_slave.vhd \ | |||
../test_hardware_task.vhd \ | |||
../../hardware/test_data_channel.vhd \ | |||
../../data/add_rand.vhd \ | |||
../../data/sine.vhd \ | |||
../../data/fft.vhd \ |