diff --git a/spi_driver.vhd b/spi_driver.vhd new file mode 100644 index 0000000..3a6f817 --- /dev/null +++ b/spi_driver.vhd @@ -0,0 +1,85 @@ +---------------------------------------------------------------------------------- +-- Company: +-- Engineer: +-- +-- Create Date: 12:51:31 05/17/2016 +-- Design Name: +-- Module Name: spi_driver - 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.NUMERIC_STD.ALL; + +-- Uncomment the following library declaration if instantiating +-- any Xilinx primitives in this code. +--library UNISIM; +--use UNISIM.VComponents.all; + +entity spi_driver is + Generic (clk_freq: natural:= 50000000; + adc_res: natural:=12); + Port ( clk : in STD_LOGIC; + rst: in STD_LOGIC; + val : in unsigned (adc_res-1 downto 0); + sck : out STD_LOGIC; + cs : out STD_LOGIC; + mosi : out STD_LOGIC); +end spi_driver; + +architecture Behavioral of spi_driver is + type states is(S_IDLE, S_WORK); + signal state_reg, state_next: states := S_IDLE; + signal counter, counter_next: unsigned(5 downto 0) := (others => '0'); + signal data: unsigned(23 downto 0); +begin + REGS: process (clk, rst) is + begin -- process start + if rst = '1' then -- asynchronous reset (active high) + state_reg <= S_IDLE; + counter <= to_unsigned(0,counter'length); + elsif rising_edge(clk) then -- rising clock edge + state_reg <= state_next; + counter <= counter_next; + end if; + end process REGS; + + data(23 downto 20) <= "0011"; --Command: Write to and Update (Power Up) + data(19 downto 16) <= "0000"; --Adress: DAC0 + data(15 downto 4) <= val; -- DAC Value (12bit) + data(3 downto 0) <= "0000"; -- 4x don't care + + mosi <= data(23 - to_integer(counter srl 1)) when state_reg=S_WORK else '0'; + sck <= '1' when state_reg=S_WORK and counter(0)='1' else '0'; + cs <= '1' when state_reg =S_IDLE else '0'; + + NSL: process (state_reg, counter) is + begin + state_next <= state_reg; + counter_next <= counter; + case state_reg is -- switch on current state + when S_IDLE => -- currently in idle state + state_next <= S_WORK; + counter_next <= to_unsigned(0,counter'length); + when S_WORK => -- currently in work state + if(counter = 24*2 -1) then + state_next <= S_IDLE; + else + counter_next<= counter + 1; + end if; + when others => null; -- do nothing, if we are in a different state + end case; + end process NSL; + +end Behavioral; + diff --git a/spi_driver_tb.vhd b/spi_driver_tb.vhd new file mode 100644 index 0000000..a8c72b3 --- /dev/null +++ b/spi_driver_tb.vhd @@ -0,0 +1,118 @@ +-------------------------------------------------------------------------------- +-- Company: +-- Engineer: +-- +-- Create Date: 15:38:41 05/17/2016 +-- Design Name: +-- Module Name: /home/timo/vhdl-yasg/spi_driver_tb.vhd +-- Project Name: yasg +-- Target Device: +-- Tool versions: +-- Description: +-- +-- VHDL Test Bench Created by ISE for module: spi_driver +-- +-- Dependencies: +-- +-- Revision: +-- Revision 0.01 - File Created +-- Additional Comments: +-- +-- Notes: +-- This testbench has been automatically generated using types std_logic and +-- std_logic_vector for the ports of the unit under test. Xilinx recommends +-- that these types always be used for the top-level I/O of a design in order +-- to guarantee that the testbench will bind correctly to the post-implementation +-- simulation model. +-------------------------------------------------------------------------------- +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; + +-- Uncomment the following library declaration if using +-- arithmetic functions with Signed or Unsigned values +USE ieee.numeric_std.ALL; + +ENTITY spi_driver_tb IS +END spi_driver_tb; + +ARCHITECTURE behavior OF spi_driver_tb IS + + -- Component Declaration for the Unit Under Test (UUT) + + COMPONENT spi_driver + PORT( + clk : IN std_logic; + rst : IN std_logic; + val : IN unsigned(11 downto 0); + sck : OUT std_logic; + cs : OUT std_logic; + mosi : OUT std_logic + ); + END COMPONENT; + + + --Inputs + signal clk : std_logic := '0'; + signal rst : std_logic := '0'; + signal val : unsigned(11 downto 0) := (others => '0'); + + --Outputs + signal sck : std_logic; + signal cs : std_logic; + signal mosi : std_logic; + + -- Clock period definitions + constant clk_period : time := 20 ns; --50mhz + +BEGIN + + -- Instantiate the Unit Under Test (UUT) + uut: spi_driver PORT MAP ( + clk => clk, + rst => rst, + val => val, + sck => sck, + cs => cs, + mosi => mosi + ); + + -- Clock process definitions + clk_process :process + begin + clk <= '0'; + wait for clk_period/2; + clk <= '1'; + wait for clk_period/2; + end process; + + + -- Stimulus process + stim_proc: process + begin + -- hold reset state for 100 ns. + rst <= '1'; + wait for 100 ns; + rst <= '0'; + wait for clk_period*10; + + val <= to_unsigned(0,12); + wait for clk_period*64; + + val <= to_unsigned(7,12); + wait for clk_period*64; + + val <= to_unsigned(31,12); + wait for clk_period*64; + + val <= to_unsigned(128,12); + wait for clk_period*64; + + val <= to_unsigned(512,12); + wait for clk_period*64; + + -- insert stimulus here + + wait; + end process; + +END; diff --git a/yasg.gise b/yasg.gise index b11f790..20c0240 100644 --- a/yasg.gise +++ b/yasg.gise @@ -37,19 +37,30 @@ - - - + + + + + + + + + + + + + + @@ -60,100 +71,101 @@ - + + + - + - + - + - + + + - + - - - + + - + - - + - + - + - + - + - + - + - + - - - - - - - - - - + + + + + + + + + diff --git a/yasg.xise b/yasg.xise index 87f2d52..fff95c7 100644 --- a/yasg.xise +++ b/yasg.xise @@ -20,19 +20,29 @@ - - + + - - + + - + + + + + + + + + + + @@ -40,23 +50,24 @@ - - - + + + - - + + + - +