diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f931e90..df0fb7a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -83,6 +83,42 @@ jobs: run: julia --color=yes tests/julia/runtests.jl shell: bash + julia-matlab-verilog-test: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Set interop directory + run: echo "CONCORE_INTEROP_DIR=$RUNNER_TEMP/concore-matlab-interop" >> "$GITHUB_ENV" + + - uses: julia-actions/setup-julia@v3 + with: + version: '1.10' + + - name: Install Icarus Verilog + run: sudo apt-get update && sudo apt-get install -y iverilog + + - name: Run Verilog interop tests + run: julia --color=yes tests/julia/test_verilog_interop.jl + + - uses: matlab-actions/setup-matlab@v3 + + - name: Write Julia data for MATLAB + run: julia --color=yes tests/julia/test_matlab_interop.jl write + + - name: Run MATLAB interop tests + uses: matlab-actions/run-command@v3 + with: + command: addpath(pwd); addpath(fullfile(pwd, 'tests', 'matlab')); test_julia_interop + + - name: Read MATLAB data from Julia + run: julia --color=yes tests/julia/test_matlab_interop.jl read + + - name: Remove interop files + if: always() + run: rm -rf "$CONCORE_INTEROP_DIR" + java-test: runs-on: ubuntu-latest steps: diff --git a/tests/julia/test_matlab_interop.jl b/tests/julia/test_matlab_interop.jl new file mode 100644 index 0000000..f92944a --- /dev/null +++ b/tests/julia/test_matlab_interop.jl @@ -0,0 +1,29 @@ +using Test + +include(joinpath(@__DIR__, "..", "..", "concore.jl")) +using .Concore + +interop_dir = get(ENV, "CONCORE_INTEROP_DIR", "") +if isempty(interop_dir) + error("CONCORE_INTEROP_DIR is not set") +end + +Concore.delay = 0.0 + +if ARGS[1] == "write" + rm(interop_dir; recursive=true, force=true) + Concore.outpath = joinpath(interop_dir, "julia_out") + Concore.simtime = 12.0 + Concore.concore_write(1, "signal", [21.0, 22.5]) + + @test read(joinpath(interop_dir, "julia_out1", "signal"), String) == + "[12.0, 21.0, 22.5]" +elseif ARGS[1] == "read" + Concore.inpath = joinpath(interop_dir, "matlab_out") + result = Concore.concore_read(1, "signal", "[0.0, 0.0, 0.0]") + + @test result == [31.0, 32.5] + @test Concore.simtime == 14.0 +else + error("expected write or read") +end diff --git a/tests/julia/test_verilog_interop.jl b/tests/julia/test_verilog_interop.jl new file mode 100644 index 0000000..fa2c38a --- /dev/null +++ b/tests/julia/test_verilog_interop.jl @@ -0,0 +1,56 @@ +using Test + +include(joinpath(@__DIR__, "..", "..", "concore.jl")) +using .Concore + +repo_root = normpath(joinpath(@__DIR__, "..", "..")) +iverilog = Sys.which("iverilog") +vvp = Sys.which("vvp") +iverilog === nothing && error("iverilog executable not found") +vvp === nothing && error("vvp executable not found") + +@testset "Verilog interop" begin + mktempdir() do dir + Concore.delay = 0.0 + Concore.outpath = joinpath(dir, "in") + Concore.simtime = 12.0 + Concore.concore_write(1, "signal", [21.0, 22.5]) + mkpath(joinpath(dir, "out1")) + + source = joinpath(dir, "julia_interop.v") + simulation = joinpath(dir, "julia_interop") + write(source, """ +`include "concore.v" + +module julia_interop; +reg [8*13-1:0] init_signal = "[0.0,0.0,0.0]"; + +initial begin + #1; + concore.readdata(1, "signal", init_signal); + if (concore.datasize != 2) \$fatal(1, "unexpected data size"); + if (concore.simtime != 12.0) \$fatal(1, "unexpected simtime"); + if (concore.data[0] != 21.0) \$fatal(1, "unexpected first value"); + if (concore.data[1] != 22.5) \$fatal(1, "unexpected second value"); + + concore.simtime = 14.0; + concore.datasize = 2; + concore.data[0] = 31.0; + concore.data[1] = 32.5; + concore.writedata(1, "signal", 0); + \$finish; +end +endmodule +""") + + run(Cmd(`$iverilog -g2012 -I$repo_root -o $simulation $source`; dir=dir)) + run(Cmd(`$vvp $simulation`; dir=dir)) + + Concore.inpath = joinpath(dir, "out") + Concore.simtime = 0.0 + result = Concore.concore_read(1, "signal", "[0.0, 0.0, 0.0]") + + @test result == [31.0, 32.5] + @test Concore.simtime == 14.0 + end +end diff --git a/tests/matlab/test_julia_interop.m b/tests/matlab/test_julia_interop.m new file mode 100644 index 0000000..b45a485 --- /dev/null +++ b/tests/matlab/test_julia_interop.m @@ -0,0 +1,23 @@ +function test_julia_interop + global concore; + import_concore; + + interop_dir = getenv('CONCORE_INTEROP_DIR'); + assert(~isempty(interop_dir)); + + concore.delay = 0; + concore.inpath = fullfile(interop_dir, 'julia_out'); + + result = concore_read(1, 'signal', '[0.0, 0.0, 0.0]'); + assert(all(abs(result - [21.0, 22.5]) < 1e-9)); + assert(abs(concore.simtime - 12.0) < 1e-9); + + concore.outpath = fullfile(interop_dir, 'matlab_out'); + output_dir = [concore.outpath '1']; + if exist(output_dir, 'dir') ~= 7 + mkdir(output_dir); + end + concore.simtime = 14.0; + concore_write(1, 'signal', [31.0, 32.5], 0); + assert(exist(fullfile(output_dir, 'signal'), 'file') == 2); +end