1

I've got a question about something I don't understand that is going on in my FPGA project. I need to control two devices (AGC and ADC) through an SPI bus. As as the FPGA will be the master device, I'm generating a clock signal, SCK, in code by dividing the system clock. I then rout that signal to an output wire through a tristate buffer. Below is my relevant bit of code. It's not shown, but the signal that controls the tristate buffer, en_SCK controlled by a FSM, when it is set low in the idle state and then high for the rest of the states.

output wire SDI

   //for SCK_clock
reg SCK_gen, SCK_hold;
integer i;
reg en_SCK;
wire neg_edge_SCK;

   //SCK_generator
    always @(posedge clk)
            begin
                i <= i+1;
                SCK_hold <= SCK_gen;
                    if(i == 10)
                        begin
                            SCK_gen <= ~SCK_gen;
                            i <= 0;
                        end
            end


assign SCK = (en_SCK) ? SCK_gen : 1'bz;

When I get implement the design i get the following warning:

WARNING:PhysDesignRules:372 - Gated clock. Clock net en_SCK_not0001 is sourced by a combinatorial pin. This is not good design practice. Use the CE pin to control the loading of data into the flip-flop.

Also I notice my clock seems very distorted. But if I don't use the tristate device in my code and direclty assign the clock signal to the output wire (as in the code below) I get a nice clean clock signal.

assign SCK = SCK_gen;

Below is a side by side of the signal SCK without the tristate buffer (left) and with the tristate buffer (right). I'm fairly new to FPGA and Verilog, but my understanding is that using that style of assign code implies a tristate buffer, so I'm confused why it seems to be interpreted as a gated clock source (The XST generated schematic shows it implimented with an and gate. I'm also confused about how it's distorting the clock signal. The FSM should be forcing the en_SCK enable signal high for many times the period of the clock so I'm not sure what's happening. Also according to the demo board manual, other devices share this signal so I have to set it to high impedance when it's not in use. If someone could point me in the right direction, or explain it to me I'd be very great full. Thanks enter image description here

1
  • 1
    Sorry I can't answer your question, but I can point out electronics.stackexchange.com where you might find more people able to help. Commented Mar 21, 2012 at 6:37

3 Answers 3

2

My understanding of SPI is that the SCK signal from the master is never tri-stated. It could be tied low or high when not being used, but should not be tri-stated. In fact, the master should not tri-state any of its SPI output signals: SCK, CS_N, MOSI (SDO).

Update based on comment:

Here is an application note using the Spartan 3E starter board. On page 4 it says, "The SPI bus signals (SDI, SDO and SCK) are shared by other devices on the board. It is vital that other devices are disabled when communicating with the Amplifier or A/D converter."

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, I may have miss understood the data sheet, but I thought the reason for doing that is because the SPI bus is shared by other peripheral circuits. (I'm using a Spartan 3e starter board.) I'm going to try it with out the tristate device. I am curious about what caused the distorted behavior though, but I guess I can get back into that later.
OK. I was reading elsewhere that shared SPI bus lines should be set to high-z when not in use. If just disabling the other devices when the AGC and ADC are in use is enough I'll try that. I guess I miss understood what I had to do. Thanks
1

SPI busses shouldn't normally be tri-stated, as long as your device is always master.

Typically, you select the peripheral you want to communicate with through a chip select pin, and keep everything else on the bus deselected. The deselected slave peripherals will then tri-state their outputs (MISO), so they don't interfere with the communication with the selected peripheral - could it be this that you've read about?

Also, are you using the generated clock internally in your design, or routing it directly to a pin? I'm not too familiar with Verilog (VHDL user myself), but a gated clock is typically because you are doing a combinatorial operation on a signal (in your case the tri-state buffer), and then using it as a clock input on a flip-flip later on.

2 Comments

Yeah. That's probably what I didn't understand correctly. I'm pretty new to digital design, and I think I also misunderstood what the appropriate use of a tri state device is. From your's and Nathans comments I've realized the tri state buffer was out of line in the first place. The reason I was tri stating the clock is because my design contains an AGC controller and an ADC controller, each which use the SPI bus, and provide their own SCK clock. I figured I could let a clock run perpetually in each controller as long as I "disconnected" their outputs when not in use.
The best way to handle two separate controllers both wanting to access the same SPI bus, would probably be to make a generic, low-level SPI controller as a separate module (which can just send/receive a number of bytes), and then make higher-level modules for each peripheral using it, that utilize the SPI module. It might be overkill for your application though...
0

The source of your warning

WARNING:PhysDesignRules:372 - Gated clock. Clock net en_SCK_not0001 is sourced by a combinatorial pin. This is not good design practice. Use the CE pin to control the loading of data into the flip-flop.

resides here in your description:

assign SCK = (en_SCK) ? SCK_gen : 1'bz;

Internal tristates in modern FPGA are commonly implemented by multiplexors, which decide which data is presented in the common bus by looking at the different combinations of control inputs.

So, your assign sentence is infering a multiplexer, i.e. a combinational piece of logic, and the output of this multiplexer goes to the clok pin of another internal module (in other words, it is used inside the sensitivity list of a always @(posedge ......) block

Multi-slave SPI schemes (one SPI master and multiple SPI slaves) share SPI, MOSI and MISO signals, so no need to tristate them (unless we are talking about a multi-master scheme, in which case you would rather implement two clock signals, each one going opposite directions).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.