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

0 Members and 3 Guests are viewing this topic.

Offline BrianHG

  • Super Contributor
  • ***
  • Posts: 7747
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #1575 on: August 21, 2020, 05:24:58 pm »
I am talking about you making a module which takes in X[0..3] or Y[0..3] and returns all the point which are equal, greater than and less than in 3 arrays which can easily be checked/used to select which lingen should be used (IE: if all X & Y coordinates on the 3 vertices are equal, no lingen will be used, just draw a point), each of those linegen's source and destination X[?]&Y[?] coordinates and select whether to add or subtract the x&y counter (x&y dir) in each linegen module's arithmetic.

Hmm.. well, this is what I've got at the moment.  It's taken straight from the FreeBasic geo program to set up the order of lines to be drawn.  It's not what you're asking for though, by the looks of it.  It doesn't do the sign (x & y dir) yet, but I'm not sure I'm on the right path anway..... it sounds like you want a module that returns three arrays - equal, greater than and less than - with the coordinates ordered accordingly and a sign flag for the use of another module?
The idea is ok, but you have not identified a lot of useful information.  Like which of the other lines go to which points.  Are any coordinates equal so you might not have to use a triangle but draw a single line.  What about drawing boxes or filled boxes and 4 sided polygons.

Like I said, first make a module to construct a cross comparison of a group of 4 coordinates.  I want to know equality, greater than and less than.

Try this.

Code: [Select]
input           logic           clk
input signed logic [11:0] in [0:3]
output         logic [15:0] in_a_eq_b
output         logic [15:0] in_a_gt_b
output         logic [15:0] in_a_lt_b

parameter bit CLOCK_OUTPUT = 0;

now, make the rest so that it will be possible to clock latch or run as combinational logic the following logic:

Code: [Select]
for (int i = 0 ; i<=15 ; i++) begin
in_a_eq_b[i] = (in[i[3:2]] == in[i[1:0]]);
in_a_gt_b[i] = (in[i[3:2]] > in[i[1:0]]);
in_a_lt_b[i] = (in[i[3:2]] < in[i[1:0]]);
end

Now, having 2 modules like this, one for all X[n] and one for all Y[n], you have the status 3 status 16 bit words which you can use to select how and what each line generator will be using and which direction they will be counting and it doesn't matter which shape you are trying to draw as you set IF selection just chooses to look only at the status bits required to construct the shape you are trying to draw.
« Last Edit: August 21, 2020, 05:33:43 pm by BrianHG »
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #1576 on: August 21, 2020, 10:27:14 pm »
Potentially the only difference in the chips is the model identifier or some fuse setting? Interesting.
No fuse identifier.  Didn't you not see the jtag scan of the chip in the last post.  Quartus could not tell whether the installed FPGA it was scanning was an EP4CE10, or a EP4CE6.  Look at the picture in the last post.  In fact, it also couldn't tell in that same FPGA was a CycloneIII EP3C5 or EP3C10.

No, I missed that as I was looking at the linked posts on my phone.  Well, that's interesting if the Cyclone 5's two lowest devices are the same, as there's about £20 difference between them.  The A2 would be fine for what I need with ~170KB of RAM and 25,000 LEs, but if I could squeeze the extra 24,000 LEs and extra 132 KB of RAM out of it instead of buying an A4, that would be a win.  Either way, jumping up a generation to Cyclone V would appear to solve a lot of memory issues.
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #1577 on: August 23, 2020, 10:07:56 am »
I'm falling behind badly - been a busy few days and there's no let up next week either.  :-\

I've completed the comparison module just now - code attached to make sure I've done it right - it compiles, which is a start.  ;)
 

Offline BrianHG

  • Super Contributor
  • ***
  • Posts: 7747
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #1578 on: August 23, 2020, 06:01:01 pm »
Just place it at the bottom of the 'geometry_xy_plotter.sv' module.
At the top, add in 2 instances, 1 for comparing the X[n] and one fore comparing the Y[n]

This line should read:

   input  signed [3:0][11:0] in,

   input  logic signed [11:0] in [0:3],

I am not sure the way you did the 'IF' and 'CLOCK_OUTPUT' will work without problems, but, we will see.


Next, the line gen modules.

We want to try to make 1 module to work in all situations.
A begin line which loads all the chosen X&Y variables.
A pass-through A input, this will pass the Ax,Ay coordinates right to the output and not engage any line drawing with the begin line function.
A pass-through B input. Same as above.
An input aX/Y and bX/Y for beginning and ending.
Has a smart pass through.  Meaning if the same beginning and ending point coordinates are at the inputs, just pass through the coordinates to write a single pixel and signal that the line is finished.
Has an enable option to draw until a specified Y coordinate has been reached.  (For raster fills on a chosen Y axis)
Has a 'Y stop' signed input to define that stopping Y coordinate.  This input is live and once changed during a stop, the linegen will continue until the new new Y coordinate has been reached or the line has reached it's end.  If we are on the last Y coordinate, to finish drawing the line, either the final Y coordinate may increase outside the Y drawing area or the Y stop enable flag may be turned off.

Outputs, X/Y coordinates.
Draw pixel data ready.
stopped on Y coordinate flag.
Finished drawing the line.

This should help you define our new line gen 'module'.
We will use 3 of them.  The first 2 line gens draw/generate the outer edge coordinates of our shape while the output of those 2 feed the coordinate inputs of the third lengen module so it may draw a line between the 2 source linegens.  With this setup, not only can we manipulate the line 3 line gens into drawing filled or un-filled triangles, but, boxes and 4 sided polygons as well just by setting up the starting conditions and when linegens 1&2 stop and go on new Y coordinates telling linegen 3 where and when to fill, or just run when 1&2 begin and finish creating an outline of a box instead of filling it.

Your compare module tells you before you begin either the draw point order for triangles, or if a vertical or horizontal line is being drawn so you do not need to do any filling.

Since we are in a crunch for time, we will do the blitter after this works.  You will need to solve the ellipse on your own after that.  The only thing I can offer is that you can make the linegens also generate ACRs, but if you are not comfortable, you can make a discrete module.
« Last Edit: August 23, 2020, 06:36:53 pm by BrianHG »
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #1579 on: August 24, 2020, 10:05:35 am »
Just place it at the bottom of the 'geometry_xy_plotter.sv' module.
At the top, add in 2 instances, 1 for comparing the X[n] and one fore comparing the Y[n]

Okay - any hints on what should be attached to the inputs / outputs yet, or does that depend on the next module being built?

This line should read:

   input  signed [3:0][11:0] in,

   input  logic signed [11:0] in [0:3],

I built the module in Quartus II and it threw errors if I used 'input logic signed', so I did some research online and arrived at 'input signed' instead.  It does appear that 'input logic signed' compiles with no errors in Quartus Prime, soo...  :-//

I am not sure the way you did the 'IF' and 'CLOCK_OUTPUT' will work without problems, but, we will see.

Me neither, but we'll see.  I'm hoping the compiler detects that the conditional is based on a compile-time setting and won't change during use, so it'll only synthesise the logic for one branch or the other.

I did have a quick look for conditional-compilation commands in SystemVerilog, but didn't find anything immediately obvious (probably because I should have been looking at Quartus, rather than SystemVerilog itself), but it compiles - I was expecting a 'signal has multiple drivers' error or something similar.

Next, the line gen modules.

We want to try to make 1 module to work in all situations.

So does this replace or part-replace the geo_xy_plotter module?  Seems I'll be removing some of the linegen stuff from geo_xy_plotter and moving it to this new module?

A begin line which loads all the chosen X&Y variables.
A pass-through A input, this will pass the Ax,Ay coordinates right to the output and not engage any line drawing with the begin line function.
A pass-through B input. Same as above.
An input aX/Y and bX/Y for beginning and ending.
Has a smart pass through.  Meaning if the same beginning and ending point coordinates are at the inputs, just pass through the coordinates to write a single pixel and signal that the line is finished.
Has an enable option to draw until a specified Y coordinate has been reached.  (For raster fills on a chosen Y axis)
Has a 'Y stop' signed input to define that stopping Y coordinate.  This input is live and once changed during a stop, the linegen will continue until the new new Y coordinate has been reached or the line has reached it's end.  If we are on the last Y coordinate, to finish drawing the line, either the final Y coordinate may increase outside the Y drawing area or the Y stop enable flag may be turned off.

Outputs, X/Y coordinates.
Draw pixel data ready.
stopped on Y coordinate flag.
Finished drawing the line.

So something starting like this?

Code: [Select]
module line_generator (

  input logic [3:0][11:0]   aX,
  input logic [3:0][11:0]   aY,
  input logic [3:0][11:0]   bX,
  input logic [3:0][11:0]   bY,
  input logic               raster_fill,
  input signed logic [11:0] Y-stop,

  output logic [3:0][11:0]  aX_passthru,
  output logic [3:0][11:0]  bX_passthru,
  output logic [11:0]       X_coord,
  output logic [11:0]       Y_coord,
  output logic              pixel_data_rdy

);

This should help you define our new line gen 'module'.
We will use 3 of them.  The first 2 line gens draw/generate the outer edge coordinates of our shape while the output of those 2 feed the coordinate inputs of the third lengen module so it may draw a line between the 2 source linegens.  With this setup, not only can we manipulate the line 3 line gens into drawing filled or un-filled triangles, but, boxes and 4 sided polygons as well just by setting up the starting conditions and when linegens 1&2 stop and go on new Y coordinates telling linegen 3 where and when to fill, or just run when 1&2 begin and finish creating an outline of a box instead of filling it.

Your compare module tells you before you begin either the draw point order for triangles, or if a vertical or horizontal line is being drawn so you do not need to do any filling.

Since we are in a crunch for time, we will do the blitter after this works.  You will need to solve the ellipse on your own after that.  The only thing I can offer is that you can make the linegens also generate ACRs, but if you are not comfortable, you can make a discrete module.

Sorry, I'm going to need more of a steer on this module - and the blitter after it - if I'm to get this done by the end of the week.  Trying to multitask between this and work just isn't working out for me that well.  :(
 

Offline BrianHG

  • Super Contributor
  • ***
  • Posts: 7747
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #1580 on: August 24, 2020, 04:50:47 pm »
option #1
Code: [Select]
module line_generator (

  input logic           clk,
  input logic           reset,   // loads the numbers and begins drawing the line.

  input logic signed [11:0]   X [0:3],
  input logic signed [11:0]   Y [0:3],
  input logic           [1:0]   sel_a,     // selects which X&Y for the beginning of the line.
  input logic           [1:0]   sel_b,     // selects which X&Y for the ending of the line.  If sel_A&B are equal,
                                                   // or different but the stored coordinates match, no line drawn, just the
                                                   // output should immediately draw 1 pixel at those coordinates.

  input logic                  ena_stop_ypos,
  input logic signed [11:0]    stop_ypos,

  output logic signed [11:0]   X_coord,
  output logic signed [11:0]   Y_coord,
  output logic                 pixel_data_rdy,

  output logic        ypos_stopped,
  output logic        line_complete
);


option #2
Code: [Select]
module line_generator (

  input logic           clk,
  input logic           reset,  // loads the numbers and begins drawing the line.

  input logic signed [11:0]   aX,
  input logic signed [11:0]   aY,
  input logic signed [11:0]   bX,
  input logic signed [11:0]   bY,

  input logic                  ena_stop_ypos,
  input logic signed [11:0]    stop_ypos,

  output logic signed [11:0]   X_coord,
  output logic signed [11:0]   Y_coord,
  output logic                 pixel_data_rdy,

  output logic        ypos_stopped,
  output logic        line_complete
);

Go with option #2 please.
The module's inputs just have the 'SELA/B' at the input port.
This makes like easier to tie the top 2 linegens' outputs into the third linegen's single A/B inputs.
« Last Edit: August 24, 2020, 04:56:34 pm by BrianHG »
 

Offline BrianHG

  • Super Contributor
  • ***
  • Posts: 7747
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #1581 on: August 24, 2020, 05:24:48 pm »
Little addition:
Code: [Select]
module line_generator (

  input logic           clk,
  input logic           run_line,  // low=loads the numbers, high = begins drawing the line.
  input logic           pass_thru_a,
  input logic           pass_thru_b,

  input logic signed [11:0]   aX,
  input logic signed [11:0]   aY,
  input logic signed [11:0]   bX,
  input logic signed [11:0]   bY,

  input logic                  ena_stop_ypos,
  input logic signed [11:0]    stop_ypos,

  output logic signed [11:0]   X_coord,
  output logic signed [11:0]   Y_coord,
  output logic                 pixel_data_rdy,

  output logic        ypos_stopped,
  output logic        line_complete
);
« Last Edit: August 24, 2020, 05:56:06 pm by BrianHG »
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #1582 on: August 25, 2020, 08:46:41 am »
Right okay, so I need to strip out the linegen code from the geo_xy_plotter module and work it into this new module?

Code: [Select]
case (geo_sub_func1)    // during the draw line, we have multiple sub-functions to call 1 at a time

                     4'd0 : begin
                 
                        errd            <= dx + dy;
                        geo_sub_func1   <= 4'd1;                 // set line sub-function to plot line.
                           
                     end // geo_sub_func1 = 0 - setup for plot line

                     4'd1 : 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.

                        if ( ( geo_x >= 0 && geo_x <= max_x ) && (geo_y>=0 && geo_y<=max_y) )
                        draw_cmd_tx     <= 1'b1;            // send command if geo_X&Y are within valid drawing area
                        else
                        draw_cmd_tx     <= 1'b0;            // otherwise turn off draw command

                        if ( geo_x == x[1] && geo_y == y[1] ) geo_shape <= 4'd0;   // last pixel - step to last sub_func1 stage, allowing time for this pixel to be written
                                                                                 // On the next clock, end the drawing-line function
                         
                        // increment x,y position
                        if ( ( errd << 1 ) > dy ) begin
                       
                          geo_x   <= geo_x + geo_xdir;
                                         
                          if ( ( ( errd << 1 ) + dy ) < dx ) begin
                         
                              geo_y   <= geo_y + geo_ydir ;
                              errd    <= errd + dx + dy   ;
                             
                          end else begin
                         
                              errd    <= errd + dy   ;
                             
                          end
                         
                        end else if ( ( errd << 1 ) < dx ) begin
                          errd    <= errd  + dx       ;
                          geo_y   <= geo_y + geo_ydir ;                           
                        end

                     end // geo_sub_func1 = 1 - plot line
                     
                  endcase // sub functions of draw line
 

Offline BrianHG

  • Super Contributor
  • ***
  • Posts: 7747
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #1583 on: August 25, 2020, 04:30:24 pm »
Correct.
The idea is to 3 running linegens, each where for the first 2, you can start and stop them when you like with which source X&Y for points A&B you like.  While the third one takes the output coordinates of linegens 1&2 as it's input A&B, and you can set it to pass through the A or B to plot those coordinates immediately, or you can run that third linegen to draw a line between the frozen captured output coordinates of linegens #1&2.

The output status flags tells you when you may start and run each module until it is time to switch to the next linegen module until all linegens have finished their initial line.
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #1584 on: August 26, 2020, 02:47:17 pm »
Just found some time to look at the line generator - I've integrated the line gen code from the geo_xy_plotter module into the new line_generator module.  Probably made quite a few mistakes as I'm rushing to make the most of the spare time I've got, so apologies if there's any glaringly obvious errors.

I've removed max_x and max_y checks as I guess they'll be done in the parent module?

When will pixel_data_rdy go high?  Constantly, I presume, once the line generator is running?

What about all the extra inputs and outputs for ena_stop_ypos, stop_ypos, ypos_stopped, etc?

I've just realised I've not done anything with line_complete.  I guess this should go high when draw_line goes low at the end of the line?
 

Offline BrianHG

  • Super Contributor
  • ***
  • Posts: 7747
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #1585 on: August 26, 2020, 05:56:17 pm »
Your doing good.  Try to wire in the module an make it function.

Yes you are correct about cheking for the max X&Y, they should only be checked once as the last and final step when sending out a write or paste pixel.

Don't forget to set the output flags.

Also, I was missing an input for the module.  A global 'enable' signal to run and stop the module tied to the ' !draw_busy ' input of the geometry_xy_plotter module.  This is the same for the clocked section of the comparator module ' tri_comp '.
« Last Edit: August 26, 2020, 06:02:00 pm by BrianHG »
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #1586 on: August 26, 2020, 08:01:35 pm »
Don't forget to set the output flags.

Sooo... line_complete needs setting at the end of the line.  I'm not sure what to do about ypos_stopped though?  Is that an acknowledge signal for a check I need to add to see if the current Y_coord is equal to stop_ypos??  Best check the attached code to make sure I'm doing the right thing.

Also, I was missing an input for the module.  A global 'enable' signal to run and stop the module tied to the ' !draw_busy ' input of the geometry_xy_plotter module.

Ah - I'd added 'draw_line' because I thought I needed something like the 'draw_busy' signal, too.  ;D  I've kept draw_line as I don't want the line generator to carry on trying to draw a line if an end condition has been met.  Hopefully that's okay (line 62 in the code).

This is the same for the clocked section of the comparator module ' tri_comp '.

I need to add a 'draw_busy' input for the clocked part of the comparator module as well?  Why's that?  Can't the parent module just ignore those inputs if draw_busy is high?

Oh - also - is the pixel_data_rdy output the same signal as the internal 'draw_line' signal I'm using?  Couldn't I just do this each clock?
Code: [Select]
pixel_data_rdy <= draw_line ;
 

Offline BrianHG

  • Super Contributor
  • ***
  • Posts: 7747
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #1587 on: August 26, 2020, 09:55:10 pm »
Think through how you will be managing more than 1 line function.

You need to start a line, but, the line function takes an additional clock to initialize.
You don't want to draw a pixel during this step, but you still need to know the line command is busy and not finished yet.
Maybe a new busy output is also required.
Also, you want to make sure when you change the Y stop position, you can still see the linegen working up until it reaches that line.  Right now, the freeze would be forever.

The Y-stop counter will be generated in the main geometry_xy_plotter as it needs to synchronize 2 of the top tier linegens.

Remember, you will need a sequencer setting the controls for all 3 linegens in the geometry_xy_plotter.
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #1588 on: August 27, 2020, 12:22:26 pm »
Think through how you will be managing more than 1 line function.

You need to start a line, but, the line function takes an additional clock to initialize.
You don't want to draw a pixel during this step, but you still need to know the line command is busy and not finished yet.
Maybe a new busy output is also required.

Can this be handled with the pixel_data_rdy signal?  Pixel_data_rdy doesn't go high until valid coordinates are being output by the line generator.

Also, you want to make sure when you change the Y stop position, you can still see the linegen working up until it reaches that line.  Right now, the freeze would be forever.

Sorry, I don't follow.  Are you talking about if the Y-stop position is changed whilst the line generator is running?  I've latched the value in the first phase now.

The Y-stop counter will be generated in the main geometry_xy_plotter as it needs to synchronize 2 of the top tier linegens.

Remember, you will need a sequencer setting the controls for all 3 linegens in the geometry_xy_plotter.

Hmm.. might need a rough map of what that will need to look like.

Couple more questions:

1) What am I doing with the pass-throughs?  If pass_thru_a or _b are high, I'm just passing the value in aX/aY or bX/bY through to the X/Y_coord outputs, but am I also showing pixel_data_rdy as well?

2) When should I be passing those values through?  Constantly, or only when certain conditions are met (other than pass_thru_a/b being high)?

3) Is there any reason the geo_sub_func1 functions can't be performed as part of the reset stage, eliminating the need for geo_sub_func1 altogether?
 

Offline BrianHG

  • Super Contributor
  • ***
  • Posts: 7747
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #1589 on: August 27, 2020, 05:40:36 pm »
Think through how you will be managing more than 1 line function.

You need to start a line, but, the line function takes an additional clock to initialize.
You don't want to draw a pixel during this step, but you still need to know the line command is busy and not finished yet.
Maybe a new busy output is also required.

Can this be handled with the pixel_data_rdy signal?  Pixel_data_rdy doesn't go high until valid coordinates are being output by the line generator.

It's ultimately up to you how to code everything.  I'm only making useful recommendations.
How can you tell is the linegen has begun to work, yet the pixel data ready doesn't yet have the first pixel ready?
Quote

Also, you want to make sure when you change the Y stop position, you can still see the linegen working up until it reaches that line.  Right now, the freeze would be forever.

Sorry, I don't follow.  Are you talking about if the Y-stop position is changed whilst the line generator is running?  I've latched the value in the first phase now.
Look at our FreeBasic code.  We select a Y coordinate to stop on.  Then run linegen #1 until that Y coordinate.  Then run linegen #2 until that Y coordinate.  Then run linegen #3 between the output coordinates or linegen #1 and linegen #2 which should both be on the same Y coordinate.
Now, what happens next after linegen #3 draws a single horizontal line?
Quote

The Y-stop counter will be generated in the main geometry_xy_plotter as it needs to synchronize 2 of the top tier linegens.

Remember, you will need a sequencer setting the controls for all 3 linegens in the geometry_xy_plotter.

Hmm.. might need a rough map of what that will need to look like.

Couple more questions:

1) What am I doing with the pass-throughs?  If pass_thru_a or _b are high, I'm just passing the value in aX/aY or bX/bY through to the X/Y_coord outputs, but am I also showing pixel_data_rdy as well?

I guess the each pass through would also drive the pixel_data_rdy output at the same time.
Quote

2) When should I be passing those values through?  Constantly, or only when certain conditions are met (other than pass_thru_a/b being high)?
Only when either pass through signal is high.
Quote

3) Is there any reason the geo_sub_func1 functions can't be performed as part of the reset stage, eliminating the need for geo_sub_func1 altogether?

Take a look as what 'errd' equals.  It needs dx & dy to be ready.


Also, the '!draw_busy' in this block needs to encompass everything including the so called 'reset'.  Make it an 'IF' outside of everything else.
 
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #1590 on: August 28, 2020, 03:06:25 pm »
It's ultimately up to you how to code everything.  I'm only making useful recommendations.
How can you tell is the linegen has begun to work, yet the pixel data ready doesn't yet have the first pixel ready?

Fair point - I've added a 'busy' output as well.

Look at our FreeBasic code.  We select a Y coordinate to stop on.  Then run linegen #1 until that Y coordinate.  Then run linegen #2 until that Y coordinate.  Then run linegen #3 between the output coordinates or linegen #1 and linegen #2 which should both be on the same Y coordinate.
Now, what happens next after linegen #3 draws a single horizontal line?

A check is made to see if linegen #1 needs to switch to the third line?

I'm still confused about what the issue is here.  :-//  My line generator module sets a flag to show the line is complete and that it has stopped at the specified Y-coordinate.  It clears several other flags but all of these flags are either reset (in the case of the Y-stop and line complete flags) or set again when the next line is specified to be drawn in the reset (now called start for clarity) function?
Code: [Select]
// Set latched registers, phase counters and flags
geo_sub_func1  <= 4'b0       ; // reset the phase counter
ypos_stopped   <= 1'b0       ; // reset ypos_stopped flag
line_complete  <= 1'b0       ; // reset line_complete flag
Y_stop         <= stop_ypos  ; // latch the Y_stop coordinate
stop_ypos_en   <= ena_stop_y ; // latch Y_stop enable
draw_line      <= 1'b1       ; // start drawing the line on the next clock cycle
busy           <= 1'b1       ;

// Initialise starting coordinates and direction for immediate plotting
X_coord        <= aX         ; // initialize starting X pixel location
Y_coord        <= aY         ; // initialize starting Y pixel location

Quote
3) Is there any reason the geo_sub_func1 functions can't be performed as part of the reset stage, eliminating the need for geo_sub_func1 altogether?

Take a look as what 'errd' equals.  It needs dx & dy to be ready.

Ah, missed that.

Also, the '!draw_busy' in this block needs to encompass everything including the so called 'reset'.  Make it an 'IF' outside of everything else.

Sorted.  Updated file attached.  Just need to write the reset function and fix any last issues (like the Y-stop thing?)
 

Offline BrianHG

  • Super Contributor
  • ***
  • Posts: 7747
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #1591 on: August 28, 2020, 05:47:43 pm »
A check is made to see if linegen #1 needs to switch to the third line?

It's the second linegen, not the first.
Why do you think I told you to make 2 outputs, 1 which tells you when the linegen has stopped due to reaching the chosen Y coordinate VS if the linegen has finished it's current line.  Don't you think this flag may be of use as well?

Also, you have conditions where the pixel_data_ready gets set, but never cleared if the pass throughs are disabled and a reset comes next.


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.

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.

Then worry about controlling the linegens to step/advance a Y coordinate at a time with pre-sorted coordinates coming from the Z80.

Then worry about wiring 3 of them together and controlling them with pre-sorted coordinates from the Z80.

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.
« Last Edit: August 28, 2020, 05:52:44 pm by BrianHG »
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #1592 on: August 29, 2020, 11:39:38 am »
Why do you think I told you to make 2 outputs, 1 which tells you when the linegen has stopped due to reaching the chosen Y coordinate VS if the linegen has finished it's current line.  Don't you think this flag may be of use as well?

Okay, so the 1st linegen draws the longest line (to the lowest Y-coordinate) - this is set by the sorting function before the drawing starts.  The 2nd linegen draws the connected line from the topmost Y-coordinate, connected to the 1st linegen line, and (by definition as it's a triangle) stops at some point before reaching (or upon reaching) the end of the first line.

As I understand it, the two ending signals are for the following conditions:
  • When the line reaches its end. This is when line_complete goes HIGH.
  • When the line reaches a specified Y-coordinate. This is when ypos_stopped goes HIGH.
The two linegens are run, set to stop at each Y-pixel so that the raster line can be filled if required - this is where ypos_stopped is used.  When linegen #2 signals line_complete, then the parent function sets up the third line to be drawn - or if it's the third line signalling complete, the triangle is complete.  Is that right?

Also, you have conditions where the pixel_data_ready gets set, but never cleared if the pass throughs are disabled and a reset comes next.

I've added a reset for pixel_data_rdy in the start phase.  Is there somewhere else I should be resetting it, or is it covered now?

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.

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.

Then worry about controlling the linegens to step/advance a Y coordinate at a time with pre-sorted coordinates coming from the Z80.

Then worry about wiring 3 of them together and controlling them with pre-sorted coordinates from the Z80.

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.

No problem - will make a start on this and update when I have anything to report.

Again - thanks for all your help BrianHG. :-+
 

Offline BrianHG

  • Super Contributor
  • ***
  • Posts: 7747
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #1593 on: August 29, 2020, 03:19:44 pm »
You got the basics of it.

Code: [Select]
                    if ( stop_ypos_en && Y_coord == Y_stop ) begin // reached Y_coordinate stop position and we want to stop on Y_pos
                   
                        draw_line      <= 1'b0 ; // last pixel - allow time for this pixel to be written by ending on next clock
                        line_complete  <= 1'b1 ; // set line_complete flag to let parent module know the line is done
                        ypos_stopped   <= 1'b1 ; // let the parent module know the line generator has stopped on ypos
                        pixel_data_rdy <= 1'b0 ; // reset pixel_data_rdy flag - no more valid coordinates after this clock
                        busy           <= 1'b0 ; // line generator is no longer busy
                   
                    end

The line isn't necessarily complete when Y stopped.
Also, Y-stopped needs to be cleared if the coordinates change or the feature is disabled.
You have no mechanism to do this.
Also, does the line engine actually stop?
A little more thought may be needed here.

As for the start, you should first compare is points A&B are equal.
If so, just pass thru point A to output.
In fact, you can actually do this as part of the first 'if ( pass_thru_a ) begin' bypassing the rest of the line draw algorithm.


« Last Edit: August 29, 2020, 06:25:20 pm by BrianHG »
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #1594 on: August 30, 2020, 04:22:10 pm »
The line isn't necessarily complete when Y stopped.
Also, Y-stopped needs to be cleared if the coordinates change or the feature is disabled.
You have no mechanism to do this.

Why would the coordinates change or the feature be disabled in the middle of drawing a line?  :-//  (Unless you mean the Y-pos coordinates changing?)

Hmm.. the line generator stops on Y-pos, so the parent function can then fill in the raster line, but what causes the line generator to restart again?

.....Okay, my thinking is now going along these lines - I need to clear ypos_stopped when stop_ypos changes.  I also need to set draw_line, busy and pixel_data_rdy again to get the line generator running to the next stop_ypos.  Is that right?

Also, does the line engine actually stop?
A little more thought may be needed here.

Well, this is where I'm going with my thought process above.  The line generator currently is stopping on Y-pos and there's no way to start it again for the next Y-pos.  I think I'm finally getting how it works.  ;)

As for the start, you should first compare is points A&B are equal.
If so, just pass thru point A to output.
In fact, you can actually do this as part of the first 'if ( pass_thru_a ) begin' bypassing the rest of the line draw algorithm.

Have done that as below:
Code: [Select]
if ( pass_thru_a || ( aX == bX && aY == bY ) ) begin

pixel_data_rdy <= 1'b1 ; // valid coordinates at output
X_coord        <= aX   ; // pass-through aX value
Y_coord        <= aY   ; // pass-through aY value

if ( aX == bX && aY == bY ) begin

line_complete  <= 1'b1 ; // set line_complete flag to let parent module know the line is done

end

end
 

Offline BrianHG

  • Super Contributor
  • ***
  • Posts: 7747
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #1595 on: August 30, 2020, 05:27:13 pm »
It's time to insert with the main geometry_xy_plotter and first replicate drawing a single line.
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #1596 on: September 02, 2020, 01:37:25 pm »
Okay, I've done some tweaking to get it to work in the geometry_xy_plotter module, but I think it's okay...  The simulation is showing the correct pixels being output from the line_generator module and being passed to PAGET.  I just feel there's probably a much cleaner way of integrating the line_generator into the geo_xy_plotter module...

Anyhow, here's the simulation output:



I've attached the line_generator and geo_xy_plotter modules at the end of this post too.

Maybe the timing could be tightened by a few clocks?
 

Offline BrianHG

  • Super Contributor
  • ***
  • Posts: 7747
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #1597 on: September 02, 2020, 05:53:01 pm »
I cannot see in your simulation the output coordinates at the address.  Choose a different base address and screen width to make this easy to decode on the waveform.
You also seem to be drawing an extra pixel at 6,5, or, is the flag I'm looking at mean something else?
I do not remember the old linegen changing pixel numbers after the line has finished.

Delays are due to fifo setup and pipe through time.
Give it a try with the Z80 constructing a few known shapes.
I say shapes so you know that the ends of the lines properly touch.
When testing with the Z80, first use the original line-gen, then, switch to this new one.
Make a program that uses something like 8-12 lines deliberate lines.
Speed is not important here.  It's coverage of the screen with odd angles and a few different colors at 320x200.

The output from both versions of the code should match.

If everything is ok, then go onto the next step which will only be simulate-able, making the smart point draw when point A= point B.  I say you can only simulate since it happens so fast that you could not tell with the Z80.

« Last Edit: September 02, 2020, 06:02:36 pm by BrianHG »
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #1598 on: September 03, 2020, 12:26:21 pm »
Okay, so testing has thrown up a glitch.  I'm no professional, but it looks like it could be a FIFO thing going on, maybe?

I'm drawing a square, with a cross through it, but not drawing the very edge pixels of the square (in my mind it seemed like a good way to test for overrun etc).  One pic shows the normal GPU HDL drawing the image, the other shows the new line_gen code with the obvious errors.

I've included the geo_xy_plotter and line_generator modules for info, but I suspect it's probably a simple error I've made whilst integrating the new line_generator module.  It seems to simulate just fine and PAGET is throwing out addresses with no breaks, so I'm wondering if I've missed a busy check or something somewhere..  I note that there are more breaks in the horizontal lines than the other lines, maybe due to more cache hits and thus more misses (due to the faster pixel-write throughput) if PAGET's busy?
« Last Edit: September 03, 2020, 12:29:37 pm by nockieboy »
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #1599 on: September 03, 2020, 01:09:01 pm »
Also, I'd tidied up the line_generator after it finishes, so it's not running on for another pixel.  Latest simulation results below.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf