Skip to content

Commit

Permalink
Add "force" and "noforce" commands to TCL shell
Browse files Browse the repository at this point in the history
  • Loading branch information
nickg committed Jul 22, 2023
1 parent 3c81bf1 commit a6575e9
Show file tree
Hide file tree
Showing 8 changed files with 375 additions and 72 deletions.
88 changes: 52 additions & 36 deletions src/rt/model.c
Original file line number Diff line number Diff line change
Expand Up @@ -3143,14 +3143,14 @@ static inline void check_delay(int64_t delay)
}
}

void force_signal(rt_signal_t *s, const void *values, int offset, size_t count)
void force_signal(rt_model_t *m, rt_signal_t *s, const void *values,
int offset, size_t count)
{
RT_LOCK(s->lock);

TRACE("force signal %s (offset %d) to %s", istr(tree_ident(s->where)), offset,
TRACE("force signal %s+%d to %s", istr(tree_ident(s->where)), offset,
fmt_values(values, count));

rt_model_t *m = get_model();
assert(m->can_create_delta);

rt_nexus_t *n = split_nexus(m, s, offset, count);
Expand All @@ -3169,14 +3169,37 @@ void force_signal(rt_signal_t *s, const void *values, int offset, size_t count)
}
}

void deposit_signal(rt_signal_t *s, const void *values, int offset, size_t count)
void release_signal(rt_model_t *m, rt_signal_t *s, int offset, size_t count)
{
RT_LOCK(s->lock);

TRACE("deposit signal %s (offset %d) to %s", istr(tree_ident(s->where)),
TRACE("release signal %s+%d", istr(tree_ident(s->where)), offset);

assert(m->can_create_delta);

rt_nexus_t *n = split_nexus(m, s, offset, count);
for (; count > 0; n = n->chain) {
count -= n->width;
assert(count >= 0);

if (n->flags & NET_F_FORCED)
n->flags &= ~NET_F_FORCED;

rt_source_t *src = get_forcing_source(m, n);
src->disconnected = 1;

deltaq_insert_force_release(m, n);
}
}

void deposit_signal(rt_model_t *m, rt_signal_t *s, const void *values,
int offset, size_t count)
{
RT_LOCK(s->lock);

TRACE("deposit signal %s+%d to %s", istr(tree_ident(s->where)),
offset, fmt_values(values, count));

rt_model_t *m = get_model();
assert(m->can_create_delta);

rt_nexus_t *n = split_nexus(m, s, offset, count);
Expand Down Expand Up @@ -3445,6 +3468,25 @@ int64_t get_static_expr(rt_model_t *m, tree_t expr)
return eval_static_expr(m->jit, expr);
}

void get_forcing_value(rt_signal_t *s, uint8_t *value)
{
uint8_t *p = value;
rt_nexus_t *n = &(s->nexus);
for (int i = 0; i < s->n_nexus; i++) {
assert(n->n_sources > 0);
rt_source_t *s = NULL;
for (s = &(n->sources); s; s = s->chain_input) {
if (s->tag == SOURCE_FORCING)
break;
}
assert(s != NULL);

memcpy(p, s->u.forcing.bytes, n->width * n->size);
p += n->width * n->size;
}
assert(p == value + s->shared.size);
}

////////////////////////////////////////////////////////////////////////////////
// Entry points from compiled code

Expand Down Expand Up @@ -4081,30 +4123,16 @@ void x_disconnect(sig_shared_t *ss, uint32_t offset, int32_t count,
void x_force(sig_shared_t *ss, uint32_t offset, int32_t count, void *values)
{
rt_signal_t *s = container_of(ss, rt_signal_t, shared);
RT_LOCK(s->lock);

TRACE("force signal %s+%d value=%s count=%d", istr(tree_ident(s->where)),
offset, fmt_values(values, count), count);

rt_proc_t *proc = get_active_proc();

check_postponed(0, proc);

rt_model_t *m = get_model();
rt_nexus_t *n = split_nexus(m, s, offset, count);
char *vptr = values;
for (; count > 0; n = n->chain) {
count -= n->width;
assert(count >= 0);

n->flags |= NET_F_FORCED;

rt_source_t *src = get_forcing_source(m, n);
copy_value_ptr(n, &(src->u.forcing), vptr);
vptr += n->width * n->size;
check_postponed(0, proc);

deltaq_insert_force_release(m, n);
}
force_signal(m, s, values, offset, count);
}

void x_release(sig_shared_t *ss, uint32_t offset, int32_t count)
Expand All @@ -4115,23 +4143,11 @@ void x_release(sig_shared_t *ss, uint32_t offset, int32_t count)
offset, count);

rt_proc_t *proc = get_active_proc();

check_postponed(0, proc);

rt_model_t *m = get_model();
rt_nexus_t *n = split_nexus(m, s, offset, count);
for (; count > 0; n = n->chain) {
count -= n->width;
assert(count >= 0);

if (n->flags & NET_F_FORCED)
n->flags &= ~NET_F_FORCED;

rt_source_t *src = get_forcing_source(m, n);
src->disconnected = 1;
check_postponed(0, proc);

deltaq_insert_force_release(m, n);
}
release_signal(m, s, offset, count);
}

void x_resolve_signal(sig_shared_t *ss, jit_handle_t handle, void *context,
Expand Down
8 changes: 6 additions & 2 deletions src/rt/model.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,13 @@ const void *signal_last_value(rt_signal_t *s);
uint8_t signal_size(rt_signal_t *s);
uint32_t signal_width(rt_signal_t *s);
size_t signal_expand(rt_signal_t *s, uint64_t *buf, size_t max);
void force_signal(rt_signal_t *s, const void *values, int offset, size_t count);
void deposit_signal(rt_signal_t *s, const void *values, int offset, size_t count);
void force_signal(rt_model_t *m, rt_signal_t *s, const void *values,
int offset, size_t count);
void release_signal(rt_model_t *m, rt_signal_t *s, int offset, size_t count);
void deposit_signal(rt_model_t *m, rt_signal_t *s, const void *values,
int offset, size_t count);
rt_watch_t *find_watch(rt_nexus_t *n, sig_event_fn_t fn);
void get_forcing_value(rt_signal_t *s, uint8_t *value);

int64_t get_static_expr(rt_model_t *m, tree_t expr);

Expand Down
40 changes: 36 additions & 4 deletions src/rt/printer.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,24 @@ static void std_logic_vector_printer(print_func_t *f, const void *data,
tb_append(f->printer->buf, '"');
}

static void bit_printer(print_func_t *f, const void *data, size_t size,
print_flags_t flags)
{
assert(size == 1);
tb_cat(f->printer->buf, *(uint8_t *)data ? "'1'" : "'0'");
}

static void bit_vector_printer(print_func_t *f, const void *data,
size_t size, print_flags_t flags)
{
tb_append(f->printer->buf, '"');

for (int i = 0; i < size; i++)
tb_append(f->printer->buf, *((uint8_t *)data + i) ? '1' : '0');

tb_append(f->printer->buf, '"');
}

printer_t *printer_new(void)
{
printer_t *p = xcalloc(sizeof(printer_t));
Expand Down Expand Up @@ -145,6 +163,9 @@ print_func_t *printer_for(printer_t *p, type_t type)
case W_IEEE_ULOGIC:
f->typefn = std_logic_printer;
break;
case W_STD_BIT:
f->typefn = bit_printer;
break;
default:
goto invalid;
}
Expand All @@ -155,10 +176,13 @@ print_func_t *printer_for(printer_t *p, type_t type)
case W_IEEE_ULOGIC_VECTOR:
f->typefn = std_logic_vector_printer;
break;
default:
goto invalid;
}
break;
case W_STD_BIT_VECTOR:
f->typefn = bit_vector_printer;
break;
default:
goto invalid;
}
break;
default:
goto invalid;
}
Expand All @@ -177,3 +201,11 @@ const char *print_signal(print_func_t *fn, rt_signal_t *s, print_flags_t flags)
(*fn->typefn)(fn, s->shared.data, s->shared.size, flags);
return tb_get(fn->printer->buf);
}

const char *print_raw(print_func_t *fn, const void *data, size_t size,
print_flags_t flags)
{
tb_rewind(fn->printer->buf);
(*fn->typefn)(fn, data, size, flags);
return tb_get(fn->printer->buf);
}
2 changes: 2 additions & 0 deletions src/rt/printer.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,7 @@ void printer_free(printer_t *p);
print_func_t *printer_for(printer_t *p, type_t type);

const char *print_signal(print_func_t *fn, rt_signal_t *s, print_flags_t flags);
const char *print_raw(print_func_t *fn, const void *data, size_t size,
print_flags_t flags);

#endif // _RT_PRINTER_H
Loading

0 comments on commit a6575e9

Please sign in to comment.