4.Test
This commit is contained in:
parent
c90753aa23
commit
4d0bb79521
@ -1,77 +1,195 @@
|
||||
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.task.all;
|
||||
use work.reg32.all;
|
||||
use work.task.all;
|
||||
|
||||
entity add is
|
||||
port (
|
||||
clk : in std_logic;
|
||||
reset : 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;
|
||||
task_state : out work.task.State;
|
||||
|
||||
signal_a_read : out std_logic;
|
||||
signal_a_readdata : in std_logic_vector( 31 downto 0 );
|
||||
signal_a_read : out std_logic;
|
||||
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_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 )
|
||||
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;
|
||||
|
||||
-- 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-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
|
||||
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;
|
||||
-- combinational rising edge detect
|
||||
task_start_re <= task_start and not task_start_d;
|
||||
|
||||
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;
|
||||
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
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.task.all;
|
||||
use work.reg32.all;
|
||||
use work.task.all;
|
||||
|
||||
entity rand is
|
||||
port (
|
||||
@ -16,17 +16,21 @@ entity rand is
|
||||
seed : in work.reg32.word;
|
||||
|
||||
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;
|
||||
|
||||
architecture rtl of rand 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 := 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;
|
||||
|
||||
signal lfsr : std_logic_vector(31 downto 0) := (others => '0');
|
||||
|
||||
begin
|
||||
-- task_state_transitions
|
||||
task_state_transitions : process ( current_task_state, task_start, index ) is
|
||||
begin
|
||||
next_task_state <= current_task_state;
|
||||
@ -47,27 +51,92 @@ begin
|
||||
end process task_state_transitions;
|
||||
|
||||
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
|
||||
if ( reset = '1' ) then
|
||||
current_task_state <= work.task.TASK_IDLE;
|
||||
index <= 0;
|
||||
elsif ( rising_edge( clk ) ) then
|
||||
index <= 0;
|
||||
lfsr <= (others => '0');
|
||||
signal_write <= '0';
|
||||
signal_writedata <= (others => '0');
|
||||
|
||||
elsif rising_edge( clk ) then
|
||||
-- State-Register
|
||||
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;
|
||||
|
||||
-- Defaults (wichtig für assert_level)
|
||||
signal_write <= '0';
|
||||
signal_writedata <= (others => '0');
|
||||
|
||||
-- Datapath-Steuerung:
|
||||
-- RUNNING-Aktionen ausführen, wenn
|
||||
-- a) gerade RUNNING sind (auch wenn next schon DONE ist -> letztes Sample!)
|
||||
-- b) in RUNNING eintreten (IDLE/DONE -> RUNNING)
|
||||
entering := (current_task_state /= work.task.TASK_RUNNING) and (next_task_state = work.task.TASK_RUNNING);
|
||||
do_run := (current_task_state = work.task.TASK_RUNNING) or entering;
|
||||
|
||||
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 process sync;
|
||||
|
||||
task_state <= current_task_state;
|
||||
|
||||
end architecture rtl;
|
||||
|
||||
|
||||
@ -1,77 +1,256 @@
|
||||
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;
|
||||
|
||||
step_size : in work.reg32.word;
|
||||
phase : in work.reg32.word;
|
||||
phase : in work.reg32.word;
|
||||
amplitude : in work.reg32.word;
|
||||
|
||||
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;
|
||||
end entity;
|
||||
|
||||
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 states
|
||||
|
||||
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
|
||||
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;
|
||||
-- combinational rising-edge detect (1-cycle faster than registered pulse)
|
||||
|
||||
task_start_re <= task_start and not task_start_d;
|
||||
|
||||
-- Output 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/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;
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user