1
votes

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

3
Sorry I can't answer your question, but I can point out electronics.stackexchange.com where you might find more people able to help.jcoder

3 Answers

2
votes

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."

1
votes

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.

0
votes

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).