Skip to content

Commit e8be7da

Browse files
committed
Lower Verilog UDPs to MIR directly
1 parent c6171bf commit e8be7da

27 files changed

+632
-343
lines changed

lib/nvc/verilog-body.vhd

+12
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,18 @@ package body verilog is
377377
end if;
378378
end function;
379379

380+
function "and" (l, r : t_logic_array) return t_logic is
381+
variable result : t_logic := '0';
382+
begin
383+
for i in l'range loop
384+
result := result and l(i);
385+
end loop;
386+
for i in r'range loop
387+
result := result and r(i);
388+
end loop;
389+
return result;
390+
end function;
391+
380392
function "and" (l, r : t_logic_array) return t_logic_array is
381393
constant llen : natural := l'length;
382394
constant rlen : natural := r'length;

lib/nvc/verilog.vhd

+1
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ package verilog is
7272
function resize (value : t_logic; length : natural) return t_logic_array;
7373

7474
function "and" (l, r : t_logic) return t_logic;
75+
function "and" (l, r : t_logic_array) return t_logic;
7576
function "and" (l, r : t_logic_array) return t_logic_array;
7677

7778
function "nand" (l, r : t_logic) return t_logic;

src/cgen.c

+17-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
#include "phase.h"
3131
#include "thread.h"
3232
#include "type.h"
33-
#include "vcode.h"
33+
#include "vlog/vlog-node.h"
3434

3535
#include <stdlib.h>
3636
#include <string.h>
@@ -110,6 +110,8 @@ static void cgen_find_dependencies(mir_context_t *mc, unit_registry_t *ur,
110110
ident_t link = mir_get_linkage(mu, i);
111111
if (hset_contains(seen, link))
112112
continue;
113+
else if (ident_char(link, 0) == '$')
114+
continue; // TODO: handle VPI differently
113115
else if (preload || !cgen_is_preload(link)) {
114116
APUSH(*units, link);
115117
hset_insert(seen, link);
@@ -126,6 +128,9 @@ static void cgen_walk_hier(unit_list_t *units, hset_t *seen, tree_t block,
126128
APUSH(*units, unit_name);
127129
hset_insert(seen, unit_name);
128130

131+
tree_t hier = tree_decl(block, 0);
132+
assert(tree_kind(hier) == T_HIER);
133+
129134
const int nstmts = tree_stmts(block);
130135
for (int i = 0; i < nstmts; i++) {
131136
tree_t s = tree_stmt(block, i);
@@ -141,6 +146,17 @@ static void cgen_walk_hier(unit_list_t *units, hset_t *seen, tree_t block,
141146
hset_insert(seen, proc_name);
142147
}
143148
break;
149+
case T_VERILOG:
150+
{
151+
vlog_node_t mod = tree_vlog(tree_ref(hier));
152+
ident_t name = tree_ident(s);
153+
ident_t suffix = well_known(W_SHAPE);
154+
ident_t shape = ident_prefix(vlog_ident(mod), suffix, '.');
155+
ident_t sym = ident_prefix(shape, name, '.');
156+
APUSH(*units, sym);
157+
hset_insert(seen, sym);
158+
}
159+
break;
144160
default:
145161
break;
146162
}

src/elab.c

+6-3
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ typedef struct _elab_ctx {
6464
hash_t *generics;
6565
jit_t *jit;
6666
unit_registry_t *registry;
67+
mir_context_t *mir;
6768
lower_unit_t *lowered;
6869
cover_data_t *cover;
6970
sdf_file_t *sdf;
@@ -264,7 +265,7 @@ static mod_cache_t *elab_cached_module(vlog_node_t mod, const elab_ctx_t *ctx)
264265
if (mc == NULL) {
265266
mc = xcalloc(sizeof(mod_cache_t));
266267
mc->module = mod;
267-
mc->shape = vlog_lower(ctx->registry, mod);
268+
mc->shape = vlog_lower(ctx->registry, ctx->mir, mod);
268269

269270
mc->block = tree_new(T_BLOCK);
270271
tree_set_loc(mc->block, vlog_loc(mod));
@@ -1315,6 +1316,7 @@ static void elab_inherit_context(elab_ctx_t *ctx, const elab_ctx_t *parent)
13151316
ctx->parent = parent;
13161317
ctx->jit = parent->jit;
13171318
ctx->registry = parent->registry;
1319+
ctx->mir = parent->mir;
13181320
ctx->root = parent->root;
13191321
ctx->dotted = ctx->dotted ?: parent->dotted;
13201322
ctx->inst_name = ctx->inst_name ?: parent->inst_name;
@@ -2218,8 +2220,8 @@ static void elab_verilog_root_cb(void *arg)
22182220
elab_verilog_module(NULL, vlog_ident2(mc->module), mc, ctx);
22192221
}
22202222

2221-
tree_t elab(object_t *top, jit_t *jit, unit_registry_t *ur, cover_data_t *cover,
2222-
sdf_file_t *sdf, rt_model_t *m)
2223+
tree_t elab(object_t *top, jit_t *jit, unit_registry_t *ur, mir_context_t *mc,
2224+
cover_data_t *cover, sdf_file_t *sdf, rt_model_t *m)
22232225
{
22242226
make_new_arena();
22252227

@@ -2251,6 +2253,7 @@ tree_t elab(object_t *top, jit_t *jit, unit_registry_t *ur, cover_data_t *cover,
22512253
.jit = jit,
22522254
.sdf = sdf,
22532255
.registry = ur,
2256+
.mir = mc,
22542257
.modcache = hash_new(16),
22552258
.dotted = lib_name(work),
22562259
.model = m,

src/jit/jit-core.c

+10-17
Original file line numberDiff line numberDiff line change
@@ -421,30 +421,23 @@ void jit_fill_irbuf(jit_func_t *f)
421421
if (f->jit->pack != NULL && jit_pack_fill(f->jit->pack, f->jit, f))
422422
goto done;
423423

424-
vcode_unit_t unit = NULL;
425-
if (f->jit->registry != NULL) {
426-
// Unit registry is not thread-safe
427-
SCOPED_LOCK(f->jit->lock);
428-
unit = unit_registry_get(f->jit->registry, f->name);
429-
}
430-
431-
if (unit == NULL) {
432-
store_release(&(f->state), JIT_FUNC_ERROR);
433-
jit_missing_unit(f);
434-
}
424+
mir_unit_t *mu = mir_get_unit(f->jit->mir, f->name);
435425

436-
mir_unit_t *mu;
437-
{
438-
// MIR import is not thread-safe
426+
if (mu == NULL && f->jit->registry != NULL) {
427+
// Unit registry and MIR import is not thread-safe
439428
SCOPED_LOCK(f->jit->lock);
440-
441-
mu = mir_get_unit(f->jit->mir, f->name);
442-
if (mu == NULL) {
429+
vcode_unit_t unit = unit_registry_get(f->jit->registry, f->name);
430+
if (unit != NULL) {
443431
mu = mir_import(f->jit->mir, unit);
444432
mir_put_unit(f->jit->mir, mu);
445433
}
446434
}
447435

436+
if (mu == NULL) {
437+
store_release(&(f->state), JIT_FUNC_ERROR);
438+
jit_missing_unit(f);
439+
}
440+
448441
jit_irgen(f, mu);
449442

450443
done:

src/jit/jit-irgen.c

+2
Original file line numberDiff line numberDiff line change
@@ -4047,6 +4047,8 @@ static void irgen_block(jit_irgen_t *g, mir_block_t block)
40474047
fatal_trace("cannot generate JIT IR for MIR op %s", mir_op_string(op));
40484048
}
40494049
}
4050+
4051+
DEBUG_ONLY(if (nops == 0) j_trap(g));
40504052
}
40514053

40524054
static void irgen_locals(jit_irgen_t *g)

src/mir/mir-dump.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -627,7 +627,8 @@ void mir_annotate(mir_unit_t *mu, const mir_annotate_t *cb, void *ctx)
627627
color_printf(" $magenta$%s$$\n", istr(mu->linkage.items[i]));
628628
}
629629

630-
printf("Begin\n");
630+
if (mu->blocks.count > 0)
631+
printf("Begin\n");
631632

632633
for (int i = 0; i < mu->blocks.count; i++) {
633634
const block_data_t *b = &(mu->blocks.items[i]);

src/mir/mir-node.c

+15
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ block_data_t *mir_block_data(mir_unit_t *mu, mir_block_t block)
3939

4040
mir_block_t mir_add_block(mir_unit_t *mu)
4141
{
42+
assert(mu->kind != MIR_UNIT_PLACEHOLDER);
43+
4244
mir_block_t b = { .tag = MIR_TAG_BLOCK, .id = mu->blocks.count };
4345

4446
block_data_t bd = {
@@ -239,12 +241,24 @@ bool mir_is_terminator(mir_op_t op)
239241
case MIR_OP_JUMP:
240242
case MIR_OP_COND:
241243
case MIR_OP_WAIT:
244+
case MIR_OP_CASE:
245+
case MIR_OP_PCALL:
246+
case MIR_OP_UNREACHABLE:
242247
return true;
243248
default:
244249
return false;
245250
}
246251
}
247252

253+
bool mir_block_finished(mir_unit_t *mu, mir_block_t block)
254+
{
255+
const block_data_t *bd = mir_block_data(mu, block);
256+
if (bd->num_nodes == 0)
257+
return false;
258+
259+
return mir_is_terminator(mu->nodes[bd->nodes[bd->num_nodes - 1]].op);
260+
}
261+
248262
static inline node_id_t mir_node_id(mir_unit_t *mu, node_data_t *n)
249263
{
250264
assert(n >= mu->nodes && n < mu->nodes + mu->num_nodes);
@@ -254,6 +268,7 @@ static inline node_id_t mir_node_id(mir_unit_t *mu, node_data_t *n)
254268
static node_data_t *mir_alloc_node(mir_unit_t *mu)
255269
{
256270
assert(!mir_is_null(mu->cursor.block));
271+
assert(mu->kind != MIR_UNIT_PLACEHOLDER);
257272

258273
node_data_t *n;
259274
block_data_t *bd = mir_block_data(mu, mu->cursor.block);

src/mir/mir-node.h

+1
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,7 @@ mir_var_flags_t mir_get_var_flags(mir_unit_t *mu, mir_value_t value);
379379
mir_type_t mir_get_var_type(mir_unit_t *mu, mir_value_t value);
380380
void mir_set_input(mir_unit_t *mu, mir_value_t phi, unsigned nth,
381381
mir_block_t block, mir_value_t value);
382+
bool mir_block_finished(mir_unit_t *mu, mir_block_t block);
382383

383384
void mir_set_result(mir_unit_t *mu, mir_type_t type);
384385
mir_type_t mir_get_result(mir_unit_t *mu);

src/mir/mir-priv.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ bool mir_stamp_const(mir_unit_t *mu, mir_stamp_t stamp, int64_t *cval);
7070
bool mir_is_terminator(mir_op_t op);
7171

7272
void mir_free_types(type_tab_t *tab);
73-
void *mir_malloc(mir_context_t *mc, size_t fixed, size_t nelems, size_t size);
73+
void *mir_global_malloc(mir_context_t *mc, size_t fixed, size_t nelems,
74+
size_t size);
7475

7576
#endif // _MIR_PRIV_H

src/mir/mir-structs.h

+5-1
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,8 @@ typedef struct _mir_unit {
206206
mir_unit_kind_t kind;
207207
mir_shape_t *parent;
208208
mir_shape_t *shape;
209+
mem_pool_t *pool;
210+
hash_t *objmap;
209211
mir_type_t result;
210212
known_types_t types;
211213
mir_cursor_t cursor;
@@ -267,14 +269,16 @@ typedef struct {
267269
typedef struct _mir_shape {
268270
ident_t name;
269271
mir_shape_t *parent;
272+
hash_t *objmap;
270273
mir_type_t type;
271274
mir_unit_kind_t kind;
272275
unsigned num_slots;
273276
shape_slot_t slots[];
274277
} mir_shape_t;
275278

276279
typedef struct {
277-
mir_shape_t *parent;
280+
ident_t name;
281+
ident_t parent;
278282
mir_lower_fn_t fn;
279283
object_t *object;
280284
mir_unit_kind_t kind;

src/mir/mir-type.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -252,8 +252,8 @@ static void mir_install_type(mir_unit_t *mu, type_data_t *dst,
252252

253253
dst_r->name = src_r->name;
254254
dst_r->count = src_r->count;
255-
dst_r->fields = mir_malloc(mu->context, 0, src_r->count * 2,
256-
sizeof(mir_type_t));
255+
dst_r->fields = mir_global_malloc(mu->context, 0, src_r->count * 2,
256+
sizeof(mir_type_t));
257257

258258
for (int i = 0; i < src_r->count; i++) {
259259
mir_type_t pointer = mir_get_var_pointer(mu, src_r->fields[i]);

0 commit comments

Comments
 (0)