Skip to content

Commit

Permalink
Various fixes for Verilog module instantiation. Issue xxx
Browse files Browse the repository at this point in the history
  • Loading branch information
nickg committed Aug 24, 2024
1 parent 38e900d commit b5f5a04
Show file tree
Hide file tree
Showing 7 changed files with 120 additions and 32 deletions.
22 changes: 10 additions & 12 deletions src/elab.c
Original file line number Diff line number Diff line change
Expand Up @@ -667,7 +667,7 @@ static tree_t elab_verilog_binding(vlog_node_t inst, mod_cache_t *mc,

if (type_eq(dtype, ptype)) {
if (have_named)
abort();
add_param(bind, make_ref(decl), P_NAMED, make_ref(port));
else
add_param(bind, make_ref(decl), P_POS, NULL);
}
Expand Down Expand Up @@ -1427,13 +1427,9 @@ static void elab_lower(tree_t b, vcode_unit_t shape, elab_ctx_t *ctx)
diag_remove_hint_fn(elab_hint_fn);
}

static void elab_verilog_module(tree_t bind, tree_t wrap, const elab_ctx_t *ctx)
static void elab_verilog_module(tree_t bind, ident_t label, mod_cache_t *mc,
const elab_ctx_t *ctx)
{
vlog_node_t mod = tree_vlog(wrap);
mod_cache_t *mc = elab_cached_module(mod, ctx);

ident_t label = ident_rfrom(vlog_ident(mod), '.');

const char *label_str = istr(label);
ident_t ninst = hpathf(ctx->inst_name, ':', "%s", label_str);
ident_t ndotted = ident_prefix(ctx->dotted, label, '.');
Expand All @@ -1451,7 +1447,7 @@ static void elab_verilog_module(tree_t bind, tree_t wrap, const elab_ctx_t *ctx)
tree_add_stmt(ctx->out, b);
new_ctx.out = b;

elab_push_scope(wrap, &new_ctx);
elab_push_scope(mc->wrap, &new_ctx);

if (bind != NULL)
elab_ports(mc->block, bind, &new_ctx);
Expand Down Expand Up @@ -1667,8 +1663,10 @@ static void elab_component(tree_t inst, tree_t comp, const elab_ctx_t *ctx)

if (arch == NULL)
; // Unbound architecture
else if (tree_kind(arch) == T_VERILOG)
elab_verilog_module(bind, arch, &new_ctx);
else if (tree_kind(arch) == T_VERILOG) {
mod_cache_t *mc = elab_cached_module(tree_vlog(arch), ctx);
elab_verilog_module(bind, vlog_ident2(mc->module), mc, &new_ctx);
}
else if (error_count() == 0)
elab_architecture(bind, arch, config, &new_ctx);

Expand Down Expand Up @@ -2071,7 +2069,7 @@ static void elab_verilog_stmt(tree_t wrap, const elab_ctx_t *ctx)

tree_t bind = elab_verilog_binding(v, mc, ctx);
if (bind != NULL)
elab_verilog_module(bind, mc->wrap, ctx);
elab_verilog_module(bind, vlog_ident(v), mc, ctx);
}
break;
default:
Expand Down Expand Up @@ -2305,7 +2303,7 @@ tree_t elab(object_t *top, jit_t *jit, unit_registry_t *ur, cover_data_t *cover)
}
else {
mod_cache_t *mc = elab_cached_module(vlog, &ctx);
elab_verilog_module(NULL, mc->wrap, &ctx);
elab_verilog_module(NULL, vlog_ident2(mc->module), mc, &ctx);
}

const void *key;
Expand Down
32 changes: 16 additions & 16 deletions src/lower.c
Original file line number Diff line number Diff line change
Expand Up @@ -12164,14 +12164,9 @@ static void lower_direct_mapped_port(lower_unit_t *lu, driver_set_t *ds,
}

int hops = 0;
vcode_var_t var = VCODE_INVALID_VAR;
if (field != -1) var = lower_search_vcode_obj(port, lu, &hops);

if (var == VCODE_INVALID_VAR || hops > 0) {
vcode_type_t vtype = lower_signal_type(port_type);
var = emit_var(vtype, vtype, tree_ident(port), VAR_SIGNAL);
lower_put_vcode_obj(port, var, lu);
}
vcode_var_t var = lower_search_vcode_obj(port, lu, &hops);
assert(var != VCODE_INVALID_VAR);
assert(hops == 0);

type_t field_type = port_type;
if (field != -1) {
Expand Down Expand Up @@ -12242,17 +12237,12 @@ static void lower_direct_mapped_port(lower_unit_t *lu, driver_set_t *ds,
}

static void lower_port_signal(lower_unit_t *lu, tree_t port,
vcode_reg_t bounds_reg)
vcode_var_t var, vcode_reg_t bounds_reg)
{
type_t type = tree_type(port);
type_t value_type = type;

const port_mode_t mode = tree_subkind(port);

vcode_type_t vtype = lower_signal_type(type);
vcode_var_t var = emit_var(vtype, vtype, tree_ident(port), VAR_SIGNAL);
lower_put_vcode_obj(port, var, lu);

tree_t view = NULL;
vcode_reg_t init_reg = VCODE_INVALID_REG;
if (mode == PORT_RECORD_VIEW || mode == PORT_ARRAY_VIEW) {
Expand Down Expand Up @@ -12432,6 +12422,7 @@ static void lower_ports(lower_unit_t *lu, driver_set_t *ds, tree_t block)

hset_t *direct = hset_new(nports * 2), *poison = NULL;
vcode_reg_t *map_regs LOCAL = xmalloc_array(nparams, sizeof(vcode_reg_t));
vcode_var_t *port_vars LOCAL = xmalloc_array(nports, sizeof(vcode_var_t));

for (int i = 0; i < nparams; i++) {
tree_t p = tree_param(block, i);
Expand All @@ -12448,6 +12439,15 @@ static void lower_ports(lower_unit_t *lu, driver_set_t *ds, tree_t block)
map_regs[i] = lower_rvalue(lu, value);
}

for (int i = 0; i < nports; i++) {
tree_t port = tree_port(block, i);
type_t type = tree_type(port);

vcode_type_t vtype = lower_signal_type(type);
port_vars[i] = emit_var(vtype, vtype, tree_ident(port), VAR_SIGNAL);
lower_put_vcode_obj(port, port_vars[i], lu);
}

if (!opt_get_int(OPT_NO_COLLAPSE)) {
// Filter out "direct mapped" inputs which can be aliased to
// signals in the scope above
Expand All @@ -12467,9 +12467,9 @@ static void lower_ports(lower_unit_t *lu, driver_set_t *ds, tree_t block)
bounds_reg = lower_get_type_bounds(lu, type);

if (!hset_contains(direct, port))
lower_port_signal(lu, port, bounds_reg);
lower_port_signal(lu, port, port_vars[i], bounds_reg);
else if (poison != NULL && hset_contains(poison, port))
lower_port_signal(lu, port, bounds_reg);
lower_port_signal(lu, port, port_vars[i], bounds_reg);
else if (tree_class(port) == C_SIGNAL && tree_subkind(port) != PORT_IN) {
// Any drivers for collapsed output ports must take their
// initial value from the port declaration
Expand Down
2 changes: 2 additions & 0 deletions src/rt/wave.c
Original file line number Diff line number Diff line change
Expand Up @@ -821,6 +821,7 @@ static void fst_enter_scope(wave_dumper_t *wd, tree_t unit, rt_scope_t *scope,
case T_IF_GENERATE: st = FST_ST_VHDL_IF_GENERATE; break;
case T_PACKAGE: st = FST_ST_VHDL_PACKAGE; break;
case T_COMPONENT: st = FST_ST_VHDL_ARCHITECTURE; break;
case T_VERILOG: st = FST_ST_VCD_MODULE; break;
default:
st = FST_ST_VHDL_ARCHITECTURE;
warn_at(tree_loc(unit), "no FST scope type for %s",
Expand Down Expand Up @@ -915,6 +916,7 @@ static void fst_walk_design(wave_dumper_t *wd, tree_t block)
fst_walk_design(wd, s);
break;
case T_PROCESS:
case T_VERILOG:
break;
case T_PSL:
break; // TODO: consider emitting to FST
Expand Down
23 changes: 19 additions & 4 deletions src/vlog/vlog-lower.c
Original file line number Diff line number Diff line change
Expand Up @@ -1288,6 +1288,15 @@ static void vlog_lower_udp(unit_registry_t *ur, lower_unit_t *parent,
case '*':
cmp_reg = emit_event_flag(in_nets[j], one_reg);
break;
case 'b':
{
vcode_reg_t is0_reg =
emit_cmp(VCODE_CMP_EQ, in_regs[j], logic0_reg);
vcode_reg_t is1_reg =
emit_cmp(VCODE_CMP_EQ, in_regs[j], logic1_reg);
cmp_reg = emit_and(is0_reg, is1_reg);
}
break;
case '?':
break;
case '(':
Expand Down Expand Up @@ -1368,8 +1377,12 @@ static void vlog_lower_udp(unit_registry_t *ur, lower_unit_t *parent,

vcode_reg_t drive_reg;
switch (*sp) {
case '0': drive_reg = logic0_reg; break;
case '1': drive_reg = logic1_reg; break;
case '0':
case '1':
case 'x':
case 'X':
drive_reg = level_map[(int)*sp];
break;
case '-':
// No change, skip assignment to output
drive_reg = VCODE_INVALID_REG;
Expand Down Expand Up @@ -1398,8 +1411,10 @@ static void vlog_lower_udp(unit_registry_t *ur, lower_unit_t *parent,

vcode_select_block(wait_bb);

vcode_reg_t result_reg = emit_load(result_var);
vcode_reg_t drive_reg = vlog_lower_to_net_value(lu, result_reg);
vcode_reg_t result_reg = emit_load(result_var), drive_reg = result_reg;
if (kind == V_UDP_COMB)
drive_reg = vlog_lower_to_net_value(lu, result_reg);

vcode_reg_t out_reg = emit_load_indirect(emit_var_upref(hops, out_var));
emit_sched_waveform(out_reg, one_reg, drive_reg, zero_reg, zero_reg);

Expand Down
32 changes: 32 additions & 0 deletions test/lower/mixed2.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@

primitive UDP_MUX2 (Q, A, B, SL);
output Q;
input A, B, SL;
table
// A B SL : Q
0 0 ? : 0 ;
1 1 ? : 1 ;
0 ? 0 : 0 ;
1 ? 0 : 1 ;
? 0 1 : 0 ;
? 1 1 : 1 ;
x ? 0 : x ;
? x 1 : x ;
1 0 x : x ;
0 1 x : x ;
endtable
endprimitive

module SLE_Prim (output Q,
input ADn,
input ALn,
input CLK,
input D,
input LAT,
input SD,
input EN,
input SLn);

UDP_MUX2 mux_0(SYNC, SD, D, SLn);
UDP_MUX2 mux_1(DATA, Q, SYNC, EN);
endmodule
20 changes: 20 additions & 0 deletions test/lower/mixed2.vhd
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
library ieee;
use ieee.std_logic_1164.all;

entity polarfire_test is
end entity;

architecture test of polarfire_test is
component SLE_Prim is
port ( Q : out std_logic;
ADn, ALn, CLK, D, LAT, SD, EN, SLn : in std_logic );
end component;

signal Q : std_logic;
signal ADn, ALn, CLK, D, LAT, SD, EN, SLn : std_logic;
begin

u: component SLE_Prim
port map (Q, ADn, ALn, CLK, D, LAT, SD, EN, SLn);

end architecture;
21 changes: 21 additions & 0 deletions test/test_lower.c
Original file line number Diff line number Diff line change
Expand Up @@ -6287,6 +6287,26 @@ START_TEST(test_issue934)
}
END_TEST

START_TEST(test_mixed2)
{
analyse_file(TESTDIR "/lower/mixed2.v", NULL, NULL);

input_from_file(TESTDIR "/lower/mixed2.vhd");

run_elab();

vcode_unit_t vu = find_unit("WORK.POLARFIRE_TEST.U.SLE_Prim.mux_0");
vcode_select_unit(vu);

// Ports should be in declaration order
ck_assert_int_eq(vcode_count_vars(), 4);
fail_unless(vcode_var_name(0) == ident_new("Q"));
fail_unless(vcode_var_name(1) == ident_new("A"));
fail_unless(vcode_var_name(2) == ident_new("B"));
fail_unless(vcode_var_name(3) == ident_new("SL"));
}
END_TEST

Suite *get_lower_tests(void)
{
Suite *s = suite_create("lower");
Expand Down Expand Up @@ -6433,6 +6453,7 @@ Suite *get_lower_tests(void)
tcase_add_test(tc, test_trigger1);
tcase_add_test(tc, test_issue859);
tcase_add_test(tc, test_issue934);
tcase_add_test(tc, test_mixed2);
suite_add_tcase(s, tc);

return s;
Expand Down

0 comments on commit b5f5a04

Please sign in to comment.