HDL compilers love to spit out warnings about all sorts of things so you usually won't get a zero warning zero error compilation like you tend to strive for in most other programming, If nothing else it will spit out a warning that it is not fully licensed.
HDL compilers love to spit out warnings about all sorts of things so you usually won't get a zero warning zero error compilation like you tend to strive for in most other programming, If nothing else it will spit out a warning that it is not fully licensed.
and it is freaking annoying, because sometimes somewhere in the ten pages of silly warnings something important is hidden
It seems the warning is due to the literal values '0' and '1'? Any way around that?By googling quartus warning 10230 I found Intel recommending explicit width specification on constants to suppress the warning.
QuoteI have assigned the signals to pins in the Pin Manager, but I'm clearly missing something else important as well?I consider warnings in a synthesizer as polite FYIs. Unfortunately, that means I have to think when reviewing the warnings to see if they really are a problem, to see if something I really needed got simplified away.

Can we have a look at vga01.v? And your top file? Are you actually driving them? Do you need to drive them? The 13410 will probably not be a real problem of its own, if it resolves once you have provided drivers for that output port, and if you want them "stuck" at 0.
Another note, it helps readability to use the C conventions for the case of constants (all caps) vs. variables (not all caps).

Although:Code: [Select]// generate sync signals (active low for 640x480)Is absolutely correct, however, the >= comparison and < do eat up gates when compiling and your output driving a pin will be a combination unlatched logic equation directly based on your output counter bits. To get a clean output and better F-Max allowing Quartus's Fitter to better route the logic in your FPGA to meet timing constraints, I would:
assign hsync = ~((h_count >= HS_STA) & (h_count < HS_END));
assign vsync = ~((v_count >= VS_STA) & (v_count < VS_END));
A) Make Hsync and Vsync a register.
B) Inside your if (pix_enable), make the logic look like this
if (h_count == HS_STA) begin
hsync <= 1;
end else if (h_count == HS_END) hsync <= 0;
if (V_count == VS_STA) begin
vsync <= 1;
end else if (h_count == VS_END) vsync <= 0;
*Being registers, this now means that those outputs are delayed by 1 pixel clock, but, those outputs will be cleanly timed to the rising edge of your fpga PLL internal clock as those DFF register outputs don't have any logic gates to go through, those DFF register outputs will feed the IO pin directly. (Though, I usually add another DFF stage/pipe to all my DAC and sync outputs allowing the compiler/fitter to bury the logic anywhere deep in the FPGA, the use each pins macrocell flipflops registers to drive the pin itself generating the cleanest possible outputs.)

As for your Assign X&Y, again, doing all that realtime arithmetic is not a problem:Code: [Select]// keep x and y bound within the display area
assign x = (h_count < DA_STA) ? 0 : (h_count - DA_STA); // x is zero if current pixel is before display area
assign y = (v_count >= VA_END) ? (VA_END - 1) : (v_count); // y is VA_END-1 if v_count is outside display area
However, like the HSync and Vsync, personally, I make these outputs a single bit which turns on or off using the simple equality == trick I used to generate the Hsync and Vsync. I rely on my video graphics generator to have an address generator which may increment count every single, every second, or every third/fourth line.
Also, not just that one master image X&Y output enable which is REQUIRED by all DVI transmitters and which may also be used as an image crop mute to protect the video output borders for analog VGA dacs (outside the active video area, the RGB level must be always black), I usually would have something like another 16 programmable of these X&Y on and off output flags which may be used to position sprites or superimposed hardware video windows. Among these 16, which may be positioned after the active video region output, allotting a time slot which may be used to signal memory access cycles to fill your audio DAC buffer, or signal load a new set of X&Y video memory pointers from memory which change the beginning video read address of the next line of video allowing you to dynamically have a new video address and video mode on each new video line. (EG like the Atari 800 display list which allows for a few lines of text mode, then a few with graphics, then more text at a different resolution, or Amiga pulldown screens with a vertically scroll-able window on top of another, each with a different graphics mode pointing to somewhere different in memory.)
If you still directly want to use you h_count and v_count as reference pixel counters and get rid of the ensuing subtraction math to improve FMAX, I would move your hsync and vsync to the end of your counters so that 0 through 639 and 0 through 479 are passed through without any math while the blank front & back porches with syncs come at then end after pixel 640 and line 480. I personally still prefer the 1 bit enables which can actually tell you ensuing logic when to start and stop reading, or when there is free time to read memory for other purposes. With your current code, your logic will continue reading pixel 0x0 whenever there is no video being outputted.

Just a thought regarding the CPU part itself. Of course you could consider using a Z80 core in the FPGA you're going to use. But if you still want a true CPU IC, you could consider the Z180 series. They are software compatible with the Z80, but contain many improvements and embedded peripherals, and there are 3.3V versions as well. The Z8L180 is readily available for instance (at least at Mouser)... so unless you really want to go for a true, vintage Z80, that would be sometthing to consider.
https://en.wikipedia.org/wiki/Zilog_Z180
Many things omitted for simplicity sake but at the top:
module sync_gen ( clk, hsync, hcount );
parameter HS_STA = 10 ; //Turn on hsync signal position
parameter HS_END = 210 ; //Turn off hsync signal position
input clk;
output hsync;
output hcount;
---------------------------------
V1
---------------------------------
reg [9:0] h_count;
wire hsync;
assign hsync = ~((h_count >= HS_STA) & (h_count < HS_END));
always @(posedge clk) begin
h_count <= h_count + 1; // Without a reset limit, the h_count will run 0 to 1023.
end
---------------------------------
V2
---------------------------------
reg [9:0] h_count;
reg hsync;
always @(posedge clk) begin
h_count <= h_count + 1;
hsync <= ~((h_count >= HS_STA) & (h_count < HS_END));
end
---------------------------------
V3
---------------------------------
reg [9:0] h_count;
reg hsync;
always @(posedge clk) begin
h_count <= h_count + 1;
if (h_count == HS_STA) begin
hsync <= 1;
end else if (h_count == HS_END) begin
hsync <= 0;
end
end
---------------------------------
endmodule
Ok, what the blocking statement ( <= ) does and a bit on making optimized fast compact code: What I'm describing here is a little of whats going on inside the compilers mind, and how it wires gates in the FPGA according to the example verilog code. Remember, there is no single core math unit in these FPGAs, whatever you write is literally constructed by wiring masses of gates inside the FPGA. All these wires have lengths, propagation delays, and the gates' inputs have capacitive loads which further slows everything down. This primer gives you an example of coding technique to be aware of to achieve a minimal gate count FPGA core which is fast as possible and lowest power consuming design...



Ok, what the blocking statement ( <= ) does and a bit on making optimized fast compact code: What I'm describing here is a little of whats going on inside the compilers mind, and how it wires gates in the FPGA according to the example verilog code. Remember, there is no single core math unit in these FPGAs, whatever you write is literally constructed by wiring masses of gates inside the FPGA. All these wires have lengths, propagation delays, and the gates' inputs have capacitive loads which further slows everything down. This primer gives you an example of coding technique to be aware of to achieve a minimal gate count FPGA core which is fast as possible and lowest power consuming design...
Wow - thanks BrianHG!
If I'm doing it right, the v3 counter implementation in Quartus II is quoting an Fmax of 217.2 MHz for clk (that's including the vga01.v top level as well).
It still amazes me when I have to keep reminding myself that the code I'm writing has a physical consequence in the FPGA - so what appears to me to be the easiest way of programmatically achieving a task may actually be quite costly in terms of hardware.
Next, now you know what the '<=' function does, basically a bundle of final flipflops latching the outputs of all the synthesized logic gates which are required to perform the boolean algebra on the right of that blocking function, all of them tied to the same dedicated network clock @(posedge...), it's time to take a look at your sync code and what your top hierarchy screenshot within quartus looks like. (For the top, I still use quartus's block diagram entry for the IO pins and my Veriliog appears as 1 master or multiple wired block diagram modules...)
When your ready, post here your latest syncgen.v when you are ready...
it's time to take a look at your sync code and what your top hierarchy screenshot within quartus looks like. (For the top, I still use quartus's block diagram entry for the IO pins and my Veriliog appears as 1 master or multiple wired block diagram modules...)

I ran up a simulation....
You need to be sure if LINE and SCANLINES are terminal counts, or are the total number. Currently your h_counter goes from 0 to 800 (801 counts), and v_counter goes from 0 to 525 (526 lines).
General suggestion (take them or leave them):
- You need to be clear about what is internal state, and what is exposed. Currently the x & y outputs feel bad.
- Your reset should reset all state (even if it is only for simulation).
- I am not sure why you have "posedge reset" in your always. I don't think it is needed.
Here's what I would do:
- Reset all outputs and state in the reset clause
- keep h_counter and v_counter for internal use only, and change the x & y outputs to be reg not wires.
- Keep LINES and SCANLINES as a total count, so compare to LINES-1 or SCANLINES-1 as the test for resetting the counters/
- Likewise keep HS_STA & HS_END the count where it starts, so remove the "-1" from the localparam and put it in the test.
- Try to avoid ternary operators - usage tends to be very idiomatic, so are a common source of bugs
- Unless you are careful, there is going to be ambiguity about when vsync pulse starts and ends. I suggest you testboth h_count and v_count to decide when to assert vsync. So if you want it to be aligned with the start of the visible pixels use "if (h_count == LINES-1 && v_count == VS_STA-1)" and ""if (h_count == LINES-1 && v_count == VS_END-1)" as the tests when to set the vsync outputs.
This might not give you the fastest design, nor the most compact code, but it will help you avoid lots of subtle bugs.
- You need to be clear about what is internal state, and what is exposed. Currently the x & y outputs feel bad.
Not sure what you mean by 'top hierarchy screenshot'? Do you mean the pin assignments? Here's a screenshot of my Quartus II workbench, if that helps:
I'm not convinced that's what you're after, though. I haven't used Quartus' block diagram tool to design the hierarchy, I just created the first file (vga01.v) and went from there, creating sync_generator.v and referring to it in vga01.v. Sorry if I'm being vague or missing an obvious request, it's been a loooong day.


I wonder if the polarity of HSYNC and/or VSYNC are wrong for the chosen resolution.
You need to be sure if LINE and SCANLINES are terminal counts, or are the total number. Currently your h_counter goes from 0 to 800 (801 counts), and v_counter goes from 0 to 525 (526 lines).

- Reset all outputs and state in the reset clause
- keep h_counter and v_counter for internal use only, and change the x & y outputs to be reg not wires.
- Keep LINES and SCANLINES as a total count, so compare to LINES-1 or SCANLINES-1 as the test for resetting the counters/
- Likewise keep HS_STA & HS_END the count where it starts, so remove the "-1" from the localparam and put it in the test.
- Try to avoid ternary operators - usage tends to be very idiomatic, so are a common source of bugs
- Unless you are careful, there is going to be ambiguity about when vsync pulse starts and ends. I suggest you testboth h_count and v_count to decide when to assert vsync. So if you want it to be aligned with the start of the visible pixels use "if (h_count == LINES-1 && v_count == VS_STA-1)" and ""if (h_count == LINES-1 && v_count == VS_END-1)" as the tests when to set the vsync outputs.
This might not give you the fastest design, nor the most compact code, but it will help you avoid lots of subtle bugs.
Quote- You need to be clear about what is internal state, and what is exposed. Currently the x & y outputs feel bad.
I feel the same, I believe the sync generator should be 100% positive logic. Meaning positive hsync / vsync / an active video region output which crops the active visual area (a requirement for most DVI/HDMI serializers), and additional optional signals to trigger video timing specific events which may be fixed to the master h_count and v_count. Any visual display address / graphics /memory pointers, counters and sub-alignment positioning in the 'active video region' should be in the separate graphics image generator. Remember, a second new X/Y coordinate counter is only another 20 register flipflops max.
I'm waiting a day, however, I'll make a few suggestions to the ops sync generator which will solve those -1's without a -1 in the code, and solve that 1 clock delay with regards to the other variables, including the picture_enable_h and picture_enable_v signal (together = picture_enable).

@nockieboy, some questions:
1. Do you have an oscilloscope?

2. Which cyclone II board do you have?
3. Which version of quartus are you using?
4. Are you willing to use Quartus graphics design entry?
(Not for coding, your verilog coding will stay the same, but, just to wire your verilog modules to the IO pins and potentially a few xxxx.v modules together. This will allow you to easily drop in or take out modules or remove them on the fly and see how your graphics pipe is affected as well as the CPU interface. It will allow you to easily invert IO pins, or, enable a global PLL. You can always make a now top hierarchy later-on, or, even tell quartus automatically generate you a top 'MyProject.v' verilog code of your illustrated schematic. Quartus has a feature to automatically generate a design block of each of your 'xxxx.v' source codes which you may place within your schematic layout, including multiple instances. )

@nockieboy, some questions:
1. Do you have an oscilloscope?Yes. It's barely up to anything (and my skills using it are also pretty poor - remember, I'm not an electronics engineer and this isn't my day job!) but it's a 20 MHz Hitachi V-212. I got it cheap off eBay a year or two back when I was breadboard-prototyping my Microcom and didn't know that a logic analyser would have been far more useful.
Check the hsync and vsync being sent to your monitor. Make sure the pulse is clean and at least 4v p-p. Preferably 5v. If you are driving your monitor with a 3.3v-3.6v hsync, it may do some funny things... This is random based on the monitor's internal circuitry.

If the sync it too low, IE you are driving the monitor HS/VS with an FPGA IO directly, there are 2 thing you will need to try.
1> buffer the signal through a 74HC04 inverter, or 74HC245 buffer powered with 5v. I like to drive the HS and VS into 3 gates each in parallel, and tie each of the 3 outputs in parallel to get a good current output to drive the monitor cable.
If you use 2 channels, placing 1 probe on hsync and the second on a R/G/B pin, you should see if you get a regular pattern or not.



If electronics are not your main thing then you are actually doing pretty well since FPGAs are pretty far from regular programming.
An oscilloscope is one of the most useful tools for debugging electronics, no other tool gives the same deal of universal insight into what circuits are doing. You do usually want to have a digital scope for digital circuits so that you can one shot capture communication buses and decode them. But video luckily involves stable repeating patterns so a analog scope can still be quite useful when triggered from vsync or hsync.

But there is a trick with FPGAs. You can build a logic analyzer in the same chip as the cirucit. Quartus has a tool for doing this called SignalTap:...
You give it a list of signals you want to monitor and how much memory to use and it generates a logic analyzer for that, taps off those signals and adds it to the design.
Well, that sorted the problem - thanks BrianHG!
Clearly my monitor wasn't happy with the 3.3v sync signals - I found a 74AHC541 in my box of bits and am now running the vertical and horizontal sync signals through one of these line drivers powered at 5v and am getting a nice stable output:
It's surprising how pleased I am at getting four overlapping squares to display on a monitor!!! Haha!
HCT is actually better for converting the FPGA 3.3v to 5v since it's inputs have a trigger threshold at TTL levels instead of mid 5v, or 2.5v. Any will work, like 74HCT, 74ACT, and other variants. (You would have never figured this one out without me. This one nearly destroyed a huge demo I had 10 years ago since my home test monitors were studio grade monitors whose sync inputs would work perfectly with a 0.7vp-p sync... The cheap PC screens didn't like that 3.3v.)
You should be thinking of making your own character generator, but first, you need to clean up your sync generator.

In Quartus, making a 'New' block diagram file is a key feature, not a hidden one.
Setting that .bdf (block diagram file) as the top hierarchy is also standard.



