Livt packages

Livt.IO

Version 1.8.1

Memory, UART, I2C, SPI, and Ethernet input/output components for Livt hardware designs.

Published files (126)

src/memory/Ram.lvt

namespace Livt.IO

/**
 * Scheduled element-addressable RAM with compile-time payload, capacity and style.
 * Cells survive reset; unwritten contents are unspecified. Use SynchronousRam
 * directly when a one-command-per-clock datapath is needed.
 */
component Ram<T, CAPACITY: int = 64, STYLE: MemoryStyle = MemoryStyle.Auto> : IRam<T>
{
	// Element geometry; capacity counts T values rather than bytes.
	public const ADDRESS_WIDTH: int = Bits.RequiredFor(CAPACITY - 1)
	public const MAX_ADDRESS: int = CAPACITY - 1

	static assert CAPACITY > 0, "RAM capacity must be positive"

	// One portable payload store and one scheduled transaction owner.
	storage: SynchronousRam<T, logic[ADDRESS_WIDTH], CAPACITY, STYLE>
	access: IRam<T>

	/**
	 * Constructs the portable backend in the inherited clock/reset context.
	 */
	new()
	{
		this.storage = new SynchronousRam<T, logic[ADDRESS_WIDTH], CAPACITY, STYLE>()
		this.access = new RamAccess<T, logic[ADDRESS_WIDTH], CAPACITY, SynchronousRam<T, logic[ADDRESS_WIDTH], CAPACITY, STYLE>>(this.storage)
	}

	/**
	 * Reads one element, or zero for an invalid address.
	 */
	override fn Read(address: int) T
	{
		return this.access.Read(address)
	}

	/**
	 * Writes one element; invalid addresses are ignored.
	 */
	override fn Write(address: int, value: T)
	{
		this.access.Write(address, value)
	}

	/**
	 * Reports whether address selects an element in this memory.
	 */
	override fn IsValidAddress(address: int) bool
	{
		return this.access.IsValidAddress(address)
	}
}