Closed Seven-Zeng closed 5 years ago
Hi,
1) The shift register (data_shreg) capture incoming data from master in CLK cycle, when a rising edge was detected (spi_clk_redge_en) on the SCLK signal. But I have a bug #5, SCLK should be synchronized (two FFs) to the CKL clock domain. Timing diagram of current implementation:
CLK _|‾|_|‾|_|‾|_|‾|_|‾|_|‾|_|‾|_|‾|_|‾|_|‾|_
SCLK (async) ___________|‾‾‾‾‾‾‾‾‾‾‾‾‾‾|______________
spi_clk_reg _____________|‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾|___________
spi_clk_redge_en ___________|‾|___________________________
data_shreg D0...........|D1.........................
2) Both implementations have advantages and disadvantages. For example my solution does not require a more complex cross domain crossing from SCLK to CLK (asynchronous FIFO) and all FFs are active on the rising edge of the same clock
3) No, RST is typically a global FPGA reset. CS_N is used to select the SPI slave module. My SPI slave module allows to accept user data to be transmitted even when not active CS_N.
Hi, The diagram illustrated you intention so clearly, while, forgive my silly, there still one point I haven't gotten:
the code is like:
data_shreg_p : process (CLK)
begin
if (rising_edge(CLK)) then
if (load_data_en = '1') then
data_shreg <= DIN;
elsif (spi_clk_redge_en = '1' and CS_N = '0') then
data_shreg <= data_shreg(6 downto 0) & MOSI;
CLK _|‾|_|‾|_|‾|_|‾|_|‾|_|‾|_|‾|_|‾|_|‾|_|‾|_
SCLK (async) ___________|‾‾‾‾‾‾‾‾‾‾‾‾‾‾|______________
spi_clk_reg _____________|‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾|___________
spi_clk_redge_en ___________|‾|___________________________
data_shreg D0..............|D1.........................
------------------------------^---------------------------
the bit is latched on the rising edge AND spi_clk_redge_en == '1', but spi_clk_redge_en is reset to '0' at exactly the same rising edge of the CLK, what if spi_clk_redge_en falls to zero before the bit shift condition is checked? Is that gonna be a risk?
Besides, when you say add another FF do you mean implementing it like this:
CLK _|‾|_|‾|_|‾|_|‾|_|‾|_|‾|_|‾|_|‾|_|‾|_|‾|_
SCLK (async) ___________|‾‾‾‾‾‾‾‾‾‾‾‾‾‾|______________
spi_clk_reg1 _____________|‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾|___________
spi_clk_reg2 _________________|‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾|___________
spi_clk_redge_en _____________|‾‾‾|___________________________
data_shreg D0...............|D1.........................
The described situation cannot occur. From sampling theorem: CLK clock must be more than twice as fast as SCLK. For reliable data transmission, I have a much stricter condition on my SPI master (SCLK_FREQ <= CLK_FREQ/10).
The problem may be when spi_clk_redge_en is set at the same time as rising edge of the CLK. This problem can cause metastability (bug #5) and can be solved by adding at least two FFs. Yes your diagram corresponds to an implementation with one FF added.
Got you! Many thanks !
Hi man,
I have to say that your code looks so comfortable.
I'm a rookie of FPGA designing and have some questions hope that you can help: