Select Git revision
uart_xstep_timer.vhd
uart_xstep_timer.vhd 15.31 KiB
----------------------------------------------------------------------------------
--
-- Project : ModNEF
-- Component name : uart_xstep
-- Depencies : uart_controller
--
-- Authors : Aurelie Saulquin
-- Email : aurelie.saulquin@univ-lille.fr
--
-- Version : 1.0
-- Version comment : stable version
--
-- Licenses : cern-ohl-s-2.0
--
-- Description :
-- UART component where one data transmission(read/write) is use for multiple
-- emulation step. The first data read from uart controller is the number of data
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use work.math.all;
entity Uart_XStep_Timer is
generic(
clk_freq : integer := 100_000_000;
baud_rate : integer := 115_200;
queue_read_depth : integer := 32;
queue_read_width : integer := 1;
queue_write_depth : integer := 32;
input_layer_size : integer := 8;
output_layer_size : integer := 8
);
port (
i_clk : in std_logic;
i_en : in std_logic;
i_tx : in std_logic;
o_rx : out std_logic;
i_emu_ready : in std_logic;
o_start_emu : out std_logic;
o_reset_membrane : out std_logic;
i_req : in std_logic;
o_ack : out std_logic;
i_emu_busy : in std_logic;
i_spike_flag : in std_logic;
i_aer : in std_logic_vector(log_b(output_layer_size, 2)-1 downto 0);
o_req : out std_logic;
i_ack : in std_logic;
o_emu_busy : out std_logic;
o_spike_flag : out std_logic;
o_aer : out std_logic_vector(log_b(input_layer_size, 2)-1 downto 0)
);
end Uart_XStep_Timer;
architecture Behavioral of Uart_XStep_Timer is
component uart_controller is
generic(
clk_freq : integer := 100_000_000;
baud_rate : integer := 115_200;
oversamp_rate : integer := 16;
queue_read_depth : integer := 64;
queue_read_width : integer := 1;
queue_read_type : string := "fifo";
queue_write_depth : integer := 16;
queue_write_width : integer := 1;
queue_write_type : string := "fifo" -- fifo or lifo
);
port(
i_clk : in std_logic;
i_en : in std_logic;
o_busy : out std_logic;
o_reset_detected : out std_logic;
-- UART pins
i_tx : in std_logic;
o_rx : out std_logic;
o_uart_busy : out std_logic;
-- read I/O
o_read_data : out std_logic_vector(queue_read_width*8-1 downto 0);
i_read_pop : in std_logic;
o_read_busy : out std_logic;
o_read_queue_empty : out std_logic;
o_read_queue_full : out std_logic;
-- write I/O
i_start_transmission : in std_logic;
i_write_data : in std_logic_vector(queue_write_width*8-1 downto 0);
i_write_push : in std_logic;
o_write_busy : out std_logic;
o_write_queue_empty : out std_logic;
o_write_queue_full : out std_logic
);
end component;
-- type definition
type emu_state_t is (idle, wait_data, check_emu, emulate, wait_out_aer, send_aer, wait_transmission, push_timer, push_timer_2, start_tr);
type uart_to_network_state_t is (idle, check_data, get_data_number, request, accept, transfert);
type network_to_uart_state_t is (idle, wait_request, accept, wait_aer, push_data_number);
-- queue constant
constant queue_write_width : integer := log_b(output_layer_size, 256);
-- read queue signals
signal read_data : std_logic_vector(queue_read_width*8-1 downto 0) := (others=>'0');
signal read_pop : std_logic := '0';
signal read_busy : std_logic;
signal read_empty : std_logic;
-- write queue signals
signal write_data : std_logic_vector(queue_write_width*8-1 downto 0) := (others=>'0');
signal write_aer_buffer : std_logic_vector(queue_write_width*8-1 downto 0) := (others=>'0');
signal write_push : std_logic := '0';
signal write_busy : std_logic;
signal write_empty : std_logic;
-- UART signals
signal start_uart_transmission : std_logic := '0';
-- emulation signals
signal emu_state : emu_state_t := idle;
signal start_emu : std_logic;
-- uart to network signals
signal uart_to_network_state : uart_to_network_state_t := idle;
signal uart_to_network_busy : std_logic := '0';
-- network to uart signals
signal network_to_uart_data_number : std_logic_vector(queue_write_width*8-1 downto 0) := (others=>'0');
signal network_to_uart_state : network_to_uart_state_t := idle;
signal network_to_uart_busy : std_logic := '0';
-- membrane reset signals
signal reset_detected : std_logic := '0';
signal reset_membrane : std_logic := '0';
-- timer signals
constant timer_width : integer := 2;
signal timer : std_logic_vector(timer_width*8-1 downto 0) := (others=>'0');
signal count_time : std_logic := '0';
signal reset_timer : std_logic := '0';
signal timer_data : std_logic_vector(queue_write_width*8-1 downto 0) := (others=>'0');
signal timer_byte_counter : integer := 0;
--constant z : std_logic_vector(queue_write_width*8-1-7 downto 0) := (others=>'0');
begin
o_start_emu <= start_emu;
o_reset_membrane <= reset_membrane;
process(i_clk)
begin
if rising_edge(i_clk) then
if count_time = '1' then
timer <= std_logic_vector(unsigned(timer)+1);
elsif reset_timer='1' then
timer <= (others=>'0');
end if;
end if;
end process;
-- controller FSM
process(i_clk, i_en)
begin
if i_en = '0' then
emu_state <= idle;
start_emu <= '0';
start_uart_transmission <= '0';
else
if rising_edge(i_clk) then
case emu_state is
when idle =>
start_emu <= '0';
start_uart_transmission <= '0';
reset_membrane <= '0';
reset_timer <= '1';
count_time <= '0';
timer_byte_counter <= 0;
if read_busy = '1' then
emu_state <= wait_data;
else
emu_state <= idle;
end if;
when wait_data =>
reset_timer <= '0';
if read_busy = '0' then
emu_state <= check_emu;
else
emu_state <= wait_data;
end if;
when check_emu =>
if i_emu_ready = '1' then
emu_state <= emulate;
start_emu <= '1';
count_time <= '1';
else
emu_state <= check_emu;
end if;
when emulate =>
start_emu <= '0';
if network_to_uart_busy = '1' then
emu_state <= wait_out_aer;
else
emu_state <= emulate;
end if;
when wait_out_aer =>
if i_emu_ready = '1' and network_to_uart_busy='0' then
count_time <= '0';
if read_empty = '1' then -- no more data to process
emu_state <= push_timer;
--timer_data(7 downto 0) <= timer(7 downto 0);
reset_membrane <= reset_detected;
else
emu_state <= check_emu;
end if;
else
emu_state <= wait_out_aer;
end if;
when push_timer =>
--timer_data(7 downto 0) <= timer(7 downto 0);
emu_state <= push_timer_2;
when push_timer_2 =>
--timer_data(7 downto 0) <= timer(15 downto 8);
emu_state <= start_tr;
when start_tr =>
start_uart_transmission <= '1';
emu_state <= send_aer;
when send_aer =>
start_uart_transmission <= '0';
reset_membrane <= '0';
if write_busy = '1' then
emu_state <= wait_transmission;
else
emu_state <= send_aer;
end if;
when wait_transmission =>
reset_membrane <= '0';
if write_busy = '0' then
emu_state <= idle;
else
emu_state <= wait_transmission;
end if;
end case;
end if;
end if;
end process;
-- Controller to network FSM
--o_aer <= read_data(log_b(input_layer_size, 2)-1 downto 0) when uart_to_network_state = transfert else (others=>'0');
process(i_clk, i_en)
variable data_counter : integer range 0 to queue_read_depth := 0;
variable uart_to_network_data_number : integer range 0 to queue_read_depth := 0;
begin
if rising_edge(i_clk) then
if i_en = '0' then
o_req <= '0';
o_spike_flag <= '0';
o_emu_busy <= '0';
read_pop <= '0';
uart_to_network_busy <= '0';
uart_to_network_state <= idle;
else
case uart_to_network_state is
when idle =>
o_req <= '0';
o_spike_flag <= '0';
read_pop <= '0';
if start_emu = '1' then
uart_to_network_state <= check_data;
o_emu_busy <= '1';
uart_to_network_busy <= '1';
else
uart_to_network_state <= idle;
o_emu_busy <= '0';
uart_to_network_busy <= '0';
end if;
when check_data =>
if read_empty = '1' then
uart_to_network_state <= idle;
o_emu_busy <= '0';
uart_to_network_busy <= '0';
else
uart_to_network_state <= get_data_number;
read_pop <= '1';
end if;
when get_data_number =>
uart_to_network_state <= transfert;
read_pop <= '0';
data_counter := 0;
uart_to_network_data_number := to_integer(unsigned(read_data));
if uart_to_network_data_number = 0 then
uart_to_network_busy <= '0';
uart_to_network_state <= idle;
else
uart_to_network_state <= request;
o_req <= '1';
end if;
when request =>
if i_ack = '1' then
uart_to_network_state <= accept;
o_req <= '0';
else
uart_to_network_state <= request;
o_req <= '1';
end if;
when accept =>
if i_ack = '0' then
uart_to_network_state <= transfert;
read_pop <= '1';
else
uart_to_network_state <= accept;
end if;
when transfert =>
if data_counter = uart_to_network_data_number then
uart_to_network_state <= idle;
o_emu_busy <= '0';
read_pop <= '0';
o_spike_flag <= '0';
uart_to_network_busy <= '0';
elsif data_counter = uart_to_network_data_number-1 then
read_pop <= '0';
uart_to_network_state <= transfert;
o_spike_flag <= '1';
data_counter := data_counter+1;
o_aer <= read_data(log_b(input_layer_size, 2)-1 downto 0);
else
uart_to_network_state <= transfert;
read_pop <= '1';
o_spike_flag <= '1';
data_counter := data_counter + 1;
o_aer <= read_data(log_b(input_layer_size, 2)-1 downto 0);
end if;
end case;
end if;
end if;
end process;
write_aer_buffer(log_b(output_layer_size, 2)-1 downto 0) <= i_aer;
timer_data <= timer(7 downto 0) when emu_state=push_timer else
timer(15 downto 8) when emu_state = push_timer_2 else
(others=>'0');
write_data <= write_aer_buffer when network_to_uart_state = wait_aer else
network_to_uart_data_number when network_to_uart_state = push_data_number else
timer_data when emu_state=push_timer else
timer_data when emu_state = push_timer_2 else
(others=>'0');
write_push <= i_spike_flag when network_to_uart_state = wait_aer else
'1' when network_to_uart_state = push_data_number else
'1' when emu_state = push_timer else
'1' when emu_state = push_timer_2 else
'0';
process(i_clk, i_en)
variable data_counter : integer range 0 to output_layer_size := 0;
begin
if rising_edge(i_clk) then
if i_en = '0' then
network_to_uart_state <= idle;
network_to_uart_busy <= '0';
o_ack <= '0';
data_counter := 0;
else
case network_to_uart_state is
when idle =>
data_counter := 0;
o_ack <= '0';
if i_emu_busy = '1' then
network_to_uart_state <= wait_request;
network_to_uart_busy <= '1';
else
network_to_uart_state <= idle;
network_to_uart_busy <= '0';
end if;
when wait_request =>
if i_emu_busy = '0' then
network_to_uart_state <= push_data_number;
network_to_uart_data_number <= std_logic_vector(to_unsigned(data_counter, queue_write_width*8));
elsif i_req = '1' then
o_ack <= '1';
network_to_uart_state <= accept;
else
network_to_uart_state <= wait_request;
end if;
when accept =>
if i_req = '0' then
network_to_uart_state <= wait_aer;
o_ack <= '0';
else
network_to_uart_state <= accept;
o_ack <= '1';
end if;
when wait_aer =>
if i_emu_busy = '0' then
network_to_uart_state <= push_data_number;
network_to_uart_data_number <= std_logic_vector(to_unsigned(data_counter, queue_write_width*8));
else
network_to_uart_state <= wait_aer;
if i_spike_flag = '1' then
data_counter := data_counter + 1;
end if;
end if;
when push_data_number =>
network_to_uart_state <= idle;
network_to_uart_busy <= '0';
end case;
end if;
end if;
end process;
c_uart_controller : uart_controller generic map(
clk_freq => clk_freq,
baud_rate => baud_rate,
oversamp_rate => 16,
queue_read_depth => queue_read_depth,
queue_read_width => queue_read_width,
queue_read_type => "fifo",
queue_write_depth => queue_write_depth,
queue_write_width => queue_write_width,
queue_write_type => "lifo"
) port map(
i_clk => i_clk,
i_en => i_en,
o_busy => open,
o_reset_detected => reset_detected,
i_tx => i_tx,
o_rx => o_rx,
o_uart_busy => open,
o_read_data => read_data,
i_read_pop => read_pop,
o_read_busy => read_busy,
o_read_queue_empty => read_empty,
o_read_queue_full => open,
i_start_transmission => start_uart_transmission,
i_write_data => write_data,
i_write_push => write_push,
o_write_busy => write_busy,
o_write_queue_empty => open,
o_write_queue_full => open
);
end Behavioral;