OpenCores
URL https://opencores.org/ocsvn/tinyvliw8/tinyvliw8/trunk

Subversion Repositories tinyvliw8

[/] [tinyvliw8/] [trunk/] [src/] [vhdl/] [spiSlave.vhd] - Rev 2

Compare with Previous | Blame | View Log

--
-- 	SPI slave module
 
LIBRARY	IEEE;
USE	IEEE.STD_LOGIC_1164.ALL;
 
ENTITY spiSlave IS
	PORT (
		rst_n    : IN  STD_LOGIC;	-- asynchr. reset, low active
 
  -- SPI bus lines		
		sclk      : IN  STD_LOGIC;	-- clock signal
		cs        : IN  STD_LOGIC;	-- chip select, low active
		mosi      : IN  STD_LOGIC;	-- data in (from SPI master)
		miso      : OUT STD_LOGIC;	-- data out (to SPI master)
 
  -- connection to SPI_registers		
		addr      : OUT std_logic_vector(10 downto 0);	-- register address
		memSel    : out std_logic_vector(1 downto 0);   -- memory selection
 
		writeEn_n : OUT STD_LOGIC;	                     -- write enable, low active
		readEn_n  : OUT STD_LOGIC;                      -- read enable, low active
		dataOut   : OUT std_logic_vector(31 downto 0);	-- data bus for writing register
		dataIn    : IN std_logic_vector(31 downto 0)    -- data bus for reading register
	);
END spiSlave;
 
ARCHITECTURE behav OF spiSlave IS
 
	signal count    : INTEGER RANGE 0 TO 32 + 16;       -- state counter
	signal size     : INTEGER RANGE 0 TO 1;             -- data size flag
 
	signal miso_s   : std_logic;
 
	signal rdEn_s   : std_logic;
	signal wrEn_s   : std_logic;
 
	signal wr_s     : std_logic;
	signal memSel_s : std_logic_vector(1 downto 0);
	signal addr_s    : std_logic_vector(10 downto 0);
	signal addrOut_s : std_logic_vector(10 downto 0);
 
	signal data_s   : std_logic_vector(31 downto 0);
 
BEGIN
 
	PROCESS (sclk, rst_n, cs)			-- state counter
	BEGIN
		IF (rst_n = '0') THEN
			count <= 0;
			wr_s <= '0';
 
			memSel_s  <= (others => '0');
			addr_s    <= (others => '0');
			addrOut_s <= (others => '0');
 
			data_s   <= (others => '0');
		ELSE
	   	if (cs = '0') then
				if (sclk'EVENT AND sclk='1') THEN	-- rising SCKL edge
					IF (size = 0 and count = (16 + 7)) or (size = 1 and count = (16 + 31)) THEN
						count <= 0;
					ELSE
						count <= count + 1;
					END IF;
 
					IF count < 8 then
						addr_s(7 downto 0) <= addr_s(6 downto 0) & mosi;
					elsif count > 7 and count < 11 THEN
						addr_s(10 downto 8) <= addr_s(9 downto 8) & mosi;
					elsif count = 12 THEN
						addrOut_s <= addr_s;
						memSel_s(1) <= mosi;
					elsif count = 13 THEN
						memSel_s(0) <= mosi;
					elsif count = 15 THEN
						wr_s <= mosi;
					elsif ((count > 15) and ((size = 0 and (count < (16 + 8))) or (size = 1 and (count < (16 + 32))))) then
						data_s <= data_s(30 downto 0) & mosi;
					END if;
				END if;
			else
				count <= 0;
			end if;
		END IF;
	END PROCESS;
 
	PROCESS (sclk, rst_n, cs)			-- input SPI shift register
	BEGIN
		if (rst_n = '0' or cs = '1') then
			size <= 0;
 
			wrEn_s <= '0';
			rdEn_s <= '0';
 
			miso_s <= '0';
		else
			IF sclk'EVENT AND sclk='0' THEN          -- falling SCKL edge
				if (count = 0) then
					wrEn_s <= wr_s;                 -- generate write enable signal
				elsif (count = 1) then
					wrEn_s <= '0';
					rdEn_s <= '0';
				elsif (count = 15) then
					rdEn_s <= '1';
					if (memSel_s = "00") then
						size <= 1;
					end if;
				elsif ((count > 15) and ((size = 0 and (count < (16 + 7))) or (size = 1 and (count < (16 + 31))))) then
					if (memSel_s = "00") then
						miso_s <= dataIn(47 - count);
					else
						miso_s <= dataIn(23 - count);
					end if;
				END IF;
			END IF;
		END IF;
	END PROCESS;
 
	miso      <= miso_s;
 
	readEn_n  <= not(rdEn_s) when cs = '0' else
	             '1';
	writeEn_n <= not(wrEn_s) when cs = '0' else
	             '1';
 
	memSel    <= memSel_s;
	addr      <= addrOut_s;
	dataOut   <= data_s;
 
END behav;
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.