How to make block RAM visible in a PowerPak mapper?

Discuss hardware-related topics, such as development cartridges, CopyNES, PowerPak, EPROMs, or whatever.

Moderators: B00daW, Moderators

Post Reply
User avatar
NovaSquirrel
Posts: 376
Joined: Fri Feb 27, 2009 2:35 pm
Location: Fort Wayne, Indiana
Contact:

How to make block RAM visible in a PowerPak mapper?

Post by NovaSquirrel » Fri Dec 23, 2016 12:16 am

I'm writing a PowerPak mapper (an experimental one with a coprocessor) that requires me to map the FPGA's block RAM into the CPU's address space, probably at $5xxx.

I'm using Loopy's mapper source as a reference, and it looks like the part that actually routes PRG ROM and WRAM to the NES's CPU is the Game Genie module, which I'm disabling because I won't have spare logic for it (coprocessor uses 75% when synthesized as a top level module). Do I just set nesprgdout to ramprgdin unless the address space is inside $5xxx?

For accessing the block RAM itself I tried this, making six dual ported block RAM primitives and using a multiplexer to choose the appropriate output from one of them. The problem with that is it uses like 9% of the FPGA space. Is there a way to do this with less resources? Are the space usage counts when marking each different module as the top level one even accurate? I made a module with both this block RAM and the coprocessor together and it added less than 9% to the coprocessor's usage amount.

User avatar
Myask
Posts: 965
Joined: Sat Jul 12, 2014 3:04 pm

Re: How to make block RAM visible in a PowerPak mapper?

Post by Myask » Thu Jan 12, 2017 5:38 pm

I'm curious if you got a solution, as I'd be interested in the answer, too.

User avatar
NovaSquirrel
Posts: 376
Joined: Fri Feb 27, 2009 2:35 pm
Location: Fort Wayne, Indiana
Contact:

Re: How to make block RAM visible in a PowerPak mapper?

Post by NovaSquirrel » Thu Jan 12, 2017 10:47 pm

I probably did this wrong (judging from Chipmunk's random problems with writing to block RAM), but here's what I ended up doing: I made an instance of my module that links all the block RAM together into one 3KB dual-ported RAM, like so:

Code: Select all

    wire is_blockram = m2_n & prgain[15:12] == 4'h5;
    wire is_blockwrite = is_blockram && nesprg_we;
    wire is_blockread = is_blockram && !nesprg_we;
    wire [7:0] nes_blockram_out;
    blockram ram(~clk20, clk20, chip_dataOut, chip_data, nesprgdin, nes_blockram_out, chip_addr, prgain[11:0], ~chip_we, is_blockwrite, chip_reset, is_blockram);
Loopy's mappers put the NES's reading on one port and writing on the other port, but I needed both ports to be able to read and write. I struggled with that but using clk20 as a clock rather than m2 seemed to work.

nesprgdout comes from the block RAM when the address is $5xxx, and otherwise it comes from either PRG ROM or WRAM. Output enable also needs to come on when doing a read from block RAM:

Code: Select all

    assign nesprgdout = ((is_blockram)?nes_blockram_out:ramprgdin);
    assign nesprg_oe = wram_oe | prgram_oe | config_rd | is_blockread;

Post Reply