• 0
sanrod

Implementation SPI basys3

Question

Hi, I need your help please, actually I am work in an arduino communication with FPGA (Basys3), but i have a problem with the implementation, can you help me?

VHDL:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity SPI_rx3_top is
    Port ( SCK  : in  STD_LOGIC;    -- SPI input clock
           DATA : in  STD_LOGIC;    -- SPI serial data input
           CS   : in  STD_LOGIC;    -- chip select input (active low)
           led  : out STD_LOGIC_VECTOR (7 downto 0) := X"FF");
end SPI_rx3_top;

architecture Behavioral of SPI_rx3_top is
    signal dat_reg : STD_LOGIC_VECTOR (7 downto 0);
begin

    process (SCK)
    begin
        if (SCK'event and SCK = '1') then  -- rising edge of SCK
            if (CS = '0') then             -- SPI CS must be selected
                -- shift serial data into dat_reg on each rising edge
                -- of SCK, MSB first
                dat_reg <= dat_reg(6 downto 0) & DATA;
            end if;
        end if;
    end process;

    process (CS)
    begin
        if (CS'event and CS = '1') then
            -- update LEDs with new data on rising edge of CS
            led <= not dat_reg;
        end if;
    end process;

end Behavioral;

XDC:

## LEDs
set_property PACKAGE_PIN U16 [get_ports {led[0]}]					
	set_property IOSTANDARD LVCMOS33 [get_ports {led[0]}]
set_property PACKAGE_PIN E19 [get_ports {led[1]}]					
	set_property IOSTANDARD LVCMOS33 [get_ports {led[1]}]
set_property PACKAGE_PIN U19 [get_ports {led[2]}]					
	set_property IOSTANDARD LVCMOS33 [get_ports {led[2]}]
set_property PACKAGE_PIN V19 [get_ports {led[3]}]					
	set_property IOSTANDARD LVCMOS33 [get_ports {led[3]}]
set_property PACKAGE_PIN W18 [get_ports {led[4]}]					
	set_property IOSTANDARD LVCMOS33 [get_ports {led[4]}]
set_property PACKAGE_PIN U15 [get_ports {led[5]}]					
	set_property IOSTANDARD LVCMOS33 [get_ports {led[5]}]
set_property PACKAGE_PIN U14 [get_ports {led[6]}]					
	set_property IOSTANDARD LVCMOS33 [get_ports {led[6]}]
set_property PACKAGE_PIN V14 [get_ports {led[7]}]					
	set_property IOSTANDARD LVCMOS33 [get_ports {led[7]}]

##Pmod Header JB
##Sch name = JB1
set_property PACKAGE_PIN A14 [get_ports {CS}]					
	set_property IOSTANDARD LVCMOS33 [get_ports {CS}]
##Sch name = JB2
set_property PACKAGE_PIN A16 [get_ports {DATA}]					
	set_property IOSTANDARD LVCMOS33 [get_ports {DATA}]
##Sch name = JB3
set_property PACKAGE_PIN B15 [get_ports {SCK}]					
	set_property IOSTANDARD LVCMOS33 [get_ports {SCK}]

Warnings:

  • [Place 30-876] Port 'SCK' is assigned to PACKAGE_PIN 'B15' which can only be used as the N side of a differential clock input. Please use the following constraint(s) to pass this DRC check: set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets {SCK_IBUF}]
  • [Place 30-99] Placer failed with error: 'Implementation Feasibility check failed, Please see the previously displayed individual error or warning messages for more details.' Please review all ERROR, CRITICAL WARNING, and WARNING messages during placement to understand the cause for failure.
  • [Common 17-69] Command failed: Placer could not place all instances

Share this post


Link to post
Share on other sites

7 answers to this question

  • 0

Hi @sanrod,

Is your issue with the warnings? If so have you tried using a different name for SCK in your VHDL and XDC. I will try you code tomorrow and see what I get. Also here is a forum that deals with an arduino, basys 3 and a level shifter.

cheers,

Jon

Share this post


Link to post
Share on other sites
  • 0
4 minutes ago, jpeyron said:

Hi @sanrod,

Is your issue with the warnings? If so have you tried using a different name for SCK in your VHDL and XDC. I will try you code tomorrow and see what I get. Also here is a forum that deals with an arduino, basys 3 and a level shifter.

cheers,

Jon

Thanks very much, right now change the CS to other PIN and I can finish the implementation and generate my bitstream.

But i have a warnings (yellow), can you say me if I will could problems with it

Route design:

  • [Timing 38-313] There are no user specified timing constraints. Timing constraints are needed for proper timing analysis.
  • [Power 33-232] No user defined clocks were found in the design! Resolution: Please specify clocks using create_clock/create_generated_clock for sequential elements. For pure combinatorial circuits, please specify a virtual clock, otherwise the vectorless estimation might be inaccurate

Write Bitstream

  • [DRC 23-20] Rule violation (CFGBVS-1) Missing CFGBVS and CONFIG_VOLTAGE Design Properties - Neither the CFGBVS nor CONFIG_VOLTAGE voltage property is set in the current_design. Configuration bank voltage select (CFGBVS) must be set to VCCO or GND, and CONFIG_VOLTAGE must be set to the correct configuration voltage, in order to determine the I/O voltage support for the pins in bank 0. It is suggested to specify these either using the 'Edit Device Properties' function in the GUI or directly in the XDC file using the following syntax: set_property CFGBVS value1 [current_design] #where value1 is either VCCO or GND set_property CONFIG_VOLTAGE value2 [current_design] #where value2 is the voltage provided to configuration bank 0 Refer to the device configuration user guide for more information.

Share this post


Link to post
Share on other sites
  • 0

@sanrod,

So, to handle the DRC violation, stick these two lines into your XDC file:

set_property CFGBVS VCCO [current_design]
set_property CONFIG_VOLTAGE 3.3 [current_design]

At least ... those are the lines that I placed into my own Basys3 XDC file.

As for your logic, ...

  • I would *highly* recommend that you do not transition your logic on either the SCK or the CS pins.  Use a system wide clock instead.  Transitioning on SCK and CS is going to ... set you up for problems when you wish to do anything else with your chip.  (That's part of what Vivado is complaining about in those errors--these clocks (SCK and CS) have no timing associated with them--but if you stop using them as clocks and just use them as logic, the errors will go away.)
  • To synchronize the external pins to your system wide clock, clock all of your inputs into flip flops twice before using them.  Otherwise, you'll struggle with unpredictable things happening within your design.  (See metastability ...)
  • After clocking your inputs twice, look for a SCK line that is high with the previous SCK low, and for CS to be low on both clocks.  This logic test, at the speed of your board clock (100MHz) should be sufficient to detect a rising clock edge.
  • On the 8th rising clock edge, a byte has been given to you.  Send that byte to the rest of your design, together with a logic "strobe" (true for only one clock) telling the rest of your logic that you have received such a byte.  (You might wish to pass another line indicating if this was the first byte received since CS went low.)
  • The approach outlined above, when applied with a 100MHz clock, should still have no problems dealing with SPI clocks 25MHz or above--even though all of your logic is running at 100MHz.

You can see a discussion of this, along with other common Diligilent forum requests,  on the ZipCPU blog.

Dan

Share this post


Link to post
Share on other sites
  • 0
6 hours ago, D@n said:

@sanrod,

So, to handle the DRC violation, stick these two lines into your XDC file:


set_property CFGBVS VCCO [current_design]
set_property CONFIG_VOLTAGE 3.3 [current_design]

At least ... those are the lines that I placed into my own Basys3 XDC file.

As for your logic, ...

  • I would *highly* recommend that you do not transition your logic on either the SCK or the CS pins.  Use a system wide clock instead.  Transitioning on SCK and CS is going to ... set you up for problems when you wish to do anything else with your chip.  (That's part of what Vivado is complaining about in those errors--these clocks (SCK and CS) have no timing associated with them--but if you stop using them as clocks and just use them as logic, the errors will go away.)
  • To synchronize the external pins to your system wide clock, clock all of your inputs into flip flops twice before using them.  Otherwise, you'll struggle with unpredictable things happening within your design.  (See metastability ...)
  • After clocking your inputs twice, look for a SCK line that is high with the previous SCK low, and for CS to be low on both clocks.  This logic test, at the speed of your board clock (100MHz) should be sufficient to detect a rising clock edge.
  • On the 8th rising clock edge, a byte has been given to you.  Send that byte to the rest of your design, together with a logic "strobe" (true for only one clock) telling the rest of your logic that you have received such a byte.  (You might wish to pass another line indicating if this was the first byte received since CS went low.)
  • The approach outlined above, when applied with a 100MHz clock, should still have no problems dealing with SPI clocks 25MHz or above--even though all of your logic is running at 100MHz.

You can see a discussion of this, along with other common Diligilent forum requests,  on the ZipCPU blog.

Dan

 

Thank you very much for your answer and those tips, what I understand is that should I use my internal clock as if it were a general? For example assign it together with a reset, and that on each flank read if there was a change in SCK or CS? By the way, what I intend to do is to use arduino as "ADC" and send the digital signal to fpga by SPI. thanks for your help

Share this post


Link to post
Share on other sites
  • 0

@sanrod,

Well ... close ... but the Basys3 doesn't really have an internal oscillator.  It has an external 100MHz oscillator.

My recommendation is that all of your logic transition on positive edges of that 100MHz oscillator.  If 100MHz is the wrong speed, then use a PLL or MMCM (or clocking wizard IP to generate a PLL or MMCM) to create a clock that all of your logic will then transition on.  (100MHz should be fine for what you are doing ...)

Further, do not assign anything to be your clock signal.  If you create a signal with logic (A <= !A for example), then do not trigger off of the positive edge of it.  If you are struggling to figure out how to handle timing within an FPGA under these rules, check out this post on how to handle FPGA timing issues.

Dan

Tickstart likes this

Share this post


Link to post
Share on other sites
  • 0
10 hours ago, Tickstart said:

You can refer to many good advice on my thread in which I tried doing the same thing. I have functional SPI code between the Arduino and the Basys 3 now thanks to the help from this forum and AVRFreaks.

http://www.avrfreaks.net/forum/solved-spi-m328parduino-uno-r3

 

 

Thanks for your answers, the truth is that it switches from SPI to UART, and can send information from arduino to fpga. But thanks to you I learned new things, I hope that the questions were not so simple, but how little I have been learning on my own since in my school practically we did not see any programming in fpga and they also asked me for a Semester project.

Tickstart likes this

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now