1//
2// Copyright 2011 Ettus Research LLC
3// Copyright 2018 Ettus Research, a National Instruments Company
4//
5// SPDX-License-Identifier: LGPL-3.0-or-later
6//
7// Description
8//  This code implements a parameterizable true dual port memory
9//  (both ports can read and write). If an enable is not necessary
10//  it may be tied off.
11//
12// Note
13//  This module requires the ram_2port_impl.vh header file. The
14//  header is included multiple times with different values of
15//  the RAM_DIRECTIVE macro to create different implementations of the
16//  RAM. An implementation is chosen in ram_2port based on the
17//  user parameter for RAM_TYPE.
18
19// Mode: AUTOMATIC
20`define RAM_DIRECTIVE
21`define RAM_MOD_NAME ram_2port_impl_auto
22`include "ram_2port_impl.vh"
23`undef RAM_MOD_NAME
24`undef RAM_DIRECTIVE
25
26// Mode: REG
27`define RAM_DIRECTIVE (* ram_style = "registers" *)
28`define RAM_MOD_NAME ram_2port_impl_reg
29`include "ram_2port_impl.vh"
30`undef RAM_MOD_NAME
31`undef RAM_DIRECTIVE
32
33// Mode: LUTRAM
34`define RAM_DIRECTIVE (* ram_style = "distributed" *)
35`define RAM_MOD_NAME ram_2port_impl_lutram
36`include "ram_2port_impl.vh"
37`undef RAM_MOD_NAME
38`undef RAM_DIRECTIVE
39
40// Mode: BRAM
41`define RAM_DIRECTIVE (* ram_style = "block" *)
42`define RAM_MOD_NAME ram_2port_impl_bram
43`include "ram_2port_impl.vh"
44`undef RAM_MOD_NAME
45`undef RAM_DIRECTIVE
46
47// Mode: URAM
48`define RAM_DIRECTIVE (* ram_style = "ultra" *)
49`define RAM_MOD_NAME ram_2port_impl_uram
50`include "ram_2port_impl.vh"
51`undef RAM_MOD_NAME
52`undef RAM_DIRECTIVE
53
54module ram_2port #(
55  parameter DWIDTH    = 32,           // Width of the memory block
56  parameter AWIDTH    = 9,            // log2 of the depth of the memory block
57  parameter RW_MODE   = "READ-FIRST", // Read-write mode {READ-FIRST, WRITE-FIRST, NO-CHANGE}
58  parameter RAM_TYPE  = "AUTOMATIC",  // Type of RAM to infer {AUTOMATIC, REG, LUTRAM, BRAM, URAM}
59  parameter OUT_REG   = 0,            // Instantiate an output register? (+1 cycle of read latency)
60  parameter INIT_FILE = ""            // Optionally initialize memory with this file
61) (
62  input  wire              clka,
63  input  wire              ena,
64  input  wire              wea,
65  input  wire [AWIDTH-1:0] addra,
66  input  wire [DWIDTH-1:0] dia,
67  output wire [DWIDTH-1:0] doa,
68
69  input  wire              clkb,
70  input  wire              enb,
71  input  wire              web,
72  input  wire [AWIDTH-1:0] addrb,
73  input  wire [DWIDTH-1:0] dib,
74  output wire [DWIDTH-1:0] dob
75);
76
77  generate
78    if (RAM_TYPE == "URAM")
79      ram_2port_impl_uram #(
80        .DWIDTH(DWIDTH), .AWIDTH(AWIDTH), .RW_MODE(RW_MODE),
81        .OUT_REG(OUT_REG), .INIT_FILE(INIT_FILE)
82      ) impl (
83        .clka(clka), .ena(ena), .wea(wea), .addra(addra), .dia(dia), .doa(doa),
84        .clkb(clkb), .enb(enb), .web(web), .addrb(addrb), .dib(dib), .dob(dob)
85      );
86    else if (RAM_TYPE == "BRAM")
87      ram_2port_impl_bram #(
88        .DWIDTH(DWIDTH), .AWIDTH(AWIDTH), .RW_MODE(RW_MODE),
89        .OUT_REG(OUT_REG), .INIT_FILE(INIT_FILE)
90      ) impl (
91        .clka(clka), .ena(ena), .wea(wea), .addra(addra), .dia(dia), .doa(doa),
92        .clkb(clkb), .enb(enb), .web(web), .addrb(addrb), .dib(dib), .dob(dob)
93      );
94    else if (RAM_TYPE == "LUTRAM")
95      ram_2port_impl_lutram #(
96        .DWIDTH(DWIDTH), .AWIDTH(AWIDTH), .RW_MODE(RW_MODE),
97        .OUT_REG(OUT_REG), .INIT_FILE(INIT_FILE)
98      ) impl (
99        .clka(clka), .ena(ena), .wea(wea), .addra(addra), .dia(dia), .doa(doa),
100        .clkb(clkb), .enb(enb), .web(web), .addrb(addrb), .dib(dib), .dob(dob)
101      );
102    else if (RAM_TYPE == "REG")
103      ram_2port_impl_reg #(
104        .DWIDTH(DWIDTH), .AWIDTH(AWIDTH), .RW_MODE(RW_MODE),
105        .OUT_REG(OUT_REG), .INIT_FILE(INIT_FILE)
106      ) impl (
107        .clka(clka), .ena(ena), .wea(wea), .addra(addra), .dia(dia), .doa(doa),
108        .clkb(clkb), .enb(enb), .web(web), .addrb(addrb), .dib(dib), .dob(dob)
109      );
110    else
111      ram_2port_impl_auto #(
112        .DWIDTH(DWIDTH), .AWIDTH(AWIDTH), .RW_MODE(RW_MODE),
113        .OUT_REG(OUT_REG), .INIT_FILE(INIT_FILE)
114      ) impl (
115        .clka(clka), .ena(ena), .wea(wea), .addra(addra), .dia(dia), .doa(doa),
116        .clkb(clkb), .enb(enb), .web(web), .addrb(addrb), .dib(dib), .dob(dob)
117      );
118  endgenerate
119
120endmodule
121