Saturday, 13 June 2015

Verilog Code for Dual Port Asynchronous RAM

  • Dual Port RAM has two ports and in each port either read or write is possible. Here, in Asynchronous RAM read and write clocks are different.
  • For e.g.
  • Write to both Port 0 and Port 1
  • Read from both Port 0 and Port 1
  • Read/Write from/to Port 0 and Port 1
  • To avoid memory contention while writing to both ports at same time, write address should be different. Also, Read address and Write address should be different for simultaneous operation.
  • We can assume that, to avoid memory contention logic is implemented in outside system accessing the RAM.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
//////////////////////////////////////////////////////
// Module: dp_async_ram.v
// Dual Port Asynchronous RAM with Asynchronous Reset
// Read and Write Clock Frequencies are Different
//////////////////////////////////////////////////////

module dp_async_ram #(parameter DEPTH = 16, WIDTH = 8,ADDR = 4)(
     wr_clk,
     rd_clk,
     reset,
     data_0,
     data_1,
     addr_0,
     addr_1,
     wr_en_0,
     wr_en_1,
     o_en_0,
     o_en_1);
 
 //Bidirectional Ports
 inout [WIDTH-1:0] data_0, data_1;
 
 //Input Ports
 input wr_clk, rd_clk;
 input reset;
 input [ADDR-1:0] addr_0, addr_1;
 input wr_en_0, wr_en_1;
 input o_en_0, o_en_1;
 
 reg [WIDTH-1:0] data_0_reg, data_1_reg;
 integer i;
 
 //Define Memory
 reg [WIDTH-1:0] mem[DEPTH-1:0];
 
 //Write Logic
 always@(posedge wr_clk or posedge reset)
 begin
  if(reset)
  begin
   for(i = 0; i < DEPTH; i = i + 1)
    mem[i] <= 0;
  end
  else 
  begin 
  if(wr_en_0 && (!o_en_0))
    mem[addr_0] <= data_0;
  if(wr_en_1 && (!o_en_1))
    mem[addr_1] <= data_1;
  end
 end
 
 //Read Logic
 //Here data width is of 8-bits
 assign data_0 = (o_en_0 && (!wr_en_0))?data_0_reg:8'bz;
 assign data_1 = (o_en_1 && (!wr_en_1))?data_1_reg:8'bz;
 
 always@(posedge rd_clk)
 begin
  if(o_en_0 && (!wr_en_0))
   data_0_reg <= mem[addr_0];
  if(o_en_1 && (!wr_en_1))
   data_1_reg <= mem[addr_1];
 end
 
endmodule