4.Test
This commit is contained in:
parent
c90753aa23
commit
4d0bb79521
@ -1,77 +1,195 @@
|
|||||||
library ieee;
|
library ieee;
|
||||||
use ieee.std_logic_1164.all;
|
use ieee.std_logic_1164.all;
|
||||||
use ieee.numeric_std.all;
|
use ieee.numeric_std.all;
|
||||||
|
|
||||||
library work;
|
library work;
|
||||||
use work.reg32.all;
|
use work.reg32.all;
|
||||||
use work.task.all;
|
use work.task.all;
|
||||||
|
|
||||||
entity add is
|
entity add is
|
||||||
port (
|
port (
|
||||||
clk : in std_logic;
|
clk : in std_logic;
|
||||||
reset : in std_logic;
|
reset : in std_logic;
|
||||||
|
|
||||||
task_start : in std_logic;
|
task_start : in std_logic;
|
||||||
task_state : out work.task.State;
|
task_state : out work.task.State;
|
||||||
|
|
||||||
signal_a_read : out std_logic;
|
signal_a_read : out std_logic;
|
||||||
signal_a_readdata : in std_logic_vector( 31 downto 0 );
|
signal_a_readdata : in std_logic_vector(31 downto 0);
|
||||||
|
|
||||||
signal_b_read : out std_logic;
|
signal_b_read : out std_logic;
|
||||||
signal_b_readdata : in std_logic_vector( 31 downto 0 );
|
signal_b_readdata : in std_logic_vector(31 downto 0);
|
||||||
|
|
||||||
signal_write : out std_logic;
|
signal_write : out std_logic;
|
||||||
signal_writedata : out std_logic_vector( 31 downto 0 )
|
signal_writedata : out std_logic_vector(31 downto 0)
|
||||||
);
|
);
|
||||||
end entity add;
|
end entity add;
|
||||||
|
|
||||||
architecture rtl of add is
|
architecture rtl of add is
|
||||||
signal current_task_state : work.task.State;
|
|
||||||
signal next_task_state : work.task.State;
|
-- Task FSM
|
||||||
signal index : integer range 0 to work.task.STREAM_LEN;
|
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-1 := 0;
|
||||||
|
|
||||||
|
-- task_start rising edge detect (combinational pulse)
|
||||||
|
signal task_start_d : std_logic := '0';
|
||||||
|
signal task_start_re : std_logic;
|
||||||
|
|
||||||
|
-- float_add IP core
|
||||||
|
signal fa_start : std_logic := '0';
|
||||||
|
signal fa_done : std_logic := '0';
|
||||||
|
signal fa_sum : std_logic_vector(31 downto 0);
|
||||||
|
|
||||||
|
signal a_value : std_logic_vector(31 downto 0) := (others => '0');
|
||||||
|
signal b_value : std_logic_vector(31 downto 0) := (others => '0');
|
||||||
|
|
||||||
|
-- Calc FSM
|
||||||
|
type calc_state_t is (
|
||||||
|
C_IDLE,
|
||||||
|
C_READ_A,
|
||||||
|
C_READ_B,
|
||||||
|
C_START_ADD,
|
||||||
|
C_WAIT_ADD,
|
||||||
|
C_WRITE_RESULT
|
||||||
|
);
|
||||||
|
signal calc_state : calc_state_t := C_IDLE;
|
||||||
|
|
||||||
begin
|
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
|
-- combinational rising edge detect
|
||||||
begin
|
task_start_re <= task_start and not task_start_d;
|
||||||
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_state <= current_task_state;
|
||||||
|
|
||||||
|
-- float_add instance
|
||||||
|
u_float_add : entity work.float_add
|
||||||
|
port map (
|
||||||
|
A => a_value,
|
||||||
|
B => b_value,
|
||||||
|
clk => clk,
|
||||||
|
reset => reset,
|
||||||
|
start => fa_start,
|
||||||
|
done => fa_done,
|
||||||
|
sum => fa_sum
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Task FSM transitions (ONLY driver of next_task_state)
|
||||||
|
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 - 1) and (calc_state = C_WRITE_RESULT) 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;
|
||||||
|
-- Synchronous process
|
||||||
|
sync : process(clk, reset)
|
||||||
|
begin
|
||||||
|
if reset = '1' then
|
||||||
|
|
||||||
|
current_task_state <= work.task.TASK_IDLE;
|
||||||
|
index <= 0;
|
||||||
|
|
||||||
|
task_start_d <= '0';
|
||||||
|
|
||||||
|
calc_state <= C_IDLE;
|
||||||
|
|
||||||
|
fa_start <= '0';
|
||||||
|
signal_a_read <= '0';
|
||||||
|
signal_b_read <= '0';
|
||||||
|
signal_write <= '0';
|
||||||
|
|
||||||
|
signal_writedata <= (others => '0');
|
||||||
|
a_value <= (others => '0');
|
||||||
|
b_value <= (others => '0');
|
||||||
|
|
||||||
|
elsif rising_edge(clk) then
|
||||||
|
|
||||||
|
-- register delayed start for edge detect
|
||||||
|
task_start_d <= task_start;
|
||||||
|
|
||||||
|
-- defaults
|
||||||
|
signal_a_read <= '0';
|
||||||
|
signal_b_read <= '0';
|
||||||
|
signal_write <= '0';
|
||||||
|
fa_start <= '0';
|
||||||
|
|
||||||
|
-- update task state
|
||||||
|
current_task_state <= next_task_state;
|
||||||
|
|
||||||
|
-- index update
|
||||||
|
case current_task_state is
|
||||||
|
when work.task.TASK_IDLE =>
|
||||||
|
index <= 0;
|
||||||
|
|
||||||
|
when work.task.TASK_RUNNING =>
|
||||||
|
if calc_state = C_WRITE_RESULT then
|
||||||
|
if index < work.task.STREAM_LEN - 1 then
|
||||||
|
index <= index + 1;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
when work.task.TASK_DONE =>
|
||||||
|
index <= 0;
|
||||||
|
end case;
|
||||||
|
|
||||||
|
-- calc FSM
|
||||||
|
case calc_state is
|
||||||
|
|
||||||
|
when C_IDLE =>
|
||||||
|
if current_task_state = work.task.TASK_RUNNING then
|
||||||
|
calc_state <= C_READ_A;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
when C_READ_A =>
|
||||||
|
signal_a_read <= '1';
|
||||||
|
a_value <= signal_a_readdata;
|
||||||
|
calc_state <= C_READ_B;
|
||||||
|
|
||||||
|
when C_READ_B =>
|
||||||
|
signal_b_read <= '1';
|
||||||
|
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 =>
|
||||||
|
fa_start <= '1';
|
||||||
|
if fa_done = '1' then
|
||||||
|
calc_state <= C_WRITE_RESULT;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
when C_WRITE_RESULT =>
|
||||||
|
signal_write <= '1';
|
||||||
|
signal_writedata <= fa_sum;
|
||||||
|
|
||||||
|
if index = work.task.STREAM_LEN - 1 then
|
||||||
|
calc_state <= C_IDLE;
|
||||||
|
else
|
||||||
|
calc_state <= C_READ_A;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
end case;
|
||||||
|
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
end architecture rtl;
|
end architecture rtl;
|
||||||
|
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
library ieee;
|
library ieee;
|
||||||
use ieee.std_logic_1164.all;
|
use ieee.std_logic_1164.all;
|
||||||
use ieee.numeric_std.all;
|
use ieee.numeric_std.all;
|
||||||
|
|
||||||
library work;
|
library work;
|
||||||
use work.reg32.all;
|
use work.reg32.all;
|
||||||
use work.task.all;
|
use work.task.all;
|
||||||
|
|
||||||
entity rand is
|
entity rand is
|
||||||
port (
|
port (
|
||||||
@ -16,17 +16,21 @@ entity rand is
|
|||||||
seed : in work.reg32.word;
|
seed : in work.reg32.word;
|
||||||
|
|
||||||
signal_write : out std_logic;
|
signal_write : out std_logic;
|
||||||
signal_writedata : out std_logic_vector( 31 downto 0 )
|
signal_writedata : out std_logic_vector(31 downto 0)
|
||||||
);
|
);
|
||||||
end entity rand;
|
end entity rand;
|
||||||
|
|
||||||
architecture rtl of rand is
|
architecture rtl of rand is
|
||||||
|
|
||||||
signal current_task_state : work.task.State;
|
signal current_task_state : work.task.State := work.task.TASK_IDLE;
|
||||||
signal next_task_state : work.task.State;
|
signal next_task_state : work.task.State := work.task.TASK_IDLE;
|
||||||
signal index : integer range 0 to work.task.STREAM_LEN;
|
|
||||||
|
signal index : integer range 0 to work.task.STREAM_LEN-1 := 0;
|
||||||
|
|
||||||
|
signal lfsr : std_logic_vector(31 downto 0) := (others => '0');
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
-- task_state_transitions
|
||||||
task_state_transitions : process ( current_task_state, task_start, index ) is
|
task_state_transitions : process ( current_task_state, task_start, index ) is
|
||||||
begin
|
begin
|
||||||
next_task_state <= current_task_state;
|
next_task_state <= current_task_state;
|
||||||
@ -45,29 +49,94 @@ begin
|
|||||||
end if;
|
end if;
|
||||||
end case;
|
end case;
|
||||||
end process task_state_transitions;
|
end process task_state_transitions;
|
||||||
|
|
||||||
sync : process ( clk, reset ) is
|
sync : process ( clk, reset ) is
|
||||||
|
variable fb : std_logic;
|
||||||
|
variable lfsr_work : std_logic_vector(31 downto 0);
|
||||||
|
variable lfsr_next : std_logic_vector(31 downto 0);
|
||||||
|
|
||||||
|
variable exp_rand : std_logic_vector(7 downto 0);
|
||||||
|
variable exp_new : std_logic_vector(7 downto 0);
|
||||||
|
variable out_word : std_logic_vector(31 downto 0);
|
||||||
|
|
||||||
|
variable do_run : boolean;
|
||||||
|
variable entering : boolean;
|
||||||
begin
|
begin
|
||||||
if ( reset = '1' ) then
|
if ( reset = '1' ) then
|
||||||
current_task_state <= work.task.TASK_IDLE;
|
current_task_state <= work.task.TASK_IDLE;
|
||||||
index <= 0;
|
index <= 0;
|
||||||
elsif ( rising_edge( clk ) ) then
|
lfsr <= (others => '0');
|
||||||
|
signal_write <= '0';
|
||||||
|
signal_writedata <= (others => '0');
|
||||||
|
|
||||||
|
elsif rising_edge( clk ) then
|
||||||
|
-- State-Register
|
||||||
current_task_state <= next_task_state;
|
current_task_state <= next_task_state;
|
||||||
case next_task_state is
|
|
||||||
when work.task.TASK_IDLE =>
|
-- Defaults (wichtig für assert_level)
|
||||||
index <= 0;
|
signal_write <= '0';
|
||||||
signal_write <= '0';
|
signal_writedata <= (others => '0');
|
||||||
when work.task.TASK_RUNNING =>
|
|
||||||
index <= index + 1;
|
-- Datapath-Steuerung:
|
||||||
signal_write <= '1';
|
-- RUNNING-Aktionen ausführen, wenn
|
||||||
signal_writedata <= ( others => '0' );
|
-- a) gerade RUNNING sind (auch wenn next schon DONE ist -> letztes Sample!)
|
||||||
when work.task.TASK_DONE =>
|
-- b) in RUNNING eintreten (IDLE/DONE -> RUNNING)
|
||||||
index <= 0;
|
entering := (current_task_state /= work.task.TASK_RUNNING) and (next_task_state = work.task.TASK_RUNNING);
|
||||||
signal_write <= '0';
|
do_run := (current_task_state = work.task.TASK_RUNNING) or entering;
|
||||||
end case;
|
|
||||||
|
if do_run then
|
||||||
|
-- LFSR-Quelle: beim Eintritt seed, sonst aktueller lfsr
|
||||||
|
if entering then
|
||||||
|
lfsr_work := seed;
|
||||||
|
index <= 0; -- erstes Sample hat Index 0
|
||||||
|
else
|
||||||
|
lfsr_work := lfsr;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
-- Output aus aktuellem Zustand bauen
|
||||||
|
exp_rand := lfsr_work(30 downto 23);
|
||||||
|
|
||||||
|
if exp_rand(7) = '1' then
|
||||||
|
exp_new(7) := '1';
|
||||||
|
exp_new(6 downto 1) := (others => '0');
|
||||||
|
exp_new(0) := exp_rand(0);
|
||||||
|
else
|
||||||
|
exp_new(7) := '0';
|
||||||
|
exp_new(6 downto 2) := (others => '1');
|
||||||
|
exp_new(1 downto 0) := exp_rand(1 downto 0);
|
||||||
|
end if;
|
||||||
|
|
||||||
|
out_word(31) := lfsr_work(31);
|
||||||
|
out_word(30 downto 23) := exp_new;
|
||||||
|
out_word(22 downto 0) := lfsr_work(22 downto 0);
|
||||||
|
|
||||||
|
signal_write <= '1';
|
||||||
|
signal_writedata <= out_word;
|
||||||
|
|
||||||
|
-- LFSR Schritt nach Ausgabe
|
||||||
|
fb := lfsr_work(31) xor lfsr_work(21) xor lfsr_work(1) xor lfsr_work(0);
|
||||||
|
lfsr_next := lfsr_work(30 downto 0) & fb;
|
||||||
|
lfsr <= lfsr_next;
|
||||||
|
|
||||||
|
-- Index nach Write erhöhen
|
||||||
|
if index < work.task.STREAM_LEN - 1 then
|
||||||
|
index <= index + 1;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
else
|
||||||
|
case current_task_state is
|
||||||
|
when work.task.TASK_IDLE =>
|
||||||
|
index <= 0;
|
||||||
|
when work.task.TASK_DONE =>
|
||||||
|
index <= 0;
|
||||||
|
when others =>
|
||||||
|
null;
|
||||||
|
end case;
|
||||||
|
end if;
|
||||||
end if;
|
end if;
|
||||||
end process sync;
|
end process sync;
|
||||||
|
|
||||||
task_state <= current_task_state;
|
task_state <= current_task_state;
|
||||||
|
|
||||||
end architecture rtl;
|
end architecture rtl;
|
||||||
|
|
||||||
|
|||||||
@ -1,77 +1,256 @@
|
|||||||
library ieee;
|
library ieee;
|
||||||
use ieee.std_logic_1164.all;
|
use ieee.std_logic_1164.all;
|
||||||
use ieee.numeric_std.all;
|
use ieee.numeric_std.all;
|
||||||
|
|
||||||
library work;
|
library work;
|
||||||
use work.reg32.all;
|
use work.reg32.all;
|
||||||
use work.float.all;
|
use work.float.all;
|
||||||
use work.task.all;
|
use work.task.all;
|
||||||
|
|
||||||
entity sine is
|
entity sine is
|
||||||
port (
|
port (
|
||||||
clk : in std_logic;
|
clk : in std_logic;
|
||||||
reset : in std_logic;
|
reset : in std_logic;
|
||||||
|
|
||||||
task_start : in std_logic;
|
task_start : in std_logic;
|
||||||
task_state : out work.task.State;
|
task_state : out work.task.State;
|
||||||
|
|
||||||
step_size : in work.reg32.word;
|
step_size : in work.reg32.word;
|
||||||
phase : in work.reg32.word;
|
phase : in work.reg32.word;
|
||||||
amplitude : in work.reg32.word;
|
amplitude : in work.reg32.word;
|
||||||
|
|
||||||
signal_write : out std_logic;
|
signal_write : out std_logic;
|
||||||
signal_writedata : out std_logic_vector( 31 downto 0 )
|
signal_writedata : out std_logic_vector(31 downto 0)
|
||||||
);
|
);
|
||||||
end entity sine;
|
end entity;
|
||||||
|
|
||||||
architecture rtl of sine is
|
architecture rtl of sine is
|
||||||
|
|
||||||
signal current_task_state : work.task.State;
|
-- Task FSM states
|
||||||
signal next_task_state : work.task.State;
|
|
||||||
signal index : integer range 0 to work.task.STREAM_LEN;
|
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-1 := 0;
|
||||||
|
|
||||||
|
-- Rising-edge detector (only task_start_d is registered)
|
||||||
|
signal task_start_d : std_logic := '0';
|
||||||
|
signal task_start_re : std_logic;
|
||||||
|
|
||||||
|
-- float_sine IP core
|
||||||
|
signal fs_data_valid : std_logic := '0';
|
||||||
|
signal fs_busy : std_logic;
|
||||||
|
signal fs_result_valid : std_logic;
|
||||||
|
|
||||||
|
signal fs_angle : signed(31 downto 0) := (others => '0');
|
||||||
|
signal fs_sine : signed(31 downto 0);
|
||||||
|
|
||||||
|
-- Data pipeline
|
||||||
|
|
||||||
|
signal angle_reg : signed(31 downto 0) := (others => '0');
|
||||||
|
signal sine_raw_fp : std_logic_vector(31 downto 0) := (others => '0');
|
||||||
|
signal sine_scaled_fp : std_logic_vector(31 downto 0) := (others => '0');
|
||||||
|
|
||||||
|
-- Calculation FSM
|
||||||
|
|
||||||
|
type calc_state_t is (
|
||||||
|
C_IDLE,
|
||||||
|
C_PREPARE,
|
||||||
|
C_START,
|
||||||
|
C_WAIT,
|
||||||
|
C_SCALE,
|
||||||
|
C_WRITE
|
||||||
|
);
|
||||||
|
signal calc_state : calc_state_t := C_IDLE;
|
||||||
|
|
||||||
|
-- Pipeline warm-up fix (CORDIC output invalid on first result_valid)
|
||||||
|
signal first_result_seen : std_logic := '0';
|
||||||
|
|
||||||
begin
|
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
|
-- combinational rising-edge detect (1-cycle faster than registered pulse)
|
||||||
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_start_re <= task_start and not task_start_d;
|
||||||
|
|
||||||
|
-- Output current task state
|
||||||
|
|
||||||
task_state <= current_task_state;
|
task_state <= current_task_state;
|
||||||
|
|
||||||
end architecture rtl;
|
-- Task FSM (combinational)
|
||||||
|
|
||||||
|
task_fsm : 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 - 1) 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,
|
||||||
|
busy => fs_busy,
|
||||||
|
result_valid => fs_result_valid,
|
||||||
|
angle => fs_angle,
|
||||||
|
sine => fs_sine
|
||||||
|
);
|
||||||
|
|
||||||
|
sync : process(clk, reset)
|
||||||
|
variable sin_exp : unsigned(7 downto 0);
|
||||||
|
variable amp_exp : unsigned(7 downto 0);
|
||||||
|
variable new_exp : unsigned(7 downto 0);
|
||||||
|
|
||||||
|
variable sin_e_i : integer;
|
||||||
|
variable amp_e_i : integer;
|
||||||
|
variable new_e_i : integer;
|
||||||
|
begin
|
||||||
|
if reset = '1' then
|
||||||
|
|
||||||
|
current_task_state <= work.task.TASK_IDLE;
|
||||||
|
index <= 0;
|
||||||
|
|
||||||
|
task_start_d <= '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');
|
||||||
|
|
||||||
|
first_result_seen <= '0';
|
||||||
|
|
||||||
|
elsif rising_edge(clk) then
|
||||||
|
|
||||||
|
task_start_d <= task_start;
|
||||||
|
|
||||||
|
-- Default outputs
|
||||||
|
|
||||||
|
signal_write <= '0';
|
||||||
|
fs_data_valid <= '0';
|
||||||
|
|
||||||
|
-- Update Task FSM
|
||||||
|
current_task_state <= next_task_state;
|
||||||
|
|
||||||
|
-- Index update
|
||||||
|
|
||||||
|
case current_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 - 1 then
|
||||||
|
index <= index + 1;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
when work.task.TASK_DONE =>
|
||||||
|
index <= 0;
|
||||||
|
|
||||||
|
end case;
|
||||||
|
|
||||||
|
-- Calculation FSM
|
||||||
|
|
||||||
|
case calc_state is
|
||||||
|
|
||||||
|
when C_IDLE =>
|
||||||
|
if current_task_state = work.task.TASK_RUNNING then
|
||||||
|
angle_reg <= signed(phase);
|
||||||
|
first_result_seen <= '0';
|
||||||
|
calc_state <= C_PREPARE;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
when C_PREPARE =>
|
||||||
|
calc_state <= C_START;
|
||||||
|
|
||||||
|
when C_START =>
|
||||||
|
if fs_busy = '0' then
|
||||||
|
fs_data_valid <= '1';
|
||||||
|
calc_state <= C_WAIT;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
when C_WAIT =>
|
||||||
|
if fs_result_valid = '1' then
|
||||||
|
|
||||||
|
|
||||||
|
if first_result_seen = '0' then
|
||||||
|
first_result_seen <= '1';
|
||||||
|
angle_reg <= angle_reg + signed(step_size);
|
||||||
|
calc_state <= C_START;
|
||||||
|
else
|
||||||
|
sine_raw_fp <= std_logic_vector(fs_sine);
|
||||||
|
calc_state <= C_SCALE;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
end if;
|
||||||
|
|
||||||
|
when C_SCALE =>
|
||||||
|
|
||||||
|
sin_exp := unsigned(sine_raw_fp(30 downto 23));
|
||||||
|
amp_exp := unsigned(amplitude(30 downto 23));
|
||||||
|
|
||||||
|
sin_e_i := to_integer(sin_exp);
|
||||||
|
amp_e_i := to_integer(amp_exp);
|
||||||
|
|
||||||
|
new_e_i := sin_e_i + (amp_e_i - 127);
|
||||||
|
|
||||||
|
if new_e_i < 0 then
|
||||||
|
new_exp := (others => '0');
|
||||||
|
else
|
||||||
|
new_exp := to_unsigned(new_e_i, 8);
|
||||||
|
end if;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
when C_WRITE =>
|
||||||
|
|
||||||
|
signal_write <= '1';
|
||||||
|
signal_writedata <= sine_scaled_fp;
|
||||||
|
|
||||||
|
if index = work.task.STREAM_LEN - 1 then
|
||||||
|
calc_state <= C_IDLE;
|
||||||
|
else
|
||||||
|
angle_reg <= angle_reg + signed(step_size);
|
||||||
|
calc_state <= C_START;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
end case;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
end architecture;
|
||||||
|
|
||||||
|
|||||||
@ -3,10 +3,37 @@
|
|||||||
#include "system/data_channel.h"
|
#include "system/data_channel.h"
|
||||||
#include "system/float_word.h"
|
#include "system/float_word.h"
|
||||||
|
|
||||||
int task_rand_run( void * task ) {
|
int task_rand_run(void *task)
|
||||||
|
{
|
||||||
|
rand_config *config = (rand_config *)task;
|
||||||
|
|
||||||
// TODO
|
uint32_t data_channel_base = config->base.sink;
|
||||||
|
data_channel_clear(data_channel_base);
|
||||||
|
|
||||||
|
float_word seed_fw = { .value = config->seed };
|
||||||
|
uint32_t lfsr = seed_fw.word;
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < DATA_CHANNEL_DEPTH; ++i) {
|
||||||
|
|
||||||
|
uint32_t sign = (lfsr >> 31) & 0x1u;
|
||||||
|
uint32_t mant = lfsr & 0x007FFFFFu; // 23 Bit Mantisse
|
||||||
|
uint32_t exp_rand = (lfsr >> 23) & 0xFFu; // 8 Bit Exponent
|
||||||
|
|
||||||
|
uint32_t exp_new;
|
||||||
|
if (exp_rand & 0x80u) {
|
||||||
|
exp_new = 0x80u | (exp_rand & 0x01u);
|
||||||
|
} else {
|
||||||
|
exp_new = 0x7Cu | (exp_rand & 0x03u);
|
||||||
|
}
|
||||||
|
|
||||||
|
float_word out;
|
||||||
|
out.word = (sign << 31) | (exp_new << 23) | mant;
|
||||||
|
|
||||||
|
data_channel_write(data_channel_base, out.word);
|
||||||
|
|
||||||
|
uint32_t fb = ((lfsr >> 31) ^ (lfsr >> 21) ^ (lfsr >> 1) ^ (lfsr >> 0)) & 0x1u;
|
||||||
|
lfsr = (lfsr << 1) | fb;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user