Compare commits
6 Commits
08bd5f166b
...
38f96cdc63
Author | SHA1 | Date | |
---|---|---|---|
38f96cdc63 | |||
0133fa8cce | |||
9e5b958f46 | |||
f5f643287f | |||
1f894866ab | |||
5d6df0219b |
@ -37,9 +37,10 @@ begin
|
|||||||
|
|
||||||
receiver : block
|
receiver : block
|
||||||
-- Signal conditioning
|
-- Signal conditioning
|
||||||
signal rx : std_logic;
|
signal rx : std_logic;
|
||||||
signal rx_last : std_logic;
|
signal rx_last : std_logic;
|
||||||
signal rx_edge : std_logic;
|
signal rx_last_static : std_logic;
|
||||||
|
signal rx_edge : std_logic;
|
||||||
|
|
||||||
-- Bit recovery
|
-- Bit recovery
|
||||||
signal bit_value : std_logic;
|
signal bit_value : std_logic;
|
||||||
@ -61,11 +62,23 @@ begin
|
|||||||
data_out => rx
|
data_out => rx
|
||||||
);
|
);
|
||||||
|
|
||||||
-- Edge detector for RX
|
-- Edge detector for RX (+glitch filter)
|
||||||
rx_last <= '0' when rst
|
edgedet : process(clk, rst) is
|
||||||
else rx when rising_edge(clk)
|
begin
|
||||||
;
|
if rst then
|
||||||
rx_edge <= rx_last xor rx;
|
rx_last <= '0';
|
||||||
|
rx_last_static <= '0';
|
||||||
|
rx_edge <= '0';
|
||||||
|
|
||||||
|
elsif rising_edge(clk) then
|
||||||
|
rx_edge <= '0';
|
||||||
|
if (rx_last = rx) then
|
||||||
|
rx_edge <= rx_last_static xor rx;
|
||||||
|
rx_last_static <= rx;
|
||||||
|
end if;
|
||||||
|
rx_last <= rx;
|
||||||
|
end if;
|
||||||
|
end process edgedet;
|
||||||
|
|
||||||
demanchestizer : block
|
demanchestizer : block
|
||||||
-- Transition detector
|
-- Transition detector
|
||||||
@ -85,7 +98,7 @@ begin
|
|||||||
signal bit_ev : bit_ev_t;
|
signal bit_ev : bit_ev_t;
|
||||||
|
|
||||||
-- Bit recovery
|
-- Bit recovery
|
||||||
type demanchestization_state_t is (SYNC, DATA);
|
type demanchestization_state_t is (SYNC, DATA, ERROR);
|
||||||
signal demanchestization_state : demanchestization_state_t;
|
signal demanchestization_state : demanchestization_state_t;
|
||||||
begin
|
begin
|
||||||
-- Detects spacing of transitions
|
-- Detects spacing of transitions
|
||||||
@ -133,7 +146,7 @@ begin
|
|||||||
|
|
||||||
if transition_stb then
|
if transition_stb then
|
||||||
case last_transition is
|
case last_transition is
|
||||||
when LONG =>
|
when LONG => -- @suppress: Exit condition through indirect assignment
|
||||||
if transition_duration = LONG then
|
if transition_duration = LONG then
|
||||||
bit_ev <= TOGGLE;
|
bit_ev <= TOGGLE;
|
||||||
end if;
|
end if;
|
||||||
@ -147,6 +160,10 @@ begin
|
|||||||
last_transition <= LONG;
|
last_transition <= LONG;
|
||||||
end case;
|
end case;
|
||||||
end if;
|
end if;
|
||||||
|
|
||||||
|
if (not transition_activity) then
|
||||||
|
last_transition <= LONG;
|
||||||
|
end if;
|
||||||
end if;
|
end if;
|
||||||
end process transition_analyzer;
|
end process transition_analyzer;
|
||||||
|
|
||||||
@ -157,23 +174,32 @@ begin
|
|||||||
demanchestization_state <= SYNC;
|
demanchestization_state <= SYNC;
|
||||||
bit_stb <= '0';
|
bit_stb <= '0';
|
||||||
rx_active <= '0';
|
rx_active <= '0';
|
||||||
|
rx_error <= '0';
|
||||||
elsif rising_edge(clk) then
|
elsif rising_edge(clk) then
|
||||||
bit_stb <= '0';
|
bit_stb <= '0';
|
||||||
|
rx_error <= '0';
|
||||||
|
|
||||||
if (bit_ev /= NONE) then
|
if (bit_ev /= NONE) then
|
||||||
rx_active <= '1';
|
|
||||||
case demanchestization_state is
|
case demanchestization_state is
|
||||||
when SYNC =>
|
when SYNC =>
|
||||||
if (bit_ev = KEEP) then
|
if (bit_ev = KEEP) then
|
||||||
bit_value <= '1';
|
bit_value <= '1';
|
||||||
demanchestization_state <= DATA;
|
demanchestization_state <= DATA;
|
||||||
|
rx_active <= '1';
|
||||||
end if;
|
end if;
|
||||||
when DATA =>
|
when DATA => -- @suppress: Condition outside of case allows to exit this state
|
||||||
bit_value <= not bit_value when bit_ev = TOGGLE else bit_value;
|
bit_value <= not bit_value when bit_ev = TOGGLE else bit_value;
|
||||||
bit_stb <= '1';
|
bit_stb <= '1';
|
||||||
|
when ERROR => -- @suppress: Condition outside of case allows to exit this state
|
||||||
|
null;
|
||||||
end case;
|
end case;
|
||||||
end if;
|
end if;
|
||||||
|
|
||||||
|
if (bit_ev = ERROR) then
|
||||||
|
rx_error <= '1';
|
||||||
|
demanchestization_state <= ERROR;
|
||||||
|
end if;
|
||||||
|
|
||||||
if (not transition_activity) then
|
if (not transition_activity) then
|
||||||
demanchestization_state <= SYNC;
|
demanchestization_state <= SYNC;
|
||||||
rx_active <= '0';
|
rx_active <= '0';
|
||||||
@ -194,7 +220,7 @@ begin
|
|||||||
|
|
||||||
if rx_active then
|
if rx_active then
|
||||||
if (bit_stb) then
|
if (bit_stb) then
|
||||||
data_rx <= data_rx(data_rx'high - 1 downto 0) & bit_value;
|
data_rx <= bit_value & data_rx(data_rx'high downto data_rx'low + 1);
|
||||||
if (bit_cnt = 7) then
|
if (bit_cnt = 7) then
|
||||||
data_rx_valid <= '1';
|
data_rx_valid <= '1';
|
||||||
bit_cnt <= 0;
|
bit_cnt <= 0;
|
||||||
@ -212,7 +238,7 @@ begin
|
|||||||
nlp_timeout_p : process(clk, rst) is
|
nlp_timeout_p : process(clk, rst) is
|
||||||
begin
|
begin
|
||||||
if rst then
|
if rst then
|
||||||
nlp_timeout_cnt <= NLP_TIMEOUT_CNT_MAX;
|
nlp_timeout_cnt <= 0;
|
||||||
elsif rising_edge(clk) then
|
elsif rising_edge(clk) then
|
||||||
if rx_edge then -- Technically, we should use only the rising edge here, but a project called `trashernet` probably won't mind ;)
|
if rx_edge then -- Technically, we should use only the rising edge here, but a project called `trashernet` probably won't mind ;)
|
||||||
nlp_timeout_cnt <= NLP_TIMEOUT_CNT_MAX;
|
nlp_timeout_cnt <= NLP_TIMEOUT_CNT_MAX;
|
||||||
@ -244,5 +270,4 @@ begin
|
|||||||
end process nlp;
|
end process nlp;
|
||||||
tx_p <= '1' when cnt < 0 else '0';
|
tx_p <= '1' when cnt < 0 else '0';
|
||||||
end block transmitter;
|
end block transmitter;
|
||||||
|
|
||||||
end architecture rtl;
|
end architecture rtl;
|
||||||
|
Loading…
Reference in New Issue
Block a user