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

0 Members and 1 Guest are viewing this topic.

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #650 on: December 10, 2019, 05:47:47 pm »
How did you come to the conclusion that the 'addr_out_a' is a clock behind the ram 'data_out_a'?
Does this image not represent the GPU_INTEL memory:
(Attachment Link)
Count the number of clocks from address in to data out by counting the number of D-flipflops in the attached image...
How many do you count?
How many D-flipflops has the 'addr_out_a' gone through since the 'addr_a' input?

I actually meant that addr_out_a is one clock behind addr_a, not data_out_a.  It's actually two clocks behind:

Code: [Select]
rd_addr_pipe_a <= addr_a;
addr_out_a <= rd_addr_pipe_a;

That's what I was referring to, but in any case the reason for using it was that data_out_a was getting ahead of itself using addr_a, which wasn't holding the right data and corrupting the output, I guess.  :-BROKE
« Last Edit: December 10, 2019, 05:50:31 pm by nockieboy »
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 7740
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #651 on: December 10, 2019, 06:04:16 pm »

And, we will be multiplying the 'multiport_gpu_ram' module 3 fold making a 15 read address ports for 15 parallel pixel reads, plus the 1 host_ port.

I'm going to need a bigger FPGA! :o  It'll maybe stretch to doubling the multiport_gpu_ram module with it's ~33 KB of RAM, but certainly won't manage three or more such modules.  :-\
I hate to burst your bubble, but, I just compiled you project for your Cyclone IV EP4CE6E22C8 after removing the bulk of the HV_triggers which would never reach the display directly.  You are only using 20% of your logic gates.

In your compilation report, under Fitter section, under resource section, under 'resource utilization by entity':

It says that 82 logic cells are used, and we are using 50% of the module, so, 1 full module would be around 164 logic cells.  * by 3 = 492, - original 82 = 410, since we are not adding ram, the change means 410 new additional logic cells for 15 read ports.  So, your current design total of 1330 logic cells of 6272 will increase to 1740 or 6272 = 28% usage.  That's only an 8% increase of used logic cells.

You are clear for a 15 port, 25Mhz x 16 bit read ram, or a read rate of 750 megabytes a second not counting the additional speed of the host port's 125 megabytes a second plus the palettes read speed.

« Last Edit: December 10, 2019, 06:06:15 pm by BrianHG »
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #652 on: December 10, 2019, 06:10:31 pm »
You are clear for a 15 port, 25Mhz x 16 bit read ram, or a read rate of 750 megabytes a second not counting the additional speed of the host port's 125 megabytes a second plus the palettes read speed.

Well colour me impressed, then.  ^-^ I thought you meant there'd be three RAM modules (each 16 KB).  ???

Ooh, latest project files attached.
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 7740
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #653 on: December 10, 2019, 06:20:46 pm »
You are clear for a 15 port, 25Mhz x 16 bit read ram, or a read rate of 750 megabytes a second not counting the additional speed of the host port's 125 megabytes a second plus the palettes read speed.

Well colour me impressed, then.  ^-^ I thought you meant there'd be three RAM modules (each 16 KB).  ???

Ooh, latest project files attached.
The first 3 ports are the text and bottom display windows.  The new 12 will be the 12 sprites, each again 1 window anywhere on the screen positioned by the HV_triggers, and any width and any height pointing anywhere in your bulk of GPU memory.
If you go to the 2 megabit lattice part, with it's 500MHz capable core ram, you will have room and cycle time for 30 read ports, leaving 27 sprites, or graphics windows overplayed on top of each other.

Now these window sprites can be larger than the display area too.  Any X&Y size from memory meaning a 27 layer parallax scrolling game scenery is possible in full color.  Talk about roasting the Amiga.

Each window layer can be at any resolution, any bitplane color depth, any zoom level, as long as they all share the same 256 color palette or, you set a layer to 65536 color mode where the palette will be bypassed.
« Last Edit: December 10, 2019, 06:25:00 pm by BrianHG »
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 7740
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #654 on: December 10, 2019, 06:37:10 pm »
A little more perspective:
The Amiga could only do 4 bitplanes in highres.

Here, in high res, you have a maximum of 16 bit per pixel with 14 superimposed parallel layers.  That's a 224 bitplane display.  Double that on the lattice part.
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #655 on: December 10, 2019, 06:49:49 pm »
The first 3 ports are the text and bottom display windows.  The new 12 will be the 12 sprites, each again 1 window anywhere on the screen positioned by the HV_triggers, and any width and any height pointing anywhere in your bulk of GPU memory.
If you go to the 2 megabit lattice part, with it's 500MHz capable core ram, you will have room and cycle time for 30 read ports, leaving 27 sprites, or graphics windows overplayed on top of each other.

Now these window sprites can be larger than the display area too.  Any X&Y size from memory meaning a 27 layer parallax scrolling game scenery is possible in full color.  Talk about roasting the Amiga.

Each window layer can be at any resolution, any bitplane color depth, any zoom level, as long as they all share the same 256 color palette or, you set a layer to 65536 color mode where the palette will be bypassed.

Aye carumba!  :o

So, the address generators are next?
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 7740
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #656 on: December 10, 2019, 06:59:33 pm »
Yes.

An address generator resets to a base HW_REGS reg stored memory address once every v-sync.
Every (Y size) H-syncs, a second HW_REGS is added to that address generator base defining the horizontal size of the bitmap to be displayed.
Another HW reg store a pixel X size counter and Y size counter defining the width and height of the active window.
Another 2 store the X&Y beginning point of the window already setup with the HV_triggers.
2 more X&Y period size counters define the width and height of the pixels. (call this an X&Y zoom, or scale)
Another HW reg stores the bitplane color mode, background color and enable/disable.

This above address generator is identical for all graphics / sprite layers.

For the text mode, another HW_Reg stores the base address and X&Y pixel size of the font to be passed through the read port ram a second time from it's first address generator.  Later in the Lattice part, with it's size, you may have the room for a text mode for every sprite layer making the Supernintendo's tile system look like a toy peanut.
« Last Edit: December 10, 2019, 07:15:08 pm by BrianHG »
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 7740
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #657 on: December 10, 2019, 07:13:14 pm »
An expansion patch to the bitplane to raster module:
Everywhere you have unused surplus pixel_out bits, ie:
---------------------------------
pixel_out[7:2] <= 6'b000000;
pixel_out[7:4] <= 4'b0000;
---------------------------------
Change it to:
---------------------------------
pixel_out[7:2] <= bg_color[7:2];
pixel_out[7:4] <= bg_color[7:4];
---------------------------------


You know what, just copy and paste the changes from here:
Code: [Select]
module bitplane_to_raster (

// inputs
input wire clk,
input wire pixel_in_ena,
input wire [3:0] pc_ena,
input wire [15:0] ram_byte_in, // ****** changed to 16 bit width
input wire [7:0] ram_byte_h,
input wire [7:0] bg_colour,
input wire [9:0] x_in,
input wire [2:0] colour_mode_in,
input wire two_byte_mode,

// outputs
output reg pixel_out_ena,
output reg mode_16bit, // high when in 16-bit mode
output reg [7:0] pixel_out,
output reg [7:0] pixel_out_h,
output reg [9:0] x_out,
output reg [2:0] colour_mode_out

);

// internal registers
//reg [7:0] colour_data;

// *****************************************************************************
// *                                                                           *
// *  PASS-THRUS                                                               *
// *                                                                           *
// *****************************************************************************

always @ ( posedge clk ) begin

if (pc_ena[3:0] == 0) begin

x_out <= x_in;
//colour_data <= ram_byte_in; // in two-byte mode, colour_data should follow the ram_data byte
colour_mode_out <= colour_mode_in;

end // pc_ena

end // always@clk
// *****************************************************************************


// *****************************************************************************
// *                                                                           *
// *  RASTER GENERATION                                                        *
// *                                                                           *
// *****************************************************************************

// color_mode_in determines the operating mode for the bitplane_to_raster module
// it is a 3-bit signal, providing 4 modes of operation to this module e.g.:
//
// 000 =   2 colour mode - 8 pixels per byte in GPU RAM
// 001 =   4 colour mode - 4 pixels -----"------"------
// 010 =  16 colour mode - 2 pixels -----"------"------
// 011 = 256 colour mode - 1 pixels -----"------"------
// 1xx = OFF

always @ (posedge clk) begin

if (pc_ena[3:0] == 0) begin

pixel_out_ena <= pixel_in_ena; // pass pixel_ena through to the output

if (~pixel_in_ena || colour_mode_in[2]) begin

// nothing to see here (disabled)
pixel_out <= 8'b00000000;
pixel_out_h <= 8'b00000000;

end
else if (~two_byte_mode) begin // 8-bit mode

case (colour_mode_in)

2'h0 : begin // 1-bit (2 colour) - 8 pixels per byte
// set the output pixel color to the first 4 bits of the background color
// when the bit on the picture bitplane byte is 0 and use the upper 4 bits
// when the bit on the bit-plane byte is high

mode_16bit <= 1'b0; // update mode_16bit output to 8-bit mode

if (ram_byte_in[(~x_in[2:0])] == 1'b1) begin

pixel_out[7:4] <= 4'b0000; // was: pixel_out[7:5] <= 3'b000;
pixel_out[3:0] <= bg_colour[7:4];

end
else begin

pixel_out[7:4] <= 4'b0000;
pixel_out[3:0] <= bg_colour[3:0];

end

end

2'h1 : begin // 2-bit (4 colour) - 4 pixels per byte
// output will be 2 bits stacked, 2 copies every second X pixel, you will
// output a 2 bit color. EG pixel 0&1 output bitplane[7:6],  pixel 2&3
// output bitplane[5:4], pixel 4&5 output bitplane[3:2]

mode_16bit <= 1'b0; // update mode_16bit output to 8-bit mode

pixel_out[7:2] <= bg_color[7:2];

case (x_in[2:1])
2'h0 : begin

pixel_out[1:0] <= ram_byte_in[7:6];

end
2'h1 : begin

pixel_out[1:0] <= ram_byte_in[5:4];

end
2'h2 : begin

pixel_out[1:0] <= ram_byte_in[3:2];

end
2'h3 : begin

pixel_out[1:0] <= ram_byte_in[1:0];

end
endcase

end

2'h2 : begin // 4-bit (16 colour) - 2 pixels per byte
// output will be 4 bits stacked, 4 copies every four X pixel, you will
// output a 4 bit color.  EG pixel 0,1,2,3 output bitplane[7:4], EG pixel
// 4,5,6,7 output bitplane[3:0]

mode_16bit <= 1'b0; // update mode_16bit output to 8-bit mode

pixel_out[7:4] <= bg_color[7:4];

if (x_in[3])
pixel_out[3:0] <= ram_byte_in[3:0];
else
pixel_out[3:0] <= ram_byte_in[7:4];

end

2'h3 : begin // 8-bit (256 colour) - 1 pixel per byte
// output will be 8 bits stacked, 8 copies every eight X pixel, you will
// output a 4 bit color.  EG pixel 0,1,2,3,4,5,6,7 output bitplane[7:0],
// yes that same 1 value will repeat 8 times is the source X counter
// counts through those numbers sequentially

mode_16bit <= 1'b0; // update the mode output to show whether it's 8 or 16-bit mode

pixel_out <= ram_byte_in[7:0];

end

endcase

end // 8-bit mode
else begin // 16-bit mode

case (colour_mode_in)

2'h0 : begin // special colour text mode
// 2-bit colour 2-byte mode
// latch ram_byte as the bit plane graphic and colour_data
// as a replacement for the background default color. The
// rest should follow #1.

mode_16bit <= 1'b0; // update mode_16bit output to 8-bit mode

if (ram_byte_in[(~x_in[2:0])] == 1'b1) begin

pixel_out[7:4] <= bg_color[7:4];
pixel_out[3:0] <= ram_byte_h[7:4];

end
else begin

pixel_out[7:4] <= bg_color[7:4];
pixel_out[3:0] <= ram_byte_h[3:0];

end

end
2'h3 : begin // 16-bit (true colour)
// taking 2 sequential bytes, like the color text mode, and outputting
// a full 16 bits parallel on the output

mode_16bit <= 1'b1; // update mode_16bit output to 16-bit mode

pixel_out <= ram_byte_in[7:0];
pixel_out_h <= ram_byte_h;

end

endcase

end // 16-bit mode

end // if (pc_ena[3:0] == 0)

end // always@clk

endmodule


So now, if you define a sprite with 4 or 16 color pixels, you may choose the upper palette bits of that sprite's layer by setting the matching upper bits of it's bg_color.  This way, each sprite can share or have it's own palette anywhere inside the 256 color palette as long as it isn't 256 color sprite where it obviously uses all 256 entries in the palette.
 
The following users thanked this post: nockieboy

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #658 on: December 10, 2019, 07:23:25 pm »
An address generator resets to a base HW_REGS reg stored memory address once every v-sync.
Every (Y size) H-syncs, a second HW_REGS is added to that address generator base defining the horizontal size of the bitmap to be displayed.
Another HW reg store a pixel X size counter and Y size counter defining the width and height of the active window.
Another 2 store the X&Y beginning point of the window already setup with the HV_triggers.
2 more X&Y period size counters define the width and height of the pixels. (call this an X&Y zoom, or scale)
Another HW reg stores the bitplane color mode, background color and enable/disable.

This above address generator is identical for all graphics / sprite layers.

Okay, having read that I'm thinking of moving the existing three HW registers (fore/background colour, two_byte_mode and colour_mode_in) from their current positions to 00, 01 and 02.  I can then just use the regs sequentially after that for the new features we're adding.  I feel it's more logical than them currently being sat in an island from 0A-0C, which was just an arbitrary address I plucked out of thin air.  Any issues with that?

For the text mode, another HW_Reg stores the base address and X&Y pixel size of the font to be passed through the read port ram a second time from it's first address generator.  Later in the Lattice part, with it's size, you may have the room for a text mode for every sprite layer making the Supernintendo's tile system look like a toy peanut.

Toy peanut. Love it.  ;D
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 7740
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #659 on: December 10, 2019, 07:33:10 pm »
Hang on, I'll lay out the address generator controls by byte tonight and we will decide the base for each address line generator since the HV_Triggers are separate of the line generators  and the first text mode and controls reside inside the 32 reset defaults.  This way when the 'reset' is hit, a default functional display will be produced.

With your current layout, before switching you core GPU INTEL ram from 125MHz to 250MHz, you will only have access to 1 text display and 3 sprites, 1 of which is the bottom background graphics display while the other 2 sit on top of everything else including the text.


« Last Edit: December 10, 2019, 08:44:51 pm by BrianHG »
 
The following users thanked this post: nockieboy

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #660 on: December 10, 2019, 07:40:18 pm »
An expansion patch to the bitplane to raster module...

...So now, if you define a sprite with 4 or 16 color pixels, you may choose the upper palette bits of that sprite's layer by setting the matching upper bits of it's bg_color.  This way, each sprite can share or have it's own palette anywhere inside the 256 color palette as long as it isn't 256 color sprite where it obviously uses all 256 entries in the palette.

Excellent, thanks.  :-+

I'm especially intrigued to find out how the sprites will move - I guess this will be driven by the Z80 setting an X,Y position in the HW regs every frame?
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 7740
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #661 on: December 10, 2019, 07:59:30 pm »
Yes, you need to set the HV trig as an X&Y, I'm still deciding if you will need to set the right side and bottom, or will I have additional X&Y counter...
To scroll the image off the left hand side of the screen or scroll it above the top of the display, your going to need to adjust 2 more bytes to reposition the raster's memory base address and shrink the visible width.
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 7740
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #662 on: December 10, 2019, 08:41:45 pm »
After the address generator, we will be modding the gpu_INTEL ram into a new wrapper module, running the the INTEL ram at 250MHz, making it's 2 ports into 4 ports at 125MHz.  And, we will be multiplying the 'multiport_gpu_ram' module 3 fold making a 15 read address ports for 15 parallel pixel reads, plus the 1 host_ port.  I hope you are up to the challenge.  (We would need 1GHz 8 bit static ram to replicate this, not counting the palette memory which would double that as we might do the same 15 ports there for true multiple degrees of translucency between all layers instead of between 2 layers, then just transparent color 0 / vs non-transparent.  Also in the lattice part, you will ran the ram at 500Mhz, in other words, you would need a 4GHz 8 bit static ram to replicate that display engine with it's 40 parallel read ports and 2x equivalent host_ ports.)

 :-\  I hope I'm up to the challenge, as well!  I might have to fold and ask for more breadcrumbs to get me through this more quickly, though.  Can't believe I've wasted a day today hunting for (and thankfully fixing) two silly bugs.  |O
Remember this one: https://www.eevblog.com/forum/fpga/fpga-vga-controller-for-8-bit-computer/msg2782402/#msg2782402
Just scroll down the message and look for that big red '1' and you will see what took me hours to find...
In the new year, I wont have the same time as now, your gonna have to get used to finding bugs all on your own...

« Last Edit: December 10, 2019, 08:43:41 pm by BrianHG »
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #663 on: December 10, 2019, 11:21:00 pm »
:-\  I hope I'm up to the challenge, as well!  I might have to fold and ask for more breadcrumbs to get me through this more quickly, though.  Can't believe I've wasted a day today hunting for (and thankfully fixing) two silly bugs.  |O
Remember this one: https://www.eevblog.com/forum/fpga/fpga-vga-controller-for-8-bit-computer/msg2782402/#msg2782402
Just scroll down the message and look for that big red '1' and you will see what took me hours to find...
In the new year, I wont have the same time as now, your gonna have to get used to finding bugs all on your own...

I know, and I really do appreciate the time and effort you've put in to help me.  :)  I'm operating on the assumption that you won't be around after the new year to help at all, so I'm hoping to get as much done before Christmas as possible; stupid mistakes allowing, of course.  :-[
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 7740
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #664 on: December 11, 2019, 04:26:53 am »
Next is the address generator/graphics instruction engine.

Here are the targeted controls/capable features:  (We want to make 1 identical algorithm which will be used 4 times.)

1) Enable/disable.  Requires 1 bit.

2) The base/beginning of a memory address which contains either the screen text data, font data, graphics data and sprite data.  (This eats 20 bits since we can address 1 megabyte for this address)

3) Vertical memory increment size.  When beginning a new line, this is the amount added every time to the base address.  (16 bits is fair, maximum 64kb wide picture.)

4) Pixel type.  1bit=8 pixels wide per byte 2 colors per pixel,
                       2bit=4 pixels per byte 4 colors per pixel,
                       4bit=2 pixels per byte 16 colors,
                       8bit=1 pixel per byte, 256 colors,
                      16bit=2 bytes per pixel, 65k true-color
          = 5 settings possible meaning requires 3 bits for this setting.

5)  X scale.  Counts the number of pixels wide each bitmap image pixel will occupy.  1 through 16 (4 bits)

6)  Y scale.  Counts the number of lines each bitmap image line  will occupy.  1 through 16 (4 bits)

7) Sub-pixel starting X&Y coordinates.  This setting vertically & horizontally shifts the image up and to the left by single pixels in text mode and 4/2/1 bit color modes.  IE, smooth scrolling of text horizontally by up to 7/8th of 1 character, then you can change the base memory address by 1 character and reset this setting back to 0 allowing you to move the text pixel by pixel horizontally and vertically. The shift 16 pixels x by 16 pixels y , or 8 bits total.

8 )  Special control for font size.  8x8 pixel bitmap to 16x16 bitmap.  4 bit control.

9)  Total number of video lines to render before loading a new set of the above controls.  This will allow you to switch video modes mid screen, EG: have a window of 40 column text for half the screen, then switch to 80 column text for the bottom half.

Have I missed anything.  The total here is around 14 control bytes, or, we will reserve 16 bytes per address generator and call it safe.

Extra Note: The horizontal and vertical windows and enables for the 16 sprites will be stored separately.  10bit X 10 bit Y.
Palettes also have a dedicated separate set of registers.  A programmable interrupt generator based on a selected line of video will also be added for smooth animation apps.

Ok, here we go:

     We will have a master H & V trigger for the horizontal reset and vertical reset.  This will be parameter assigned inside the address_generator-s, bitplane_to_raster-s, and palette_mixer-s.

     All register controls should be latched on the parameter selected ' H && V ' triggers so that the Z80 can make changes during the entire display time, however, the entire bulk of graphics / coordinate settings will be updated/refreshed once every V-sync.  The down side (except for the H&V trigger which we will fix later on) is that you cannot take 1 sprite and manipulate it's settings in real time during the middle of the screen refresh to trick construct multiple additional sprites.  However, the pros are a ton of CPU cycles may be used to construct an animated display during the entire display time while the next V-sync, all screen geometries will be refreshed all at once.  Also, with 12 sprites, and a jump to 24 sprites with the Lattice FPGA part, each one of the 24 being able to be larger than 640x480, like 65536x65536 viewport window, if you complain about this real-time limitation, I'll be on a flight over seas to murder you...  ;)

Each line generator will also have a parameter to identify which 1 set of H&V trigger will be used to position their top-left X&Y coordinate location and a second H&V trigger to define the bottom right screen coordinates of the image.

Next, #1 & #4.  We will squeeze these 2 together with a few other options.  This HW_REG will hold the control for the bitplane_to_raster module.  All 8 bits will be sent into that module and define the video mode.  Off, 1 bit color, 2 bit color, 4 bit color, 8 bit color, 16 bit color, special 2 byte text color font.  Color Palette type (either ARGB 4444, RGB 565, or 16 bit 565 thru, or mixed 16bit 656 thru with last 256 colors assigned through the palette).  (5 or 6 bits consumed, 2 spare bits for future features)

Next, bg_color and fg_color.  These are 2 HW_REG byte values used for the 1 bit color mode and for where within the palette the remaining missing upper bits of the 16 and 4 color modes will be placed.

Next, #2  The base/beginning of a memory address which contains either the screen text data, font data, graphics data and sprite data. 3 HW_REG bytes.
Next, #3  The X size/width in bytes of the image in memory being displayed.  2 HW_REG bytes.

next, X&Y scale, and sub_pixel X&Y start.  1 byte each for a total of 4 bytes.

We are at 16 bytes to control every feature of the window line generator.  15 address generators, + 16 bytes for a few global controls means 256 bytes for the HE_REGS.  You will need to double this setting on the Lattice FPGA as it will have 30 address generators.  More if you want to add an audio system.

When a line generator is in the special ascii text mode, it will have the same controls, but with 1 or 2 changes to define the font's X&Y size attributes plus 1 input in the module will be used to receive an incoming ASCII character from the multiport_ram output from a previous line generator to realtime point to a font's position to construct a bitmap.  This means you need 2 address generators with 2 ram ports to construct a text/character tile based display on the screen, though the second line generator is mostly dead and just passes through a bunch of wired signals.

For our development path, we will start with a simple line generator which will open a 256 color display window on the screen, with adjustable X&Y coordinates and X&Y size.  We will use port 3 on our multiport ram and add bitplane to raster module to receive the output, then feed the palette mixer module 565 input.

We wont touch the text yet.  Need to first get the basics working.

More to come after some sleep...
« Last Edit: December 11, 2019, 04:32:39 am by BrianHG »
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 7740
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #665 on: December 11, 2019, 12:07:00 pm »
Step #1, minor touch up to the bitplane_to_raster.v module:

     Add HW_REGS input to the bitplane_to_raster module.
     Add a parameter which defines the base of the 3 control bytes:
             The video mode byte, the bg_color byte and fg_color byte.
     Change you 'case' statement to accommodate the the new byte bitplane mode selection from the above post which controls everything in 1 byte.  Like 16bit color mode, pixel color bits, ect.  (document these bit switches)

     Add a new input wire named 'enable_in'.  When low, the pixel outputs will go to '0', identical to having the video mode set to 'off'.

     Add a new output reg called 'enable_out'.  Goes low when 'off' or 'enable_in' is low.  Goes high when 'enable_in' is high and any selected valid video mode.

Start documenting the new controls.  Also note that each display layer will have it's own bitplane_to_raster.v, so, this means 5 of them in you current design going up to 15 once we double the clock of your core memory, each with their own controls.

First part of the address generator, window coordinates, H&V size and H&V scale coming this afternoon.
« Last Edit: December 11, 2019, 12:17:34 pm by BrianHG »
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 7740
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #666 on: December 11, 2019, 12:59:16 pm »
Change you 'case' statement to accommodate the the new byte bitplane mode selection from the above post which controls everything in 1 byte.  Like 16bit color mode, pixel color bits, ect.  (document these bit switches)

And now you know why within my RS232_Debugger HEX editor, you may click on the bits in the Binary view of the memory byte you are editing, and that bit will toggle allowing you to switch on and off multiple features controlled by different bits in a single byte.
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #667 on: December 11, 2019, 01:34:59 pm »
Step #1, minor touch up to the bitplane_to_raster.v module:

     Add HW_REGS input to the bitplane_to_raster module.
     Add a parameter which defines the base of the 3 control bytes:
             The video mode byte, the bg_color byte and fg_color byte.
     Change you 'case' statement to accommodate the the new byte bitplane mode selection from the above post which controls everything in 1 byte.  Like 16bit color mode, pixel color bits, ect.  (document these bit switches)

     Add a new input wire named 'enable_in'.  When low, the pixel outputs will go to '0', identical to having the video mode set to 'off'.

     Add a new output reg called 'enable_out'.  Goes low when 'off' or 'enable_in' is low.  Goes high when 'enable_in' is high and any selected valid video mode.

Start documenting the new controls.  Also note that each display layer will have it's own bitplane_to_raster.v, so, this means 5 of them in you current design going up to 15 once we double the clock of your core memory, each with their own controls.

First part of the address generator, window coordinates, H&V size and H&V scale coming this afternoon.

All done.  Have hardwired enable_in HIGH in vid_osd_generator for testing.

I've removed colour_mode_in and colour_mode_out from the bitplane_to_raster module as they're not used now that the video_mode byte has taken over setting the mode.  All working as expected so far.

bitplane_to_raster.v:
Code: [Select]
module bitplane_to_raster (

// inputs
input wire clk,
input wire pixel_in_ena,
input wire two_byte_mode,
input wire enable_in,
input wire [3:0]  pc_ena,
input wire [15:0] ram_byte_in,
input wire [7:0]  ram_byte_h,
input wire [7:0]  bg_colour,
input wire [9:0]  x_in,
//input wire [2:0]  colour_mode_in,
input wire [7:0]  GPU_HW_Control_regs[0:(2**HW_REGS_SIZE-1)],

// outputs
output reg enable_out,
output reg pixel_out_ena,
output reg mode_16bit, // high when in 16-bit mode
output reg [7:0] pixel_out,
output reg [7:0] pixel_out_h,
output reg [9:0] x_out
//output reg [2:0] colour_mode_out

);

parameter CTRL_BYTE_BASE = 8'h0; // defines the base address of the 3 control bytes (video_mode, bg_colour, fg_colour) in the HW_REGS

// *****************************************************************************
// video_mode byte - CTRL_BYTE_BASE + 0
//
// This HW_REG defines the video mode:
//
// 0000 - Off
// 0001 - 1 bit color
// 0010 - 2 bit color
// 0011 - 4 bit color
// 0100 - 8 bit color
// 0101 - 16 bit color
// 0110 - Special 2-byte text colour mode
// 0111 - ARGB4444
// 1000 - RGB565
// 1001 - 16 bit 565 thru
// 1010 - Mixed 16-bit 656 thru with last 256 colors assigned through the palette
// *****************************************************************************

parameter HW_REGS_SIZE = 8; // default size for hardware register bus - set by HW_REGS parameter in design view

// *****************************************************************************
// *                                                                           *
// *  PASS-THRUS                                                               *
// *                                                                           *
// *****************************************************************************

always @ ( posedge clk ) begin

if (pc_ena[3:0] == 0) begin

x_out <= x_in;
//colour_mode_out <= colour_mode_in;

end // pc_ena

end // always@clk
// *****************************************************************************


// *****************************************************************************
// *                                                                           *
// *  RASTER GENERATION                                                        *
// *                                                                           *
// *****************************************************************************

// color_mode_in determines the operating mode for the bitplane_to_raster module
// it is a 3-bit signal, providing 4 modes of operation to this module e.g.:
//
// 000 =   2 colour mode - 8 pixels per byte in GPU RAM
// 001 =   4 colour mode - 4 pixels -----"------"------
// 010 =  16 colour mode - 2 pixels -----"------"------
// 011 = 256 colour mode - 1 pixels -----"------"------
// 1xx = OFF

always @ (posedge clk) begin

if (pc_ena[3:0] == 0) begin

pixel_out_ena <= pixel_in_ena; // pass pixel_ena through to the output
enable_out <= enable_in;

if (~pixel_in_ena || ~enable_in) begin

// disable output as not in display area or enable_in is LOW
pixel_out <= 8'b00000000;
pixel_out_h <= 8'b00000000;

end
else begin

case (GPU_HW_Control_regs[CTRL_BYTE_BASE + 0]) // select case based on video_mode HW_reg

2'h0 : begin // off
// disable output as turned off
pixel_out <= 8'b00000000;
pixel_out_h <= 8'b00000000;
enable_out <= 1'b0; // set enable_out LOW
end

2'h1 : begin // 1-bit (2 colour) - 8 pixels per byte

mode_16bit <= 1'b0; // set mode_16bit output to 8-bit mode
enable_out <= 1'b1; // set enable_out HIGH

if (ram_byte_in[(~x_in[2:0])] == 1'b1) begin

pixel_out[7:4] <= 4'b0000;
pixel_out[3:0] <= bg_colour[7:4];

end
else begin

pixel_out[7:4] <= 4'b0000;
pixel_out[3:0] <= bg_colour[3:0];

end

end

2'h2 : begin // 2-bit (4 colour) - 4 pixels per byte

mode_16bit <= 1'b0; // set mode_16bit output to 8-bit mode
enable_out <= 1'b1; // set enable_out HIGH

pixel_out[7:2] <= bg_colour[7:2];

case (x_in[2:1])
2'h0 : begin

pixel_out[1:0] <= ram_byte_in[7:6];

end
2'h1 : begin

pixel_out[1:0] <= ram_byte_in[5:4];

end
2'h2 : begin

pixel_out[1:0] <= ram_byte_in[3:2];

end
2'h3 : begin

pixel_out[1:0] <= ram_byte_in[1:0];

end
endcase

end

2'h3 : begin // 4-bit (16 colour) - 2 pixels per byte

mode_16bit <= 1'b0; // set mode_16bit output to 8-bit mode
enable_out <= 1'b1; // set enable_out HIGH

pixel_out[7:4] <= bg_colour[7:4];

if (x_in[3])
pixel_out[3:0] <= ram_byte_in[3:0];
else
pixel_out[3:0] <= ram_byte_in[7:4];

end

2'h4 : begin // 8-bit (256 colour) - 1 pixel per byte

mode_16bit <= 1'b0; // set mode_16bit output to 8-bit mode
enable_out <= 1'b1; // set enable_out HIGH

pixel_out <= ram_byte_in[7:0];

end

2'h5 : begin // 16-bit (true colour)

mode_16bit <= 1'b1; // set mode_16bit output to 16-bit mode
enable_out <= 1'b1; // set enable_out HIGH

pixel_out <= ram_byte_in[7:0];
pixel_out_h <= ram_byte_h;

end

2'h6 : begin // special colour text mode

mode_16bit <= 1'b0; // set mode_16bit output to 8-bit mode
enable_out <= 1'b1; // set enable_out HIGH

if (ram_byte_in[(~x_in[2:0])] == 1'b1) begin

pixel_out[7:4] <= bg_colour[7:4];
pixel_out[3:0] <= ram_byte_h[7:4];

end
else begin

pixel_out[7:4] <= bg_colour[7:4];
pixel_out[3:0] <= ram_byte_h[3:0];

end

end

endcase

end

end // if (pc_ena[3:0] == 0)

end // always@clk

endmodule
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #668 on: December 11, 2019, 01:37:36 pm »
Obviously, the case doesn't have any selects for the palette modes (0111-1010) yet - I assume that's correct and have left them out for the moment.

And now you know why within my RS232_Debugger HEX editor, you may click on the bits in the Binary view of the memory byte you are editing, and that bit will toggle allowing you to switch on and off multiple features controlled by different bits in a single byte.

It's almost as if you're working to some kind of plan...  ;)
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 7740
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #669 on: December 11, 2019, 01:54:26 pm »
Step #1, minor touch up to the bitplane_to_raster.v module:

     Add HW_REGS input to the bitplane_to_raster module.
     Add a parameter which defines the base of the 3 control bytes:
             The video mode byte, the bg_color byte and fg_color byte.
     Change you 'case' statement to accommodate the the new byte bitplane mode selection from the above post which controls everything in 1 byte.  Like 16bit color mode, pixel color bits, ect.  (document these bit switches)

     Add a new input wire named 'enable_in'.  When low, the pixel outputs will go to '0', identical to having the video mode set to 'off'.

     Add a new output reg called 'enable_out'.  Goes low when 'off' or 'enable_in' is low.  Goes high when 'enable_in' is high and any selected valid video mode.

Start documenting the new controls.  Also note that each display layer will have it's own bitplane_to_raster.v, so, this means 5 of them in you current design going up to 15 once we double the clock of your core memory, each with their own controls.

First part of the address generator, window coordinates, H&V size and H&V scale coming this afternoon.

All done.  Have hardwired enable_in HIGH in vid_osd_generator for testing.

I've removed colour_mode_in and colour_mode_out from the bitplane_to_raster module as they're not used now that the video_mode byte has taken over setting the mode.  All working as expected so far.

bitplane_to_raster.v:
Code: [Select]
module bitplane_to_raster (

// inputs
input wire clk,
input wire pixel_in_ena,
input wire two_byte_mode,
input wire enable_in,
input wire [3:0]  pc_ena,
input wire [15:0] ram_byte_in,
input wire [7:0]  ram_byte_h,
input wire [7:0]  bg_colour,
input wire [9:0]  x_in,
//input wire [2:0]  colour_mode_in,
input wire [7:0]  GPU_HW_Control_regs[0:(2**HW_REGS_SIZE-1)],

// outputs
output reg enable_out,
output reg pixel_out_ena,
output reg mode_16bit, // high when in 16-bit mode
output reg [7:0] pixel_out,
output reg [7:0] pixel_out_h,
output reg [9:0] x_out
//output reg [2:0] colour_mode_out

);

parameter CTRL_BYTE_BASE = 8'h0; // defines the base address of the 3 control bytes (video_mode, bg_colour, fg_colour) in the HW_REGS

// *****************************************************************************
// video_mode byte - CTRL_BYTE_BASE + 0
//
// This HW_REG defines the video mode:
//
// 0000 - Off
// 0001 - 1 bit color
// 0010 - 2 bit color
// 0011 - 4 bit color
// 0100 - 8 bit color
// 0101 - 16 bit color
// 0110 - Special 2-byte text colour mode
// 0111 - ARGB4444
// 1000 - RGB565
// 1001 - 16 bit 565 thru
// 1010 - Mixed 16-bit 656 thru with last 256 colors assigned through the palette
// *****************************************************************************

parameter HW_REGS_SIZE = 8; // default size for hardware register bus - set by HW_REGS parameter in design view

// *****************************************************************************
// *                                                                           *
// *  PASS-THRUS                                                               *
// *                                                                           *
// *****************************************************************************

always @ ( posedge clk ) begin

if (pc_ena[3:0] == 0) begin

x_out <= x_in;
//colour_mode_out <= colour_mode_in;

end // pc_ena

end // always@clk
// *****************************************************************************


// *****************************************************************************
// *                                                                           *
// *  RASTER GENERATION                                                        *
// *                                                                           *
// *****************************************************************************

// color_mode_in determines the operating mode for the bitplane_to_raster module
// it is a 3-bit signal, providing 4 modes of operation to this module e.g.:
//
// 000 =   2 colour mode - 8 pixels per byte in GPU RAM
// 001 =   4 colour mode - 4 pixels -----"------"------
// 010 =  16 colour mode - 2 pixels -----"------"------
// 011 = 256 colour mode - 1 pixels -----"------"------
// 1xx = OFF

always @ (posedge clk) begin

if (pc_ena[3:0] == 0) begin

pixel_out_ena <= pixel_in_ena; // pass pixel_ena through to the output
enable_out <= enable_in;

if (~pixel_in_ena || ~enable_in) begin

// disable output as not in display area or enable_in is LOW
pixel_out <= 8'b00000000;
pixel_out_h <= 8'b00000000;

end
else begin

case (GPU_HW_Control_regs[CTRL_BYTE_BASE + 0]) // select case based on video_mode HW_reg

2'h0 : begin // off
// disable output as turned off
pixel_out <= 8'b00000000;
pixel_out_h <= 8'b00000000;
enable_out <= 1'b0; // set enable_out LOW
end

2'h1 : begin // 1-bit (2 colour) - 8 pixels per byte

mode_16bit <= 1'b0; // set mode_16bit output to 8-bit mode
enable_out <= 1'b1; // set enable_out HIGH

if (ram_byte_in[(~x_in[2:0])] == 1'b1) begin

pixel_out[7:4] <= 4'b0000;
pixel_out[3:0] <= bg_colour[7:4];

end
else begin

pixel_out[7:4] <= 4'b0000;
pixel_out[3:0] <= bg_colour[3:0];

end

end

2'h2 : begin // 2-bit (4 colour) - 4 pixels per byte

mode_16bit <= 1'b0; // set mode_16bit output to 8-bit mode
enable_out <= 1'b1; // set enable_out HIGH

pixel_out[7:2] <= bg_colour[7:2];

case (x_in[2:1])
2'h0 : begin

pixel_out[1:0] <= ram_byte_in[7:6];

end
2'h1 : begin

pixel_out[1:0] <= ram_byte_in[5:4];

end
2'h2 : begin

pixel_out[1:0] <= ram_byte_in[3:2];

end
2'h3 : begin

pixel_out[1:0] <= ram_byte_in[1:0];

end
endcase

end

2'h3 : begin // 4-bit (16 colour) - 2 pixels per byte

mode_16bit <= 1'b0; // set mode_16bit output to 8-bit mode
enable_out <= 1'b1; // set enable_out HIGH

pixel_out[7:4] <= bg_colour[7:4];

if (x_in[3])
pixel_out[3:0] <= ram_byte_in[3:0];
else
pixel_out[3:0] <= ram_byte_in[7:4];

end

2'h4 : begin // 8-bit (256 colour) - 1 pixel per byte

mode_16bit <= 1'b0; // set mode_16bit output to 8-bit mode
enable_out <= 1'b1; // set enable_out HIGH

pixel_out <= ram_byte_in[7:0];

end

2'h5 : begin // 16-bit (true colour)

mode_16bit <= 1'b1; // set mode_16bit output to 16-bit mode
enable_out <= 1'b1; // set enable_out HIGH

pixel_out <= ram_byte_in[7:0];
pixel_out_h <= ram_byte_h;

end

2'h6 : begin // special colour text mode

mode_16bit <= 1'b0; // set mode_16bit output to 8-bit mode
enable_out <= 1'b1; // set enable_out HIGH

if (ram_byte_in[(~x_in[2:0])] == 1'b1) begin

pixel_out[7:4] <= bg_colour[7:4];
pixel_out[3:0] <= ram_byte_h[7:4];

end
else begin

pixel_out[7:4] <= bg_colour[7:4];
pixel_out[3:0] <= ram_byte_h[3:0];

end

end

endcase

end

end // if (pc_ena[3:0] == 0)

end // always@clk

endmodule


Dont forget to remove the bg_color input and make a bg_color and fg_color wires which are assigned to the adjacent HW_Register for the control mode.  Also, for now, make the default base address 16 decimal as we don't want to interfere with the first HV_Triggers.

Also, we never got into this, but, are you using little or big endian for your data in the Z80?  I don't know how the Z80 handles 16bit and 32bit math.  We may want to get this fixed now...
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #670 on: December 11, 2019, 02:04:58 pm »
Also, we never got into this, but, are you using little or big endian for your data in the Z80?  I don't know how the Z80 handles 16bit and 32bit math.  We may want to get this fixed now...

Little-endian.  But it's what you do with it that counts.  :-DD

EDIT:  In terms of 16-bit and 32-bit math, it doesn't really do a lot - it is capable of doing limited 16-bit math with the instruction set, but mostly it's up to the user to write routines that do anything more complicated than addition or subtraction of 16-bit numbers.
« Last Edit: December 11, 2019, 02:08:25 pm by nockieboy »
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #671 on: December 11, 2019, 02:22:10 pm »
Dont forget to remove the bg_color input and make a bg_color and fg_color wires which are assigned to the adjacent HW_Register for the control mode.  Also, for now, make the default base address 16 decimal as we don't want to interfere with the first HV_Triggers.

Done - although fg_colour isn't set up in the case yet, so I can only change the background colour.  Foreground is black, so I guess I need to replace all the pixel_out[7:4] assignments from 4'b0000 to fg_colour?
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #672 on: December 11, 2019, 04:36:33 pm »
Fixed foreground (font) colour in 1-bit mode:

Code: [Select]
2'h1 : begin // 1-bit (2 colour) - 8 pixels per byte

mode_16bit <= 1'b0; // set mode_16bit output to 8-bit mode
enable_out <= 1'b1; // set enable_out HIGH

if (ram_byte_in[(~x_in[2:0])] == 1'b1) begin

pixel_out <= fg_colour;

end
else begin

pixel_out <= bg_colour;

end

end

I figured that's how you planned on it working in 2-colour mode - there's either going to be the foreground or background colour, which the above case caters for.  I've removed the old byte-splitting and am just assigning the entire colour byte to the pixel output now, so it's 2-colour mode, from a palette of 256 colours.  Hope that's okay?
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 7740
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #673 on: December 11, 2019, 05:08:35 pm »
Also, we never got into this, but, are you using little or big endian for your data in the Z80?  I don't know how the Z80 handles 16bit and 32bit math.  We may want to get this fixed now...

Little-endian.  But it's what you do with it that counts.  :-DD

EDIT:  In terms of 16-bit and 32-bit math, it doesn't really do a lot - it is capable of doing limited 16-bit math with the instruction set, but mostly it's up to the user to write routines that do anything more complicated than addition or subtraction of 16-bit numbers.
As I'm sure you know, this is important as it defines when you write or copy all these settings, right now, the lower memory address holds the MSB of a 16 bit or 32 bit number.  As you increase the memory address, you head toward the LSB.  So, I assume we are keeping this setup?

IE, you wont be using any compilers/interpreters which store 16bit ints backwards making this graphics card incompatible?

ANY other viewers with Z80 experience have any comments?
« Last Edit: December 11, 2019, 06:22:22 pm by BrianHG »
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #674 on: December 11, 2019, 06:43:41 pm »
As I'm sure you know, this is important as it defines when you write or copy all these settings, right now, the lower memory address holds the MSB of a 16 bit or 32 bit number.  As you increase the memory address, you head toward the LSB.  So, I assume we are keeping this setup?

IE, you wont be using any compilers/interpreters which store 16bit ints backwards making this graphics card incompatible?

Hmm..  ???  This could be a bit of an issue if the conversion for little-endian to big-endian is done by the Z80 - it'll add processing overhead to any interactions with the GPU.

EDIT: Of course my suggestion to convert in the z80_bridge wouldn't work, as only 1 byte is written at a time by the Z80 so it would be impossible to work out if a 16-bit word is being written and thus needed to be reversed...
« Last Edit: December 11, 2019, 06:48:07 pm by nockieboy »
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf