2
\$\begingroup\$

Is it possible to efficiently infer a RAM with "peek" ports apart from the usual standard ports?

A 32-bit x 4 RAM might have a peek port to peek at data just ahead of the current data being accessed by the read address. Approximate code would be...

assign peek = mem [ (rd_addr + 1) & 2'b11 ]; // RAM peek port (read).

apart from the stock RAM code...

reg [31:0] mem [3:0]; // 2D array.
always @ (posedge clk) if (wr ) mem [ wr_addr ] <= wr_data; // Write.
always @* rd_data = mem [ rd_addr ]; // Main Read.

It would be nice to infer a SINGLE block RAM with some extra (very simple?) read circuitry (ISE infers 2 RAM blocks). I guess this shouldn't require a true dual read port RAM (independent read circuits) or RAM duplication since the read addresses are always related (always 1 ahead). Is there an area efficient way of implementing the above in a typical modern FPGA ?

EDIT: Forgot to add write enable!

EDIT: This RAM is intended for video decoding. Example a stream of pixels received as 0x1234_5678 0x023_45678, 0xAAAA_AAAA would be decoded as 0x1234 (16-bit upper), 0x5678_23 (lower 16-bit + 0x23 from next, initial 0x0 is skipped), 0x678A_AAAA etc (0x45 is skipped). The decoding algorithm is derived from an LFSR that maps to the transmitter and changes for every pixel.

\$\endgroup\$
6
  • \$\begingroup\$ If ISE infers two RAM blocks is because you made an incomplete model of the RAM... how do you thing the second block would be updated when you need to write to the RAM? If BW is the issue, you can burst access the RAM. \$\endgroup\$ Commented Jul 1, 2016 at 17:12
  • \$\begingroup\$ @ClaudioAviChami, oops! forgot to put a write enable. \$\endgroup\$
    – user105000
    Commented Jul 1, 2016 at 18:52
  • 1
    \$\begingroup\$ Because you forgot you received a 'simple' solution. A real solution is more complicated because you have to take care of writing to both RAMs. \$\endgroup\$ Commented Jul 2, 2016 at 5:04
  • 1
    \$\begingroup\$ @ClaudioAviChami, I don't want to write to 2 RAMs, I want a single RAM with an extra read port instead of writing to 2 RAMs in parallel. I don't think the complexity of a true dual port RAM or RAM duplication is required since the 2 read addresses are always related in a very specific way. My guess is that FPGAs do not provide native implementations of lookahead RAMs (like AndyW mentioned) and must be implemented using LUTs. \$\endgroup\$
    – user105000
    Commented Jul 3, 2016 at 15:52
  • \$\begingroup\$ at the FPGA level you simply can't do that. If you were making an ASIC (maybe) you could access the RAM cells and do the trick. On an FPGA a single-port memory is a defined block where there is a single data bus that reflects the contents of the last requested address. There is no other data bus available, and no LUTs will be able to access data that is not at the RAM port. Any solution to do what you want demand a dual port RAM. \$\endgroup\$ Commented Jul 4, 2016 at 3:47

1 Answer 1

1
\$\begingroup\$

I assume you mean to ask if it's possible with a physical RAM, not a "virtual" RAM. In essence, many modern processor Memory Management Units (MMU) try to do this kind of lookahead, by prefetching the contents of the next few RAM locations during RAM bus cycles that would otherwise be idle.

This strategy has been around for some time, and sounds simple, but when implemented in a processor the complications rapidly mount. Processors don't always want to see the "next" location in RAM, even when executing program instructions. Data-dependent branches occur (conditional loops, "FOR" and "WHILE" constructs in high level languages…), and MMU's need to then "flush" the look-ahead buffer when this happens.

In order to implement a single-location look-ahead in a physical RAM, there are a number of possible strategies: 1) a true dual port RAM, as you point out. This requires two address and two data buses and can look ahead to any arbitrary location, not just the next one. 2) a "look-ahead by one location" RAM, which would require only a single address bus, but still requires two data buses (one for the "current" location contents, and one for the "next" location contents) 3) a "prefetched" RAM, which reads out the contents of the "next" location, stores it into an external one-word buffer, while presenting the previous fetch results on the output of the buffer. This kind of arrangement need to be "primed" with a read operation to fill the one-word buffer before entering the "normal" prefetch mode.

\$\endgroup\$
6
  • \$\begingroup\$ I would expect another variation would be a double-width RAM which has an extra "+1" addressing input which causes half the array to access an address one higher than indicated [insert a mux layer between the row-select generators and the row selects themselves, so each row on that half could be selected using its own address or the one below], as well as a multiplexing circuit to swap the bus connections for the left and right halves. That would make it possible to fetch a pair of storage chunks from any address regardless of alignment without changing the basic cell circuitry. \$\endgroup\$
    – supercat
    Commented Jul 1, 2016 at 17:37
  • \$\begingroup\$ This RAM is intended to be used in a display decoding IP. Certain pixels will need only the 32-bit value while some need the current 32-bit value and the next 5 to 24-bit (varies) value to decode correctly, thus the need for a peek port. \$\endgroup\$
    – user105000
    Commented Jul 1, 2016 at 18:55
  • \$\begingroup\$ Supercat, that is also very simply achieved with two RAM devices, RAM0 and RAM1, where both use the same address bits, but address bit A0 (the LSB of the address) is used to select RAM0 or RAM1 data lines. The selector, of course, needs to be bidirectional in order to allow for writes to RAM. \$\endgroup\$
    – AndyW
    Commented Jul 1, 2016 at 19:04
  • \$\begingroup\$ @AndyW, the lookahead by 1 location (option 2) that you mentions fits the best. Is there a standard way to efficiently implement it or is the code I have given roughly enough. \$\endgroup\$
    – user105000
    Commented Jul 1, 2016 at 19:09
  • \$\begingroup\$ Not being an FPGA coder, I unfortunately cannot offer you comment on the code. Just on the physical organization. \$\endgroup\$
    – AndyW
    Commented Jul 1, 2016 at 19:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.