4

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.

Roh
  • 4,598
  • 6
  • 41
  • 86
chasep255
  • 523
  • 9
  • 23
  • Why not use a clock divider component? – Jake Robinson Dec 24 '15 at 14:28
  • 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? – chasep255 Dec 24 '15 at 14:50
  • 2
    ```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. – Tom Carpenter Dec 24 '15 at 15:06
  • 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? – Paebbels Dec 24 '15 at 18:09

1 Answers1

1

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.

Krunal Desai
  • 6,246
  • 1
  • 21
  • 32
  • 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? – chasep255 Dec 24 '15 at 18:40
  • 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? – Krunal Desai Dec 24 '15 at 22:32
  • 2
    Don't generate clocks this way. Use a DCM or PLL instead. – alex.forencich Dec 24 '15 at 22:32
  • 1
    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. – Krunal Desai Dec 24 '15 at 22:54