From 12b95498d124ea6cfdf49d516d7dca8d3cacc6a5 Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Wed, 25 Oct 2023 21:02:13 +0100 Subject: [PATCH] Add conversion functions for Verilog/VHDL interface boundary --- lib/nvc.08/deps.mk | 4 ++-- lib/nvc.19/deps.mk | 4 ++-- lib/nvc/deps.mk | 4 ++-- lib/nvc/verilog-body.vhd | 26 ++++++++++++++++++++++--- lib/nvc/verilog.vhd | 11 +++++++++-- src/vcode.c | 2 +- src/vlog/vlog-lower.c | 41 +++++++++++++++++++++++++-------------- test/regress/mixed1.v | 6 ++++++ test/regress/mixed1.vhd | 40 ++++++++++++++++++++++++++++++++++++++ test/regress/testlist.txt | 1 + 10 files changed, 112 insertions(+), 27 deletions(-) create mode 100644 test/regress/mixed1.v create mode 100644 test/regress/mixed1.vhd diff --git a/lib/nvc.08/deps.mk b/lib/nvc.08/deps.mk index af7c8098..3ab0e637 100644 --- a/lib/nvc.08/deps.mk +++ b/lib/nvc.08/deps.mk @@ -16,7 +16,7 @@ lib/nvc.08/NVC.TEXT_UTIL-body: lib/std.08/STD.STANDARD lib/nvc.08/NVC.TEXT_UTIL lib/nvc.08/NVC.TEXT_UTIL: lib/std.08/STD.STANDARD $(top_srcdir)/lib/nvc/text_util.vhd -lib/nvc.08/NVC.VERILOG-body: lib/std.08/STD.STANDARD lib/nvc.08/NVC.VERILOG $(top_srcdir)/lib/nvc/verilog-body.vhd +lib/nvc.08/NVC.VERILOG-body: lib/std.08/STD.STANDARD lib/nvc.08/NVC.VERILOG lib/nvc.08/NVC.POLYFILL lib/ieee.08/IEEE.STD_LOGIC_1164 $(top_srcdir)/lib/nvc/verilog-body.vhd -lib/nvc.08/NVC.VERILOG: lib/std.08/STD.STANDARD $(top_srcdir)/lib/nvc/verilog.vhd +lib/nvc.08/NVC.VERILOG: lib/std.08/STD.STANDARD lib/ieee.08/IEEE.STD_LOGIC_1164 $(top_srcdir)/lib/nvc/verilog.vhd diff --git a/lib/nvc.19/deps.mk b/lib/nvc.19/deps.mk index 42d732ad..28fc85c1 100644 --- a/lib/nvc.19/deps.mk +++ b/lib/nvc.19/deps.mk @@ -16,7 +16,7 @@ lib/nvc.19/NVC.TEXT_UTIL-body: lib/std.19/STD.STANDARD lib/nvc.19/NVC.TEXT_UTIL lib/nvc.19/NVC.TEXT_UTIL: lib/std.19/STD.STANDARD $(top_srcdir)/lib/nvc/text_util.vhd -lib/nvc.19/NVC.VERILOG-body: lib/std.19/STD.STANDARD lib/nvc.19/NVC.VERILOG $(top_srcdir)/lib/nvc/verilog-body.vhd +lib/nvc.19/NVC.VERILOG-body: lib/std.19/STD.STANDARD lib/nvc.19/NVC.VERILOG lib/nvc.19/NVC.POLYFILL lib/ieee.19/IEEE.STD_LOGIC_1164 $(top_srcdir)/lib/nvc/verilog-body.vhd -lib/nvc.19/NVC.VERILOG: lib/std.19/STD.STANDARD $(top_srcdir)/lib/nvc/verilog.vhd +lib/nvc.19/NVC.VERILOG: lib/std.19/STD.STANDARD lib/ieee.19/IEEE.STD_LOGIC_1164 $(top_srcdir)/lib/nvc/verilog.vhd diff --git a/lib/nvc/deps.mk b/lib/nvc/deps.mk index f4b4dc1e..8f34a95f 100644 --- a/lib/nvc/deps.mk +++ b/lib/nvc/deps.mk @@ -14,7 +14,7 @@ lib/nvc/NVC.TEXT_UTIL-body: lib/std/STD.STANDARD lib/nvc/NVC.TEXT_UTIL lib/nvc/N lib/nvc/NVC.TEXT_UTIL: lib/std/STD.STANDARD $(top_srcdir)/lib/nvc/text_util.vhd -lib/nvc/NVC.VERILOG-body: lib/std/STD.STANDARD lib/nvc/NVC.VERILOG $(top_srcdir)/lib/nvc/verilog-body.vhd +lib/nvc/NVC.VERILOG-body: lib/std/STD.STANDARD lib/nvc/NVC.VERILOG lib/nvc/NVC.POLYFILL lib/ieee/IEEE.STD_LOGIC_1164 $(top_srcdir)/lib/nvc/verilog-body.vhd -lib/nvc/NVC.VERILOG: lib/std/STD.STANDARD $(top_srcdir)/lib/nvc/verilog.vhd +lib/nvc/NVC.VERILOG: lib/std/STD.STANDARD lib/ieee/IEEE.STD_LOGIC_1164 $(top_srcdir)/lib/nvc/verilog.vhd diff --git a/lib/nvc/verilog-body.vhd b/lib/nvc/verilog-body.vhd index 337664cc..914d28b9 100644 --- a/lib/nvc/verilog-body.vhd +++ b/lib/nvc/verilog-body.vhd @@ -46,7 +46,27 @@ package body verilog is return r; end function; - function "&" (l, r : t_logic) return t_logic is + function to_vhdl (value : t_logic) return std_ulogic is + begin + case value is + when '1' => return '1'; + when '0' => return '0'; + when 'Z' => return 'Z'; + when others => return 'U'; + end case; + end function; + + function to_verilog (value : std_ulogic) return t_logic is + begin + case value is + when '1' | 'H' => return '1'; + when '0' | 'L' => return '0'; + when 'Z' => return 'Z'; + when others => return 'X'; + end case; + end function; + + function "and" (l, r : t_logic) return t_logic is begin if l = '1' and r = '1' then return '1'; @@ -57,7 +77,7 @@ package body verilog is end if; end function; - function "&" (l, r : t_packed_logic) return t_packed_logic is + function "and" (l, r : t_packed_logic) return t_packed_logic is constant llen : natural := l'length; constant rlen : natural := r'length; constant len : natural := maximum(llen, rlen); @@ -67,7 +87,7 @@ package body verilog is begin for i in result'range loop if i < llen and i < rlen then - result(i) := la(i) & ra(i); + result(i) := la(i) and ra(i); else result(i) := '0'; end if; diff --git a/lib/nvc/verilog.vhd b/lib/nvc/verilog.vhd index 5ca44106..b24f5a81 100644 --- a/lib/nvc/verilog.vhd +++ b/lib/nvc/verilog.vhd @@ -18,6 +18,9 @@ -- This package provides support routines for Verilog simulation ------------------------------------------------------------------------------- +library ieee; +use ieee.std_logic_1164.all; + package verilog is type t_int64 is range -9223372036854775807 - 1 to 9223372036854775807; @@ -30,7 +33,11 @@ package verilog is function to_time (value : t_packed_logic) return delay_length; - function "&" (l, r : t_logic) return t_logic; - function "&" (l, r : t_packed_logic) return t_packed_logic; + function to_vhdl (value : t_logic) return std_ulogic; + + function to_verilog (value : std_ulogic) return t_logic; + + function "and" (l, r : t_logic) return t_logic; + function "and" (l, r : t_packed_logic) return t_packed_logic; end package; diff --git a/src/vcode.c b/src/vcode.c index 26ac93ed..b136cf39 100644 --- a/src/vcode.c +++ b/src/vcode.c @@ -953,7 +953,7 @@ const char *vcode_op_string(vcode_op_t op) "memset", "case", "endfile", "file open", "file write", "file close", "file read", "null", "new", "null check", "deallocate", "all", "const real", "last event", "debug out", "cover stmt", "cover branch", - "cover toggle", "cover expr", "uarray len", "undefined", + "cover toggle", "cover expr", "cover state", "uarray len", "undefined", "range null", "var upref", "resolved", "last value", "init signal", "map signal", "drive signal", "link var", "resolution wrapper", "last active", "driving", "driving value", "address of", "closure", diff --git a/src/vlog/vlog-lower.c b/src/vlog/vlog-lower.c index b99e2847..d0c91f82 100644 --- a/src/vlog/vlog-lower.c +++ b/src/vlog/vlog-lower.c @@ -39,6 +39,10 @@ const loc_t _old_loc = *vcode_last_loc(); \ emit_debug_info(vlog_loc((v))); \ +#define T_LOGIC "19NVC.VERILOG.T_LOGIC" +#define T_PACKED_LOGIC "26NVC.VERILOG.T_PACKED_LOGIC" +#define T_INT64 "19NVC.VERILOG.T_INT64" + static void vlog_lower_stmts(lower_unit_t *lu, vlog_node_t v); static vcode_reg_t vlog_lower_rvalue(lower_unit_t *lu, vlog_node_t v); @@ -104,7 +108,7 @@ static vcode_reg_t vlog_lower_to_time(lower_unit_t *lu, vcode_reg_t reg) vcode_reg_t wrap_reg = vlog_lower_wrap(lu, reg); vcode_reg_t args[] = { context_reg, wrap_reg }; vcode_type_t vtime = vtype_time(); - ident_t func = ident_new("NVC.VERILOG.TO_TIME(26NVC.VERILOG.T_PACKED_LOGIC)" + ident_t func = ident_new("NVC.VERILOG.TO_TIME(" T_PACKED_LOGIC ")" "25STD.STANDARD.DELAY_LENGTH"); return emit_fcall(func, vtime, vtime, VCODE_CC_VHDL, args, ARRAY_LEN(args)); } @@ -115,9 +119,8 @@ static vcode_reg_t vlog_lower_to_integer(lower_unit_t *lu, vcode_reg_t reg) vcode_reg_t wrap_reg = vlog_lower_wrap(lu, reg); vcode_reg_t args[] = { context_reg, wrap_reg }; vcode_type_t vint64 = vtype_int(INT64_MIN, INT64_MAX); - ident_t func = ident_new("NVC.VERILOG.TO_INTEGER" - "(26NVC.VERILOG.T_PACKED_LOGIC)" - "19NVC.VERILOG.T_INT64"); + ident_t func = ident_new("NVC.VERILOG.TO_INTEGER(" + T_PACKED_LOGIC ")" T_INT64); return emit_fcall(func, vint64, vint64, VCODE_CC_VHDL, args, ARRAY_LEN(args)); } @@ -214,6 +217,19 @@ static void vlog_lower_port_map(lower_unit_t *lu, vlog_node_t root, tree_t wrap) { const int nparams = tree_params(wrap); + ident_t to_vhdl_name = ident_new("NVC.VERILOG.TO_VHDL(" T_LOGIC ")U"); + ident_t to_verilog_name = ident_new("NVC.VERILOG.TO_VERILOG(U)" T_LOGIC); + + vcode_reg_t context_reg = emit_link_package(ident_new("NVC.VERILOG")); + + vcode_type_t vt_verilog = vlog_logic_type(); + vcode_type_t vt_vhdl = vtype_int(0, 8); + + vcode_reg_t to_vhdl = + emit_closure(to_vhdl_name, context_reg, vt_verilog, vt_vhdl); + vcode_reg_t to_verilog = + emit_closure(to_verilog_name, context_reg, vt_vhdl, vt_verilog); + for (int i = 0, pos = 0; i < nparams; i++) { tree_t map = tree_param(wrap, i); assert(tree_subkind(map) == P_POS); @@ -232,14 +248,10 @@ static void vlog_lower_port_map(lower_unit_t *lu, vlog_node_t root, tree_t wrap) vcode_reg_t count_reg = emit_const(vtype_offset(), 1); - if (vlog_subkind(port) == V_PORT_INPUT) { - vcode_reg_t conv_reg = VCODE_INVALID_REG; // TODO - emit_map_signal(vhdl_reg, vlog_reg, count_reg, count_reg, conv_reg); - } - else { - vcode_reg_t conv_reg = VCODE_INVALID_REG; // TODO - emit_map_signal(vlog_reg, vhdl_reg, count_reg, count_reg, conv_reg); - } + if (vlog_subkind(port) == V_PORT_INPUT) + emit_map_signal(vhdl_reg, vlog_reg, count_reg, count_reg, to_verilog); + else + emit_map_signal(vlog_reg, vhdl_reg, count_reg, count_reg, to_vhdl); } } @@ -354,9 +366,8 @@ static vcode_reg_t vlog_lower_rvalue(lower_unit_t *lu, vlog_node_t v) vcode_reg_t left_reg = vlog_lower_rvalue(lu, vlog_left(v)); vcode_reg_t right_reg = vlog_lower_rvalue(lu, vlog_right(v)); - ident_t func = ident_new( - "NVC.VERILOG.\"&\"(26NVC.VERILOG.T_PACKED_LOGIC" - "26NVC.VERILOG.T_PACKED_LOGIC)26NVC.VERILOG.T_PACKED_LOGIC"); + ident_t func = ident_new("NVC.VERILOG.\"and\"(" T_PACKED_LOGIC + T_PACKED_LOGIC ")" T_PACKED_LOGIC); vcode_reg_t context_reg = emit_link_package(ident_new("NVC.VERILOG")); diff --git a/test/regress/mixed1.v b/test/regress/mixed1.v new file mode 100644 index 00000000..49e616d7 --- /dev/null +++ b/test/regress/mixed1.v @@ -0,0 +1,6 @@ +`timescale 1ps/1ps +module clkbuf (input i, output o); + + assign o = i; + +endmodule // clkmux diff --git a/test/regress/mixed1.vhd b/test/regress/mixed1.vhd new file mode 100644 index 00000000..d5c9697c --- /dev/null +++ b/test/regress/mixed1.vhd @@ -0,0 +1,40 @@ +entity mixed1 is +end entity; + +library ieee; +use ieee.std_logic_1164.all; + +architecture test of mixed1 is + component clkbuf is + port ( i : in std_logic; + o : out std_logic ); + end component; + + signal i, o : std_logic; +begin + + u: component clkbuf + port map (i, o); + + test: process is + begin + assert o = 'U'; + i <= '1'; + wait for 1 ns; + assert o = '1'; + i <= 'H'; + wait for 1 ns; + assert o = '1'; + i <= 'L'; + wait for 1 ns; + assert o = '0'; + i <= 'Z'; + wait for 1 ns; + assert o = 'Z'; + i <= '-'; + wait for 1 ns; + assert o = 'U'; + wait; + end process; + +end architecture; diff --git a/test/regress/testlist.txt b/test/regress/testlist.txt index 5edfbc33..b0e1937e 100644 --- a/test/regress/testlist.txt +++ b/test/regress/testlist.txt @@ -891,3 +891,4 @@ cover18 cover,shell cover19 cover,shell gentype6 normal,2008 signal34 fail,gold,2008 +mixed1 mixed -- 2.39.2