2008年3月26日 星期三

Memory Synthesis in Verilog

Memory Synthesis in Verilog

Most synthesizers implement a Verilog memory array, such as the one shown in the following code, as an array of latches or flip-flops.

reg [31:0] MyMemory [3:0]; // a 4 x 32-bit register

For example, the following code models a small RAM, and the synthesizer maps the memory array to sequential logic:

module RAM_1(A, CEB, WEB, OEB, INN, OUTT);

input [6:0] A; input CEB,WEB,OEB; input [4:0]INN;

output [4:0] OUTT;

reg [4:0] OUTT; reg [4:0] int_bus; reg [4:0] memory [127:0];

always @( negedge CEB) begin

if (CEB == 0) begin

if (WEB == 1) int_bus = memory[A];

else if (WEB == 0) begin memory[A] = INN; int_bus = INN; end

else int_bus = 5'bxxxxx;

end

end

always @(OEB or int_bus) begin

case (OEB) 0 : OUTT = int_bus;

default : OUTT = 5'bzzzzz; endcase

end

endmodule

Memory synthesis using random control logic and transparent latches for each bit is reasonable only for small, fast register files, or for local RAM on an MGA or CBIC. For large RAMs synthesized memory becomes very expensive and instead you should normally use a dedicated RAM compiler.

Typically there will be restrictions on synthesizing RAM with multiple read/writes:

  • If you write to the same memory in two different processes, be careful to avoid address contention.
  • You need a multiport RAM if you read or write to multiple locations simultaneously.
  • If you write and read the same memory location, you have to be very careful. To mimic hardware you need to read before you write so that you read the old memory value. If you attempt to write before reading, the difference between blocking and nonblocking assignments can lead to trouble.

You cannot make a memory access that depends on another memory access in the same clock cycle. For example, you cannot do this:

memory[i + 1] = memory[i]; // needs two clock cycles

or this:

pointer = memory[memory[i]]; // needs two clock cycles

For the same reason (but less obviously) we cannot do this:

pc = memory[addr1]; memory[addr2] = pc + 1; // not on the same cycle

沒有留言: