I've made a start on the multiport_gpu_ram already - lots of things going off here though, so can't focus on this at the moment - will be back to it later tonight.
Current multiport_gpu_ram.v:
module multiport_gpu_ram (
input clk, // Primary clk input (125 MHz)
input [3:0] pc_ena, // Pixel clock enable
input clk_b, // Host (Z80) clock input
input write_ena_b, // 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 pass-thru bus (output)
output reg [19:0] addr_passthru,
// 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 bits - effectively the RAM size
parameter MAX_ADDR_BITS = 20;
reg [MAX_ADDR_BITS - 1:0] address_mux;
reg [7:0] aux_read_mux;
// create a GPU RAM instance
gpu_dual_port_ram_INTEL gpu_RAM(
.clk(clk),
.pc_ena_in(pc_ena),
.clk_b(clk_b),
.wr_en_b(wr_en_b),
.addr_a(address_mux),
.addr_b(),
.data_in_b(),
.addr_out_a(addr_passthru),
.pc_ena_out(),
.data_out_a(aux_read_mux),
.data_out_b()
);
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;
addr_passthru <= address_0;
end
3'b001 : begin
address_mux <= address_1;
aux_read_mux <= aux_read_1;
addr_passthru <= address_1;
end
3'b011 : begin
address_mux <= address_2;
aux_read_mux <= aux_read_2;
addr_passthru <= address_2;
end
3'b100 : begin
address_mux <= address_3;
aux_read_mux <= aux_read_3;
addr_passthru <= address_3;
end
3'b101 : begin
address_mux <= address_4;
aux_read_mux <= aux_read_4;
addr_passthru <= address_4;
end
endcase
end // always @clk
endmodule
Have merged all the pass-through addresses into one bus - otherwise can't see the point of having them in the mux at all? addr_passthru is the passed-through address, muxed from one of the five input addresses depending on pc_ena value. Hopefully that's right.
Ok, from what I can see so far:
After initiating the "gpu_dual_port_ram_INTEL gpu_RAM(.....);", you need the:
---------------------------
defparam
gpu_RAM.MAX_ADDR_BITS = MAX_ADDR_BITS ;
---------------------------
This will pass the module multiport_gpu_ram's MAX_ADDR_BITS parameter into the gpu_dual_port_ram_INTEL's MAX_ADDR_BITS parameter. It may be useful to pass the 'altsyncram_component.numwords_a&b' since it may be possible to allocate 24kb in the FPGA since it has that much memory, yet not 32kb.
.addr_out_a(addr_passthru), should change to (addr_passthru_mux) and don't forget to declare it as a wire.
.data_out_a(aux_read_mux) is also a wire.
.pc_ena_out(pc_ena_out), is also a wire and an output
// address pass-thru bus (output)
output reg [19:0] addr_out, There are 5 of these to match the read address ins 0 through 5 in.
// 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,
change all these to cmd_in[15:0]. (global search and replace)
// 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,
change these to cmd_out[15:0]
reg [MAX_ADDR_BITS - 1:0] address_mux;
change to reg [19:0] address_mux;
reg [7:0] aux_read_mux;
change to reg [15:0] cmd_read_mux (global search and replace)
Your missing a few of the new ports for 'gpu_dual_port_ram_INTEL gpu_RAM(...);'
Almost done, next you will resort the read ram contents, the piped through address & cmds into their output registers and sync those to your new delayed 'pc_ena_out[3:0]' coming out of the Intel ram module.
Note that we forgot to wire through the 'pc_ena_out[3:0]' coming out of the Intel ram module thought to the multiport_gpu_ram ( ...) ports, so that the rest of our graphics pipe heading to the output pins will incorporate the delay shift generated by the memory. (Though we can work around this through sophisticated re-syncing all the ram outputs back to the next pc_ena_in==0 cycle, this ena signal in the FPGA is beginning to drive so much logic limiting our FMAX, this is an opportune point to D-clock pipe the signals for the second half of our graphics pipe.)