feat: 🔥 oh god
This commit is contained in:
parent
cdb5492bfe
commit
3c7f48016d
30 changed files with 708 additions and 280 deletions
129
test/faux_build_dir/vhdl/spi_master.vhd
Normal file
129
test/faux_build_dir/vhdl/spi_master.vhd
Normal file
|
@ -0,0 +1,129 @@
|
|||
--! @author David Bailey (d.bailey@cern.ch)
|
||||
|
||||
-- comf.include: UQDS_specifics_pkg.vhd
|
||||
-- comf.vhdl.work: uqdslib
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.std_logic_unsigned.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
Library UQDSLib;
|
||||
use UQDSLib.UQDS_specifics_pkg.all;
|
||||
|
||||
--! @brief Simple 8-bit fixed length SPI master
|
||||
--! @details This VHDL code is intended to provide a basic data I/O
|
||||
--! interface to easily interface with standard SPI-based peripherals.
|
||||
--! Its main purpose is to clock data in/out. It does *not* contain
|
||||
--! arbitratrion nor chip-select handling!
|
||||
entity spi_master is
|
||||
generic(
|
||||
--! Will divide the FPGA-Clock by this value for the SPI clock
|
||||
clkdiv : natural := 40;
|
||||
clk_idle : std_logic := '1'
|
||||
);
|
||||
port(
|
||||
--! Resets the SPI port. Will stop it mid-transition.
|
||||
--! Forces data_rx to 0.
|
||||
rst : in std_logic;
|
||||
--! FPGA Clock to run internal logic at
|
||||
clk : in std_logic;
|
||||
|
||||
spi_control_to : in spi_control_to_t;
|
||||
spi_control_from : out spi_control_from_t;
|
||||
|
||||
pin_mosi : out std_logic;
|
||||
pin_miso : in std_logic;
|
||||
pin_clk : out std_logic
|
||||
);
|
||||
end;
|
||||
|
||||
architecture rtl of spi_master is
|
||||
type spi_state_t is ( IDLE, HIGH_CLK, LOW_CLK );
|
||||
signal spi_state : spi_state_t := IDLE;
|
||||
|
||||
signal clk_divider : integer range 0 to clkdiv/2 ;
|
||||
signal bit_cnt : integer range 0 to 7;
|
||||
|
||||
signal data_rx_fragment : std_logic_vector(7 downto 0);
|
||||
signal data_tx_fragment : std_logic_vector(6 downto 0);
|
||||
|
||||
signal byte_tx_complete_i : std_logic := '0';
|
||||
signal byte_rx_complete_i : std_logic := '0';
|
||||
begin
|
||||
|
||||
spi_control_from.byte_tx_complete <= byte_tx_complete_i;
|
||||
spi_control_from.byte_rx_complete <= byte_rx_complete_i;
|
||||
|
||||
spi_transmission: process(clk)
|
||||
begin
|
||||
if(rising_edge(clk)) then
|
||||
byte_tx_complete_i <= '0';
|
||||
byte_rx_complete_i <= '0';
|
||||
|
||||
--! Reset clause, the rest of the code won't get to run
|
||||
--! while reset asserts
|
||||
if(rst = '1') then
|
||||
spi_state <= IDLE;
|
||||
|
||||
clk_divider <= 0;
|
||||
bit_cnt <= 0;
|
||||
|
||||
data_rx_fragment <= (others => '0');
|
||||
data_tx_fragment <= (others => '0');
|
||||
|
||||
spi_control_from.data_rx <= (others => '0');
|
||||
|
||||
byte_tx_complete_i <= '0';
|
||||
byte_rx_complete_i <= '0';
|
||||
|
||||
pin_mosi <= '0';
|
||||
pin_clk <= clk_idle;
|
||||
elsif(clk_divider > 0) then
|
||||
clk_divider <= clk_divider - 1;
|
||||
else
|
||||
case spi_state is
|
||||
when IDLE =>
|
||||
if(spi_control_to.send_request) then
|
||||
data_tx_fragment <= spi_control_to.data_tx(6 downto 0);
|
||||
data_rx_fragment <= (others => '0');
|
||||
|
||||
clk_divider <= clkdiv / 2;
|
||||
bit_cnt <= 7;
|
||||
|
||||
pin_clk <= not clk_idle;
|
||||
pin_mosi <= spi_control_to.data_tx(spi_control_to.data_tx'left);
|
||||
|
||||
spi_state <= HIGH_CLK;
|
||||
|
||||
byte_tx_complete_i <= '1';
|
||||
end if;
|
||||
when HIGH_CLK =>
|
||||
pin_clk <= clk_idle;
|
||||
|
||||
data_rx_fragment <= data_rx_fragment(6 downto 0) & pin_miso;
|
||||
|
||||
clk_divider <= clkdiv / 2;
|
||||
spi_state <= LOW_CLK;
|
||||
|
||||
if(bit_cnt = 0) then
|
||||
spi_control_from.data_rx <= data_rx_fragment(6 downto 0) & pin_miso;
|
||||
byte_rx_complete_i <= '1';
|
||||
|
||||
spi_state <= IDLE;
|
||||
else
|
||||
bit_cnt <= bit_cnt - 1;
|
||||
end if;
|
||||
when LOW_CLK =>
|
||||
pin_clk <= not clk_idle;
|
||||
pin_mosi <= data_tx_fragment(data_tx_fragment'left);
|
||||
data_tx_fragment <= data_tx_fragment(data_tx_fragment'left-1 downto 0) & '0';
|
||||
|
||||
clk_divider <= clkdiv / 2;
|
||||
spi_state <= HIGH_CLK;
|
||||
end case;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end architecture;
|
Loading…
Add table
Add a link
Reference in a new issue