implemented TX part of UART paripheral
Stefan Schuermans

Stefan Schuermans commited on 2012-02-16 20:33:52
Showing 10 changed files, with 378 additions and 26 deletions.

... ...
@@ -7,6 +7,7 @@
7 7
          <top_modules>
8 8
             <top_module name="e_testbed" />
9 9
             <top_module name="io_lcd_pins" />
10
+            <top_module name="io_switches_pins" />
10 11
             <top_module name="mips_types" />
11 12
             <top_module name="numeric_std" />
12 13
             <top_module name="std_logic_1164" />
... ...
@@ -15,10 +16,6 @@
15 16
       </db_ref>
16 17
    </db_ref_list>
17 18
    <WVObjectSize size="26" />
18
-   <wvobject fp_name="/e_testbed/s_rst" type="logic" db_ref_id="1">
19
-      <obj_property name="ElementShortName">s_rst</obj_property>
20
-      <obj_property name="ObjectShortName">s_rst</obj_property>
21
-   </wvobject>
22 19
    <wvobject fp_name="/e_testbed/s_clk" type="logic" db_ref_id="1">
23 20
       <obj_property name="ElementShortName">s_clk</obj_property>
24 21
       <obj_property name="ObjectShortName">s_clk</obj_property>
... ...
@@ -31,6 +28,10 @@
31 28
       <obj_property name="ElementShortName">pin_lcd</obj_property>
32 29
       <obj_property name="ObjectShortName">pin_lcd</obj_property>
33 30
    </wvobject>
31
+   <wvobject fp_name="/e_testbed/pin_uart_tx" type="logic" db_ref_id="1">
32
+      <obj_property name="ElementShortName">pin_uart_tx</obj_property>
33
+      <obj_property name="ObjectShortName">pin_uart_tx</obj_property>
34
+   </wvobject>
34 35
    <wvobject fp_name="/e_testbed/system/core/regs/r_regs[29]" type="array" db_ref_id="1">
35 36
       <obj_property name="ElementShortName">[29]</obj_property>
36 37
       <obj_property name="ObjectShortName">r_regs[29]</obj_property>
... ...
@@ -0,0 +1 @@
1
+NET "pin_o_uart_tx" LOC = "F15" | IOSTANDARD = LVTTL | DRIVE = 4 | SLEW = SLOW;
... ...
@@ -1,4 +1,4 @@
1
-SRCS=cyc_cnt.c lcd.c leds.c main.c switches.c
1
+SRCS=cyc_cnt.c lcd.c leds.c main.c switches.c uart.c
2 2
 
3 3
 PERL=perl
4 4
 CC=mipsel-elf-gcc
... ...
@@ -1,6 +1,7 @@
1 1
 #include "cyc_cnt.h"
2 2
 #include "lcd.h"
3 3
 #include "leds.h"
4
+#include "uart.h"
4 5
 #include "switches.h"
5 6
 
6 7
 const int myconst = 0x12345678;
... ...
@@ -50,6 +51,18 @@ int main()
50 51
   lcd_str(0, "MIPS I system");
51 52
   lcd_str(1, "");
52 53
 
54
+  uart_cfg_scale(62); /* 115200 */
55
+  uart_cfg_bits(8);
56
+  uart_cfg_stop(1);
57
+  uart_tx('M');
58
+  uart_tx('I');
59
+  uart_tx('P');
60
+  uart_tx('S');
61
+  uart_tx(' ');
62
+  uart_tx('I');
63
+  uart_tx('\r');
64
+  uart_tx('\n');
65
+
53 66
   while (1) {
54 67
     for (i = 0x1; i < 0x80; i <<= 1) {
55 68
       leds_set_state(i);
... ...
@@ -0,0 +1,42 @@
1
+#include "uart.h"
2
+
3
+static volatile unsigned char *const uart_ptr =
4
+  (volatile unsigned char *)0x80000300;
5
+
6
+/**
7
+ * @brief configure baudrate scaler
8
+ * @param[in] scale baudrate scaler (1 = 7.143 Mhz)
9
+ */
10
+void uart_cfg_scale(unsigned short scale)
11
+{
12
+  *(unsigned short *)(uart_ptr + 0) = scale;
13
+}
14
+
15
+/**
16
+ * @brief configure number of data bits
17
+ * @param[in] bits number of data bits
18
+ */
19
+void uart_cfg_bits(unsigned char bits)
20
+{
21
+  *(uart_ptr + 2) = bits;
22
+}
23
+
24
+/**
25
+ * @brief configure number of stop bits
26
+ * @param[in] stop number of stop bits
27
+ */
28
+void uart_cfg_stop(unsigned char stop)
29
+{
30
+  *(uart_ptr + 3) = stop;
31
+}
32
+
33
+/**
34
+ * @brief transmit a character
35
+ * @param[in] chr character to transmit
36
+ */
37
+void uart_tx(unsigned short chr)
38
+{
39
+  while (!*(uart_ptr + 4));
40
+  *(unsigned short *)(uart_ptr + 8) = chr;
41
+}
42
+
... ...
@@ -0,0 +1,30 @@
1
+#ifndef UART_H
2
+#define UART_H
3
+
4
+/**
5
+ * @brief configure baudrate scaler
6
+ * @param[in] scale baudrate scaler (1 = 7.143 Mhz)
7
+ */
8
+void uart_cfg_scale(unsigned short scale);
9
+
10
+/**
11
+ * @brief configure number of data bits
12
+ * @param[in] bits number of data bits
13
+ */
14
+void uart_cfg_bits(unsigned char bits);
15
+
16
+/**
17
+ * @brief configure number of stop bits
18
+ * @param[in] stop number of stop bits
19
+ */
20
+void uart_cfg_stop(unsigned char stop);
21
+
22
+/**
23
+ * @brief transmit a character
24
+ * @param[in] chr character to transmit
25
+ */
26
+void uart_tx(unsigned short chr);
27
+
28
+
29
+#endif /* #ifndef UART_H */
30
+
... ...
@@ -0,0 +1,217 @@
1
+LIBRARY IEEE;
2
+USE IEEE.STD_LOGIC_1164.ALL;
3
+USE IEEE.NUMERIC_STD.ALL;
4
+
5
+ENTITY e_io_uart IS
6
+    PORT (
7
+        rst:       IN  std_logic;
8
+        clk:       IN  std_logic;
9
+        i_addr:    IN  std_logic_vector( 1 DOWNTO 0);
10
+        o_rd_data: OUT std_logic_vector(31 DOWNTO 0);
11
+        i_wr_data: IN  std_logic_vector(31 DOWNTO 0);
12
+        i_wr_en:   IN  std_logic_vector( 3 DOWNTO 0);
13
+        pin_o_tx:  OUT std_logic
14
+    );
15
+END ENTITY e_io_uart;
16
+
17
+ARCHITECTURE a_io_uart OF e_io_uart IS
18
+
19
+    TYPE t_state IS (inactive, start, data, stop);
20
+
21
+    SIGNAL n_cfg_scale: std_logic_vector(15 DOWNTO 0);
22
+    SIGNAL r_cfg_scale: std_logic_vector(15 DOWNTO 0) := X"0001";
23
+    SIGNAL n_cfg_bits:  std_logic_vector( 3 DOWNTO 0);
24
+    SIGNAL r_cfg_bits:  std_logic_vector( 3 DOWNTO 0) := X"1";
25
+    SIGNAL n_cfg_stop:  std_logic_vector( 1 DOWNTO 0);
26
+    SIGNAL r_cfg_stop:  std_logic_vector( 1 DOWNTO 0) := "01";
27
+
28
+    SIGNAL n_tx_scale:  natural RANGE 2**16 - 1 DOWNTO 0;
29
+    SIGNAL r_tx_scale:  natural RANGE 2**16 - 1 DOWNTO 0 := 1;
30
+    SIGNAL n_tx_bits:   natural RANGE 15        DOWNTO 0;
31
+    SIGNAL r_tx_bits:   natural RANGE 15        DOWNTO 0 := 1;
32
+    SIGNAL n_tx_stop:   natural RANGE 3         DOWNTO 0;
33
+    SIGNAL r_tx_stop:   natural RANGE 3         DOWNTO 0 := 1;
34
+    SIGNAL n_tx_state:  t_state;
35
+    SIGNAL r_tx_state:  t_state                         := inactive;
36
+    SIGNAL n_tx_cnt:    natural RANGE 2**16 - 1 DOWNTO 0;
37
+    SIGNAL r_tx_cnt:    natural RANGE 2**16 - 1 DOWNTO 0 := 0;
38
+    SIGNAL n_tx_sample: natural RANGE 6         DOWNTO 0;
39
+    SIGNAL r_tx_sample: natural RANGE 6         DOWNTO 0 := 0;
40
+    SIGNAL n_tx_bit:    natural RANGE 15        DOWNTO 0;
41
+    SIGNAL r_tx_bit:    natural RANGE 15        DOWNTO 0 := 0;
42
+    SIGNAL n_tx_data:   std_logic_vector(15 DOWNTO 0);
43
+    SIGNAL r_tx_data:   std_logic_vector(15 DOWNTO 0)   := X"0000";
44
+
45
+BEGIN
46
+
47
+    p_cfg_next: PROCESS(r_cfg_scale, r_cfg_bits, r_cfg_stop,
48
+                        i_addr, i_wr_data, i_wr_en)
49
+    BEGIN
50
+        n_cfg_scale <= r_cfg_scale;
51
+        n_cfg_bits  <= r_cfg_bits;
52
+        n_cfg_stop  <= r_cfg_stop;
53
+        IF i_addr = "00" THEN
54
+            IF i_wr_en(1 DOWNTO 0) = "11" AND
55
+               i_wr_data(15 DOWNTO 0) /= X"0000" THEN
56
+                n_cfg_scale <= i_wr_data(15 DOWNTO 0);
57
+            END IF;
58
+            IF i_wr_en(2) = '1' AND
59
+               i_wr_data(23 DOWNTO 20) = X"0" AND
60
+               i_wr_data(19 DOWNTO 16) /= X"0" THEN
61
+                n_cfg_bits <= i_wr_data(19 DOWNTO 16);
62
+            END IF;
63
+            IF i_wr_en(3) = '1' AND
64
+               i_wr_data(31 DOWNTO 26) = "000000" AND
65
+               i_wr_data(25 DOWNTO 24) /= "00" THEN
66
+                n_cfg_stop <= i_wr_data(25 DOWNTO 24);
67
+            END IF;
68
+        END IF;
69
+    END PROCESS p_cfg_next;
70
+
71
+    p_cfg_sync: PROCESS(rst, clk)
72
+    BEGIN
73
+        IF rst = '1' THEN
74
+            r_cfg_scale <= X"0001";
75
+            r_cfg_bits  <= X"1";
76
+            r_cfg_stop  <= "01";
77
+        ELSIF rising_edge(clk) THEN
78
+            r_cfg_scale <= n_cfg_scale;
79
+            r_cfg_bits  <= n_cfg_bits;
80
+            r_cfg_stop  <= n_cfg_stop;
81
+        END IF;
82
+    END PROCESS p_cfg_sync;
83
+
84
+    p_tx_next: PROCESS(r_cfg_scale, r_cfg_bits, r_cfg_stop,
85
+                       r_tx_scale, r_tx_bits, r_tx_stop,
86
+                       r_tx_state, r_tx_cnt, r_tx_sample, r_tx_bit, r_tx_data,
87
+                       i_addr, i_wr_data, i_wr_en)
88
+        VARIABLE v_next_cnt:    boolean;
89
+        VARIABLE v_next_sample: boolean;
90
+        VARIABLE v_next_bit:    boolean;
91
+        VARIABLE v_next_state:  boolean;
92
+        VARIABLE v_bits:        natural RANGE 15 DOWNTO 0;
93
+    BEGIN
94
+        n_tx_scale  <= r_tx_scale;
95
+        n_tx_bits   <= r_tx_bits;
96
+        n_tx_stop   <= r_tx_stop;
97
+        n_tx_state  <= r_tx_state;
98
+        n_tx_cnt    <= r_tx_cnt;
99
+        n_tx_sample <= r_tx_sample;
100
+        n_tx_bit    <= r_tx_bit;
101
+        n_tx_data   <= r_tx_data;
102
+        v_next_cnt    := false;
103
+        v_next_sample := false;
104
+        v_next_bit    := false;
105
+        v_next_state  := false;
106
+        v_bits        := 0;
107
+        IF r_tx_state = inactive THEN
108
+            IF i_addr = "10" AND i_wr_en(1 DOWNTO 0) = "11" THEN
109
+                n_tx_scale  <= to_integer(unsigned(r_cfg_scale));
110
+                n_tx_bits   <= to_integer(unsigned(r_cfg_bits));
111
+                n_tx_stop   <= to_integer(unsigned(r_cfg_stop));
112
+                n_tx_state  <= start;
113
+                n_tx_cnt    <= 0;
114
+                n_tx_sample <= 0;
115
+                n_tx_bit    <= 0;
116
+                n_tx_data   <= i_wr_data(15 DOWNTO 0);
117
+            END IF;
118
+        ELSE
119
+            v_next_cnt := true;
120
+        END IF;
121
+        IF v_next_cnt THEN
122
+            IF r_tx_cnt + 1 /= r_tx_scale THEN
123
+                n_tx_cnt <= r_tx_cnt + 1;
124
+            ELSE
125
+                n_tx_cnt <= 0;
126
+                v_next_sample := true;
127
+            END IF;
128
+        END IF;
129
+        IF v_next_sample THEN
130
+            IF r_tx_sample + 1 /= 7 THEN
131
+                n_tx_sample <= r_tx_sample + 1;
132
+            ELSE
133
+                n_tx_sample <= 0;
134
+                v_next_bit := true;
135
+            END IF;
136
+        END IF;
137
+        IF v_next_bit THEN
138
+            CASE r_tx_state IS
139
+                WHEN start => v_bits := 1;
140
+                WHEN data  => v_bits := r_tx_bits;
141
+                WHEN stop  => v_bits := r_tx_stop;
142
+                WHEN OTHERS => NULL;
143
+            END CASE;
144
+            IF r_tx_bit + 1 /= v_bits THEN
145
+                n_tx_bit <= r_tx_bit + 1;
146
+            ELSE
147
+                n_tx_bit <= 0;
148
+                v_next_state := true;
149
+            END IF;
150
+        END IF;
151
+        IF v_next_state THEN
152
+            CASE r_tx_state IS
153
+                WHEN start => n_tx_state <= data;
154
+                WHEN data  => n_tx_state <= stop;
155
+                WHEN stop  => n_tx_state <= inactive;
156
+                WHEN OTHERS => NULL;
157
+            END CASE;
158
+        END IF;
159
+    END PROCESS p_tx_next;
160
+
161
+    p_tx_sync: PROCESS(rst, clk)
162
+    BEGIN
163
+        IF rst = '1' THEN
164
+            r_tx_scale  <= 1;
165
+            r_tx_bits   <= 1;
166
+            r_tx_stop   <= 1;
167
+            r_tx_state  <= inactive;
168
+            r_tx_cnt    <= 0;
169
+            r_tx_sample <= 0;
170
+            r_tx_bit    <= 0;
171
+            r_tx_data   <= X"0000";
172
+        ELSIF rising_edge(clk) THEN
173
+            r_tx_scale  <= n_tx_scale;
174
+            r_tx_bits   <= n_tx_bits;
175
+            r_tx_stop   <= n_tx_stop;
176
+            r_tx_state  <= n_tx_state;
177
+            r_tx_cnt    <= n_tx_cnt;
178
+            r_tx_sample <= n_tx_sample;
179
+            r_tx_bit    <= n_tx_bit;
180
+            r_tx_data   <= n_tx_data;
181
+        END IF;
182
+    END PROCESS p_tx_sync;
183
+
184
+    p_tx_out: PROCESS(r_tx_bit, r_tx_state, r_tx_data)
185
+    BEGIN
186
+        pin_o_tx <= '1';
187
+        CASE r_tx_state IS
188
+            WHEN start => pin_o_tx <= '0';
189
+            WHEN data  => pin_o_tx <= r_tx_data(r_tx_bit);
190
+            WHEN stop  => pin_o_tx <= '1';
191
+            WHEN OTHERS => NULL;
192
+        END CASE;
193
+    END PROCESS p_tx_out;
194
+
195
+    p_read: PROCESS(rst, clk)
196
+    BEGIN
197
+        IF rst = '1' THEN
198
+            o_rd_data <= (OTHERS => '0');
199
+        ELSIF rising_edge(clk) THEN
200
+            o_rd_data <= (OTHERS => '0');
201
+            CASE i_addr IS
202
+                WHEN "00" =>
203
+                    o_rd_data(15 DOWNTO  0) <= r_cfg_scale;
204
+                    o_rd_data(19 DOWNTO 16) <= r_cfg_bits;
205
+                    o_rd_data(25 DOWNTO 24) <= r_cfg_stop;
206
+                WHEN "01" =>
207
+                    IF r_tx_state = inactive THEN
208
+                        o_rd_data(0) <= '1';
209
+                    END IF;
210
+                WHEN OTHERS =>
211
+                    NULL;
212
+            END CASE;
213
+        END IF;
214
+    END PROCESS p_read;
215
+
216
+END ARCHITECTURE a_io_uart;
217
+
... ...
@@ -52,22 +52,22 @@
52 52
       <association xil_pn:name="Implementation" xil_pn:seqID="4"/>
53 53
     </file>
54 54
     <file xil_pn:name="system/system.vhd" xil_pn:type="FILE_VHDL">
55
-      <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="21"/>
56
-      <association xil_pn:name="Implementation" xil_pn:seqID="21"/>
55
+      <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="22"/>
56
+      <association xil_pn:name="Implementation" xil_pn:seqID="22"/>
57 57
     </file>
58 58
     <file xil_pn:name="test/testbed.vhd" xil_pn:type="FILE_VHDL">
59
-      <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="22"/>
59
+      <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="23"/>
60 60
       <association xil_pn:name="PostMapSimulation" xil_pn:seqID="128"/>
61 61
       <association xil_pn:name="PostRouteSimulation" xil_pn:seqID="128"/>
62 62
       <association xil_pn:name="PostTranslateSimulation" xil_pn:seqID="128"/>
63 63
     </file>
64 64
     <file xil_pn:name="fw/rom.vhd" xil_pn:type="FILE_VHDL">
65
-      <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="16"/>
66
-      <association xil_pn:name="Implementation" xil_pn:seqID="16"/>
65
+      <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="17"/>
66
+      <association xil_pn:name="Implementation" xil_pn:seqID="17"/>
67 67
     </file>
68 68
     <file xil_pn:name="io/leds.vhd" xil_pn:type="FILE_VHDL">
69
-      <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="13"/>
70
-      <association xil_pn:name="Implementation" xil_pn:seqID="13"/>
69
+      <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="14"/>
70
+      <association xil_pn:name="Implementation" xil_pn:seqID="14"/>
71 71
     </file>
72 72
     <file xil_pn:name="constraints/leds.ucf" xil_pn:type="FILE_UCF">
73 73
       <association xil_pn:name="Implementation" xil_pn:seqID="0"/>
... ...
@@ -76,12 +76,12 @@
76 76
       <association xil_pn:name="Implementation" xil_pn:seqID="0"/>
77 77
     </file>
78 78
     <file xil_pn:name="io/cyc_cnt.vhd" xil_pn:type="FILE_VHDL">
79
-      <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="15"/>
80
-      <association xil_pn:name="Implementation" xil_pn:seqID="15"/>
79
+      <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="16"/>
80
+      <association xil_pn:name="Implementation" xil_pn:seqID="16"/>
81 81
     </file>
82 82
     <file xil_pn:name="io/lcd.vhd" xil_pn:type="FILE_VHDL">
83
-      <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="14"/>
84
-      <association xil_pn:name="Implementation" xil_pn:seqID="14"/>
83
+      <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="15"/>
84
+      <association xil_pn:name="Implementation" xil_pn:seqID="15"/>
85 85
     </file>
86 86
     <file xil_pn:name="io/lcd_pins.vhd" xil_pn:type="FILE_VHDL">
87 87
       <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="10"/>
... ...
@@ -91,30 +91,37 @@
91 91
       <association xil_pn:name="Implementation" xil_pn:seqID="0"/>
92 92
     </file>
93 93
     <file xil_pn:name="fw/ram.0.vhd" xil_pn:type="FILE_VHDL">
94
+      <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="21"/>
95
+      <association xil_pn:name="Implementation" xil_pn:seqID="21"/>
96
+    </file>
97
+    <file xil_pn:name="fw/ram.1.vhd" xil_pn:type="FILE_VHDL">
94 98
       <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="20"/>
95 99
       <association xil_pn:name="Implementation" xil_pn:seqID="20"/>
96 100
     </file>
97
-    <file xil_pn:name="fw/ram.1.vhd" xil_pn:type="FILE_VHDL">
101
+    <file xil_pn:name="fw/ram.2.vhd" xil_pn:type="FILE_VHDL">
98 102
       <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="19"/>
99 103
       <association xil_pn:name="Implementation" xil_pn:seqID="19"/>
100 104
     </file>
101
-    <file xil_pn:name="fw/ram.2.vhd" xil_pn:type="FILE_VHDL">
105
+    <file xil_pn:name="fw/ram.3.vhd" xil_pn:type="FILE_VHDL">
102 106
       <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="18"/>
103 107
       <association xil_pn:name="Implementation" xil_pn:seqID="18"/>
104 108
     </file>
105
-    <file xil_pn:name="fw/ram.3.vhd" xil_pn:type="FILE_VHDL">
106
-      <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="17"/>
107
-      <association xil_pn:name="Implementation" xil_pn:seqID="17"/>
108
-    </file>
109 109
     <file xil_pn:name="io/switches_pins.vhd" xil_pn:type="FILE_VHDL">
110 110
       <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="9"/>
111 111
       <association xil_pn:name="Implementation" xil_pn:seqID="9"/>
112 112
     </file>
113 113
     <file xil_pn:name="io/switches.vhd" xil_pn:type="FILE_VHDL">
114
+      <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="13"/>
115
+      <association xil_pn:name="Implementation" xil_pn:seqID="13"/>
116
+    </file>
117
+    <file xil_pn:name="constraints/switches.ucf" xil_pn:type="FILE_UCF">
118
+      <association xil_pn:name="Implementation" xil_pn:seqID="0"/>
119
+    </file>
120
+    <file xil_pn:name="io/uart.vhd" xil_pn:type="FILE_VHDL">
114 121
       <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="12"/>
115 122
       <association xil_pn:name="Implementation" xil_pn:seqID="12"/>
116 123
     </file>
117
-    <file xil_pn:name="constraints/switches.ucf" xil_pn:type="FILE_UCF">
124
+    <file xil_pn:name="constraints/uart.ucf" xil_pn:type="FILE_UCF">
118 125
       <association xil_pn:name="Implementation" xil_pn:seqID="0"/>
119 126
     </file>
120 127
   </files>
... ...
@@ -433,6 +440,7 @@
433 440
     <binding xil_pn:location="/e_system" xil_pn:name="constraints/clk.ucf"/>
434 441
     <binding xil_pn:location="/e_system" xil_pn:name="constraints/lcd.ucf"/>
435 442
     <binding xil_pn:location="/e_system" xil_pn:name="constraints/switches.ucf"/>
443
+    <binding xil_pn:location="/e_system" xil_pn:name="constraints/uart.ucf"/>
436 444
   </bindings>
437 445
 
438 446
   <libraries/>
... ...
@@ -9,7 +9,8 @@ ENTITY e_system IS
9 9
         clk:            IN  std_logic;
10 10
         pin_o_leds:     OUT std_logic_vector(7 DOWNTO 0);
11 11
         pin_o_lcd:      OUT t_io_lcd_pins;
12
-        pin_i_switches: IN  t_io_switches_pins
12
+        pin_i_switches: IN  t_io_switches_pins;
13
+        pin_o_uart_tx:  OUT std_logic
13 14
     );
14 15
 END ENTITY e_system;
15 16
 
... ...
@@ -35,6 +36,10 @@ ARCHITECTURE a_system OF e_system IS
35 36
     SIGNAL s_lcd_wr_en:   std_logic_vector( 3 DOWNTO 0);
36 37
     SIGNAL s_switches_addr:    std_logic_vector( 2 DOWNTO 0);
37 38
     SIGNAL s_switches_rd_data: std_logic_vector(31 DOWNTO 0);
39
+    SIGNAL s_uart_addr:    std_logic_vector( 3 DOWNTO 0);
40
+    SIGNAL s_uart_rd_data: std_logic_vector(31 DOWNTO 0);
41
+    SIGNAL s_uart_wr_data: std_logic_vector(31 DOWNTO 0);
42
+    SIGNAL s_uart_wr_en:   std_logic_vector( 3 DOWNTO 0);
38 43
     SIGNAL s_cyc_cnt_rd_data: std_logic_vector(31 DOWNTO 0);
39 44
     SIGNAL s_cyc_cnt_wr_data: std_logic_vector(31 DOWNTO 0);
40 45
     SIGNAL s_cyc_cnt_wr_en:   std_logic;
... ...
@@ -148,6 +153,18 @@ ARCHITECTURE a_system OF e_system IS
148 153
         );
149 154
     END COMPONENT e_io_switches;
150 155
 
156
+    COMPONENT e_io_uart IS
157
+        PORT (
158
+            rst:       IN  std_logic;
159
+            clk:       IN  std_logic;
160
+            i_addr:    IN  std_logic_vector( 1 DOWNTO 0);
161
+            o_rd_data: OUT std_logic_vector(31 DOWNTO 0);
162
+            i_wr_data: IN  std_logic_vector(31 DOWNTO 0);
163
+            i_wr_en:   IN  std_logic_vector( 3 DOWNTO 0);
164
+            pin_o_tx:  OUT std_logic
165
+        );
166
+    END COMPONENT e_io_uart;
167
+
151 168
     COMPONENT e_io_cyc_cnt IS
152 169
         PORT (
153 170
             rst:       IN  std_logic;
... ...
@@ -188,6 +205,7 @@ BEGIN
188 205
                     s_leds_rd_data,
189 206
                     s_lcd_rd_data,
190 207
                     s_switches_rd_data,
208
+                    s_uart_rd_data,
191 209
                     s_cyc_cnt_rd_data)
192 210
         VARIABLE v_wr_en_word: std_logic;
193 211
     BEGIN
... ...
@@ -202,6 +220,9 @@ BEGIN
202 220
         s_lcd_wr_data <= (OTHERS => '0');
203 221
         s_lcd_wr_en   <= (OTHERS => '0');
204 222
         s_switches_addr <= (OTHERS => '0');
223
+        s_uart_addr    <= (OTHERS => '0');
224
+        s_uart_wr_data <= (OTHERS => '0');
225
+        s_uart_wr_en   <= (OTHERS => '0');
205 226
         s_cyc_cnt_wr_data <= (OTHERS => '0');
206 227
         s_cyc_cnt_wr_en   <= '0';
207 228
         IF s_dbus_addr(31) = '0' THEN
... ...
@@ -222,6 +243,11 @@ BEGIN
222 243
                 WHEN X"02" =>
223 244
                     s_dbus_rd_data  <= s_switches_rd_data;
224 245
                     s_switches_addr <= s_dbus_addr(2 DOWNTO 0);
246
+                WHEN X"03" =>
247
+                    s_dbus_rd_data <= s_uart_rd_data;
248
+                    s_uart_addr    <= s_dbus_addr(3 DOWNTO 0);
249
+                    s_uart_wr_data <= s_dbus_wr_data;
250
+                    s_uart_wr_en   <= s_dbus_wr_en;
225 251
                 WHEN X"10" =>
226 252
                     s_dbus_rd_data    <= s_cyc_cnt_rd_data;
227 253
                     s_cyc_cnt_wr_data <= s_dbus_wr_data;
... ...
@@ -308,6 +334,17 @@ BEGIN
308 334
             pin_i_switches => pin_i_switches
309 335
         );
310 336
 
337
+    uart: e_io_uart
338
+        PORT MAP (
339
+            rst       => rst,
340
+            clk       => clk,
341
+            i_addr    => s_uart_addr(3 DOWNTO 2),
342
+            o_rd_data => s_uart_rd_data,
343
+            i_wr_data => s_uart_wr_data,
344
+            i_wr_en   => s_uart_wr_en,
345
+            pin_o_tx  => pin_o_uart_tx
346
+        );
347
+
311 348
     cyc_cnt: e_io_cyc_cnt
312 349
         PORT MAP (
313 350
             rst       => rst,
... ...
@@ -15,13 +15,15 @@ ARCHITECTURE a_testbed OF e_testbed IS
15 15
             clk:            IN  std_logic;
16 16
             pin_o_leds:     OUT std_logic_vector(7 DOWNTO 0);
17 17
             pin_o_lcd:      OUT t_io_lcd_pins;
18
-            pin_i_switches: IN  t_io_switches_pins
18
+            pin_i_switches: IN  t_io_switches_pins;
19
+            pin_o_uart_tx:  OUT std_logic
19 20
         );
20 21
     END COMPONENT e_system;
21 22
 
22 23
     SIGNAL s_clk:       std_logic;
23 24
     SIGNAL pin_leds:    std_logic_vector(7 DOWNTO 0);
24 25
     SIGNAL pin_lcd:     t_io_lcd_pins;
26
+    SIGNAL pin_uart_tx: std_logic;
25 27
 
26 28
 BEGIN
27 29
 
... ...
@@ -30,7 +32,8 @@ BEGIN
30 32
             clk            => s_clk,
31 33
             pin_o_leds     => pin_leds,
32 34
             pin_o_lcd      => pin_lcd,
33
-            pin_i_switches => (sw => (OTHERS => '0'), OTHERS => '0')
35
+            pin_i_switches => (sw => (OTHERS => '0'), OTHERS => '0'),
36
+            pin_o_uart_tx  => pin_uart_tx
34 37
         );
35 38
 
36 39
     p_rst_clk: PROCESS
37 40