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