- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
I'm stuck on what is most likely a simple problem. I'm trying to constrain a signal in my design, but I'm not sure exactly how. I've tried a couple different ways and figured it would be better to just ask. I have a start signal that goes high on the falling edge of a pin. This start signal clocks another register in my design. When I run compilation I get a warning attached below. https://www.alteraforum.com/forum/attachment.php?attachmentid=9126 Because this signal clocks anther process it determines it to be a clock. How is this normally handled? This is for an I2C module. Also, is my approach for constraining SDA and SCL correct? I am assuming they will run at 100k so I've constrained them as follows. create_clock -name SCL_clk -period 10000 [get_ports sm5882_air_data_sensor_0_scl_export] create_clock -name SDA_clk -period 10000 [get_ports sm5882_air_data_sensor_0_sda_export] I've also attached my HDL. * Had to zip up my .sdc file because the forum would not let me upload it as is for some reason. Thanks, RobLink Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I wouldn't use SDA as a clock signal. Sample both SDA and SCL lines with your system clock (preferably each of them through two FFs) and use them to drive Enable signals for shift register.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Agreed. You'll get a rather high chance of clock-skew. Rather than sampling on the falling edge, double the clock-rate (if you can) and the sample on the positive edge with the start signal acting as an enable. FPGA's have dedicated clock buffers with low-skew, so use them when you can!
-Mux- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hey guys,
Thanks for the reply. I am starting to agree with you about over sampling rather than using SDA/SCL as clocks. I currently have it all written up in an HDL project and connected to an MSP430 that is talking to it. The fpga will shift data out for a minute or so sometimes then fail. I'm assuming this is probably related to using the SDA/SCL edges rather than oversampling like you recommended. I have such a simple design I thought it would be ok. All I need the FPGA to so is receive it's address and then shift out two bytes. I was hoping to not have to start over but its looking like I may have no choice. Mux, could you elaborate on the dedicated clock buffers you mentioned? I've been out of fpga's for a while and don't remember how to use these. Are you saying with my architecture now I should be connecting SDA and SCL to these clock buffers? Or are you saying in general no matter which design I use (my current sampling on edges, or oversampling) they should both uses these dedicated clock buffers? Thanks, Rob- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Pretty much all FPGA's have dedicated routing for clocks. Just open up any Altera Handbook.
When you use dedicated clocks (i.e. designated clk pins or outputs from a PLL) it will use those as much as possible. But when you use an edge from any other signal (i.e. output from a combinatorial / latch), you'll incur additional latency into your logic. Worse still, you can end up with runt clock pulses which introduces a whole different set off problems. If you still have an old version of Quartus laying around, or (ugh) Modelsim, try running some experiments in the simulator :-) -Mux- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Ok. When I get a sec I'll do some reading about those pins. Does it make sense to shift my data in and out using SCL still?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
They're just global clocks..
As far as using SCL, I'd use an edge detect and use that as an enable for the main clock. YMMV though.. -Mux- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You can use SCL as a clock, but then you have to make sure you pass data between two clock domains correctly. In this case it shouldn't be a problem - first shift in whole byte with SCL. When it's done, give some indication to logic in system clock domain and copy the received data from SCL domain to system clock domain. In timequest analyzer set false path from the register holding the received data in SCL domain to the register you will be copying received data in system clock domain. It's the same when sending data only the other way around.
The other way of doing this is to do everything in one clock domain. First, you oversample SDA and SCL with your system clock - each of them thru two FFs. Then use edge detection on SDA to generate/detect START/STOP signals and edge detection on SCL to shift in/out data. Here's and example of edge detection logic - http://fpgacenter.com/examples/basic/edge_detector.php (http://fpgacenter.com/examples/basic/edge_detector.php). In your case, for example, clk would be your system clock, signal_in would be oversampled SCL, output would be enable signal for shift register (of course, you`d have to 'and' with some signal indicating that it's time to receive data). P.S. I might be wrong about some of this as I'm also learning :)- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hey Mux,
Thanks for the help so far. I've rewritten a lot of my code so that I use edge detectors rather than SDA, SCL as clocks. I like this way more and a lot of the control signals look much cleaner. I do have one issue thought that I don't think I've ever run into. For some reason I get a whole bunch of these warnings. https://www.alteraforum.com/forum/attachment.php?attachmentid=9162 They are all pretty much the same. It says that one of the states in 3 different state machines is a clock and I didn't specify an associated clock assignment. I'm assuming it wants me to assign a clock in the .sdc file. The problem I have though is that I don't think any of these states are clocking anything. They are just plain states that I progress through. Have you ever seen this? I can't figure out how to get rid of these warnings because I don't think they are supposed to be interpreted as clocks. Attached is my code.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi There!
Glad things are going better! While VHDL isn't my strongest, had a quick look at your code. I've come across similar warnings that were fixed by assigning the clk signal correctly. As far as the edge detect goes, it seems a bit overkill to do a state machine as you can do it with a simple 2-bit shift register and an AND gate. In verilog, It'd be something like this: reg scl0, scl1; always @ ( posedge clk ) begin scl0 <= scl1; scl1 <= scl; end wire rising_edge = ~scl0 & scl1; wire falling_edge = scl0 & ~scl1; Note that you'd have to clear them on reset. Hope this helps and you get things working! -Mux- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Probably something in your code makes the tools think that those signals might be clocks even if they aren't actually clocking anything. I'd guess that it's something in the next-state logic - in the non-clocked process. For example, I don't see the meaning of assigning *_next_state <= *_current_state before the case statement.
May last post wasn't approved by moderator or something, but as MUX said, you can do the edge detection in a much easier way. For example, rising edge detection: https://www.alteraforum.com/forum/attachment.php?attachmentid=9164 https://www.alteraforum.com/forum/attachment.php?attachmentid=9165- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks again. That is a very clever way, but my clock that would clock the dff isn't necessarily synchronized to the edge i'm trying to detect (SCL) and when I look at the signals on the scope I get some strange blips on the out put of that edge detector circuit that clocks my counters when it shouldn't be. I'm still working on this though so it may be something I'm doing wrong on my end rather than that detection circuit. Thanks so much for the help I've learned a fair amount from talking to you guys :)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
That's why you first have to 'bring the SCL and SDA into your system clock domain'. In the case of a 1 bit signal (simply signal) it's done by putting it thru two consecutive FF as show in MUXs example.
process (clk, reset) begin
if reset = '0' then
scl_0 <= '0';
scl_1 <= '0';
sda_0 <= '0';
sda_1 <= '1';
elsif (clk'event and clk = '1') then
scl_1 <= scl_0;
scl_0 <= scl_in;
sda_1 <= sda_0;
sda_0 <= sda_1;
end if;
end process;
Now both SCL and SDA signals are brought into your clock domain (synchronized with clk). Apparently I can't post links, so google yourself things like 'Synchronous logic', 'clock domains', 'Metastability', 'crossing clock domains (signals vs buses)', etc. The basic idea is that every register is clocked by the same clock and the fitter can make sure that setup and hold requirements for each register are met. If you want to pass data between registers clocked by different clocks you have to make extra consideration (like in this example putting SCL and SDA (which are synchronous to your external I2C masters clock) thru two FF to bring them into your FPGAs logics clock domain. So, now you will only use 'scl_1' and 'sda_1'. Put them thru edge detect logic etc. (detect the start/stop conditions etc.) but don't use them as clocks! Lets say that you have detected a start bit, meaning that now you will have start clock in data on every scl edge, indicating that by some signal 'incoming_data = '1''. Your data shift register would look something like this: process(clk, reset, incoming_data, scl_1_edge_detect) begin
if reset = '0' then
data <= (others => '0');
elsif clk'event and clk = '1' then
if incoming_data = '1' and scl_1_edge_detect '1' then
data <= data(6 downto 0) & sda_1;
end if;
end if;
end process;
Note that shift register is clocked by the same clock and the 'little pulse' (in conjunction with incoming_data) from scl edge detect logic is only used as an enable signal (check RTL netlist!) Hope this helps, Vents
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Vents,
Thanks so much for the write up. This is making more sense now. I wanted to reply and let you know I really appreciate the info. I'll spend some time this week and next week reading those recommended search topics and going further down this path. The examples also really clarified things. One initial thing I'm wondering right of the bat is why you use to dff to shift sda and scl through to synchronize it to your clock? Why wouldn't one ff work? Thanks again for the info. I'm going to re-write some stuff and study this stuff some more. Again much appreciated!- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If SDA or SCL happen to change at the exact moment when your system clock changes (to be more precise - setup or hold times aren't met) the output of FF can become unstable. It takes some time for it to settle to a 0 or 1. This reduces the setup time slack for next FF, and if there's some logic in between them it's even worse. So the idea is to simply sample it again (with no additional logic which would cause extra delay - reduce t_su slack) and rely that the possibly unstable output of first FF will settle (giving it more time to settle).
I attached alteras document on metastability, take a look. Vents
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page