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

0 Members and 52 Guests are viewing this topic.

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #2175 on: November 20, 2020, 09:24:40 pm »
But before that, before entering the DDR3 controller, he need to read it's documentation and see what features and configuration he will want to use.  He also needs to decide whether to tie everything together to the existing GPU via block diagram, or go 100% HDL and drop the block diagram entry he has been using to date and write modules merging his existing HDL cores.

Tackling the easiest task first, I'd like to stick with the block diagram.  It provides me with an easily understandable overview of how all the modules interlink that I just wouldn't have with some large, unwieldy block of HDL instantiating everything.

As for the DDR features/configuration, I've made a start on the datasheet. ???  So you want me to specify things like the burst length, burst type, CAS latency, operating mode, DLL RESET, write recovery and precharge power down mode?

Without having much of a clue about all these configuration options, I guess I'd need BL8 as we won't be interested in BC4 nibbles.  Sequential burst type?

Write Recovery is set as the result of a calculation - WR (cycles) = roundup (tWR [ns]/tCK [ns]).  Were we looking at 200MHz for the DDR clock?  That's tCK of 5ns, but how do I find tWR?

That's probably it for me for the next few days - got a busy weekend and next week.  :-\
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 8143
  • Country: ca
    • LinkedIn
Re: FPGA VGA Controller for 8-bit computer
« Reply #2176 on: November 20, 2020, 10:05:40 pm »
But before that, before entering the DDR3 controller, he need to read it's documentation and see what features and configuration he will want to use.  He also needs to decide whether to tie everything together to the existing GPU via block diagram, or go 100% HDL and drop the block diagram entry he has been using to date and write modules merging his existing HDL cores.

Tackling the easiest task first, I'd like to stick with the block diagram.  It provides me with an easily understandable overview of how all the modules interlink that I just wouldn't have with some large, unwieldy block of HDL instantiating everything.

As for the DDR features/configuration, I've made a start on the datasheet. ???  So you want me to specify things like the burst length, burst type, CAS latency, operating mode, DLL RESET, write recovery and precharge power down mode?

Without having much of a clue about all these configuration options, I guess I'd need BL8 as we won't be interested in BC4 nibbles.  Sequential burst type?

Write Recovery is set as the result of a calculation - WR (cycles) = roundup (tWR [ns]/tCK [ns]).  Were we looking at 200MHz for the DDR clock?  That's tCK of 5ns, but how do I find tWR?

That's probably it for me for the next few days - got a busy weekend and next week.  :-\
For now, select a 300MHz ram clock and select a matching ram chip.  The megafunction will automatically enter all those fields for you.   I know they only have the -125/-15E versions of the ram chip.  This is ok as we are not clocking up to the 1GHz of the ram chip available at LCSC.

The additional features like on-die-termination should also be enabled as by default, they are not.

Also, 'enable hard memory interface' should be disabled.

Begin with this.
You will want to make a new project with your chosen FPGA, 256 ball, -C7.
You will need to add a PLL which takes in your reference 50MHz and outputs 300MHz.
Set IO pins on selected banks.  (Avoid using bank 5A for ram.)
Also, under controller settings, we will use the 'byte enable' and create 2 ports, 1 read and 1 write.
Begin here.
We will then occupy the ram controller with temporary dummy controls an compile to see if we can extend the FMAX beyond 300/600MHz.
« Last Edit: November 20, 2020, 10:12:11 pm by BrianHG »
 

Offline asmi

  • Super Contributor
  • ***
  • Posts: 2839
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #2177 on: November 20, 2020, 10:30:47 pm »
For now, select a 300MHz ram clock and select a matching ram chip.
Set it to 303 MHz to stay within datasheet specs for DDR3 - it specifies 3.3 ns as max clock period, which corresponds to 1000 / 3.3 = 303.(03) MHz, so 303 is "close enough".

Also, before you settle on pinout, build a diagram of your package like the one in attachment (Xilinx did that for us, but other vendors couldn't be bothered for some reason, even though it's super-useful) which overlays DQ groups and IO bank numbers over physical package. This will allow you to see that you can actually route the pinout to a single DDR3 x16 module. You can think of it this way - you will need 2 adjacent DQ groups for data bus, and two more for address/control. If you will look at memory device's pinout, you will see that there are three separate "sections" - one for address/control, and two for two separate DQ groups (DQ0-7,DQS0+/-,DM0 for byte 0, DQ8-15,DQS1+/-,DM1 for byte 1). You will need to use a bit of imagination to think of how it's going to look like on a board, but one of advantages of "soft" controllers is that you have a lot more freedom to select pinout to facilitate routing.
« Last Edit: November 20, 2020, 11:01:21 pm by asmi »
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 8143
  • Country: ca
    • LinkedIn
Re: FPGA VGA Controller for 8-bit computer
« Reply #2178 on: November 20, 2020, 11:02:05 pm »
Actual compiler tested FMAX IO bank speeds.  CycloneV 256 BGA

Bank #  - Inner IOs - outer IOs
Bank 8A - 766/702   - 1088/706
Bank 7A - 844/710   - 1086/710
Bank 5B - 709/709   - 1086/717
Bank 5A - 1082/717  - 653/653   (The outer IOs are dual-purpose configuration pins)
Bank 4A - 877-717   - 991/717
Bank 3B - 938/717   - 912/717
Bank 3A - 832/717   - 946/717
Bank 2A - 703/703   - 719/702

 

Offline asmi

  • Super Contributor
  • ***
  • Posts: 2839
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #2179 on: November 20, 2020, 11:06:30 pm »
Actual compiler tested FMAX IO bank speeds.  CycloneV 256 BGA
Are these real numbers you can actually physically measure on outputs, or just BS numbers that can theoretically happen but never do in a real world?

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 8143
  • Country: ca
    • LinkedIn
Re: FPGA VGA Controller for 8-bit computer
« Reply #2180 on: November 20, 2020, 11:17:44 pm »
Actual compiler tested FMAX IO bank speeds.  CycloneV 256 BGA
Are these real numbers you can actually physically measure on outputs, or just BS numbers that can theoretically happen but never do in a real world?
I tied a DDR port to all the IOs with 2 counters for the clk & clk_n feeding the DDR bus.
I set the system PLL clock to 350MHz.
The figures are what Quartus reported as the maximum attainable clock frequency.
I'm sure Quartus knows how fast it's chip can run.

Only half of port 5A failed to achieve the 700mbps data rate.
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 8143
  • Country: ca
    • LinkedIn
Re: FPGA VGA Controller for 8-bit computer
« Reply #2181 on: November 26, 2020, 11:36:20 pm »
@nockieboy: nothing?

At least get started on the entry level 24bit RGB + HS/VS/DE -> DVI converter.

Begin with the basic sync generator tied to the current dev-board's 7 color output RGB plug with a basic white screen.

Then simulate that tied to your 24bit RGB + HS/VS/DE  to 3x 10 bit parallel symbol output. (IE embeded HS/VS/DE & 24bit color input).

(Simulate here.)

Then add a serializer which takes the 4x10 bit in (last one is the pixel clock) and outputs the 4 serial bits.

(Simulate here, & test new PCB)

Next switch over/add to 48KHz stereo HDMI embedded audio with a source rom sine wave.

(Test on TV with audio support)
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #2182 on: November 27, 2020, 10:36:37 am »
Work has been really busy and tomorrow will be my first day off for two weeks, so no real progress on the project yet.  All I've managed to do in the small amount of spare time I've had is to work on the text blitting to get a hardware scroll working.

The video I've just done isn't great - 320x200 mode, multicolour text is deleted with the wrong colour background (blue instead of black), but it works fine in single-colour text, but the video demonstrates scrolling text up the screen using the blitter.

It also works in 640x400 mode too.  The smaller-than-VGA resolutions are due to RAM limitations in the EP4CE10.

I've tried to get 320x240x2 working, but whatever I try I can't seem to get it to display anything.  640x400x1 and 320x200x4 work fine.

 
The following users thanked this post: BrianHG

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #2183 on: November 27, 2020, 11:56:06 am »
Parts and PCBs are now on order. :)

While I'm waiting for the PCBs to be delivered, I guess I should head back and finish that HDL ellipse function. :scared:
Ok, you need to change 1 thing in the current basic code.  Right now it makes an ellipse inside a box coordinates.
You need to change it so it makes an ellipse from a 'center x,y' coordinate and an 'x,y radius'.
Then it will be ready to convert to HDL.

Okay, is this really as easy as adding a couple more variables and working out the box coordinates from the supplied centre x,y and radius?

Code: [Select]
Dim As Integer x0 = xc - radius, y0 = yc - radius
Dim As Integer x1 = xc + radius, y1 = yc + radius

I added the above two lines to the existing FreeBasic function to draw an ellipse, corrected the expected parameters for the subroutine and it's working fine?  I guess this solution will probably add a clock cycle to the HDL function and you'll probably point out there's a better way to do it.  ;)

Parts arrived a few days ago, by the way.  I'm just waiting on the PCBs, which are on their way.

EDIT:  There's probably some optimisation of the subroutine I can do as we don't need to worry about ordering x0/y0 and x1/y1 anymore.
« Last Edit: November 27, 2020, 12:01:00 pm by nockieboy »
 
The following users thanked this post: BrianHG

Offline DiTBho

  • Super Contributor
  • ***
  • Posts: 4247
  • Country: gb
Re: FPGA VGA Controller for 8-bit computer
« Reply #2184 on: November 27, 2020, 02:33:37 pm »
hardware scroll working.

how does it work?
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #2185 on: November 27, 2020, 03:08:03 pm »
hardware scroll working.

how does it work?

So the screen is just a bitmap - when a newline is needed, the software checks if the last line is reached.  If it is, then it uses the blitter in the FPGA to copy the screen (minus the top row of pixels) and pastes it to the top of the screen (0,0).  The end result is the whole screen is shifted up by one row of pixels.  Repeat that 16 times (as that's the height of each text row) and you've got a hardware scroll, neatly scrolling the screen up one row at a time as required.
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 8143
  • Country: ca
    • LinkedIn
Re: FPGA VGA Controller for 8-bit computer
« Reply #2186 on: November 27, 2020, 04:00:37 pm »
Wow, nice smooth accelerated vertical text scrolling on a 320x200x16 color graphics screen with accelerated font rendering.  Funny how even without trying, we don't see vertical sync animation tearing.  I guess if you did it horizontally with enough graphics, it would become visible unless you timed the blitt to the VS.

You can also try 'Bold' test by painting each letter twice 1 pixel apart with translucency enabled for at least the second character.

As for 320x240x2, did you change the output screen & output blitt depth setting correctly?  Remember when selecting a color for the output characters you limit the output color to 2 bits.  I guess it would still work with more bits, jut maybe the output color would be messed up.

 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #2187 on: November 27, 2020, 04:39:48 pm »
Wow, nice smooth accelerated vertical text scrolling on a 320x200x16 color graphics screen with accelerated font rendering.  Funny how even without trying, we don't see vertical sync animation tearing.  I guess if you did it horizontally with enough graphics, it would become visible unless you timed the blitt to the VS.

There's no tearing at all.   ;D

You can also try 'Bold' test by painting each letter twice 1 pixel apart with translucency enabled for at least the second character.

Ah yes, hadn't thought of that!  Will give that a go next.  :-+

As for 320x240x2, did you change the output screen & output blitt depth setting correctly?  Remember when selecting a color for the output characters you limit the output color to 2 bits.  I guess it would still work with more bits, jut maybe the output color would be messed up.

Okay, well I don't want to lose you all in Z80 assembly (I would normally 'simplify' this code, but I don't have the time at the moment), but here's my setup code for 320x200x4 - this works (as you've seen in the video):
Code: [Select]
    ; Set screen mode flags
    LD      A,4
    LD      (SCR_MODE),A
    LD      A,3                 ; Valid values: 0, 1, 3, 7, 15
    LD      (SCR_BPP),A
    LD      HL,0140H            ; 320 pixels wide
    LD      (SCR_WDTH),HL
    LD      HL,00C8H            ; 200 pixels high
    LD      (SCR_HITE),HL
    LD      HL,0340H            ; Lower 3 bytes of 2nd pixel row address
    LD      (ROW2_ADR),HL
    LD      HL,0400H
    LD      (DELAY),HL          ; set scroll delay

    ; Set graphics | 4-bit colour
    LD      A,10
    LD      (GPU_RAM+60H),A

    ; Leave foreground and background colours (default to 0)

    ; Set screen memory base address to 1200h
    LD      A,12H
    LD      (GPU_RAM+64H),A

    ; Set YINC_ADDR (bytes per line - this changes with bpp!)
    ; This is half the pixel width as there are 2 pixels per byte
    ; in the current 4 bpp mode
    LD      HL,0A000H               ; set to 160 bytes per line for 4 bpp
    LD      (GPU_RAM+66H),HL

    ; X_SIZE to 320 pixels width
    LD      HL,013FH
    LD      (GPU_RAM+68H),HL

    ; Y_SIZE to 200 rows height (remember - 1 less than target)
    LD      A,0C7H ; 200 rows height
    ;LD      A,0EFH ; 240 rows height
    LD      (GPU_RAM+6BH),A

    ; X & Y scale (set to 1 to double size of image - 320x240 into 640x480 screen)
    LD      HL,0101H
    LD      (GPU_RAM+6CH),HL

    ; X & Y sub-pixel position (set to 0,0)
    LD      HL,0000H
    LD      (GPU_RAM+6EH),HL

    ; set GPU base_addr for graphics
    GPU_CMD 0F001H       ; set Y[3] to 01
    GPU_CMD 0B200H       ; set X[3] to 200
    GPU_CMD 7F00H        ; send cmd 124 to set destination base address
    ; set raster width (H) and bit depth (L)
    GPU_CMD 0F000H       ; reset Y[3] to 0
    GPU_CMD 0B140H       ; set X[3] to 320
    GPU_CMD 7103H        ; set dest width to Y[3]X[3] and bpp to 3 for 16 colours
    ; set X & Y limits
    GPU_CMD 8140H        ; set X[0] to 320
    GPU_CMD 0C0C8H       ; set Y[0] to 200
    ;GPU_CMD 0C0F0H       ; set Y[0] to 240
    GPU_CMD 5F00H        ; set max X & Y to X[0],Y[0]
   
    ; Turn off the blitter
    GPU_CMD 0000H        ; Blitter, PM & CP disabled

This is a straight lift from my assembly code for the graphics test program, so apologies if your Z80 assembly isn't fluent.

Here's the 320x240x2 setup code:
Code: [Select]
    ; Set screen mode flags
    LD      A,2
    LD      (SCR_MODE),A
    LD      A,1                 ; Valid values: 0, 1, 3, 7, 15
    LD      (SCR_BPP),A
    LD      HL,0140H            ; 320 pixels wide
    LD      (SCR_WDTH),HL
    LD      HL,00F0H            ; 240 pixels high
    LD      (SCR_HITE),HL
    LD      HL,0250H            ; Lower 3 bytes of 2nd pixel row address
    LD      (ROW2_ADR),HL
    LD      HL,0800H
    LD      (DELAY),HL          ; set scroll delay

    ; Set graphics mode | BP2RAST_cmd | 2-bit colour
    LD      A,9
    LD      (GPU_RAM+60H),A

    ; Set foreground to white, leave background black
    LD      A,0FH
    LD      (GPU_RAM+62H),a

    ; Set screen memory base address to 1200h
    LD      A,12H
    LD      (GPU_RAM+64H),A

    ; Set YINC_ADDR (bytes per line - this changes with bpp!)
    ; This is 1/4 the pixel width as there are 4 pixels per byte
    ; with 2 bit per pixel mode
    LD      HL,5000H               ; set to 80 bytes per line for 2 bpp @ 320
    LD      (GPU_RAM+66H),HL

    ; X_SIZE to 319 pixels width
    LD      HL,013FH
    LD      (GPU_RAM+68H),HL

    ; Y_SIZE to 239 rows height
    LD      A,0EFH ; 239 rows height
    LD      (GPU_RAM+6BH),A

    ; X & Y scale (set to 1 to double size of image - 320x240 into 640x480 screen)
    LD      HL,0101H
    LD      (GPU_RAM+6CH),HL

    ; X & Y sub-pixel position (set to 0,0)
    LD      HL,0000H
    LD      (GPU_RAM+6EH),HL

    ; set GPU base_addr for graphics
    GPU_CMD 0F001H       ; set Y[3] to 01
    GPU_CMD 0B200H       ; set X[3] to 200
    GPU_CMD 7F00H        ; send cmd 124 to set destination base address
    ; set raster width (H) and bit depth (L)
    GPU_CMD 0F000H       ; reset Y[3] to 0
    GPU_CMD 0B140H       ; set X[3] to 320
    GPU_CMD 7101H        ; set dest width to Y[3]X[3] and bpp to 2 for 4 colours
    ; set X & Y limits
    GPU_CMD 8140H        ; set X[0] to 320
    GPU_CMD 0C0F0H       ; set Y[0] to 240
    GPU_CMD 5F00H        ; set max X & Y to X[0],Y[0]
    ; Turn off the blitter
    GPU_CMD 0000H        ; Blitter, PM & CP disabled

Then finally, doesn't matter which of the two previous setup functions are executed, the blitter is set up for text as below:
Code: [Select]
SET_BLIT:
    ; Set base memory address to start of font table ($0200)
    GPU_CMD 0C000H          ; set Y[0] to 0
    GPU_CMD 8200H           ; set X[0] to 200
    GPU_CMD 7800H           ; set base memory address
    ; Set the source raster width to 8 pixels and 1 bit color depth
    GPU_CMD 0A008H          ; set X[2] to 8
    GPU_CMD 0E000H          ; set Y[2] to 0
    GPU_CMD 7200H           ; set raster width to Y[2] pixels, 1 bpp
    ; Set the destination raster width to SCR_WDTH pixels and SCR_BPP color depth
    LD      HL,(SCR_WDTH)   ; Get pixel width of screen
    LD      BC,0A000H       ; Command to load width into X[2]
    ADD     HL,BC           ; Add pixel width to the command
    CALL    send_gpu        ; set X[2] to SCR_WDTH
    GPU_CMD 0E000H          ; set Y[2] to 0
    LD      HL,7303H
    LD      A,(SCR_BPP)
    LD      L,A             ; Overwrite '03' with SCR_BPP
    CALL    send_gpu        ; set destination raster width to X[2] pixels, 4 bpp
    ; Set the blitter width and height to 8x16
    GPU_CMD 0A007H       ; set X[2] to 7
    GPU_CMD 0E00FH       ; set Y[2] to 15
    GPU_CMD 7400H        ; set copy width/height to 8x16 pixels
    ; Turn on the blitter
    LD      HL,0001H        ; Blitter enabled, PM & CP disabled
    LD      A,(BLIT_SET)
    LD      L,A             ; Override settings with defined features
    CALL    send_gpu
    RET
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #2188 on: November 27, 2020, 06:35:38 pm »
You can also try 'Bold' test by painting each letter twice 1 pixel apart with translucency enabled for at least the second character.

It works, but the font is low-res so the difference isn't as obvious as it would be on a finer, higher-res tileset.  :-+
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 8143
  • Country: ca
    • LinkedIn
Re: FPGA VGA Controller for 8-bit computer
« Reply #2189 on: November 28, 2020, 04:13:51 am »
When running the blitter, remember, you have a 'source bits/color' setting for the font which is 0 (ie 1bpp/2colors) and a 'destination bits/color' which now should be 1 or 3, (ie 2bpp/4 colors, or, 4bpp/16 colors).  Are these set properly?

Are you able to draw regular pixels the old fashioned way on the 2bpp 4 color screen?

 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #2190 on: November 28, 2020, 12:02:32 pm »
When running the blitter, remember, you have a 'source bits/color' setting for the font which is 0 (ie 1bpp/2colors) and a 'destination bits/color' which now should be 1 or 3, (ie 2bpp/4 colors, or, 4bpp/16 colors).  Are these set properly?

Are you able to draw regular pixels the old fashioned way on the 2bpp 4 color screen?

It's something to do with my code - have fixed one issue, can now see text in 2bpp mode - but there's other issues that I'll need to bugfix in my code.  ::)
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #2191 on: November 28, 2020, 03:16:33 pm »
All fixed - working fine in 2 bpp mode now.  One issue was with the colour being 'out of bounds' for the bpp mode - it was causing some very odd behaviour, but it's all sorted now.  :-+
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #2192 on: November 28, 2020, 03:18:08 pm »
At least get started on the entry level 24bit RGB + HS/VS/DE -> DVI converter.

Begin with the basic sync generator tied to the current dev-board's 7 color output RGB plug with a basic white screen.

Then simulate that tied to your 24bit RGB + HS/VS/DE  to 3x 10 bit parallel symbol output. (IE embeded HS/VS/DE & 24bit color input).

Will get started on this next.  :-/O
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #2193 on: November 28, 2020, 03:23:00 pm »
Parts and PCBs are now on order. :)

While I'm waiting for the PCBs to be delivered, I guess I should head back and finish that HDL ellipse function. :scared:
Ok, you need to change 1 thing in the current basic code.  Right now it makes an ellipse inside a box coordinates.
You need to change it so it makes an ellipse from a 'center x,y' coordinate and an 'x,y radius'.
Then it will be ready to convert to HDL.

Okay, is this really as easy as adding a couple more variables and working out the box coordinates from the supplied centre x,y and radius?

Code: [Select]
Dim As Integer x0 = xc - radius, y0 = yc - radius
Dim As Integer x1 = xc + radius, y1 = yc + radius

I added the above two lines to the existing FreeBasic function to draw an ellipse, corrected the expected parameters for the subroutine and it's working fine?  I guess this solution will probably add a clock cycle to the HDL function and you'll probably point out there's a better way to do it.  ;)

Parts arrived a few days ago, by the way.  I'm just waiting on the PCBs, which are on their way.

EDIT:  There's probably some optimisation of the subroutine I can do as we don't need to worry about ordering x0/y0 and x1/y1 anymore.

@BrianHG - don't know if you missed this post - any feedback at all?
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 8143
  • Country: ca
    • LinkedIn
Re: FPGA VGA Controller for 8-bit computer
« Reply #2194 on: November 29, 2020, 07:53:16 pm »

Okay, is this really as easy as adding a couple more variables and working out the box coordinates from the supplied centre x,y and radius?

Code: [Select]
Dim As Integer x0 = xc - radius, y0 = yc - radius
Dim As Integer x1 = xc + radius, y1 = yc + radius

I added the above two lines to the existing FreeBasic function to draw an ellipse, corrected the expected parameters for the subroutine and it's working fine?  I guess this solution will probably add a clock cycle to the HDL function and you'll probably point out there's a better way to do it.  ;)


You are adding complexity to the routine which was once was a center ellipse converted to a box ellipse by the original source from the website you got that code from, and now you are sitting that code inside 2 more box un/re-center variables to convert it back into a center ellipse routine...

We want to simplify, not complicate things here.

Take a look at the last 'integer general ellipse' algorithm .pdf I posted.  In the middle of that .pdf, there is a simple code which generates a 'center ellipse' using 2 small loops to generate each half of the curve (actually 1/2 of each quadrant which is what we want).  That one removes all the clutter and should convert to both basic and verilog in a snap written as is.
 

Offline DiTBho

  • Super Contributor
  • ***
  • Posts: 4247
  • Country: gb
Re: FPGA VGA Controller for 8-bit computer
« Reply #2195 on: November 29, 2020, 09:10:28 pm »
why do you need eclipses?
aren't lines and triangles enough as "basic" primitives?
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 8143
  • Country: ca
    • LinkedIn
Re: FPGA VGA Controller for 8-bit computer
« Reply #2196 on: November 29, 2020, 10:23:04 pm »
why do you need eclipses?
aren't lines and triangles enough as "basic" primitives?
A Z80 is very basic and slow.  Yes, you can construct circles from triangles or a bunch of line segments.  There are a ton of apps at low res where a 'pixel/raster' rendering of circles/ellipses is a very useful geometry portion of such an engine.  Eventually Nockieboy may add the ability for the GPU to process such chunks of memory as compiled geometric vertices, however, if you need a circle/ellipse, having an available command which takes 6 variables to construct any you like which renders at core clock speed is very useful.  Complaining about adding this to the GPU:

Code: [Select]
// First 45 degrees 1 quadrant of arc
int a2 = a*a , b2 = b*b , fa2 = 4*a2 ;
int x , y , sigma ;
for ( x = 0 , y = b , sigma = 2*b2+a2*(1-2*b ) ; b2*x <= a2*y ; x++)
{
  DrawPixel ( xc+x , yc+y ) ; // draw 4 quadrants around center coordinates
  DrawPixel ( xc-x , yc+y ) ;
  DrawPixel ( xc+x , yc-y ) ;
  DrawPixel ( xc-x , yc-y ) ;

  if ( sigma >= 0 )
  {
    sigma += fa2*(1-y) ;
    y--;
  }
  sigma += b2*(4*x+6);
}

// Second 45 degrees of 1 quadrant of arc
int a2 = a*a , b2 = b*b , fb2 = 4*b2 ;
int x , y , sigma ;
for ( x = a , y = 0 , sigma = 2*a2+b2*(1-2*a) ; a2*y <= b2*x ; y++)
{
  DrawPixel ( xc+x , yc+y ) ; // draw 4 quadrants around center coordinates
  DrawPixel ( xc-x , yc+y ) ;
  DrawPixel ( xc+x , yc-y ) ;
  DrawPixel ( xc-x , yc-y ) ;
 
 if ( sigma >= 0 )
  {
    sigma += fb2*(1-x) ;
    x--;
  }
  sigma += a2*(4*y+6);
}

// Ideally, in verilog, the first and second 45 degrees should be the same code run twice once further simplification has been done.

After all the effort in a processor which was developed to render triangles, smartly filled horizontally line by line to optimize memory access cache with a new pixel ready every single core clock in a 6k logic gate FPGA with everything else we squished in there is now, not adding the above function is just being lazy.  Especially since we are upgrading to a 25kle FPGA.  (I would add that a 'general ellipse' which means an ellipse with a rotation is also much more complicated, but would cover more capability.)

« Last Edit: November 29, 2020, 10:30:57 pm by BrianHG »
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #2197 on: November 29, 2020, 10:37:34 pm »
You are adding complexity to the routine which was once was a center ellipse converted to a box ellipse by the original source from the website you got that code from, and now you are sitting that code inside 2 more box un/re-center variables to convert it back into a center ellipse routine...

We want to simplify, not complicate things here.

Take a look at the last 'integer general ellipse' algorithm .pdf I posted.  In the middle of that .pdf, there is a simple code which generates a 'center ellipse' using 2 small loops to generate each half of the curve (actually 1/2 of each quadrant which is what we want).  That one removes all the clutter and should convert to both basic and verilog in a snap written as is.

Okay, aside from the filling loop, here's the FreeBasic code for the ellipse algorithm you're talking about:

Code: [Select]
Sub drawCircle(ByVal xc As integer, ByVal yc As Integer, ByVal radius As integer, ByVal colour as Integer, ByVal filled As Boolean = FALSE)

   Dim As Integer a = radius, b = radius : Rem values of diameter
Dim As Integer x, y, sigma, xd
Dim As Integer a2 = a*a, b2 = b*b, fa2 = 4*a2, fb2 = 4*b2

x=0
y=radius
sigma = 2*b2+a2*(1-2*b)
   While (b2*x <= a2*y)
      draw_pixel(xc+x, yc+y, colour) : Rem   I. Quadrant
      draw_pixel(xc-x, yc+y, colour) : Rem   II. Quadrant
      draw_pixel(xc+x, yc-y, colour) : Rem   III. Quadrant
      draw_pixel(xc-x, yc-y, colour) : Rem   IV. Quadrant
     
If (filled) Then
      For xd=xc-x to xc+x
draw_pixel (xd, yc+y, colour)
draw_pixel (xd, yc-y, colour)
      Next xd
EndIf

If (sigma>= 0) Then
sigma += fa2*(1-y)
y=y-1
EndIf
sigma = sigma + b2*(4*x+6)
x=x+1
   Wend
   
   x=radius
   y=0
   sigma = 2*a2+b2*(1-2*a)
   While (a2*y <= b2*x)
      draw_pixel(xc+x, yc+y, colour) : Rem   I. Quadrant
      draw_pixel(xc-x, yc+y, colour) : Rem   II. Quadrant
      draw_pixel(xc+x, yc-y, colour) : Rem   III. Quadrant
      draw_pixel(xc-x, yc-y, colour) : Rem   IV. Quadrant

If (filled) Then
      For xd=xc-x to xc+x
draw_pixel (xd, yc+y, colour)
draw_pixel (xd, yc-y, colour)
      Next xd
EndIf

If (sigma>= 0) Then
sigma += fb2*(1-x)
x=x-1
EndIf
sigma = sigma + a2*(4*y+6)
y=y+1
   Wend
 
End Sub

I seem to have had a breakthrough in understanding the algorithm and FreeBasic and it's working fine, producing the same results as the previous function I was using.

Tomorrow I'll finish this off - at the moment it'll only draw circles, with a minor tweak to the input parameters it'll draw any ellipse, but I'll do that tomorrow when I have more time.

Is this what you're saying will convert to HDL easily?  ???
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 8143
  • Country: ca
    • LinkedIn
Re: FPGA VGA Controller for 8-bit computer
« Reply #2198 on: November 29, 2020, 10:50:51 pm »
Yes.  What you have is a modified linegen which makes 2 arcs generating the variables X&Y.  And if we look at the two 45 degree segments/halves, with a little effort, we will make that two loop code into a single loop code, called twice with a selection switch to draw each 45 degree half.  Then, for the output, we will make the 4x 'drawpixels' into 1 'drawpixel' and call the routine 4 times, each time with a switch selecting to output 1 of those 4 quadrants.

For the fill flag, we already have that programmed programmed into our verilog code where we currently fill the triangles and boxes.  All we need the ellipse to do is generate the outer edge of the arc line by line, or in a manner where we can see the y coordinate has moved.  Again, already coded as you know.

« Last Edit: November 29, 2020, 10:53:24 pm by BrianHG »
 

Offline DiTBho

  • Super Contributor
  • ***
  • Posts: 4247
  • Country: gb
Re: FPGA VGA Controller for 8-bit computer
« Reply #2199 on: November 29, 2020, 11:30:08 pm »
I have recently implemented a VT100-fully functioning-but-features-reduced engine in VHDL. It's small, and I like it because for the host-CPU it's basically an "advanced serial port" with a large FIFO. I want more features, so I am thinking about implementing a VT220, and about that I am also thinking about implementing a small Softcore (RISC-V multi-cycle) so I could program it in C. This way the next VT220-on-chip will be simpler and it will take less time and effort than thinking about how to design/develop/test/and verify algorithms in HDL.

So, regarding this project, I wonder: why not implementing a Softcore, say a RISC-V CPU, that does all the graphics stuff? This way, the Z80 would only need to move code and data into the GPU's ram (DMA is possible here), and the "graphic CPU" can be programmed in C more comfortably and more productively.
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf