Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix dependency for vhdl instances inside (Sysytem) verilog modules #979

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions examples/mixed/uart/run.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#!/usr/bin/env python3

# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
# You can obtain one at http://mozilla.org/MPL/2.0/.
#
# Copyright (c) 2014-2023, Lars Asplund lars.anders.asplund@gmail.com

"""
SystemVerilog UART
------------------

A more realistic test bench of an UART to show VUnit SystemVerilog
usage on a typical module.
"""

from pathlib import Path
from vunit import VUnit

SRC_PATH = Path(__file__).parent / "src"
VHDL_SRC_PATH = Path(__file__).parent / "../../vhdl/uart/src"
VU = VUnit.from_argv()
VU.add_verilog_builtins()
VU.add_vhdl_builtins()

uart_lib = VU.add_library("uart_lib")
uart_lib.add_source_files(SRC_PATH / "*.sv")
uart_lib.add_source_files(VHDL_SRC_PATH / "*.vhd")

VU.add_library("tb_uart_lib").add_source_files(SRC_PATH / "test" / "*.sv")

VU.set_sim_option("modelsim.vsim_flags", ["-suppress", "3839"])

VU.main()
39 changes: 39 additions & 0 deletions examples/mixed/uart/src/axis_intf.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Copyright (c) 2014-2023, Lars Asplund lars.anders.asplund@gmail.com

`include "vunit_defines.svh"

interface axis_intf #(parameter int DW=8) (input logic clk);

logic tready;
logic tvalid;
logic [DW-1:0] tdata;

modport master (input tready, output tvalid, tdata);
modport slave (output tready, input tvalid, tdata);

task automatic send(int word);
tvalid <= 1'b1;
tdata <= word;
//words.push_back(word);
@(posedge clk iff tvalid == 1'b1 && tready == 1'b1);
$info($sformatf("AXIs: Sent word x%0h", word));
tvalid <= 1'b0;
endtask // send

task automatic check (int word);
tready <= 1'b1;
do
@(posedge clk);
while (tvalid !=1);
`CHECK_EQUAL(tdata, word);
tready <= 1'b0;
@(posedge clk);
`CHECK_EQUAL(tvalid, 1'b0);
endtask // receive

endinterface // axis_intf

46 changes: 46 additions & 0 deletions examples/mixed/uart/src/bit_intf.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Copyright (c) 2014-2023, Lars Asplund lars.anders.asplund@gmail.com

`include "vunit_defines.svh"

interface bit_intf (input clk);

logic rx_tx;

modport master (output rx_tx);
modport slave (input rx_tx);

task automatic uart_send(input integer data, baud_rate);
integer time_per_bit;
time_per_bit = (10**9 / baud_rate);
rx_tx = 1'b0;
#(time_per_bit * 1ns);

for (int i=0; i<8; i++) begin
rx_tx = data[i];
#(time_per_bit * 1ns);
end

rx_tx = 1'b1;
#(time_per_bit * 1ns);
endtask // uart_send

task automatic check(output integer data, input int time_per_bit);
data = 0;
wait(rx_tx == 1'b0);
#(time_per_bit/2 * 1ns);
`CHECK_EQUAL(rx_tx, 1'b0, "Expected low rx_tx");
#(time_per_bit * 1ns);
for (int i=0; i<8; i++) begin
data[i] = rx_tx;
#(time_per_bit * 1ns);
end
`CHECK_EQUAL(rx_tx, 1'b1, "Expected high rx_tx");
#(time_per_bit / 2 * 1ns);
endtask


endinterface // bit_intf
103 changes: 103 additions & 0 deletions examples/mixed/uart/src/test/tb_uart_mix.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Copyright (c) 2014-2023, Lars Asplund lars.anders.asplund@gmail.com

`include "vunit_defines.svh"

module tb_uart_mix;

localparam integer baud_rate = 115200; // bits / s
localparam integer clk_period = 20; // ns
localparam integer cycles_per_bit = 50 * 10**6 / baud_rate;
localparam time_per_bit = (10**9 / baud_rate);
localparam time_per_half_bit = time_per_bit/2;
logic clk = 1'b0;

axis_intf #(.DW(8)) m_axis (clk);
axis_intf s_axis (clk);

bit_intf bit_if(clk);

logic overflow;

int uart_data;

int num_overflows = 0;

`TEST_SUITE begin
`TEST_CASE("test_tvalid_low_at_start") begin
fork : tvalid_low_check
begin
wait (s_axis.tvalid == 1'b1);
$error("tvalid should not be high unless data received");
disable tvalid_low_check;
end
begin
#100ns;
disable tvalid_low_check;
end
join
end

`TEST_CASE("test_send_receive_one_byte") begin
fork
m_axis.send(8'h77);
s_axis.check(8'h77);
bit_if.check(uart_data, time_per_bit);
join
`CHECK_EQUAL(num_overflows, 0)
end

`TEST_CASE("test_two_bytes_cause_overflow") begin
fork
m_axis.send(8'h77);
bit_if.check(uart_data, time_per_bit);
join
`CHECK_EQUAL(uart_data, 8'h77)
@(posedge clk iff s_axis.tvalid == 1'b1);
`CHECK_EQUAL(num_overflows, 0)
fork
m_axis.send(8'h77);
bit_if.check(uart_data, time_per_bit);
join
`CHECK_EQUAL(uart_data, 8'h77)
`CHECK_EQUAL(num_overflows, 1);
end
end

`WATCHDOG(10ms);

initial begin
m_axis.tvalid = 0;
s_axis.tready = 0;
end

always @(posedge clk iff overflow == 1'b1) begin
num_overflows <= num_overflows + 1;
end

always begin
#(clk_period/2 * 1ns);
clk <= !clk;
end

uart_tx #(.cycles_per_bit(cycles_per_bit))
dut_tx
(.clk (clk),
.tx (bit_if.rx_tx),
.tready (m_axis.tready),
.tvalid (m_axis.tvalid),
.tdata (m_axis.tdata));

uart_rx #(.cycles_per_bit(cycles_per_bit))
dut_rx
(.clk (clk),
.rx (bit_if.rx_tx),
.overflow (overflow),
.tready (s_axis.tready),
.tvalid (s_axis.tvalid),
.tdata (s_axis.tdata));

endmodule // tb_uart_mix
4 changes: 4 additions & 0 deletions tests/acceptance/test_external_run_scripts.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ def test_verilog_user_guide_example_project(self):
def test_verilog_uart_example_project(self):
self.check(ROOT / "examples/verilog/uart/run.py")

@mark.skipif(not simulator_supports_verilog(), reason="Requires a Verilog simulator")
def test_mixed_uart_example_project(self):
self.check(ROOT / "examples/mixed/uart/run.py")

@mark.skipif(not simulator_supports_verilog(), reason="Requires a Verilog simulator")
@mark.xfail(reason="Requires AMS")
def test_verilog_ams_example(self):
Expand Down
8 changes: 5 additions & 3 deletions vunit/parsing/verilog/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,12 @@
COLON,
COMMENT,
END,
ENDINTERFACE,
ENDMODULE,
DOUBLE_COLON,
HASH,
IDENTIFIER,
INTERFACE,
IMPORT,
MODULE,
MULTI_COMMENT,
Expand Down Expand Up @@ -288,7 +290,7 @@ def _parse_block_label(stream):

class VerilogModule(object):
"""
A verilog module
A verilog module (or interface)
"""

def __init__(self, name, parameters):
Expand Down Expand Up @@ -319,13 +321,13 @@ def find(cls, tokens):
results = []
parameters = []
while idx < len(tokens):
if tokens[idx].kind == MODULE:
if tokens[idx].kind in (INTERFACE, MODULE):
if balance == 0:
name = tokens[idx + 1].value
parameters = []
balance += 1

elif tokens[idx].kind == ENDMODULE:
elif tokens[idx].kind in (ENDINTERFACE, ENDMODULE):
balance -= 1
if balance == 0:
results.append(cls(name, parameters))
Expand Down
9 changes: 7 additions & 2 deletions vunit/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@ def _find_verilog_package_dependencies(self, source_file):

def _find_verilog_module_dependencies(self, source_file):
"""
Find dependencies from instantiation of verilog modules
Find dependencies from instantiation of verilog modules or vhdl entities
"""
for module_name in source_file.module_dependencies:
if module_name in source_file.library.modules:
Expand All @@ -370,7 +370,12 @@ def _find_verilog_module_dependencies(self, source_file):
design_unit = library.modules[module_name]
yield design_unit.source_file
except KeyError:
pass
try:
# VHDL?
design_unit = library.primary_design_units[module_name]
yield design_unit.source_file
except KeyError:
pass

@staticmethod
def _find_component_design_unit_dependencies(source_file):
Expand Down