Author Topic: FPGA VGA Controller for 8-bit computer  (Read 510744 times)

0 Members and 29 Guests are viewing this topic.

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 8143
  • Country: ca
    • LinkedIn
Re: FPGA VGA Controller for 8-bit computer
« Reply #1625 on: September 07, 2020, 04:09:34 pm »
You need to proceed and simulate in these steps to make you life possible:

First, worry about getting a single line generator working and simulating in place of the original one.  DONE!

Next worry about getting the linegen to recognize that the beginning and ending coordinates are on the same point bypassing everything else and just drawing the dot. Done.

Then worry about controlling the linegens to step/advance a Y coordinate at a time with pre-sorted coordinates coming from the Z80. Simulate and test what I sent you...

Then worry about wiring 3 of them together and controlling them with pre-sorted coordinates from the Z80.  Time to do this one.

Then worry about enabling the fill.

Then worry about sorting the coordinates to the 3 triangles in the geometry unit.

Then worry about making the linegens process all other shapes except ellipses.
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #1626 on: September 08, 2020, 07:59:20 am »
Before this, you need to re-test the new attached project's line command, with and without the Y_stopped feature.  Once verified, we will add 2 additional linegens and generate your first triangle.

Two pictures attached - first one is the new linegen with Y-stop disabled.  The second is with Y-stop enabled (as per the test bench, with ~y_stopped into the ena_stop_y input).  Both are identical.  :-+

 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #1627 on: September 08, 2020, 10:52:16 am »
So, this is how I see it working:
  • Run linegens #1 and #2 until next Y_stop
  • If fill enabled and empty pixels between the two lines, use linegen#3 to draw a raster line between the two points
  • If #2 has reached the end, reset it to draw from second point to the last point
  • Has #1 reached the end? No - loop back to No.1 above, otherwise triangle is complete
I realise it's a compressed version of what's going on in geo.bas, it's more of an overview than anything else as it raises a big question in my mind; namely, point number 3. It's going to be expensive to have another set of 12-bit X/Y coordinate registers to pipe X[1]Y[1],X[2]Y[2] into them to feed linegen#2, then I'll lose a clock cycle when linegen#2 completes the second line and switches over to the third line, as the new coordinates are clocked into its registers.  Or maybe it's not expensive at all and it's a better option than having another linegen?  :-//
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 8143
  • Country: ca
    • LinkedIn
Re: FPGA VGA Controller for 8-bit computer
« Reply #1628 on: September 08, 2020, 04:56:46 pm »
So, this is how I see it working:
  • Run linegens #1 and #2 until next Y_stop
  • If fill enabled and empty pixels between the two lines, use linegen#3 to draw a raster line between the two points
  • If #2 has reached the end, reset it to draw from second point to the last point
  • Has #1 reached the end? No - loop back to No.1 above, otherwise triangle is complete
I realise it's a compressed version of what's going on in geo.bas, it's more of an overview than anything else as it raises a big question in my mind; namely, point number 3. It's going to be expensive to have another set of 12-bit X/Y coordinate registers to pipe X[1]Y[1],X[2]Y[2] into them to feed linegen#2, then I'll lose a clock cycle when linegen#2 completes the second line and switches over to the third line, as the new coordinates are clocked into its registers.  Or maybe it's not expensive at all and it's a better option than having another linegen?  :-//

Close, as in do not worry about the extra 2 clock cycles as linegen swaps from xy[0]-xy[1] to xy[1]-xy[2].

Ok, we have 3 coordinates. xy[0,1,2].
For now, we will always assume xy[0] has the lowest Y coordinate and, xy[2] has the highest Y coordinate.
This means our master first linegen #1 will run A-B from xy[0] to xy[2].
For now, hard wire these in.
Our second linegen #2 will run A-B from xy[0] to xy[1].
Once it has reached xy[1], then, it will run A-B from xy[1] to xy[2].
For now, hard wire linegen #2 A-B from xy[0] to xy[1].

The xy outputs of the first linegen #1 output coordinates will feed the third linegen #3's A coordinates while the xy outputs of the second linegen #2 coordinates will feed the third linegen #3's B coordinates input.

The third linegen #3's output coordinates will now drive the pixel_cmd_ready and the actual plotting xy coordinates.

Procedure order:
1. Wireup the basics.

2. Only get linegen #1 to draw a line like now, except, the 'line_dat_rdy' will now be driving the 'pass_thru_a' on the linegen #3 and you should be able to still simulate and draw lines on the screen, except the line will now go from xy[0] to xy[2], not xy[0] to xy[1].  (YStop disabled.)

3. Next, when calling the line, start linegen #1 and let it draw waiting for the next Y step, then, start linegen #2 and let it draw waiting for the next Y step, then go back to linegen #1, then #2 and cycle until linegen #2 is finished, then let linegen #1 finish it's line.  This will construct only 2 faces of the triangle.

4. Next, when linegen #2 ends, swap and re-run it's coordinates so that it begins again A-B now from xy[1] to xy[2].  Then once setup, let it run until it has a matching Y coordinate and now continue cycling linegens #1 & #2 until both finish their lines.  If you have completed this process properly, you should be rendering an outline of a triangle.  Test a few triangles on the Z80, following the rule that the Y in xy[0] is the smallest Y of the 3 coordinates and the Y in xy[2] has the largest coordinates.


BONUS: Then worry about enabling the fill....

5. Fill.  If the fill bit is in the draw command is enabled, the current linegen loop:
           Until linegens #1,#2 end, loop (y_wait #1,y_wait #2)

Will now change to:
           Until linegens #1,#2 end, loop (y_wait #1,y_wait #2, run linegen #3 from A-B until linegen #3 ends)

Running this should now render filled triangles.

     If you haven't noticed yet, because of the wiring, just by altering the sequence rules you can render a single line, or by changing the coordinates feeding linegen #1 & #2, you can render boxes, filled boxes, or any 4 sided polygons.  But not yet.  This comes after: Then worry about sorting the coordinates to the 3 triangles in the geometry unit. as the coordinate selection process for linegen #1&#2 with sequence order will be built into that coordinate selection logic based on which geometry shape has been selected meaning this processing block could generate any draw function/shape except ellipses.
« Last Edit: September 08, 2020, 05:11:12 pm by BrianHG »
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #1629 on: September 09, 2020, 11:21:58 am »
Ok, we have 3 coordinates. xy[0,1,2].
For now, we will always assume xy[0] has the lowest Y coordinate and, xy[2] has the highest Y coordinate.
This means our master first linegen #1 will run A-B from xy[0] to xy[2].
For now, hard wire these in.
Our second linegen #2 will run A-B from xy[0] to xy[1].
Once it has reached xy[1], then, it will run A-B from xy[1] to xy[2].
For now, hard wire linegen #2 A-B from xy[0] to xy[1].

The xy outputs of the first linegen #1 output coordinates will feed the third linegen #3's A coordinates while the xy outputs of the second linegen #2 coordinates will feed the third linegen #3's B coordinates input.

The third linegen #3's output coordinates will now drive the pixel_cmd_ready and the actual plotting xy coordinates.

Okay, wired up as described above.

Procedure order:
1. Wireup the basics. DONE

2. Only get linegen #1 to draw a line like now, except, the 'line_dat_rdy' will now be driving the 'pass_thru_a' on the linegen #3 and you should be able to still simulate and draw lines on the screen, except the line will now go from xy[0] to xy[2], not xy[0] to xy[1].  (YStop disabled.)

Now I've hit a wall. |O  For some reason, I'm getting nothing out of the geo unit after the first pixel.  Initially I thought I'd got the wrong commands and X[2]Y[2] were empty, leading linegen#1 to end on the first pixel, but I've checked the commands and they seem to be okay.   As you can see in the attached simulation output, linegen#1 is working as draw_line is high, but it seems linegen#3 isn't happy about something - most probably I've made a silly wiring error, but I can't see it.

I'll keep looking and update if I fix it.  Latest versions of line_generator and geo_xy_plotter attached.
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 8143
  • Country: ca
    • LinkedIn
Re: FPGA VGA Controller for 8-bit computer
« Reply #1630 on: September 09, 2020, 04:31:35 pm »
Why are you toying with the perfect address generator?

You should concentrate on your issues with the 'geometry_xy_plotter.sv' and 'line_generator.sv'.

I would start with the fact that linegens #1 & #2 shouldn't even have the input pass-thru functions wired anywhere...
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #1631 on: September 09, 2020, 05:34:00 pm »
Why are you toying with the perfect address generator?

You should concentrate on your issues with the 'geometry_xy_plotter.sv' and 'line_generator.sv'.

I would start with the fact that linegens #1 & #2 shouldn't even have the input pass-thru functions wired anywhere...

Sorry - no I haven't been toying with PAGET at all - don't know why I attached that file (other than doing three things at once and not concentrating on this one!)

I meant to attach the line_generator, not PAGET.  |O

EDIT: Have removed the inputs to the pass-thrus on linegens #1 and #2, and removed pass_thru_b on linegen#3.  No change in the output.
« Last Edit: September 09, 2020, 05:54:59 pm by nockieboy »
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 8143
  • Country: ca
    • LinkedIn
Re: FPGA VGA Controller for 8-bit computer
« Reply #1632 on: September 09, 2020, 06:23:41 pm »
Pass thru shouldn't be dependent on a run commend...
Pass thru is a pass thru, not run a line from points A-B.

(on a few lines in line_gen)
 if ( run && ( pass_thru_a || ( aX == bX && aY == bY ) ) ) begin

Nor should it be stopped by any running Y function...
Same if both coordinates A&B are equal (only this one requires the 'run' but has no ystop action).  They should pipe through.

Also, in geometry line 232
linegen_3_start = linegen_1_start ; // necessary to allow linegen#3 to pass-through coordinates

Nope, make this 0 for now as this linegen module should only respond to passthrough commands.

Hopefully this should pass though linegen 1's commands.

« Last Edit: September 09, 2020, 06:25:32 pm by BrianHG »
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #1633 on: September 09, 2020, 07:19:34 pm »
Aha - okay, sorted those issues now.  Here's the latest output - looks okay....??  ???

 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 8143
  • Country: ca
    • LinkedIn
Re: FPGA VGA Controller for 8-bit computer
« Reply #1634 on: September 09, 2020, 08:02:30 pm »
Why is the pixel_cmd_rdy staying high?

Let me guess, you forgot to clear it once the pass through A/or/B goes low, right?
Something looks upsidedown...
« Last Edit: September 09, 2020, 08:04:03 pm by BrianHG »
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #1635 on: September 09, 2020, 10:14:55 pm »
Why is the pixel_cmd_rdy staying high?

Let me guess, you forgot to clear it once the pass through A/or/B goes low, right?
Something looks upsidedown...

Hmm.. I'm not sure what's going on.  Yes, I'd forgotten to clear pixel_cmd_rdy as you've said, but I added an edge-detect for when pass_thru_a goes low again to reset pixel_cmd_rdy, but it didn't seem to make a difference.  Seems draw_cmd_rdy and pixel_cmd_rdy is high shortly after reset clears, before any commands are sent at all (see attached output)?
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #1636 on: September 10, 2020, 08:09:49 am »
Okay, think I've fixed it.  Well, certainly the pixel_cmd_rdy being high all the time, anyway.  The offending code was line 92 in the line_generator module:
Code: [Select]
if ( pass_thru_a || ( aX == bX && aY == bY ) )begin
... should have been:
Code: [Select]
if ( pass_thru_a || ( run && ( aX == bX && aY == bY ) ) )begin
Also, I wasn't sure about line 230 in the line_generator module - looks like it would be setting pixel_data_rdy HIGH all the time if nothing else was being done...?
Code: [Select]
else  pixel_data_rdy <= 1'b1 ; // reset pixel_data_rdy flag - no more valid coordinates after this clock
Even the comment indicated it should RESET, not set... so I've changed that to 1'b0 instead.

Latest code and simulation output attached.
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 8143
  • Country: ca
    • LinkedIn
Re: FPGA VGA Controller for 8-bit computer
« Reply #1637 on: September 10, 2020, 08:36:03 am »
Ok, if the Z80 also creates a line on the screen, next make linegen 2 run after linegen 1 does a Y-stop.  Then once linegen 2 does a stop, go back to lingen 1.  Once linegen 2 finishes, continue linegen1 until it's finish.

You might as well make your logic so that if linegen1 finishes first, let linegen 2 finish.

Once working, make is so that when linegen2 finishes before linegen1, restart linegen2 with new coordinates and when it Y-stops, go back and forth finishing linegen1 & the new linegen2.  This should make a 3 face triangle.
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #1638 on: September 10, 2020, 11:15:28 am »
Works fine on the Z80.  Will push on with the next step.  It may be a couple of days before I can do anything.  :-+
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 8143
  • Country: ca
    • LinkedIn
Re: FPGA VGA Controller for 8-bit computer
« Reply #1639 on: September 10, 2020, 01:09:49 pm »
Hint: Choose 3 coordinates where you know what the results should look like on the simulation so it is easier to debug.

Like a vertical line for linegen1 and a 45 degree line, half height for linegen2...
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #1640 on: September 13, 2020, 04:08:28 pm »
I've had very little time to sit and work on this at all - this is how far I have got.  Doesn't run currently, as I'm thinking about how to get linegen#2 to start, but not at the same time as linegen#1 (which is what happens at the moment thanks to the combinational logic section).

Would appreciate any thoughts on my current implementation (am I on the right track?) and how best to start the second linegen one y-stop after the first.
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 8143
  • Country: ca
    • LinkedIn
Re: FPGA VGA Controller for 8-bit computer
« Reply #1641 on: September 13, 2020, 05:43:28 pm »
Think in this always_comb section:
Code: [Select]
    linegen_1_start = !reset && ( !fifo_cmd_rdy_n && ~geo_run ) && ( command_in[7:5] == 3'd0 && command_in[2:0] == 3'd1 ) ;  // for now, only the draw line command
    linegen_2_start = linegen_1_start ; // start with linegen_1
Maybe say:
Code: [Select]
    line_gen_starter =  !reset && ( !fifo_cmd_rdy_n && ~geo_run ) && ( command_in[7:5] == 3'd0 && command_in[2:0] == 3'd1 ) ;  // for now, only the draw line command

    linegen_1_start = line_gen_starter && !line_gen_2_running && !line_gen_1_running ; //  initiate linegen1 when lingen2 is not running.
    linegen_2_start = line_gen_starter && y_stopped_1 && !line_gen_2_running ;          // initiate linegen2 after linegen1 has it's first stop

    y_stop_en_1 = !y_stopped_2 ; // once linegen2 has stopped, continue linegen1  These might need another term
    y_stop_en_2 = !y_stopped_1 ; // once linegen1 has stopped, continue linegen2

I'm sure there is a logic bomb here, but as you can see I forced you to make all those linegen flag outputs so you could sequence the 3 linegens with nothing more than 2 or 3 combinational logic equations, or if the different shape make an equation too complex, you can use a look-up table to trigger actions.

You will most likely use a look-up table when deciding which xy[ # ] are selected for which linegen# and A/or/B position based on the selected drawing shape and 'tri_comp' module's in_a_gt_b[] and in_a_eq_b[] outputs.
 
Also, when drawing other shapes, this sequence may need additional enable/disable/blocking.

I have not looked at any of the other code you have done.  If you have attempted to do what I have above, it may all be trashed.

Now, we can switch the logic so you may start linegen 1&2 at the same time, but, have the lingens stop and wait for you to signal their advance before beginning to draw....
« Last Edit: September 13, 2020, 05:50:30 pm by BrianHG »
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #1642 on: September 15, 2020, 12:33:27 pm »
|O |O |O |O

I'm not giving up yet, but I've spent two days trying to get this to work and I'm getting nowhere with it, fast.

Linegen#1 should restart when linegen#2 stops after its first pixel.  I'm using an edge-detect on pixel_data_rdy from the other linegen to re-enable the y_stop and re-start the first linegen.  Doesn't seem to be working, though.

I've tried a couple of things, none of which work.  Any ideas where I'm going wrong?
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 8143
  • Country: ca
    • LinkedIn
Re: FPGA VGA Controller for 8-bit computer
« Reply #1643 on: September 15, 2020, 05:15:38 pm »
Please provide a copy of your full project so I can follow you...
« Last Edit: September 15, 2020, 05:26:31 pm by BrianHG »
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #1644 on: September 15, 2020, 05:36:23 pm »
Haven't tested the !geo amendment yet, but here's the test project.  The only changes I've made are to geo_xy_plotter.sv and a slight change to line_generator to make reset_stop_y go HIGH for one clock when ena_stop_y goes HIGH..

Project attached.
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 8143
  • Country: ca
    • LinkedIn
Re: FPGA VGA Controller for 8-bit computer
« Reply #1645 on: September 15, 2020, 06:20:26 pm »
Try changing line 79 in line_generator.sv to this:

      if ( !ena_stop_y ) begin

The way you had it, once the line has stopped, it would never start.
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #1646 on: September 15, 2020, 09:11:08 pm »
Try changing line 79 in line_generator.sv to this:

      if ( !ena_stop_y ) begin

The way you had it, once the line has stopped, it would never start.

Hmm.. okay, but the reset_stop_y that was in its place was supposed to go high for one clock when ena_stop_y transitioned from low to high, starting the line again.  Obviously that wasn't working.

Have attached simulation output with the change made as you've suggested.  Linegen#1 is now completing its line and y_stopping after each apparent change in Y coordinate (I say apparent, as I haven't tested it with multiple pixels on the same Y-coordinate yet).  However, it's only outputting the first pixel - none of the remaining pixels are sent to PAGET (pixel_data_rdy stays low after the first pixel).  As you can see, linegen#2 is stuck on the first pixel for some reason, but at least it keeps sending that pixel to PAGET.  I think this could be because busy and draw_line are going low before it finishes its line, so it's being reset each time it gets to draw a pixel?

Also, linegen#1 is not staying y_stopped whilst linegen#2 works, it just alternates between on and off each clock cycle once the first pixel is sent to PAGET.  Going to need to think about additional terms in the combinational logic for the y_stop_en signals, I think?

I'll try to have a closer look at this tomorrow.  :)
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 8143
  • Country: ca
    • LinkedIn
Re: FPGA VGA Controller for 8-bit computer
« Reply #1647 on: September 15, 2020, 09:40:25 pm »
Look:
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #1648 on: September 15, 2020, 10:03:34 pm »
Oh for Pete's sake!  |O

 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 8143
  • Country: ca
    • LinkedIn
Re: FPGA VGA Controller for 8-bit computer
« Reply #1649 on: September 16, 2020, 06:43:05 am »
Ok, I removed a heap of a mess in both the linegen and geometry_xy_plotter.
Get the attached files below.

My added comments arent too detailed, so read up and add comments and ask me questions why while I still have a bit of time left.

Run and test a simulation.
If it looks good, then try it on the Z80.

If everything is of, move onto making linegen2 automatically continue to close the triangle.

Then, worry about making linegen3 do the raster fills.

I already passed everything through linegen3 and setup 4 pointers:

    lgen_1a = 0;
    lgen_1b = 2;
    lgen_2a = 0;
    lgen_2b = 1;

Which select the starting coordinates for the first 2 linegens.

Once the triangle fills, you will need to edit the command numbers. We will want these commands:
0 = do nothing.
1 = place a pixel.  (Currently a line, or the triangle we are debugging.)
2 = draw a line.
3 = draw a triangle.
4 = draw a box
5 = draw a quadrilateral
6 = draw an ellipse
7 = draw a spline    (spare, may be used for something else).

These shapes should only manipulate the lines 256-257 for how & when to start & stop + added lingen3 if necessary, lines 244-246 for what starts when & lines  250-254 to tell the linegens 1&2 which coordinates to use to draw a line.

See lines 422+ in geometry_xy_plotter for the fill/paste/mask flags.
(paste enables the copy blitter algorithm module which will replace lines 309-315.)
(IE disabled, the module will match lines 309-315 passing the plot through, enabled, the module will do a rectangular set width & height CMD_OUT_PXCOPY from the source address & CMD_OUT_PXPASTE/_M the destination address centered on the received destination gen_3_x,gen_3_y coordinates passing the mask (_M) setting if it is set.)
« Last Edit: September 16, 2020, 06:52:16 am by BrianHG »
 
The following users thanked this post: nockieboy


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf