library IEEE; use IEEE.STD_LOGIC_1164.all; use IEEE.NUMERIC_STD.all; --library work; use work. SPI_Master_pack.all; entity SPI_Master is -- SPI-Modus 0: CPOL=0, CPHA=0 generic (Quarz_Taktfrequenz : integer := 50000000; -- Hertz SPI_Taktfrequenz : integer := 1000000; -- Hertz / zur Berechnung des Reload-Werts für Taktteiler Laenge : integer := 16 -- Anzahl der zu übertragenden Bits ); port ( MOSI : out std_logic; -- MISO : in STD_LOGIC; SCLK : buffer std_logic; SS : buffer std_logic; TX_Done : out std_logic ); end SPI_Master; architecture Behavioral of SPI_Master is ------TESTBENCH Signale----------- signal TX_Start : std_logic; signal clk : std_logic; signal reset : std_logic; ------------------------------------- signal delay : integer range 0 to (Quarz_Taktfrequenz/(2*SPI_Taktfrequenz)); constant clock_delay : integer := (Quarz_Taktfrequenz/(2*SPI_Taktfrequenz))-1; type spitx_states is (spi_stx, spi_txactive, spi_etx); signal spitxstate : spitx_states := spi_stx; type arrayDataTx is array (0 to 6) of std_logic_vector(15 downto 0); constant constTxData : arrayDataTx := ("0001000001001110", --reg A "0010000100111001", --reg B "0000100000000000", --reg C "0000010010011010", --reg VADC "0011011111111111", --reg OS_IF "0111011111111111", --reg OS_FM "0101011111111111"); --reg OS_CAP_FM signal TxData : arrayDataTx; signal assortment : std_logic_vector(3 downto 0):=("0000"); signal spiclk : std_logic; signal spiclklast : std_logic; -- signal TX_Data : STD_LOGIC_VECTOR (Laenge-1 downto 0); -- Sendedaten signal bitcounter : integer range 0 to Laenge + 1; -- wenn bitcounter = Laenge --> alle Bits uebertragen signal tx_reg : std_logic_vector(Laenge-1 downto 0) := (others => '0'); signal rx_reg : std_logic_vector(Laenge-1 downto 0) := (others => '0'); --signal txsrslave : std_logic_vector(0 downto 0) := ("000000000000000"); signal EN_MEASbit : std_logic_vector(0 downto 0); signal DEM_PMUTEbit : std_logic_vector(0 downto 0); signal CNT_RSTbitL : std_logic_vector(0 downto 0); signal CNT_RSTbitH : std_logic_vector(0 downto 0); signal CNT1_ENbit : std_logic_vector(0 downto 0); signal CNT1_DISbit : std_logic_vector(0 downto 0); signal OS_IF_OSCbit : std_logic_vector(3 downto 0); signal index : integer; signal delayCount : integer; signal StartTxvar : std_logic; begin ------ Verwaltung -------- process (clk, reset) begin -- process if reset = '0' then SS <= '0'; TX_Done <= '0'; bitcounter <= Laenge; spiclk <= '0'; spiclklast <= '0'; index <= 0; delayCount <= 0; EN_MEASbit <= "0"; DEM_PMUTEbit <= "1"; CNT_RSTbitL <= "0"; CNT1_ENbit <= "1"; CNT1_DISbit <= "0"; OS_IF_OSCbit <= "1001"; CNT_RSTbitH <= "1"; else if clk'event and clk = '1' then -- falling clock edge if(delay > 0) then --zaehlt von 24 bis 0 runter delay <= delay-1; else delay <= clock_delay; end if; case spitxstate is when spi_stx => SS <= '0'; -- slave select disabled TX_Done <= '0'; bitcounter <= Laenge; spiclk <= '0'; -- SPI-Modus 0 if(TX_Start = '1') or StartTxvar = '1' then StartTxvar <= '0'; SS <= '1'; delay <= clock_delay; --spiclk <= '1'; spitxstate <= spi_txactive; end if; when spi_txactive => -- Daten aus tx_reg uebertragen if (delay = 0) then -- shift spiclk <= not spiclk; if (bitcounter = 0) then -- alle Bits uebertragen -> deselektieren spiclk <= '0'; -- SPI-Modus 0 delay <= 0; index <= index + 1; spitxstate <= spi_etx; end if; if(spiclk = '1') then bitcounter <= bitcounter-1; end if; end if; when spi_etx => SS <= '0'; -- disable Slave Select TX_Done <= '1'; if(TX_Start = '0') and (index /= 9) then spitxstate <= spi_stx; end if; if (delay = 0) and (index = 9) then delayCount <= delayCount + 1; if (delayCount = 200000) then TX_Done <= '0'; bitcounter <= Laenge; spiclk <= '0'; SS <= '1'; delay <= clock_delay; spitxstate <= spi_txactive; end if; end if; end case; spiclklast <= spiclk; end if; end if; --end if; end process; ------ Sendeschieberegister ------- Sendeschieberegister: process (clk, index) begin StartTxvar <= '0'; if rising_edge(CLK) then if (spitxstate = spi_stx) and (index <= 6) then --assortment <= x"A"; tx_reg <= constTxData(index); --Defaultwerte werden ausgegeben end if; if(spitxstate = spi_stx) and (index > 6) and (index <= 8) then --assortment <= x"B"; tx_reg <= TxData(index - 7); --bei 0 -> Reg A bei 1 -> Reg B elsif(spitxstate = spi_stx) and (index >= 9) then --Register B wird auf wieder auf default Wert gesetzt --Counter 1 wird "disenabled" StartTxvar <= '1'; tx_reg <= TxData(index - 8); end if; if (spiclk = '0' and spiclklast = '1') then -- SPI-Modus 0 tx_reg <= tx_reg(0) & tx_reg(tx_reg'left downto 1); end if; end if; end process Sendeschieberegister; SCLK <= spiclk; MOSI <= tx_reg(tx_reg'left); RegStatus: process(OS_IF_OSCbit, EN_MEASbit, DEM_PMUTEbit, CNT_RSTbitL, CNT_RSTbitH,CNT1_ENbit) begin --set the Values for the Measuring Mode --in register A and register B TxData <= constTxData; case index is when 0 => --Wird erst bei der Zuweisung reg_tx <= TxData im Prozess "Schieberegister" zugewiesen --TxData <= constTxData; TxData(0)(10 downto 7) <= OS_IF_OSCbit; TxData(0)(3 downto 3) <= EN_MEASbit; TxData(0)(5 downto 5) <= DEM_PMUTEbit; --Counter ist nun bereit zum --zaehlen wenn RW Enable gleich Null TxData(1) (3 downto 3) <= CNT_RSTbitL; TxData(1) (2 downto 2) <= CNT1_ENbit; when 1 => TxData(1)(2 downto 2) <= CNT1_DISbit; TxData(1)(3 downto 3) <= CNT_RSTbitH; when others => null; end case; end process RegStatus; --------------------Testbench--------------------- TAKTGEN : process begin clk <= '1'; wait for 10 ns; clk <= '0'; wait for 10 ns; end process TAKTGEN; Start : process begin TX_Start <= '0', '1' after 5 us, '0' after 25 us, '1' after 30 us, '0' after 50 us, '1' after 55 us, '0' after 75 us, '1' after 80 us, '0' after 100 us, '1' after 105 us, '0' after 125 us, '1' after 130 us, '0' after 150 us, '1' after 155 us, '0' after 175 us, '1' after 180 us, '0' after 200 us, '1' after 205 us, '0' after 225 us; wait; end process Start; INIT_RESET : process begin RESET <= '0', '1' after 1 us; wait; end process INIT_RESET; end Behavioral;