[讨论] 想用FPGA做个SPI Slave,有几个关于时钟的问题请教一下

zengxy3407   2019-7-5 11:39 楼主

Hi,各位看官,

作为一个新手,我想用FPGA实现一个SPI Slave,网上搜了一下别人的实现方式,有两点困惑请各位大牛指点一下:

 

1. 数据移位到底是直接用外部的SCLK边沿好还是用系统时钟同步后的SCLK边沿好?或者各有什么优缺点?

 

2. 在一段Process中在系统时钟的上升沿判断某个量的状态,而在另一个Process中又在系统时钟上升沿改变这个量的状态,这样会不会产生竞争?比如这段代码:


    -- -------------------------------------------------------------------------

    --  SPI CLOCK REGISTER

    -- -------------------------------------------------------------------------



    -- The SPI clock register is necessary for clock edge detection.

    spi_clk_reg_p : process (CLK)

    begin

        if (rising_edge(CLK)) then

            if (RST = '1') then

                spi_clk_reg <= '0';

            else

                spi_clk_reg <= SCLK;

            end if;

        end if;

    end process;



    -- -------------------------------------------------------------------------

    --  SPI CLOCK EDGES FLAGS

    -- -------------------------------------------------------------------------



    -- Falling edge is detect when SCLK=0 and spi_clk_reg=1.

    spi_clk_fedge_en <= not SCLK and spi_clk_reg;

    -- Rising edge is detect when SCLK=1 and spi_clk_reg=0.

    spi_clk_redge_en <= SCLK and not spi_clk_reg;

    其中的CLK为系统时钟,它的spi_clk_reg是在CLK的上升沿锁存的,因此得到的spi_clk_fedge_en和spi_clk_redge_en应该也是和CLK上升沿对齐的。但是,在数据移位的时候,用的也是CLK的上升沿:


    -- -------------------------------------------------------------------------

    --  RECEIVED BITS COUNTER

    -- -------------------------------------------------------------------------



    -- The counter counts received bits from the master. Counter is enabled when

    -- falling edge of SPI clock is detected and not asserted CS_N.

    bit_cnt_p : process (CLK)

    begin

        if (rising_edge(CLK)) then

            if (RST = '1') then

                bit_cnt <= (others => '0');

            elsif (spi_clk_fedge_en = '1' and CS_N = '0') then

                if (bit_cnt_max = '1') then

                    bit_cnt <= (others => '0');

                else

                    bit_cnt <= bit_cnt + 1;

                end if;

            end if;

        end if;

    end process;

也就是说同在CLK上升沿的时候,即要改变spi_clk_fedge_en,又要判断spi_clk_fedge_en的状态,这种做法不是容易产生竞争吗?

 

还请各位大牛多多指教

 

 

源代码出处:https://github.com/jakubcabal/spi-fpga

本帖最后由 zengxy3407 于 2019-7-6 14:07 编辑

回复评论 (4)

这儿有一个例程中有SPI的编写方法,希望可以帮到你。

点赞  2019-7-5 22:39

其实大部分人不喜欢帮别人看代码,因为他要按照你的思路去将代码阅读一遍,特别浪费时间。

点赞  2019-7-5 22:41
引用: heningbo 发表于 2019-7-5 22:41 其实大部分人不喜欢帮别人看代码,因为他要按照你的思路去将代码阅读一遍,特别浪费时间。

有道理!直接把问题放最前面

点赞  2019-7-6 14:01

直接用外部时钟的话,不利于做流水线,但是可实现的频率上限会高于使用内部时钟采样方式。频率不高的情况,使用过采样同步化后,后面的设计会比较灵活。

 

 

点赞  2019-8-5 10:59
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复