Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion lambdalib/ramlib/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@
from .la_syncfifo.la_syncfifo import Syncfifo
from .la_dpram.la_dpram import Dpram
from .la_spram.la_spram import Spram
from .la_tdpram.la_tdpram import Tdpram

__all__ = ['Asyncfifo',
'Syncfifo',
'Dpram',
'Spram']
'Spram',
'Tdpram']


class RAMLib(Design):
Expand All @@ -20,3 +22,4 @@ def __init__(self):
self.add_depfileset(Syncfifo(), depfileset="rtl")
self.add_depfileset(Dpram(), depfileset="rtl")
self.add_depfileset(Spram(), depfileset="rtl")
self.add_depfileset(Tdpram(), depfileset="rtl")
12 changes: 12 additions & 0 deletions lambdalib/ramlib/la_tdpram/la_tdpram.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from lambdalib.lambdalib import Lambda


class Tdpram(Lambda):
def __init__(self):
name = 'la_tdpram'
super().__init__(name, __file__, extrasources=['rtl/la_tdpram_impl.v'])


if __name__ == "__main__":
d = Tdpram()
d.write_fileset(f"{d.name}.f", fileset="rtl")
85 changes: 85 additions & 0 deletions lambdalib/ramlib/la_tdpram/rtl/la_tdpram.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/*****************************************************************************
* Function:
* Copyright: Lambda Project Authors. All rights Reserved.
* License: MIT (see LICENSE file in Lambda repository)
*
* Docs:
*
* This is a wrapper for selecting from a set of hardened memory macros.
*
* A synthesizable reference model is used when the PROP is DEFAULT. The
* synthesizable model does not implement the cfg and test interface and should
* only be used for basic testing and for synthesizing for FPGA devices.
* Advanced ASIC development should rely on complete functional models
* supplied on a per macro basis.
*
* Technology specific implementations of "la_tdpram" would generally include
* one or more hardcoded instantiations of RAM modules with a generate
* statement relying on the "PROP" to select between the list of modules
* at build time.
*
****************************************************************************/

module la_tdpram #(
parameter DW = 32, // Memory width
parameter AW = 10, // address width (derived)
parameter PROP = "DEFAULT", // pass through variable for hard macro
parameter CTRLW = 128, // width of asic ctrl interface
parameter TESTW = 128 // width of asic test interface
) ( // A port
input clk_a, // write clock
input ce_a, // write chip-enable
input we_a, // write enable
input [DW-1:0] wmask_a, // write mask
input [AW-1:0] addr_a, // write address
input [DW-1:0] din_a, // write data in
output [DW-1:0] dout_a, // read data out
// B port
input clk_b, // write clock
input ce_b, // write chip-enable
input we_b, // write enable
input [DW-1:0] wmask_b, // write mask
input [AW-1:0] addr_b, // write address
input [DW-1:0] din_b, // write data in
output [DW-1:0] dout_b, // read data out
// Power signal
input vss, // ground signal
input vdd, // memory core array power
input vddio, // periphery/io power
// Generic interfaces
input [CTRLW-1:0] ctrl, // pass through ASIC control interface
input [TESTW-1:0] test // pass through ASIC test interface
);

la_tdpram_impl #(
.DW (DW),
.AW (AW),
.PROP (PROP),
.CTRLW (CTRLW),
.TESTW (TESTW)
) memory (
.clk_a (clk_a),
.ce_a (ce_a),
.we_a (we_a),
.wmask_a (wmask_a),
.addr_a (addr_a),
.din_a (din_a),
.dout_a (dout_a),

.clk_b (clk_b),
.ce_b (ce_b),
.we_b (we_b),
.wmask_b (wmask_b),
.addr_b (addr_b),
.din_b (din_b),
.dout_b (dout_b),

.vss (vss),
.vdd (vdd),
.vddio (vddio),

.ctrl (ctrl),
.test (test)
);

endmodule
93 changes: 93 additions & 0 deletions lambdalib/ramlib/la_tdpram/rtl/la_tdpram_impl.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/*****************************************************************************
* Function: True Dual Port RAM (Two write + read ports)
* Copyright: Lambda Project Authors. All rights Reserved.
* License: MIT (see LICENSE file in Lambda repository)
*
* Docs:
*
* This is a wrapper for selecting from a set of hardened memory macros.
*
* A synthesizable reference model is used when the PROP is DEFAULT. The
* synthesizable model does not implement the cfg and test interface and should
* only be used for basic testing and for synthesizing for FPGA devices.
* Advanced ASIC development should rely on complete functional models
* supplied on a per macro basis.
*
* Technology specific implementations of "la_tdpram" would generally include
* one or more hardcoded instantiations of RAM modules with a generate
* statement relying on the "PROP" to select between the list of modules
* at build time.
*
****************************************************************************/

module la_tdpram_impl #(
parameter DW = 32, // Memory width
parameter AW = 10, // address width (derived)
parameter PROP = "DEFAULT", // pass through variable for hard macro
parameter CTRLW = 128, // width of asic ctrl interface
parameter TESTW = 128 // width of asic test interface
) ( // Write port
input clk_a, // write clock
input ce_a, // write chip-enable
input we_a, // write enable
input [DW-1:0] wmask_a, // write mask
input [AW-1:0] addr_a, // write address
input [DW-1:0] din_a, // write data in
output reg [DW-1:0] dout_a, // read data out
// B port
input clk_b, // write clock
input ce_b, // write chip-enable
input we_b, // write enable
input [DW-1:0] wmask_b, // write mask
input [AW-1:0] addr_b, // write address
input [DW-1:0] din_b, // write data in
output reg [DW-1:0] dout_b, // read data out
// Power signal
input vss, // ground signal
input vdd, // memory core array power
input vddio, // periphery/io power
// Generic interfaces
input [CTRLW-1:0] ctrl, // pass through ASIC control interface
input [TESTW-1:0] test // pass through ASIC test interface
);

// Generic RTL RAM
/* verilator lint_off MULTIDRIVEN */
reg [DW-1:0] ram[(2**AW)-1:0];
/* verilator lint_on MULTIDRIVEN */

integer i;

// Port A write
always @(posedge clk_a) begin
for (i = 0; i < DW; i = i + 1) begin
if (ce_a && we_a && wmask_a[i]) begin
ram[addr_a][i] <= din_a[i];
end
end
end

// Port B write
always @(posedge clk_b) begin
for (i = 0; i < DW; i = i + 1) begin
if (ce_b && we_b && wmask_b[i]) begin
ram[addr_b][i] <= din_b[i];
end
end
end

// Port A read
always @(posedge clk_a) begin
if (ce_a && ~we_a) begin
dout_a <= ram[addr_a];
end
end

// Port B read
always @(posedge clk_b) begin
if (ce_b && ~we_b) begin
dout_b <= ram[addr_b];
end
end

endmodule