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 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
|
# 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;
}
}
|