1 |
23 |
TobiasJ |
------------------------------------------------------------------------
|
2 |
|
|
-- File infomation
|
3 |
|
|
------------------------------------------------------------------------
|
4 |
|
|
-- Tobias N. Jeppe - 22-01-2013
|
5 |
|
|
-- Wish Bone interface
|
6 |
|
|
-- Implemented with standard single write cycle and single read cycle
|
7 |
|
|
-- 8 bit address, 8 bit in and out put data
|
8 |
|
|
--
|
9 |
|
|
------------------------------------------------------------------------
|
10 |
|
|
|
11 |
|
|
|
12 |
|
|
library IEEE;
|
13 |
|
|
use IEEE.STD_LOGIC_1164.ALL;
|
14 |
|
|
use IEEE.STD_LOGIC_ARITH.ALL;
|
15 |
|
|
use IEEE.STD_LOGIC_UNSIGNED.ALL;
|
16 |
|
|
|
17 |
|
|
entity uart_wb is
|
18 |
31 |
TobiasJ |
port( --WB interface
|
19 |
23 |
TobiasJ |
CLK_I : in std_logic;
|
20 |
31 |
TobiasJ |
master_rst : in std_logic;
|
21 |
23 |
TobiasJ |
RST_I : in std_logic;
|
22 |
|
|
ADR_I : in std_logic_vector(7 downto 0);
|
23 |
|
|
DAT_I : in std_logic_vector(7 downto 0);
|
24 |
|
|
WE_I : in std_logic;
|
25 |
|
|
STB_I : in std_logic;
|
26 |
|
|
CYC_I : in std_logic;
|
27 |
|
|
|
28 |
|
|
DAT_O : out std_logic_vector(7 downto 0);
|
29 |
|
|
ACK_O : out std_logic;
|
30 |
|
|
|
31 |
|
|
--uart controll
|
32 |
|
|
word_width : out std_logic_vector(3 downto 0);
|
33 |
|
|
baud_period : out std_logic_vector(15 downto 0);
|
34 |
|
|
use_parity_bit : out std_logic;
|
35 |
|
|
parity_type : out std_logic;
|
36 |
|
|
stop_bits : out std_logic_vector(1 downto 0);
|
37 |
|
|
idle_line_lvl : out std_logic;
|
38 |
|
|
rx_enable : out std_logic; --rx specific
|
39 |
|
|
start_samples : out std_logic_vector(3 downto 0); --rx specific
|
40 |
|
|
line_samples : out std_logic_vector(3 downto 0); --rx specific
|
41 |
|
|
uart_rx_rst : out std_logic;
|
42 |
|
|
uart_rx_fifo_rst : out std_logic;
|
43 |
|
|
uart_tx_rst : out std_logic;
|
44 |
|
|
uart_tx_fifo_rst : out std_logic;
|
45 |
|
|
|
46 |
|
|
--FIFO control/data
|
47 |
|
|
tx_fifo_entries_free : in std_logic_vector (7 downto 0);
|
48 |
|
|
write_tx_data : out std_logic;
|
49 |
|
|
tx_data : out std_logic_vector(7 downto 0);
|
50 |
|
|
|
51 |
|
|
read_rx_data : out std_logic;
|
52 |
|
|
rx_data : in std_logic_vector(7 downto 0);
|
53 |
|
|
rx_fifo_entries_free : in std_logic_vector (7 downto 0));
|
54 |
|
|
end entity uart_wb;
|
55 |
|
|
|
56 |
|
|
|
57 |
|
|
architecture behaviour of uart_wb is
|
58 |
|
|
-- Components
|
59 |
|
|
-- Signals
|
60 |
|
|
signal we_ok : std_logic;
|
61 |
|
|
signal uart_setup_rst : std_logic;
|
62 |
|
|
|
63 |
|
|
signal write_reg_addr_1 : std_logic;
|
64 |
|
|
signal reg_addr_1_q, reg_addr_1_d : std_logic;
|
65 |
|
|
|
66 |
|
|
signal write_reg_addr_100 : std_logic;
|
67 |
|
|
signal reg_addr_100_q, reg_addr_100_d : std_logic_vector(7 downto 0); --00000100 = rx_idle_line_lvl(r/w)(rst.1)|x|rx_use_parity(r/w)(rst.0)|rx_parity_type|rx_stop_bits(rw)(rst.01)|word_width
|
68 |
|
|
signal write_reg_addr_101 : std_logic;
|
69 |
|
|
signal reg_addr_101_q, reg_addr_101_d : std_logic_vector(7 downto 0); --00000101 = start_samples(4) | reg_samples(4)
|
70 |
|
|
signal write_reg_addr_110 : std_logic;
|
71 |
|
|
signal reg_addr_110_q, reg_addr_110_d : std_logic_vector(7 downto 0); --00000110 = period low LSB ( 7 downto 0) (Baud / Frequenzy, min 32, max 655??)
|
72 |
|
|
signal write_reg_addr_111 : std_logic;
|
73 |
|
|
signal reg_addr_111_q, reg_addr_111_d : std_logic_vector(7 downto 0); --00000111 = period high MSB (15 downto 8)
|
74 |
|
|
|
75 |
|
|
signal write_reg_addr_1000 : std_logic;
|
76 |
|
|
signal reg_addr_1000_q, reg_addr_1000_d : std_logic_vector(4 downto 0); --00001000 = xxx | rst_uart_rx | rst_uart_rx_fifo | rst_uart_tx | rst_uart_tx_fifo | rst_uart_setup
|
77 |
|
|
signal write_reg_addr_1001 : std_logic;
|
78 |
31 |
TobiasJ |
signal reg_addr_1001_q : std_logic_vector(4 downto 0);-- := "11111"; --00001001 = xxx | rst_uart_rx_if_rst_wb | rst_uart_rx_fifo_if_rst_wb | rst_uart_tx_if_rst_wb | rst_uart_tx_fifo_if_rst_wb | rst_uart_setup_if_rst_wb |
|
79 |
26 |
TobiasJ |
signal reg_addr_1001_d : std_logic_vector(4 downto 0);
|
80 |
23 |
TobiasJ |
|
81 |
|
|
Begin
|
82 |
|
|
-------------------------
|
83 |
|
|
-- Combinational Logic --
|
84 |
|
|
-------------------------
|
85 |
26 |
TobiasJ |
we_ok <= WE_I and CYC_I;
|
86 |
23 |
TobiasJ |
ACK_O <= STB_I;
|
87 |
|
|
|
88 |
|
|
--DAT_O asynchronous
|
89 |
|
|
with ADR_I select
|
90 |
|
|
DAT_O <= "0000000" & reg_addr_1_q when "00000001",
|
91 |
|
|
rx_fifo_entries_free when "00000010",
|
92 |
|
|
tx_fifo_entries_free when "00000011",
|
93 |
|
|
reg_addr_100_q when "00000100",
|
94 |
|
|
reg_addr_101_q when "00000101",
|
95 |
|
|
reg_addr_110_q when "00000110",
|
96 |
|
|
reg_addr_111_q when "00000111",
|
97 |
|
|
"000" & reg_addr_1000_q when "00001000",
|
98 |
|
|
"000" & reg_addr_1001_q when "00001001",
|
99 |
|
|
rx_data when others;
|
100 |
|
|
|
101 |
|
|
rx_enable <= reg_addr_1_q;
|
102 |
|
|
write_reg_addr_1 <= '1' when (ADR_I = "00000001" and we_ok = '1') or uart_setup_rst = '1' else
|
103 |
|
|
'0';
|
104 |
31 |
TobiasJ |
reg_addr_1_d <= '0' when uart_setup_rst = '1' else
|
105 |
23 |
TobiasJ |
DAT_I(0);
|
106 |
|
|
|
107 |
|
|
idle_line_lvl <= reg_addr_100_q(7);
|
108 |
|
|
use_parity_bit <= reg_addr_100_q(6);
|
109 |
|
|
parity_type <= reg_addr_100_q(5);
|
110 |
|
|
stop_bits <= reg_addr_100_q(4 downto 3);
|
111 |
|
|
word_width <= '0' & reg_addr_100_q(2 downto 0); --the msb is missing
|
112 |
|
|
write_reg_addr_100 <= '1' when (ADR_I = "00000100" and we_ok = '1') or uart_setup_rst = '1' else
|
113 |
|
|
'0';
|
114 |
31 |
TobiasJ |
reg_addr_100_d <= "10001000" when uart_setup_rst = '1' else
|
115 |
23 |
TobiasJ |
DAT_I;
|
116 |
|
|
|
117 |
|
|
start_samples <= reg_addr_101_q(7 downto 4);
|
118 |
|
|
line_samples <= reg_addr_101_q(3 downto 0);
|
119 |
|
|
write_reg_addr_101 <= '1' when (ADR_I = "00000101" and we_ok = '1') or uart_setup_rst = '1' else
|
120 |
|
|
'0';
|
121 |
|
|
reg_addr_101_d <= "0110" & "0100" when uart_setup_rst = '1' else
|
122 |
|
|
DAT_I;
|
123 |
|
|
|
124 |
|
|
baud_period <= reg_addr_111_q & reg_addr_110_q;
|
125 |
26 |
TobiasJ |
write_reg_addr_110 <= '1' when (ADR_I = "00000110" and we_ok = '1') or uart_setup_rst = '1' else
|
126 |
23 |
TobiasJ |
'0';
|
127 |
26 |
TobiasJ |
reg_addr_110_d <= "00010000" when uart_setup_rst = '1' else
|
128 |
23 |
TobiasJ |
DAT_I;
|
129 |
|
|
write_reg_addr_111 <= '1' when (ADR_I = "00000111" and we_ok = '1') or uart_setup_rst = '1' else
|
130 |
|
|
'0';
|
131 |
|
|
reg_addr_111_d <= "00000000" when uart_setup_rst = '1' else
|
132 |
|
|
DAT_I;
|
133 |
|
|
|
134 |
31 |
TobiasJ |
uart_rx_rst <= (RST_I and reg_addr_1001_q(4)) or reg_addr_1000_q(4) or master_rst;
|
135 |
|
|
uart_rx_fifo_rst <= (RST_I and reg_addr_1001_q(3)) or reg_addr_1000_q(3) or master_rst;
|
136 |
|
|
uart_tx_rst <= (RST_I and reg_addr_1001_q(2)) or reg_addr_1000_q(2) or master_rst;
|
137 |
|
|
uart_tx_fifo_rst <= (RST_I and reg_addr_1001_q(1)) or reg_addr_1000_q(1) or master_rst;
|
138 |
|
|
uart_setup_rst <= (RST_I and reg_addr_1001_q(0)) or reg_addr_1000_q(0) or master_rst;
|
139 |
23 |
TobiasJ |
write_reg_addr_1000 <= '1' when (ADR_I = "00001000" and we_ok = '1') or uart_setup_rst = '1' else
|
140 |
|
|
'0';
|
141 |
|
|
reg_addr_1000_d <= "00000" when uart_setup_rst = '1' else
|
142 |
|
|
DAT_I(4 downto 0);
|
143 |
|
|
|
144 |
|
|
write_reg_addr_1001 <= '1' when (ADR_I = "00001001" and we_ok = '1') or uart_setup_rst = '1' else
|
145 |
|
|
'0';
|
146 |
31 |
TobiasJ |
reg_addr_1001_d <= "11111" when uart_setup_rst = '1' else
|
147 |
23 |
TobiasJ |
DAT_I(4 downto 0);
|
148 |
|
|
|
149 |
|
|
--Write to tx_fifo
|
150 |
31 |
TobiasJ |
write_tx_data <= '1' when ADR_I = "00000000" and we_ok = '1' else '0';
|
151 |
23 |
TobiasJ |
tx_data <= DAT_I;
|
152 |
|
|
|
153 |
|
|
--Read from rx_fifo
|
154 |
31 |
TobiasJ |
read_rx_data <= '1' when ADR_I = "00000000" and (WE_I='0' and CYC_I = '1') else '0';
|
155 |
23 |
TobiasJ |
|
156 |
|
|
--------------------
|
157 |
|
|
-- Register Logic --
|
158 |
|
|
--------------------
|
159 |
|
|
register_logic : process(CLK_I, write_reg_addr_100, write_reg_addr_101, write_reg_addr_110,write_reg_addr_111,write_reg_addr_1000,write_reg_addr_1001)
|
160 |
|
|
begin
|
161 |
|
|
if rising_edge(CLK_I) then
|
162 |
|
|
if write_reg_addr_1 = '1' then
|
163 |
|
|
reg_addr_1_q <= reg_addr_1_d;
|
164 |
|
|
end if;
|
165 |
|
|
|
166 |
|
|
if write_reg_addr_100 = '1' then
|
167 |
|
|
reg_addr_100_q <= reg_addr_100_d;
|
168 |
|
|
end if;
|
169 |
|
|
|
170 |
|
|
if write_reg_addr_101 = '1' then
|
171 |
|
|
reg_addr_101_q <= reg_addr_101_d;
|
172 |
|
|
end if;
|
173 |
|
|
|
174 |
|
|
if write_reg_addr_110 = '1' then
|
175 |
|
|
reg_addr_110_q <= reg_addr_110_d;
|
176 |
|
|
end if;
|
177 |
|
|
|
178 |
|
|
if write_reg_addr_111 = '1' then
|
179 |
|
|
reg_addr_111_q <= reg_addr_111_d;
|
180 |
|
|
end if;
|
181 |
|
|
|
182 |
|
|
if write_reg_addr_1000 = '1' then
|
183 |
|
|
reg_addr_1000_q <= reg_addr_1000_d;
|
184 |
|
|
end if;
|
185 |
|
|
|
186 |
|
|
if write_reg_addr_1001 = '1' then
|
187 |
|
|
reg_addr_1001_q <= reg_addr_1001_d;
|
188 |
|
|
end if;
|
189 |
|
|
end if;
|
190 |
|
|
|
191 |
|
|
end process;
|
192 |
|
|
|
193 |
|
|
end architecture behaviour;
|