Commit 749af830 authored by kblantos's avatar kblantos

Remove unused spi_slave_old.vhd module

parent 8ed2e0c7
-------------------------------------------------------------------------------
-- SPDX-FileCopyrightText: 2022 CERN (home.cern)
--
-- SPDX-License-Identifier: CERN-OHL-W-2.0+
-------------------------------------------------------------------------------
-- Title : SPI Slave
-- Project : ProFIP
-------------------------------------------------------------------------------
-- File : spi_slave.vhd
-- Author : Konstantinos Blantos
-- Company : CERN (BE-CEM-EDL)
-- Created : 13-10-2022
-- Last update:
-- Platform : FPGA-generic
-- Standard : VHDL'08
-------------------------------------------------------------------------------
-- Description: Simple SPI Slave. Receiving input data in any given width
-- and sending to a master through MISO. Receiving MOSI bits and
-- converting it to output data. Control signals also supported.
-------------------------------------------------------------------------------
-- Copyright (c) 2019 CERN
--
-- Copyright and related rights are licensed under the Solderpad Hardware
-- License, Version 0.51 (the "License") (which enables you, at your option,
-- to treat this file as licensed under the Apache License 2.0); you may not
-- use this file except in compliance with the License. You may obtain a copy
-- of the License at http://solderpad.org/licenses/SHL-0.51.
-- Unless required by applicable law or agreed to in writing, software,
-- hardware and materials distributed under this License is distributed on an
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
-- or implied. See the License for the specific language governing permissions
-- and limitations under the License.
-------------------------------------------------------------------------------
--=============================================================================
-- Libraries & Packages --
--=============================================================================
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
--=============================================================================
-- Entity declaration for spi_slave --
--=============================================================================
entity spi_slave is
generic (
g_data_width : natural; -- Data width in bits
g_cpol : natural range 0 to 1; -- Clock polarity (can be 0 or 1)
g_cpha : natural range 0 to 1 -- Clock phase (can be 0 or 1)
);
port (
-- FPGA clock and reset
clk_i : in std_logic; -- System (wishbone) clock
rst_n_i : in std_logic; -- System (wishbone) reset
-- SPI Interface
spi_clk_i : in std_logic; -- SPI clock
spi_cs_n_i : in std_logic; -- SPI chip select, active LOW
spi_mosi_i : in std_logic; -- SPI serial data, master out slave in
spi_miso_o : out std_logic; -- SPI serial data, master in slave out
-- User Interface
data_i : in std_logic_vector(g_data_width-1 downto 0);
data_valid_i : in std_logic;
data_o : out std_logic_vector(g_data_width-1 downto 0);
data_valid_o : out std_logic;
-- Flag
busy_o : out std_logic;
ready_o : out std_logic
);
end entity spi_slave;
--==============================================================================
-- Architecture declaration --
--==============================================================================
architecture rtl of spi_slave is
-- Returns log of 2 of a natural number
function f_log2_ceil(N : natural) return positive is
begin
if N <= 2 then
return 1;
elsif N mod 2 = 0 then
return 1 + f_log2_ceil(N/2);
else
return 1 + f_log2_ceil((N+1)/2);
end if;
end;
--! Reset
signal s_rst_n : std_logic;
-- Signals
signal data_reg_o : std_logic_vector(g_data_width-1 downto 0);
signal data_reg_i : std_logic_vector(g_data_width-1 downto 0);
signal mosi_cnt : unsigned(f_log2_ceil(g_data_width)-1 downto 0);
signal miso_cnt : unsigned(f_log2_ceil(g_data_width)-1 downto 0);
signal s_data_valid : std_logic;
signal spi_clk_sync : std_logic;
signal spi_clk_redge : std_logic;
signal spi_clk_fedge : std_logic;
signal spi_cs_n_sync : std_logic;
signal sample_en : std_logic;
signal shift_en : std_logic;
signal mosi : std_logic;
signal s_ready : std_logic;
begin
----------------------------------------------------------------------------
-- Synchronize signals from SPI to the clock domain of FPGA
----------------------------------------------------------------------------
-- Use of gc_sync_ffs module in order to synchronize and
-- detect the negative and positive edges of clock
-- Here spi clock can be 0.5MHz up to 25MHz
-- and FPGA clk_i should be 62.5MHz or 100MHz/125MHz
cmp_spi_clk_sync_ffs : entity work.gc_sync_ffs
generic map (
g_SYNC_EDGE => "positive"
)
port map (
clk_i => clk_i, -- clock from the destination clock domain (125MHz)
rst_n_i => rst_n_i, -- async reset
data_i => spi_clk_i, -- async input
synced_o => spi_clk_sync, -- synchronized output
npulse_o => spi_clk_fedge, -- negative edge detect output
ppulse_o => spi_clk_redge -- positive edge detect output
);
-- Define the sampling and shifting based on the CPHA
gen_pha_zero : if g_cpha = 0 generate
sample_en <= spi_clk_redge;
shift_en <= spi_clk_fedge;
end generate;
gen_pha_one : if g_cpha = 1 generate
sample_en <= spi_clk_fedge;
shift_en <= spi_clk_redge;
end generate;
cmp_spi_cs_n_sync_ffs : entity work.gc_sync_ffs
generic map (
g_SYNC_EDGE => "positive"
)
port map (
clk_i => clk_i, -- clock from the destination clock domain (125MHz)
rst_n_i => rst_n_i, -- async reset
data_i => spi_cs_n_i, -- async input
synced_o => spi_cs_n_sync, -- synchronized output
npulse_o => open, -- negative edge detect output
ppulse_o => open -- positive edge detect output
);
cmp_spi_mosi_sync_ffs : entity work.gc_sync_ffs
generic map (
g_SYNC_EDGE => "positive"
)
port map (
clk_i => clk_i, -- clock from the destination clock domain (125MHz)
rst_n_i => rst_n_i, -- async reset
data_i => spi_mosi_i, -- async input
synced_o => mosi, -- synchronized output
npulse_o => open, -- negative edge detect output
ppulse_o => open -- positive edge detect output
);
----------------------------------------------------------------------------
-- RTL logic for Sampling and Shifting MOSI/MISO data bits
----------------------------------------------------------------------------
--! Reset
s_rst_n <= rst_n_i and not(spi_cs_n_sync);
----------------------------------------------------------------------------
-- MOSI
----------------------------------------------------------------------------
-- Process to sample the MOSI data
p_MOSI : process(clk_i, s_rst_n)
begin
if s_rst_n = '0' then
data_reg_o <= (others=>'0');
mosi_cnt <= (others=>'0');
s_data_valid <= '0';
elsif rising_edge(clk_i) then
if sample_en = '1' then
data_reg_o <= data_reg_o(g_data_width-2 downto 0) & mosi;
if (mosi_cnt = g_data_width-1) then
s_data_valid <= '1';
mosi_cnt <= (others=>'0');
else
s_data_valid <= '0';
mosi_cnt <= mosi_cnt + 1;
end if;
end if;
end if;
end process p_MOSI;
data_o <= data_reg_o;
data_valid_o <= s_data_valid;
----------------------------------------------------------------------------
-- MISO
----------------------------------------------------------------------------
p_MISO : process(clk_i, s_rst_n)
begin
if s_rst_n = '0' then
data_reg_i <= (others=>'0');
miso_cnt <= (others=>'0');
s_ready <= '0';
elsif rising_edge(clk_i) then
if shift_en = '1' then
if g_cpha = 1 and miso_cnt = 0 then
data_reg_i <= data_i;
miso_cnt <= miso_cnt + 1;
s_ready <= '0';
else
data_reg_i <= data_reg_i(g_data_width-2 downto 0) & '0';
if miso_cnt = g_data_width-1 then
miso_cnt <= (others=>'0');
s_ready <= '1';
else
miso_cnt <= miso_cnt + 1;
s_ready <= '0';
end if;
end if;
end if;
end if;
end process p_MISO;
spi_miso_o <= data_reg_i(g_data_width-1);
ready_o <= s_ready;
end architecture rtl;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment