mc8051_siu_rtl.vhd
上传用户:sztwq510
上传日期:2007-04-20
资源大小:209k
文件大小:48k
源码类别:
VHDL/FPGA/Verilog
开发平台:
Matlab
- -------------------------------------------------------------------------------
- -- --
- -- 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鰈ler
- --
- -- Filename: mc8051_siu_rtl.vhd
- --
- -- Date of Creation: Mon Aug 9 12:14:48 1999
- --
- -- Version: $Revision: 1.7 $
- --
- -- Date of Latest Version: $Date: 2002/01/30 16:42:16 $
- --
- --
- -- Description: Serial interface unit for the mc8051 microcontroller.
- --
- --
- --
- --
- -------------------------------------------------------------------------------
- architecture rtl of mc8051_siu is
- signal s_pre_count : unsigned(5 downto 0); -- these three signals provide
- signal s_m0_shift_en : std_logic; -- masks out every sixteenth
- -- rising edge of clk
- signal s_m2_shift_en : std_logic; -- mode 2 shift enable
- signal s_m13_shift_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_m13_ff0 : std_logic; -- generates an enable singal
- signal s_m13_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); -- 8th 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; -- 8th 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,
- reset)
- begin
- if reset = '1' then
- s_ff0 <= '0';
- s_ff1 <= '0';
- s_trans <= '0';
- else
- if clk'event and clk = '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_shift_en = '1' then
- s_trans <= '0';
- end if;
- when ("10") =>
- if s_m2_shift_en = '1' then
- s_trans <= '0';
- end if;
- when others =>
- if s_m13_shift_en = '1' then
- s_trans <= '0';
- end if;
- end case;
- end if;
- end if;
- end if;
- end process p_sample_tf;
- -------------------------------------------------------------------------------
- -- The register s_pre_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 sixteenth 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_pre_count(3 downto 0) = conv_unsigned(15,5)
- else '0';
- s_m2_shift_en <= '1' when (s_pre_count(4 downto 0) = conv_unsigned(31,5) and
- smod_i = '1') or
- (s_pre_count = conv_unsigned(63,6) and
- smod_i = '0')
- else '0';
- s_m13_shift_en <= '1' when s_m13_ff0 = '1' and s_m13_ff1 = '0' else '0';
- p_divide_clk: process (clk, reset)
- begin
- if reset = '1' then
- s_pre_count <= conv_unsigned(0,6);
- s_m13_ff0 <= '0';
- s_m13_ff1 <= '0';
- else
- if clk'event and clk='1' then
- s_m13_ff1 <= s_m13_ff0;
- if smod_i = '1' then
- if s_pre_count(3 downto 0) = conv_unsigned(15,4) then
- s_m13_ff0 <= '1';
- else
- s_m13_ff0 <= '0';
- end if;
- else
- if s_pre_count(4 downto 0) = conv_unsigned(31,5) then
- s_m13_ff0 <= '1';
- else
- s_m13_ff0 <= '0';
- end if;
- end if;
- if s_detect = '1' then
- s_pre_count <= conv_unsigned(0,6);
- else
- if s_mode=conv_unsigned(0,2) or s_mode=conv_unsigned(2,2) then
- s_pre_count <= s_pre_count + conv_unsigned(1,1);
- else
- if s_tf = '1' then
- s_pre_count <= s_pre_count + conv_unsigned(1,1);
- end if;
- 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,
- 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' 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_pre_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_pre_count(0) = '1' then
- s_det_ff0 <= rxd_i;
- s_det_ff1 <= s_det_ff0;
- end if;
- else
- if s_pre_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_pre_count(3 downto 0) = conv_unsigned(7,4) or
- s_pre_count(3 downto 0) = conv_unsigned(8,4) or
- s_pre_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_pre_count(4 downto 0) = conv_unsigned(14,5) or
- s_pre_count(4 downto 0) = conv_unsigned(16,5) or
- s_pre_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_pre_count(4 downto 0) = conv_unsigned(14,5) or
- s_pre_count(4 downto 0) = conv_unsigned(16,5) or
- s_pre_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_pre_count(5 downto 0) = conv_unsigned(28,6) or
- s_pre_count(5 downto 0) = conv_unsigned(32,6) or
- s_pre_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, 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 <= '0';
- rxdwr_o <= '0';
- else
- if clk'event and clk = '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_pre_count(3 downto 0) = conv_unsigned(14, 4) or
- s_pre_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
- 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_shift_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_shift_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_shift_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_shift_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_shift_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_shift_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_shift_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_shift_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_shift_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_shift_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_shift_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_shift_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_shift_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_shift_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_shift_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_shift_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_shift_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_shift_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_shift_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_shift_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_shift_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_shift_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_shift_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_shift_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_shift_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_shift_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_shift_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_shift_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_shift_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_shift_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_shift_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_shift_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,
- 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' 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_shift_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_shift_en = '1' then
- v_rxstep := "10";
- end if;
- end if;
- end if;
- when ("0010") => -- D1
- if s_m13_shift_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_shift_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_shift_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_shift_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_shift_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_shift_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_shift_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_shift_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_shift_en = '1' then
- 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_shift_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_shift_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_shift_en = '1' then
- v_rxstep := "10";
- end if;
- end if;
- when ("0010") => -- D1
- if s_m2_shift_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_shift_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_shift_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_shift_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_shift_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_shift_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_shift_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_shift_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_shift_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_shift_en = '1' then
- v_rxstep := "01";
- end if;
- when ("1011") => -- D10 STOP BIT
- -- recommence listening for a start bit
- if s_m2_shift_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_rxd_val = '0' then
- if s_m13_shift_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_shift_en = '1' then
- v_rxstep := "10";
- end if;
- end if;
- when ("0010") => -- D1
- if s_m13_shift_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_shift_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_shift_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_shift_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_shift_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_shift_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_shift_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_shift_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_shift_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_shift_en = '1' then
- v_rxstep := "01";
- end if;
- when ("1011") => -- D10 STOP BIT
- -- recommence listening for a start bit
- if s_m13_shift_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;