![]() |
|
|
|
#1 |
|
Hi,
I'm implementing a small entity capable of receiving serial spi-like data at speeds up to 20MHz. The spi clock will be an input (being a slave) at the same rate. I was thinking about reading each bit on each rising edge of that clock. My concern is now that this way I'll not be able to be sure about the stability of the bit value. Is this approach (one clock -> one bit read) to completely avoid or is, sometimes, used? In UART-like snippet I saw the FPGA clock runs faster than the serial one and each bit value is then acquired in the mid-point of the serial-clock-period, even if the data shuold be presented on its line with some advance on the clock rising front in order to be yet stable. Sometimes, then, you may need to see that the reading bit keeps the same value for at least n FPGA-clock cycles and this is like inserting a filter. Comments are welcome. Thanks, Marco Marco |
|
|
|
|
#2 |
|
Posts: n/a
|
Marco schrieb:
> Hi, > > I'm implementing a small entity capable of receiving serial spi-like > data at speeds up to 20MHz. The spi clock will be an input (being a > slave) at the same rate. I was thinking about reading each bit on each > rising edge of that clock. My concern is now that this way I'll not be > able to be sure about the stability of the bit value. > Is this approach (one clock -> one bit read) to completely avoid or is, > sometimes, used? > In UART-like snippet I saw the FPGA clock runs faster than the serial > one and each bit value is then acquired in the mid-point of the > serial-clock-period, even if the data shuold be presented on its line > with some advance on the clock rising front in order to be yet stable. > Sometimes, then, you may need to see that the reading bit keeps the > same value for at least n FPGA-clock cycles and this is like inserting > a filter. > Comments are welcome. > > Thanks, > Marco > some comments, a spi interface is an synchronous interface mostly used between chips. it' origin is from motorola. Therefore noise is not so much expected for datatransfers between chips, as it is, if you connect two computers with a uart over several meters normally data is clocked out at the falling edge of SCLK and sampled at the rising edge of sclk. ( this depends on CPOL and CPHA see link) the dataline has half the clock time to setup correctly. a uart is a asynchronous interface, so you have to oversample the data line to find the bit transitions (mostly 16x oversampling is used). see e.g. http://www.maxim-ic.com/appnotes.cfm?appnote_number=802 so normally i would use the rxclk to shift in the data in a shift register bit by bit. remember that you will get two clock domains with this approch, and you should use two stage sysnchronizers to transfer signals from one clock domain to the other. hope this is correct and this helps a little Thomas Fischer |
|
|
|
#3 |
|
Posts: n/a
|
Thomas,
your comments are a great help, thanks. Let me check with you if this way to synchronize is correct. I have 2 different processes, one moved by the serial clock that only acquires 1 bit each rising edge, counts for bits received and stores them into a vector, when done it activates the data_ready flag. The other process, powered by the faster system clock, makes its work when it find the data_ready flag activated, then it builds up another vector with the answer (communication between an FPGA and a DSP) and sets the answer_ready flag on. Finally, a serial-clock-process will send the answer back to the DSP on reading the answer_ready flag. Should I do in a different way, unsing a temp flag that gives its value to another one on the rising edge of the system clock or something? Thanks, Marco Thomas Fischer ha scritto: > Marco schrieb: > > Hi, > > > > I'm implementing a small entity capable of receiving serial spi-like > > data at speeds up to 20MHz. The spi clock will be an input (being a > > slave) at the same rate. I was thinking about reading each bit on each > > rising edge of that clock. My concern is now that this way I'll not be > > able to be sure about the stability of the bit value. > > Is this approach (one clock -> one bit read) to completely avoid or is, > > sometimes, used? > > In UART-like snippet I saw the FPGA clock runs faster than the serial > > one and each bit value is then acquired in the mid-point of the > > serial-clock-period, even if the data shuold be presented on its line > > with some advance on the clock rising front in order to be yet stable. > > Sometimes, then, you may need to see that the reading bit keeps the > > same value for at least n FPGA-clock cycles and this is like inserting > > a filter. > > Comments are welcome. > > > > Thanks, > > Marco > > > some comments, > > a spi interface is an synchronous interface mostly used between chips. > it' origin is from motorola. Therefore noise is not so much expected > for datatransfers between chips, as it is, if you connect two computers > with a uart over several meters > normally data is clocked out at the falling edge of SCLK and sampled > at the rising edge of sclk. ( this depends on CPOL and CPHA see link) > the dataline has half the clock time to setup correctly. > > a uart is a asynchronous interface, so you have to oversample the data line > to find the bit transitions (mostly 16x oversampling is used). > > see e.g. > http://www.maxim-ic.com/appnotes.cfm?appnote_number=802 > > so normally i would use the rxclk to shift in the data in a shift > register bit by bit. > remember that you will get two clock domains with this approch, and you > should use two stage sysnchronizers to transfer signals from one clock > domain > to the other. > > hope this is correct and this helps a little Marco |
|
|
|
#4 |
|
Posts: n/a
|
Marco schrieb:
> Thomas, > > your comments are a great help, thanks. > Let me check with you if this way to synchronize is correct. > I have 2 different processes, one moved by the serial clock that only > acquires 1 bit each rising edge, counts for bits received and stores > them into a vector, when done it activates the data_ready flag. The > other process, powered by the faster system clock, makes its work when > it find the data_ready flag activated, then it builds up another vector > with the answer (communication between an FPGA and a DSP) and sets the > answer_ready flag on. Finally, a serial-clock-process will send the > answer back to the DSP on reading the answer_ready flag. > > Should I do in a different way, unsing a temp flag that gives its value > to another one on the rising edge of the system clock or something? > > Thanks, > Marco > > > > > Thomas Fischer ha scritto: > >> Marco schrieb: >>> Hi, >>> >>> I'm implementing a small entity capable of receiving serial spi-like >>> data at speeds up to 20MHz. The spi clock will be an input (being a >>> slave) at the same rate. I was thinking about reading each bit on each >>> rising edge of that clock. My concern is now that this way I'll not be >>> able to be sure about the stability of the bit value. >>> Is this approach (one clock -> one bit read) to completely avoid or is, >>> sometimes, used? >>> In UART-like snippet I saw the FPGA clock runs faster than the serial >>> one and each bit value is then acquired in the mid-point of the >>> serial-clock-period, even if the data shuold be presented on its line >>> with some advance on the clock rising front in order to be yet stable. >>> Sometimes, then, you may need to see that the reading bit keeps the >>> same value for at least n FPGA-clock cycles and this is like inserting >>> a filter. >>> Comments are welcome. >>> >>> Thanks, >>> Marco >>> >> some comments, >> >> a spi interface is an synchronous interface mostly used between chips. >> it' origin is from motorola. Therefore noise is not so much expected >> for datatransfers between chips, as it is, if you connect two computers >> with a uart over several meters >> normally data is clocked out at the falling edge of SCLK and sampled >> at the rising edge of sclk. ( this depends on CPOL and CPHA see link) >> the dataline has half the clock time to setup correctly. >> >> a uart is a asynchronous interface, so you have to oversample the data line >> to find the bit transitions (mostly 16x oversampling is used). >> >> see e.g. >> http://www.maxim-ic.com/appnotes.cfm?appnote_number=802 >> >> so normally i would use the rxclk to shift in the data in a shift >> register bit by bit. >> remember that you will get two clock domains with this approch, and you >> should use two stage sysnchronizers to transfer signals from one clock >> domain >> to the other. >> >> hope this is correct and this helps a little > you will need two data_ready flags. one that is generated from your rx process and a second that is the data_ready_flag synchronized to your system clock domain. google for two stage synchronizer, or fpga metastability e.g. http://www.asic-world.com/tidbits/clock_domain.html http://www.chipdesignmag.com/print.p...d=32?issueId=5 http://www.embedded.com/showArticle....icleID=9901007 you can make a simple synchronizer component like the following --################################### -- two stage synchronizer library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity sync is port ( rst : in std_logic; clk : in std_logic; d0 : in std_logic; q0 : out std_logic); end sync; architecture a of sync is signal q_temp : std_logic; begin process (clk,rst) begin if(rst = '1') then q0 <= '0'; q_temp <= '0'; elsif rising_edge(clk) then q_temp <= d0; q0 <= q_temp; end if; end process; end a; --################################### then use in your main vhdl signal sys_clk : std_logic; -- system clock signal rx_clk : std_logic; -- receive clock signal data_rdy_d0_s : std_logic; -- signal data ready in rxclk domain (d0) signal data_rdy_d1_s : std_logic; -- signal data ready in sys clk domain (d1) signal rx_data_d0 : std_logic_vector(7 downto 0); -- rxdata in domain rxclk (shiftregister) signal rx_data_d1 : std_logic_vector(7 downto 0); -- rxdata in domain sys_clk begin -- synchronize rx_data_rdy from rx_clk domain to sys_clk domain sync_rx_data_rdy : sync port map (rst => rst, clk => sys_clk, d0 => data_rdy_d0_s, q0 => data_rdy_d1_s); -- synchronize rx_enable from sys_clk domain to rx_clk domain sync_rx_enable : sync port map (rst => rst, clk => rx_clk, d0 => rx_enable_d1_s, q0 => rx_enable_d0_s); process (sys_clk, rst) begin if(rst = '1') then rx_data_d1 <= (others => '0'); elsif rising_edge(sys_clk) then if (data_rdy_d1_s = '1') then rx_data_d1 <= rx_data_d0; -- rx_data_d0 will not change in this monment end if; end if; end process; Thomas Fischer |
|
![]() |
| Thread Tools | Search this Thread |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Good News, Incredible International & Long Distance Toll Rate with Quality Voice | John | A+ Certification | 0 | 02-25-2005 01:22 PM |
| pass rate for Core and OS.. | Graham Chapman | A+ Certification | 1 | 04-21-2004 04:06 PM |
| Program to find refresh rate | AG | A+ Certification | 9 | 01-29-2004 04:30 PM |
| Re: thinking about getting XP but weary of the low refresh rate bug =( | controlc | A+ Certification | 0 | 01-09-2004 12:27 PM |
| Re: thinking about getting XP but weary of the low refresh rate bug =( | Geoff | A+ Certification | 1 | 01-01-2004 06:40 AM |