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 10 and 11

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

Rev 10 Rev 11
Line 132... Line 132...
--                                  frequency sequential circuits, to preserve clocking resources and avoid path delay glitches.
--                                  frequency sequential circuits, to preserve clocking resources and avoid path delay glitches.
-- 2011/07/10   v1.00.0098  [JD]    implemented SCK clock divider circuit to generate spi clock directly from system clock.
-- 2011/07/10   v1.00.0098  [JD]    implemented SCK clock divider circuit to generate spi clock directly from system clock.
-- 2011/07/10   v1.10.0075  [JD]    verified spi_master_slave in silicon at 50MHz, 25MHz, 16.666MHz, 12.5MHz, 10MHz, 8.333MHz, 
-- 2011/07/10   v1.10.0075  [JD]    verified spi_master_slave in silicon at 50MHz, 25MHz, 16.666MHz, 12.5MHz, 10MHz, 8.333MHz, 
--                                  7.1428MHz, 6.25MHz, 1MHz and 500kHz. The core proved very robust at all tested frequencies.
--                                  7.1428MHz, 6.25MHz, 1MHz and 500kHz. The core proved very robust at all tested frequencies.
-- 2011/07/16   v1.11.0080  [JD]    verified both spi_master and spi_slave in loopback at 50MHz SPI clock.
-- 2011/07/16   v1.11.0080  [JD]    verified both spi_master and spi_slave in loopback at 50MHz SPI clock.
 
-- 2011/07/17   v1.11.0080  [JD]    BUG: CPOL='1', CPHA='1' @50MHz causes MOSI to be shifted one bit earlier.
 
--                                  BUG: CPOL='0', CPHA='1' causes SCK to have one extra pulse with one sclk_i width at the end.
 
-- 2011/07/18   v1.12.0105  [JD]    CHG: spi sck output register changed to remove glitch at last clock when CPHA='1'.
 
--                                  for CPHA='1', max spi clock is 25MHz. for CPHA= '0', max spi clock is >50MHz.
--
--
-----------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------
--  TODO
--  TODO
--  ====
--  ====
--
--
Line 205... Line 209...
    signal spi_2x_ce : std_logic := '1';    -- spi_2x clock enable
    signal spi_2x_ce : std_logic := '1';    -- spi_2x clock enable
    signal spi_clk : std_logic := '0';      -- spi bus output clock
    signal spi_clk : std_logic := '0';      -- spi bus output clock
    signal spi_clk_reg : std_logic := '0';  -- output pipeline delay for spi sck
    signal spi_clk_reg : std_logic := '0';  -- output pipeline delay for spi sck
    -- core fsm clock enables
    -- core fsm clock enables
    signal fsm_ce : std_logic := '1';       -- fsm clock enable
    signal fsm_ce : std_logic := '1';       -- fsm clock enable
 
    signal ena_sck_ce   : std_logic := '1';     -- SCK clock enable
    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 
Line 367... Line 372...
        if CPHA = '1' generate
        if CPHA = '1' generate
        begin
        begin
            fsm_ce <= core_ce;              -- for CPHA=1, latch registers at rising edge of positive core clock enable
            fsm_ce <= core_ce;              -- for CPHA=1, latch registers at rising edge of positive core clock enable
        end generate;
        end generate;
 
 
 
    ena_sck_ce <= core_n_ce;                -- for CPHA=1, SCK is advanced one-half cycle
 
 
    --=============================================================================================
    --=============================================================================================
    --  REGISTERED INPUTS
    --  REGISTERED INPUTS
    --=============================================================================================
    --=============================================================================================
    -- rx bit flop: capture rx bit after SAMPLE edge of sck
    -- rx bit flop: capture rx bit after SAMPLE edge of sck
    --
    --
    --  ATTENTION:  REMOVING THE FLIPFLOP (DIRECT CONNECTION) WE GET HIGHER PERFORMANCE DUE TO 
    --  ATTENTION:  REMOVING THE FLIPFLOP (DIRECT CONNECTION) WE GET HIGHER PERFORMANCE DUE TO 
    --              REDUCED DEMAND ON MISO SETUP TIME. 
    --              REDUCED DEMAND ON MISO SETUP TIME. 
    --
    --
    rx_bit_proc : process (sclk_i, spi_miso_i) is
    rx_bit_proc : process (sclk_i, spi_miso_i) is
    begin
    begin
--        if sclk_i'event and sclk_i = '1' then
        if sclk_i'event and sclk_i = '1' then
--            if samp_ce = '1' then
            if samp_ce = '1' then
                rx_bit_reg <= spi_miso_i;
                rx_bit_reg <= spi_miso_i;
--            end if;
            end if;
--        end if;
        end if;
    end process rx_bit_proc;
    end process rx_bit_proc;
 
 
    --=============================================================================================
    --=============================================================================================
    --  CROSS-CLOCK PIPELINE TRANSFER LOGIC
    --  CROSS-CLOCK PIPELINE TRANSFER LOGIC
    --=============================================================================================
    --=============================================================================================
Line 446... Line 453...
                state_reg <= 0;                             -- only provide local reset for the state machine
                state_reg <= 0;                             -- only provide local reset for the state machine
            elsif fsm_ce = '1' then                         -- fsm_ce is clock enable for the fsm
            elsif fsm_ce = '1' then                         -- fsm_ce is clock enable for the fsm
                state_reg <= state_next;                    -- state register
                state_reg <= state_next;                    -- state register
            end if;
            end if;
        end if;
        end if;
        -- FF registers clocked on rising edge
        -- FF registers clocked synchronous to the fsm state
        if sclk_i'event and sclk_i = '1' then
        if sclk_i'event and sclk_i = '1' then
            if fsm_ce = '1' then
            if fsm_ce = '1' then
                sh_reg <= sh_next;                          -- shift register
                sh_reg <= sh_next;                          -- shift register
                ena_ssel_reg <= ena_ssel_next;              -- spi select enable
                ena_ssel_reg <= ena_ssel_next;              -- spi select enable
                ena_sck_reg <= ena_sck_next;                -- spi clock enable
                ena_sck_reg <= ena_sck_next;                -- spi clock enable
Line 458... Line 465...
                do_transfer_reg <= do_transfer_next;        -- output data transferred to buffer
                do_transfer_reg <= do_transfer_next;        -- output data transferred to buffer
                di_req_reg <= di_req_next;                  -- input data request
                di_req_reg <= di_req_next;                  -- input data request
                wren_ack_reg <= wren_ack_next;              -- wren ack for data load synchronization
                wren_ack_reg <= wren_ack_next;              -- wren ack for data load synchronization
            end if;
            end if;
        end if;
        end if;
 
        -- FF registers clocked one-half cycle earlier than the fsm state
 
--        if sclk_i'event and sclk_i = '1' then
 
--            if ena_sck_ce = '1' then
 
--                ena_sck_reg <= ena_sck_next;                -- spi clock enable
 
--            end if;
 
--        end if;
    end process core_reg_proc;
    end process core_reg_proc;
 
 
    --=============================================================================================
    --=============================================================================================
    --  RTL combinatorial LOGIC PROCESSES
    --  RTL combinatorial LOGIC PROCESSES
    --=============================================================================================
    --=============================================================================================
Line 537... Line 550...
    -----------------------------------------------------------------------------------------------
    -----------------------------------------------------------------------------------------------
    -- This is a MUX with an output register. The register gives us a pipeline delay for the SCK line,
    -- This is a MUX with an output register. The register gives us a pipeline delay for the SCK line,
    -- enabling higher SCK frequency. The MOSI and SCK phase are compensated by the pipeline delay.
    -- enabling higher SCK frequency. The MOSI and SCK phase are compensated by the pipeline delay.
    spi_sck_o_gen_proc : process (sclk_i, ena_sck_reg, spi_clk, spi_clk_reg) is
    spi_sck_o_gen_proc : process (sclk_i, ena_sck_reg, spi_clk, spi_clk_reg) is
    begin
    begin
        if sclk_i'event and sclk_i = '1' then
--        if sclk_i'event and sclk_i = '1' then
 
--            if ena_sck_reg = '1' then
 
--                spi_clk_reg <= spi_clk;                                 -- copy the selected clock polarity
 
--            else
 
--                spi_clk_reg <= CPOL;                                    -- when clock disabled, set to idle polarity
 
--            end if;
 
--        end if;
            if ena_sck_reg = '1' then
            if ena_sck_reg = '1' then
 
            if sclk_i'event and sclk_i = '1' then
                spi_clk_reg <= spi_clk;                                 -- copy the selected clock polarity
                spi_clk_reg <= spi_clk;                                 -- copy the selected clock polarity
 
            end if;
            else
            else
                spi_clk_reg <= CPOL;                                    -- when clock disabled, set to idle polarity
                spi_clk_reg <= CPOL;                                    -- when clock disabled, set to idle polarity
            end if;
            end if;
        end if;
 
        spi_sck_o <= spi_clk_reg;                                       -- connect register to output
        spi_sck_o <= spi_clk_reg;                                       -- connect register to output
    end process spi_sck_o_gen_proc;
    end process spi_sck_o_gen_proc;
 
 
    --=============================================================================================
    --=============================================================================================
    --  DEBUG LOGIC PROCESSES
    --  DEBUG LOGIC PROCESSES

powered by: WebSVN 2.1.0

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