Skip to content

Commit

Permalink
Corrections on SCOM and FTDI
Browse files Browse the repository at this point in the history
  • Loading branch information
rodmarfran committed Apr 6, 2021
1 parent c2b0d2f commit fd0254f
Show file tree
Hide file tree
Showing 8 changed files with 509 additions and 485 deletions.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -4,49 +4,51 @@ use ieee.numeric_std.all;

package ftdi_irq_manager_pkg is

type t_ftdi_rx_irq_manager_watches is record
rx_buffer_empty : std_logic;
rly_hccd_last_rx_buffer : std_logic;
rx_hccd_comm_err_state : std_logic;
end record t_ftdi_rx_irq_manager_watches;

type t_ftdi_rx_irq_manager_flags is record
rx_hccd_received : std_logic;
rx_hccd_comm_err : std_logic;
end record t_ftdi_rx_irq_manager_flags;

constant c_FTDI_RX_IRQ_MANAGER_WATCHES_RST : t_ftdi_rx_irq_manager_watches := (
rx_buffer_empty => '0',
rly_hccd_last_rx_buffer => '0',
rx_hccd_comm_err_state => '0'
);

constant c_FTDI_RX_IRQ_MANAGER_FLAGS_RST : t_ftdi_rx_irq_manager_flags := (
rx_hccd_received => '0',
rx_hccd_comm_err => '0'
);

--

type t_ftdi_tx_irq_manager_watches is record
tx_lut_transmitted : std_logic;
tx_lut_comm_err_state : std_logic;
end record t_ftdi_tx_irq_manager_watches;

type t_ftdi_tx_irq_manager_flags is record
tx_lut_finished : std_logic;
tx_lut_comm_err : std_logic;
end record t_ftdi_tx_irq_manager_flags;

constant c_FTDI_TX_IRQ_MANAGER_WATCHES_RST : t_ftdi_tx_irq_manager_watches := (
tx_lut_transmitted => '0',
tx_lut_comm_err_state => '0'
);

constant c_FTDI_TX_IRQ_MANAGER_FLAGS_RST : t_ftdi_tx_irq_manager_flags := (
tx_lut_finished => '0',
tx_lut_comm_err => '0'
);
type t_ftdi_rx_irq_manager_watches is record
-- rx_buffer_empty : std_logic;
rly_hccd_last_rx_buffer : std_logic;
avm_controller_wr_finished : std_logic;
rx_hccd_comm_err_state : std_logic;
end record t_ftdi_rx_irq_manager_watches;

type t_ftdi_rx_irq_manager_flags is record
rx_hccd_received : std_logic;
rx_hccd_comm_err : std_logic;
end record t_ftdi_rx_irq_manager_flags;

constant c_FTDI_RX_IRQ_MANAGER_WATCHES_RST : t_ftdi_rx_irq_manager_watches := (
-- rx_buffer_empty => '0',
rly_hccd_last_rx_buffer => '0',
avm_controller_wr_finished => '0',
rx_hccd_comm_err_state => '0'
);

constant c_FTDI_RX_IRQ_MANAGER_FLAGS_RST : t_ftdi_rx_irq_manager_flags := (
rx_hccd_received => '0',
rx_hccd_comm_err => '0'
);

--

type t_ftdi_tx_irq_manager_watches is record
tx_lut_transmitted : std_logic;
tx_lut_comm_err_state : std_logic;
end record t_ftdi_tx_irq_manager_watches;

type t_ftdi_tx_irq_manager_flags is record
tx_lut_finished : std_logic;
tx_lut_comm_err : std_logic;
end record t_ftdi_tx_irq_manager_flags;

constant c_FTDI_TX_IRQ_MANAGER_WATCHES_RST : t_ftdi_tx_irq_manager_watches := (
tx_lut_transmitted => '0',
tx_lut_comm_err_state => '0'
);

constant c_FTDI_TX_IRQ_MANAGER_FLAGS_RST : t_ftdi_tx_irq_manager_flags := (
tx_lut_finished => '0',
tx_lut_comm_err => '0'
);

end package ftdi_irq_manager_pkg;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,93 +5,102 @@ use ieee.numeric_std.all;
use work.ftdi_irq_manager_pkg.all;

entity ftdi_rx_irq_manager_ent is
port(
clk_i : in std_logic;
rst_i : in std_logic;
irq_manager_stop_i : in std_logic;
irq_manager_start_i : in std_logic;
global_irq_en_i : in std_logic;
irq_watches_i : in t_ftdi_rx_irq_manager_watches;
irq_flags_en_i : in t_ftdi_rx_irq_manager_flags;
irq_flags_clr_i : in t_ftdi_rx_irq_manager_flags;
irq_flags_o : out t_ftdi_rx_irq_manager_flags;
irq_o : out std_logic
);
port(
clk_i : in std_logic;
rst_i : in std_logic;
irq_manager_stop_i : in std_logic;
irq_manager_start_i : in std_logic;
global_irq_en_i : in std_logic;
irq_watches_i : in t_ftdi_rx_irq_manager_watches;
irq_flags_en_i : in t_ftdi_rx_irq_manager_flags;
irq_flags_clr_i : in t_ftdi_rx_irq_manager_flags;
irq_flags_o : out t_ftdi_rx_irq_manager_flags;
irq_o : out std_logic
);
end entity ftdi_rx_irq_manager_ent;

architecture RTL of ftdi_rx_irq_manager_ent is

signal s_irq_manager_started : std_logic;
signal s_irq_watches_delayed : t_ftdi_rx_irq_manager_watches;
signal s_irq_flags : t_ftdi_rx_irq_manager_flags;
signal s_irq_manager_started : std_logic;
signal s_irq_watches_delayed : t_ftdi_rx_irq_manager_watches;
signal s_irq_flags : t_ftdi_rx_irq_manager_flags;

signal s_rx_payload_written_flag : std_logic;
signal s_rx_payload_written_flag : std_logic;
signal s_avm_controller_wr_finished : std_logic;

begin

p_ftdi_rx_irq_manager : process(clk_i, rst_i) is
begin
if (rst_i = '1') then

s_irq_manager_started <= '0';
s_irq_watches_delayed <= c_FTDI_RX_IRQ_MANAGER_WATCHES_RST;
s_irq_flags <= c_FTDI_RX_IRQ_MANAGER_FLAGS_RST;

s_rx_payload_written_flag <= '0';

elsif (rising_edge(clk_i)) then

-- manage start/stop
if (irq_manager_start_i = '1') then
s_irq_manager_started <= '1';
elsif (irq_manager_stop_i = '1') then
s_irq_manager_started <= '0';
end if;

-- manage flags
if (s_irq_manager_started = '0') then
-- keep flags cleared
s_irq_flags <= c_FTDI_RX_IRQ_MANAGER_FLAGS_RST;
s_rx_payload_written_flag <= '0';
else
-- clear flags --
if (irq_flags_clr_i.rx_hccd_received = '1') then
s_rx_payload_written_flag <= '0';
s_irq_flags.rx_hccd_received <= '0';
end if;
if (irq_flags_clr_i.rx_hccd_comm_err = '1') then
s_irq_flags.rx_hccd_comm_err <= '0';
end if;
-- set flags --
-- check if the global interrupt is enabled
if (global_irq_en_i = '1') then
if (irq_flags_en_i.rx_hccd_received = '1') then

if ((s_irq_watches_delayed.rly_hccd_last_rx_buffer = '0') and (irq_watches_i.rly_hccd_last_rx_buffer = '1')) then
s_rx_payload_written_flag <= '1';
end if;
if ((s_irq_watches_delayed.rx_buffer_empty = '0') and (irq_watches_i.rx_buffer_empty = '1') and (s_rx_payload_written_flag = '1')) then
s_irq_flags.rx_hccd_received <= '1';
end if;
end if;
if (irq_flags_en_i.rx_hccd_comm_err = '1') then
if ((s_irq_watches_delayed.rx_hccd_comm_err_state = '0') and (irq_watches_i.rx_hccd_comm_err_state = '1')) then
s_irq_flags.rx_hccd_comm_err <= '1';
end if;
end if;
end if;
end if;

-- delay signals
s_irq_watches_delayed <= irq_watches_i;

end if;
end process p_ftdi_rx_irq_manager;

-- irq assignment and outputs generation
irq_flags_o <= s_irq_flags;
irq_o <= ('0') when (rst_i = '1')
else ('1') when ((s_irq_flags.rx_hccd_received = '1') or (s_irq_flags.rx_hccd_comm_err = '1'))
else ('0');
p_ftdi_rx_irq_manager : process(clk_i, rst_i) is
begin
if (rst_i = '1') then

s_irq_manager_started <= '0';
s_irq_watches_delayed <= c_FTDI_RX_IRQ_MANAGER_WATCHES_RST;
s_irq_flags <= c_FTDI_RX_IRQ_MANAGER_FLAGS_RST;

s_rx_payload_written_flag <= '0';
s_avm_controller_wr_finished <= '0';

elsif (rising_edge(clk_i)) then

-- manage start/stop
if (irq_manager_start_i = '1') then
s_irq_manager_started <= '1';
elsif (irq_manager_stop_i = '1') then
s_irq_manager_started <= '0';
end if;

-- manage flags
if (s_irq_manager_started = '0') then
-- keep flags cleared
s_irq_flags <= c_FTDI_RX_IRQ_MANAGER_FLAGS_RST;
s_rx_payload_written_flag <= '0';
else
-- clear flags --
if (irq_flags_clr_i.rx_hccd_received = '1') then
s_rx_payload_written_flag <= '0';
s_irq_flags.rx_hccd_received <= '0';
end if;
if (irq_flags_clr_i.rx_hccd_comm_err = '1') then
s_irq_flags.rx_hccd_comm_err <= '0';
end if;
-- set flags --
-- check if the global interrupt is enabled
if (global_irq_en_i = '1') then
if (irq_flags_en_i.rx_hccd_received = '1') then
if ((s_irq_watches_delayed.rly_hccd_last_rx_buffer = '0') and (irq_watches_i.rly_hccd_last_rx_buffer = '1')) then
s_rx_payload_written_flag <= '1';
end if;
-- if ((s_irq_watches_delayed.rx_buffer_empty = '0') and (irq_watches_i.rx_buffer_empty = '1') and (s_rx_payload_written_flag = '1')) then
-- s_irq_flags.rx_hccd_received <= '1';
-- end if;
if ((s_irq_watches_delayed.avm_controller_wr_finished = '0') and (irq_watches_i.avm_controller_wr_finished = '1')) then
s_avm_controller_wr_finished <= '1';
end if;
if ((s_rx_payload_written_flag = '1') and (s_avm_controller_wr_finished = '1')) then
s_irq_flags.rx_hccd_received <= '1';
s_rx_payload_written_flag <= '0';
s_avm_controller_wr_finished <= '0';
end if;
end if;
if (irq_flags_en_i.rx_hccd_comm_err = '1') then
if ((s_irq_watches_delayed.rx_hccd_comm_err_state = '0') and (irq_watches_i.rx_hccd_comm_err_state = '1')) then
s_irq_flags.rx_hccd_comm_err <= '1';
end if;
end if;
end if;
end if;

-- delay signals
s_irq_watches_delayed <= irq_watches_i;

end if;
end process p_ftdi_rx_irq_manager;

-- irq assignment and outputs generation
irq_flags_o <= s_irq_flags;
irq_o <= ('0') when (rst_i = '1')
else ('1') when ((s_irq_flags.rx_hccd_received = '1') or (s_irq_flags.rx_hccd_comm_err = '1'))
else ('0');

end architecture RTL;
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,8 @@ architecture RTL of ftdi_rx_protocol_payload_reader_ent is

signal s_payload_write_flag : std_logic;
signal s_force_payload_length_flag : std_logic;
signal s_registered_forced_length_bytes : unsigned(31 downto 0);
signal s_registered_forced_length_bytes : unsigned(26 downto 0); -- 2^32 bytes of maximum length / 32 bytes per write = 2^27 maximum write length
constant c_FORCED_LENGTH_BYTES_ZERO : unsigned((s_registered_forced_length_bytes'length - 1) downto 0) := (others => '0');

signal s_qqword_delay_clear : std_logic;
signal s_qqword_delay_trigger : std_logic;
Expand Down Expand Up @@ -221,12 +222,12 @@ begin
v_ftdi_tx_prot_payload_reader_state := WAITING_RX_DATA_EOP;
end if;
-- check if the payload length need to be forced to a specific length
if (payload_force_length_bytes_i /= x"00000000") then
if ((payload_force_length_bytes_i /= x"00000000") and (payload_force_length_bytes_i /= payload_length_bytes_i)) then
-- the payload length need to be forced to a specific length
-- set the force payload length flag
s_force_payload_length_flag <= '1';
-- register the forced payload length
s_registered_forced_length_bytes <= unsigned(payload_force_length_bytes_i);
-- register the forced payload length to (forced payload length / 32)
s_registered_forced_length_bytes <= unsigned(payload_force_length_bytes_i(31 downto 5));
end if;
end if;

Expand Down Expand Up @@ -713,7 +714,7 @@ begin
if (s_force_payload_length_flag = '1') then
-- the payload need to be forced to a specific length
-- check if the payload has passed the forced length
if (s_registered_forced_length_bytes <= 32) then
if (s_registered_forced_length_bytes <= 1) then
-- the payload has passed the forced length
-- clear the payload write flag
s_payload_write_flag <= '0';
Expand All @@ -724,7 +725,7 @@ begin
else
-- the payload has passed not the forced length
-- decrement the 32 bytes written to the buffer
s_registered_forced_length_bytes <= s_registered_forced_length_bytes - 32;
s_registered_forced_length_bytes <= s_registered_forced_length_bytes - 1;
end if;
end if;
-- check if the rx data buffer is full
Expand Down Expand Up @@ -887,7 +888,7 @@ begin
if (s_force_payload_length_flag = '1') then
-- the payload need to be forced to a specific length
-- check if the payload need to be filled with zeros
if (s_registered_forced_length_bytes /= x"00000000") then
if (s_registered_forced_length_bytes /= c_FORCED_LENGTH_BYTES_ZERO) then
-- the payload need to be filled with zeros
-- go to payload wating fill
s_ftdi_tx_prot_payload_reader_state <= PAYLOAD_WAITING_FILL;
Expand Down Expand Up @@ -955,15 +956,15 @@ begin
v_mask_cnt := 0;
-- conditional state transition
-- check if the zero fill ended
if (s_registered_forced_length_bytes <= 32) then
if (s_registered_forced_length_bytes <= 1) then
-- the zero fill ended
-- go to finish payload rx
s_ftdi_tx_prot_payload_reader_state <= FINISH_PAYLOAD_RX;
v_ftdi_tx_prot_payload_reader_state := FINISH_PAYLOAD_RX;
else
-- the zero fill has not ended
-- decrement the 32 bytes written to the buffer
s_registered_forced_length_bytes <= s_registered_forced_length_bytes - 32;
s_registered_forced_length_bytes <= s_registered_forced_length_bytes - 1;
-- go to payload wating fill
s_ftdi_tx_prot_payload_reader_state <= PAYLOAD_DELAY_FILL;
v_ftdi_tx_prot_payload_reader_state := PAYLOAD_DELAY_FILL;
Expand Down
Loading

0 comments on commit fd0254f

Please sign in to comment.