示例#1
0
文件: expr.c 项目: nickg/iverilog
static void emit_expr_select(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
{
      ivl_expr_t sel_expr = ivl_expr_oper2(expr);
      ivl_expr_t sig_expr = ivl_expr_oper1(expr);
      ivl_select_type_t sel_type = ivl_expr_sel_type(expr);
      if (sel_expr) {
	    unsigned width = ivl_expr_width(expr);
	    ivl_expr_type_t type = ivl_expr_type(sig_expr);
	    assert(width > 0);
	      /* The compiler uses selects for some shifts. */
	    if (type != IVL_EX_NUMBER && type != IVL_EX_SIGNAL) {
		  fprintf(vlog_out, "(" );
		  emit_select_name(scope, sig_expr, wid);
		  fprintf(vlog_out, " >> " );
		  emit_scaled_expr(scope, sel_expr, 1, 0);
		  fprintf(vlog_out, ")" );
	    } else {
		    /* A constant/parameter must be zero based in 1364-1995
		     * so keep the compiler generated normalization. This
		     * does not always work for selects before the parameter
		     * since 1364-1995 does not support signed math. */
		  int msb = 1;
		  int lsb = 0;
		  if (type == IVL_EX_SIGNAL) {
			ivl_signal_t sig = ivl_expr_signal(sig_expr);
			msb = ivl_signal_msb(sig);
			lsb = ivl_signal_lsb(sig);
		  }
		    /* A bit select. */
		  if (width == 1) {
			emit_select_name(scope, sig_expr, wid);
			fprintf(vlog_out, "[");
			emit_scaled_expr(scope, sel_expr, msb, lsb);
			fprintf(vlog_out, "]");
		  } else {
			if (ivl_expr_type(sel_expr) == IVL_EX_NUMBER) {
				/* A constant part select. */
			      emit_select_name(scope, sig_expr, wid);
			      emit_scaled_range(scope, sel_expr, width,
			                        msb, lsb);
			} else {
				/* An indexed part select. */
			      assert(sel_type != IVL_SEL_OTHER);
			      emit_expr_ips(scope, sig_expr, sel_expr,
			                    sel_type, width, msb, lsb);
			}
		  }
	    }
      } else {
// HERE: Should this sign extend if the expression is signed?
	    emit_expr(scope, sig_expr, wid);
      }
}
示例#2
0
static void emit_expr_signal(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
{
      ivl_signal_t sig = ivl_expr_signal(expr);
      emit_scope_call_path(scope, ivl_signal_scope(sig));
      emit_id(ivl_signal_basename(sig));
      if (ivl_signal_dimensions(sig)) {
	    int lsb = ivl_signal_array_base(sig);
	    int msb = lsb + ivl_signal_array_count(sig);
	    fprintf(vlog_out, "[");
	    emit_scaled_expr(scope, ivl_expr_oper1(expr), msb, lsb);
	    fprintf(vlog_out, "]");
      }
}
示例#3
0
文件: stmt.c 项目: nickg/iverilog
static void emit_stmt_lval_name(ivl_scope_t scope, ivl_lval_t lval,
                                ivl_signal_t sig)
{
      ivl_expr_t array_idx = ivl_lval_idx(lval);
      emit_scope_call_path(scope, ivl_signal_scope(sig));
      emit_id(ivl_signal_basename(sig));
      if (array_idx) {
	    int msb, lsb;
	    assert(ivl_signal_dimensions(sig));
	    fprintf(vlog_out, "[");
	      /* For an array the LSB/MSB order is not important. They are
	       * always accessed from base counting up. */
	    lsb = ivl_signal_array_base(sig);
	    msb = lsb + ivl_signal_array_count(sig) - 1;
	    emit_scaled_expr(scope, array_idx, msb, lsb);
	    fprintf(vlog_out, "]");
      }
}
示例#4
0
文件: stmt.c 项目: nickg/iverilog
static void emit_stmt_lval_piece(ivl_scope_t scope, ivl_lval_t lval)
{
      ivl_signal_t sig = ivl_lval_sig(lval);
      ivl_expr_t sel_expr;
      ivl_select_type_t sel_type;
      unsigned width = ivl_lval_width(lval);
      int msb, lsb;
      assert(width > 0);

	/* If there are no selects then just print the name. */
      sel_expr = ivl_lval_part_off(lval);
      if (! sel_expr && (width == ivl_signal_width(sig))) {
	    emit_stmt_lval_name(scope, lval, sig);
	    return;
      }

	/* We have some kind of select. */
      lsb = ivl_signal_lsb(sig);
      msb = ivl_signal_msb(sig);
      sel_type = ivl_lval_sel_type(lval);
      assert(sel_expr);
	/* A bit select. */
      if (width == 1) {
	    emit_stmt_lval_name(scope, lval, sig);
	    fprintf(vlog_out, "[");
	    emit_scaled_expr(scope, sel_expr, msb, lsb);
	    fprintf(vlog_out, "]");
      } else {
	      /* A constant part select. */
	    if (ivl_expr_type(sel_expr) == IVL_EX_NUMBER) {
		  emit_stmt_lval_name(scope, lval, sig);
		  emit_scaled_range(scope, sel_expr, width, msb, lsb);
	      /* An indexed part select. */
	    } else {
		  assert(sel_type != IVL_SEL_OTHER);
		  emit_stmt_lval_ips(scope, lval, sig, sel_expr, sel_type,
		                     width, msb, lsb);
	    }
      }
}
示例#5
0
/*
 * Emit an indexed part select as a concatenation of bit selects.
 */
static void emit_expr_ips(ivl_scope_t scope, ivl_expr_t sig_expr,
                          ivl_expr_t sel_expr, ivl_select_type_t sel_type,
                          unsigned wid, int msb, int lsb)
{
      unsigned idx;
      assert(wid > 0);
      fprintf(vlog_out, "{");
      if (msb >= lsb) {
	    if (sel_type == IVL_SEL_IDX_DOWN) {
		  lsb  += wid - 1;
		  msb  += wid - 1;
		  emit_select_name(scope, sig_expr, wid);
		  fprintf(vlog_out, "[");
		  emit_scaled_expr(scope, sel_expr, msb, lsb);
		  fprintf(vlog_out, "]");
		  for (idx = 1; idx < wid; idx += 1) {
			fprintf(vlog_out, ", ");
			emit_select_name(scope, sig_expr, wid);
			fprintf(vlog_out, "[");
			emit_scaled_expr(scope, sel_expr, msb, lsb);
			fprintf(vlog_out, " - %u]", idx);
		  }
		  fprintf(vlog_out, "}");
	    } else {
		  assert(sel_type == IVL_SEL_IDX_UP);
		  for (idx = wid - 1; idx > 0; idx -= 1) {
			emit_select_name(scope, sig_expr, wid);
			fprintf(vlog_out, "[");
			emit_scaled_expr(scope, sel_expr, msb, lsb);
			fprintf(vlog_out, " + %u], ", idx);
		  }
		  emit_select_name(scope, sig_expr, wid);
		  fprintf(vlog_out, "[");
		  emit_scaled_expr(scope, sel_expr, msb, lsb);
		  fprintf(vlog_out, "]}");
	    }
      } else {
	    if (sel_type == IVL_SEL_IDX_UP) {
		  lsb  -= wid - 1;
		  msb  -= wid - 1;
		  emit_select_name(scope, sig_expr, wid);
		  fprintf(vlog_out, "[");
		  emit_scaled_expr(scope, sel_expr, msb, lsb);
		  fprintf(vlog_out, "]");
		  for (idx = 1; idx < wid; idx += 1) {
			fprintf(vlog_out, ", ");
			emit_select_name(scope, sig_expr, wid);
			fprintf(vlog_out, "[");
			emit_scaled_expr(scope, sel_expr, msb, lsb);
			fprintf(vlog_out, " + %u]", idx);
		  }
		  fprintf(vlog_out, "}");
	    } else {
		  assert(sel_type == IVL_SEL_IDX_DOWN);
		  for (idx = wid - 1; idx > 0; idx -= 1) {
			emit_select_name(scope, sig_expr, wid);
			fprintf(vlog_out, "[");
			emit_scaled_expr(scope, sel_expr, msb, lsb);
			fprintf(vlog_out, " - %u], ", idx);
		  }
		  emit_select_name(scope, sig_expr, wid);
		  fprintf(vlog_out, "[");
		  emit_scaled_expr(scope, sel_expr, msb, lsb);
		  fprintf(vlog_out, "]}");
	    }
      }
}