mirror of https://github.com/YosysHQ/yosys.git
192 lines
4.7 KiB
Plaintext
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;
|
|
}
|
|
}
|