Livt packages
Eccelerators.RiscV
Version 0.3.0
Composable RV32I and Zmmul processors, machine-mode support, and reusable FPGA system components written in Livt.
Published files (120)
- fixtures
- DelayedWordDevice.lvt
- PipelineFetchMemory.lvt
- PipelineWordDevice.lvt
- README.md
- Rv32BusCoreTest.lvt
- Rv32BusProtocolTest.lvt
- Rv32CsrEngineTest.lvt
- Rv32CsrRetirement.lvt
- Rv32DspControlTest.lvt
- Rv32DspEngineTest.lvt
- Rv32DspMultiplierTest.lvt
- Rv32DualReadDistributedTest.lvt
- Rv32DualReadRegisterBankTest.lvt
- Rv32ExternalInterruptTest.lvt
- Rv32FetchBusTest.lvt
- Rv32iConstantsTest.lvt
- Rv32iDecodeTest.lvt
- Rv32InterruptCsrTest.lvt
- Rv32iPackageApiTest.lvt
- Rv32iSemanticsTest.lvt
- Rv32IterativeMultiplierTest.lvt
- Rv32LoadStoreBusTest.lvt
- Rv32MachineCsrsTest.lvt
- Rv32MachineDecoderTest.lvt
- Rv32MultiplyRetirement.lvt
- Rv32MultiplyVectors.lvt
- Rv32PipelineControlTest.lvt
- Rv32PipelineCsrEngineTest.lvt
- Rv32PipelineDspEngineTest.lvt
- Rv32PipelineEngineTest.lvt
- Rv32PipelineExternalInterruptTest.lvt
- Rv32PipelineTimerInterruptTest.lvt
- Rv32PipelineTrapEngineTest.lvt
- Rv32PipelineZmmulEngineTest.lvt
- Rv32RegisterBankTest.lvt
- Rv32SequentialControlTest.lvt
- Rv32SequentialEngineTest.lvt
- Rv32TimerInterruptTest.lvt
- Rv32TrapEngineTest.lvt
- Rv32TrapPolicyTest.lvt
- Rv32ZicsrAccessTest.lvt
- Rv32ZicsrDecoderTest.lvt
- Rv32ZmmulControlTest.lvt
- Rv32ZmmulDecodeTest.lvt
- Rv32ZmmulEngineTest.lvt
- RvExternalInterruptsTest.lvt
- RvMachineSystemTest.lvt
- RvMachineTimerTest.lvt
- RvPipelineSystemTest.lvt
- RvSystemTest.lvt
- RvUartDeviceTest.lvt
- RvUartSystemTest.lvt
tests/Rv32DualReadDistributedTest.lvt
namespace Eccelerators.RiscV.Tests
using Eccelerators.RiscV.Storage
using Eccelerators.RiscV.Contracts
using Livt.IO
/**
* Independent architectural checks for simultaneous read/write register storage.
* Every test initializes the bank and uses distinct operand values.
*/
@Test
component Rv32DualReadDistributedTest
{
// Owned provider and compatibility witness in the test clock domain.
subject: Rv32DualReadRegisterBank<MemoryStyle.Distributed>
contract: RvPipelineContract<Rv32DualReadRegisterBank.READ_PORTS,
Rv32DualReadRegisterBank.READ_LATENCY, Rv32DualReadRegisterBank.INDEPENDENT_WRITE,
Rv32DualReadRegisterBank.WRITE_FORWARDING>
/**
* Instantiates a concrete storage style with the documented pipeline contract.
*/
new()
{
subject = new Rv32DualReadRegisterBank<MemoryStyle.Distributed>()
contract = new RvPipelineContract<Rv32DualReadRegisterBank.READ_PORTS,
Rv32DualReadRegisterBank.READ_LATENCY, Rv32DualReadRegisterBank.INDEPENDENT_WRITE,
Rv32DualReadRegisterBank.WRITE_FORWARDING>()
}
/**
* Initializes architectural registers through the public write port.
*/
fn Initialize()
{
subject.readEnable = 0b0
subject.writeEnable = 0b0
for (var index: uint = 1; index < 32; index++) {
subject.writeIndex = index as logic[5]
subject.writeData = (index * 17) as logic[32]
subject.writeEnable = 0b1
Simulation.Wait(2)
}
subject.writeEnable = 0b0
Simulation.Wait(2)
}
/**
* Both operands are independently addressed, including the last register.
*/
@Test
fn IndependentReads()
{
Initialize()
subject.readEnable = 0b1
for (var index: uint = 0; index < 32; index++) {
subject.leftIndex = index as logic[5]
subject.rightIndex = (31 - index) as logic[5]
Simulation.Wait(2)
assert subject.leftData as uint == index * 17
assert subject.rightData as uint == (31 - index) * 17
}
}
/**
* A write forwards to either or both readers and persists in both copies.
*/
@Test
fn CollisionsReturnNewValue()
{
Initialize()
subject.readEnable = 0b1
subject.leftIndex = 3
subject.rightIndex = 5
subject.writeIndex = 3
subject.writeData = 0x12345678
subject.writeEnable = 0b1
Simulation.Wait(2)
assert subject.leftData == 0x12345678
assert subject.rightData == 85
subject.writeIndex = 5
subject.writeData = 0xabcdef01
Simulation.Wait(2)
assert subject.leftData == 0x12345678
assert subject.rightData == 0xabcdef01
subject.leftIndex = 5
Simulation.Wait(2)
assert subject.leftData == 0xabcdef01
assert subject.rightData == 0xabcdef01
subject.writeEnable = 0b0
subject.leftIndex = 3
subject.rightIndex = 3
Simulation.Wait(2)
assert subject.leftData == 0x12345678
assert subject.rightData == 0x12345678
}
/**
* Architectural zero wins even when both read ports collide with a write to x0.
*/
@Test
fn ZeroIgnoresWrites()
{
Initialize()
subject.readEnable = 0b1
subject.leftIndex = 0
subject.rightIndex = 0
subject.writeEnable = 0b1
subject.writeIndex = 0
subject.writeData = 0xffffffff
Simulation.Wait(2)
assert subject.leftData == 0
assert subject.rightData == 0
}
/**
* Disabled reads retain the previous pair while independent writes proceed.
*/
@Test
fn DisabledReadsHoldDuringWrites()
{
Initialize()
subject.readEnable = 0b1
subject.leftIndex = 7
subject.rightIndex = 9
Simulation.Wait(2)
subject.readEnable = 0b0
subject.writeEnable = 0b1
subject.writeIndex = 7
subject.writeData = 0xffffffff
Simulation.Wait(3)
assert subject.leftData == 119
assert subject.rightData == 153
subject.writeEnable = 0b0
subject.readEnable = 0b1
Simulation.Wait(2)
assert subject.leftData == 0xffffffff
assert subject.rightData == 153
}
}