---------------------------------------------------------------------------------- -- Company: -- Engineer: -- -- Create Date: 15:14:35 08/04/2011 -- Design Name: -- Module Name: SPI_if - Behavioral -- Project Name: -- Target Devices: -- Tool versions: -- Description: -- -- Dependencies: -- -- Revision: -- Revision 0.01 - File Created -- Additional Comments: -- ---------------------------------------------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; use IEEE.std_logic_misc.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 primitives in this code. library UNISIM; use UNISIM.VComponents.all; entity SPI_if is Port ( SCK : in STD_LOGIC; CSn : in STD_LOGIC; MOSI : in STD_LOGIC; MISO : out STD_LOGIC; SN : in STD_LOGIC_VECTOR (8 downto 0); IsT1 : in STD_LOGIC; OT : in STD_LOGIC; newIPADDR : out STD_LOGIC; SPI_we : out STD_LOGIC; en_RARP : out STD_LOGIC; IPADDR : out STD_LOGIC_VECTOR (31 downto 0); SPI_rdata : in STD_LOGIC_VECTOR (7 downto 0); SPI_wdata : out STD_LOGIC_VECTOR (7 downto 0); SPI_addr : out STD_LOGIC_VECTOR (7 downto 0)); end SPI_if; architecture Behavioral of SPI_if is signal SPI_write : std_logic := '0'; signal SPI_read : std_logic := '0'; signal READ_STATUS : std_logic := '0'; signal WRITE_CTL : std_logic := '0'; signal BitCntr : std_logic_vector(4 downto 0) := (others => '0'); signal sr_in : std_logic_vector(6 downto 0) := (others => '0'); signal sr_out : std_logic_vector(7 downto 0) := (others => '0'); signal addr : std_logic_vector(8 downto 0) := (others => '0'); signal SPI_we_i : std_logic := '0'; signal SPI_we_q : std_logic := '0'; signal STATUS : std_logic_vector(7 downto 0) := x"10"; --signal CONF : std_logic_vector(7 downto 0) := (others => '0'); signal SLOT : std_logic_vector(7 downto 0) := (others => '0'); signal SPI_IPADDR : std_logic_vector(31 downto 0) := (others => '0'); signal IPADDR_i : std_logic_vector(31 downto 0) := (others => '0'); signal IPADDR_high : std_logic_vector(23 downto 0) := (others => '0'); signal NET_MASK : std_logic_vector(31 downto 0) := (others => '0'); signal BOOT_VECTOR : std_logic_vector(15 downto 0) := (others => '0'); begin newIPADDR <= STATUS(5); SPI_addr <= addr(7 downto 0); SPI_we <= SPI_we_i; SPI_wdata <= sr_in & MOSI; MISO <= sr_out(7); IPADDR <= IPADDR_i; --IPADDR_high <= x"c0a801" when SN(7) = '1' else x"c0a802"; IPADDR_high <= x"c0a801" when SN(8 downto 7) = "11" else x"c0a802" when SN(8 downto 7) = "10" else x"c0a803" when SN(8 downto 7) = "01" else x"c0a804"; IPADDR_i <= (IPADDR_high & SN(6 downto 0) & IsT1) when STATUS(5) = '0' else SPI_IPADDR; en_RARP <= '1' when STATUS(5) = '1' and SPI_IPADDR(31 downto 24) = x"00" else '0'; --IPADDR_i <= (x"c0a801" & SN(6 downto 0) & IsT1); process(SCK, CSn, sr_in, MOSI) variable in_byte : std_logic_vector(7 downto 0); begin in_byte := sr_in & MOSI; if(CSn = '1')then SPI_write <= '0'; SPI_read <= '0'; READ_STATUS <= '0'; WRITE_CTL <= '0'; SPI_we_i <= '0'; SPI_we_q <= '0'; BitCntr <= (others => '0'); elsif(SCK'event and SCK = '1')then BitCntr(2 downto 0) <= BitCntr(2 downto 0) + 1; if(BitCntr(2 downto 0) = "111")then BitCntr(4) <= BitCntr(3) or BitCntr(4); BitCntr(3) <= not BitCntr(3) or BitCntr(4); end if; if(BitCntr = "00111")then if(in_byte = x"03")then SPI_read <= '1'; else SPI_read <= '0'; end if; if(in_byte = x"02")then SPI_write <= '1'; else SPI_write <= '0'; end if; if(in_byte = x"05")then READ_STATUS <= '1'; else READ_STATUS <= '0'; end if; if(in_byte = x"07")then WRITE_CTL <= '1'; else WRITE_CTL <= '0'; end if; end if; if(BitCntr = "11110" and SPI_write = '1')then SPI_we_i <= '1'; else SPI_we_i <= '0'; end if; SPI_we_q <= SPI_we_i; end if; end process; process(SCK, sr_in, MOSI) variable CONF :std_logic_vector(7 downto 0); begin CONF := sr_in & MOSI; if(SCK'event and SCK = '1')then sr_in <= sr_in(5 downto 0) & MOSI; if(WRITE_CTL = '1' and BitCntr = "01111")then STATUS(7) <= (STATUS(7) and not (CONF(7) and CONF(0))) or (CONF(7) and CONF(1)); STATUS(6) <= (STATUS(6) and not (CONF(6) and CONF(0))) or (CONF(6) and CONF(1)); STATUS(5) <= (STATUS(5) and not (CONF(5) and CONF(0))) or (CONF(5) and CONF(1)); STATUS(4) <= STATUS(4) and not (CONF(5) and CONF(1)); end if; if(SPI_write = '1' and BitCntr = "11111" and or_reduce(addr(8 downto 4)) = '0')then case addr(3 downto 0) is when x"0" => SLOT <= CONF; when x"1" => NET_MASK(31 downto 24) <= CONF; when x"2" => NET_MASK(23 downto 16) <= CONF; when x"3" => NET_MASK(15 downto 8) <= CONF; when x"4" => NET_MASK(7 downto 0) <= CONF; when x"5" => SPI_IPADDR(31 downto 24) <= CONF; when x"6" => SPI_IPADDR(23 downto 16) <= CONF; when x"7" => SPI_IPADDR(15 downto 8) <= CONF; when x"8" => SPI_IPADDR(7 downto 0) <= CONF; when x"9" => BOOT_VECTOR(15 downto 8) <= CONF; when x"a" => BOOT_VECTOR(7 downto 0) <= CONF; when others => null; end case; end if; if(BitCntr = "01111")then addr(8) <= or_reduce(sr_in & MOSI); elsif(BitCntr = "10111")then addr(7 downto 0) <= sr_in & MOSI; elsif((SPI_read = '1' and BitCntr = "11111") or SPI_we_q = '1')then addr <= addr + 1; end if; end if; end process; STATUS(3) <= OT; process(SCK) begin if(SCK'event and SCK = '0')then if(READ_STATUS = '0' and (SPI_read = '0' or BitCntr(4) = '0' or BitCntr(3) = '0'))then sr_out <= x"ff"; elsif(BitCntr(2 downto 0) = "000")then if(READ_STATUS = '1' and BitCntr(4 downto 3) = "01")then sr_out <= STATUS; elsif(or_reduce(addr(8 downto 4)) = '0')then case addr(3 downto 0) is when x"0" => sr_out <= SLOT; when x"1" => sr_out <= NET_MASK(31 downto 24); when x"2" => sr_out <= NET_MASK(23 downto 16); when x"3" => sr_out <= NET_MASK(15 downto 8); when x"4" => sr_out <= NET_MASK(7 downto 0); when x"5" => sr_out <= SPI_IPADDR(31 downto 24); when x"6" => sr_out <= SPI_IPADDR(23 downto 16); when x"7" => sr_out <= SPI_IPADDR(15 downto 8); when x"8" => sr_out <= SPI_IPADDR(7 downto 0); when x"9" => sr_out <= BOOT_VECTOR(15 downto 8); when x"a" => sr_out <= BOOT_VECTOR(7 downto 0); when x"b" => sr_out <= IPADDR_i(31 downto 24); when x"c" => sr_out <= IPADDR_i(23 downto 16); when x"d" => sr_out <= IPADDR_i(15 downto 8); when x"e" => sr_out <= IPADDR_i(7 downto 0); when others => sr_out <= x"00"; end case; else sr_out <= x"00"; end if; else sr_out <= sr_out(6 downto 0) & '0'; end if; end if; end process; end Behavioral;