1-- Literatur: EDS4 Uebungsbeispiel von Markus Pfaff, Martina Zeinzinger,
2-- Friedrich Seebacher (FH-Hagenberg)
3
4--IfRs232Tx-p.vhd
5 library ieee;
6 use ieee.std_logic_1164.all;
7 use ieee.numeric_std.all;
8
9 use work.global.all;
10
11 package IfRs232Tx is
12 type acRs232Tx is record
13 DataBitWidth : natural;
14 end record;
15
16 constant cRs232Tx : acRs232Tx := (
17 DataBitWidth => 8
18 );
19
20 type aiRs232Tx is record
21 -----------------------------------------------------------
22 -- Control inputs
23 -----------------------------------------------------------
24 -- Transmit if activated and stop transmission if not
25 -- activated, but finish transmission of the current data.
26 Transmit : std_ulogic;
27 -- Is data available which can be read with the next rising
28 -- edge of the clk and sent from then on?
29 DataAvailable : std_ulogic;
30 -- The baud rate for the bits which are sent out is
31 -- determined by an external unit called a baud rate
32 -- generator or simply strobe generator. The strobe we get
33 -- from this unit is input by the port
34 BitStrobe : std_ulogic;
35 -----------------------------------------------------------
36 -- Data inputs
37 -----------------------------------------------------------
38 Data : std_ulogic_vector(cRs232Tx.DataBitWidth-1
39 downto 0);
40 end record;
41
42 type aoRs232Tx is record
43 -----------------------------------------------------------
44 -- Status outputs
45 -----------------------------------------------------------
46 -- Clock egdge 1
47 -- The source of parallel data (e.g. a FIFO) feeding this
48 -- transmitter will offer a data word at its data output and
49 -- flag data validity at the same time via activation of a
50 -- control output (named DataValid or similar).
51 -- Clock edge 2
52 -- The transmitter reacts on the validity of the input data
53 -- by reading the data into an internal register flagging
54 -- that the data was read.
55 -- Clock edge 3
56 -- The transmitter deactivates the "data was read" flag
57 -- again. The data source may provide new valid data keeping
58 -- DataValid active or may run out of valid data for the
59 -- moment, thus deactivating DataValid.
60 DataWasRead : std_ulogic;
61 -----------------------------------------------------------
62 -- Result outputs
63 -----------------------------------------------------------
64 -- The serial data line carying the Tx signal.
65 Tx : std_ulogic;
66 end record;
67
68 end IfRs232Tx;
69
70
71-- Rs232Tx-e.vhd
72 library IEEE;
73 use IEEE.std_logic_1164.all;
74 use IEEE.numeric_std.all;
75
76 use work.Global.all;
77 use work.IfRs232Tx.all;
78
79 entity Rs232Tx is
80 port (
81 inResetAsync : in std_ulogic;
82 iClk : in std_ulogic;
83
84 iRs232Tx : in aiRs232Tx;
85 oRs232Tx : out aoRs232Tx
86 );
87 end Rs232Tx;
88
89
90-- Rs232Tx-Rtl-a.vhd
91 architecture Rtl of Rs232Tx is
92
93 constant cTxLineStartBitVal : std_ulogic := '0';
94 constant cTxLineStopBitAndIdleVal : std_ulogic := '1';
95
96 type aDataInputState is (CanAcceptNewData,
97 FreshDataArrived,
98 DataBufferBusy);
99 type aRegion is (StartBit, DataBits,
100 ParityBit, StopBit,
101 StopBitAndIdle);
102
103 -- Register structure of design
104 type aRegSet is record
105 DataInputState : aDataInputState;
106 Region : aRegion;
107 BitIdx : natural range 0 to cRs232Tx.DataBitWidth-1;
108 DataWasRead : std_ulogic;
109 Data : std_ulogic_vector(cRs232Tx.DataBitWidth-1
110 downto 0);
111 parity : std_ulogic;
112 Tx : std_ulogic;
113 end record;
114
115 constant cInitValR : aRegSet := (
116 DataInputState => CanAcceptNewData,
117 Region => StopBitAndIdle, --Idle,
118 BitIdx => 0,
119 DataWasRead => cInactivated,
120 Data => (others => '0'),
121 parity => cInactivated,
122 Tx => cTxLineStopBitAndIdleVal
123 );
124
125 -- All registers in design
126 signal R, NextR : aRegSet;
127 begin
128
129 Comb : process (R, iRs232Tx)
130 begin
131 -- Set the defaults.
132 NextR <= R;
133
134 -- Parallel data input part of transmitter .
135 NextR.DataWasRead <= cInactivated ;
136 case R.DataInputState is
137 when CanAcceptNewData =>
138 -- We are waiting for data to be transmitted .
139 if (( iRs232Tx.Transmit = cActivated ) and
140 ( iRs232Tx.DataAvailable = cActivated )) then
141 NextR.Data <= iRs232Tx.Data ;
142 NextR.DataInputState <= FreshDataArrived ;
143 NextR.DataWasRead <= cActivated ;
144 end if;
145 when FreshDataArrived =>
146 -- We have loaded new data into the send register .
147 if ( R.Region = StartBit ) then
148 NextR.DataInputState <= DataBufferBusy ;
149 end if;
150 when DataBufferBusy =>
151 -- The send register is still occupied .
152 if (R.Region = StopBitAndIdle ) then
153 NextR.DataInputState <= CanAcceptNewData ;
154 end if;
155 end case ;
156
157 -- Serial output part of transmitter .
158 case R.Region is
159 when StartBit =>
160 NextR.Tx <= cTxLineStartBitVal ;
161 if iRs232Tx.BitStrobe = cActivated then
162 NextR.Region <= DataBits ;
163 NextR.BitIdx <= 0;
164 end if;
165 when DataBits =>
166 NextR.Tx <= R.Data (R.BitIdx );
167 if iRs232Tx.BitStrobe = cActivated then
168 if R.BitIdx = 0 then
169 NextR.parity <= R.Data (R.BitIdx);
170 else
171 NextR.parity <= R.parity xor
172 R.Data (R.BitIdx);
173 end if;
174 if R.BitIdx = cRs232Tx.DataBitWidth -1 then
175 -- All bits sent .
176 NextR.Region <= ParityBit ;
177 else
178 -- Send next bit .
179 NextR.BitIdx <= R.BitIdx + 1;
180 end if;
181 end if;
182 when ParityBit => -- gerade Parit�t
183 NextR.Tx <= R.parity ;
184 if iRs232Tx.BitStrobe = cActivated then
185 NextR.Region <= StopBit ;
186 end if;
187 when StopBit =>
188 NextR.Tx <= cTxLineStopBitAndIdleVal ;
189 if iRs232Tx.BitStrobe = cActivated then
190 NextR.Region <= StopBitAndIdle ;
191 end if;
192 when StopBitAndIdle =>
193 NextR.Tx <= cTxLineStopBitAndIdleVal ;
194 if iRs232Tx.BitStrobe = cActivated then
195 if R.DataInputState = FreshDataArrived then
196 NextR.Region <= StartBit ;
197 end if;
198 end if;
199 end case;
200 end process Comb;
201
202 ----------------------
203 -- Update register values
204 ----------------------
205 Registering : process(iClk, inResetAsync)
206 begin
207 if (inResetAsync = cnActivated) then
208 R <= cInitValR;
209 elsif ((iClk'event) and (iClk = '1')) then
210 R <= NextR;
211 end if;
212 end process;
213
214 -----------------------------
215 -- Connect registers to ports
216 -----------------------------
217 oRs232Tx.DataWasRead <= R.DataWasRead;
218 oRs232Tx.Tx <= R.Tx;
219
220 end Rtl;