Author Topic: FPGA VGA Controller for 8-bit computer  (Read 421953 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 #875 on: January 06, 2020, 01:21:11 pm »
No, the Z80_bridge updates aren't working properly - the first one causes write errors.  Haven't tested the second as a result.
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 7720
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #876 on: January 06, 2020, 01:36:52 pm »
No, the Z80_bridge updates aren't working properly - the first one causes write errors.  Haven't tested the second as a result.
The first one, the one which is in the .zip file, is identical to the one you deemed perfect.  All I've done is remove the comments and unused registers and parameters.

The only other difference is that I turned off the 'Perform Register Retiming For Performance' feature in the assignment settings, compiler settings, 'Advanced Settings (Fitter)...' button.

You can try turning that back on and see if there is a difference.

 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #877 on: January 06, 2020, 02:07:05 pm »
The project was fine - it's the first z80_bridge.v.txt update that seems to have caused issues?
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 7720
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #878 on: January 06, 2020, 02:08:46 pm »
The project was fine - it's the first z80_bridge.v.txt update that seems to have caused issues?

Are you talking about ''Z80_bridge_1-write.v''?

If so, I need to know...
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #879 on: January 06, 2020, 02:36:36 pm »
Yes.  :-+
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 7720
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #880 on: January 06, 2020, 03:02:40 pm »
Ok, change line 104 of 'Z80_bridge_1-write.v' to this:

Code: [Select]
gpu_wr_ena      <=  Write_GPU_RAM && ~last_Z80_WR ; // Pulse the GPU ram's write enable at the BEGINNING of the Z80 write cycle.
And test.



 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #881 on: January 06, 2020, 03:30:33 pm »
Ok, change line 104 of 'Z80_bridge_1-write.v' to this:

Code: [Select]
gpu_wr_ena      <=  Write_GPU_RAM && ~last_Z80_WR ; // Pulse the GPU ram's write enable at the BEGINNING of the Z80 write cycle.
And test.

No, that's not working either - lots of errors caused when writing to the GPU RAM.
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 7720
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #882 on: January 06, 2020, 03:44:45 pm »
You have got to be kidding me....
Right?

It's almost as if for some silly reason, we need to fire off multiple of the same writes...
Unless the data lines are bouncing around and eventually the right data gets in...

Give this a try.  All I have done is make the gpu_wr_ena go active for 2 consecutive clocks instead of 1 single clock after a Z80 write has been confirmed.

Code: [Select]
module Z80_bridge (

// input
input wire reset, // GPU reset signal
input wire GPU_CLK, // GPU clock (125 MHz)
input wire Z80_CLK, // Microcom clock signal (8 MHz)
input wire Z80_M1n, // Z80 M1 - active LOW
input wire Z80_MREQn, // Z80 MREQ - active LOW
input wire Z80_WRn, // Z80 WR - active LOW
input wire Z80_RDn, // Z80 RD - active LOW
input wire [21:0] Z80_addr, // Microcom 22-bit address bus
input wire [7:0] Z80_wData, // Z80 DATA bus to pass incoming data to GPU RAM
input wire [7:0] gpu_rData,
input wire gpu_rd_rdy, // one-shot signal from mux that data is ready

// output
output reg Z80_245data_dir, // control level converter direction for data flow - HIGH = A -> B (toward FPGA)
output reg [7:0]  Z80_rData, // Z80 DATA bus to return data from GPU RAM to Z80
output reg Z80_rData_ena, // flag HIGH to write data back to Z80
output reg Z80_245_oe, // OE for 245 level translator *** ACTIVE LOW ***
output reg gpu_wr_ena, // flag HIGH for 1 clock when writing to GPU RAM
output reg gpu_rd_req, // flag HIGH for 1 clock when reading from GPU RAM
output reg [19:0] gpu_addr, // connect to Z80_addr in vid_osd_generator to address GPU RAM
output reg [7:0]  gpu_wdata, // 8-bit data bus to GPU RAM in vid_osd_generator

    input wire  sel_pclk,  // make HIGH to trigger the Z80 bus on the positive edge of Z80_CLK
    input wire  sel_nclk   // make LOW  to trigger the Z80 bus on the negative edge of Z80_CLK
);

// TODO:
//
// 1) Prevent reads to GPU RAM above top of GPU RAM
// 2) Respond with appropriate data to any requests from Microcom ROM identification routines
//

parameter MEMORY_RANGE  = 3'b010; // Z80_addr[21:19] == 3'b010 targets the 512KB 'window' at 0x100000-0x17FFFF (Socket 3 on the Microcom)
parameter MEM_SIZE_BITS = 15; //

wire Z80_mreq, Z80_write, Z80_read, Write_GPU_RAM;
wire Read_GPU_RAM;
wire Z80_clk_pos,Z80_clk_neg,Z80_clk_trig;

reg Z80_clk_delay, last_Z80_WR, last_Z80_RD, mem_valid_range, mem_window, last_Z80_WR2, last_Z80_WR3 ;


assign Z80_clk_pos   = ~Z80_clk_delay &&  Z80_CLK;
assign Z80_clk_neg   =  Z80_clk_delay && ~Z80_CLK;
assign Z80_clk_trig  = (Z80_clk_pos && sel_pclk) || (Z80_clk_neg && ~sel_nclk);


assign Z80_mreq     = ~Z80_MREQn && Z80_M1n; // Define a bus memory access state
assign Z80_write = ~Z80_WRn ; // write transaction

assign Z80_read     = ~Z80_RDn; // read transaction

assign Write_GPU_RAM =  mem_window && Z80_mreq && Z80_write && mem_valid_range; // Define a GPU Write action - only write to address within GPU RAM bounds
assign Read_GPU_RAM   =  mem_window && Z80_mreq && Z80_read  && mem_valid_range;   // Define the beginning of a Z80 read request of GPU Ram.

// **********************************************************************************************************

always @ (posedge GPU_CLK) begin

gpu_addr         <=  Z80_addr[18:0];                        // latch address bus onto GPU address bus
mem_valid_range  <= (Z80_addr[18:0]  <  2**MEM_SIZE_BITS); // Define GPU addressable memory space
mem_window   <= (Z80_addr[21:19] == MEMORY_RANGE);    // Define an active memory range

if ( Write_GPU_RAM ) begin
Z80_245data_dir  <= 1'b1; // set 245 dir toward FPGA
Z80_rData_ena    <= 1'b0; // set FPGA pins to input (should be by default)
Z80_245_oe       <= 1'b0; // enable 245 output (WAS 1 - moved forward to step 0)
 
gpu_wdata        <= Z80_wData; // latch data bus onto GPU data bus
//gpu_wr_ena       <= 1'b1; // turn on FPGA RAM we
end else begin
//gpu_wr_ena       <= 1'b0; // turn off FPGA RAM we
end


if ( Read_GPU_RAM ) begin

gpu_rd_req <= 1'b1; // flag a read request to the mux which is one-shotted in the mux

Z80_245data_dir <= 1'b0; // set 245 direction (TO Z80)
Z80_245_oe <= 1'b0; // enable 245 output
Z80_rData_ena    <= 1'b1; // set bidir pins to output
end else begin
gpu_rd_req <= 1'b0; // end GPU read req after 1 pulse

Z80_245data_dir   <= 1'b1; // set 245 dir toward FPGA
Z80_rData_ena <= 1'b0; // re-set bidir pins to input
end


if ( gpu_rd_rdy ) begin
if (mem_valid_range) Z80_rData[7:0] <= gpu_rData[7:0];  // Latch the GPU RAM read into the output register for the Z80
else Z80_rData[7:0]  <= 8'b11111111;      // return $FF if addressed byte is outside the GPU's upper RAM limit
end


last_Z80_WR <= Write_GPU_RAM;
last_Z80_WR2 <= last_Z80_WR;
last_Z80_WR3 <= last_Z80_WR2;
last_Z80_RD <= Read_GPU_RAM;
Z80_clk_delay <= Z80_CLK; // find the rising clock edge

gpu_wr_ena      <= Write_GPU_RAM && ~last_Z80_WR2 ; // Pulse the GPU ram's write enable only once after the Z80 write cycle has completed
//gpu_rd_req      <= Read_GPU_RAM && ~ last_Z80_RD ; // Pulse the read request only once at the beginning of a read cycle.

end

// **********************************************************************************************************

endmodule


Maybe something fishy is going on inside the MUX and it is not seeing the single clock wide write pulse, though, then, the RS232_debugger should also have similar write errors.
« Last Edit: January 06, 2020, 03:54:50 pm by BrianHG »
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 7720
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #883 on: January 06, 2020, 03:55:40 pm »
TYPO ERROR:, fix this line 106:

gpu_wr_ena      <= Write_GPU_RAM && ~last_Z80_WR2 ; // Pulse the GPU ram's write enable only once after the Z80 write cycle has completed


(I just edited the line in the above post as well.)
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #884 on: January 06, 2020, 04:02:25 pm »
That seems to work fine?
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 7720
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #885 on: January 06, 2020, 04:16:40 pm »
That seems to work fine?

Ok, Good.  Next, the new single cycle read version:

Code: [Select]
module Z80_bridge (

// input
input wire reset, // GPU reset signal
input wire GPU_CLK, // GPU clock (125 MHz)
input wire Z80_CLK, // Microcom clock signal (8 MHz)
input wire Z80_M1n, // Z80 M1 - active LOW
input wire Z80_MREQn, // Z80 MREQ - active LOW
input wire Z80_WRn, // Z80 WR - active LOW
input wire Z80_RDn, // Z80 RD - active LOW
input wire [21:0] Z80_addr, // Microcom 22-bit address bus
input wire [7:0] Z80_wData, // Z80 DATA bus to pass incoming data to GPU RAM
input wire [7:0] gpu_rData,
input wire gpu_rd_rdy, // one-shot signal from mux that data is ready

// output
output reg Z80_245data_dir, // control level converter direction for data flow - HIGH = A -> B (toward FPGA)
output reg [7:0]  Z80_rData, // Z80 DATA bus to return data from GPU RAM to Z80
output reg Z80_rData_ena, // flag HIGH to write data back to Z80
output reg Z80_245_oe, // OE for 245 level translator *** ACTIVE LOW ***
output reg gpu_wr_ena, // flag HIGH for 1 clock when writing to GPU RAM
output reg gpu_rd_req, // flag HIGH for 1 clock when reading from GPU RAM
output reg [19:0] gpu_addr, // connect to Z80_addr in vid_osd_generator to address GPU RAM
output reg [7:0]  gpu_wdata, // 8-bit data bus to GPU RAM in vid_osd_generator

    input wire  sel_pclk,  // make HIGH to trigger the Z80 bus on the positive edge of Z80_CLK
    input wire  sel_nclk   // make LOW  to trigger the Z80 bus on the negative edge of Z80_CLK
);

// TODO:
//
// 1) Prevent reads to GPU RAM above top of GPU RAM
// 2) Respond with appropriate data to any requests from Microcom ROM identification routines
//

parameter MEMORY_RANGE  = 3'b010; // Z80_addr[21:19] == 3'b010 targets the 512KB 'window' at 0x100000-0x17FFFF (Socket 3 on the Microcom)
parameter MEM_SIZE_BITS = 15; //

wire Z80_mreq, Z80_write, Z80_read, Write_GPU_RAM;
wire Read_GPU_RAM;
wire Z80_clk_pos,Z80_clk_neg,Z80_clk_trig;

reg Z80_clk_delay, last_Z80_WR, last_Z80_RD, mem_valid_range, mem_window, last_Z80_WR2, last_Z80_WR3, last_Z80_RD2, last_Z80_RD3 ;


assign Z80_clk_pos   = ~Z80_clk_delay &&  Z80_CLK;
assign Z80_clk_neg   =  Z80_clk_delay && ~Z80_CLK;
assign Z80_clk_trig  = (Z80_clk_pos && sel_pclk) || (Z80_clk_neg && ~sel_nclk);


assign Z80_mreq     = ~Z80_MREQn && Z80_M1n; // Define a bus memory access state
assign Z80_write = ~Z80_WRn ; // write transaction

assign Z80_read     = ~Z80_RDn; // read transaction

assign Write_GPU_RAM =  mem_window && Z80_mreq && Z80_write && mem_valid_range; // Define a GPU Write action - only write to address within GPU RAM bounds
assign Read_GPU_RAM   =  mem_window && Z80_mreq && Z80_read  && mem_valid_range;   // Define the beginning of a Z80 read request of GPU Ram.

// **********************************************************************************************************

always @ (posedge GPU_CLK) begin

gpu_addr         <=  Z80_addr[18:0];                        // latch address bus onto GPU address bus
mem_valid_range  <= (Z80_addr[18:0]  <  2**MEM_SIZE_BITS); // Define GPU addressable memory space
mem_window   <= (Z80_addr[21:19] == MEMORY_RANGE);    // Define an active memory range

if ( Write_GPU_RAM ) begin
Z80_245data_dir  <= 1'b1; // set 245 dir toward FPGA
Z80_rData_ena    <= 1'b0; // set FPGA pins to input (should be by default)
Z80_245_oe       <= 1'b0; // enable 245 output (WAS 1 - moved forward to step 0)
 
gpu_wdata        <= Z80_wData; // latch data bus onto GPU data bus
//gpu_wr_ena       <= 1'b1; // turn on FPGA RAM we
end else begin
//gpu_wr_ena       <= 1'b0; // turn off FPGA RAM we
end


if ( Read_GPU_RAM ) begin

//gpu_rd_req <= 1'b1; // flag a read request to the mux which is one-shotted in the mux

Z80_245data_dir <= 1'b0; // set 245 direction (TO Z80)
Z80_245_oe <= 1'b0; // enable 245 output
Z80_rData_ena    <= 1'b1; // set bidir pins to output
end else begin
//gpu_rd_req <= 1'b0; // end GPU read req after 1 pulse

Z80_245data_dir   <= 1'b1; // set 245 dir toward FPGA
Z80_rData_ena <= 1'b0; // re-set bidir pins to input
end


if ( gpu_rd_rdy ) begin
if (mem_valid_range) Z80_rData[7:0] <= gpu_rData[7:0];  // Latch the GPU RAM read into the output register for the Z80
else Z80_rData[7:0]  <= 8'b11111111;      // return $FF if addressed byte is outside the GPU's upper RAM limit
end


Z80_clk_delay <= Z80_CLK; // find the rising clock edge

last_Z80_WR <= Write_GPU_RAM;
last_Z80_WR2 <= last_Z80_WR;
last_Z80_WR3 <= last_Z80_WR2;

last_Z80_RD <= Read_GPU_RAM;
last_Z80_RD2 <= last_Z80_RD;
last_Z80_RD3 <= last_Z80_RD2;

gpu_wr_ena      <= Write_GPU_RAM && ~last_Z80_WR2 ; // Pulse the GPU ram's write enable only once after the Z80 write cycle has completed
gpu_rd_req      <= Read_GPU_RAM  && ~last_Z80_RD2 ; // Pulse the read request only once at the beginning of a read cycle.

end

// **********************************************************************************************************

endmodule


I've done the same thing for the read as the write, so, it should also work fine.
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #886 on: January 06, 2020, 04:28:31 pm »
Yes, that's working.  :-+
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 7720
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #887 on: January 06, 2020, 04:35:08 pm »
Ok, version 1.0 finished.
Archive it away and show us something 'interesting' working in the Z80.
 
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 #888 on: January 06, 2020, 05:05:28 pm »
Ok, version 1.0 finished.
Archive it away and show us something 'interesting' working in the Z80.

Okay, v1.0 project files attached.  Will get something 'interesting' up here in the next few days, work allowing.  :-+
 
The following users thanked this post: BrianHG

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 7720
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #889 on: January 06, 2020, 05:08:25 pm »
Ok, version 1.0 finished.
Archive it away and show us something 'interesting' working in the Z80.

Okay, v1.0 project files attached.  Will get something 'interesting' up here in the next few days, work allowing.  :-+

I still cant believe we got the Z80 bus interface working without a single scope shot or logic analyzer view.
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #890 on: January 06, 2020, 05:43:53 pm »
I still cant believe we got the Z80 bus interface working without a single scope shot or logic analyzer view.

And there I was worrying that it wasn't working on the first day I connected it all up. ::)  Was starting to think that there was something major wrong with my wiring and you were going to run out of suggestions to try next. :scared:
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #891 on: January 06, 2020, 05:47:27 pm »
I've just realised, I've been spending time trying to get 8-bit and 16-bit text modes working and swapping between them with a command in the DMI... but then I stopped and thought, "Why?"  :-//  Is there any reason I'd need to use 8-bit text mode?  I mean, if the FPGA is so small that the difference between a 2.4 KB and 4.8 KB screen buffer is the difference between it working or not, then there's bigger issues with the choice of FPGA...?
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #892 on: January 06, 2020, 06:12:48 pm »
What would be the most straight-forward way to modify the existing 'return any reads to addresses above mem_valid_range as $FF' to return a byte addressed from a string (say 'GPU v1.0' for example) virtually addressed in the last $0F bytes of each page ($FF bytes) in the ~mem_valid_range?

As a practical example, the Microcom identifies the contents of each 16 KB bank of memory by the last 16 bytes.  If it's a ROM bank (and it's not empty), it'll have something like "DMI v1.34" in the last 16 bytes of that bank.

It'd be handy if the GPU could return the core version, for example, so the Microcom could identify that a GPU is attached and report to the user what version the GPU core is.

I'd be considering something like this (pseudo-code):

Code: [Select]
   if ( gpu_rd_rdy ) begin
      if (mem_valid_range)
          Z80_rData[7:0] <= gpu_rData[7:0];  // Latch the GPU RAM read into the output register for the Z80
      end else begin
          if (mem_ID_range == gpu_addr[13:4]) begin
              Z80_rData[7:0] <= ID_array[gpu_addr[3:0]][7:0];  // where ID_array = ['GPU v1.0' + 8'b11111111] *** for example ***
          else
              Z80_rData[7:0] <= 8'b11111111;     // return $FF if addressed byte is outside the GPU's upper RAM limit
      end
   end
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 7720
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #893 on: January 07, 2020, 07:38:12 am »
Now @nockieboy, when we were team-viewing awhile back, you setup a test bench simulation for your Z80_Bridge.  Update it's Z80_bridge.v to the new one, try a few different read addresses and test the code you want to create.
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #894 on: January 07, 2020, 11:25:47 am »
Okay, it's not all that 'interesting', but here's a screenshot of the video output using the memory editor in the DMI:

 
The following users thanked this post: BrianHG

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #895 on: January 07, 2020, 11:35:01 am »
And a screenshot of the memory editor viewing the first page of the GPU RAM, with the HV_triggers and MAGGIE settings.

904424-0
 
The following users thanked this post: BrianHG

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 14431
  • Country: fr
Re: FPGA VGA Controller for 8-bit computer
« Reply #896 on: January 07, 2020, 04:33:36 pm »
Nice!
 
The following users thanked this post: nockieboy

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 7720
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #897 on: January 07, 2020, 05:57:24 pm »
Right off the bat, with 7 layers, if he uses 1 graphics layer, he has another 6 layers for sprites, he can make an authentic hi-res version on games like PacMan.  4 colors for the hires background maze & pellets, and 4 or 16 colors for the player sprites.  Or he can use a colored font layer for the background.

No audio though...
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #898 on: January 07, 2020, 06:00:13 pm »
Playing around with the Z80 code now and 'colouring-in' lots of the output has made me realise how restrictive my MMU is.  4x16KB areas just isn't cutting it anymore - especially if I want to get the GPU running with CP/M; I'm going to have to make it more fine-grained.  I'm halfway through designing a much more flexible MMU in hardware, but I haven't touched that since I started down this FPGA GPU route a couple of months ago - now I'm thinking that I might as well build the MMU into the FPGA, seeing as it has access to (nearly) all the address lines it needs and some spare RAM space. I'm running out of IOs on this dev board though!  :o

PS2 keyboard is next, and whenever @jhpadjustable is up for it, perhaps some sound.  ;D
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 7720
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #899 on: January 07, 2020, 06:01:59 pm »
Nice!
Already have colored text functional.
Excellent.

Also got rid of the monochrome junk.  ;)
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf