aboutsummaryrefslogtreecommitdiffstats
path: root/testsuite/synth/issue2273/mc8051_siu_rtl.vhd
diff options
context:
space:
mode:
Diffstat (limited to 'testsuite/synth/issue2273/mc8051_siu_rtl.vhd')
-rw-r--r--testsuite/synth/issue2273/mc8051_siu_rtl.vhd1202
1 files changed, 1202 insertions, 0 deletions
diff --git a/testsuite/synth/issue2273/mc8051_siu_rtl.vhd b/testsuite/synth/issue2273/mc8051_siu_rtl.vhd
new file mode 100644
index 000000000..b3a9282f1
--- /dev/null
+++ b/testsuite/synth/issue2273/mc8051_siu_rtl.vhd
@@ -0,0 +1,1202 @@
+-------------------------------------------------------------------------------
+-- --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- XX XX X X X X X X X XX --
+-- X X X X X X X X X X X X --
+-- X X X X X X X X X X X X --
+-- X X X X XXXXXX X X XXXXXX X --
+-- X X X X X X X X X --
+-- X X X X X X X X X --
+-- X X X X X X X X X X --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- --
+-- --
+-- O R E G A N O S Y S T E M S --
+-- --
+-- Design & Consulting --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- Web: http://www.oregano.at/ --
+-- --
+-- Contact: mc8051@oregano.at --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- MC8051 - VHDL 8051 Microcontroller IP Core --
+-- Copyright (C) 2001 OREGANO SYSTEMS --
+-- --
+-- This library 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 library 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. --
+-- --
+-- Full details of the license can be found in the file LGPL.TXT. --
+-- --
+-- You should have received a copy of the GNU Lesser General Public --
+-- License along with this library; if not, write to the Free Software --
+-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --
+-- --
+-------------------------------------------------------------------------------
+--
+--
+-- Author: Roland Höller
+--
+-- Filename: mc8051_siu_rtl.vhd
+--
+-- Date of Creation: Mon Aug 9 12:14:48 1999
+--
+-- Version: $Revision: 1.10 $
+--
+-- Date of Latest Version: $Date: 2010-03-24 10:20:48 $
+--
+--
+-- Description: Serial interface unit for the mc8051 microcontroller.
+--
+--
+--
+--
+-------------------------------------------------------------------------------
+architecture rtl of mc8051_siu is
+
+ signal s_rxpre_count : unsigned(5 downto 0); -- Receive prescaler
+ signal s_txpre_count : unsigned(5 downto 0); -- Transmit prescaler
+ signal s_m0_shift_en : std_logic; -- masks out every twelfth
+ -- rising edge of clk
+ signal s_m2_rxshift_en : std_logic; -- mode 2 shift enable
+ signal s_m13_rxshift_en : std_logic; -- mode 1 and 3 shift enable
+ signal s_m2_txshift_en : std_logic; -- mode 2 shift enable
+ signal s_m13_txshift_en : std_logic; -- mode 1 and 3 shift enable
+ signal s_ff0 : std_logic; -- flipflop for edge dedection
+ signal s_ff1 : std_logic; -- flipflop for edge dedection
+ signal s_tf : std_logic; -- synchronised timer flag
+ signal s_mode : unsigned(1 downto 0); -- mode
+ signal s_sm2 : std_logic; -- multi processor comm. bit
+ signal s_detect : std_logic; -- indicates start of recept.
+ signal s_ren : std_logic; -- receive enable
+ signal s_rxd_val : std_logic; -- received data bit
+ signal s_txdm0 : std_logic; -- shift clock for m0
+ signal s_ri : std_logic; -- external receive interrupt
+ signal s_trans : std_logic; -- enable transmission
+ signal s_recv_done : std_logic; -- receive interrupt
+ signal s_tran_done : std_logic; -- transmit interrupt
+ signal s_rb8 : std_logic; -- 8th data bit
+ signal s_tb8 : std_logic; -- 8th data bit
+ signal s_recv_state : unsigned(3 downto 0); -- state reg. of receive unit
+ signal s_tran_state : unsigned(3 downto 0); -- state reg. of transmit unit
+ signal s_rxd_ff0 : std_logic; -- sample flip-flop
+ signal s_rxd_ff1 : std_logic; -- sample flip-flop
+ signal s_rxd_ff2 : std_logic; -- sample flip-flop
+ signal s_det_ff0 : std_logic; -- rec. detect flip-flop
+ signal s_det_ff1 : std_logic; -- rec. detect flip-flop
+ signal s_tran_sh : unsigned(10 downto 0); -- transmission shift register
+ signal s_recv_sh : unsigned(7 downto 0); -- reception shift register
+ signal s_recv_buf : unsigned(7 downto 0); -- reception buffer register
+ signal s_rxm13_ff0 : std_logic; -- generates an enable singal
+ signal s_rxm13_ff1 : std_logic; -- generates an enable singal
+ signal s_txm13_ff0 : std_logic; -- generates an enable singal
+ signal s_txm13_ff1 : std_logic; -- generates an enable singal
+
+begin -- architecture rtl
+
+ s_mode(1) <= scon_i(4); -- defines the 4 operating modes
+ s_mode(0) <= scon_i(3);
+ s_ren <= scon_i(1); -- receive enable
+ s_sm2 <= scon_i(2); -- 1 time or half time baud rate
+ s_tb8 <= scon_i(0); -- 9th data bit for transmission
+ s_ri <= scon_i(5); -- the receive interrupt bit of the
+ -- control unit
+ sbuf_o <= std_logic_vector(s_recv_buf); -- the receive buffer output
+ scon_o(0) <= s_recv_done; -- set when reception is completed
+ scon_o(1) <= s_tran_done; -- set when transmission is completed
+ scon_o(2) <= s_rb8; -- 9th data bit of reception
+
+-------------------------------------------------------------------------------
+ -- The two flip flops are updated every rising clock edge of clk.
+ -- If a rising edge
+ -- on the port tf_i is dedected the signal s_tf is set to 1 for one period.
+ --
+ -- The transmission start signal s_trans is generated and held high till
+ -- the statemachine has been launched with its first shift.
+ --
+ -- The shift clock for mode0 is generated. It toggles with the half
+ -- s_m0_shift_en rate.
+
+ s_tf <= '1' when (s_ff0 = '1' and s_ff1 = '0') else '0';
+
+ p_sample_tf: process (clk, cen, reset)
+
+ begin
+
+ if reset = '1' then
+ s_ff0 <= '0';
+ s_ff1 <= '0';
+ s_trans <= '0';
+ else
+ if clk'event and clk = '1' and cen='1' then
+ s_ff0 <= tf_i;
+ s_ff1 <= s_ff0;
+
+ if trans_i = '1' then
+ s_trans <= '1';
+ else
+ case s_mode is
+ when ("00") =>
+ if s_m0_shift_en = '1' then
+ s_trans <= '0';
+ end if;
+ when ("01") =>
+ if s_m13_txshift_en = '1' then
+ s_trans <= '0';
+ end if;
+ when ("10") =>
+ if s_m2_txshift_en = '1' then
+ s_trans <= '0';
+ end if;
+ when others =>
+ if s_m13_txshift_en = '1' then
+ s_trans <= '0';
+ end if;
+ end case;
+ end if;
+ end if;
+ end if;
+
+ end process p_sample_tf;
+
+
+-------------------------------------------------------------------------------
+ -- The register s_rxpre_count is driven with the system clock clk. So a
+ -- good enable signal (which is stable when clk has its rising edge) can be
+ -- derived to mask out every pulse of clk needed.
+ -- s_m0_shift_en activates every twelfth clock cycle
+ -- s_m2_shift_en activates baud rates of 1/32 or 1/64 the clock frequenzy
+ -- depending on signal smod_i
+ -- s_m13_shift_en activates baud rates depending on timer/counter1 flag
+
+ s_m0_shift_en <= '1' when s_txpre_count(3 downto 0) = conv_unsigned(11,5)
+ else '0';
+
+ s_m2_rxshift_en <= '1' when (s_rxpre_count(4 downto 0) = conv_unsigned(31,5)
+ and smod_i = '1') or
+ (s_rxpre_count = conv_unsigned(63,6)
+ and smod_i = '0')
+ else '0';
+ s_m13_rxshift_en <= '1' when s_rxm13_ff0 = '1' and s_rxm13_ff1 = '0'
+ else '0';
+
+ s_m2_txshift_en <= '1' when (s_txpre_count(4 downto 0) = conv_unsigned(31,5)
+ and smod_i = '1') or
+ (s_txpre_count = conv_unsigned(63,6)
+ and smod_i = '0')
+ else '0';
+ s_m13_txshift_en <= '1' when s_txm13_ff0 = '1' and s_txm13_ff1 = '0'
+ else '0';
+
+ p_divide_clk: process (clk, cen, reset)
+
+ begin
+
+ if reset = '1' then
+ s_rxpre_count <= conv_unsigned(0,6);
+ s_txpre_count <= conv_unsigned(0,6);
+ s_rxm13_ff0 <= '0';
+ s_rxm13_ff1 <= '0';
+ s_txm13_ff0 <= '0';
+ s_txm13_ff1 <= '0';
+ else
+ if clk'event and clk='1' and cen='1' then
+
+ s_rxm13_ff1 <= s_rxm13_ff0;
+ s_txm13_ff1 <= s_txm13_ff0;
+
+ if trans_i = '1' then
+ s_txpre_count <= conv_unsigned(0,6);
+ else
+ if s_mode=conv_unsigned(0,2) then
+ s_txpre_count <= s_txpre_count + conv_unsigned(1,1);
+ if s_txpre_count = conv_unsigned(11,6) then
+ s_txpre_count <= conv_unsigned(0,6);
+ end if;
+ elsif s_mode=conv_unsigned(2,2) then
+ s_txpre_count <= s_txpre_count + conv_unsigned(1,1);
+ else
+ if s_tf = '1' then
+ s_txpre_count <= s_txpre_count + conv_unsigned(1,1);
+ end if;
+ end if;
+ end if;
+
+ if s_detect = '1' then
+ s_rxpre_count <= conv_unsigned(0,6);
+ else
+ if s_mode=conv_unsigned(0,2) then
+ s_rxpre_count <= s_rxpre_count + conv_unsigned(1,1);
+ if s_rxpre_count = conv_unsigned(11,6) then
+ s_rxpre_count <= conv_unsigned(0,6);
+ end if;
+ elsif s_mode=conv_unsigned(2,2) then
+ s_rxpre_count <= s_rxpre_count + conv_unsigned(1,1);
+ else
+ if s_tf = '1' then
+ s_rxpre_count <= s_rxpre_count + conv_unsigned(1,1);
+ end if;
+ end if;
+ end if;
+
+ if smod_i = '1' then
+ if s_rxpre_count(3 downto 0) = conv_unsigned(15,4) then
+ s_rxm13_ff0 <= '1';
+ else
+ s_rxm13_ff0 <= '0';
+ end if;
+ else
+ if s_rxpre_count(4 downto 0) = conv_unsigned(31,5) then
+ s_rxm13_ff0 <= '1';
+ else
+ s_rxm13_ff0 <= '0';
+ end if;
+ end if;
+
+ if smod_i = '1' then
+ if s_txpre_count(3 downto 0) = conv_unsigned(15,4) then
+ s_txm13_ff0 <= '1';
+ else
+ s_txm13_ff0 <= '0';
+ end if;
+ else
+ if s_txpre_count(4 downto 0) = conv_unsigned(31,5) then
+ s_txm13_ff0 <= '1';
+ else
+ s_txm13_ff0 <= '0';
+ end if;
+ end if;
+
+ end if;
+ end if;
+
+ end process p_divide_clk;
+
+-------------------------------------------------------------------------------
+ -- This section samples the serial input for data detection, that is a
+ -- 1-to-0 transition at rxd in state "0000".
+ -- In all other states this unit reads the data bits depending on the baud
+ -- rate. In mode0 this section is not active.
+
+ s_detect <= '1' when s_det_ff0 = '0' and s_det_ff1 = '1' else '0';
+ s_rxd_val <= '1' when (s_rxd_ff0 = '1' and s_rxd_ff1 = '1') or
+ (s_rxd_ff0 = '1' and s_rxd_ff2 = '1') or
+ (s_rxd_ff1 = '1' and s_rxd_ff2 = '1') else '0';
+
+ p_sample_rx: process (clk, cen, reset)
+ begin
+ if reset = '1' then
+ s_rxd_ff0 <= '0';
+ s_rxd_ff1 <= '0';
+ s_rxd_ff2 <= '0';
+ s_det_ff0 <= '0';
+ s_det_ff1 <= '0';
+ else
+ if clk'event and clk='1' and cen='1' then
+ if s_recv_state = conv_unsigned(0,4) then -- state "0000" means
+ if s_ren = '1' then -- to listen for a 1 to 0
+ case s_mode is -- transition
+ when ("01") | ("11") =>
+ if smod_i = '1' then
+ if s_tf = '1' then
+ s_det_ff0 <= rxd_i;
+ s_det_ff1 <= s_det_ff0;
+ end if;
+ else
+ if s_rxpre_count(0) = '1' then
+ s_det_ff0 <= rxd_i;
+ s_det_ff1 <= s_det_ff0;
+ end if;
+ end if;
+ when ("10") =>
+ if smod_i = '1' then
+ if s_rxpre_count(0) = '1' then
+ s_det_ff0 <= rxd_i;
+ s_det_ff1 <= s_det_ff0;
+ end if;
+ else
+ if s_rxpre_count(1) = '1' then
+ s_det_ff0 <= rxd_i;
+ s_det_ff1 <= s_det_ff0;
+ end if;
+ end if;
+ when others =>
+ null;
+ end case;
+ else
+ s_det_ff0 <= '0';
+ s_det_ff1 <= '0';
+ end if;
+ else -- in all other states
+ s_det_ff0 <= '0';
+ s_det_ff1 <= '0';
+ if s_ren = '1' then -- sample for data bits
+ case s_mode is
+ when ("01") | ("11") =>
+ if smod_i = '1' then
+ if s_rxpre_count(3 downto 0) = conv_unsigned(7,4) or
+ s_rxpre_count(3 downto 0) = conv_unsigned(8,4) or
+ s_rxpre_count(3 downto 0) = conv_unsigned(9,4) then
+ s_rxd_ff0 <= rxd_i;
+ s_rxd_ff1 <= s_rxd_ff0;
+ s_rxd_ff2 <= s_rxd_ff1;
+ end if;
+ else
+ if s_rxpre_count(4 downto 0) = conv_unsigned(14,5) or
+ s_rxpre_count(4 downto 0) = conv_unsigned(16,5) or
+ s_rxpre_count(4 downto 0) = conv_unsigned(18,5) then
+ s_rxd_ff0 <= rxd_i;
+ s_rxd_ff1 <= s_rxd_ff0;
+ s_rxd_ff2 <= s_rxd_ff1;
+ end if;
+ end if;
+ when ("10") =>
+ if smod_i = '1' then
+ if s_rxpre_count(4 downto 0) = conv_unsigned(14,5) or
+ s_rxpre_count(4 downto 0) = conv_unsigned(16,5) or
+ s_rxpre_count(4 downto 0) = conv_unsigned(18,5) then
+ s_rxd_ff0 <= rxd_i;
+ s_rxd_ff1 <= s_rxd_ff0;
+ s_rxd_ff2 <= s_rxd_ff1;
+ end if;
+ else
+ if s_rxpre_count(5 downto 0) = conv_unsigned(28,6) or
+ s_rxpre_count(5 downto 0) = conv_unsigned(32,6) or
+ s_rxpre_count(5 downto 0) = conv_unsigned(36,6) then
+ s_rxd_ff0 <= rxd_i;
+ s_rxd_ff1 <= s_rxd_ff0;
+ s_rxd_ff2 <= s_rxd_ff1;
+ end if;
+ end if;
+ when others =>
+ null;
+ end case;
+ end if;
+ end if;
+ end if;
+ end if;
+
+ end process p_sample_rx;
+
+
+-------------------------------------------------------------------------------
+--*************************** TRANSMIT ****************************************
+-- This is the finit state machine for the transmit shift register
+-------------------------------------------------------------------------------
+
+ txd_o <= s_txdm0;
+
+ p_transmit : process (clk, cen, reset)
+
+ variable v_txstep : std_logic_vector(1 downto 0);
+
+ begin
+
+ if reset = '1' then
+ s_tran_state <= conv_unsigned(0, 4);
+ s_tran_sh <= conv_unsigned(0, 11);
+ s_tran_done <= '0';
+
+ s_txdm0 <= '1';
+ rxd_o <= '1';
+ rxdwr_o <= '0';
+ else
+ if clk'event and clk = '1' and cen='1' then
+
+ -- Set default behavior
+ v_txstep := "00";
+
+ case s_mode is
+-------------------------------------------------------------------------------
+-- MODE 0
+-------------------------------------------------------------------------------
+ when ("00") =>
+
+ if s_tran_state = conv_unsigned(1, 4) or
+ s_tran_state = conv_unsigned(2, 4) or
+ s_tran_state = conv_unsigned(3, 4) or
+ s_tran_state = conv_unsigned(4, 4) or
+ s_tran_state = conv_unsigned(5, 4) or
+ s_tran_state = conv_unsigned(6, 4) or
+ s_tran_state = conv_unsigned(7, 4) or
+ s_tran_state = conv_unsigned(8, 4) or
+ s_recv_state = conv_unsigned(1, 4) or
+ s_recv_state = conv_unsigned(2, 4) or
+ s_recv_state = conv_unsigned(3, 4) or
+ s_recv_state = conv_unsigned(4, 4) or
+ s_recv_state = conv_unsigned(5, 4) or
+ s_recv_state = conv_unsigned(6, 4) or
+ s_recv_state = conv_unsigned(7, 4) or
+ s_recv_state = conv_unsigned(8, 4) then
+ if s_txpre_count(3 downto 0) = conv_unsigned(14, 4) or
+ s_txpre_count(3 downto 0) = conv_unsigned(6, 4) then
+ s_txdm0 <= not(s_txdm0);
+ end if;
+ else
+ s_txdm0 <= '1';
+ end if;
+
+ if s_m0_shift_en = '1' then
+ case s_tran_state is
+ when ("0001") => -- D1
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ v_txstep := "01";
+ rxd_o <= s_tran_sh(1);
+ rxdwr_o <= '1';
+ when ("0010") => -- D2
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ v_txstep := "01";
+ rxd_o <= s_tran_sh(1);
+ rxdwr_o <= '1';
+ when ("0011") => -- D3
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ v_txstep := "01";
+ rxd_o <= s_tran_sh(1);
+ rxdwr_o <= '1';
+ when ("0100") => -- D4
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ v_txstep := "01";
+ rxd_o <= s_tran_sh(1);
+ rxdwr_o <= '1';
+ when ("0101") => -- D5
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ v_txstep := "01";
+ rxd_o <= s_tran_sh(1);
+ rxdwr_o <= '1';
+ when ("0110") => -- D6
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ v_txstep := "01";
+ rxd_o <= s_tran_sh(1);
+ rxdwr_o <= '1';
+ when ("0111") => -- D7
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ v_txstep := "01";
+ rxd_o <= s_tran_sh(1);
+ rxdwr_o <= '1';
+ when ("1000") => -- D8, STOP BIT
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ s_tran_done <= '1';
+ v_txstep := "10";
+ rxd_o <= s_tran_sh(1);
+ rxdwr_o <= '1';
+ when others => -- D0
+ -- commence transmission if conditions are met
+ rxdwr_o <= '0';
+ if s_trans = '1' then
+ s_tran_sh(10 downto 8) <= conv_unsigned(7, 3);
+ s_tran_sh(7 downto 0) <= unsigned(sbuf_i);
+ v_txstep := "01";
+ s_tran_done <= '0';
+ rxd_o <= sbuf_i(0);
+ rxdwr_o <= '1';
+ end if;
+ end case;
+ end if;
+-------------------------------------------------------------------------------
+-- MODE 1
+-------------------------------------------------------------------------------
+ when ("01") =>
+ rxdwr_o <= '0';
+ rxd_o <= '0';
+ case s_tran_state is
+ when ("0001") => -- D1
+ if s_m13_txshift_en = '1' then
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ v_txstep := "01";
+ s_txdm0 <= s_tran_sh(1);
+ end if;
+ when ("0010") => -- D2
+ if s_m13_txshift_en = '1' then
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ v_txstep := "01";
+ s_txdm0 <= s_tran_sh(1);
+ end if;
+ when ("0011") => -- D3
+ if s_m13_txshift_en = '1' then
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ v_txstep := "01";
+ s_txdm0 <= s_tran_sh(1);
+ end if;
+ when ("0100") => -- D4
+ if s_m13_txshift_en = '1' then
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ v_txstep := "01";
+ s_txdm0 <= s_tran_sh(1);
+ end if;
+ when ("0101") => -- D5
+ if s_m13_txshift_en = '1' then
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ v_txstep := "01";
+ s_txdm0 <= s_tran_sh(1);
+ end if;
+ when ("0110") => -- D6
+ if s_m13_txshift_en = '1' then
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ v_txstep := "01";
+ s_txdm0 <= s_tran_sh(1);
+ end if;
+ when ("0111") => -- D7
+ if s_m13_txshift_en = '1' then
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ v_txstep := "01";
+ s_txdm0 <= s_tran_sh(1);
+ end if;
+ when ("1000") => -- D8
+ if s_m13_txshift_en = '1' then
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ v_txstep := "01";
+ s_txdm0 <= s_tran_sh(1);
+ end if;
+ when ("1001") => -- D9, set done bit
+ if s_m13_txshift_en = '1' then
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ s_tran_done <= '1';
+ v_txstep := "10";
+ s_txdm0 <= s_tran_sh(1);
+ end if;
+ when others => -- D0
+ -- commence transmission if conditions are met
+ s_txdm0 <= '1';
+ if s_m13_txshift_en = '1' then
+ if s_trans = '1' then
+ s_tran_sh(10 downto 9) <= conv_unsigned(3, 2);
+ s_tran_sh(8 downto 1) <= unsigned(sbuf_i);
+ s_tran_sh(0) <= '0';
+ v_txstep := "01";
+ s_tran_done <= '0';
+ s_txdm0 <= '0';
+ end if;
+ end if;
+ end case;
+-------------------------------------------------------------------------------
+-- MODE 2
+-------------------------------------------------------------------------------
+ when ("10") =>
+ rxdwr_o <= '0';
+ rxd_o <= '0';
+ case s_tran_state is
+ when ("0001") => -- D1
+ if s_m2_txshift_en = '1' then
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ v_txstep := "01";
+ s_txdm0 <= s_tran_sh(1);
+ end if;
+ when ("0010") => -- D2
+ if s_m2_txshift_en = '1' then
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ v_txstep := "01";
+ s_txdm0 <= s_tran_sh(1);
+ end if;
+ when ("0011") => -- D3
+ if s_m2_txshift_en = '1' then
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ v_txstep := "01";
+ s_txdm0 <= s_tran_sh(1);
+ end if;
+ when ("0100") => -- D4
+ if s_m2_txshift_en = '1' then
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ v_txstep := "01";
+ s_txdm0 <= s_tran_sh(1);
+ end if;
+ when ("0101") => -- D5
+ if s_m2_txshift_en = '1' then
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ v_txstep := "01";
+ s_txdm0 <= s_tran_sh(1);
+ end if;
+ when ("0110") => -- D6
+ if s_m2_txshift_en = '1' then
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ v_txstep := "01";
+ s_txdm0 <= s_tran_sh(1);
+ end if;
+ when ("0111") => -- D7
+ if s_m2_txshift_en = '1' then
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ v_txstep := "01";
+ s_txdm0 <= s_tran_sh(1);
+ end if;
+ when ("1000") => -- D8
+ if s_m2_txshift_en = '1' then
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ v_txstep := "01";
+ s_txdm0 <= s_tran_sh(1);
+ end if;
+ when ("1001") => -- D9
+ if s_m2_txshift_en = '1' then
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ v_txstep := "01";
+ s_txdm0 <= s_tran_sh(1);
+ end if;
+ when ("1010") => -- D10, set done bit
+ if s_m2_txshift_en = '1' then
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ s_tran_done <= '1';
+ v_txstep := "10";
+ s_txdm0 <= s_tran_sh(1);
+ end if;
+ when others => -- D0
+ -- commence transmission if conditions are met
+ s_txdm0 <= '1';
+ if s_m2_txshift_en = '1' then
+ if s_trans = '1' then
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9) <= s_tb8;
+ s_tran_sh(8 downto 1) <= unsigned(sbuf_i);
+ s_tran_sh(0) <= '0';
+ v_txstep := "01";
+ s_tran_done <= '0';
+ s_txdm0 <= '0';
+ end if;
+ end if;
+ end case;
+-------------------------------------------------------------------------------
+-- MODE 3
+-------------------------------------------------------------------------------
+ when ("11") =>
+ rxd_o <= '0';
+ rxdwr_o <= '0';
+ case s_tran_state is
+ when ("0001") => -- D1
+ if s_m13_txshift_en = '1' then
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ v_txstep := "01";
+ s_txdm0 <= s_tran_sh(1);
+ end if;
+ when ("0010") => -- D2
+ if s_m13_txshift_en = '1' then
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ v_txstep := "01";
+ s_txdm0 <= s_tran_sh(1);
+ end if;
+ when ("0011") => -- D3
+ if s_m13_txshift_en = '1' then
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ v_txstep := "01";
+ s_txdm0 <= s_tran_sh(1);
+ end if;
+ when ("0100") => -- D4
+ if s_m13_txshift_en = '1' then
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ v_txstep := "01";
+ s_txdm0 <= s_tran_sh(1);
+ end if;
+ when ("0101") => -- D5
+ if s_m13_txshift_en = '1' then
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ v_txstep := "01";
+ s_txdm0 <= s_tran_sh(1);
+ end if;
+ when ("0110") => -- D6
+ if s_m13_txshift_en = '1' then
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ v_txstep := "01";
+ s_txdm0 <= s_tran_sh(1);
+ end if;
+ when ("0111") => -- D7
+ if s_m13_txshift_en = '1' then
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ v_txstep := "01";
+ s_txdm0 <= s_tran_sh(1);
+ end if;
+ when ("1000") => -- D8
+ if s_m13_txshift_en = '1' then
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ v_txstep := "01";
+ s_txdm0 <= s_tran_sh(1);
+ end if;
+ when ("1001") => -- D9
+ if s_m13_txshift_en = '1' then
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ v_txstep := "01";
+ s_txdm0 <= s_tran_sh(1);
+ end if;
+ when ("1010") => -- D10, set done bit
+ if s_m13_txshift_en = '1' then
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ s_tran_done <= '1';
+ v_txstep := "10";
+ s_txdm0 <= s_tran_sh(1);
+ end if;
+ when others => -- D0
+ -- commence transmission if conditions are met
+ s_txdm0 <= '1';
+ if s_m13_txshift_en = '1' then
+ if s_trans = '1' then
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9) <= s_tb8;
+ s_tran_sh(8 downto 1) <= unsigned(sbuf_i);
+ s_tran_sh(0) <= '0';
+ s_tran_done <= '0';
+ v_txstep := "01";
+ s_txdm0 <= '0';
+ end if;
+ end if;
+ end case;
+-------------------------------------------------------------------------------
+ when others =>
+ null;
+ end case;
+
+ case v_txstep is
+ when "01" =>
+ s_tran_state <= s_tran_state + conv_unsigned(1, 1);
+ when "10" =>
+ s_tran_state <= conv_unsigned(0, 4);
+ when others =>
+ null;
+ end case;
+
+ end if;
+ end if;
+ end process p_transmit;
+
+-------------------------------------------------------------------------------
+--**************************** RECEIVE ****************************************
+-- This is the finit state machine for the receive shift register
+-------------------------------------------------------------------------------
+
+ p_receive: process (clk, cen, reset)
+ variable v_rxstep : std_logic_vector(1 downto 0);
+
+ begin
+
+ if reset = '1' then
+ s_recv_state <= conv_unsigned(0,4);
+ s_recv_sh <= conv_unsigned(0,8);
+ s_recv_buf <= conv_unsigned(0,8);
+ s_recv_done <= '0';
+ s_rb8 <= '0';
+ else
+ if clk'event and clk = '1' and cen='1' then
+
+-------------------------------------------------------------------------------
+-- MODE 0
+-------------------------------------------------------------------------------
+ v_rxstep := "00";
+ case s_mode is
+ when ("00") =>
+ case s_recv_state is
+ when ("0000") => -- D0
+ -- commence reception if conditions are met
+ if s_ren = '1' and s_ri = '0' then
+ if s_m0_shift_en = '1' then
+ v_rxstep := "01";
+ s_recv_done <= '0';
+ end if;
+ end if;
+ when ("0001") => -- D1
+ if s_m0_shift_en = '1' then
+ s_recv_sh(7) <= rxd_i;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ v_rxstep := "01";
+ end if;
+ when ("0010") => -- D2
+ if s_m0_shift_en = '1' then
+ s_recv_sh(7) <= rxd_i;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ v_rxstep := "01";
+ end if;
+ when ("0011") => -- D3
+ if s_m0_shift_en = '1' then
+ s_recv_sh(7) <= rxd_i;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ v_rxstep := "01";
+ end if;
+ when ("0100") => -- D4
+ if s_m0_shift_en = '1' then
+ s_recv_sh(7) <= rxd_i;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ v_rxstep := "01";
+ end if;
+ when ("0101") => -- D5
+ if s_m0_shift_en = '1' then
+ s_recv_sh(7) <= rxd_i;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ v_rxstep := "01";
+ end if;
+ when ("0110") => -- D6
+ if s_m0_shift_en = '1' then
+ s_recv_sh(7) <= rxd_i;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ v_rxstep := "01";
+ end if;
+ when ("0111") => -- D6
+ if s_m0_shift_en = '1' then
+ s_recv_sh(7) <= rxd_i;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ v_rxstep := "01";
+ end if;
+ when ("1000") => -- D7, set bits and store data
+ if s_m0_shift_en = '1' then
+ s_recv_sh(7) <= rxd_i;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ s_recv_done <= '1';
+ s_recv_buf(7) <= rxd_i;
+ s_recv_buf(6 downto 0) <= s_recv_sh(7 downto 1);
+ v_rxstep := "10";
+ end if;
+ when others =>
+ v_rxstep := "10";
+ end case;
+
+-------------------------------------------------------------------------------
+-- MODE 1
+-------------------------------------------------------------------------------
+ when ("01") =>
+ case s_recv_state is
+ when ("0000") => -- synchronise reception
+ if s_ren = '1' and s_detect = '1' then
+ v_rxstep := "01";
+ s_recv_sh <= conv_unsigned(0,8);
+ s_recv_done <= '0';
+ end if;
+ when ("0001") => -- D0 = START BIT
+ if s_detect = '0' then
+ if s_rxd_val = '0' then
+ if s_m13_rxshift_en = '1' then
+ s_recv_sh(7) <= s_rxd_val;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ v_rxstep := "01";
+ end if;
+ else -- reject false start bits
+ if s_m13_rxshift_en = '1' then
+ v_rxstep := "10";
+ end if;
+ end if;
+ end if;
+ when ("0010") => -- D1
+ if s_m13_rxshift_en = '1' then
+ s_recv_sh(7) <= s_rxd_val;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ v_rxstep := "01";
+ end if;
+ when ("0011") => -- D2
+ if s_m13_rxshift_en = '1' then
+ s_recv_sh(7) <= s_rxd_val;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ v_rxstep := "01";
+ end if;
+ when ("0100") => -- D3
+ if s_m13_rxshift_en = '1' then
+ s_recv_sh(7) <= s_rxd_val;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ v_rxstep := "01";
+ end if;
+ when ("0101") => -- D4
+ if s_m13_rxshift_en = '1' then
+ s_recv_sh(7) <= s_rxd_val;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ v_rxstep := "01";
+ end if;
+ when ("0110") => -- D5
+ if s_m13_rxshift_en = '1' then
+ s_recv_sh(7) <= s_rxd_val;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ v_rxstep := "01";
+ end if;
+ when ("0111") => -- D6
+ if s_m13_rxshift_en = '1' then
+ s_recv_sh(7) <= s_rxd_val;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ v_rxstep := "01";
+ end if;
+ when ("1000") => -- D7
+ if s_m13_rxshift_en = '1' then
+ s_recv_sh(7) <= s_rxd_val;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ v_rxstep := "01";
+ end if;
+ when ("1001") => -- D8
+ if s_m13_rxshift_en = '1' then
+ s_recv_sh(7) <= s_rxd_val;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ v_rxstep := "01";
+ end if;
+ when ("1010") => -- D9 = STOP BIT
+ -- store data and set interrupt bit if conditions are met.
+ if (s_ri = '0' and s_sm2 = '0') or
+ (s_ri = '0' and s_rxd_val = '1') then
+ --if s_m13_rxshift_en = '1' then
+ if s_rxpre_count(3 downto 0) = conv_unsigned(10,4) then -- CK, CV: changed to enter state 0 after one stopbit
+ s_recv_sh(7) <= s_rxd_val;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ v_rxstep := "10";
+ s_recv_done <= '1';
+ s_rb8 <= s_rxd_val;
+ s_recv_buf <= s_recv_sh(7 downto 0);
+ end if;
+ -- forget data and recommence listening for a start bit
+ else
+ if s_m13_rxshift_en = '1' then
+ v_rxstep := "10";
+ end if;
+ end if;
+ when others =>
+ v_rxstep := "10";
+ end case;
+
+-------------------------------------------------------------------------------
+-- MODE 2
+-------------------------------------------------------------------------------
+ when ("10") =>
+ case s_recv_state is
+ when ("0000") => -- synchronise reception
+ if s_ren = '1' and s_detect = '1' then
+ v_rxstep := "01";
+ s_recv_sh <= conv_unsigned(0,8);
+ s_recv_done <= '0';
+ end if;
+ when ("0001") => -- D0 = START BIT
+ if s_rxd_val = '0' then
+ if s_m2_rxshift_en = '1' then
+ s_recv_sh(7) <= s_rxd_val;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ v_rxstep := "01";
+ end if;
+ else -- reject false start bits
+ if s_m2_rxshift_en = '1' then
+ v_rxstep := "10";
+ end if;
+ end if;
+ when ("0010") => -- D1
+ if s_m2_rxshift_en = '1' then
+ s_recv_sh(7) <= s_rxd_val;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ v_rxstep := "01";
+ end if;
+ when ("0011") => -- D2
+ if s_m2_rxshift_en = '1' then
+ s_recv_sh(7) <= s_rxd_val;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ v_rxstep := "01";
+ end if;
+ when ("0100") => -- D3
+ if s_m2_rxshift_en = '1' then
+ s_recv_sh(7) <= s_rxd_val;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ v_rxstep := "01";
+ end if;
+ when ("0101") => -- D4
+ if s_m2_rxshift_en = '1' then
+ s_recv_sh(7) <= s_rxd_val;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ v_rxstep := "01";
+ end if;
+ when ("0110") => -- D5
+ if s_m2_rxshift_en = '1' then
+ s_recv_sh(7) <= s_rxd_val;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ v_rxstep := "01";
+ end if;
+ when ("0111") => -- D6
+ if s_m2_rxshift_en = '1' then
+ s_recv_sh(7) <= s_rxd_val;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ v_rxstep := "01";
+ end if;
+ when ("1000") => -- D7
+ if s_m2_rxshift_en = '1' then
+ s_recv_sh(7) <= s_rxd_val;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ v_rxstep := "01";
+ end if;
+ when ("1001") => -- D8
+ if s_m2_rxshift_en = '1' then
+ s_recv_sh(7) <= s_rxd_val;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ v_rxstep := "01";
+ end if;
+ when ("1010") => -- D9
+ -- store data and set interrupt bit if conditions are met.
+ if (s_ri = '0' and s_sm2 = '0') or
+ (s_ri = '0' and s_rxd_val = '1') then
+ if s_m2_rxshift_en = '1' then
+ s_recv_sh(7) <= s_rxd_val;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ s_recv_done <= '1';
+ s_rb8 <= s_rxd_val;
+ s_recv_buf <= s_recv_sh(7 downto 0);
+ end if;
+ end if;
+ -- forget data
+ if s_m2_rxshift_en = '1' then
+ v_rxstep := "01";
+ end if;
+ when ("1011") => -- D10 STOP BIT
+ -- recommence listening for a start bit
+ if s_m2_rxshift_en = '1' then
+ -- s_recv_state <= conv_unsigned(0,4);
+ v_rxstep := "10";
+ end if;
+ when others =>
+ -- s_recv_state <= conv_unsigned(0,4);
+ v_rxstep := "10";
+ end case;
+
+-------------------------------------------------------------------------------
+-- MODE 3
+-------------------------------------------------------------------------------
+ when ("11") =>
+ case s_recv_state is
+ when ("0000") => -- synchronise reception
+ if s_ren = '1' and s_detect = '1' then
+ v_rxstep := "01";
+ s_recv_sh <= conv_unsigned(0,8);
+ s_recv_done <= '0';
+ end if;
+ when ("0001") => -- D0 = START BIT
+ if s_detect = '0' then
+ if s_rxd_val = '0' then
+ if s_m13_rxshift_en = '1' then
+ s_recv_sh(7) <= s_rxd_val;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ v_rxstep := "01";
+ end if;
+ else -- reject false start bits
+ if s_m13_rxshift_en = '1' then
+ v_rxstep := "10";
+ end if;
+ end if;
+ end if;
+ when ("0010") => -- D1
+ if s_m13_rxshift_en = '1' then
+ s_recv_sh(7) <= s_rxd_val;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ v_rxstep := "01";
+ end if;
+ when ("0011") => -- D2
+ if s_m13_rxshift_en = '1' then
+ s_recv_sh(7) <= s_rxd_val;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ v_rxstep := "01";
+ end if;
+ when ("0100") => -- D3
+ if s_m13_rxshift_en = '1' then
+ s_recv_sh(7) <= s_rxd_val;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ v_rxstep := "01";
+ end if;
+ when ("0101") => -- D4
+ if s_m13_rxshift_en = '1' then
+ s_recv_sh(7) <= s_rxd_val;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ v_rxstep := "01";
+ end if;
+ when ("0110") => -- D5
+ if s_m13_rxshift_en = '1' then
+ s_recv_sh(7) <= s_rxd_val;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ v_rxstep := "01";
+ end if;
+ when ("0111") => -- D6
+ if s_m13_rxshift_en = '1' then
+ s_recv_sh(7) <= s_rxd_val;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ v_rxstep := "01";
+ end if;
+ when ("1000") => -- D7
+ if s_m13_rxshift_en = '1' then
+ s_recv_sh(7) <= s_rxd_val;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ v_rxstep := "01";
+ end if;
+ when ("1001") => -- D8
+ if s_m13_rxshift_en = '1' then
+ s_recv_sh(7) <= s_rxd_val;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ v_rxstep := "01";
+ end if;
+ when ("1010") => -- D9
+ -- store data and set interrupt bit if conditions are met.
+ if (s_ri = '0' and s_sm2 = '0') or
+ (s_ri = '0' and s_rxd_val = '1') then
+ if s_m13_rxshift_en = '1' then
+ s_recv_sh(7) <= s_rxd_val;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ s_recv_done <= '1';
+ s_rb8 <= s_rxd_val;
+ s_recv_buf <= s_recv_sh(7 downto 0);
+ end if;
+ end if;
+ -- forget data
+ if s_m13_rxshift_en = '1' then
+ v_rxstep := "01";
+ end if;
+ when ("1011") => -- D10 STOP BIT
+ -- recommence listening for a start bit
+ if s_m13_rxshift_en = '1' then
+ v_rxstep := "10";
+ end if;
+ when others =>
+ v_rxstep := "10";
+ end case;
+ when others =>
+ null;
+ end case;
+
+ case v_rxstep is
+ when "01" =>
+ s_recv_state <= s_recv_state + conv_unsigned(1,1);
+ when "10" =>
+ s_recv_state <= conv_unsigned(0,4);
+ when others =>
+ null;
+ end case;
+
+ end if;
+ end if;
+
+
+ end process p_receive;
+
+
+end rtl;