Skip to content

Commit ccbf1ff

Browse files
Added UART_RX_CTRL file.
1 parent 5e88c04 commit ccbf1ff

File tree

1 file changed

+128
-0
lines changed

1 file changed

+128
-0
lines changed

vhdl/UART_RX_CTRL.vhd

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
-- ClariFi
2+
-- Part: XC7A35TICSG324-1L
3+
-- UART_RX_CTRL - Utilizes the Arty A7's USB-UART Bridge (Serial Port)
4+
-- Serialization information:
5+
-- TXD -> Pin A9
6+
-- RXD -> Pin D10
7+
-- 115200 Baud Rate
8+
-- 8 Data Bits, LSB First
9+
-- 1 Stop Bit
10+
-- No parity
11+
-- Data needs to be sampled at a rate of at least 115200*8 = 921.600 KHz
12+
-- A 100 MHz clock is expected. We sample in the middle of a bit data.
13+
14+
library ieee;
15+
use ieee.std_logic_1164.ALL;
16+
use ieee.numeric_std.all;
17+
18+
entity UART_RX_CTRL is
19+
generic (
20+
CLKS_PER_BIT : integer := 868 -- 868 = round(100MHz / 115200)
21+
);
22+
port (
23+
CLK : in std_logic;
24+
RST : in std_logic;
25+
UART_RX : in std_logic;
26+
RX_DONE : out std_logic;
27+
DATA : out std_logic_vector(7 downto 0)
28+
);
29+
end UART_RX_CTRL;
30+
31+
architecture BHV of UART_RX_CTRL is
32+
33+
type state_type is (S_START, S_START_BIT, S_DATA_BITS, S_STOP_BIT, S_DONE);
34+
signal state : state_type := S_START;
35+
36+
signal r_UART_RX : std_logic := '0';
37+
signal r_r_UART_RX : std_logic := '0';
38+
39+
signal r_Bit_Counter : integer range 0 to CLKS_PER_BIT-1 := 0;
40+
signal r_Bit_Index : integer range 0 to 7 := 0; -- 8 Bits Total
41+
signal r_RX_Byte : std_logic_vector(7 downto 0) := (others => '0');
42+
signal r_RX_DONE : std_logic := '0';
43+
44+
begin
45+
process (CLK)
46+
begin
47+
if rising_edge(CLK) then
48+
-- Dual-flop synchronizer to stabilize incoming signal (data)
49+
r_UART_RX <= UART_RX;
50+
r_r_UART_RX <= r_UART_RX;
51+
52+
case state is
53+
54+
when S_START =>
55+
r_RX_DONE <= '0';
56+
r_Bit_Counter <= 0;
57+
r_Bit_Index <= 0;
58+
59+
if (r_r_UART_RX = '0') then -- falling_edge(r_r_UART_RX) then -- Start bit transitioned from '1' to '0'
60+
state <= S_START_BIT;
61+
end if;
62+
state <= S_START;
63+
64+
-- Sample half bit later to make sure it's still low
65+
when S_START_BIT =>
66+
if r_Bit_Counter = (CLKS_PER_BIT-1)/2 then
67+
if r_r_UART_RX = '0' then
68+
r_Bit_Counter <= 0; -- Reset the counter
69+
state <= S_DATA_BITS; -- We are receiving data
70+
else
71+
state <= S_START; -- Start bit was not held low long enough
72+
end if;
73+
else
74+
r_Bit_Counter <= r_Bit_Counter + 1;
75+
state <= S_START_BIT;
76+
end if;
77+
78+
79+
-- Sample data after CLKS_PER_BIT-1 clock cycles
80+
when S_DATA_BITS =>
81+
if r_Bit_Counter < CLKS_PER_BIT-1 then
82+
r_Bit_Counter <= r_Bit_Counter + 1;
83+
state <= S_DATA_BITS;
84+
else
85+
r_Bit_Counter <= 0;
86+
r_RX_Byte(r_Bit_Index) <= r_r_UART_RX;
87+
88+
-- Loop back until all 8 bits have been added to r_RX_Byte
89+
if r_Bit_Index < 7 then
90+
r_Bit_Index <= r_Bit_Index + 1;
91+
state <= S_DATA_BITS;
92+
else
93+
r_Bit_Index <= 0;
94+
state <= S_STOP_BIT;
95+
end if;
96+
end if;
97+
98+
99+
-- Receive last bit, 1 stop bit.
100+
when S_STOP_BIT =>
101+
-- Check stop bit after CLKS_PER_BIT-1 clock cycles
102+
if r_Bit_Counter < CLKS_PER_BIT-1 then
103+
r_Bit_Counter <= r_Bit_Counter + 1;
104+
state <= S_STOP_BIT;
105+
else
106+
r_RX_DONE <= '1';
107+
r_Bit_Counter <= 0;
108+
state <= S_DONE;
109+
end if;
110+
111+
112+
-- Wait 1 cycle before going back to S_START
113+
when S_DONE =>
114+
state <= S_START;
115+
r_RX_DONE <= '0';
116+
117+
-- Should never be reached
118+
when others =>
119+
state <= S_START;
120+
121+
end case;
122+
end if;
123+
end process;
124+
125+
RX_DONE <= r_RX_DONE;
126+
DATA <= r_RX_Byte;
127+
128+
end BHV;

0 commit comments

Comments
 (0)