mirror of
https://github.com/verilator/verilator.git
synced 2025-01-01 04:07:34 +00:00
Signed-off-by: Bartłomiej Chmiel <bchmiel@antmicro.com>
This commit is contained in:
parent
94fd17e4f7
commit
a668b7c658
@ -291,6 +291,7 @@ AstCFunc* splitCheckCreateNewSubFunc(AstCFunc* ofuncp) {
|
|||||||
subFuncp->isLoose(true);
|
subFuncp->isLoose(true);
|
||||||
subFuncp->slow(ofuncp->slow());
|
subFuncp->slow(ofuncp->slow());
|
||||||
subFuncp->declPrivate(ofuncp->declPrivate());
|
subFuncp->declPrivate(ofuncp->declPrivate());
|
||||||
|
if (ofuncp->needProcess()) subFuncp->setNeedProcess();
|
||||||
return subFuncp;
|
return subFuncp;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -368,7 +368,9 @@ void transformForks(AstNetlist* const netlistp) {
|
|||||||
// Start with children, so later we only find awaits that are actually in this begin
|
// Start with children, so later we only find awaits that are actually in this begin
|
||||||
m_beginHasAwaits = false;
|
m_beginHasAwaits = false;
|
||||||
iterateChildrenConst(nodep);
|
iterateChildrenConst(nodep);
|
||||||
if (m_beginHasAwaits || nodep->needProcess()) {
|
if (!nodep->stmtsp()) {
|
||||||
|
nodep->unlinkFrBack();
|
||||||
|
} else if (m_beginHasAwaits || nodep->needProcess()) {
|
||||||
UASSERT_OBJ(!nodep->name().empty(), nodep, "Begin needs a name");
|
UASSERT_OBJ(!nodep->name().empty(), nodep, "Begin needs a name");
|
||||||
// Create a function to put this begin's statements in
|
// Create a function to put this begin's statements in
|
||||||
FileLine* const flp = nodep->fileline();
|
FileLine* const flp = nodep->fileline();
|
||||||
@ -407,11 +409,7 @@ void transformForks(AstNetlist* const netlistp) {
|
|||||||
} else {
|
} else {
|
||||||
// The begin has neither awaits nor a process::self call, just inline the
|
// The begin has neither awaits nor a process::self call, just inline the
|
||||||
// statements
|
// statements
|
||||||
if (nodep->stmtsp()) {
|
|
||||||
nodep->replaceWith(nodep->stmtsp()->unlinkFrBackWithNext());
|
nodep->replaceWith(nodep->stmtsp()->unlinkFrBackWithNext());
|
||||||
} else {
|
|
||||||
nodep->unlinkFrBack();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,8 @@
|
|||||||
// - a function taking VlProcess argument shared between a process that
|
// - a function taking VlProcess argument shared between a process that
|
||||||
// allocates VlProcess, and one that doesnt,
|
// allocates VlProcess, and one that doesnt,
|
||||||
// - a function that has a delay and obtains VlProcess argument,
|
// - a function that has a delay and obtains VlProcess argument,
|
||||||
// - a function that has a delay and doesn't obtain it.
|
// - a function that has a delay and doesn't obtain it,
|
||||||
|
// - an empty fork with disable fork.
|
||||||
//
|
//
|
||||||
// Blocks below contain info on whether they should (YES) or shouldn't (NO)
|
// Blocks below contain info on whether they should (YES) or shouldn't (NO)
|
||||||
// be emitted as functions with a VlProcess argument.
|
// be emitted as functions with a VlProcess argument.
|
||||||
@ -38,6 +39,13 @@ class Cls;
|
|||||||
task delay_func; /*NO*/
|
task delay_func; /*NO*/
|
||||||
fork /*NO*/ #1 $write("Finished *-*\n"); join_none
|
fork /*NO*/ #1 $write("Finished *-*\n"); join_none
|
||||||
endtask
|
endtask
|
||||||
|
task empty_fork;
|
||||||
|
fork
|
||||||
|
begin
|
||||||
|
end
|
||||||
|
join_none
|
||||||
|
disable fork;
|
||||||
|
endtask
|
||||||
endclass
|
endclass
|
||||||
|
|
||||||
module t;
|
module t;
|
||||||
@ -47,6 +55,7 @@ module t;
|
|||||||
fork /*YES*/ cls.common_func(); join_none
|
fork /*YES*/ cls.common_func(); join_none
|
||||||
cls.fork_func();
|
cls.fork_func();
|
||||||
cls.disable_fork_func();
|
cls.disable_fork_func();
|
||||||
|
cls.empty_fork();
|
||||||
cls.print();
|
cls.print();
|
||||||
end
|
end
|
||||||
|
|
||||||
|
18
test_regress/t/t_disable_fork2_split.py
Executable file
18
test_regress/t/t_disable_fork2_split.py
Executable file
@ -0,0 +1,18 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# Copyright 2024 by Wilson Snyder. This program is free software; you
|
||||||
|
# can redistribute it and/or modify it under the terms of either the GNU
|
||||||
|
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
|
# Version 2.0.
|
||||||
|
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
|
||||||
|
import vltest_bootstrap
|
||||||
|
|
||||||
|
test.scenarios('simulator')
|
||||||
|
test.top_filename = "t_disable_fork2.v"
|
||||||
|
|
||||||
|
# Validate if splitted functions get vlProcess handle
|
||||||
|
test.compile(verilator_flags2=["--timing --output-split-cfuncs 1"])
|
||||||
|
|
||||||
|
test.passes()
|
106
test_regress/t/t_vlprocess_missing.py
Executable file
106
test_regress/t/t_vlprocess_missing.py
Executable file
@ -0,0 +1,106 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# Copyright 2024 by Wilson Snyder. This program is free software; you
|
||||||
|
# can redistribute it and/or modify it under the terms of either the GNU
|
||||||
|
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
|
# Version 2.0.
|
||||||
|
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
|
||||||
|
import vltest_bootstrap
|
||||||
|
|
||||||
|
test.scenarios('simulator')
|
||||||
|
test.top_filename = test.obj_dir + "/t_vlprocess_missing.v"
|
||||||
|
|
||||||
|
# Number of tests to generate
|
||||||
|
NUM_TESTS = 200
|
||||||
|
|
||||||
|
# Testbench header template
|
||||||
|
HEADER = """\
|
||||||
|
module Testbench;
|
||||||
|
|
||||||
|
logic clk;
|
||||||
|
logic reset;
|
||||||
|
|
||||||
|
// Clock driver
|
||||||
|
initial begin
|
||||||
|
clk = 0;
|
||||||
|
forever begin
|
||||||
|
#5 clk = ~clk;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
task automatic advance_clock(int n = 1);
|
||||||
|
repeat (n) @(posedge clk);
|
||||||
|
endtask
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Test task template
|
||||||
|
TEST_TASK_TEMPLATE = """
|
||||||
|
task automatic test_{num}();
|
||||||
|
int counter = 0;
|
||||||
|
int expected_value = {num};
|
||||||
|
|
||||||
|
// Timeout wait
|
||||||
|
fork
|
||||||
|
begin
|
||||||
|
advance_clock(10000);
|
||||||
|
$error("Timeout");
|
||||||
|
end
|
||||||
|
join_none
|
||||||
|
wait (counter == expected_value);
|
||||||
|
disable fork;
|
||||||
|
|
||||||
|
while (counter < expected_value) begin
|
||||||
|
advance_clock();
|
||||||
|
counter++;
|
||||||
|
end
|
||||||
|
endtask
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Testbench footer template
|
||||||
|
FOOTER = " initial begin"
|
||||||
|
|
||||||
|
# Call template for invoking each test task
|
||||||
|
CALL_TEMPLATE = " test_{num}();\n"
|
||||||
|
|
||||||
|
# Footer end
|
||||||
|
FOOTER_END = """
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def gen(filename, num_tests):
|
||||||
|
"""
|
||||||
|
Generates a SystemVerilog testbench with the specified number of tests.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
filename (str): The output file name for the generated testbench.
|
||||||
|
num_tests (int): The number of test tasks to generate.
|
||||||
|
"""
|
||||||
|
with open(filename, 'w', encoding="utf-8") as fh:
|
||||||
|
fh.write("// Generated by t_vlprocess_missing.py\n")
|
||||||
|
|
||||||
|
# Write the header
|
||||||
|
fh.write(HEADER)
|
||||||
|
|
||||||
|
# Generate the test tasks
|
||||||
|
for i in range(1, num_tests + 1):
|
||||||
|
fh.write(TEST_TASK_TEMPLATE.format(num=i))
|
||||||
|
|
||||||
|
# Write the initial block with test calls
|
||||||
|
fh.write(FOOTER)
|
||||||
|
for i in range(1, num_tests + 1):
|
||||||
|
fh.write(CALL_TEMPLATE.format(num=i))
|
||||||
|
fh.write(FOOTER_END)
|
||||||
|
|
||||||
|
|
||||||
|
gen(test.top_filename, NUM_TESTS)
|
||||||
|
|
||||||
|
test.compile(verilator_flags2=["--binary"])
|
||||||
|
|
||||||
|
test.passes()
|
Loading…
Reference in New Issue
Block a user