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

0 Members and 33 Guests are viewing this topic.

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 8143
  • Country: ca
    • LinkedIn
Re: FPGA VGA Controller for 8-bit computer
« Reply #1175 on: July 02, 2020, 12:25:06 pm »
Haven't encountered casez before, but certainly looks like a powerful and useful statement.  Clever coding as well, reducing all those previous case statements down to two lines to assign the 12-bit number to the appropriate x# and y#.  :clap:
As long as you understand that the '?' are don't care bits, and they can be spread out through the case#.
Also you understand that how I'm addressing the x&y array 0 through 3.  You will need to do something like this again when it comes to the pixel writer.
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #1176 on: July 02, 2020, 12:44:52 pm »
So, single line drawing:

Code: [Select]
        4'd1 : begin    // draw line from (x[0],y[0]) to (x[1],y[1])
       
            if ((geo_y != (y[1] + geo_ydir) and (geo_x != x[1] + geo_xdir)) begin
       
                draw_cmd_func        <= CMD_OUT_PXWRI[3:0]; // Set up command to pixel plotter to write a pixel,
                draw_cmd_data_color  <= geo_color;          // ... in geo_colour,
                draw_cmd_data_word_Y <= geo_y ;             // ... at Y-coordinate,
                draw_cmd_data_word_X <= geo_x ;             // ... and X-coordinate.
                draw_cmd_tx          <= 1'b1;               // send command (have moved this after the X, Y setting for easy reading)
               
                // increment x,y position
               
       
            end else begin  // end of line
           
                geo_run         <= 1'b0;
                draw_cmd_tx     <= 1'b0;
           
            end
       
        end // draw line

Got that far.  I need to create variables for dx, dy, errd and magic?  Where would be the best place for these?  I thought about assigning them in the same place as where geo_x and geo_y are given their starting values?  They may not be used for all the drawing functions, but it makes sense (to me at least)?
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 8143
  • Country: ca
    • LinkedIn
Re: FPGA VGA Controller for 8-bit computer
« Reply #1177 on: July 02, 2020, 01:26:03 pm »
Ok, the line algorithm has an extended setup, so you need to think of the code running in 2 hunks.

Back at the initialization section, at line 221-222, I prepared 2 variable to allow you to make such sequences just in case:
Code: [Select]
                geo_sub_func1        <= 4'b0;           // for geometric engines which have multiple phases, reset the phase counter
                geo_sub_func2        <= 4'b0;           // for geometric engines which have 2 dimensional multiple phases, reset the phase counter

Now, this is how you would start your line code:

Code: [Select]
  4'd1 : begin    // draw line from (x[0],y[0]) to (x[1],y[1])
       
case(geo_sub_func1) // During the draw line, we have multiple sub functions to call 1 at a time

4'd0 : begin  //(case sub_function=0)  **** Initialize line parameters

/*  do this setup function 0
    dx = x1 - x0
    dy = y1 - y0
*/
geo_sub_func1 <= 4'd1 ;  // switch over to the next function
end // (case sub_function=0)

4'd1 : begin  //(case sub_function=1)  **** Second Initialize line parameters
   
/*  Do this setup function next
   if (dx < 0) Then
        dx = -dx
        sx = -1
    Else
        sx = 1
    End If
   
    if (dy > 0) Then
        dy = -dy
        sy = 1
    Else
        sy = -1
    End If
*/

geo_sub_func1 <= 4'd2 ;  // switch over to the next function
end // (case sub_function=1)

4'd2 : begin  //(case sub_function=0)  **** Initialize line parameters

/*  do this setup function last
    magic = 0
    errd  = dx + dy
    x     = x0
    y     = y0
    is_done = FALSE ********* do not bother with is_done, use 'geo_run' instead.  It is already set and you clear it to break the function.
*/

geo_sub_func1 <= 4'd3 ;   // setup done, switch over to the next function, drawing the actual line
end // (case sub_function=2)



4'd3 : begin  //(case sub_function=3) Draw the line
            if ( (geo_y != (y[1] + geo_ydir)) && (geo_x != (x[1] + geo_xdir)) ) begin
       
                draw_cmd_func        <= CMD_OUT_PXWRI[3:0]; // Set up command to pixel plotter to write a pixel,
                draw_cmd_data_color  <= geo_color;          // ... in geo_colour,
                draw_cmd_data_word_Y <= geo_y ;             // ... at Y-coordinate,
                draw_cmd_data_word_X <= geo_x ;             // ... and X-coordinate.
                draw_cmd_tx          <= 1'b1;               // send command (have moved this after the X, Y setting for easy reading)
               
                // increment x,y position
               
       
            end else begin  // end of line
           
                geo_run         <= 1'b0;
                draw_cmd_tx     <= 1'b0;
           
              end

end // (case sub_function=3) drawing the line.

endcase // ending case the multiple sub functions of draw line
       
        end // end of draw line

Now, this is a baby step that I broke down the basic code into ordered sequences which can be done in parallel.
You will need 'signed regs' for the dx,dy,errd,magic.

I coded it this way so you can see, test, and simulate what is happening an be sure of the results.  Step by step.  (Remember, in the simulation waveform, you can add internal hidden variables to the waveform view.  You can even add analog 'oscilloscope' view of any regs.  (I'm expecting a sine wave when plotting a circle))

However, with this setup, there are 3 additional system clocks going before the line begins to plot.  Once you can draw a line properly, you would want to shrink this down to 1 clock.  IE step 0 = setup, step 2 = drawing line.  Note that it is possible to do the variable setup instantly with an ugly big Boolean equation, but, for a Z80 at 20MHz, I don't think we need to worry about 1 clock at 125MHz.


« Last Edit: July 02, 2020, 01:37:48 pm by BrianHG »
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #1178 on: July 02, 2020, 01:39:29 pm »
Ah, I'd already started working on the setup before I read your last post.  Do we need sx and sy?  I was thinking I could use geo_xdir and geo_ydir for these?  I'd also obtained the absolute values for dx and dy like this:

Code: [Select]
dx              <= (x[1]>x[0]) ? (x[1]-x[0]) : (x[0]-x[1]); // get absolute size of delta-x
dy              <= (y[1]>y[0]) ? (y[1]-y[0]) : (y[0]-y[1]); // get absolute size of delta-y
 

Offline asmi

  • Super Contributor
  • ***
  • Posts: 2839
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #1179 on: July 02, 2020, 01:45:30 pm »
Hey guys! Do you have full HDL sources for this project? I'm curious if it can be ported to Xilinx/Vivado and Lattice platforms without major changes. I noticed you are using schematics for the top level, but if my memory serves me (it's been a while since I used Quartus) it can generate an actually HDL file that reflects what's on schematic.

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #1180 on: July 02, 2020, 01:52:25 pm »
Hey guys! Do you have full HDL sources for this project? I'm curious if it can be ported to Xilinx/Vivado and Lattice platforms without major changes. I noticed you are using schematics for the top level, but if my memory serves me (it's been a while since I used Quartus) it can generate an actually HDL file that reflects what's on schematic.

Full project is available here:)
 
The following users thanked this post: asmi

Offline asmi

  • Super Contributor
  • ***
  • Posts: 2839
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #1181 on: July 02, 2020, 02:29:06 pm »
Full project is available here:)
Thanks!
I tried importing it to Vivado, and as I suspected top level HDL file is missing, and I don't have Quartus to see if I can generate it :(
Well it was worth the shot.

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #1182 on: July 02, 2020, 02:36:07 pm »
Full project is available here:)
Thanks!
I tried importing it to Vivado, and as I suspected top level HDL file is missing, and I don't have Quartus to see if I can generate it :(
Well it was worth the shot.

The top-level repo isn't actually a Quartus project - there's several Quartus projects in various folders.  EP4CE10 is the one to look in for the Quartus project, but you're right, there's no top level HDL file, just a design/schematic.
 

Offline asmi

  • Super Contributor
  • ***
  • Posts: 2839
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #1183 on: July 02, 2020, 02:41:26 pm »
The top-level repo isn't actually a Quartus project - there's several Quartus projects in various folders.  EP4CE10 is the one to look in for the Quartus project, but you're right, there's no top level HDL file, just a design/schematic.
Yes I figured it out as I still remember what Quartus project looks like. Can you see if you can somehow generate HDL file from that schematic?

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #1184 on: July 02, 2020, 02:53:11 pm »
The top-level repo isn't actually a Quartus project - there's several Quartus projects in various folders.  EP4CE10 is the one to look in for the Quartus project, but you're right, there's no top level HDL file, just a design/schematic.
Yes I figured it out as I still remember what Quartus project looks like. Can you see if you can somehow generate HDL file from that schematic?

Hmmm.. it seems I can, but I'm getting errors from Quartus about illegal characters in the design file and illegal pins in the Verilog HDL.  I don't know if @BrianHG might have more luck or suggestions?
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #1185 on: July 02, 2020, 02:58:22 pm »
Here's my latest code for the line drawing (attached as file at bottom).

I can't get it to work properly, having tried a number of variations on the code.  geo_x seems to be incrementing/decrementing properly, but geo_y isn't after the first loop.  :-//

1015152-0

Oh,  also had to modify the setup of geo_xdir and geo_ydir a little to account for horizontal and vertical lines (neutral x or y increments):

EDIT:
One problem seems to be that I got the sign wrong on calculating dy - should be:
Code: [Select]
dy              <= (y[0]>y[1]) ? (y[1]-y[0]) : (y[0]-y[1]); // get absolute size of delta-y
1015162-1

Now geo_y is updating, but we're not reaching x[1]y[1] at the same time.
« Last Edit: July 02, 2020, 03:13:32 pm by nockieboy »
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 8143
  • Country: ca
    • LinkedIn
Re: FPGA VGA Controller for 8-bit computer
« Reply #1186 on: July 02, 2020, 04:19:38 pm »
Ok, if you take a look at the basic code, remember, these lines are happening forward 1 after the other:
Code: [Select]
      magic = errd shl 1
      if (magic > dy) Then
         errd += dy
         x    += sx
      End If
       
      if (magic < dx) Then
         errd += dx
         y    += sy
      End If

This means if you want to make the verilog equivalent, like the beginning startup, you will need to make a second sub 'geo_sub_func#2'.  Doing it this way, I bet you can get it to work, 1 ploted pixel would come out every 3 clock cycles.

If you want, attempt this strategy first.  I'm sure you will get it to work.  The real magic comes if you make a code which will plot a pixel every single clock cycle.  I've tested my magic functional code, I'll upload it if you give up.  For now, here is some light to send you in the right direction:

Code: [Select]
                    // increment x,y position
                    //magic       <= errd << 1; ************ Remember, this takes 1 clock cycle for magic to have the result
                    if ( (errd << 1) > dy) begin  // havind the '(errd << 1)' inside the if means it's checking the immediate number, not 1 clock delayed number

Note: Getting the rest is not as easy it may seem, but, the final result is fairly simple and should correctly plot a new pixel every single clock cycle.  The output should match the geo.bas.  (I attached one where I print the line coordinates on the screen.)

« Last Edit: July 03, 2020, 12:45:25 am by BrianHG »
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 8143
  • Country: ca
    • LinkedIn
Re: FPGA VGA Controller for 8-bit computer
« Reply #1187 on: July 02, 2020, 05:00:47 pm »
Just in case you were wondering about my 'magic' code compared to geo.bas, with an uneven line, see sim here:
1015260-0
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #1188 on: July 02, 2020, 09:15:32 pm »
No worries - will have to take a look at this tomorrow now, I've had an unexpectedly busy evening and not been able to even look at this!  ::)
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #1189 on: July 03, 2020, 08:45:04 am »
Ok, if you take a look at the basic code, remember, these lines are happening forward 1 after the other:
Code: [Select]
      magic = errd shl 1
      if (magic > dy) Then
         errd += dy
         x    += sx
      End If
       
      if (magic < dx) Then
         errd += dx
         y    += sy
      End If

This means if you want to make the verilog equivalent, like the beginning startup, you will need to make a second sub 'geo_sub_func#2'.  Doing it this way, I bet you can get it to work, 1 ploted pixel would come out every 3 clock cycles.

Ah, of course, I'd forgotten that rather important feature of HDL...  :palm:

If you want, attempt this strategy first.  I'm sure you will get it to work.  The real magic comes if you make a code which will plot a pixel every single clock cycle.  I've tested my magic functional code, I'll upload it if you give up.  For now, here is some light to send you in the right direction:

Code: [Select]
                    // increment x,y position
                    //magic       <= errd << 1; ************ Remember, this takes 1 clock cycle for magic to have the result
                    if ( (errd << 1) > dy) begin  // havind the '(errd << 1)' inside the if means it's checking the immediate number, not 1 clock delayed number

Note: Getting the rest is not as easy it may seem, but, the final result is fairly simple and should correctly plot a new pixel every single clock cycle.  The output should match the geo.bas.  (I attached one where I print the line coordinates on the screen.)

Okay, have plugged away at this over several iterations now and am still getting exactly the same output in the simulation. :(

My code is below - I've tried to go for gold and get the single-cycle pixel output, but it's not working.  geo_y isn't incrementing at the correct rate and neither geo_x or geo_y are hitting x[1] or y[1] at the same time, causing the line to carry on forever.

Code: [Select]
4'd2 : begin

draw_cmd_func        <= CMD_OUT_PXWRI[3:0]; // Set up command to pixel plotter to write a pixel,
draw_cmd_data_color  <= geo_color;          // ... in geo_colour,
draw_cmd_data_word_Y <= geo_y ;             // ... at Y-coordinate,
draw_cmd_data_word_X <= geo_x ;             // ... and X-coordinate.
draw_cmd_tx          <= 1'b1;               // send command (have moved this after the X, Y setting for easy reading)

if (geo_x == x[1] && geo_y == y[1]) begin  // end of line
geo_run         <= 1'b0;
draw_cmd_tx     <= 1'b0;
end

// increment x,y position
if ((errd << 1) > dy) begin

errd    <= errd + dy;
geo_x   <= geo_x + geo_xdir;

if (((errd+dy)<<1) < dx) begin

errd    <= errd + dx;
geo_y   <= geo_y + geo_ydir;

end

end else if ((errd << 1) < dx) begin

errd    <= errd + dx;
geo_y   <= geo_y + geo_ydir;

end

end

I can't figure out how to get the increment x,y position block to execute in a single cycle.  |O
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #1190 on: July 03, 2020, 08:48:26 am »
Ah, hang on - GOT IT!  ;D

Those if...endifs require some lateral thought to convert to a fully parallel system like HDL.  :o

1015512-0
« Last Edit: July 03, 2020, 08:50:54 am by nockieboy »
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 8143
  • Country: ca
    • LinkedIn
Re: FPGA VGA Controller for 8-bit computer
« Reply #1191 on: July 03, 2020, 08:51:39 am »
You arent plotting the last pixel....
This is my version:
Code: [Select]
                    // increment x,y position
                    //magic       <= errd << 1; ************ Remember, this takes 1 clock cycle for magic to have the result
                    if ( (errd << 1) > dy) begin  // havind the '(errd << 1)' inside the if means it's checking the immediate number, not 1 clock delayed number

geo_x   <= geo_x + geo_xdir;

if ( ((errd << 1) + dy) < dx)  begin
errd    <= errd + dy + dx;
geo_y   <= geo_y + geo_ydir;
end else errd    <= errd + dy;
 
                    end else if ( (errd << 1) < dx) begin
errd    <= errd + dx;
geo_y   <= geo_y + geo_ydir;
end
               
                end

You still need to plot the last pixel...
« Last Edit: July 03, 2020, 08:56:30 am by BrianHG »
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #1192 on: July 03, 2020, 08:53:45 am »
You arent plotting the last pixel....

Yes, I've spotted that - just looking into it.

Is that going to need another geo_sub_func1 stage to execute the draw command for the last pixel?
« Last Edit: July 03, 2020, 08:55:34 am by nockieboy »
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 8143
  • Country: ca
    • LinkedIn
Re: FPGA VGA Controller for 8-bit computer
« Reply #1193 on: July 03, 2020, 08:59:41 am »
You arent plotting the last pixel....

Yes, I've spotted that - just looking into it.

Is that going to need another geo_sub_func1 stage to execute the draw command for the last pixel?

Try this:
Code: [Select]
                    if (geo_x == x[1] && geo_y == y[1]) begin  // end of line
                        //geo_run         <= 1'b0;
                        //draw_cmd_tx     <= 1'b0;
                        //geo_sub_func1     <= 4'd3;  // On the next clock, run the stop-drawing-line function.
                        geo_shape         <= 4'd0;  // On the next clock, end the stop-drawing-line function.
                    end
Code: [Select]
           default : begin
geo_run         <= 1'b0; // no valid drawing engine selected, so stop the geo_run flag.
draw_cmd_tx     <= 1'b0; // no valid drawing engine selected, so make sure draw_cmd_tx is disabled.
end
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 8143
  • Country: ca
    • LinkedIn
Re: FPGA VGA Controller for 8-bit computer
« Reply #1194 on: July 03, 2020, 09:00:25 am »
Also simulate your line with an odd angle to make sure...
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #1195 on: July 03, 2020, 09:10:06 am »
Yeah, that seems to work just fine.  :-+

I noticed my code is slightly different to yours, though?
Code: [Select]
// increment x,y position
if ((errd << 1) > dy) begin
   
if (((errd+dy)<<1) < dx) begin

errd    <= errd + dx + dy;
geo_y   <= geo_y + geo_ydir;
geo_x   <= geo_x + geo_xdir;

end else begin

errd    <= errd + dy;
geo_x   <= geo_x + geo_xdir;

end

end else if ((errd << 1) < dx) begin

errd    <= errd + dx;
geo_y   <= geo_y + geo_ydir;

end

Hoping the differences are cosmetic.  ???
« Last Edit: July 03, 2020, 09:13:50 am by nockieboy »
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #1196 on: July 03, 2020, 09:12:52 am »
Never mind, it was cosmetic.  I hadn't streamlined the code and removed the unnecessary 'geo_x <= geo_x + geo_xdir' lines from the first nested if conditional.  Sorted now.

Have simulated with a variety of random values, negatives and positives, and all appear to work fine.  :-+
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 8143
  • Country: ca
    • LinkedIn
Re: FPGA VGA Controller for 8-bit computer
« Reply #1197 on: July 03, 2020, 09:14:57 am »
Ok, next, the big fat circle...
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 8143
  • Country: ca
    • LinkedIn
Re: FPGA VGA Controller for 8-bit computer
« Reply #1198 on: July 03, 2020, 09:18:59 am »
Never mind, it was cosmetic.  I hadn't streamlined the code and removed the unnecessary 'geo_x <= geo_x + geo_xdir' lines from the first nested if conditional.  Sorted now.

Have simulated with a variety of random values, negatives and positives, and all appear to work fine.  :-+

LOL, in you code:

            default : begin
           
                geo_run         <= 1'b0; // no valid drawing engine selected, so stop the geo_run flag.
                geo_run         <= 1'b0;  AGAIN??? ^Look Up^
                draw_cmd_tx     <= 1'b0;
               
            end

 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #1199 on: July 03, 2020, 09:30:27 am »
D'oh!  Good old copy-paste errors!  ;D
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf