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/RvMachineTimerTest.lvt
namespace Eccelerators.RiscV.Tests
using Eccelerators.RiscV.Platform
/**
* Exercises the timer through its public MMIO port; exact edge/reset checks use HDL.
*/
@Test
component RvMachineTimerTest
{
// Owned fast timebase and latest bus snapshot.
timer: RvMachineTimer<0, 1, 1>
value: uint
/**
* Uses one tick per clock to expose rollover and held-request mistakes quickly.
*/
new()
{
timer = new RvMachineTimer<0, 1, 1>()
}
/**
* Completes one request and verifies stable response while held for extra clocks.
*/
fn Access(address: uint, write: bool, data: uint, lanes: uint, error: bool)
{
timer.request = 0b0
Simulation.Wait(3)
timer.address = address as logic[32]
timer.write = write as logic
timer.writeData = data as logic[32]
timer.byteEnable = lanes as logic[4]
timer.request = 0b1
var elapsed: uint = 0
while (timer.ready == 0b0 && elapsed < 20) {
state {
elapsed++
}
}
assert timer.ready == 0b1 && (timer.error == 0b1) == error
value = timer.readData as uint
Simulation.Wait(8)
assert timer.readData as uint == value && timer.ready == 0b1
timer.request = 0b0
Simulation.Wait(3)
assert timer.ready == 0b0
}
/**
* Establishes a distant deadline and known time without depending on other tests.
*/
fn Prepare()
{
Access(8, true, 0xffffffff, 15, false)
Access(12, true, 0xffffffff, 15, false)
Access(4, true, 0, 15, false)
Access(0, true, 0, 15, false)
assert timer.timerPending == 0b0
}
/**
* A held time write happens once while the timebase keeps advancing.
*/
@Test
fn HeldWritesAndReadSnapshots()
{
Prepare()
Access(0, true, 0, 15, false)
Access(0, false, 0, 0, false)
assert value >= 12 && value < 100
var before = value
Simulation.Wait(30)
Access(0, false, 0, 0, false)
assert value > before + 30
}
/**
* Deadline words honor byte lanes; invalid addresses and zero masks have no effect.
*/
@Test
fn ByteMasksAndInvalidRequests()
{
Prepare()
Access(8, true, 0x12345678, 15, false)
Access(8, true, 0xaabbccdd, 5, false)
Access(8, false, 0, 0, false)
assert value == 0x12bb56dd
Access(8, true, 0, 0, false)
Access(9, true, 0, 15, true)
Access(16, true, 0, 15, true)
Access(0xfffffffc, true, 0, 15, true)
Access(8, false, 0, 0, false)
assert value == 0x12bb56dd
Access(12, false, 0, 0, false)
assert value == 0xffffffff && timer.timerPending == 0b0
}
/**
* Unsigned high-word comparison dominates low words, including the sign bit.
*/
@Test
fn UnsignedComparisonAndRearming()
{
Prepare()
Access(4, true, 0x80000000, 15, false)
Access(12, true, 0x7fffffff, 15, false)
assert timer.timerPending == 0b1
Access(8, true, 0xffffffff, 15, false)
Access(12, true, 0x80000000, 15, false)
assert timer.timerPending == 0b0
Access(8, true, 0, 15, false)
assert timer.timerPending == 0b1
Simulation.Wait(20)
assert timer.timerPending == 0b1
Access(12, true, 0xffffffff, 15, false)
assert timer.timerPending == 0b0
}
/**
* Carry propagates across both halves and the complete timer wraps modulo 2^64.
*/
@Test
fn FullWidthRollover()
{
Prepare()
Access(4, true, 17, 15, false)
Access(0, true, 0xffffffe0, 15, false)
Simulation.Wait(80)
Access(4, false, 0, 0, false)
assert value == 18
Access(4, true, 0xffffffff, 15, false)
Access(0, true, 0xffffffe0, 15, false)
Simulation.Wait(80)
Access(4, false, 0, 0, false)
assert value == 0
}
}