Zum Hauptinhalt springen

VHDL - FSMD

  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;