- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi, can anybody help me with this issue. I'm trying to read the SPI data from another device but it seems that I cannot make it synchronized. Briefly, I try to send a constant (16 bit), for instant and easy 1001101, but the signal sometimes is shifted one or two bit around (sometimes the output data is a range of 1001101, but after like 20ms, it's a range of 0011011, or 1100110, in other words, it's not stable).
That problem happens when I used this code: process(SPI_CS) begin if rising_edge(SPI_CS) then DATA_REG_O <= sdata_reg; end if; end process; process(SPI_SCLK) begin if rising_edge(SPI_SCLK) then sdata_reg <= sdata_reg(len_SPI-2 downto 0) & SPI_DIO; end if; end process; I can't think of any problem with the above code :( the simulation is perfect! Then I change to this code, which causes bad synchronization when the program start (as it may start in the middle of the 16-bit SPI clock). But the data is always stable (fixed at 11001100, or 1001101, in other words, I received the same signal although it's wrong, but it's always the same) process(SPI_SCLK) begin if rising_edge(SPI_SCLK) then if position_SPI = len_SPI-1 then position_SPI <= 0; DATA_REG_O <= sdata_reg; sdata_reg <= (others => '0'); else position_SPI <= position_SPI + 1; sdata_reg <= sdata_reg(len_SPI-2 downto 0) & SPI_DIO; end if; end if; end process; Please let me know if you don't understand what I'm trying to say. My English is not very good. Thanks TanLink Copied
3 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Usually you wouldnt use the SPI_SCLK as a clock, you use it as another signal and synchronise it into your system clock domain (running many times faster). This way you avoid any timing issues. And using SPI_CS as a clock is a very bad idea.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I think the best way is to synchronize everything that is running on the chip to one central clock, but assuming this SPI function does not have any interface to other VHDL modules, you can also assign a different clock to this "SPI section" of the FPGA. Just as a reminder - if you intend to use different clocks, you either need to ensure the chip has the capability of a second clock distribution network or the second clock can be routed by normal cell interconnects (which would at least lower the max. frequency). If the "SPI module" interfaces with the other logic on the chip (e.g. the "sdata_reg" is generated by other logic you need to ensure that sdata_reg cannot change (as being synchronized to another clock) than the SPI-related signals or you can get messed up readings. the issue with changing information is also most likely causing your troubles, as your code does not ensure any timing constraints between the SPI_CLK refernced part and the SPI_CS related one. Addtionally any glitch on the signal will trigger the code and that causes further problems... all of this "real life" stuff is not within your simulation as I assume the timing between SPI_CS and SPI_CLK is ideal like the signals do not have any glitches etc... As tricky already mentioned the best is to synchronize all signals like SPI_CS and SPI_CLK to System clock and run the code as a System clock depending process.. Defined a internal Signal like iSPI_CLK that is within the System clock process updated with SPI_CLK provides an Option ot detect rising and falling edges of the Signal by comparing SPI_CLK and iSPI_CLK... HTH- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you guys :)
That really helps! My program's working now but seems like I cannot make it the way you told me to not use the SPI clock to shift the register. I tried but my programming skills cannot help with that. I'm still stuck with the timing issue. Or maybe the main clock is not enough. Or whatever happens with FPGA structure. MTM: I tried so simulate the SPI clock but I have to use the CS signal to synchronize it. Maybe because of that that I cannot generate it correctly. Then I think the problem is that the CS signal causing timing issue. My solution is then, use a higher clock speed as Tricky said to deal with it. And anything works like a charm :D process(SPI_SCLK) -- It still works with this small project begin if rising_edge(SPI_SCLK) then sdata_reg <= sdata_reg(len_SPI-2 downto 0) & SPI_DIO; end if; end process; process(RESET,CLOCK_50) begin if RESET = '1' then nSPIstate <= initial; elsif rising_edge(CLOCK_50) then nSPIstate <= SPIstate; if SPIstate = ready then DATA_REG_O <= not(sdata_reg(len_SPI-1)) & sdata_reg(len_SPI-2 downto 0); end if; end if; end process; process(SPIstate,SPI_CS) begin -- To detect the middle of the CS signal (not just rising or falling which causes timing issue) end process;
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page