Concept & Design of 3.3V Parallel 16-bit VGA Boards
-
ElEctric_EyE
- Posts: 3260
- Joined: 02 Mar 2009
- Location: OH, USA
Re: Concept & Design of 3.3V Parallel 16-bit VGA Boards
What about in UG381, Select IO Resources User's Guide, where it talks about the IODELAY2 primitive? Also in the HDL library.
Seems like it uses the same delay elements in the IO section of the FPGA?
Seems like it uses the same delay elements in the IO section of the FPGA?
Re: Concept & Design of 3.3V Parallel 16-bit VGA Boards
The IODELAY2 primitive was what I was thinking of. Reading a bit in UG381, I noticed that it has a calibration mode. It requires applying a known clock on the input pad, but that may be accomplished by writing a known pattern to SRAM and reading it back as a burst.
-
ElEctric_EyE
- Posts: 3260
- Joined: 02 Mar 2009
- Location: OH, USA
Re: Concept & Design of 3.3V Parallel 16-bit VGA Boards
Interesting, seems like that way would use more resources. I started a thread in the Xilinx forums. I probably should have searched the forums first. I'll do now. 
Re: Concept & Design of 3.3V Parallel 16-bit VGA Boards
The IODELAY2 resources are already there, whether you use them or not. The calibration feature, assuming it is possible, would only take a modest amount of extra state.
-
ElEctric_EyE
- Posts: 3260
- Joined: 02 Mar 2009
- Location: OH, USA
Re: Concept & Design of 3.3V Parallel 16-bit VGA Boards
Yes, I guess that calibration state is there for those that want to push the speeds such that when temperature changes start to affect performance, they could re-run the calibration. Personally, I'm not one that wants to push the speeds to that level. I'd prefer to find out what works across all temps. Seems like setting the simpler constraints values might be the way to go... But there is no discussion of what the values actually mean.
-
ElEctric_EyE
- Posts: 3260
- Joined: 02 Mar 2009
- Location: OH, USA
Re: Concept & Design of 3.3V Parallel 16-bit VGA Boards
I just noticed an error I made using the pclk for the SyncRAM clock. I fixed that and use the dcm_clk100, now the pixels are appearing nice and small and square.
EDIT: So I noticed that
are no longer needed, as the DDR FF and the buffer take the place of the wires.
EDIT: So I noticed that
Code: Select all
wire dcm_clk100;
wire clk;-
ElEctric_EyE
- Posts: 3260
- Joined: 02 Mar 2009
- Location: OH, USA
Re: Concept & Design of 3.3V Parallel 16-bit VGA Boards
Since I'm forced to learn proper Verilog syntax, and sometimes I feel like a monkey typing almost randomly to achieve some Shakespeare novel, I prefer typing as little as possible and so I think I am learning some shortcuts. But I've come across a shortcut that appears to work only sometimes. Other times ISE13.4 sees it as a straight "syntax error".
I will post Arlet's main.v module which I've modified with his permission. I've modified it even further today and the latest modifications meld the X & Y pixel counters into the output register for the external SyncRAM address. It works, but I'm posting not for questions about functionality (although that would be useful too!), but observe some of the syntax that ISE actually passes. But only sometimes. Early on, it let's me do but later on it will not accept the same syntax for:
I will post Arlet's main.v module which I've modified with his permission. I've modified it even further today and the latest modifications meld the X & Y pixel counters into the output register for the external SyncRAM address. It works, but I'm posting not for questions about functionality (although that would be useful too!), but observe some of the syntax that ISE actually passes. But only sometimes. Early on, it let's me do
Code: Select all
wire fifo_write,
fifo_full;Code: Select all
wire xdone = (x == 639) && !fifo_full;
wire ydone = (y == 480);
wire [20:0] SRAtemp;Code: Select all
/*
* top level module
*
* (C)2012 Arlet Ottens <arlet@c-scape.nl>
* -modified by ElEctric_EyE-
*/
module main(
input clk100,
input [15:0] SRD, //SyncRAM data
output pclk_out,
output SRCLK, //SyncRAM clock
output [4:0] red,
output [5:0] green,
output [4:0] blue,
output vsync,
output hsync,
output reg DACBLANKn = 1,
output reg SRCS = 1, //SyncRAM CS, active high
output reg WEn = 1, //SyncRAM WE, active low
output reg [20:0] SRA //SyncRAM Address
);
wire [15:0] rgb;
assign blue = rgb[4:0],
green = rgb[10:5],
red = rgb[15:11];
wire fifo_write,
fifo_full;
reg [15:0] fifo_data;
wire pclk0,
vtrigger;
/* pixel clock output using DDR flipflop */
ODDR2 ODDRA (
.Q(pclk_out),
.C0(pclk),
.C1(~pclk),
.CE(1'b1),
.D0(1'b1),
.D1(1'b0),
.R(1'b0),
.S(1'b0)
);
/* SyncRAM Clock output also using DDR flipflop */
ODDR2 ODDRB (
.Q(SRCLK),
.C0(dcm_clk100),
.C1(~dcm_clk100),
.CE(1'b1),
.D0(1'b1),
.D1(1'b0),
.R(1'b0),
.S(1'b0)
);
/* clock buffers */
IBUFG IBUFG_clk( .I(clk100), .O(dcm_clk100) );
BUFG BUFG_clk( .I(dcm_clk100), .O(clk) );
BUFG BUFG_PCLK( .I(pclk0), .O(pclk) );
/* Use DCM to generate 25 MHz VGA pixel clock from 100 MHz main clock */
DCM_SP #(
.CLKDV_DIVIDE(4.0),
.CLKFX_DIVIDE(8),
.CLKFX_MULTIPLY(2),
.CLKIN_DIVIDE_BY_2("FALSE"),
.CLKIN_PERIOD(10.0),
.CLKOUT_PHASE_SHIFT("FIXED"),
.CLK_FEEDBACK("1X"),
.DESKEW_ADJUST("SYSTEM_SYNCHRONOUS"),
.DLL_FREQUENCY_MODE("LOW"),
.DUTY_CYCLE_CORRECTION("TRUE"),
.PHASE_SHIFT(0),
.STARTUP_WAIT("FALSE")
) DCM_SP_inst (
.CLKFX(pclk0), // 0 degree DCM CLK output
.CLKFB(pclk), // DCM clock feedback
.PSEN(1'b0), // no variable phase shift
.CLKIN(dcm_clk100), // Clock input (from IBUFG, BUFG or DCM)
.RST(1'b0)
);
//wire clk;
/*
* VGA generator
*/
vga vga(
.clk(clk),
.pclk(pclk),
.hsync(hsync),
.vsync(vsync),
.fifo_data(fifo_data),
.fifo_write(fifo_write),
.fifo_full(fifo_full),
.rgb(rgb) ,
.vtrigger(vtrigger)
);
/*
* when vtrigger is pulsed, generate new frame by sending 640x480 pixels
* to FIFO.
*/
reg [10:0] x = 0;
reg [9:0] y = 0;
wire xdone = (x == 639) && !fifo_full;
wire ydone = (y == 480);
wire [20:0] SRAtemp;
assign SRAtemp[10:0] = x,
SRAtemp[19:11] = y,
SRAtemp[20] = 0; //possible future bank switch bit
/*
* count x, reset at end of line, and pause when FIFO is full
*/
always @(posedge clk)
if( vtrigger || xdone )
x <= 0;
else if( !fifo_full )
x <= x + 1;
/*
* count y, reset at start of new frame, and increment at end
* of line. Pause when FIFO is full.
*/
always @(posedge clk)
if( vtrigger )
y <= 0;
else if( xdone && !ydone )
y <= y + 1;
/*
* only write fifo during active pixels
*/
assign fifo_write = !ydone;
/*
* SyncRAM address generator
*/
always @(posedge clk)
if( vtrigger )
SRA <= 0;
else if ( !fifo_full )
SRA <= SRAtemp;
/*
* SyncRAM output into FIFO
*/
always @*
fifo_data <= SRD; // RAM data
endmodule
-
ElEctric_EyE
- Posts: 3260
- Joined: 02 Mar 2009
- Location: OH, USA
Re: Concept & Design of 3.3V Parallel 16-bit VGA Boards
I know it's not good practice for flow, but the syntax is interesting nonetheless. This is the furthest I could get away with:
Code: Select all
/*
* top level module
*
* (C)2012 Arlet Ottens <arlet@c-scape.nl>
* -modified by ElEctric_EyE-
*/
module main(
input clk100,
input [15:0] SRD, //SyncRAM data
output [4:0] red,
output [5:0] green,
output [4:0] blue,
output vsync,
hsync,
pclk_out,
SRCLK, //SyncRAM clock
output reg DACBLANKn = 1,
output reg SRCS = 1, //SyncRAM CS, active high
output reg WEn = 1, //SyncRAM WE, active low
output reg [20:0] SRA //SyncRAM Address
);
wire [15:0] rgb;
wire [20:0] SRAtemp;
wire fifo_write,
fifo_full,
pclk0,
vtrigger; //when vtrigger is pulsed, generate new frame by sending 640x480 pixels to FIFO
wire xdone = (x == 639) && !fifo_full,
ydone = (y == 480);
assign blue = rgb[4:0],
green = rgb[10:5],
red = rgb[15:11],
SRAtemp[10:0] = x,
SRAtemp[19:11] = y,
SRAtemp[20] = 0, //future bank switch bit
fifo_write = !ydone; //only write fifo during active pixels
reg [15:0] fifo_data;
reg [10:0] x = 0;
reg [9:0] y = 0;
/* pixel clock output using DDR flipflop */
ODDR2 ODDRA (
.Q(pclk_out),
.C0(pclk),
.C1(~pclk),
.CE(1'b1),
.D0(1'b1),
.D1(1'b0),
.R(1'b0),
.S(1'b0)
);
/* SyncRAM Clock output also using DDR flipflop */
ODDR2 ODDRB (
.Q(SRCLK),
.C0(dcm_clk100),
.C1(~dcm_clk100),
.CE(1'b1),
.D0(1'b1),
.D1(1'b0),
.R(1'b0),
.S(1'b0)
);
/* clock buffers */
IBUFG IBUFG_clk( .I(clk100), .O(dcm_clk100) );
BUFG BUFG_clk( .I(dcm_clk100), .O(clk) );
BUFG BUFG_PCLK( .I(pclk0), .O(pclk) );
/* Use DCM to generate 25 MHz VGA pixel clock from 100 MHz main clock */
DCM_SP #(
.CLKDV_DIVIDE(4.0),
.CLKFX_DIVIDE(8),
.CLKFX_MULTIPLY(2),
.CLKIN_DIVIDE_BY_2("FALSE"),
.CLKIN_PERIOD(10.0),
.CLKOUT_PHASE_SHIFT("FIXED"),
.CLK_FEEDBACK("1X"),
.DESKEW_ADJUST("SYSTEM_SYNCHRONOUS"),
.DLL_FREQUENCY_MODE("LOW"),
.DUTY_CYCLE_CORRECTION("TRUE"),
.PHASE_SHIFT(0),
.STARTUP_WAIT("FALSE")
) DCM_SP_inst (
.CLKFX(pclk0), // 0 degree DCM CLK output
.CLKFB(pclk), // DCM clock feedback
.PSEN(1'b0), // no variable phase shift
.CLKIN(dcm_clk100), // Clock input (from IBUFG, BUFG or DCM)
.RST(1'b0)
);
/*
* VGA generator
*/
vga vga(
.clk(clk),
.pclk(pclk),
.hsync(hsync),
.vsync(vsync),
.fifo_data(fifo_data),
.fifo_write(fifo_write),
.fifo_full(fifo_full),
.rgb(rgb) ,
.vtrigger(vtrigger)
);
/*
* count x, reset at end of line, and pause when FIFO is full
*/
always @(posedge clk)
if( vtrigger || xdone )
x <= 0;
else if( !fifo_full )
x <= x + 1;
/*
* count y, reset at start of new frame, and increment at end
* of line. Pause when FIFO is full.
*/
always @(posedge clk)
if( vtrigger )
y <= 0;
else if( xdone && !ydone )
y <= y + 1;
/*
* SyncRAM address generator
*/
always @(posedge clk)
if( vtrigger )
SRA <= 0;
else if ( !fifo_full )
SRA <= SRAtemp;
/*
* SyncRAM output into FIFO
*/
always @*
fifo_data <= SRD; // RAM data
endmodule
Re: Concept & Design of 3.3V Parallel 16-bit VGA Boards
I would rather just keep the extra 'wire' in there.. makes it easy to move lines around without breaking things.
-
ElEctric_EyE
- Posts: 3260
- Joined: 02 Mar 2009
- Location: OH, USA
Re: Concept & Design of 3.3V Parallel 16-bit VGA Boards
Cool. I was just experimenting...
Tomorrow, I would like to come up with a machine that writes coordinates into the SyncRAM using the hardware line plotting routine White Flame helped me out with towards the end of this thread and your FIFO machine.
Tomorrow, I would like to come up with a machine that writes coordinates into the SyncRAM using the hardware line plotting routine White Flame helped me out with towards the end of this thread and your FIFO machine.
Re: Concept & Design of 3.3V Parallel 16-bit VGA Boards
Hmm.. I think my FPGA died. I can't program it any more. Impact returns with an red error flag. I can still program other boards, so the JTAG adapter is okay. I'll have to order another Spartan, and see if I can repair the board.
-
ElEctric_EyE
- Posts: 3260
- Joined: 02 Mar 2009
- Location: OH, USA
Re: Concept & Design of 3.3V Parallel 16-bit VGA Boards
I doubt the regulator was overloaded. That stinks...
In an effort to get the SyncRAM timing closer to being correct, I tried to add the CLK0 (before trying CLK90) output to the DCM. Then that goes to a BUFG. That clk1 output then goes to:
Now nothing works.
In an effort to get the SyncRAM timing closer to being correct, I tried to add the CLK0 (before trying CLK90) output to the DCM. Then that goes to a BUFG. That clk1 output then goes to:
Code: Select all
always @(posedge clk1)
fifo_data <= SRDRe: Concept & Design of 3.3V Parallel 16-bit VGA Boards
ElEctric_EyE wrote:
I doubt the regulator was overloaded. That stinks...
Are you just using your clk1 to capture the SRAM data, and using the other clock for everything else ? That should do something, at least. Can you lead clk1 off-chip and see if it's running at the expected frequency ? You could also run a sim, and see if the clock is running correctly on there. Are there any warnings about the clock ? You should always watch out for warnings that say that signal-such-and-such isn't used or that nothing is clocked by a certain clock.
-
ElEctric_EyE
- Posts: 3260
- Joined: 02 Mar 2009
- Location: OH, USA
Re: Concept & Design of 3.3V Parallel 16-bit VGA Boards
Arlet wrote:
I'm guessing it was taking the JTAG connector on/off while everything was powered. Maybe that caused a latch-up condition or ESD...
Arlet wrote:
...Are you just using your clk1 to capture the SRAM data, and using the other clock for everything else ? That should do something, at least. Can you lead clk1 off-chip and see if it's running at the expected frequency ? You could also run a sim, and see if the clock is running correctly on there. Are there any warnings about the clock ? You should always watch out for warnings that say that signal-such-and-such isn't used or that nothing is clocked by a certain clock.
The simulation looks good.
No warnings about the clock.
Another observation. I got rid of the IBUF, and used the DCM's CLK0 output to generate clk. Now there are no warnings during implementation. Here's what I have for the BUFGs and DCM. Still no output from the DCM. Do you see anything wrong?
Code: Select all
/* clock buffers */
//IBUFG IBUFG_clk( .I(clk100), .O(dcm_clk100) );
BUFG BUFG_clk( .I(clk0), .O(clk) );
BUFG BUFG_clk2( .I(clk1), .O(clk2) );
BUFG BUFG_PCLK( .I(pclk0), .O(pclk) );
/* Use DCM to generate 25 MHz VGA pixel clock from 100 MHz main clock */
DCM_SP #(
.CLKDV_DIVIDE(4.0),
.CLKFX_DIVIDE(8),
.CLKFX_MULTIPLY(2),
.CLKIN_DIVIDE_BY_2("FALSE"),
.CLKIN_PERIOD(10.0),
.CLKOUT_PHASE_SHIFT("FIXED"),
.CLK_FEEDBACK("1X"),
.DESKEW_ADJUST("SYSTEM_SYNCHRONOUS"),
.DLL_FREQUENCY_MODE("LOW"),
.DUTY_CYCLE_CORRECTION("TRUE"),
.PHASE_SHIFT(0),
.STARTUP_WAIT("FALSE")
) DCM_SP_inst (
.CLK0(clk0), //0 degree CLKIN output
.CLK90(clk1), //90 degree CLKIN output
.CLKFX(pclk0), // 0 degree DCM CLK output
.CLKFB(pclk), // DCM clock feedback
.PSEN(1'b0), // no variable phase shift
.CLKIN(clk100), // Clock input
.RST(1'b0)
);Re: Concept & Design of 3.3V Parallel 16-bit VGA Boards
According to UG382, p72:
So, you need to feed CLK0 output in a BUFG, and the output of the BUFG back into the CLKFB input. The IBUFG is optional. If you don't specify it, the tools will automatically infer a IBUFG. Check the technology schematic, select the clock signals, and you can see exactly how everything will be wired up. Originally I didn't have the IBUFG/BUFG, and I got some strange warning. On the Xilinx forum I found advice to explicitly include the clock buffers so the tools wouldn't get confused, even though it inferred exactly the same thing.
Quote:
CLKFB: Clock feedback input to DCM. The feedback input is required unless the DFS outputs, CLKFX or CLKFX180, are used standalone.
The source of the CLKFB input must be the CLK0 or CLK2X output from the DCM and the CLK_FEEDBACK must be set to 1X or 2X accordingly.
The source of the CLKFB input must be the CLK0 or CLK2X output from the DCM and the CLK_FEEDBACK must be set to 1X or 2X accordingly.