Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Trouble getting started with a Spartan-6

Status
Not open for further replies.

EnderW4785

Member level 1
Joined
Mar 9, 2010
Messages
34
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,286
Location
Urbana
Activity points
1,918
Hello all. For work I was given a Spartan-6 on a Drigmorn3 demo board in order to prototype some hardware. Having never done verilog or any sort of FPGA design I downloaded ISE 13.3, read through the tutorials, read a Verilog for dummies book and got started. My first goal was given a 82 MHz clock, give or take, I wanted to divide it down to. When I failed to get that working, I added in a line or two of code that would simply turn the LCD screen backlight on. Everything failed. I can't get the FPGA to show me any sort of life. I'm sure I'm doing something incredibly wrong but I don't know what it is. Here is the code that I have so far:


Code Verilog - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
module main_module( clkADC_P, clkADC_N, clkWall_P, clkWall_N, div_clk, LCDbacklight);
    
     input wire clkADC_P;
     input wire clkADC_N;
         input wire clkWall_P;
     input wire clkWall_N;
     output wire div_clk;
     output reg LCDbacklight;
     
     wire clkADC;
     wire clkWall;
     reg [25:0] divisor = 1382400;
     
    IBUFDS #(
        .CAPACITANCE("DONT_CARE"),
        .DIFF_TERM("FALSE"),
        .IBUF_DELAY_VALUE("0"),
        .IFD_DELAY_VALUE("AUTO"),
        .IOSTANDARD("LVPECL_33")) 
    IBUFDS_inst1 (
        .O(clkADC),
        .I(clkADC_P),
        .IB(clkADC_N));
    IBUFDS #(
        .CAPACITANCE("DONT_CARE"),
        .DIFF_TERM("FALSE"),
        .IBUF_DELAY_VALUE("0"),
        .IFD_DELAY_VALUE("AUTO"),
        .IOSTANDARD("LVPECL_33")) 
    IBUFDS_inst2 (
        .O(clkWall),
        .I(clkWall_P),
        .IB(clkWall_N));
    
    clk_divider clk_divider_inst (
         .clk(clkADC),
         .divisor(divisor),
         .div_clk(div_clk));
    
    always begin @(posedge clkADC)
        LCDbacklight <= 1;
    end
 
      
endmodule
 
module clk_divider(clk, divisor, div_clk);
    input clk;
    input [25:0] divisor;
    output div_clk;
 
    reg div_clk;
    reg [25:0] cnt;
 
    initial begin
        cnt = 0;
    end
 
    always @(posedge clk)begin
      if (cnt >= divisor) begin
          div_clk <= 0;
          cnt <= 0; end
      else if (cnt < divisor/2) begin
          div_clk <= 0;
          cnt <= cnt + 1; end
      else if ((cnt >= divisor/2) && (cnt < divisor)) begin 
            div_clk <= 1;
            cnt <= cnt + 1; end
    end // always
 
endmodule
 
 
#Created by Constraints Editor (xc6slx16-csg324-2) - 2012/01/30
NET "clkADC_N" TNM_NET = "clkADC_N";
TIMESPEC TS_clkADC_N = PERIOD "clkADC_N" 12.056 ns HIGH 50 %;
NET "clkADC_P" TNM_NET = "clkADC_P";
TIMESPEC TS_clkADC_P = PERIOD "clkADC_P" 12.056 ns HIGH 50 %;
NET "clkWall_N" OFFSET = IN 12.056 ns VALID 12.056 ns BEFORE "clkADC_N" RISING;
NET "clkWall_P" OFFSET = IN 12.056 ns VALID 12.056 ns BEFORE "clkADC_N" RISING;
NET "div_clk" OFFSET = OUT 12.056 ns AFTER "clkADC_N";
 
 
NET "clkADC_P" LOC = H2;
NET "clkWall_P" LOC = T4;
NET "div_clk" LOC = N6;
 
 
NET "clkADC_N" IOSTANDARD = LVPECL_33;
NET "clkADC_P" IOSTANDARD = LVPECL_33;
NET "div_clk" IOSTANDARD = LVCMOS33;
 
 
CONFIG VCCAUX  = 3.3;
#Created by Constraints Editor (xc6slx16-csg324-2) - 2012/01/30
NET "LCDbacklight" OFFSET = OUT 12.056 ns AFTER "clkADC_N";
 
 
NET "LCDbacklight" LOC = M3;
 
# PlanAhead Generated IO constraints 
 
NET "LCDbacklight" IOSTANDARD = LVCMOS33;
NET "LCDbacklight" DRIVE = 12;
NET "div_clk" DRIVE = 12;




There are a lot of pieces of this that I don’t fully understand, especially all of the timing settings in the constraits editor. I struggled for awhile trying to figure out how to interface my LVPECL 3.3V clock to the FPGA and while I think I’m close its probably not correct. The thing that’s the most discouraging is I can’t get a simple LED to turn on and off.

Any help would be appreciated. If you need more information, let me know.

Thanks,

Scott
 
Last edited by a moderator:

I'm a VHDL guy, I don't know verilog, but the first thing I would suspect is your pin mapping, i.e., assigning what signals are on which pins. Did you verify your pinmap file after P&R? Never mind, I now see that you have pin assignments in your file.
 

I checked the pinout a few times, and this would be the first thing I check tomorrow. I'm confident that the pin I'm setting high to turn on the LCD back light / LED (depending on whether I use C1 for the backlight or M# for the LED) is correct. And yet those don't turn on.

Another question I have regards programming the device. When iMPACT says configuration file generated, does that mean the FPGA is programmed? Or is there another step?
 

Aha! The configuration file is created, and is now sitting happily on your hard drive, doing nothing. You need to DOWNLOAD the file to the FPGA. Depending on which version of Impact you are using, there's a tab that gets you to the download screen. On this screen you will see the schematic representation of your FPGA (and config ROM). You may need to SCAN your board to get to that point. If you check out the HELP, it will explain it to you. This all assumes you have the programming cable connected to your board.

Barry
 

You have got to be kidding me. I knew that it didn't seem right. In iMPACT for ISE 13.3, I double click Generate File and it says Generate Succeeded. Then what? I don't see a download tab or option anywhere.

Scott
 

Check out the ISE In-Depth Tutorial (it's for ISE 12, but is still applicable to 13).

Chapter 7 should tell you all you need to know. Basically, after you've generated the bit file, configure your device using boundary scan (JTAG), assign a configuration file to the FPGA (the .bit file), and right-click and program the FPGA.

If you have other devices in the chain or connected flash devices, you'll also have the option to add them, but you don't need to assign configuration files to them if you're just testing the design at this stage.

Note that if you're using the Enterpoint Prog3 USB cable, it may not be compatible with iMPACT (I've never used it, so I don't know!) - in this case, Enterpoint should have supplied a configuration tool with it. The parallel cable or a Xilinx USB Platform Cable will work with iMPACT, though.
 

Note that if you're using the Enterpoint Prog3 USB cable, it may not be compatible with iMPACT (I've never used it, so I don't know!) - in this case, Enterpoint should have supplied a configuration tool with it. The parallel cable or a Xilinx USB Platform Cable will work with iMPACT, though.

Quick google around ==> **broken link removed**

Looks like the enterpoint prog3 usb thing will work with impact.
 
Under "Impact Flows" on the left, there should be a "Boundary Scan" selection at the top. Double click that, then right click in the right-hand window and "Initialize chain"-you should see your devices there.
 

Thank you. Some success. Now I can turn an LED on when I actually download the program. However my clock divider does not work and whenever I try to turn on the LCD screen that does not work either.

Can someone look at my timing constraints and tell me what they should say? They don't look right. clkADC_P and clkADC_N are the positive and negative end of an external clock which should be clocking the entire system. Also what should the drive levels and iostandards be for my output clock (does it matter?). Should I be terminating it somehow before I expect to see a signal? Also, does anything need to change when I'm turning on an LCD screen as opposed to an LED?.

Thank you all for the responses.
 

Have you tested the clock divider logic in ISim? Is the differential ADC clock input working?

The divider is more complicated than what I would use. To keep things simple, you can do this:


reg [25:0] divisor = 691200; // Half of 1382400

always @(posedge clk)
if (cnt == divisor) begin
div_clk <= ~div_clk;
cnt <= 0;
end else
cnt <= cnt + 1'b1;


i.e. every half a period, toggle the divided clock.

You don't really have to do anything special to output a low speed divided clock. At higher speeds or if you care about skew or jitter, you would use a global clock buffer (BUFG) and an ODDR2.

The output clock's IOSTANDARD should match whatever the thing it's connected to requires. If it's the LCD, it's probably LVCMOS33. You should be able to monitor an LVCMOS33 output using a high impedance oscilloscope probe without any special termination.

As far as I can tell, you shouldn't need to do anything to activate the LCD backlight other than output a voltage on C1. If that doesn't work, I would probably look at the schematic diagram (I just did, and it looks like taking C1 high should do the trick). Note that Enterpoint recommend using LVTTL for the LCD backlight (see http://www.enterpoint.co.uk/drigmorn/drigmorn3_issue2.ucf).

Your timing constraints look okay. As a minimum, you only need the PERIOD constraints - don't worry too much about the OFFSET constraints at this early stage, though they won't cause any harm.
 

Do you mean testing in the Behavioral Simulation mode? That seemed to be working alright. I'll double check that as I've made some changes to it since I last checked.

I'll try the LVTTL to get the LCD backlight on. Thank you for that ucf file, that will be very helpful moving forward.

Moving forward this divided clock is going to be used to PLL the faster clock to a slower clock which should be an integer multiple divisor of it. Basically I'm locking a high speed clock to wall power. Does this change your suggestion about how I should be doing the dividing / inputting and outputting?

What makes me uncomfortable with the timing constraints is that it talks about the rising edge of the positive and negative sides of the clock and not the rising edge of the actual clock. Is this a problem? Could you quickly explain what the offsets / global offsets in the timing constraints actually mean?

Thanks,

Scott
 

Yes, a behavioural simulation should be fine.

I'm not completely sure what you're trying to do with your clocks - do you mean you want to generate a clock based on a multiple of the 50/60 Hz line frequency? How fast will the fast clock be? What exactly are you trying to achieve?

There are a series of articles on timing constants at the Xilinx forum, which explain some of the details if you don't want to read the entire Timing Constraints User Guide.

There's also **broken link removed**, which states that you only need to apply the constraint to the positive clock. The answer record doesn't give very much detail, but there is a clarification on the forum. With regards to your concern about the 'actual clock', the constraint will carry through the IBUFDS (you might want to use an IBUFGDS) so you don't need to constrain the single-ended output clock separately.
 

The goal is to lock a high frequency (around 82 MHz) thats clocking an ADC to a direct multiple of 60Hz. Multiplying 60 Hz up or dividing the initial high clock frequency down are both options. Is multiplying the base frequency up an option here? Isn't that a non-causal action?

Success in dividing the frequency. The LCD backlight still won't turn on but thats not the end of the world for now.
 

The Spartan-6 has digital clock managers and PLLs, which you can use to generate arbitrary clocks (e.g. from the 25 MHz oscillator on the Drigmorn3). I think you'll probably struggle to generate an 82 MHz clock in the FPGA fabric - you would need a much faster clock to be able to divide down to that, and the Spartan-6 fabric is only good to a maximum of around 250 MHz. The DCM/PLL won't work from a 60 Hz input clock, though.

Generating ADC sampling clocks from an FPGA usually leads to pretty unsatisfactory results due to jitter. I would recommend using some other clocking solution. On one of my boards, for example, I've used a GPS-disciplined OCXO to clock a DDS, which synthesises frequencies for my ADC. The FPGA isn't involved at all (it was easier to use a PIC to program the DDS and implement the GPS frequency locked loop). You could do something much simpler with, say, a Si571 oscillator and a DAC to generate the fine-tuning control voltage.

Is there a particular reason why the ADC needs to be sampling at an exact multiple of 60 Hz?
 

I am generating the 82 MHz clock with a precise VXCO, and the plan was to divide it down to 60ish and use an xor gate internal to the FPGA to serve as my PLL feedback to the VXCO. If I should just implement my PLL off the FPGA thats fine too but figured this was an easy way to save a chip or two in the implementation. Needing to be multiple of 60 has to do with rejecting noise from the power lines in a precise measurement.
 

Ah, if your VCXO has a control voltage input that allows the output frequency to be pulled slightly, you could use this, a DAC, the 60 Hz signal, and the FPGA to implement a frequency locked loop.

You don't really need to multiply the 60 Hz clock - just do something like this:

- Use 82 MHz clock to increment a counter
- Register asynchronous 60 Hz input into the 82 MHz clock domain
- At every rising edge of the 60 Hz input, note the value of the counter and reset it to zero.
- If the counter was greater than 82E6/60, lower the control voltage. Otherwise, raise the control voltage. Or keep it the same.

You will probably want to average readings over a longer time period than 1/60 s, and perhaps employ a proper control system to set the voltage so that you get a nice response (unless you don't care about a long warm up time).
 

Thank you for your help. I think I'm all set with this issue for now (other than the fact I still can't get the darn LCD screen to light up). Onto more difficult problems including implementing ethernet communication and an LVDS deserializer.
 

I'd recommend studying XAPP1064 for deserialisation - I've used this method very successfully with the LTC2171 ADC.
 

Thank you again. This is what I've been looking for. I read a few mentions of the ISERDES functionality but this is a perfect explanation. Maybe this won't be so bad after all.

I just joined opencores for their possible help with the ethernet controller. Do you have any suggestions there?
 

I've only evaluated the gigabit Ethernet cores on Opencores and was pretty underwhelmed by the poor documentation. I'm not sure about 10/100, sorry!

I've published a working example design that uses the USRP2's GPL-ed gigabit MAC on a Spartan-6 (should work with any board using the Marvell 88E1111), but it would take a significant redesign to get this core working at other speeds.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top