OpenCores
URL https://opencores.org/ocsvn/spi_master_slave/spi_master_slave/trunk

Subversion Repositories spi_master_slave

[/] [spi_master_slave/] [trunk/] [syn/] [spi_master.vhd] - Diff between revs 6 and 7

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 6 Rev 7
Line 66... Line 66...
--      When the interface is idle, data at the 'do_o' port holds the last word received.
--      When the interface is idle, data at the 'do_o' port holds the last word received.
--
--
--      PARALLEL READ SEQUENCE
--      PARALLEL READ SEQUENCE
--      ======================
--      ======================
--                      ______        ______        ______        ______   
--                      ______        ______        ______        ______   
--      spi_clk          bit1 \______/ bitN \______/bitN-1\______/bitN-2\__...  -- spi 2x base clock
--      spi_clk          bit1 \______/ bitN \______/bitN-1\______/bitN-2\__...  -- internal spi 2x base clock
--                      _    __    __    __    __    __    __    __    __  
--                      _    __    __    __    __    __    __    __    __  
--      pclk_i           \__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \_...  -- parallel interface clock (may be async to sclk_i)
--      pclk_i           \__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \_...  -- parallel interface clock (may be async to sclk_i)
--                      _____________ _____________________________________...  -- 1) rx data is transferred to 'do_buffer_reg'
--                      _____________ _____________________________________...  -- 1) rx data is transferred to 'do_buffer_reg'
--      do_o            ___old_data__X__________new_data___________________...  --    after last rx bit, at rising 'spi_clk'.
--      do_o            ___old_data__X__________new_data___________________...  --    after last rx bit, at rising 'spi_clk'.
--                                                   ____________               
--                                                   ____________               
Line 162... Line 162...
        SPI_2X_CLK_DIV : positive := 5);                                -- for a 100MHz sclk_i, yields a 10MHz SCK
        SPI_2X_CLK_DIV : positive := 5);                                -- for a 100MHz sclk_i, yields a 10MHz SCK
    Port (
    Port (
        sclk_i : in std_logic := 'X';                                   -- high-speed serial interface system clock
        sclk_i : in std_logic := 'X';                                   -- high-speed serial interface system clock
        pclk_i : in std_logic := 'X';                                   -- high-speed parallel interface system clock
        pclk_i : in std_logic := 'X';                                   -- high-speed parallel interface system clock
        rst_i : in std_logic := 'X';                                    -- reset core
        rst_i : in std_logic := 'X';                                    -- reset core
 
        ---- serial interface ----
        spi_ssel_o : out std_logic;                                     -- spi bus slave select line
        spi_ssel_o : out std_logic;                                     -- spi bus slave select line
        spi_sck_o : out std_logic;                                      -- spi bus sck
        spi_sck_o : out std_logic;                                      -- spi bus sck
        spi_mosi_o : out std_logic;                                     -- spi bus mosi output
        spi_mosi_o : out std_logic;                                     -- spi bus mosi output
        spi_miso_i : in std_logic := 'X';                               -- spi bus spi_miso_i input
        spi_miso_i : in std_logic := 'X';                               -- spi bus spi_miso_i input
 
        ---- parallel interface ----
        di_req_o : out std_logic;                                       -- preload lookahead data request line
        di_req_o : out std_logic;                                       -- preload lookahead data request line
        di_i : in  std_logic_vector (N-1 downto 0) := (others => 'X');  -- parallel data in (clocked on rising spi_clk after last bit)
        di_i : in  std_logic_vector (N-1 downto 0) := (others => 'X');  -- parallel data in (clocked on rising spi_clk after last bit)
        wren_i : in std_logic := 'X';                                   -- user data write enable, starts transmission when interface is idle
        wren_i : in std_logic := 'X';                                   -- user data write enable, starts transmission when interface is idle
        do_valid_o : out std_logic;                                     -- do_o data valid signal, valid during one spi_clk rising edge.
        do_valid_o : out std_logic;                                     -- do_o data valid signal, valid during one spi_clk rising edge.
        do_o : out  std_logic_vector (N-1 downto 0);                    -- parallel output (clocked on rising spi_clk after last bit)
        do_o : out  std_logic_vector (N-1 downto 0);                    -- parallel output (clocked on rising spi_clk after last bit)
        --- debug ports: can be removed for the application circuit ---
        --- debug ports: can be removed or left unconnected for the application circuit ---
        do_transfer_o : out std_logic;                                  -- debug: internal transfer driver
        do_transfer_o : out std_logic;                                  -- debug: internal transfer driver
        wren_o : out std_logic;                                         -- debug: internal state of the wren_i pulse stretcher
        wren_o : out std_logic;                                         -- debug: internal state of the wren_i pulse stretcher
        wren_ack_o : out std_logic;                                     -- debug: wren ack from state machine
        wren_ack_o : out std_logic;                                     -- debug: wren ack from state machine
        rx_bit_reg_o : out std_logic;                                   -- debug: internal rx bit
        rx_bit_reg_o : out std_logic;                                   -- debug: internal rx bit
        state_dbg_o : out std_logic_vector (5 downto 0);                -- debug: internal state register
        state_dbg_o : out std_logic_vector (5 downto 0);                -- debug: internal state register
Line 206... Line 208...
    signal samp_ce : std_logic := '1';      -- data sampling clock enable
    signal samp_ce : std_logic := '1';      -- data sampling clock enable
    --
    --
    -- GLOBAL RESET: 
    -- GLOBAL RESET: 
    --      all signals are initialized to zero at GSR (global set/reset) by giving explicit
    --      all signals are initialized to zero at GSR (global set/reset) by giving explicit
    --      initialization values at declaration. This is needed for all Xilinx FPGAs, and 
    --      initialization values at declaration. This is needed for all Xilinx FPGAs, and 
    --      especially for the Spartan-6 and newer CLB architectures, where a local reset can
    --      especially for the Spartan-6 and newer CLB architectures, where a async reset can
    --      reduce the usability of the slice registers, due to the need to share the control 
    --      reduce the usability of the slice registers, due to the need to share the control 
    --      set (RESET/PRESET, CLOCK ENABLE and CLOCK) by all 8 registers in a slice.
    --      set (RESET/PRESET, CLOCK ENABLE and CLOCK) by all 8 registers in a slice.
    --      By using GSR for the initialization, and reducing RESET local init to the bare
    --      By using GSR for the initialization, and reducing async RESET local init to the bare
    --      essential, the model achieves better LUT/FF packing and CLB usability.
    --      essential, the model achieves better LUT/FF packing and CLB usability.
    --
    --
    -- internal state signals for register and combinatorial stages
    -- internal state signals for register and combinatorial stages
    signal state_next : natural range N+1 downto 0 := 0;
    signal state_next : natural range N+1 downto 0 := 0;
    signal state_reg : natural range N+1 downto 0 := 0;
    signal state_reg : natural range N+1 downto 0 := 0;
Line 285... Line 287...
    -- on using clock enables to process the serial high-speed clock at lower rates for the core fsm,
    -- on using clock enables to process the serial high-speed clock at lower rates for the core fsm,
    -- the spi clock generator and the input sampling clock.
    -- the spi clock generator and the input sampling clock.
    -- The clock generation block derive 2 continuous antiphase signals from the 2x spi base clock 
    -- The clock generation block derive 2 continuous antiphase signals from the 2x spi base clock 
    -- for the core clocking.
    -- for the core clocking.
    -- The 2 clock phases are generated by sepparate and synchronous FFs, and should have only 
    -- The 2 clock phases are generated by sepparate and synchronous FFs, and should have only 
    -- interconnect delays.
    -- differential interconnect delay skew.
    -- Clock enable signals are generated with the same phase as the 2 core clocks, and these clock 
    -- Clock enable signals are generated with the same phase as the 2 core clocks, and these clock 
    -- enables are used to control clocking of all internal synchronous circuitry. 
    -- enables are used to control clocking of all internal synchronous circuitry. 
    -- The clock enable phase is selected for serial input sampling, fsm clocking, and spi SCK output, 
    -- The clock enable phase is selected for serial input sampling, fsm clocking, and spi SCK output, 
    -- based on the configuration of CPOL and CPHA.
    -- based on the configuration of CPOL and CPHA.
    -- Each phase is selected so that all the registers can be clocked with a rising edge on all SPI
    -- Each phase is selected so that all the registers can be clocked with a rising edge on all SPI
Line 381... Line 383...
            end if;
            end if;
        end if;
        end if;
    end process rx_bit_proc;
    end process rx_bit_proc;
 
 
    --=============================================================================================
    --=============================================================================================
    --  RTL REGISTER PROCESSES
 
    --=============================================================================================
 
    -- fsm state and data registers: synchronous to the spi base reference clock
 
    core_reg_proc : process (sclk_i) is
 
    begin
 
        -- FF registers clocked on rising edge and cleared on sync rst_i
 
        if sclk_i'event and sclk_i = '1' then
 
            if rst_i = '1' then                             -- sync reset
 
                state_reg <= 0;                             -- only provide local reset for the state machine
 
            elsif fsm_ce = '1' then                         -- fsm_ce is clock enable for the fsm
 
                state_reg <= state_next;                    -- state register
 
            end if;
 
        end if;
 
        -- FF registers clocked on rising edge
 
        if sclk_i'event and sclk_i = '1' then
 
            if fsm_ce = '1' then
 
                sh_reg <= sh_next;                          -- shift register
 
                ena_ssel_reg <= ena_ssel_next;              -- spi select enable
 
                ena_sck_reg <= ena_sck_next;                -- spi clock enable
 
                do_buffer_reg <= do_buffer_next;            -- registered output data buffer 
 
                do_transfer_reg <= do_transfer_next;        -- output data transferred to buffer
 
                di_req_reg <= di_req_next;                  -- input data request
 
                wren_ack_reg <= wren_ack_next;              -- wren ack for data load synchronization
 
            end if;
 
        end if;
 
    end process core_reg_proc;
 
 
 
    --=============================================================================================
 
    --  CROSS-CLOCK PIPELINE TRANSFER LOGIC
    --  CROSS-CLOCK PIPELINE TRANSFER LOGIC
    --=============================================================================================
    --=============================================================================================
    -- do_valid_o and di_req_o strobe output logic
    -- do_valid_o and di_req_o strobe output logic
    -- this is a delayed pulse generator with a ripple-transfer FFD pipeline, that generates a 
    -- this is a delayed pulse generator with a ripple-transfer FFD pipeline, that generates a 
    -- fixed-length delayed pulse for the output flags, at the parallel clock domain
    -- fixed-length delayed pulse for the output flags, at the parallel clock domain
Line 457... Line 431...
            end if;
            end if;
        end  if;
        end  if;
    end process in_transfer_proc;
    end process in_transfer_proc;
 
 
    --=============================================================================================
    --=============================================================================================
 
    --  RTL REGISTER PROCESSES
 
    --=============================================================================================
 
    -- fsm state and data registers: synchronous to the spi base reference clock
 
    core_reg_proc : process (sclk_i) is
 
    begin
 
        -- FF registers clocked on rising edge and cleared on sync rst_i
 
        if sclk_i'event and sclk_i = '1' then
 
            if rst_i = '1' then                             -- sync reset
 
                state_reg <= 0;                             -- only provide local reset for the state machine
 
            elsif fsm_ce = '1' then                         -- fsm_ce is clock enable for the fsm
 
                state_reg <= state_next;                    -- state register
 
            end if;
 
        end if;
 
        -- FF registers clocked on rising edge
 
        if sclk_i'event and sclk_i = '1' then
 
            if fsm_ce = '1' then
 
                sh_reg <= sh_next;                          -- shift register
 
                ena_ssel_reg <= ena_ssel_next;              -- spi select enable
 
                ena_sck_reg <= ena_sck_next;                -- spi clock enable
 
                do_buffer_reg <= do_buffer_next;            -- registered output data buffer 
 
                do_transfer_reg <= do_transfer_next;        -- output data transferred to buffer
 
                di_req_reg <= di_req_next;                  -- input data request
 
                wren_ack_reg <= wren_ack_next;              -- wren ack for data load synchronization
 
            end if;
 
        end if;
 
    end process core_reg_proc;
 
 
 
    --=============================================================================================
    --  RTL combinatorial LOGIC PROCESSES
    --  RTL combinatorial LOGIC PROCESSES
    --=============================================================================================
    --=============================================================================================
    -- state and datapath combinatorial logic
    -- state and datapath combinatorial logic
    core_combi_proc : process ( sh_reg, state_reg, rx_bit_reg, ena_ssel_reg, ena_sck_reg, do_buffer_reg,
    core_combi_proc : process ( sh_reg, state_reg, rx_bit_reg, ena_ssel_reg, ena_sck_reg, do_buffer_reg,
                                do_transfer_reg, di_reg, wren ) is
                                do_transfer_reg, di_reg, wren ) is

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.