aboutsummaryrefslogtreecommitdiffstats
path: root/examples/ecp5_versa/uart.vhdl
blob: c21ab4979f336d53427f09f2513710ed0b576989 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
-- Simple UART core implementation
--
-- <hackfin@section5.ch>

library IEEE;
use IEEE.std_logic_1164.all;
use ieee.numeric_std.all;

library work;
	use work.system_map.all;

entity uart_core is
	generic (
		FIFO_DEPTH : natural := 6;
		-- Note: Currently ineffective. See library/wrappers/bram.v
		SYN_RAMTYPE  : string  := "distributed"
	);
	port (
		tx        : out std_logic;
		rx        : in std_logic;
		rxirq     : out std_logic;
		ctrl      : in uart_WritePort;
		stat      : out uart_ReadPort;
		clk       : in std_logic
	);

end uart_core;

architecture behaviour of uart_core is

	signal count16  : unsigned(4-1 downto 0) := (others => '0');
	signal counter  : unsigned(16-1 downto 0) := (others => '0');

	signal strobe_rx     : std_logic;
	signal rxd           : unsigned(7 downto 0);
	signal txd           : unsigned(7 downto 0);

	signal rxfifo_data   : unsigned(7 downto 0);

	signal rxfifo_rden   : std_logic;
	signal txfifo_wren   : std_logic;

	signal rxdata_ready  : std_logic;

	signal txfifo_dready : std_logic;
	signal txfifo_strobe : std_logic;

	signal clk16_enable  : std_logic;
	signal txclk_enable  : std_logic;

	component FifoBuffer is
		generic (
			ADDR_W          : natural := 6;
			DATA_W          : natural := 16;
			EXTRA_REGISTER  : boolean := false;
			SYN_RAMTYPE     : string  := "block_ram"
		);
		port (
			-- Write enable
			wren      : in  std_logic;
			idata     : in  unsigned(DATA_W-1 downto 0);
			iready    : out std_logic;
			-- Data stream output:
			odata     : out unsigned(DATA_W-1 downto 0);
			oready    : out std_logic;
			rden      : in  std_logic;
			err       : out std_logic;
			-- debug     : out unsigned(16-1 downto 0);
			reset     : in  std_logic;
			clk       : in  std_logic
		);
	end component FifoBuffer;


begin

-- Clock divider:
clkdiv:
	process (clk)
	begin
		if rising_edge(clk) then
			clk16_enable <= '0';
			txclk_enable <= '0';
			-- Important to reset, otherwise, the counter might run away...
			if ctrl.uart_reset = '1' then
				counter <= (others => '0');
			elsif counter = ctrl.uart_clkdiv then
				counter <= (others => '0');
				clk16_enable <= '1';
				count16 <= count16 + 1;
				if count16 = "1111" then
					txclk_enable <= '1';
				end if;
			else
				counter <= counter + 1;
			end if;
		end if;
	end process;

	rxfifo_rden <= ctrl.select_uart_rxr and rxdata_ready;
	txfifo_wren <= ctrl.select_uart_txr;

uart_rx: entity work.UARTrx
	port map (
		d_bitcount       => stat.bitcount,
		rx               => rx,
		-- Data
		err_frame        => stat.frerr,
		data             => rxd,
		strobe           => strobe_rx,
		reset            => ctrl.uart_reset,
		clk16en          => clk16_enable,
		clk              => clk
	);

uart_tx:
	entity work.UARTtx
	port map (
		busy             => stat.txbusy,
		data             => txd,
		data_ready       => txfifo_dready,
		data_out_en      => txfifo_strobe,
		tx               => tx,
		reset            => ctrl.uart_reset,
		txclken          => txclk_enable,
		clk              => clk
	);


rxfifo:
	FifoBuffer
	generic map (
		DATA_W => 8,
		ADDR_W => FIFO_DEPTH,
		SYN_RAMTYPE => SYN_RAMTYPE
	)
	port map (
		wren      => strobe_rx,
		idata     => rxd,
		iready    => open,
		odata     => rxfifo_data,
		oready    => rxdata_ready,
		rden      => rxfifo_rden,
		err       => stat.rxovr,
		reset     => ctrl.uart_reset,
		clk       => clk
	);

	stat.rxdata   <= rxfifo_data;
	stat.dvalid   <= rxdata_ready;
	stat.rxready  <= rxdata_ready;
	rxirq         <= rxdata_ready and ctrl.rx_irq_enable;

txfifo:
	FifoBuffer
	generic map (
		DATA_W => 8,
		ADDR_W => FIFO_DEPTH,
		SYN_RAMTYPE => SYN_RAMTYPE
	)
	port map (
		wren      => txfifo_wren,
		idata     => ctrl.uart_txr,
		iready    => stat.txready,
		odata     => txd,
		oready    => txfifo_dready,
		rden      => txfifo_strobe,
		err       => stat.txovr,
		reset     => ctrl.uart_reset,
		clk       => clk
	);

end behaviour;