Skip to content
Snippets Groups Projects
Commit 33502b1d authored by Aurélie saulquin's avatar Aurélie saulquin
Browse files

remove single_step uart module

parent 8f8b87a5
Branches
No related tags found
1 merge request!3Dev
----------------------------------------------------------------------------------
--
-- Project : ModNEF
-- Component name : uart_1step
-- 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 is use for one emulation step
-- Component will receive data, send all data to network and receive data
-- from network and transmit it to computer
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
use work.math.all;
entity uart_1Step is
generic(
clk_freq : integer := 100_000_000;
baud_rate : integer := 115_200;
queue_read_depth : integer := 32;
queue_read_type : string := "fifo";
queue_write_type : string := "fifo";
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_1Step;
architecture Behavioral of uart_1Step 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);
type uart_to_network_state_t is (idle, check_emu, request, accept, transfert);
type network_to_uart_state_t is (idle, wait_request, accept, wait_aer);
-- queue constant definition
--constant queue_read_depth : integer := 255;
constant queue_read_width : integer := log_b(queue_read_depth, 256);
constant queue_write_depth : integer := output_layer_size;
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_push : std_logic := '0';
signal write_busy : 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;
-- membrane reset signals
signal reset_detected : std_logic := '0';
signal reset_membrane : std_logic := '0';
-- 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_state : network_to_uart_state_t := idle;
signal network_to_uart_busy : std_logic := '0';
begin
o_start_emu <= start_emu;
o_reset_membrane <= reset_membrane;
-- controller FSM
process(i_clk, i_en)
begin
if rising_edge(i_clk) then
if i_en = '0' then
emu_state <= idle;
start_emu <= '0';
start_uart_transmission <= '0';
else
case emu_state is
when idle =>
start_emu <= '0';
start_uart_transmission <= '0';
reset_membrane <= '0';
if read_busy = '1' then
emu_state <= wait_data;
else
emu_state <= idle;
end if;
when wait_data =>
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';
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' then
emu_state <= send_aer;
start_uart_transmission <= '1';
reset_membrane <= reset_detected;
else
emu_state <= wait_out_aer;
end if;
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 =>
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)
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_emu;
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_emu =>
if read_empty = '1' then
uart_to_network_state <= idle;
o_emu_busy <= '0';
uart_to_network_busy <= '0';
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 read_empty = '1' then
uart_to_network_state <= idle;
o_emu_busy <= '0';
read_pop <= '0';
o_spike_flag <= '0';
uart_to_network_busy <= '0';
else
uart_to_network_state <= transfert;
read_pop <= '1';
o_spike_flag <= '1';
end if;
end case;
end if;
end if;
end process;
write_data(log_b(output_layer_size, 2)-1 downto 0) <= i_aer when network_to_uart_state = wait_aer else (others=>'0');
write_push <= i_spike_flag when network_to_uart_state = wait_aer else '0';
-- Network to Controller FSM
process(i_clk, i_en)
begin
if i_en = '0' then
network_to_uart_state <= idle;
network_to_uart_busy <= '0';
o_ack <= '0';
else
if rising_edge(i_clk) then
case network_to_uart_state is
when idle =>
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 <= idle;
network_to_uart_busy <= '0';
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 <= idle;
network_to_uart_busy <= '0';
else
network_to_uart_state <= wait_aer;
end if;
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 => queue_read_type,
queue_write_depth => queue_write_depth,
queue_write_width => queue_write_width,
queue_write_type => queue_write_type
) 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;
"""
File name: uart_1step
Author: Aurélie Saulquin
Version: 2.0.0
License: GPL-3.0-or-later
Contact: aurelie.saulquin@univ-lille.fr
Dependencies: io_arch, yaml
Descriptions: UART_1Step ModNEF archbuilder module
"""
from ..io_arch import IOArch
import yaml
_UART_1STEP_DEFINITION = """
component uart_1Step is
generic(
clk_freq : integer := 100_000_000;
baud_rate : integer := 115_200;
queue_read_depth : integer := 32;
queue_read_type : string := "fifo";
queue_write_type : string := "fifo";
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 component;
"""
class Uart_1Step(IOArch):
"""
Uart_1Step module class
Each UART transmission correspond to an emulation step
Attributes
----------
name : str
name of module
input_layer_size : int
size in neurons of input layer
output_layer_size : int
size in neurons of output layer
clk_freq : int
board clock frequency
baud_rate : int
data baud rate
queue_read_type : int
type of reaad queue
queue_write_type : int
type of write queue
tx_name : str
name of tx signal
rx_name : str
name of rx signal
Methods
-------
vhdl_component_name()
return component name
vhdl_component_definition()
return vhdl component definition
to_vhdl(vhdl_file, pred, suc, clock_name):
write vhdl component instanciation
to_yaml(file):
generate yaml configuration file for driver
write_io(vhdl_file):
write signals into entity definition section
"""
def __init__(self,
name: str,
input_layer_size: int,
output_layer_size: int,
clk_freq: int,
baud_rate: int,
tx_name: str,
rx_name: str,
queue_read_depth : int,
queue_read_type: str = "fifo",
queue_write_type: str = "fifo"
):
"""
Initialize attributes
Parameters
----------
name : str
name of module
clk_freq : int
board clock frequency
baud_rate : int
data baud rate
tx_name : str
name of tx signal
rx_name : str
name of rx signal
input_layer_size : int = -1
size in neurons of input layer
output_layer_size : int = -1
size in neurons of output layer
queue_read_type : str = "fifo"
read queue type : "fifo" or "lifo"
queue_write_type : str = "fifo"
write queue type : "fifo" or "lifo"
"""
self.name = name
self.input_neuron = output_layer_size
self.output_neuron = input_layer_size
self.input_layer_size = input_layer_size
self.output_layer_size = output_layer_size
self.clk_freq = clk_freq
self.baud_rate = baud_rate
self.queue_read_type = queue_read_type
self.queue_read_depth = queue_read_depth
self.queue_write_type = queue_write_type
self.tx_name = tx_name
self.rx_name = rx_name
def vhdl_component_name(self):
"""
Module identifier use during component definition
Returns
-------
str
"""
return "Uart_1_Step"
def vhdl_component_definition(self):
"""
VHDL component definition
Returns
-------
str
"""
return _UART_1STEP_DEFINITION
def to_vhdl(self, vhdl_file, pred, suc, clock_name):
"""
Write vhdl componenent
Parameters
----------
vhdl_file : TextIOWrapper
vhdl file
pred : List of ModNEFArchMod
list of predecessor module (1 pred for this module)
suc : List of ModNEFArchMod
list of successor module (1 suc for this module)
clock_name : str
clock signal name
"""
vhdl_file.write(f"\t{self.name} : uart_1step generic map(\n")
vhdl_file.write(f"\t\tclk_freq => {self.clk_freq},\n")
vhdl_file.write(f"\t\tbaud_rate => {self.baud_rate},\n")
vhdl_file.write(f"\t\tqueue_read_depth => {self.queue_read_depth},\n")
vhdl_file.write(f"\t\tqueue_read_type => \"{self.queue_read_type}\",\n")
vhdl_file.write(f"\t\tqueue_write_type => \"{self.queue_write_type}\",\n")
vhdl_file.write(f"\t\tinput_layer_size => {self.input_layer_size},\n")
vhdl_file.write(f"\t\toutput_layer_size => {self.output_layer_size}\n")
vhdl_file.write(f"\t) port map(\n")
vhdl_file.write(f"\t\ti_clk => {clock_name},\n")
vhdl_file.write("\t\ti_en => '1',\n")
vhdl_file.write(f"\t\ti_tx => {self.tx_name},\n")
vhdl_file.write(f"\t\to_rx => {self.rx_name},\n")
vhdl_file.write("\t\ti_emu_ready => emu_ready,\n")
vhdl_file.write("\t\to_start_emu => start_emu,\n")
vhdl_file.write("\t\to_reset_membrane => reset_membrane,\n")
self._write_port_map(vhdl_file, pred[0].name, self.name, "in", "", False)
self._write_port_map(vhdl_file, self.name, suc[0].name, "out", "", True)
vhdl_file.write("\t);\n")
def to_yaml(self, file):
"""
Generate yaml driver description file
Parameters
----------
file : str
configuration file name
"""
d = {}
d["module"] = "1Step"
d["input_layer_size"] = self.input_layer_size
d["output_layer_size"] = self.output_layer_size
d["baud_rate"] = self.baud_rate
d["queue_read_depth"] = self.queue_read_depth
d["queue_write_depth"] = self.output_layer_size
with open(file, 'w') as f:
yaml.dump(d, f)
def write_io(self, vhdl_file):
"""
Write port IO in entity definition section
Parameters
----------
vhdl_file : TextIOWrapper
vhdl file
"""
vhdl_file.write(f"\t\t{self.tx_name} : in std_logic;\n")
vhdl_file.write(f"\t\t{self.rx_name} : out std_logic\n")
"""
File name: single_step_driver
Author: Aurélie Saulquin
Version: 2.0.0
License: GPL-3.0-or-later
Contact: aurelie.saulquin@univ-lille.fr
Dependencies: default_driver, yaml
Descriptions: Driver class for UART_1Step uart module
"""
from .default_driver import default_transformation
from .default_driver import ModNEF_Driver, ClosedDriverError
import yaml
class SingleStep_Driver(ModNEF_Driver):
"""
Driver of Uart_SingleStep module
Attributes
----------
board_path : str
fpga driver board path
baud_rate : int
data baud rate
input_layer_size : int
number of neuron in input layer
output_layer_size : int
number of neuron in output layer
queue_read_depth : int
number of word of read queue
queue_write_depth : int
number of word of write queue
Methods
-------
from_yaml(yaml_file, board_path) : classmethod
create driver from yaml configuration file
run_sample(input_sample, transformation, reset_membrane):
run data communication to run a data sample
"""
def __init__(self, board_path, baud_rate, input_layer_size, output_layer_size, queue_read_depth, queue_write_depth):
"""
Constructor
Parameters
----------
board_path : str
fpga driver board path
baud_rate : int
data baud rate
input_layer_size : int
number of neuron in input layer
output_layer_size : int
number of neuron in output layer
queue_read_depth : int
number of word of read queue
queue_write_depth : int
number of word of write queue
"""
super().__init__(board_path, baud_rate, input_layer_size, output_layer_size, queue_read_depth, queue_write_depth)
@classmethod
def from_yaml(cls, yaml_file, board_path):
"""
classmethod
create driver from driver configuration file
Parameters
----------
yaml_file : str
configuration file
board_path : str
path to board driver
"""
with open(yaml_file, 'r') as f:
config = yaml.safe_load(f)
print("coucou")
d = cls(board_path = board_path,
baud_rate = config["baud_rate"],
input_layer_size = config["input_layer_size"],
output_layer_size = config["output_layer_size"],
queue_read_depth = config["queue_read_depth"],
queue_write_depth = config["queue_write_depth"]
)
return d
def run_sample(self, input_sample, transformation = default_transformation, reset_membrane=False, extra_step = 0):
"""
Run an entire data sample by using run_step function (for more details see run_step)
Parameters
----------
input_sample : list
list of spikes of sample
transformation : function
function call to tranform input spikes to AER representation
reset_membrane : bool
set to true if reset voltage membrane after sample transmission
Returns
-------
list of list of int:
list of list of output AER data for all emulation step
"""
if self._is_close:
raise ClosedDriverError()
sample_res = [0 for _ in range(self.output_layer_size)]
sample_aer = [transformation(s) for s in input_sample]
for es in range(extra_step):
sample_aer.append([])
for step in range(len(input_sample)):
step_spikes = sample_aer[step]
if step == len(input_sample)-1:
step_res = self.rust_driver.data_transmission(step_spikes, reset_membrane)
else:
step_res = self.rust_driver.data_transmission(step_spikes, False)
for s in step_res:
sample_res[s] += 1
return sample_res
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment