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

0 Members and 2 Guests are viewing this topic.

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 7660
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #525 on: December 01, 2019, 05:30:16 pm »
Ahhh... of course!  |O  There's a 6-pixel delay on hde, vde, vs and hs.  How did I not see that?!
it's a side effect of having someone else dictate a design strategy to you without you creating it completely yourself finding out these issues on your own.  I'm trying to balance letting you figure out things you may have missed or not noticed with how much more to just give you.  If everything works ok so far, we have address generators, bytes/pixel selection, 2 color palettes and 1 video superimpose switch.

Then we can look at sprites.

As for you 'Host' ram interface mux, your easiest solution will be a state machine to select what gets sent to the GPU's host ram port.  Since it's an A/B selection, you can do this with an 'IF' statement, and predict the pipe length going through the GPU ram for when it's read_rdy flag should pulse on the output.
 
The following users thanked this post: FenTiger

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #526 on: December 01, 2019, 05:43:35 pm »
Yes, adding an HV triggers input to the osd_generator and again a through to an output would fix the problem and for now just do it.  You may use the new HW regs trick to make to verilog code look neater and tie the delay to the 6 'pipeline' parameter.

Okay, all done.  In testing - using X and Y_OFFSET set to 16 - I'm getting lines appearing at these values:

16, 655, 16, 495

So with X- and Y- offsets set to 0, I would expect values of 0, 639, 0, 479.... which is spot on.  All seems to be working fine now!  :-+ ;D ;D

EDIT: Latest project files.
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 7660
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #527 on: December 01, 2019, 09:20:35 pm »
Ok, you will now need to generate a configurable - bitplane-2-raster - Verilog module.  You already have a fixed one here in the vid_osd_generator:

Code: [Select]
assign osd_image          = char_line[(~dly6_disp_x[2:0])];

What this is doing is taking the byte 'char_line[7:0]' and selecting the bits from MSB to LSB according to the disp_x coordinate's 3 lsb.

However, we will now have 4 pixel types:

You will have an 8 bit input for bitplane the pixel data.
You will have an 8 bit input for the background default color.
You will have an 'x' coordinate input.
You will have the pena[3:0] input.
You will have a color mode input + 1 special input to latch a second adjacent byte in multi-color text mode and 16 bit RGB color mode.

You will pass through the 'x' coordinate
You will pass through the color mode.


1) monochrome 8bit.  Basically the existing above, however, you will 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.
2) 4 color 2 bit per pixel.  Now, your 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],
3) 16 color 4 bit.  Now, our 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]
3) 256 color 8 bit.  Now, our 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.

4) Special color text mode where you latch the first character as the bit plane graphic and the second character as a replacement for the background default color.  The rest should follow #1.
5) Special 16bit true color mode.  Your taking 2 sequential bytes, like the color text mode, and outputting a full 16 bits parallel on the output, however you will also output a 17th bit as a flag so that proceeding modules will know you are in this 16bit RGB mode.

Come back with ideas on how you want to achieve this...
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #528 on: December 01, 2019, 09:46:38 pm »
Ok, you will now need to generate a configurable - bitplane-2-raster - Verilog module.  You already have a fixed one here in the vid_osd_generator:

Code: [Select]
assign osd_image          = char_line[(~dly6_disp_x[2:0])];

What this is doing is taking the byte 'char_line[7:0]' and selecting the bits from MSB to LSB according to the disp_x coordinate's 3 lsb.

Yeah, just so I'm happy I understand this - char_line[7:0] is a byte returned from the GPU RAM where the character to be drawn is addressed at the current XY-position.  The 8-bits returned refer to the horizontal slice through the character at the current screen raster position, and the exact pixel is the bit in that byte referred to by ~dly6_disp_x[2:0], right?  ???

However, we will now have 4 pixel types:

You will have an 8 bit input for bitplane the pixel data.

Bitplane pixel data?  Is this the character tile set?

You will have an 8 bit input for the background default color.

This will be another bitplane, or a palette entry?

You will have an 'x' coordinate input.

So this sounds like ~dly6_disp_x[2:0]?  Or will this be an 'x' coordinate from the entire width of the display area?

You will have the pena[3:0] input.

This one I can handle.  ^-^

You will have a color mode input + 1 special input to latch a second adjacent byte in multi-color text mode and 16 bit RGB color mode.

These inputs don't sound like they'll be a parameters?  Could these be done with the HW_regs?

You will pass through the 'x' coordinate
You will pass through the color mode.

So these will need to be delayed by PIPE_DELAY accordingly?

1) monochrome 8bit.  Basically the existing above, however, you will 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.

So this is what we're using already, but using 4-bit colour taken from the MSN or LSN of the background colour based on whether the picture bitplane byte (or bit?) is 0 or 1?

2) 4 color 2 bit per pixel.  Now, your 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],
3) 16 color 4 bit.  Now, our 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]
3) 256 color 8 bit.  Now, our 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.

4) Special color text mode where you latch the first character as the bit plane graphic and the second character as a replacement for the background default color.  The rest should follow #1.
5) Special 16bit true color mode.  Your taking 2 sequential bytes, like the color text mode, and outputting a full 16 bits parallel on the output, however you will also output a 17th bit as a flag so that proceeding modules will know you are in this 16bit RGB mode.

 :o  Oh I'm going to need some serious guidance on creating this.   :-//
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 7660
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #529 on: December 01, 2019, 10:06:31 pm »
Ok, each byte coming from ram can either be set to:

2 color, B&W, ie, 1 byte of ram = 8 pixels.
4 color,  ie 1 byte of ram = 4 pixels, 4 possible colors each.
16 color, ie 1 byte of ram = 2 pixels, 16 possible colors each
256 color, ie 1 byte of ram = 1 pixel, 256 colors each.

Now it doesn't matter if the byte we receive is from a font memory (tile memory) or just raw pixel data.  The idea is to have a general purpose module where we can set an output video mode type, keep on feeding it bytes, doesn't matter from where, and an X coordinate.  This module should spit out pixels accordingly.

So, in 256 color mode, the X coordinate is ignored.  In 16 color mode, the X coordinate's 2 LSBs are ignored, it's just the 3rd bit which is used to determine whether to show the first half, or second half of the pixel.

In 2 color mode, we want to use the alternate background color byte to define the 2 possible 16 color to show.  If the pixel is 1, then present the upper 4 bits of the default input color byte.  If the pixel is a 0, then present the lower 4 bits of the default color byte input.

Let's start with this much.
« Last Edit: December 01, 2019, 10:15:41 pm by BrianHG »
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #530 on: December 02, 2019, 10:20:59 am »
Okay, I've got this far:

Code: [Select]
module bitplane_to_raster (

// inputs
input wire clk,
input wire [3:0] pc_ena,
input wire [7:0] pixel_data_in,
input wire [7:0] bg_color,
input wire [9:0] x_in,
input wire [1:0] colour_mode_in,
input wire two_byte_mode,

// outputs
output reg osd_ena,
output reg [7:0] osd_data_out,
output reg [9:0] x_out,
output reg [1:0] colour_mode_out

);

// parameters
parameter PIPE_DELAY = 2;

// *****************************************************************************
// *                                                                           *
// *  DELAY PIPES                                                              *
// *                                                                           *
// *****************************************************************************
reg [9:0] dly_x [9:0];
reg [1:0] dly_colour_mode [9:0];

always @ ( posedge clk ) begin

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

dly_x[0] <= x_in;
dly_x[9:1] <= dly_x[8:0];
x_out <= dly_x[PIPE_DELAY-1];

dly_colour_mode[0] <= colour_mode_in;
dly_colour_mode[9:1] <= dly_colour_mode[8:0];
colour_mode_out <= dly_colour_mode[PIPE_DELAY-1];

end // pc_ena

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


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

// color_mode_in determines the operating mode for the bitplane_to_raster module
// it is a 2-bit signal, providing 4 modes of operation to this module e.g.:
//
// 00 =   2 colour mode - 8 pixels per byte in GPU RAM
// 01 =   4 colour mode - 4 pixels -----"------"------
// 10 =  16 colour mode - 2 pixels -----"------"------
// 11 = 256 colour mode - 1 pixels -----"------"------

case (colour_mode_in)
2'h0 : begin // 1-bit (2 colour)

assign osd_data_out <= pixel_data[(x_out[2:0])];

end
2'h1 : begin // 2-bit (4 colour)

assign osd_data_out <= pixel_data[(x_out[2:1])];

end
2'h2 : begin // 4-bit (16 colour)

assign osd_data_out <= pixel_data[(x_out[2])];

end
2'h3 : begin // 8-bit (256 colour)

assign osd_data_out <= pixel_data;

end
endcase


endmodule

Obviously I know the code above won't work in its current state, the case statement is mostly placeholder to assist with my understanding as we flesh it out, but I'm not sure about the delay pipes - whether they're needed at all, for example - but they're there and can be removed if necessary.  Also, am I going in the right direction with the case statement, or should it be in an always block?

I'm a bit confused about this next bit, though - I've obviously misunderstood the output from this module (so it should be an 8-bit output?):

1) monochrome 8bit.  Basically the existing above, however, you will 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.

If the output is an 8-bit value, we're only talking about assigning the upper or lower nibble of that output byte - what happens to the other half?

Is this going in the right direction?
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 7660
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #531 on: December 02, 2019, 02:31:43 pm »
Will this help:


Now, in 2 byte 1 bit color mode, the 'Default Color Byte' will be the second 'Byte In' instead of the default single value input.
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #532 on: December 02, 2019, 05:50:03 pm »
Sooo... something like this?

Code: [Select]
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

if (pixel_data[(x_out[2:0])] == 1'b1) begin

assign osd_data_out[7:5] <= 1'b0;
assign osd_data_out[4] <= 1'b1;
assign osd_data_out[3:0] <= bg_color[7:4];

end
else begin

assign osd_data_out[7:5] <= 1'b0;
assign osd_data_out[4] <= 1'b0;
assign osd_data_out[3:0] <= bg_color[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]

assign osd_data_out <= pixel_data[(x_out[2:1])];

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]

assign osd_data_out <= pixel_data[(x_out[2])];

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

assign osd_data_out <= pixel_data;

end
endcase

So, according to the comments in the code (which I cut 'n' pasted from one of your previous posts for guidance), 1-bit and 8-bit modes should work according to the requirements.  It's just 2-bit and 4-bit I'm not sure about.  And haven't touched the special modes yet.  Your diagram helped me understand 1-bit colour mode, but according to the diagrams, 4-bit mode puts both halves of the pixel_data into two consecutive osd_data_out bytes with the top nibble set to 0 - is that right?  :-//
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 7660
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #533 on: December 02, 2019, 06:12:51 pm »
1 bit looks good.

2 bit should look like 4 bit, but you are tunneling bit AB, then CD, then EF, then GH into the bottom 2 bits of byte color out.

8 bit is obviously correct.

Then expand to 2 byte source data.  (This will mess thing up since the bytes come in sequentially adn you need to turn them into parallel ahead of everything else)


I know this doesn't look like the Amiga style bitplanes.  Where a separate bitplane layer comes from a different section of memory.  The Amiga was done this way since they wanted at least 32/64 colors with 14Mhz ram, 256 kilobytes on the original Amiga 1000.   We don't have speed issues, however, you did say you were going to a larger FPGA for internal ram and we do have the speed for true 8bit color, I chose the Atari800 style 2,4,16 color modes packed in 8 bits.
« Last Edit: December 02, 2019, 07:13:34 pm by BrianHG »
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #534 on: December 02, 2019, 07:44:48 pm »
Okay, I'm not 100% but I think this is what you're asking for?

Code: [Select]
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

if (pixel_data[(x_out[2:0])] == 1'b1) begin

assign osd_data_out[7:5] <= 1'b0;
assign osd_data_out[4] <= 1'b1;
assign osd_data_out[3:0] <= bg_color[7:4];

end
else begin

assign osd_data_out[7:5] <= 1'b0;
assign osd_data_out[4] <= 1'b0;
assign osd_data_out[3:0] <= bg_color[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]

assign osd_data_out[7:6] <= pixel_data[1:0];
assign osd_data_out[5:4] <= pixel_data[3:2];
assign osd_data_out[3:2] <= pixel_data[5:4];
assign osd_data_out[1:0] <= pixel_data[7:6];

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]

assign osd_data_out[7:4] <= pixel_data[3:0];
assign osd_data_out[3:0] <= pixel_data[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

assign osd_data_out <= pixel_data;

end
endcase
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 7660
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #535 on: December 02, 2019, 09:07:29 pm »
Nope...

Except for 8 bit, Pixels are coming in in a parallel fashion, you need to send them out in a series fashion.

Look at the 2 channels in my hand drawing for the 4 bit color.  The output is only 4 bits, bus switches between the source 2 groups of 4 bits depending on the x coordinate.
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 7660
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #536 on: December 02, 2019, 09:36:20 pm »
Think about is this way, you have 2 pixels in a byte, each can be 1 of the same 16 colors, how do you send those out, 1 16 color pixel at a time?

Now you have 4 pixels in 1 byte, 4 possible colors for each pixel, how do you send those out 1 4 color pixel at a time?

Now, you have 8 pixels in 1 byte, 2 possible colors, how do you send out those out, 1 2 color pixel at a time?  (Ignoring my bg_color[] thing)

 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #537 on: December 02, 2019, 10:36:44 pm »
Okay, how about this?

Code: [Select]
if (~two_byte_mode) begin // one-byte 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

if (pixel_data[(x_out[2:0])] == 1'b1) begin

assign osd_data_out[7:5] <= 3'b000;
assign osd_data_out[4] <= 1'b1;
assign osd_data_out[3:0] <= bg_color[7:4];

end
else begin

assign osd_data_out[7:5] <= 3'b000;
assign osd_data_out[4] <= 1'b0;
assign osd_data_out[3:0] <= bg_color[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]

assign osd_data_out[7:4] <= 4'b0000;
case (x_out[2:1])
2'h0 : begin
assign osd_data_out[3:2] <= pixel_data[7:6];
assign osd_data_out[1:0] <= pixel_data[7:6];
end
2'h1 : begin
assign osd_data_out[3:0] <= pixel_data[5:4];
assign osd_data_out[1:0] <= pixel_data[5:4];
end
2'h2 : begin
assign osd_data_out[3:0] <= pixel_data[3:2];
assign osd_data_out[1:0] <= pixel_data[3:2];
end
2'h3 : begin
assign osd_data_out[3:0] <= pixel_data[1:0];
assign osd_data_out[1:0] <= pixel_data[1:0];
end
end

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]

assign osd_data_out[7:4] <= 4'b0000;
if (x_out[3])
assign osd_data_out[3:0] <= pixel_data[3:0];
else
assign osd_data_out[3:0] <= pixel_data[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

assign osd_data_out <= pixel_data;

end
endcase
end // one-byte mode
else begin

end // two-byte mode
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 7660
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #538 on: December 02, 2019, 10:42:03 pm »
4 bit is correct.  With 2 bit, 4 color mode, why are you stacking 2 pixels at the output simultaneously.  There should only be 2 bottom bits coming out and all the 6 upper bits should = '0'.

Also, you cant 'assign' when you are making 1 reg equal another.

Also, get rid of the osd_data.  Let's call this one 'pixel_out'.
And for the input, call it 'ram_byte_in'.

These labels would make so much more sense.
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #539 on: December 02, 2019, 10:53:17 pm »
4 bit is correct.  With 2 bit, 4 color mode, why are you stacking 2 pixels at the output simultaneously.  There should only be 2 bottom bits coming out and all the 6 upper bits should = '0'.

Chalk that up to misunderstanding what you'd written previously about stacking bits and making copies every second pixel.  ::)

Also, you cant 'assign' when you are making 1 reg equal another.

pixel_data_in is a wire, if that makes any difference?  I know you can't assign in an 'always' block, but this isn't in one?  So I should just remove the assign keywords?

Also, get rid of the osd_data.  Let's call this one 'pixel_out'.
And for the input, call it 'ram_byte_in'.

These labels would make so much more sense.

Sure do.  Wasn't sure what to call them and, as I was working from the old vid_osd_generator, I used labels from that.  Okay, they're all renamed.  Full module code below.

Code: [Select]
module bitplane_to_raster (

// inputs
input wire clk,
input wire [3:0] pc_ena,
input wire [7:0] ram_byte_in,
input wire [7:0] bg_color,
input wire [9:0] x_in,
input wire [1:0] colour_mode_in,
input wire two_byte_mode,

// outputs
output reg pixel_out_ena,
output reg [7:0] pixel_out,
output reg [9:0] x_out,
output reg [1:0] colour_mode_out

);

// parameters
parameter PIPE_DELAY = 2;

// *****************************************************************************
// *                                                                           *
// *  DELAY PIPES                                                              *
// *                                                                           *
// *****************************************************************************
reg [9:0] dly_x [9:0];
reg [1:0] dly_colour_mode [9:0];

always @ ( posedge clk ) begin

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

dly_x[0] <= x_in;
dly_x[9:1] <= dly_x[8:0];
x_out <= dly_x[PIPE_DELAY-1];

dly_colour_mode[0] <= colour_mode_in;
dly_colour_mode[9:1] <= dly_colour_mode[8:0];
colour_mode_out <= dly_colour_mode[PIPE_DELAY-1];

end // pc_ena

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


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

// color_mode_in determines the operating mode for the bitplane_to_raster module
// it is a 2-bit signal, providing 4 modes of operation to this module e.g.:
//
// 00 =   2 colour mode - 8 pixels per byte in GPU RAM
// 01 =   4 colour mode - 4 pixels -----"------"------
// 10 =  16 colour mode - 2 pixels -----"------"------
// 11 = 256 colour mode - 1 pixels -----"------"------

if (~two_byte_mode) begin // one-byte 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

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

pixel_out[7:5] <= 3'b000;
pixel_out[4] <= 1'b1;
pixel_out[3:0] <= bg_color[7:4];

end
else begin

pixel_out[7:5] <= 3'b000;
pixel_out[4] <= 1'b0;
pixel_out[3:0] <= bg_color[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]

assign pixel_out[7:2] <= 6'b000000;
case (x_out[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
end

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]

pixel_out[7:4] <= 4'b0000;
if (x_out[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

pixel_out <= ram_byte_in;

end
endcase
end // one-byte mode
else begin

end // two-byte mode

endmodule


Actually, I've just tried compiling the code and it's throwing errors - should the raster generation section be in an 'always' block then?
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 7660
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #540 on: December 03, 2019, 12:23:04 am »
And this one is tricky, in 2 byte mode the ram_data_in will be giving you the bitplane data like usual when lsb of the X coordinate is 0 and it will be giving you the upper 8bits, or color_data when the X coordinate's lsb is 1.  Since you need the 2 data's in parallel, maybe you should latch these 2 firstly. and remember, 1 will need an extra delay to be parallel and you entire color pixel generator will now be up to a 3 pixel clock delay when all is said and done.


Remember, take and latch the ram data input and delay it.  Latch/hold it's value every second pixel if you are in 16bit pixel mode and latch the odd pixels into the upper 8 bits register.  We will want an output flag to signify 16 bit mode when not in the special colored text mode.
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 7660
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #541 on: December 03, 2019, 12:25:38 am »
4 bit is correct.  With 2 bit, 4 color mode, why are you stacking 2 pixels at the output simultaneously.  There should only be 2 bottom bits coming out and all the 6 upper bits should = '0'.

Chalk that up to misunderstanding what you'd written previously about stacking bits and making copies every second pixel.  ::)

Also, you cant 'assign' when you are making 1 reg equal another.

pixel_data_in is a wire, if that makes any difference?  I know you can't assign in an 'always' block, but this isn't in one?  So I should just remove the assign keywords?

Also, get rid of the osd_data.  Let's call this one 'pixel_out'.
And for the input, call it 'ram_byte_in'.

These labels would make so much more sense.

Sure do.  Wasn't sure what to call them and, as I was working from the old vid_osd_generator, I used labels from that.  Okay, they're all renamed.  Full module code below.

Code: [Select]
module bitplane_to_raster (

// inputs
input wire clk,
input wire [3:0] pc_ena,
input wire [7:0] ram_byte_in,
input wire [7:0] bg_color,
input wire [9:0] x_in,
input wire [1:0] colour_mode_in,
input wire two_byte_mode,

// outputs
output reg pixel_out_ena,
output reg [7:0] pixel_out,
output reg [9:0] x_out,
output reg [1:0] colour_mode_out

);

// parameters
parameter PIPE_DELAY = 2;

// *****************************************************************************
// *                                                                           *
// *  DELAY PIPES                                                              *
// *                                                                           *
// *****************************************************************************
reg [9:0] dly_x [9:0];
reg [1:0] dly_colour_mode [9:0];

always @ ( posedge clk ) begin

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

dly_x[0] <= x_in;
dly_x[9:1] <= dly_x[8:0];
x_out <= dly_x[PIPE_DELAY-1];

dly_colour_mode[0] <= colour_mode_in;
dly_colour_mode[9:1] <= dly_colour_mode[8:0];
colour_mode_out <= dly_colour_mode[PIPE_DELAY-1];

end // pc_ena

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


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

// color_mode_in determines the operating mode for the bitplane_to_raster module
// it is a 2-bit signal, providing 4 modes of operation to this module e.g.:
//
// 00 =   2 colour mode - 8 pixels per byte in GPU RAM
// 01 =   4 colour mode - 4 pixels -----"------"------
// 10 =  16 colour mode - 2 pixels -----"------"------
// 11 = 256 colour mode - 1 pixels -----"------"------

if (~two_byte_mode) begin // one-byte 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

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

pixel_out[7:5] <= 3'b000;
pixel_out[4] <= 1'b1;
pixel_out[3:0] <= bg_color[7:4];

end
else begin

pixel_out[7:5] <= 3'b000;
pixel_out[4] <= 1'b0;
pixel_out[3:0] <= bg_color[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]

assign pixel_out[7:2] <= 6'b000000;
case (x_out[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
end

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]

pixel_out[7:4] <= 4'b0000;
if (x_out[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

pixel_out <= ram_byte_in;

end
endcase
end // one-byte mode
else begin

end // two-byte mode

endmodule


Actually, I've just tried compiling the code and it's throwing errors - should the raster generation section be in an 'always' block then?
Not only that, but inside the 'pc_ena[3:0]==0'.  Also, I think you have the 16 color high and low bits backwards/mirrored.
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #542 on: December 03, 2019, 09:54:30 am »
Not only that, but inside the 'pc_ena[3:0]==0'.  Also, I think you have the 16 color high and low bits backwards/mirrored.

Are you sure?  I've set it up as per the comment you'd made previously (included as comments):

Code: [Select]
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]

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

I've interpreted the comments to mean if x_out[3] is 1, output bitplane [3:0] - which is the pixel_out[3:0] <= ram_byte_in[3:0]; line?  Does that definitely need swapping around then?  ???
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #543 on: December 03, 2019, 10:41:16 am »
Okay, ignore the content of the case selects for 16-bit mode, they're just placeholders from the 8-bit code.

I've updated the module to make a start on 16-bit mode.  In doing so, I'm wondering if we actually need a 'two_byte_mode' input at all?  It would make sense to just add another bit to colour_mode_in and put the 16-bit code in the main case..select block for any values of colour_mode_in with bit 2 set high?  Or do you have other plans for the separate 'two_byte_mode' input?

You may want to pay special attention to the DELAY PIPES block.  I've delayed RAM_BYTE_IN using the usual pipe method and am setting a new value, COLOUR_DATA, using the byte in the pipeline after the delayed RAM_BYTE value.  Hopefully that should work to get the two bytes in parallel for all cases where PIPE_DELAY > 1.

Now I'm just a little confused about the output in 16-bit mode, so haven't done anything with the placeholder code in the 16-bit case block.  Can you expand a little on what is required to make these two special cases work?

Code: [Select]
module bitplane_to_raster (

// inputs
input wire clk,
input wire [3:0] pc_ena,
input wire [7:0] ram_byte_in,
input wire [7:0] bg_color,
input wire [9:0] x_in,
input wire [1: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 [9:0] x_out,
output reg [1:0] colour_mode_out

);

// parameters
parameter PIPE_DELAY = 3; // minimum value of 2

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

// *****************************************************************************
// *                                                                           *
// *  DELAY PIPES                                                              *
// *                                                                           *
// *****************************************************************************
reg [9:0] dly_x [9:0];
reg [9:0] dly_ram_byte [7:0];
reg [9:0] dly_colour_mode [1:0];
reg [9:0] dly_mode_bit [1:0];

always @ ( posedge clk ) begin

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

dly_x[0] <= x_in;
dly_x[9:1] <= dly_x[8:0];
x_out <= dly_x[PIPE_DELAY-1];

dly_mode_bit[0] <= two_byte_mode;
dly_mode_bit[9:1] <= dly_mode_bit[8:0];
mode_16bit <= dly_mode_bit[PIPE_DELAY-1];

dly_ram_byte[0] <= ram_byte_in;
dly_ram_byte[9:1] <= dly_ram_byte[8:0];
ram_byte <= dly_ram_byte[PIPE_DELAY-1];
colour_data <= dly_ram_byte[PIPE_DELAY-2]; // in two-byte mode, colour_data should follow the ram_data byte

dly_colour_mode[0] <= colour_mode_in;
dly_colour_mode[9:1] <= dly_colour_mode[8:0];
colour_mode_out <= dly_colour_mode[PIPE_DELAY-1];

end // pc_ena

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


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

// color_mode_in determines the operating mode for the bitplane_to_raster module
// it is a 2-bit signal, providing 4 modes of operation to this module e.g.:
//
// 00 =   2 colour mode - 8 pixels per byte in GPU RAM
// 01 =   4 colour mode - 4 pixels -----"------"------
// 10 =  16 colour mode - 2 pixels -----"------"------
// 11 = 256 colour mode - 1 pixels -----"------"------

always @ (posedge clk) begin

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

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[(x_out[2:0])] == 1'b1) begin

pixel_out[7:5] <= 3'b000;
pixel_out[4] <= 1'b1;
pixel_out[3:0] <= bg_color[7:4];

end
else begin

pixel_out[7:5] <= 3'b000;
pixel_out[4] <= 1'b0;
pixel_out[3:0] <= bg_color[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] <= 6'b000000;

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

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

end
2'h1 : begin

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

end
2'h2 : begin

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

end
2'h3 : begin

pixel_out[1:0] <= ram_byte[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] <= 4'b0000;

if (x_out[3])
pixel_out[3:0] <= ram_byte[3:0];
else
pixel_out[3:0] <= ram_byte[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;

end

endcase

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

case (colour_mode_in[0])

1'h0 : begin // special colour text 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[(x_out[2:0])] == 1'b1) begin

pixel_out[7:5] <= 3'b000;
pixel_out[4] <= 1'b1;
pixel_out[3:0] <= bg_color[7:4];

end
else begin

pixel_out[7:5] <= 3'b000;
pixel_out[4] <= 1'b0;
pixel_out[3:0] <= bg_color[3:0];

end

end
1'h1 : begin // 16-bit (true colour)
// taking 2 sequential bytes, like the color text mode, and outputting
// a full 16 bits parallel on the output, however you will also output
// a 17th bit as a flag so that proceeding modules will know you are
// in this 16bit RGB mode.

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

pixel_out[7:2] <= 6'b000000;

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

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

end
2'h1 : begin

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

end
2'h2 : begin

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

end
2'h3 : begin

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

end
endcase

end

endcase

end // 16-bit mode

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

end // always@clk

endmodule
« Last Edit: December 03, 2019, 10:55:26 am by nockieboy »
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 7660
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #544 on: December 03, 2019, 04:14:55 pm »
Ok, for the 16 bit mode, we will use an alternate parallel byte input.  eg: currently you are using the bg_color[7:0].  place a second input 'ram_byte_h[7:0]'.  Use that byte that byte switch inside the first :

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

Where you select between bg_color[7:0] & ram_byte_h[7:0] depending on 16 bit color mode.  get rid of the second half or your code.

Next, instead of an 'if' just pixel shift/pipe through the 'two_byte_mode' to it's output and shift in a 'ram_byte_h[7:0]' to a 'pixel_out_h[7:0]'.  Make sure the pipes have the same delay as the pixel bitplane to raster processing.

Also, you only have 3 color modes, I want a fourth 'enable/disable'  in the disable, you should shift out '0' on the pixel_out and two_byte_mode outputs.  Remember that all the input controls should operate in parallel and any controls being fed through should come out with the appropriate pixel.

The x pixel positioning looks correct everywhere except in the 1 bit color mode.  You need to have the ' ~ ' just like in the original code when analyzing the bit based on pixel location.  My dyslexia got the 16 color and 2 color modes backwards...


For now, see if you can wire in the module to the existing font ram's output.  Adjust the osd_module's 6 pipeline delay setting, start choosing and wiring HW_Regs to the input controls.  Make a HW_Regs table so you know where your controls are and what they do.  And for the output, we will next make 2 palettes, 1 for text and 1 for regular 256 color graphics.  You will need to made default colors for these as well...
« Last Edit: December 03, 2019, 04:18:31 pm by BrianHG »
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #545 on: December 03, 2019, 04:36:21 pm »
Ok, for the 16 bit mode, we will use an alternate parallel byte input.  eg: currently you are using the bg_color[7:0].  place a second input 'ram_byte_h[7:0]'.  Use that byte that byte switch inside the first :

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

Where you select between bg_color[7:0] & ram_byte_h[7:0] depending on 16 bit color mode.  get rid of the second half or your code.

Sorry, didn't get that at all. :o  Again with the crayons and single-syllables please!  ;)  I've created an extra input, 'ram_byte_h[7:0]', but I don't follow with the rest of the instructions here.  :-[

Next, instead of an 'if' just pixel shift/pipe through the 'two_byte_mode' to it's output and shift in a 'ram_byte_h[7:0]' to a 'pixel_out_h[7:0]'.  Make sure the pipes have the same delay as the pixel bitplane to raster processing.

Instead of an if??  I've created another output, 'pixel_out_h [7:0]', and created a delay pipeline for ram_byte_h to pixel_out_htwo_byte_mode is already pipelined.

Also, you only have 3 color modes, I want a fourth 'enable/disable'  in the disable, you should shift out '0' on the pixel_out and two_byte_mode outputs.  Remember that all the input controls should operate in parallel and any controls being fed through should come out with the appropriate pixel.

3? Looks like 4 to me? 2, 4, 16 and 256 colour mode?  How would I implement this? Add another bit to colour_mode???

The x pixel positioning looks correct everywhere except in the 1 bit color mode.  You need to have the ' ~ ' just like in the original code when analyzing the bit based on pixel location.  My dyslexia got the 16 color and 2 color modes backwards...

Okay, have fixed that hopefully.  Current code below:

Code: [Select]
module bitplane_to_raster (

// inputs
input wire clk,
input wire [3:0] pc_ena,
input wire [7:0] ram_byte_in,
input wire [7:0] ram_byte_h,
input wire [7:0] bg_color,
input wire [9:0] x_in,
input wire [1: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 [1:0] colour_mode_out

);

// parameters
parameter PIPE_DELAY = 3; // minimum value of 2

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

// *****************************************************************************
// *                                                                           *
// *  DELAY PIPES                                                              *
// *                                                                           *
// *****************************************************************************
reg [9:0] dly_x [9:0];
reg [9:0] dly_ram_byte [7:0];
reg [9:0] dly_ram_h_byte [7:0];
reg [9:0] dly_colour_mode [1:0];
reg [9:0] dly_mode_bit [1:0];

always @ ( posedge clk ) begin

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

dly_x[0] <= x_in;
dly_x[9:1] <= dly_x[8:0];
x_out <= dly_x[PIPE_DELAY-1];

dly_mode_bit[0] <= two_byte_mode;
dly_mode_bit[9:1] <= dly_mode_bit[8:0];
mode_16bit <= dly_mode_bit[PIPE_DELAY-1];

dly_ram_byte[0] <= ram_byte_in;
dly_ram_byte[9:1] <= dly_ram_byte[8:0];
ram_byte <= dly_ram_byte[PIPE_DELAY-1];
colour_data <= dly_ram_byte[PIPE_DELAY-2]; // in two-byte mode, colour_data should follow the ram_data byte

dly_ram_h_byte[0] <= ram_byte_h;
dly_ram_h_byte[9:1] <= dly_ram_h_byte[8:0];
pixel_out_h <= dly_ram_h_byte[PIPE_DELAY-1];

dly_colour_mode[0] <= colour_mode_in;
dly_colour_mode[9:1] <= dly_colour_mode[8:0];
colour_mode_out <= dly_colour_mode[PIPE_DELAY-1];

end // pc_ena

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


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

// color_mode_in determines the operating mode for the bitplane_to_raster module
// it is a 2-bit signal, providing 4 modes of operation to this module e.g.:
//
// 00 =   2 colour mode - 8 pixels per byte in GPU RAM
// 01 =   4 colour mode - 4 pixels -----"------"------
// 10 =  16 colour mode - 2 pixels -----"------"------
// 11 = 256 colour mode - 1 pixels -----"------"------

always @ (posedge clk) begin

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

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[(~x_out[2:0])] == 1'b1) begin

pixel_out[7:5] <= 3'b000;
pixel_out[4] <= 1'b1;
pixel_out[3:0] <= bg_color[7:4];

end
else begin

pixel_out[7:5] <= 3'b000;
pixel_out[4] <= 1'b0;
pixel_out[3:0] <= bg_color[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] <= 6'b000000;

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

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

end
2'h1 : begin

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

end
2'h2 : begin

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

end
2'h3 : begin

pixel_out[1:0] <= ram_byte[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] <= 4'b0000;

if (x_out[3])
pixel_out[3:0] <= ram_byte[3:0];
else
pixel_out[3:0] <= ram_byte[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;

end

endcase

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

case (colour_mode_in[0])

1'h0 : begin // special colour text 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[(x_out[2:0])] == 1'b1) begin

pixel_out[7:5] <= 3'b000;
pixel_out[4] <= 1'b1;
pixel_out[3:0] <= bg_color[7:4];

end
else begin

pixel_out[7:5] <= 3'b000;
pixel_out[4] <= 1'b0;
pixel_out[3:0] <= bg_color[3:0];

end

end
1'h1 : begin // 16-bit (true colour)
// taking 2 sequential bytes, like the color text mode, and outputting
// a full 16 bits parallel on the output, however you will also output
// a 17th bit as a flag so that proceeding modules will know you are
// in this 16bit RGB mode.

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

pixel_out[7:2] <= 6'b000000;

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

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

end
2'h1 : begin

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

end
2'h2 : begin

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

end
2'h3 : begin

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

end
endcase

end

endcase

end // 16-bit mode

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

end // always@clk

endmodule
« Last Edit: December 03, 2019, 04:39:25 pm by nockieboy »
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 7660
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #546 on: December 03, 2019, 04:51:05 pm »
In 2 byte mode, if you keep your current mode of thinking, there is no 2bit color mode there, it's just the high byte and low byte being passed through.

It's 16 bit color mode. in other words, 65536 colors.

No palette for this mode.  That's why we need to pass-through flag to tell the palette section to change the way it works with a 16 bit pixel coming in instead of a 8 bit pixel.
« Last Edit: December 03, 2019, 04:52:42 pm by BrianHG »
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #547 on: December 03, 2019, 05:07:06 pm »
In 2 byte mode, if you keep your current mode of thinking, there is no 2bit color mode there, it's just the high byte and low byte being passed through.

It's 16 bit color mode. in other words, 65536 colors.

No palette for this mode.  That's why we need to pass-through flag to tell the palette section to change the way it works with a 16 bit pixel coming in instead of a 8 bit pixel.

There's no 1-bit or 4-bit mode either, surely?  But that doesn't clarify anything from my previous post.  I'm going away to have a lie down for a bit.  Maybe coming back after a break will help.  :scared:
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 7660
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #548 on: December 03, 2019, 05:13:09 pm »
In 2 byte mode, if you keep your current mode of thinking, there is no 2bit color mode there, it's just the high byte and low byte being passed through.

It's 16 bit color mode. in other words, 65536 colors.

No palette for this mode.  That's why we need to pass-through flag to tell the palette section to change the way it works with a 16 bit pixel coming in instead of a 8 bit pixel.


There's no 1-bit or 4-bit mode either, surely?  But that doesn't clarify anything from my previous post.  I'm going away to have a lie down for a bit.  Maybe coming back after a break will help.  :scared:

No, everything else is correct...
No touch...
In 16bit mode, all 16 bits make a single pixel. Normal ram_byte and ram_byte_h make 1 16 bit pixel
5 bits go straight to red, 6 bits go straight to green, 5 bits go straight to blue.

It's only the 1 bit text mode which is different, where we use the lower byte to construct the text font and the higher byte to select the foreground and background 2 possible 16 colors.

I guess you can engineer a 4 color font mode if you like, re-routing the upper byte into the upper 6 missing bits of the pixel out, then route the 2 top bits into the 2 bottom bits of the pixel_out_h byte.

This is your project after all.  Make what you like.


« Last Edit: December 03, 2019, 05:18:36 pm by BrianHG »
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #549 on: December 03, 2019, 05:54:13 pm »
I guess you can engineer a 4 color font mode if you like, re-routing the upper byte into the upper 6 missing bits of the pixel out, then route the 2 top bits into the 2 bottom bits of the pixel_out_h byte.

This is your project after all.  Make what you like.

No it's fine, I wasn't suggesting there should be a 4-colour font mode, I was just thinking through the implications of what you'd said.

Anywho, I'm at a bit of a stumbler here - I don't know what I need to do to progress the 16-bit mode code segment.  :-//
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf