Livt packages
Eccelerators.Matrix
Version 1.0.1
Reusable RGB matrix drawing, color conversion, animation pacing, and HUB75 display components for Livt.
Published files (48)
- ColorConverterTest.lvt
- ColorGainTest.lvt
- ColorSampleBitmap.lvt
- ConvertedPainterTest.lvt
- DisplayTestBitmap.lvt
- Hub75ChainTest.lvt
- Hub75Clock100Test.lvt
- Hub75Clock50Test.lvt
- Hub75Clock75Test.lvt
- Hub75Color6Test.lvt
- Hub75ColorTest.lvt
- Hub75Display4Test.lvt
- Hub75Display6Test.lvt
- Hub75FramebufferTest.lvt
- Hub75GeometryTest.lvt
- MatrixColorTest.lvt
- MatrixFramePacerTest.lvt
- MatrixPictureHoldTest.lvt
- MatrixPictureSequenceTest.lvt
- MatrixPipelineTest.lvt
- MatrixRendererPacingTest.lvt
- MatrixRendererTest.lvt
- MemoryDisplay.lvt
- RendererClient.lvt
tests/Hub75FramebufferTest.lvt
namespace Eccelerators.Matrix.Tests
using Eccelerators.Matrix
using Eccelerators.Matrix.Hub75
/**
* Verify bounds, drawing isolation and frame-boundary presentation on an 8x4
* framebuffer. One test deliberately starts from construction state to check
* reset visibility, then explicitly clears each drawing transaction.
*/
@Test
component Hub75FramebufferTest
{
// Owned framebuffer under test.
subject: Hub75Framebuffer<8, 1>
// Controlled scan address, boundary pulse and observed lane outputs.
x: logic[3]
row: logic[1]
boundary: logic
upper: logic[3]
lower: logic[3]
// Frame-boundary stimulus and acknowledgment counters.
pulsing: bool
counter: int
boundaries: int
/**
* Own an 8x4 framebuffer for this test run.
*/
new()
{
this.subject = new Hub75Framebuffer<8, 1>()
}
/**
* Wire the controlled scan address and boundary pulse and observe both lanes.
*/
process Connect[]()
{
this.subject.readColumn = this.x
this.subject.readRow = this.row
this.subject.frameBoundary = this.boundary
this.upper = this.subject.rgbUpper
this.lower = this.subject.rgbLower
}
/**
* Emit a frame boundary every 128 clocks while the test enables pulsing.
*/
process Boundaries()
{
state {
this.boundary = 0b0
if (this.pulsing) {
if (this.counter == 127) {
this.counter = 0;
this.boundary = 0b1;
this.boundaries++
} else {
this.counter++
}
} else {
this.counter = 0
}
}
}
/**
* Allow eight context edges for the scan read pipeline to settle.
*/
fn Settle()
{
for (var i = 0; i < 8; i++) {
state {
}
}
}
/**
* Check construction visibility, rejected requests, completed writes and bank swaps.
* Clear each new image explicitly; this is the component’s only test case.
*/
@Test
fn PreservesFrontBufferUntilPresentation()
{
this.Settle()
assert this.upper == 0b000 && this.lower == 0b000
assert this.subject.Present() == false
this.subject.Clear(0b100)
assert this.subject.SetPixel(0, 0, 0b010) == true
assert this.subject.SetPixel(7, 3, 0b001) == true
assert this.subject.SetPixel(-1, 0, 0b111) == false
assert this.subject.SetPixel(8, 0, 0b111) == false
assert this.subject.SetPixel(0, -1, 0b111) == false
assert this.subject.SetPixel(0, 4, 0b111) == false
assert this.upper == 0b000 && this.lower == 0b000
var before = this.boundaries
this.pulsing = true
assert this.subject.Present() == true
assert this.boundaries == before + 1
this.pulsing = false
this.Settle()
assert this.upper == 0b010 && this.lower == 0b100
this.x = 0b111
this.row = 0b1
this.Settle()
assert this.upper == 0b100 && this.lower == 0b001
this.subject.Clear(0b001)
assert this.subject.SetPixel(7, 1, 0b010) == true
this.Settle()
assert this.upper == 0b100 && this.lower == 0b001
this.pulsing = true
assert this.subject.Present() == true
this.pulsing = false
this.Settle()
assert this.upper == 0b010 && this.lower == 0b001
this.x = 0b000
this.row = 0b0
this.Settle()
assert this.upper == 0b001 && this.lower == 0b001
assert this.subject.Present() == false
}
}