URL
https://opencores.org/ocsvn/manchesteruart/manchesteruart/trunk
Subversion Repositories manchesteruart
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 1 to Rev 2
- ↔ Reverse comparison
Rev 1 → Rev 2
/manchesteruart/trunk/bench/vhdl/manchester_tb.vhd
0,0 → 1,209
--************************************************************************* |
--* * |
--* Copyright (C) 2014 William B Hunter - LGPL * |
--* * |
--* This source file may be used and distributed without * |
--* restriction provided that this copyright statement is not * |
--* removed from the file and that any derivative work contains * |
--* the original copyright notice and the associated disclaimer. * |
--* * |
--* This source file is free software; you can redistribute it * |
--* and/or modify it under the terms of the GNU Lesser General * |
--* Public License as published by the Free Software Foundation; * |
--* either version 2.1 of the License, or (at your option) any * |
--* later version. * |
--* * |
--* This source is distributed in the hope that it will be * |
--* useful, but WITHout ANY WARRANTY; without even the implied * |
--* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR * |
--* PURPOSE. See the GNU Lesser General Public License for more * |
--* details. * |
--* * |
--* You should have received a copy of the GNU Lesser General * |
--* Public License along with this source; if not, download it * |
--* from http://www.opencores.org/lgpl.shtml * |
--* * |
--************************************************************************* |
-- |
-- Engineer: William B Hunter |
-- Create Date: 08/08/2014 |
-- Project: Manchester Uart |
-- File: Manchester_tb.vhd |
-- Description: This is a testbench for the Manchester UART. It consists of two instances of |
-- the UART, both run on independant clocks. The clocks start off at the same frequency ( |
-- 16x 9600 baud), and one is slowly decreaased to check the robustness of the uart to |
-- differences in clock frequencies. Currently it fails when the clocks are about 18% different. |
-- The test bench consists of the two UARTs, each has a feeder process and a capture process. |
-- The feeder sends data to the transmitters, and the capture process is simply to make viewing |
-- the output more convenient. |
|
---------------------------------------------------------------------------------- |
|
|
entity manchester_tb is |
|
end manchester_tb; |
|
|
library IEEE; |
use IEEE.STD_LOGIC_1164.ALL; |
use IEEE.NUMERIC_STD.ALL; |
|
architecture Behavioral of manchester_tb is |
signal sdat_1to2 : std_logic := '1'; |
signal sdat_2to1 : std_logic := '1'; |
signal clk1 : std_logic := '1'; |
signal clk2 : std_logic := '1'; |
signal xrst : std_logic := '1'; |
signal txerr1 : std_logic := '0'; |
signal txidle1 : std_logic := '0'; |
signal rxerr1 : std_logic := '0'; |
signal rxidle1 : std_logic := '0'; |
signal txdata1 : std_logic_vector(15 downto 0) := x"0000"; |
signal txstb1 : std_logic := '0'; |
signal rxdata1 : std_logic_vector(15 downto 0) := x"0000"; |
signal rxstb1 : std_logic := '0'; |
signal txerr2 : std_logic := '0'; |
signal txidle2 : std_logic := '0'; |
signal rxerr2 : std_logic := '0'; |
signal rxidle2 : std_logic := '0'; |
signal txdata2 : std_logic_vector(15 downto 0) := x"0000"; |
signal txstb2 : std_logic := '0'; |
signal rxdata2 : std_logic_vector(15 downto 0) := x"0000"; |
signal rxstb2 : std_logic := '0'; |
signal clk2_time : time := 3.255 ns; |
signal cap1 : std_logic_vector(15 downto 0) := x"0000"; |
signal cap2 : std_logic_vector(15 downto 0) := x"0000"; |
|
begin |
|
xrst <= '1', '0' after 1000 ns; |
|
--clk1 is a fixed 16x 9600 clock |
p_clk1 :process |
begin |
clk1 <= '0'; |
wait for 3.255 us; |
clk1 <= '1'; |
wait for 3.255 us; |
end process; |
|
--this process slowly decreases the clk2 by 100 ns every 10 ms |
p_clkmod :process |
begin |
clk2_time <= 3.255 us; |
while true loop |
wait for 10 ms; |
clk2_time <= clk2_time - 100 ns; |
end loop; |
end process; |
|
--this is the slowly decreasing clock 2 |
p_clk2 :process |
begin |
clk2 <= '0'; |
wait for clk2_time; |
clk2 <= '1'; |
wait for clk2_time; |
end process; |
|
|
--first UART |
u_manch1 : entity work.Manchester(rtl) |
port map( |
clk16x => clk1, |
srst => xrst, |
rxd => sdat_2to1, |
rx_data => rxdata1, |
rx_stb => rxstb1, |
rx_idle => rxidle1, |
fm_err => rxerr1, |
txd => sdat_1to2, |
tx_data => txdata1, |
tx_stb => txstb1, |
tx_idle => txidle1, |
or_err => txerr1 |
); |
|
|
--second UART |
u_manch2 : entity work.Manchester(rtl) |
port map( |
clk16x => clk2, |
srst => xrst, |
rxd => sdat_1to2, |
rx_data => rxdata2, |
rx_stb => rxstb2, |
rx_idle => rxidle2, |
fm_err => rxerr2, |
txd => sdat_2to1, |
tx_data => txdata2, |
tx_stb => txstb2, |
tx_idle => txidle2, |
or_err => txerr2 |
); |
|
--feeder 1 - feeds data into UART1's transmitter |
p_feeder1 : process |
begin |
txdata1 <= x"aaaa"; |
txstb1 <= '0'; |
wait until xrst = '0'; |
for i in 1 to 100 loop |
wait until clk1 = '1'; |
end loop; |
while unsigned(txdata1) < x"abaa" loop |
wait until clk1 = '1'; |
if txidle1 = '1' then |
wait for 400 us; |
wait until clk1 = '0'; |
txdata1 <= std_logic_vector(unsigned(txdata1) + x"0001"); |
txstb1 <= '1'; |
wait until clk1 = '0'; |
txstb1 <= '0'; |
wait until clk1 = '0'; |
end if; |
end loop; |
end process; |
|
|
--feeder 2 - feeds data into UART2's tranmitter |
p_feeder2 : process |
begin |
txdata2 <= x"5555"; |
txstb2 <= '0'; |
wait until xrst = '0'; |
for i in 1 to 100 loop |
wait until clk2 = '1'; |
end loop; |
while unsigned(txdata2) > x"5455" loop |
wait until clk2 = '1'; |
if txidle2 = '1' then |
wait for 400 us; |
wait until clk2 = '0'; |
txdata2 <= std_logic_vector(unsigned(txdata2) - x"0001"); |
txstb2 <= '1'; |
wait until clk2 = '0'; |
txstb2 <= '0'; |
wait until clk2 = '0'; |
end if; |
end loop; |
end process; |
|
--cap1 - captures rx data from UART1's reciever for easy viewing |
p_cap1 : process |
begin |
wait until rxstb1 = '1'; |
wait until clk1 = '0'; |
cap1 <= rxdata1; |
end process; |
|
--cap2 - captures rx data from UART2's reciver for easy viewing |
p_cap2 : process |
begin |
wait until rxstb2 = '1'; |
wait until clk2 = '0'; |
cap2 <= rxdata2; |
end process; |
|
end Behavioral; |
/manchesteruart/trunk/rtl/vhdl/decode.vhd
0,0 → 1,239
--************************************************************************* |
--* * |
--* Copyright (C) 2014 William B Hunter - LGPL * |
--* * |
--* This source file may be used and distributed without * |
--* restriction provided that this copyright statement is not * |
--* removed from the file and that any derivative work contains * |
--* the original copyright notice and the associated disclaimer. * |
--* * |
--* This source file is free software; you can redistribute it * |
--* and/or modify it under the terms of the GNU Lesser General * |
--* Public License as published by the Free Software Foundation; * |
--* either version 2.1 of the License, or (at your option) any * |
--* later version. * |
--* * |
--* This source is distributed in the hope that it will be * |
--* useful, but WITHout ANY WARRANTY; without even the implied * |
--* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR * |
--* PURPOSE. See the GNU Lesser General Public License for more * |
--* details. * |
--* * |
--* You should have received a copy of the GNU Lesser General * |
--* Public License along with this source; if not, download it * |
--* from http://www.opencores.org/lgpl.shtml * |
--* * |
--************************************************************************* |
-- |
-- Engineer: William B Hunter |
-- Create Date: 08/08/2014 |
-- Project: Manchester Uart |
-- File: decode.vhd |
-- Description: This decoder recieves short bursts of 16 bit data words encoded with as manchester data. |
-- Because this is not a stream decoder, it has no sync pattern or packet alignment typical of manchester decoders. |
-- It therefore uses start and stop bits much like a UART. Both the start and stop bits are always ones. The idle |
-- state is always high, and the ones are a low to high transition in the middle of the bit period, and a zero is a |
-- high to low transition in the middle of the bit period. A high for 3 bit periods is a reset/resync. |
---------------------------------------------------------------------------------- |
|
|
library IEEE; |
use IEEE.STD_LOGIC_1164.ALL; |
use IEEE.NUMERIC_STD.ALL; |
|
entity decode is |
Port( |
clk16x : in STD_LOGIC; |
srst : in STD_LOGIC; |
rxd : in STD_LOGIC; |
rx_data : out STD_LOGIC_VECTOR (15 downto 0); |
rx_stb : out STD_LOGIC; |
fm_err : out STD_LOGIC; |
rx_idle : out STD_LOGIC |
); |
end decode; |
|
architecture rtl of decode is |
signal shifter : std_logic_vector(15 downto 0); |
signal tick_cnt : integer range 0 to 31 := 0; |
signal bit_cnt : integer range 0 to 15 := 0; |
signal rcv_stb : std_logic := '0'; |
signal debounce : std_logic_vector(3 downto 0) := (others=>'1'); |
signal filt : std_logic := '1'; |
signal filt_old : std_logic := '1'; |
signal fall_det : std_logic := '0'; |
signal rst_det : std_logic := '0'; |
signal rst_cnt :integer range 0 to 15 := 0; |
signal rise_det : std_logic := '0'; |
|
|
type rcv_state_type is (SM_SEEK, SM_START, SM_RCV, SM_END, SM_ERR); |
signal rcv_state : rcv_state_type := SM_SEEK; |
|
begin |
--this process debounces the input signal to remove noise. It also detects rising |
-- and falling edges and reset conditions. |
p_debounce: process(clk16x) |
begin |
if rising_edge(clk16x) then |
if srst = '1' then |
debounce <= "1111"; |
rise_det <= '0'; |
fall_det <= '0'; |
rst_cnt <= 0; |
rst_det <= '0'; |
filt_old <= '1'; |
else |
if filt_old = '0' and filt = '1' then |
rise_det <= '1'; |
fall_det <= '0'; |
elsif filt_old = '1' and filt = '0' then |
rise_det <= '0'; |
fall_det <= '1'; |
else |
rise_det <= '0'; |
fall_det <= '0'; |
end if; |
if filt = '0' then |
rst_cnt <= 0; |
rst_det <= '0'; |
elsif rst_cnt = 47 then |
rst_det <= '1'; |
else |
rst_det <= '0'; |
rst_cnt <= rst_cnt +1; |
end if; |
debounce <= debounce(2 downto 0) & rxd; |
filt_old <= filt; |
end if; |
end if; |
end process; |
|
--this is the actual debounce logic. It is a basic 2 out of three majority vote |
with debounce(3 downto 1) select filt <= |
'1' when "111", |
'1' when "110", |
'1' when "101", |
'1' when "011", |
'0' when others; |
|
|
--This process is the main reciever. It detects the start bit, 16 data bits and the stop bit. |
-- it does this by having a window for which it looks for the midbit transistions. When a transition is found, |
-- it syncs on the new transition so that it can look for the next. This allows the wide variation in clock rates |
-- between the transmitter and reciever. |
p_reciever: process(clk16x) |
begin |
if rising_edge(clk16x) then |
if srst = '1' then |
rcv_state <= SM_SEEK; |
rcv_stb <= '0'; |
tick_cnt <= 0; |
bit_cnt <= 0; |
else |
case rcv_state is |
--The idle state is high, so look for the leading edge of the start bit which is a falling edge |
when SM_SEEK => |
rcv_stb <= '0'; |
tick_cnt <= 0; |
bit_cnt <= 0; |
if fall_det = '1' then |
rcv_state <= SM_START; |
end if; |
--After the falling edge, there should be the mid bit rising edge of the start bit, Make sure |
-- this appears in the right window |
when SM_START => |
--skip the first 4 clock periods |
if tick_cnt < 4 then |
tick_cnt <= tick_cnt + 1; |
--The active window is ticks 4 to 10, look for the rising edge in this window |
elsif tick_cnt < 11 then |
--a rising edge in the window allows us to start recieveing data |
if rise_det = '1' then |
tick_cnt <= 0; |
rcv_state <= SM_RCV; |
--two falling edges in a row is an error |
elsif fall_det = '1' then |
rcv_state <= SM_ERR; |
tick_cnt <= 0; |
bit_cnt <= 0; |
else |
tick_cnt <= tick_cnt + 1; |
end if; |
--if there was no rising edge in the window, than error out |
else |
rcv_state <= SM_ERR; |
tick_cnt <= 0; |
bit_cnt <= 0; |
end if; |
when SM_RCV => |
--During recieve, we only look for the mid bit transisions in the window of |
-- 12 to 18 ticks from the previous mid bit transition |
if tick_cnt < 12 then |
tick_cnt <= tick_cnt + 1; |
elsif tick_cnt < 19 then |
if rise_det = '1' or fall_det = '1' then |
tick_cnt <= 0; |
shifter <= shifter(14 downto 0) & rise_det; |
if bit_cnt = 15 then |
rcv_state <= SM_END; |
tick_cnt <= 0; |
else |
bit_cnt <= bit_cnt + 1; |
end if; |
else |
tick_cnt <= tick_cnt + 1; |
end if; |
else |
rcv_state <= SM_ERR; |
tick_cnt <= 0; |
bit_cnt <= 0; |
end if; |
when SM_END => |
--after all 16 data bits, we should see a stop bit which is always 1 (rising edge) |
if tick_cnt < 12 then |
tick_cnt <= tick_cnt + 1; |
elsif tick_cnt < 19 then |
if rise_det = '1' then |
tick_cnt <= 0; |
bit_cnt <= 0; |
rcv_stb <= '1'; |
rcv_state <= SM_SEEK; |
elsif fall_det = '1' then |
rcv_state <= SM_ERR; |
tick_cnt <= 0; |
bit_cnt <= 0; |
else |
tick_cnt <= tick_cnt + 1; |
end if; |
else |
rcv_state <= SM_ERR; |
tick_cnt <= 0; |
bit_cnt <= 0; |
end if; |
--this state handles the error conditions. The error persists until a reset condition |
--It is up to external logic to latch errors if nessesary |
when SM_ERR => |
rcv_stb <= '0'; |
tick_cnt <= 4; |
bit_cnt <= 0; |
if rst_det = '1' then |
rcv_state <= SM_SEEK; |
end if; |
--we should never get here |
when others => |
rcv_stb <= '0'; |
tick_cnt <= 4; |
bit_cnt <= 0; |
rcv_state <= SM_SEEK; |
end case; |
end if; --srst |
end if; --clk16x |
end process; |
|
rx_idle <= '1' when rcv_state = SM_SEEK else '0'; |
fm_err <= '1' when rcv_state = SM_ERR else '0'; |
rx_data <= shifter; |
rx_stb <= rcv_stb; |
|
end rtl; |
/manchesteruart/trunk/rtl/vhdl/Manchester.vhd
0,0 → 1,108
--************************************************************************* |
--* * |
--* Copyright (C) 2014 William B Hunter - LGPL * |
--* * |
--* This source file may be used and distributed without * |
--* restriction provided that this copyright statement is not * |
--* removed from the file and that any derivative work contains * |
--* the original copyright notice and the associated disclaimer. * |
--* * |
--* This source file is free software; you can redistribute it * |
--* and/or modify it under the terms of the GNU Lesser General * |
--* Public License as published by the Free Software Foundation; * |
--* either version 2.1 of the License, or (at your option) any * |
--* later version. * |
--* * |
--* This source is distributed in the hope that it will be * |
--* useful, but WITHout ANY WARRANTY; without even the implied * |
--* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR * |
--* PURPOSE. See the GNU Lesser General Public License for more * |
--* details. * |
--* * |
--* You should have received a copy of the GNU Lesser General * |
--* Public License along with this source; if not, download it * |
--* from http://www.opencores.org/lgpl.shtml * |
--* * |
--************************************************************************* |
-- |
-- Engineer: William B Hunter |
-- Create Date: 08/08/2014 |
-- Project: Manchester Uart |
-- File: manchester.vhd - a Manchester encoded UART |
-- Description: This is a wrapper for teh encoder and decoder. |
-- |
-- Justification: The use of the Manchester UART has some advantages of a standard UART. |
-- 1. The Manchester UART can tolerate about 18% difference in timing between the transmitter and reciever. |
-- This is very useful if one or both of the systems don't have an accurate clock. RC oscillators can be used |
-- instead of crystals. No PLL is required for recovery of the data signal. |
-- 2. The Manchester UART is better when powering low power (devices off of the serial lines (parasitic power). |
-- A typical UART can have a continuous low output for 9 bit times, whereas the Manchester UART has a max |
-- low time of 1 bit time. |
-- There is also a disadvantage of the Manchester UART. It can have twice the transitions per bit compared to |
-- a normal UART.This requires twice the bandwidth in the UART dirvers for a given data rate. |
-- |
-- Operational Description: This is a Manchester encoded UART - It encodes 16 bit data grams using Manchester encoding. |
-- This unit is designed for short data bursts rather than stream encoding typical of Manchester systesm. |
-- Since this is a burst encoder, it relys on start and stop bits for synchronization instead of sync patterns. |
-- The Manchester UART goes to an idle state when no data is being transmitted. The idle state is a logic high. |
-- Bits are encoded by a high to low (zero) or low to high(one) transition in the middle of the bit period. Start |
-- and stop bits are always ones (low to high transitions). |
---------------------------------------------------------------------------------- |
|
|
library IEEE; |
use IEEE.STD_LOGIC_1164.ALL; |
|
-- Uncomment the following library declaration if using |
-- arithmetic functions with Signed or Unsigned values |
--use IEEE.NUMERIC_STD.ALL; |
|
-- Uncomment the following library declaration if instantiating |
-- any Xilinx leaf cells in this code. |
--library UNISIM; |
--use UNISIM.VComponents.all; |
|
entity Manchester is |
Port ( |
clk16x : in STD_LOGIC; |
srst : in STD_LOGIC; |
rxd : in STD_LOGIC; |
rx_data : out STD_LOGIC_VECTOR (15 downto 0); |
rx_stb : out STD_LOGIC; |
rx_idle : out STD_LOGIC; |
fm_err : out STD_LOGIC; |
txd : out STD_LOGIC; |
tx_data : in STD_LOGIC_VECTOR (15 downto 0); |
tx_stb : in STD_LOGIC; |
tx_idle : out STD_LOGIC; |
or_err : out STD_LOGIC |
); |
end Manchester; |
|
architecture rtl of Manchester is |
|
begin |
|
u_decode : entity work.decode(rtl) |
port map( |
clk16x => clk16x, |
srst => srst, |
rxd => rxd, |
rx_data => rx_data, |
rx_stb => rx_stb, |
fm_err => fm_err, |
rx_idle => rx_idle |
); |
|
u_encode : entity work.encode(rtl) |
port map( |
clk16x => clk16x, |
srst => srst, |
txd => txd, |
tx_data => tx_data, |
tx_stb => tx_stb, |
or_err => or_err, |
tx_idle => tx_idle |
); |
|
end rtl; |
/manchesteruart/trunk/rtl/vhdl/encode.vhd
0,0 → 1,162
--************************************************************************* |
--* * |
--* Copyright (C) 2014 William B Hunter - LGPL * |
--* * |
--* This source file may be used and distributed without * |
--* restriction provided that this copyright statement is not * |
--* removed from the file and that any derivative work contains * |
--* the original copyright notice and the associated disclaimer. * |
--* * |
--* This source file is free software; you can redistribute it * |
--* and/or modify it under the terms of the GNU Lesser General * |
--* Public License as published by the Free Software Foundation; * |
--* either version 2.1 of the License, or (at your option) any * |
--* later version. * |
--* * |
--* This source is distributed in the hope that it will be * |
--* useful, but WITHout ANY WARRANTY; without even the implied * |
--* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR * |
--* PURPOSE. See the GNU Lesser General Public License for more * |
--* details. * |
--* * |
--* You should have received a copy of the GNU Lesser General * |
--* Public License along with this source; if not, download it * |
--* from http://www.opencores.org/lgpl.shtml * |
--* * |
--************************************************************************* |
-- |
-- Engineer: William B Hunter |
-- Create Date: 08/08/2014 |
-- Project: Manchester Uart |
-- File: encode.vhd |
-- Description: This encoder sends out short bursts of 16 bit data words encoded with as manchester data. |
-- Because this is not a stream encoder, it has no sync pattern or packet alignment typical of manchester encoders. |
-- It therefor uses start and stop bits much like a UART. Both the start and stop bits are always ones. The idle |
-- state is always high, and the ones are a low to high transition in the middle of the bit period, and a zero is a |
-- high to low transition in the middle of the bit period. A high for 3 bit periods is a reset/resync. |
---------------------------------------------------------------------------------- |
|
|
library IEEE; |
use IEEE.STD_LOGIC_1164.ALL; |
use IEEE.NUMERIC_STD.ALL; |
|
entity encode is |
Port ( |
clk16x : in STD_LOGIC; |
srst : in STD_LOGIC; |
tx_data : in STD_LOGIC_VECTOR (15 downto 0); |
tx_stb : in STD_LOGIC; |
txd : out STD_LOGIC; |
or_err : out STD_LOGIC; |
tx_idle : out STD_LOGIC |
); |
end encode; |
|
architecture rtl of encode is |
signal shifter : std_logic_vector(15 downto 0); |
signal tick_cnt : integer range 0 to 15 := 0; |
signal bit_cnt : integer range 0 to 15 := 0; |
signal txd_int : std_logic := '1'; |
signal err_int : std_logic := '0'; |
|
type txr_state_type is (SM_IDLE, SM_START, SM_SEND, SM_STOP); |
signal txr_state : txr_state_type := SM_IDLE; |
|
begin |
|
p_transmitter: process(clk16x) |
begin |
if rising_edge(clk16x) then |
if srst = '1' then |
txr_state <= SM_IDLE; |
tick_cnt <= 0; |
bit_cnt <= 0; |
else |
case txr_state is |
--wait for a tx strobe to start a transmission |
when SM_IDLE => |
tick_cnt <= 0; |
bit_cnt <= 0; |
if tx_stb = '1' then |
txr_state <= SM_START; |
shifter <= tx_data; |
end if; |
--the start is a one, which is 8 ticks low followed by 8 ticks high |
when SM_START => |
if tick_cnt < 8 then |
txd_int <= '0'; |
tick_cnt <= tick_cnt + 1; |
elsif tick_cnt < 15 then |
txd_int <= '1'; |
tick_cnt <= tick_cnt + 1; |
else |
txd_int <= '1'; |
tick_cnt <= 0; |
bit_cnt <= 0; |
txr_state <= SM_SEND; |
end if; |
when SM_SEND => |
--for each bit, a one is 8 ticks low followed by 8 ticks high, and a zero is 8 ticks high followed by 8 ticks low |
if tick_cnt < 8 then |
txd_int <= not shifter(15); |
tick_cnt <= tick_cnt + 1; |
elsif tick_cnt < 15 then |
txd_int <= shifter(15); |
tick_cnt <= tick_cnt + 1; |
else |
txd_int <= shifter(15); |
tick_cnt <= 0; |
shifter <= shifter(14 downto 0) & '1'; |
--at end of this bit check to see if we have more bits or if it's time for the stop bit |
if bit_cnt < 15 then |
bit_cnt <= bit_cnt + 1; |
else |
bit_cnt <=0; |
txr_state <= SM_STOP; |
end if; |
end if; |
when SM_STOP => |
--stop bits are always ones, which are 8 ticks low followed by 8 ticks high |
if tick_cnt < 8 then |
txd_int <= '0'; |
tick_cnt <= tick_cnt + 1; |
elsif tick_cnt < 15 then |
txd_int <= '1'; |
tick_cnt <= tick_cnt + 1; |
else |
txd_int <= '1'; |
tick_cnt <= 0; |
txr_state <= SM_IDLE; |
end if; |
--we should never get to the iothers state. |
when others => |
tick_cnt <= 4; |
bit_cnt <= 0; |
txr_state <= SM_IDLE; |
end case; |
end if; --srst |
end if; --clk16x |
end process; |
|
|
--An overrun error occurs when the transmit strobe is triggered and we are not finished with the previous state. |
-- The error is cleared when the transmitter goes back to idle |
p_or_err: process(clk16x) |
begin |
if rising_edge(clk16x) then |
if srst = '1' then |
err_int <='0'; |
elsif tx_stb = '1' and txr_state /= SM_IDLE then |
err_int <= '1'; |
elsif txr_state = SM_IDLE then |
err_int <= '0'; |
end if; |
end if; |
end process; |
|
txd <= txd_int; |
or_err <= err_int; |
tx_idle <= '1' when txr_state = SM_IDLE else '0'; |
|
end rtl; |