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 编辑引用: heningbo 发表于 2019-7-5 22:41 其实大部分人不喜欢帮别人看代码,因为他要按照你的思路去将代码阅读一遍,特别浪费时间。
有道理!直接把问题放最前面