diff --git a/sim/CMakeLists.txt b/sim/CMakeLists.txt index 5d652d8..f02b352 100644 --- a/sim/CMakeLists.txt +++ b/sim/CMakeLists.txt @@ -9,15 +9,19 @@ set(CMAKE_C_STANDARD 11) FetchContent_Declare( - dear_imgui - GIT_REPOSITORY https://github.com/ocornut/imgui.git - GIT_TAG 231cbee0fc4f59dbe5b8b853a11b08dc84e57c65 # version 1.90.5 + dear_imgui + GIT_REPOSITORY https://github.com/ocornut/imgui.git + GIT_TAG 231cbee0fc4f59dbe5b8b853a11b08dc84e57c65 # version 1.90.5 + CONFIGURE_COMMAND "" + BUILD_COMMAND "" ) FetchContent_Declare( - sokol - GIT_REPOSITORY https://github.com/floooh/sokol.git - GIT_TAG 55bc9cf3fa4051d485d10412c75c893c3135e885 + sokol + GIT_REPOSITORY https://github.com/floooh/sokol.git + GIT_TAG 55bc9cf3fa4051d485d10412c75c893c3135e885 + CONFIGURE_COMMAND "" + BUILD_COMMAND "" ) @@ -28,10 +32,18 @@ FetchContent_Declare( ) + FetchContent_MakeAvailable(sokol dear_imgui Catch2) + +# sokol +add_library(sokol INTERFACE) +target_include_directories(sokol INTERFACE ${sokol_SOURCE_DIR}) + list(APPEND CMAKE_MODULE_PATH ${catch2_SOURCE_DIR}/extras) # needed for the catch_discover_tests function +list(APPEND VSOURCES ../verilog/hub75e.sv ../verilog/lineram.v) + set(CMAKE_EXPORT_COMPILE_COMMANDS TRUE) find_package(verilator HINTS $ENV{VERILATOR_ROOT}) @@ -43,14 +55,23 @@ target_sources(sim PRIVATE target_include_directories(sim PRIVATE inc/) - - -list(APPEND VSOURCES ../verilog/hub75e.sv ../verilog/lineram.v) - verilate(sim SOURCES ${VSOURCES} TRACE VERILATOR_ARGS -Wno-MULTITOP) -target_link_libraries(sim PRIVATE Catch2::Catch2WithMain) +target_link_libraries(sim PRIVATE sokol) + +add_executable(sim_test) +target_sources(sim_test PRIVATE + test/hub75.cpp +) + +target_include_directories(sim_test PRIVATE inc/) + +target_link_libraries(sim_test PRIVATE sokol) + +verilate(sim_test SOURCES ${VSOURCES} TRACE VERILATOR_ARGS -Wno-MULTITOP) + +target_link_libraries(sim_test PRIVATE Catch2::Catch2WithMain) include(CTest) include(Catch) -catch_discover_tests(sim) +catch_discover_tests(sim_test) diff --git a/sim/test/hub75.cpp b/sim/test/hub75.cpp new file mode 100644 index 0000000..3fda243 --- /dev/null +++ b/sim/test/hub75.cpp @@ -0,0 +1,87 @@ +#include "Vhub75e.h" +#include "devices.hpp" +#include "tests.hpp" +#include +#include +#include +#include +#include + +TEST_CASE("HUB75E Driver Test") { + auto fixture = VerilatorTestFixture(); + // very simple done checker. + auto done_check = [](Vhub75e &dut, unsigned long time) { + return dut.done == 1; + }; + fixture.set_done_callback(done_check); + const Vhub75e &dut = fixture.get(); + // stimulus to start the transaction. + auto stim = std::make_shared(dut.write_trig, 4); + fixture.add_module(stim); + fixture.set_timeout(250000); + auto bram = std::make_shared(1, dut.clk, dut.pixbuf_addr, + dut.pixbuf_data); + fixture.add_module(bram); + auto display = std::make_shared(128, 64, dut); + fixture.add_module(display); + + + SECTION("Smoke Tests") { + + fixture.exec(); + + CHECK(fixture.get_reason() == + VerilatorTestFixture::FinishReason::Ok); + + auto rows = display->get_past_rows(); + CHECK(rows.size() == 8); + for (int i = 0; i < rows.size(); i++) { + auto &[r0, r1] = rows[i]; + CHECK(r0.size() == 128); + CHECK(r1.size() == 128); + } + // pulse width smoke tests. + auto pulses = display->get_pulse_widths(); + REQUIRE(pulses.size() == rows.size()); + for (int i = 1; i < pulses.size(); i++) { + REQUIRE(pulses[i] == pulses[i - 1] / 2); + } + auto [row0, row1] = display->transpose(); + REQUIRE(row0.size() == 128); + REQUIRE(row1.size() == 128); + auto ram_ref = bram->get(); + + CAPTURE(row0); + CHECK(std::equal(ram_ref.begin(), ram_ref.begin() + 128, row0.begin(), + row0.end())); + } + SECTION("Line Correctness") { + // this is the part where we validate that the line in = line out. + // we have to generate different values since the + fixture.enable_trace("testing.vcd"); + // generate an entire block of RAM + auto line = GENERATE(take(1, chunk(512, random(0, 0xFFFFFF)))); + std::copy(line.begin(), line.end(), bram->get().begin()); + + fixture.exec(); + + REQUIRE(fixture.get_reason() == + VerilatorTestFixture::FinishReason::Ok); + + auto [row0, row1] = display->transpose(); + REQUIRE(row0.size() == 128); + REQUIRE(row1.size() == 128); + auto ram_ref = bram->get(); + + for (int i = 0; i < 128; i++) { + CAPTURE(i); + CAPTURE(ram_ref[i], row0[i]); + CHECK(ram_ref[i] == row0[i]); + CAPTURE(ram_ref[i+256], row1[i]); + CHECK(ram_ref[i+256] == row1[i]); + + } + // CHECK(std::equal(ram_ref.begin(), ram_ref.begin() + 128, row0.begin(), + // row0.end())); + } +} diff --git a/verilog/hub75e.sv b/verilog/hub75e.sv index b578011..9eebdb9 100644 --- a/verilog/hub75e.sv +++ b/verilog/hub75e.sv @@ -84,18 +84,18 @@ module hub75e ( end 1: begin // load pix 1 - panel_rgb0 <= ram_rgb_slice; // wait for pix 1 pixrow <= 1; end 2: begin + panel_rgb0 <= ram_rgb_slice; + end + 3: begin panel_rgb1 <= ram_rgb_slice; - pixrow <= 0; counter <= 0; state <= StateWriteRow; end default: begin - counter <= 0; end endcase end