yosys/techlibs/microchip/LSRAM.txt

192 lines
4.7 KiB
Plaintext

# ISC License
#
# Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
# LSRAM true dual-port
ram block $__LSRAM_TDP_ {
# Cost of a given cell is assumed to be:
# (cost-widthscale) + [widthscale * (used_bits/14)]
cost 129;
# INIT is supported
init any;
# port A and port B are allowed to have different widths, but they MUST have
# WIDTH values of the same set.
# Example: Port A has a Data Width of 1. Then Port B's Data Width must be either
# 1, 2, 4, 8, or 16 (both values are in the 'WIDTH_1' set).
# WIDTH_1 = {1, 2, 4, 8, 16}
# WIDTH_2 = {5, 10, 20}
# "byte" specifies how many data bits correspond to one write enable bit.
# "byte" must be larger than width, or width must be a multipler of "byte"
# if "byte" > WIDTH, a single enable wire is inferred
# otherwise, WIDTH/byte number of enable wires are inferred
#
# WIDTH = {1, 2, 4, 5, 8, 10} requires 1 enable wire
# WIDTH = {16, 20} requires 2 enable wire
option "WIDTH_CONFIG" "REGULAR" {
# Data-Width| Address bits
# 1 | 14
# 2 | 13
# 4 | 12
# 8 | 11
# 16 | 10
# 14 address bits
abits 14;
widths 1 2 4 8 16 per_port;
byte 8;
}
option "WIDTH_CONFIG" "ALIGN" {
# Data-Width| Address bits
# 5 | 12
# 10 | 11
# 20 | 10
# Quick "hack" to fix address bit alignment by setting address bits to 12.
# If abits=14, tool will think there are 14 bits for width=5, 13 bits for width=10, 12 bits for width=20
# THe LSRAM_map.v file detects if this option is being used, and adjusts the address port alignments accordingly.
abits 12;
widths 5 10 20 per_port;
byte 10;
}
port srsw "A" "B" {
# read & write width must be same
width tied;
# clock polarity is rising
clock posedge;
# A/B read-enable
rden;
# initial value of read port data (not supported)
rdinit none;
# write modes (<A/B>_WMODE)
# 1. Simple Write: read-data port holds prev value (similar to "NO_CHANGE" for RAMB18E1)
# 2. Feed-through: read-data port takes new write value (similar to "WRITE_FIRST" for RAMB18E1)
# 3. Read-Before-Write: read-data port holds old value while being written (similar to "READ_FIRST" for RAMB18E1)
portoption "WRITE_MODE" "NO_CHANGE" {
# Read-write interaction
rdwr no_change;
# Write transparency:
# For write ports, define behaviour when another synchronous read port
# reads from the same memory cell that said write port is writing to at the same time.
wrtrans all old;
}
portoption "WRITE_MODE" "WRITE_FIRST" {
# bits corresponding to high A/B_WEN are updated
rdwr new_only;
wrtrans all new;
}
portoption "WRITE_MODE" "READ_FIRST" {
rdwr old;
wrtrans all old;
}
# generate params to indicate if read or write is used for each port
optional_rw;
}
}
# two-port configuration
ram block $__LSRAM_SDP_ {
# since two-port configuration is dedicated for wide-read/write,
# we want to prioritize this configuration over TDP to avoid tool picking multiple TDP RAMs
# inplace of a single SDP RAM for wide read/write. This means the cost of a single SDP should
# be less than 2 TDP.
cost 129;
init any;
option "WIDTH_CONFIG" "REGULAR" {
# Data-Width| Address bits
# 1 | 14
# 2 | 13
# 4 | 12
# 8 | 11
# 16 | 10
# 32 | 9
abits 14;
widths 1 2 4 8 16 32 per_port;
# width = 32, byte-write size is 8, ignore other widths
byte 8;
}
option "WIDTH_CONFIG" "ALIGN" {
# Data-Width| Address bits
# 5 | 12
# 10 | 11
# 20 | 10
# 40 | 9
# Same trick as TSP RAM for alignment
abits 12;
widths 5 10 20 40 per_port;
byte 10;
}
port sw "W" {
# only consider wide write
option "WIDTH_CONFIG" "REGULAR" width 32;
option "WIDTH_CONFIG" "ALIGN" width 40;
clock posedge;
# only simple write supported for two-port mode
wrtrans all old;
optional;
}
port sr "R" {
option "WIDTH_CONFIG" "REGULAR" width 32;
option "WIDTH_CONFIG" "ALIGN" width 40;
clock posedge;
rden;
rdinit none;
optional;
}
}