# 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 (_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; } }