---------------------------------------------------------------------------- -- top.vhd -- MicroZed simple VHDL example -- Version 1.0 -- -- Copyright (C) 2015-2017 H.Poetzl -- -- This program is free software: you can redistribute it and/or -- modify it under the terms of the GNU General Public License -- as published by the Free Software Foundation, either version -- 2 of the License, or (at your option) any later version. -- -- Vivado 2016.4: -- mkdir -p build.vivado -- (cd build.vivado && vivado -mode tcl -source ../vivado.tcl) ---------------------------------------------------------------------------- library IEEE; use IEEE.std_logic_1164.ALL; use IEEE.numeric_std.ALL; library unisim; use unisim.VCOMPONENTS.ALL; -- library unimacro; -- use unimacro.VCOMPONENTS.ALL; use work.vivado_pkg.ALL; -- Vivado Attributes use work.helper_pkg.ALL; -- Various Helpers use work.icsp_pkg.ALL; -- ICSP Commands use work.fifo_pkg.ALL; -- FIFO Functions entity top is port ( i2c0_scl : inout std_logic; -- icsp clock i2c0_sda : inout std_logic; -- icsp data -- i2c1_scl : inout std_logic; -- icsp clock i2c1_sda : inout std_logic; -- icsp data -- icsp_d1 : inout std_logic; icsp_c1 : inout std_logic; -- icsp_d2 : inout std_logic; icsp_c2 : inout std_logic; -- icsp_d3 : inout std_logic; icsp_c3 : inout std_logic; -- pmod_n : out std_logic_vector (7 downto 0) ); end entity top; architecture RTL of top is signal icsp_clk_o : std_logic; signal icsp_clk_t : std_logic; signal icsp_dat_i : std_logic; signal icsp_dat_o : std_logic; signal icsp_dat_t : std_logic; signal icsp_sel : std_logic_vector (15 downto 0); alias icsp_ifc : std_logic_vector (1 downto 0) is icsp_sel(1 downto 0); alias icsp_urx : std_logic_vector (2 downto 0) is icsp_sel(6 downto 4); alias icsp_utx : std_logic_vector (2 downto 0) is icsp_sel(10 downto 8); signal ps_fclk : std_logic_vector (3 downto 0); signal ps_reset_n : std_logic_vector (3 downto 0); signal uart0_rx : std_logic; signal uart0_tx : std_logic; signal uart1_rx : std_logic; signal uart1_tx : std_logic; -------------------------------------------------------------------- -- ICSP/UART PLL Signals -------------------------------------------------------------------- signal clk_100 : std_logic; signal clk_125 : std_logic; signal pll_fb : std_logic; signal pll_clk0 : std_logic; signal pll_clk1 : std_logic; signal pll_clk2 : std_logic; signal uart_clk : std_logic; signal smpl_clk : std_logic; signal mchp_clk : std_logic; signal serd_clk : std_logic; -------------------------------------------------------------------- -- CRC Signals -------------------------------------------------------------------- signal crc_rx_reset : std_logic; signal crc_rx_in : std_logic_vector (7 downto 0); signal crc_rx_en : std_logic; signal crc_rx_out : std_logic_vector (15 downto 0); signal crc_tx_reset : std_logic; signal crc_tx_in : std_logic_vector (7 downto 0); signal crc_tx_en : std_logic; signal crc_tx_out : std_logic_vector (15 downto 0); -------------------------------------------------------------------- -- ICSP Signals -------------------------------------------------------------------- constant MAX_ICSP : natural := 4; signal icsp_in : icsp_value_t; signal icsp_out : icsp_value_t; signal icsp_cmd : icsp_cmd_t; signal icsp_valid : std_logic; signal icsp_ready : std_logic; signal icsp_active : std_logic := '0'; -------------------------------------------------------------------- -- FIFO UART Signals -------------------------------------------------------------------- signal rx0_data : std_logic_vector (7 downto 0); signal rx0_empty : std_logic; signal rx0_ren : std_logic; signal tx0_data : std_logic_vector (7 downto 0); signal tx0_full : std_logic; signal tx0_wen : std_logic; signal rx1_data : std_logic_vector (7 downto 0); signal rx1_empty : std_logic; signal rx1_ren : std_logic; signal tx1_data : std_logic_vector (7 downto 0); signal tx1_full : std_logic; signal tx1_wen : std_logic; signal fifo0_reset : std_logic; signal fifo1_reset : std_logic; signal fifo0_debug : std_logic_vector (17 downto 0); signal fifo1_debug : std_logic_vector (17 downto 0); alias fifo0_debug_wvalid : std_logic is fifo0_debug(0); alias fifo0_debug_widle : std_logic is fifo0_debug(1); alias fifo0_debug_wstate : std_logic_vector (2 downto 0) is fifo0_debug(4 downto 2); alias fifo0_debug_rvalid : std_logic is fifo0_debug(5); alias fifo0_debug_ridle : std_logic is fifo0_debug(6); alias fifo0_debug_rstate : std_logic_vector (9 downto 7) is fifo0_debug(4 downto 2); alias fifo0_debug_rx_fifo0_full : std_logic is fifo0_debug(10); alias fifo0_debug_rx_fifo0_empty : std_logic is fifo0_debug(11); alias fifo0_debug_rx_fifo0_wen : std_logic is fifo0_debug(12); alias fifo0_debug_rx_fifo0_ren : std_logic is fifo0_debug(13); alias fifo0_debug_tx_fifo0_full : std_logic is fifo0_debug(14); alias fifo0_debug_tx_fifo0_empty : std_logic is fifo0_debug(15); alias fifo0_debug_tx_fifo0_wen : std_logic is fifo0_debug(16); alias fifo0_debug_tx_fifo0_ren : std_logic is fifo0_debug(17); -------------------------------------------------------------------- -- I2C Signals -------------------------------------------------------------------- signal i2c0_sda_i : std_logic; signal i2c0_sda_o : std_logic; signal i2c0_sda_t : std_logic; signal i2c0_sda_t_n : std_logic; signal i2c0_scl_i : std_logic; signal i2c0_scl_o : std_logic; signal i2c0_scl_t : std_logic; signal i2c0_scl_t_n : std_logic; signal i2c1_sda_i : std_logic; signal i2c1_sda_o : std_logic; signal i2c1_sda_t : std_logic; signal i2c1_sda_t_n : std_logic; signal i2c1_scl_i : std_logic; signal i2c1_scl_o : std_logic; signal i2c1_scl_t : std_logic; signal i2c1_scl_t_n : std_logic; -------------------------------------------------------------------- -- ICSP Signals -------------------------------------------------------------------- signal icsp_d1_i : std_logic; signal icsp_d1_o : std_logic; signal icsp_d1_t : std_logic; signal icsp_c1_i : std_logic; signal icsp_c1_o : std_logic; signal icsp_c1_t : std_logic; signal icsp_d2_i : std_logic; signal icsp_d2_o : std_logic; signal icsp_d2_t : std_logic; signal icsp_c2_i : std_logic; signal icsp_c2_o : std_logic; signal icsp_c2_t : std_logic; signal icsp_d3_i : std_logic; signal icsp_d3_o : std_logic; signal icsp_d3_t : std_logic; signal icsp_c3_i : std_logic; signal icsp_c3_o : std_logic; signal icsp_c3_t : std_logic; signal uart_d1_o : std_logic; signal uart_d1_t : std_logic; signal uart_c1_o : std_logic; signal uart_c1_t : std_logic; signal uart_d2_o : std_logic; signal uart_d2_t : std_logic; signal uart_c2_o : std_logic; signal uart_c2_t : std_logic; signal uart_d3_o : std_logic; signal uart_d3_t : std_logic; signal uart_c3_o : std_logic; signal uart_c3_t : std_logic; begin -------------------------------------------------------------------- -- PS7 Interface -------------------------------------------------------------------- ps7_stub_inst : entity work.ps7_stub port map ( ps_fclk => ps_fclk, ps_reset_n => ps_reset_n, -- uart0_rx => uart0_tx, uart0_tx => uart0_rx, -- i2c0_sda_i => i2c0_sda_i, i2c0_sda_o => i2c0_sda_o, i2c0_sda_t_n => i2c0_sda_t_n, -- i2c0_scl_i => i2c0_scl_i, i2c0_scl_o => i2c0_scl_o, i2c0_scl_t_n => i2c0_scl_t_n, -- i2c1_sda_i => i2c1_sda_i, i2c1_sda_o => i2c1_sda_o, i2c1_sda_t_n => i2c1_sda_t_n, -- i2c1_scl_i => i2c1_scl_i, i2c1_scl_o => i2c1_scl_o, i2c1_scl_t_n => i2c1_scl_t_n); clk_100 <= ps_fclk(0); clk_125 <= ps_fclk(3); -------------------------------------------------------------------- -- I2C Interface -------------------------------------------------------------------- i2c0_sda_t <= not i2c0_sda_t_n; IOBUF_sda_inst0 : IOBUF port map ( I => i2c0_sda_o, O => i2c0_sda_i, T => i2c0_sda_t, IO => i2c0_sda ); i2c0_scl_t <= not i2c0_scl_t_n; IOBUF_scl_inst0 : IOBUF port map ( I => i2c0_scl_o, O => i2c0_scl_i, T => i2c0_scl_t, IO => i2c0_scl ); i2c1_sda_t <= not i2c1_sda_t_n; IOBUF_sda_inst1 : IOBUF port map ( I => i2c1_sda_o, O => i2c1_sda_i, T => i2c1_sda_t, IO => i2c1_sda ); PULLUP_sda_inst : PULLUP port map ( O => i2c1_sda ); i2c1_scl_t <= not i2c1_scl_t_n; IOBUF_scl_inst1 : IOBUF port map ( I => i2c1_scl_o, O => i2c1_scl_i, T => i2c1_scl_t, IO => i2c1_scl ); PULLUP_scl_inst : PULLUP port map ( O => i2c1_scl ); -------------------------------------------------------------------- -- ICSP Interface -------------------------------------------------------------------- icsp_d1_o <= icsp_dat_o when icsp_ifc = "01" else uart_d1_o; icsp_d1_t <= icsp_dat_t when icsp_ifc = "01" else uart_d1_t; IOBUF_d1_inst : IOBUF port map ( I => icsp_d1_o, O => icsp_d1_i, T => icsp_d1_t, IO => icsp_d1 ); icsp_c1_o <= icsp_clk_o when icsp_ifc = "01" else uart_c1_o; icsp_c1_t <= icsp_clk_t when icsp_ifc = "01" else uart_c1_t; IOBUF_c1_inst : IOBUF port map ( I => icsp_c1_o, O => icsp_c1_i, T => icsp_c1_t, IO => icsp_c1 ); icsp_d2_o <= icsp_dat_o when icsp_ifc = "10" else uart_d2_o; icsp_d2_t <= icsp_dat_t when icsp_ifc = "10" else uart_d2_t; IOBUF_d2_inst : IOBUF port map ( I => icsp_d2_o, O => icsp_d2_i, T => icsp_d2_t, IO => icsp_d2 ); icsp_c2_o <= icsp_clk_o when icsp_ifc = "10" else uart_c2_o; icsp_c2_t <= icsp_clk_t when icsp_ifc = "10" else uart_c2_t; IOBUF_c2_inst : IOBUF port map ( I => icsp_c2_o, O => icsp_c2_i, T => icsp_c2_t, IO => icsp_c2 ); icsp_d3_o <= icsp_dat_o when icsp_ifc = "11" else uart_d3_o; icsp_d3_t <= icsp_dat_t when icsp_ifc = "11" else uart_d3_t; IOBUF_d3_inst : IOBUF port map ( I => icsp_d3_o, O => icsp_d3_i, T => icsp_d3_t, IO => icsp_d3 ); icsp_c3_o <= icsp_clk_o when icsp_ifc = "11" else uart_c3_o; icsp_c3_t <= icsp_clk_t when icsp_ifc = "11" else uart_c3_t; IOBUF_c3_inst : IOBUF port map ( I => icsp_c3_o, O => icsp_c3_i, T => icsp_c3_t, IO => icsp_c3 ); with icsp_ifc select icsp_dat_i <= 'Z' when "00", icsp_d1_i when "01", icsp_d2_i when "10", icsp_d3_i when "11"; with icsp_urx select uart1_rx <= icsp_d1_i when "001", icsp_c1_i when "101", icsp_d2_i when "010", icsp_c2_i when "110", icsp_d3_i when "011", icsp_c3_i when "111", 'Z' when others; uart_d1_o <= uart1_tx when icsp_utx = "001" else 'Z'; uart_c1_o <= uart1_tx when icsp_utx = "101" else 'Z'; uart_d2_o <= uart1_tx when icsp_utx = "010" else 'Z'; uart_c2_o <= uart1_tx when icsp_utx = "110" else 'Z'; uart_d3_o <= uart1_tx when icsp_utx = "011" else 'Z'; uart_c3_o <= uart1_tx when icsp_utx = "111" else 'Z'; uart_d1_t <= '0' when icsp_utx = "001" else '1'; uart_c1_t <= '0' when icsp_utx = "101" else '1'; uart_d2_t <= '0' when icsp_utx = "010" else '1'; uart_c2_t <= '0' when icsp_utx = "110" else '1'; uart_d3_t <= '0' when icsp_utx = "011" else '1'; uart_c3_t <= '0' when icsp_utx = "111" else '1'; -------------------------------------------------------------------- -- ICSP/UART Clock PLL -------------------------------------------------------------------- PLL_inst : PLLE2_BASE generic map ( BANDWIDTH => "LOW", CLKFBOUT_MULT => 8, CLKIN1_PERIOD => 8.0, CLKOUT0_DIVIDE => 800/50, CLKOUT1_DIVIDE => 800/8, CLKOUT2_DIVIDE => 800/20, DIVCLK_DIVIDE => 1 ) port map ( CLKIN1 => clk_100, -- 100MHz CLKFBOUT => pll_fb, CLKFBIN => pll_fb, CLKOUT0 => pll_clk0, -- 50MHz (10MHz*5) CLKOUT1 => pll_clk1, -- 8MHz (2MHz*4) CLKOUT2 => pll_clk2, -- 20MHz (4MHz*5) PWRDWN => '0', RST => '0' ); BUFG_inst0 : BUFG port map ( I => pll_clk0, O => uart_clk ); BUFG_inst1 : BUFG port map ( I => pll_clk1, O => smpl_clk ); BUFG_inst2 : BUFG port map ( I => pll_clk2, O => serd_clk ); -------------------------------------------------------------------- -- Clock Buffer -------------------------------------------------------------------- BUFR_inst : BUFR generic map ( BUFR_DIVIDE => "4" ) port map ( CE => '1', CLR => '0', I => smpl_clk, O => mchp_clk ); -------------------------------------------------------------------- -- FIFO UART -------------------------------------------------------------------- fifo_uart_inst0 : entity work.fifo_uart generic map ( DATA_BITS => 8, STOP_BITS => 1, PARITY_BITS => 0, SAMPLE_COUNT => 5 ) port map ( uart_clk => uart_clk, -- uart_rx => uart0_rx, uart_tx => uart0_tx, -- fifo_clk => mchp_clk, reset => fifo0_reset, debug => fifo0_debug, -- rx_data => rx0_data, rx_empty => rx0_empty, rx_ren => rx0_ren, -- tx_data => tx0_data, tx_full => tx0_full, tx_wen => tx0_wen ); fifo0_reset_proc : process (mchp_clk) variable shift_v : unsigned(50 downto 0) := (0 to 10 => '0', others => '1'); begin if rising_edge(mchp_clk) then fifo0_reset <= shift_v(0) or not ps_reset_n(0); shift_v := shift_right(shift_v, 1); end if; end process; fifo_uart_inst1 : entity work.fifo_uart generic map ( DATA_BITS => 8, STOP_BITS => 1, PARITY_BITS => 0, SAMPLE_COUNT => 5 ) port map ( uart_clk => serd_clk, -- uart_rx => uart1_rx, uart_tx => uart1_tx, -- fifo_clk => mchp_clk, reset => fifo1_reset, debug => fifo1_debug, -- rx_data => rx1_data, rx_empty => rx1_empty, rx_ren => rx1_ren, -- tx_data => tx1_data, tx_full => tx1_full, tx_wen => tx1_wen ); fifo1_reset_proc : process (mchp_clk) variable shift_v : unsigned(50 downto 0) := (0 to 10 => '0', others => '1'); begin if rising_edge(mchp_clk) then fifo1_reset <= shift_v(0) or not ps_reset_n(1); shift_v := shift_right(shift_v, 1); end if; end process; -------------------------------------------------------------------- -- CRC Module -------------------------------------------------------------------- crc_rx_inst : entity work.crc port map ( clk => mchp_clk, reset => crc_rx_reset, -- data => crc_rx_in, enable => crc_rx_en, crc => crc_rx_out ); crc_tx_inst : entity work.crc port map ( clk => mchp_clk, reset => crc_tx_reset, -- data => crc_tx_in, enable => crc_tx_en, crc => crc_tx_out ); -------------------------------------------------------------------- -- ICSP Interface -------------------------------------------------------------------- icsp_inst : entity work.icsp port map ( smpl_clk => smpl_clk, mchp_clk => mchp_clk, -- icsp_clk_t => icsp_clk_t, icsp_clk_o => icsp_clk_o, -- icsp_dat_t => icsp_dat_t, icsp_dat_o => icsp_dat_o, icsp_dat_i => icsp_dat_i, -- icsp_sel => icsp_sel, -- data_out => icsp_out, data_in => icsp_in, -- command => icsp_cmd, valid => icsp_valid, ready => icsp_ready); dispatch_proc : process (mchp_clk) pure function ord (ch : character) return natural is variable pos_v : natural; begin return character'pos(ch); end ord; pure function asc (ch : character) return std_logic_vector is begin return std_logic_vector(to_unsigned(ord(ch), 8)); end asc; type htoa_t is array (natural range <>) of std_logic_vector (7 downto 0); constant htoa_c : htoa_t(0 to 15) := ( asc('0'), asc('1'), asc('2'), asc('3'), asc('4'), asc('5'), asc('6'), asc('7'), asc('8'), asc('9'), asc('A'), asc('B'), asc('C'), asc('D'), asc('E'), asc('F') ); function htoa_f (hex : std_logic_vector) return std_logic_vector is begin return htoa_c(to_index(hex(3 downto 0))); end function; type atoh_t is array (natural range <>) of std_logic_vector(3 downto 0); constant atoh_c : atoh_t(0 to 255) := ( character'pos('0') => x"0", character'pos('1') => x"1", character'pos('2') => x"2", character'pos('3') => x"3", character'pos('4') => x"4", character'pos('5') => x"5", character'pos('6') => x"6", character'pos('7') => x"7", character'pos('8') => x"8", character'pos('9') => x"9", character'pos('A') => x"A", character'pos('B') => x"B", character'pos('C') => x"C", character'pos('D') => x"D", character'pos('E') => x"E", character'pos('F') => x"F", others => x"0" ); function within_f ( v : std_logic_vector; a : std_logic_vector; b : std_logic_vector ) return boolean is begin return (v >= a and v <= b); end within_f; function ready_f ( flags : std_logic_vector; mask : std_logic_vector ) return boolean is begin for I in mask'low to mask'high loop if (mask(I) = '1') and (flags(I) = '0') then return false; end if; end loop; return true; end ready_f; procedure inc_p ( variable v : inout std_logic_vector ) is begin v := std_logic_vector(unsigned(v) + "1"); end inc_p; type cmd_state is (idle_s, wait_s, read_s, echo_s, cout_s, dout_s, pout_s, sout_s); variable state_v : cmd_state := idle_s; variable index_v : natural range 0 to 1; variable count_v : natural range 0 to 3; variable crc_rx_v : std_logic_vector (15 downto 0); variable crc_tx_v : std_logic_vector (15 downto 0); variable stat_echo_v : std_logic_vector (3 downto 0); variable stat_full_v : std_logic_vector (3 downto 0); variable stat_ovfl_v : std_logic_vector (3 downto 0); variable stat_badc_v : std_logic_vector (3 downto 0); variable value_v : icsp_value_t; variable cmd_v : icsp_cmd_t; variable action_v : boolean := false; variable active_v : boolean := false; variable echo_v : boolean := true; variable echo_this_v : boolean; begin rx0_ren <= '0'; tx0_wen <= '0'; rx1_ren <= '0'; tx1_wen <= '0'; crc_rx_reset <= '0'; crc_tx_reset <= '0'; if rising_edge(mchp_clk) then case state_v is when idle_s => if not rx0_empty and icsp_ready then action_v := false; active_v := false; echo_this_v := echo_v; if within_f(rx0_data, asc('0'), asc('9')) or within_f(rx0_data, asc('A'), asc('F')) then value_v := value_v(value_v'high-4 downto 0) & atoh_c(to_index(rx0_data)); state_v := wait_s; else -- note: 'A' - 'F' is used for hex case rx0_data is when asc('X') => -- config value_v := x"0000"; cmd_v := ICSP_CMD_W6; action_v := true; state_v := wait_s; when asc('W') => -- write data value_v := x"0002"; cmd_v := ICSP_CMD_W6; action_v := true; state_v := wait_s; when asc('R') => -- read data value_v := x"0004"; cmd_v := ICSP_CMD_W6; action_v := true; state_v := wait_s; when asc('P') => -- icsp port state_v := pout_s; when asc('L') => -- nMCLR low cmd_v := ICSP_CMD_ML; action_v := true; state_v := wait_s; icsp_active <= '1'; when asc('H') => -- nMCLR high cmd_v := ICSP_CMD_MH; action_v := true; state_v := wait_s; icsp_active <= '0'; when asc('Z') => -- nMCLR tri cmd_v := ICSP_CMD_MZ; action_v := true; state_v := wait_s; icsp_active <= '0'; when asc('S') => -- select cmd_v := ICSP_CMD_SEL; action_v := true; state_v := wait_s; when asc('^') => -- enter LVP cmd_v := ICSP_CMD_LVP; action_v := true; state_v := wait_s; when asc('\') => -- echo back active_v := true; state_v := echo_s; when asc(':') => -- send data cmd_v := ICSP_CMD_W8; action_v := true; state_v := wait_s; when asc('=') => -- send data cmd_v := ICSP_CMD_W16; action_v := true; state_v := wait_s; when asc('?') => -- receive cmd_v := ICSP_CMD_R16; action_v := true; state_v := read_s; when asc('!') => -- command value_v := value_v; cmd_v := ICSP_CMD_W6; action_v := true; state_v := wait_s; when asc('+') => -- increment value_v := x"0006"; cmd_v := ICSP_CMD_W6; action_v := true; state_v := wait_s; when asc('.') => -- delay value_v := value_v; cmd_v := ICSP_CMD_DLY; action_v := true; state_v := wait_s; when asc('#') => -- crc crc_tx_v := crc_tx_out; crc_rx_v := crc_rx_out; count_v := 3; index_v := 0; state_v := cout_s; when asc('%') => -- stats stat_ovfl_v := (others => '0'); count_v := 3; state_v := sout_s; when asc('[') => -- echo off echo_v := false; echo_this_v := false; state_v := wait_s; when asc(']') => -- echo on echo_v := true; state_v := wait_s; when asc('_') => -- ignore echo_this_v := false; state_v := wait_s; when others => -- bad char inc_p(stat_badc_v); value_v := (others => '0'); state_v := wait_s; end case; end if; if action_v then icsp_cmd <= cmd_v; icsp_out <= value_v; icsp_valid <= '1'; value_v := (others => '0'); active_v := true; end if; rx0_ren <= '1'; -- consume char if echo_this_v then if not tx0_full then -- if not full inc_p(stat_echo_v); tx0_data <= rx0_data; -- echo back tx0_wen <= '1'; else inc_p(stat_full_v); end if; end if; elsif not icsp_active then if not active_v then if not rx1_empty and not tx0_full then rx1_ren <= '1'; -- consume char tx0_data <= rx1_data; -- output tx0_wen <= '1'; active_v := true; end if; else active_v := false; end if; end if; when wait_s => icsp_valid <= '0'; if not active_v and (icsp_ready = '1') then state_v := idle_s; end if; active_v := false; when read_s => icsp_valid <= '0'; if not active_v and (icsp_ready = '1') then count_v := 3; state_v := dout_s; end if; active_v := false; when echo_s => if not active_v and (rx0_empty = '0') then if rx0_data = asc('\') then state_v := wait_s; end if; rx0_ren <= '1'; -- consume char tx0_data <= rx0_data; -- echo back tx0_wen <= '1'; active_v := true; else active_v := false; end if; when cout_s => if (tx0_full = '0') and not active_v then tx0_data <= htoa_c(to_index( crc_rx_v(count_v*4+3 downto count_v*4))) when index_v = 0 else htoa_c(to_index( crc_tx_v(count_v*4+3 downto count_v*4))); tx0_wen <= '1'; if count_v = 0 then if index_v = 1 then crc_rx_reset <= '1'; crc_tx_reset <= '1'; state_v := idle_s; else count_v := 3; index_v := index_v + 1; end if; else count_v := count_v - 1; end if; active_v := true; else active_v := false; end if; when dout_s => if (tx0_full = '0') and not active_v then tx0_data <= htoa_c(to_index( icsp_in(count_v*4+3 downto count_v*4))); tx0_wen <= '1'; if count_v = 0 then state_v := idle_s; else count_v := count_v - 1; end if; active_v := true; else active_v := false; end if; when pout_s => if (tx0_full = '0') and not active_v then tx0_data <= "0000" & icsp_clk_t & icsp_dat_t & icsp_clk_o & icsp_dat_o; tx0_wen <= '1'; state_v := idle_s; active_v := true; else active_v := false; end if; when sout_s => if (tx0_full = '0') and not active_v then with count_v select tx0_data <= htoa_c(to_index(stat_badc_v)) when 3, htoa_c(to_index(stat_full_v)) when 2, htoa_c(to_index(stat_ovfl_v)) when 1, htoa_c(to_index(stat_echo_v)) when 0; tx0_wen <= '1'; if count_v = 0 then stat_echo_v := (others => '0'); stat_full_v := (others => '0'); stat_ovfl_v := (others => '0'); stat_badc_v := (others => '0'); state_v := idle_s; else count_v := count_v - 1; end if; active_v := true; else active_v := false; end if; end case; end if; end process; crc_rx_in <= rx0_data; crc_rx_en <= rx0_ren; crc_tx_in <= tx0_data; crc_tx_en <= tx0_wen; pmod_n(0) <= uart1_rx; pmod_n(1) <= rx1_empty; pmod_n(2) <= rx1_ren; pmod_n(3) <= icsp_active; pmod_n(4) <= icsp_ready; pmod_n(7 downto 5) <= icsp_urx; /* debug_proc : process (mchp_clk) variable count_v : unsigned(15 downto 0) := (others => '0'); begin if rising_edge(mchp_clk) then count_v := count_v + "1"; pmod_n <= std_logic_vector(count_v(15 downto 8)); end if; end process; */ end RTL;