4
\$\begingroup\$

I just got a Digilent Basys 3 board (Artix-7 FPGA) and I am trying to create a program to transmit data over the UART-USB connection. I wrote a module but when I tried to implement it I got a timing error. I have been using the standard 100 Mhz clock which comes with the board. I now think I need something slower like 50 Mhz. I don't think I can change the standard clock since that is fixed at 100 Mhz by the board so I think I need to create a generated clock. I added the following lines to my xdc file.

set_property PACKAGE_PIN W5 [get_ports clk]
set_property IOSTANDARD LVCMOS33 [get_ports clk]
create_clock -period 10.000 -name sys_clk_pin -waveform {0.000 5.000} -add [get_ports clk]

create_generated_clock -divide_by 2 -source [get_ports clk] [get_ports clk2]

I then get the error. Generated clock clk2 has not logical path from master clock sys_clk_pin. Am I missing a step. Do I need to do something more than create it in the XDC file? Here is the header for my top level module.

module serial_emitter(
    output RsTx,
    input RsRx,
    input clk,
    input clk2,
    output [3:0] an,
    output [6:0] seg);

I want the slower clock to map to the clk2 input.

\$\endgroup\$
  • \$\begingroup\$ Why not use a clock divider component? \$\endgroup\$ – Jake Robinson Dec 24 '15 at 14:28
  • \$\begingroup\$ So I used the Clock Wizzard IP to create a generated clock which seems to work. I guess I don't need to add the constraint to the XDC file in this case? \$\endgroup\$ – chasep255 Dec 24 '15 at 14:50
  • 2
    \$\begingroup\$ create_generated_clock instructions are nothing more than directives to the static timing analyser to describe what clocks are what. You actually need to implement the logic or primitives that produce the clock. \$\endgroup\$ – Tom Carpenter Dec 24 '15 at 15:06
  • \$\begingroup\$ I think you should also review your UART module, because a normal UART can run with up to 250 MHz on 7-Series FPGA. When the timing analysis reports failing paths, have you check what's going wrong with these paths? \$\endgroup\$ – Paebbels Dec 24 '15 at 18:09
2
\$\begingroup\$

You've constrained the clock for static timing analysis, but you never actually wrote the logic to divide a clock by two:

reg r_clk_div;
always @(posedge i_clk) begin

   r_clk_div  <=  !r_clk_div;

end

assign o_clk2 = r_clk_div;

This should synthesize to a DFF clocked by input clock, Q tied to D through an inverter, and then the Q output is your new clock. Your constraint tells the tools that you've generated this clock from an existing clock / resource and to treat it accordingly.

Note that I don't have a reset for this divider since I didn't see one in your module, but it may not be a bad idea to avoid temporary meta stability.

Apologies for typos, I'm on mobile.

\$\endgroup\$
  • \$\begingroup\$ Just wondering how do I add a reset. Is it a signal that gets generated when the device starts? How would I add that port to my top level module and add it to the XDC file? \$\endgroup\$ – chasep255 Dec 24 '15 at 18:40
  • \$\begingroup\$ I think you must have a reset somewhere in your design -- I bet the Digilent board has a reset wired up to a pin already. Think of it this way -- how do you make sure all your nice peripherals and registers you've written start up in the state you want? \$\endgroup\$ – Krunal Desai Dec 24 '15 at 22:32
  • 2
    \$\begingroup\$ Don't generate clocks this way. Use a DCM or PLL instead. \$\endgroup\$ – alex.forencich Dec 24 '15 at 22:32
  • 1
    \$\begingroup\$ A DCM/PLL is the better way to generate a clock, agreed. They just aren't always available in a FPGA and this application seems simple enough that a simple DFF will do the job and be a bit more educational. \$\endgroup\$ – Krunal Desai Dec 24 '15 at 22:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.