Skip to content
Browse files

Move all signal initialisation to a single `reset' function

  • Loading branch information...
1 parent 76e6f22 commit 9c97c722b630efa84c82d529984793891e349575 @nickg committed Jun 16, 2012
Showing with 52 additions and 60 deletions.
  1. +41 −55 src/cgen.c
  2. +10 −4 src/rt/rtkern.c
  3. +1 −1 test/regress/signal8.vhd
View
96 src/cgen.c
@@ -2197,57 +2197,6 @@ static void cgen_jump_table_fn(tree_t t, void *arg)
}
}
-static void cgen_driver_init_fn(tree_t t, void *arg)
-{
- assert(tree_kind(t) == T_SIGNAL_ASSIGN);
-
- cgen_ctx_t ctx = arg;
-
- tree_t target = tree_target(t);
- tree_kind_t kind;
- while ((kind = tree_kind(target)) != T_REF) {
- assert((kind == T_ARRAY_REF) || (kind == T_ARRAY_SLICE));
- target = tree_value(target);
- }
-
- tree_t decl = tree_ref(target);
- assert(tree_kind(decl) == T_SIGNAL_DECL);
-
- ident_t tag_i = ident_new("driver_tag");
- if (tree_attr_ptr(decl, tag_i) == ctx->proc)
- return; // Already initialised this signal
-
- assert(tree_has_value(decl));
- LLVMValueRef val = cgen_expr(tree_value(decl), ctx);
-
- type_t type = tree_type(decl);
- if (type_is_array(type)) {
- // Initialise only those sub-elements for which this
- // process is a driver
-
- int64_t low, high;
- range_bounds(type_dim(type, 0), &low, &high);
-
- for (unsigned i = 0; i < high - low + 1; i++) {
- for (unsigned j = 0; j < tree_sub_drivers(decl, i); j++) {
- if (tree_sub_driver(decl, i, j) == ctx->proc) {
- LLVMValueRef ptr = cgen_array_signal_ptr(decl, llvm_int32(i));
- LLVMValueRef indices[] = { llvm_int32(0), llvm_int32(i) };
- LLVMValueRef ith = LLVMBuildGEP(builder, val, indices,
- ARRAY_LEN(indices), "");
- LLVMValueRef deref = LLVMBuildLoad(builder, ith, "");
- cgen_sched_waveform(ptr, deref, llvm_int64(0));
- }
- }
- }
- }
- else
- cgen_sched_waveform(tree_attr_ptr(decl, sig_struct_i), val,
- llvm_int64(0));
-
- tree_add_attr_ptr(decl, tag_i, ctx->proc);
-}
-
struct cgen_proc_var_ctx {
LLVMTypeRef *types;
unsigned offset;
@@ -2371,10 +2320,6 @@ static void cgen_process(tree_t t)
}
}
- // Signal driver initialisation
-
- tree_visit_only(t, cgen_driver_init_fn, &ctx, T_SIGNAL_ASSIGN);
-
// Return to simulation kernel after initialisation
cgen_sched_process(llvm_int64(0));
@@ -2867,6 +2812,45 @@ static void cgen_global_const(tree_t t)
}
}
+static void cgen_reset_function(tree_t t)
+{
+ char name[128];
+ snprintf(name, sizeof(name), "%s_reset", istr(tree_ident(t)));
+
+ LLVMValueRef fn =
+ LLVMAddFunction(module, name,
+ LLVMFunctionType(LLVMVoidType(), NULL, 0, false));
+
+ struct cgen_ctx ctx = {
+ .fn = fn
+ };
+
+ LLVMBasicBlockRef entry_bb = LLVMAppendBasicBlock(fn, "entry");
+ LLVMPositionBuilderAtEnd(builder, entry_bb);
+
+ for (unsigned i = 0; i < tree_decls(t); i++) {
+ tree_t d = tree_decl(t, i);
+ if (tree_kind(d) != T_SIGNAL_DECL)
+ continue;
+
+ // Schedule the initial assignment to the signal
+ assert(tree_has_value(d));
+ LLVMValueRef val = cgen_expr(tree_value(d), &ctx);
+
+ LLVMValueRef p_signal = cgen_array_signal_ptr(d, llvm_int32(0));
+
+ type_t type = tree_type(d);
+
+ if (type_is_array(type))
+ cgen_array_signal_store(p_signal, type, val, type,
+ llvm_int64(0), &ctx);
+ else
+ cgen_sched_waveform(p_signal, val, llvm_int64(0));
+ }
+
+ LLVMBuildRetVoid(builder);
+}
+
static void cgen_top(tree_t t)
{
for (unsigned i = 0; i < tree_decls(t); i++) {
@@ -2895,6 +2879,8 @@ static void cgen_top(tree_t t)
}
}
+ cgen_reset_function(t);
+
if (tree_kind(t) == T_ELAB) {
for (unsigned i = 0; i < tree_stmts(t); i++)
cgen_process(tree_stmt(t, i));
View
14 src/rt/rtkern.c
@@ -221,7 +221,7 @@ void _sched_waveform_vec(void *_sig, int32_t source, void *values,
struct signal *sig = _sig;
TRACE("_sched_waveform_vec %s source=%d values=%p n=%d size=%d after=%s",
- fmt_sig(sig), source, values, n, size, fmt_time(after));
+ sig, source, values, n, size, fmt_time(after));
const uint8_t *v8 = values;
const uint16_t *v16 = values;
@@ -637,10 +637,16 @@ static void rt_run(struct rt_proc *proc, bool reset)
}
}
-static void rt_initial(void)
+static void rt_initial(tree_t top)
{
// Initialisation is described in LRM 93 section 12.6.4
+ char name[128];
+ snprintf(name, sizeof(name), "%s_reset", istr(tree_ident(top)));
+
+ void (*reset_fn)(void) = jit_fun_ptr(name);
+ (*reset_fn)();
+
for (size_t i = 0; i < n_procs; i++)
rt_run(&procs[i], true /* reset */);
}
@@ -1031,7 +1037,7 @@ void rt_batch_exec(tree_t e, uint64_t stop_time, tree_rd_ctx_t ctx)
rt_one_time_init();
rt_setup(e);
rt_stats_ready();
- rt_initial();
+ rt_initial(e);
while (heap_size(eventq_heap) > 0 && !rt_stop_now(stop_time))
rt_cycle();
rt_cleanup(e);
@@ -1097,7 +1103,7 @@ void rt_slave_exec(tree_t e, tree_rd_ctx_t ctx)
case SLAVE_RESTART:
rt_setup(e);
- rt_initial();
+ rt_initial(e);
break;
case SLAVE_RUN:
View
2 test/regress/signal8.vhd
@@ -11,7 +11,7 @@ begin
process is
begin
- a(1)(2) <= 2;
+ -- a(1)(2) <= 2;
--assert a(1)(2) = 2;
-- a := ( others => ( 1, 2, 3, 4 ) );
-- b := a(1);

0 comments on commit 9c97c72

Please sign in to comment.
Something went wrong with that request. Please try again.