diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c297b79..8c65b7b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -115,6 +115,12 @@ jobs: - name: Install Icarus Verilog run: sudo apt-get update && sudo apt-get install -y iverilog + - name: Run Verilog read tests + run: | + mkdir -p "$RUNNER_TEMP/verilog/in1" + iverilog -g2012 -I. -o "$RUNNER_TEMP/verilog/test_read_simtime" tests/verilog/test_read_simtime.v + cd "$RUNNER_TEMP/verilog" && vvp test_read_simtime + - name: Run Verilog interop tests run: julia --color=yes tests/julia/test_verilog_interop.jl diff --git a/concore.v b/concore.v index 8d77d93..3576989 100644 --- a/concore.v +++ b/concore.v @@ -126,6 +126,7 @@ module concore; input [`CONCORE_MAXLEN*8-1:0] name; input [`CONCORE_MAXLEN*8-1:0] initstr; reg datavalid; + real readtime; reg [(`CONCORE_MAXLEN+`INPATHLEN)*8-1:0] fname; //room for 6 extra chars reg [7:0] asciiport; integer i; @@ -189,13 +190,16 @@ module concore; $fclose(fin); end //parse - literal_eval(datavalid,simtime); + literal_eval(datavalid,readtime); if (datavalid == 0) begin retrycount = retrycount + 1; end //time end //datavalid + // keep simtime monotonic like the other bindings, an older file or the + // init string used for a missing file must not move it back + if (readtime > simtime) simtime = readtime; end endtask diff --git a/concoredocker.v b/concoredocker.v index edf0caa..4871fdd 100644 --- a/concoredocker.v +++ b/concoredocker.v @@ -126,6 +126,7 @@ module concore; input [`CONCORE_MAXLEN*8-1:0] name; input [`CONCORE_MAXLEN*8-1:0] initstr; reg datavalid; + real readtime; reg [(`CONCORE_MAXLEN+`INPATHLEN)*8-1:0] fname; //room for 6 extra chars reg [7:0] asciiport; integer i; @@ -189,13 +190,16 @@ module concore; $fclose(fin); end //parse - literal_eval(datavalid,simtime); + literal_eval(datavalid,readtime); if (datavalid == 0) begin retrycount = retrycount + 1; end //time end //datavalid + // keep simtime monotonic like the other bindings, an older file or the + // init string used for a missing file must not move it back + if (readtime > simtime) simtime = readtime; end endtask diff --git a/tests/protocol_fixtures/cross_runtime_matrix.phase2.json b/tests/protocol_fixtures/cross_runtime_matrix.phase2.json index 0ffda31..6aedeb3 100644 --- a/tests/protocol_fixtures/cross_runtime_matrix.phase2.json +++ b/tests/protocol_fixtures/cross_runtime_matrix.phase2.json @@ -268,9 +268,9 @@ "note": "Audit planned in phase 2." }, "verilog": { - "status": "not_audited", + "status": "observed_pass", "classification": "implementation_defined", - "note": "May require binding-specific interpretation." + "note": "readdata() falls back to the init string, so data and simtime match the fixture. concore.v has no success flag to return, so the ok=False part has no equivalent. Checked by tests/verilog/test_read_simtime.v." } } }, @@ -304,9 +304,9 @@ "note": "Audit planned in phase 2." }, "verilog": { - "status": "not_audited", + "status": "observed_pass", "classification": "implementation_defined", - "note": "May require binding-specific interpretation." + "note": "readdata() only moves simtime forward, an older file timestamp leaves it unchanged. Checked by tests/verilog/test_read_simtime.v." } } } diff --git a/tests/test_protocol_conformance_phase2.py b/tests/test_protocol_conformance_phase2.py index 4c13f52..e9f8296 100644 --- a/tests/test_protocol_conformance_phase2.py +++ b/tests/test_protocol_conformance_phase2.py @@ -93,3 +93,11 @@ def test_phase2_matrix_cpp_status_is_recorded_for_each_case(): assert cpp_result["status"] == "observed_fail" else: assert cpp_result["status"] == "observed_pass" + + +# concore.v only has the file based read path, so the read_file cases are the +# ones that apply to it. tests/verilog/test_read_simtime.v checks both in CI. +def test_phase2_matrix_verilog_read_file_cases_pass(): + for row in _phase2_matrix()["cases"]: + if row["target"] == "read_file": + assert row["runtime_results"]["verilog"]["status"] == "observed_pass" diff --git a/tests/verilog/test_read_simtime.v b/tests/verilog/test_read_simtime.v new file mode 100644 index 0000000..1dca36c --- /dev/null +++ b/tests/verilog/test_read_simtime.v @@ -0,0 +1,29 @@ +`include "concore.v" + +// read_file cases from tests/protocol_fixtures/python_phase1_cases.json +// run from a directory that has an empty in1/ folder +module test_read_simtime; +reg [8*10-1:0] missing_init = "[0.0, 5.0]"; +reg [8*10-1:0] ym_init = "[0.0, 0.0]"; +integer f; + +initial begin + // read_file/missing_file_returns_default_and_false + concore.simtime = 4; + concore.readdata(1, "missing", missing_init); + if (concore.simtime != 4) $fatal(1, "missing file: simtime is %f, expected 4", concore.simtime); + if (concore.data[0] != 5.0) $fatal(1, "missing file: data[0] is %f, expected 5.0", concore.data[0]); + + // read_file/older_timestamp_does_not_decrease_simtime + f = $fopen("in1/ym", "w"); + $fwrite(f, "[7.0, 3.14]"); + $fclose(f); + concore.simtime = 10; + concore.readdata(1, "ym", ym_init); + if (concore.simtime != 10) $fatal(1, "older timestamp: simtime is %f, expected 10", concore.simtime); + if (concore.data[0] != 3.14) $fatal(1, "older timestamp: data[0] is %f, expected 3.14", concore.data[0]); + + $display("read simtime tests passed"); + $finish; +end +endmodule