SURF  1.0
UartRx.vhd
Go to the documentation of this file.
1 -------------------------------------------------------------------------------
2 -- File : UartRx.vhd
3 -- Company : SLAC National Accelerator Laboratory
4 -- Created : 2016-05-13
5 -- Last update: 2016-06-09
6 -------------------------------------------------------------------------------
7 -- Description: UART Receiver
8 -------------------------------------------------------------------------------
9 -- This file is part of 'SLAC Firmware Standard Library'.
10 -- It is subject to the license terms in the LICENSE.txt file found in the
11 -- top-level directory of this distribution and at:
12 -- https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html.
13 -- No part of 'SLAC Firmware Standard Library', including this file,
14 -- may be copied, modified, propagated, or distributed except according to
15 -- the terms contained in the LICENSE.txt file.
16 -------------------------------------------------------------------------------
17 
18 library ieee;
19 use ieee.std_logic_1164.all;
20 use ieee.std_logic_unsigned.all;
21 
22 use work.StdRtlPkg.all;
23 
24 --! @see entity
25  --! @ingroup protocols_uart
26 entity UartRx is
27  generic (
28  TPD_G : time := 1 ns);
29  port (
30  clk : in sl;
31  rst : in sl;
32  baud16x : in sl;
33  rdData : out slv(7 downto 0);
34  rdValid : out sl;
35  rdReady : in sl;
36  rx : in sl);
37 end entity UartRx;
38 
39 architecture rtl of UartRx is
40 
41  type StateType is (WAIT_START_BIT_S, WAIT_8_S, WAIT_16_S, SAMPLE_RX_S, WAIT_STOP_S, WRITE_OUT_S);
42 
43  type RegType is
44  record
45  rdValid : sl;
46  rdData : slv(7 downto 0);
47  rxState : stateType;
48  rxShiftReg : slv(7 downto 0);
49  rxShiftCount : slv(2 downto 0);
50  baud16xCount : slv(3 downto 0);
51  end record regType;
52 
53  constant REG_INIT_C : RegType := (
54  rdValid => '0',
55  rdData => (others => '0'),
56  rxState => WAIT_START_BIT_S,
57  rxShiftReg => (others => '0'),
58  rxShiftCount => (others => '0'),
59  baud16xCount => (others => '0'));
60 
61  signal r : RegType := REG_INIT_C;
62  signal rin : RegType;
63 
64  signal rxSync : sl;
65  signal rxFall : sl;
66 
67 begin
68 
69  U_SynchronizerEdge_1 : entity work.SynchronizerEdge
70  generic map (
71  TPD_G => TPD_G,
72  STAGES_G => 3,
73  INIT_G => "111")
74  port map (
75  clk => clk, -- [in]
76  rst => rst, -- [in]
77  dataIn => rx, -- [in]
78  dataOut => rxSync, -- [out]
79  risingEdge => open, -- [out]
80  fallingEdge => rxFall); -- [out]
81 
82  comb : process (baud16x, r, rdReady, rst, rxFall, rxSync) is
83  variable v : RegType;
84  begin
85  v := r;
86 
87  if (rdReady = '1') then
88  v.rdValid := '0';
89  end if;
90 
91  case r.rxState is
92 
93  -- Wait for RX to drop to indicate start bit
94  when WAIT_START_BIT_S =>
95  if (rxFall = '1') then
96  v.rxState := WAIT_8_S;
97  v.baud16xCount := "0000";
98  end if;
99 
100  -- Wait 8 baud16x counts to find center of start bit
101  -- Every rx bit is 16 baud16x pulses apart
102  when WAIT_8_S =>
103  if (baud16x = '1') then
104  v.baud16xCount := r.baud16xCount + 1;
105  if (r.baud16xCount = "0111") then
106  v.baud16xCount := "0000";
107  v.rxState := WAIT_16_S;
108  end if;
109  end if;
110 
111  -- Wait 16 baud16x counts (center of next bit)
112  when WAIT_16_S =>
113  if (baud16x = '1') then
114  v.baud16xCount := r.baud16xCount + 1;
115  if (r.baud16xCount = "1111") then
116  v.rxState := SAMPLE_RX_S;
117  end if;
118  end if;
119 
120  -- Sample the rx line and shift it in.
121  -- Go back and wait 16 for the next bit unless last bit
122  when SAMPLE_RX_S =>
123  v.rxShiftReg := rxSync & r.rxShiftReg(7 downto 1);
124  v.rxShiftCount := r.rxShiftCount + 1;
125  v.rxState := WAIT_16_S;
126  if (r.rxShiftCount = "111") then
127  v.rxState := WAIT_STOP_S;
128  end if;
129 
130  -- Wait for the stop bit
131  when WAIT_STOP_S =>
132  if (rxSync = '1') then
133  v.rxState := WRITE_OUT_S;
134  end if;
135 
136  -- Put the parallel rx data on the output port.
137  when WRITE_OUT_S =>
138  v.rdData := r.rxShiftReg;
139  v.rdValid := '1';
140  v.rxState := WAIT_START_BIT_S;
141 
142  end case;
143 
144  if (rst = '1') then
145  v := REG_INIT_C;
146  end if;
147 
148  rin <= v;
149  rdData <= r.rdData;
150  rdValid <= r.rdValid;
151 
152  end process comb;
153 
154  sync : process (clk) is
155  begin
156  if (rising_edge(clk)) then
157  r <= rin after TPD_G;
158  end if;
159  end process;
160 
161 end architecture RTL;
in rdReadysl
Definition: UartRx.vhd:35
in rxsl
Definition: UartRx.vhd:36
TPD_Gtime := 1 ns
Definition: UartRx.vhd:28
std_logic sl
Definition: StdRtlPkg.vhd:28
_library_ ieeeieee
Definition: UartBrg.vhd:18
out rdDataslv( 7 downto 0)
Definition: UartRx.vhd:33
in rstsl :=not RST_POLARITY_G
STAGES_Gpositive := 3
in rstsl
Definition: UartRx.vhd:31
out rdValidsl
Definition: UartRx.vhd:34
in clksl
Definition: UartRx.vhd:30
in baud16xsl
Definition: UartRx.vhd:32
std_logic_vector slv
Definition: StdRtlPkg.vhd:29