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;