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

0 Members and 33 Guests are viewing this topic.

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #250 on: November 09, 2019, 10:32:39 am »
Good show  :-+ .  You see all the comments I've added to Verilog code are a must read.

Absolutely.  The more comments, the better.  ;)

Now:
1) please post the final OSD code so I can proof the working version.
2) Will you be working on the code this weekend? What time?
3) What is you current FMAX?  Which FPGA part# are you using?

1) See attachment in this post
2) Likely, yes, but I can't commit to specific times with any certainty, but most likely in the evenings (so anything from 12pm-7pm your time?) - have to placate the missus somehow.  ;D
3) FMAX is currently 182.65 MHz, with a Restricted Fmax of 163.03 MHz.  Apparently limited due to high minimum pulse width violation (tch)?  It was around 200 MHz before the changes yesterday.  :-\

Next steps:
1.  Set up the PLL to give you a 125Mhz clock.  This means we will change the PC_ENA coming out of your 'sync_generator' into a 4 bit number with a parameter in the sync generator which selects the maximum count of 4, then resets to 0.  All the attached graphics modules which had 1 wire input PC_ENA will now need PC_ENA[3:0], and all the if (PC_ENA) will change to if (PC_ENA[3:0] == 0).

Is this right?

Code: [Select]
altsyncram altsyncram_component_osd_font ( .wren_a ( wren_font ), .clock0 (clk), .clock1 (clk), .clocken1 (pc_ena[3:0] == 0),
.address_a (wr_addr[9:0]), .address_b (font_pos[9:0]),
.data_a (wr_data[7:0]), .q_b (sub_wire1));

Hmm.. my monitor is saying 'out of range', quoting 19.5 KHz / 24 Hz...  either I've made a typo or there's a clock division error on PC_ENA.  If PC_ENA[3:0] == 0 is dividing  by 8, surely?  Or are my maths out?  That'll give a PC_ENA frequency of 15 MHz?

Using pc_ena[3:2] == 0 gives an output the monitor can understand, though, even though it's a little... wrong.  I think there's a memory timing issue here?

868952-0
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #251 on: November 09, 2019, 10:44:46 am »
Yes, I agree, the unary ~ operator instead of the '8-' or '7-' would give the compiler less headaches.
I dunno, ~ just seemed more natural to me. "Be the bits you wish to see in the world."

Anyway this is turning out to be an interesting lab/demonstration in pair programming. I'm going to try to sit back as a good audience member and watch quietly. :)

Yep, I changed this earlier - I knew the 8 - ... was a complete hack, but I didn't have time to look up a better way to do it.  Using ~ didn't occur at the time!  ::)
 
The following users thanked this post: BrianHG

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 8143
  • Country: ca
    • LinkedIn
Re: FPGA VGA Controller for 8-bit computer
« Reply #252 on: November 09, 2019, 10:47:42 am »
Ok, in sync_gen.v, the 'pc_ena' should read:
---------------------------------------------------
if (pc_ena == PIX_CLK_DIVIED) pc_ena <= 0;
else pc_ena <= pc_ena +1;
---------------------------------------------------

Make 'PIX_CLK_DIVIED' a parameter and make the default value 4.


In the ' if (pc_ena[3:2] == 0)   // once per pixel '
it should read:
if (pc_ena[2:0] == 0)     // for now, use [2:0] on your small FPGA...
^^^^ Change this one everywhere!!!

This means a single pixel advance will happen 1 clock after the 'PIX_CLK_DIVIED' value makes pc_ena[3:0] = to 0.

« Last Edit: November 09, 2019, 10:57:04 am by BrianHG »
 
The following users thanked this post: nockieboy

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 8143
  • Country: ca
    • LinkedIn
Re: FPGA VGA Controller for 8-bit computer
« Reply #253 on: November 09, 2019, 10:54:04 am »
Your PLL clock should have a ratio of X10/2 for 125MHz.


Your current FMAX slowdown is due to this line:
assign osd_image[0] = char_line[(~dly4_disp_x[3:1])];

Though correct, since osd_image[0] is not a register, this is just a mass of gates.  For now, you are clearing 125MHz and we will be fixing this later on.

If 'osd_image[0]' was a register, this would give an additional clock cycle for the bit selector to do select bits 7 through 0, then that output would be shifted off to the and gates and video stencil.
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #254 on: November 09, 2019, 10:56:26 am »
Looking good again.  :)

Fmax has dropped to 162.31 MHz though.
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #255 on: November 09, 2019, 11:04:53 am »
Your PLL clock should have a ratio of X10/2 for 125MHz.

My board's clock is 50 MHz... that would make the PLL clock 250 MHz.  :-//
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 8143
  • Country: ca
    • LinkedIn
Re: FPGA VGA Controller for 8-bit computer
« Reply #256 on: November 09, 2019, 11:06:50 am »
FMAX going up and down can mean logic has been simplified out due to design change, or errors.

Now, look as my post about the 2 sub modules you need to make:

'multiport_gpu_ram.v'
and
'gpu_dual_port_ram_INTEL.v'

Begin with the ''multiport_gpu_ram.v''. 
begin the module with all the inputs and outputs labeled as you like.
Make a second clock and clock enable input for the Z80 cpu port side.  It's nice just to have it there...

Add at least these 1 parameters:
Maximum address bit (name it what you like, this one will configure the maximum size of memory)

As a strategy, keep the address ports all 20bit, even if you configure the memory to 10 bits.  You will bury the address wiring limit inside the ram module only, but you still wan to pass all 20 bits through the module whether you use them or not.


 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 8143
  • Country: ca
    • LinkedIn
Re: FPGA VGA Controller for 8-bit computer
« Reply #257 on: November 09, 2019, 11:07:54 am »
Your PLL clock should have a ratio of X10/2 for 125MHz.

My board's clock is 50 MHz... that would make the PLL clock 250 MHz.  :-//
My bad...
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #258 on: November 09, 2019, 11:22:15 am »
Next step #2:  Copy and rename the OSD generator to graphics generator.  You will remove both dual port 'altsynccrams' and replace it with a new verilog module 'multiport_gpu_ram.v'.  In your new 'multiport_gpu_ram.v' you will place a single 'altsynccrams' which is 4Kilobytes, and you will make IO registers for:

Okay, with you so far (I think) - see attached file.

5 read addressed [20 bit] (Your graphics system will handle a maximum 1 megabyte frame buffer), 5 auxiliary read commands[8bit], 5 data output[8bit], 5 passed through read addresses and 5 passed through auxiliary read commands, all synchronous to the PC_ENA[3:0] position 0, an active pixel cycle.

Need to confirm I'm reading this right - you want 5x 20-bit read address buses, 5x 8-bit read buses, 5x 8-bit data buses, and 5x pass-thru address buses and 5x pass-thru command buses???!?!

How does this fit into the dual-port paradigm?  I thought it was bad enough trying to get a dual-port memory chip, let alone a five-port one!

Any chance of some single-syllable clarification on this next step?  :o  ;D
« Last Edit: November 09, 2019, 11:23:51 am by nockieboy »
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 8143
  • Country: ca
    • LinkedIn
Re: FPGA VGA Controller for 8-bit computer
« Reply #259 on: November 09, 2019, 11:40:26 am »
You will only have a  dual port ram which will be inside the ''gpu_dual_port_ram_INTEL.v'' module.

The 'multiport_gpu_ram.v' doesn't have the 'altsyncram_component_gpu_ram' in it, it will have the ''gpu_dual_port_ram_INTEL.v'' called in it where you will unify the that dual memory's IO ports.

What the 'multiport_gpu_ram.'v contains is a 5:1 mux for all those address inputs, each selected during the pena[2:0] 5 phases 0 through 4, then feeds that 1 result address into the read address of 1 read port of the dual port ram hidden inside the ''gpu_dual_port_ram_INTEL.v'' module.  Then take the data coming out and latch that data into the correct 1 of five data output registers which are all parallel represented as 8 x 8bit outputs.

Since our ram will now run at 125MHz, having it's ENA hard wired to 1/ON, we can feed the 5 read address and latch the 5 sequential data outputs into 5 sequential registers making that ram appear to have 5 parallel read ports running at 25MHz.

With you 25MHz pixel port, you can now fetch the character memory, then fetch the font pixel, then feed that output from 1 same block of memory, instead you will now need to deal with different base memory address.  This is the next step after the 5 port ram works.

As for the second dedicated read/write port for the 8 bit CPU, that one will be a pass-through.
« Last Edit: November 09, 2019, 11:43:00 am by BrianHG »
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 8143
  • Country: ca
    • LinkedIn
Re: FPGA VGA Controller for 8-bit computer
« Reply #260 on: November 09, 2019, 11:48:12 am »
Remember, except for the 8bit CPU ports, make all the outputs I specified into separate registers.
The core issue will be the MUX selector and how you parallel delay the piped function to maintain FMAX.
For now, keep it basic and remember to use a register at each point.

This means that the memory which once took 2 clocks from in to out, will now also have additional piped stages for the address and data output to consider, and also all the final results will need to land back on pena[2:0] phase 0.
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #261 on: November 09, 2019, 12:21:53 pm »
Remember, except for the 8bit CPU ports, make all the outputs I specified into separate registers.
The core issue will be the MUX selector and how you parallel delay the piped function to maintain FMAX.
For now, keep it basic and remember to use a register at each point.

This means that the memory which once took 2 clocks from in to out, will now also have additional piped stages for the address and data output to consider, and also all the final results will need to land back on pena[2:0] phase 0.

Okay, this is where I am so far with multiport_gpu_ram.v:

Code: [Select]
module multiport_gpu_ram (

input clk, // Primary clk input (125 MHz)
input [3:0] pc_ena, // Pixel clock enable
input clk_host, // Host (Z80) clock input
input hc_ena, // Host (Z80) clock enable

// address buses (input)
input [19:0] address_0,
input [19:0] address_1,
input [19:0] address_2,
input [19:0] address_3,
input [19:0] address_4,
input [19:0] addr_host,

// auxilliary read command buses (input)
input [7:0] aux_read_0,
input [7:0] aux_read_1,
input [7:0] aux_read_2,
input [7:0] aux_read_3,
input [7:0] aux_read_4,

// address buses (pass-thru outputs)
output reg [19:0] addrPT_0,
output reg [19:0] addrPT_1,
output reg [19:0] addrPT_2,
output reg [19:0] addrPT_3,
output reg [19:0] addrPT_4,

// auxilliary read command buses (pass-thru output)
output reg [7:0] auxRdPT_0,
output reg [7:0] auxRdPT_1,
output reg [7:0] auxRdPT_2,
output reg [7:0] auxRdPT_3,
output reg [7:0] auxRdPT_4,

// data buses (output)
output reg [7:0] dataOUT_0,
output reg [7:0] dataOUT_1,
output reg [7:0] dataOUT_2,
output reg [7:0] dataOUT_3,
output reg [7:0] dataOUT_4,
output [7:0] data_host

);

// dual-port GPU RAM handler

// define the maximum address bit - effectively the RAM size
parameter MAX_ADDR_BIT = 20;

// create a GPU RAM instance
gpu_dual_port_ram_INTEL gpu_RAM(
// TBC
);

always @(posedge clk) begin

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



end // pc_ena

end // always @clk

endmodule

addr_host and data_host are host Z80 buses.

Am I going along the right lines?
« Last Edit: November 09, 2019, 12:27:19 pm by nockieboy »
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 8143
  • Country: ca
    • LinkedIn
Re: FPGA VGA Controller for 8-bit computer
« Reply #262 on: November 09, 2019, 12:35:46 pm »
Yes, good work, except, for the first time, you will be working differently with the 'if (pc_ena[2:0] == 0) begin'

Next, make a reg 'address_mux[]' & 'aux_read_mux[]', (use you preferred name) and make those registers run at 125Mhz, serial sequencing through the 5 pc_ena[2:0] stages.

Now, there is one little annoying problem here, a 20+8 bits in total, mux 5:1 may run too slow for 125Mhz, if so, later on as we add new inputs to the ports, you may need to make that muxing algorithm take 3 clocks instead of 1 clock.  Basically 3 parallel 2:1 muxers, those outputs feed another 2 parallel 2:1 muxers, than that last one will feed a final 2:1 muxer.



 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #263 on: November 09, 2019, 12:44:04 pm »
Here's the skeleton of the 5:1 mux:

Code: [Select]
always @(posedge clk) begin

// perform 5:1 mux for all inputs to the dual-port RAM
case (pc_ena[2:0])
3'b011 : ;
3'b100 : ;
3'b101 : ;
3'b110 : ;
3'b111 : ;

end // always @clk

Just trying to work out what to put into the case statements based on your comment about making the data available on the next p_ena[2:0] phase 0...  :o

Yes, good work, except, for the first time, you will be working differently with the 'if (pc_ena[2:0] == 0) begin'

Next, make a reg 'address_mux[]' & 'aux_read_mux[]', (use you preferred name) and make those registers run at 125Mhz, serial sequencing through the 5 pc_ena[2:0] stages.

Now, there is one little annoying problem here, a 20+8 bits in total, mux 5:1 may run too slow for 125Mhz, if so, later on as we add new inputs to the ports, you may need to make that muxing algorithm take 3 clocks instead of 1 clock.  Basically 3 parallel 2:1 muxers, those outputs feed another 2 parallel 2:1 muxers, than that last one will feed a final 2:1 muxer.

Ookay, I think that's kind of what I've started to do (running the case statement at 125 MHz).
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 8143
  • Country: ca
    • LinkedIn
Re: FPGA VGA Controller for 8-bit computer
« Reply #264 on: November 09, 2019, 12:50:20 pm »
Remember, the case for pc_ena[2:0] goes 0,1,2,3,4,0...  Remember, I'm adding in the sync generator and resetting back to 0 after 4, the case of b111 for pc_ena[2:0] will never be reached.

This is not like the 8 bit font where at the left most coordinate of the screen xpos=0 the first pixel in the font's byte is the 7th bit, then 6th bit, then ect...
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #265 on: November 09, 2019, 12:55:38 pm »
Remember, the case for pc_ena[2:0] goes 0,1,2,3,4,0...  Remember, I'm adding in the sync generator and resetting back to 0 after 4, the case of b111 for pc_ena[2:0] will never be reached.

This is not like the 8 bit font where at the left most coordinate of the screen xpos=0 the first pixel in the font's byte is the 7th bit, then 6th bit, then ect...

Ah yes,  I'd forgotten about the reset after the 5th count, hence the confusion over the bit count in the case statement.

Code: [Select]
reg address_mux[19:0], aux_read_mux[7:0];

// create a GPU RAM instance
gpu_dual_port_ram_INTEL gpu_RAM(
// TBC
);

always @(posedge clk) begin

// perform 5:1 mux for all inputs to the dual-port RAM
case (pc_ena[2:0])
3'b000 : begin
address_mux <= address_0;
aux_read_mux <= aux_read_0;
addrPT_0 <= address_0;
end
3'b001 : begin
address_mux <= address_1;
aux_read_mux <= aux_read_1;
addrPT_1 <= address_1;
end
3'b011 : begin
address_mux <= address_2;
aux_read_mux <= aux_read_2;
addrPT_2 <= address_2;
end
3'b100 : begin
address_mux <= address_3;
aux_read_mux <= aux_read_3;
addrPT_3 <= address_3;
end
3'b101 : begin
address_mux <= address_4;
aux_read_mux <= aux_read_4;
addrPT_4 <= address_4;
end
endcase

end // always @clk
« Last Edit: November 09, 2019, 12:58:02 pm by nockieboy »
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 8143
  • Country: ca
    • LinkedIn
Re: FPGA VGA Controller for 8-bit computer
« Reply #266 on: November 09, 2019, 01:11:26 pm »
Ok, next, we will start our  ''gpu_dual_port_ram_INTEL.v'' module.

In that module, you should have an input wire read port with address in , aux in, and pc_ena_in[2:0], data out, address out, aux out, pc_ena out[]  and host port wires and bidir.

Now, the altsyncram is obsolete, so, what you should do is within quartus, block diagram editor, double click on a blank area and insert a megafunction from the LPM_Ram_dp section.  Make sure launch wizard is selected on.

Next configure the memory for 1 read/write port and 1 read only port.  Clock/register the addresses going in and register the data coming out.  Before completing the function, sen me a snapshot of you screen example block diagram.

If it looks good, when finishing the wizard, select 'generate verilog source code/source files'.  Quartus will generate an example verilog.v file where you will copy and paste the LPM_Ram_dp/altsyncram into your ''gpu_dual_port_ram_INTEL.v'' source file where you will wire through the memories ports.
In that ''gpu_dual_port_ram_INTEL.v'', you will also pipe through the read address and aux input to the address output as well as pipe through the pc_ena_in[2:0] to an output pc_ena_out[2:0].

Don't forget about also having a MAX_RAM_ADDRESS parameter in this sub module as well.
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #267 on: November 09, 2019, 01:21:41 pm »
Ok, next, we will start our  ''gpu_dual_port_ram_INTEL.v'' module.

In that module, you should have an input wire read port with address in , aux in, and pc_ena_in[2:0], data out, address out, aux out, pc_ena out[]  and host port wires and bidir.

Now, the altsyncram is obsolete, so, what you should do is within quartus, block diagram editor, double click on a blank area and insert a megafunction from the LPM_Ram_dp section.  Make sure launch wizard is selected on.

I don't have an LPM_Ram_dp section?



 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #268 on: November 09, 2019, 01:23:39 pm »
The post today was interesting, however.  Have received the Cyclone IV EasyFPGA board - has an EP4CE6 on board, with SDRAM and VGA connector (as well as PS2, which will be handy later).

Is it worth me updating to the latest Quartus software to support this chip?  I was using Quartus II 13.0sp1 as it was the last version to support the Cyclone II I was using...

Will mean a delay in proceedings whilst I get it all set up.
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 8143
  • Country: ca
    • LinkedIn
Re: FPGA VGA Controller for 8-bit computer
« Reply #269 on: November 09, 2019, 01:27:49 pm »
Ok, next, we will start our  ''gpu_dual_port_ram_INTEL.v'' module.

In that module, you should have an input wire read port with address in , aux in, and pc_ena_in[2:0], data out, address out, aux out, pc_ena out[]  and host port wires and bidir.

Now, the altsyncram is obsolete, so, what you should do is within quartus, block diagram editor, double click on a blank area and insert a megafunction from the LPM_Ram_dp section.  Make sure launch wizard is selected on.

I don't have an LPM_Ram_dp section?

[ Attachment Invalid Or Does Not Exist ]

Strange, it should be in the memory compiler section.  Scroll down and expand/shrink the list.  Don't type LPM in the query box, it may just be called ram_dp, dual_port_ram...
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #270 on: November 09, 2019, 01:30:25 pm »
Strange, it should be in the memory compiler section.  Scroll down and expand/shrink the list.  Don't type LPM in the query box, it may just be called ram_dp, dual_port_ram...

Is it because it's an older Quartus II version?  It may not have the module you're looking for?

 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 8143
  • Country: ca
    • LinkedIn
Re: FPGA VGA Controller for 8-bit computer
« Reply #271 on: November 09, 2019, 01:35:59 pm »
The post today was interesting, however.  Have received the Cyclone IV EasyFPGA board - has an EP4CE6 on board, with SDRAM and VGA connector (as well as PS2, which will be handy later).

Is it worth me updating to the latest Quartus software to support this chip?  I was using Quartus II 13.0sp1 as it was the last version to support the Cyclone II I was using...

Will mean a delay in proceedings whilst I get it all set up.
For now, while I'm available, let's work with what you have in hand.  You will need to transfer your project on your own time.
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 8143
  • Country: ca
    • LinkedIn
Re: FPGA VGA Controller for 8-bit computer
« Reply #272 on: November 09, 2019, 01:36:35 pm »
Strange, it should be in the memory compiler section.  Scroll down and expand/shrink the list.  Don't type LPM in the query box, it may just be called ram_dp, dual_port_ram...

Is it because it's an older Quartus II version?  It may not have the module you're looking for?

(Attachment Link)
Try the ram-2port.  It's not the quartus version, I think its that you are using a CycloneII.  It shouldn't matter as the newer FPGA will support all the memory features of the earlier ones.

 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #273 on: November 09, 2019, 01:46:47 pm »
Okay, this is where I am currently...

 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 8143
  • Country: ca
    • LinkedIn
Re: FPGA VGA Controller for 8-bit computer
« Reply #274 on: November 09, 2019, 01:51:31 pm »
You got it.  Now, remember the specs.

2 different clocks.
1 port read only.
other port read & write.
8 bits
13 addressees, or, 8192 words.

and clock the input controls as well as the output data.  As you change your options, the illustration will update showing you what you are creating.  send me the final image + the verilog.v example text...
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf