mirror of https://github.com/YosysHQ/yosys.git
Redo integer passing on top of bignum
This commit is contained in:
parent
f7400a06cd
commit
f0704b6ede
240
kernel/tclapi.cc
240
kernel/tclapi.cc
|
@ -21,6 +21,11 @@
|
||||||
#include "kernel/rtlil.h"
|
#include "kernel/rtlil.h"
|
||||||
#include "libs/json11/json11.hpp"
|
#include "libs/json11/json11.hpp"
|
||||||
|
|
||||||
|
#ifdef YOSYS_ENABLE_TCL
|
||||||
|
#include "tclTomMath.h"
|
||||||
|
#include "tclTomMathDecls.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
YOSYS_NAMESPACE_BEGIN
|
YOSYS_NAMESPACE_BEGIN
|
||||||
|
|
||||||
#ifdef YOSYS_ENABLE_TCL
|
#ifdef YOSYS_ENABLE_TCL
|
||||||
|
@ -145,29 +150,106 @@ static int tcl_yosys_cmd(ClientData, Tcl_Interp *interp, int argc, const char *a
|
||||||
continue; \
|
continue; \
|
||||||
} \
|
} \
|
||||||
|
|
||||||
|
#define FLAG2(name) \
|
||||||
|
if (!strcmp(Tcl_GetString(objv[i]), "-" #name)) { \
|
||||||
|
name##_flag = true; \
|
||||||
|
continue; \
|
||||||
|
} \
|
||||||
|
|
||||||
#define ERROR(str) \
|
#define ERROR(str) \
|
||||||
{ \
|
{ \
|
||||||
Tcl_SetResult(interp, (char *)(str), TCL_STATIC); \
|
Tcl_SetResult(interp, (char *)(str), TCL_STATIC); \
|
||||||
return TCL_ERROR; \
|
return TCL_ERROR; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool const_to_mp_int(const Const &a, mp_int *b, bool force_signed, bool force_unsigned)
|
||||||
|
{
|
||||||
|
if (!a.is_fully_def())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (mp_init(b))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
bool negative = ((a.flags & RTLIL::CONST_FLAG_SIGNED) || force_signed) &&
|
||||||
|
!force_unsigned &&
|
||||||
|
!a.empty() && (a.back() == RTLIL::S1);
|
||||||
|
|
||||||
|
for (int i = a.size() - 1; i >= 0; i--) {
|
||||||
|
if (mp_mul_2d(b, 1, b)) {
|
||||||
|
mp_clear(b);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((a[i] == RTLIL::S1) ^ negative) {
|
||||||
|
if (mp_add_d(b, 1, b)) {
|
||||||
|
mp_clear(b);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (negative) {
|
||||||
|
if (mp_add_d(b, 1, b) || mp_neg(b, b)) {
|
||||||
|
mp_clear(b);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool mp_int_to_const(mp_int *a, Const &b, bool is_signed)
|
||||||
|
{
|
||||||
|
bool negative = (mp_cmp_d(a, 0) == MP_LT);
|
||||||
|
if (negative && !is_signed)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (negative) {
|
||||||
|
mp_neg(a, a);
|
||||||
|
mp_sub_d(a, 1, a);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<unsigned char> buf;
|
||||||
|
buf.resize(mp_ubin_size(a));
|
||||||
|
size_t written; // dummy
|
||||||
|
mp_to_ubin(a, buf.data(), buf.size(), &written);
|
||||||
|
|
||||||
|
b.bits().reserve(mp_count_bits(a) + is_signed);
|
||||||
|
for (int i = 0; i < mp_count_bits(a);) {
|
||||||
|
for (int j = 0; j < 8 && i < mp_count_bits(a); j++, i++) {
|
||||||
|
bool bv = ((buf.back() & (1 << j)) != 0) ^ negative;
|
||||||
|
b.bits().push_back(bv ? RTLIL::S1 : RTLIL::S0);
|
||||||
|
}
|
||||||
|
buf.pop_back();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_signed) {
|
||||||
|
b.bits().push_back(negative ? RTLIL::S1 : RTLIL::S0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static int tcl_get_attr(ClientData, Tcl_Interp *interp, int argc, const char *argv[])
|
static int tcl_get_attr(ClientData, Tcl_Interp *interp, int argc, const char *argv[])
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
bool mod_flag = false, string_flag = false, int_flag = false, bool_flag = false;
|
bool mod_flag = false, string_flag = false, bool_flag = false;
|
||||||
|
bool int_flag = false, sint_flag = false, uint_flag = false;
|
||||||
for (i = 1; i < argc; i++) {
|
for (i = 1; i < argc; i++) {
|
||||||
FLAG(mod)
|
FLAG(mod)
|
||||||
FLAG(string)
|
FLAG(string)
|
||||||
FLAG(int)
|
FLAG(int)
|
||||||
|
FLAG(sint)
|
||||||
|
FLAG(uint)
|
||||||
FLAG(bool)
|
FLAG(bool)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((mod_flag && i != argc - 2) ||
|
if ((mod_flag && i != argc - 2) ||
|
||||||
(!mod_flag && i != argc - 3) ||
|
(!mod_flag && i != argc - 3) ||
|
||||||
(string_flag + int_flag + bool_flag > 1))
|
(string_flag + int_flag + sint_flag + uint_flag + bool_flag > 1))
|
||||||
ERROR("bad usage: expected \"get_attr -mod [-string|-int|-bool] <module> <attrname>\""
|
ERROR("bad usage: expected \"get_attr -mod [-string|-int|-sint|-uint|-bool] <module> <attrname>\""
|
||||||
" or \"get_attr [-string|-int|-bool] <module> <identifier> <attrname>\"")
|
" or \"get_attr [-string|-int|-sint|-uint|-bool] <module> <identifier> <attrname>\"")
|
||||||
|
|
||||||
IdString mod_id, obj_id, attr_id;
|
IdString mod_id, obj_id, attr_id;
|
||||||
mod_id = RTLIL::escape_id(argv[i++]);
|
mod_id = RTLIL::escape_id(argv[i++]);
|
||||||
|
@ -197,19 +279,17 @@ static int tcl_get_attr(ClientData, Tcl_Interp *interp, int argc, const char *ar
|
||||||
|
|
||||||
if (string_flag) {
|
if (string_flag) {
|
||||||
Tcl_SetResult(interp, (char *) obj->get_string_attribute(attr_id).c_str(), TCL_VOLATILE);
|
Tcl_SetResult(interp, (char *) obj->get_string_attribute(attr_id).c_str(), TCL_VOLATILE);
|
||||||
} else if (int_flag) {
|
} else if (int_flag || uint_flag || sint_flag) {
|
||||||
if (!obj->has_attribute(attr_id))
|
if (!obj->has_attribute(attr_id))
|
||||||
ERROR("attribute missing (required for -int)");
|
ERROR("attribute missing (required for -int)");
|
||||||
|
|
||||||
RTLIL::Const &value = obj->attributes.at(attr_id);
|
RTLIL::Const &value = obj->attributes.at(attr_id);
|
||||||
if (value.size() > 32)
|
|
||||||
ERROR("value too large")
|
|
||||||
|
|
||||||
// FIXME: 32'hffffffff will return as negative despite is_signed=false
|
mp_int value_mp;
|
||||||
Tcl_SetResult(interp, (char *) std::to_string(value.as_int()).c_str(), TCL_VOLATILE);
|
if (!const_to_mp_int(value, &value_mp, sint_flag, uint_flag))
|
||||||
|
ERROR("bignum manipulation failed");
|
||||||
|
Tcl_SetObjResult(interp, Tcl_NewBignumObj(&value_mp));
|
||||||
} else if (bool_flag) {
|
} else if (bool_flag) {
|
||||||
bool value = obj->get_bool_attribute(attr_id);
|
Tcl_SetObjResult(interp, Tcl_NewBooleanObj(obj->get_bool_attribute(attr_id)));
|
||||||
Tcl_SetResult(interp, (char *) std::to_string(value).c_str(), TCL_VOLATILE);
|
|
||||||
} else {
|
} else {
|
||||||
if (!obj->has_attribute(attr_id))
|
if (!obj->has_attribute(attr_id))
|
||||||
ERROR("attribute missing (required unless -bool or -string)")
|
ERROR("attribute missing (required unless -bool or -string)")
|
||||||
|
@ -264,33 +344,34 @@ static int tcl_has_attr(ClientData, Tcl_Interp *interp, int argc, const char *ar
|
||||||
return TCL_OK;
|
return TCL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tcl_set_attr(ClientData, Tcl_Interp *interp, int argc, const char *argv[])
|
static int tcl_set_attr(ClientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
bool mod_flag = false, string_flag = false, int_flag = false, bool_flag = false;
|
bool mod_flag = false, string_flag = false, bool_flag = false;
|
||||||
bool false_flag = false, true_flag = false;
|
bool true_flag = false, false_flag = false, sint_flag = false, uint_flag = false;
|
||||||
for (i = 1; i < argc; i++) {
|
for (i = 1; i < objc; i++) {
|
||||||
FLAG(mod)
|
FLAG2(mod)
|
||||||
FLAG(string)
|
FLAG2(string)
|
||||||
FLAG(int)
|
FLAG2(true)
|
||||||
FLAG(bool)
|
FLAG2(false)
|
||||||
FLAG(false)
|
FLAG2(sint)
|
||||||
FLAG(true)
|
FLAG2(uint)
|
||||||
|
FLAG2(bool)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((i != argc - (2 + !mod_flag + !(true_flag || false_flag))) ||
|
if ((i != objc - (2 + !mod_flag + !(true_flag || false_flag))) ||
|
||||||
(string_flag + int_flag + bool_flag + true_flag + false_flag > 1))
|
(string_flag + sint_flag + uint_flag + bool_flag + true_flag + false_flag > 1))
|
||||||
ERROR("bad usage: expected \"set_attr -mod [-string|-int|-bool] <module> <attrname> <value>\""
|
ERROR("bad usage: expected \"set_attr -mod [-string|-sint|-uint|-bool] <module> <attrname> <value>\""
|
||||||
" or \"set_attr [-string|-int|-bool] <module> <identifier> <attrname> <value>\""
|
" or \"set_attr [-string|-sint|-uint|-bool] <module> <identifier> <attrname> <value>\""
|
||||||
" or \"set_attr [-true|-false] <module> <identifier> <attrname>\""
|
" or \"set_attr [-true|-false] <module> <identifier> <attrname>\""
|
||||||
" or \"set_attr -mod [-true|-false| <module> <attrname>\"")
|
" or \"set_attr -mod [-true|-false| <module> <attrname>\"")
|
||||||
|
|
||||||
IdString mod_id, obj_id, attr_id;
|
IdString mod_id, obj_id, attr_id;
|
||||||
mod_id = RTLIL::escape_id(argv[i++]);
|
mod_id = RTLIL::escape_id(Tcl_GetString(objv[i++]));
|
||||||
if (!mod_flag)
|
if (!mod_flag)
|
||||||
obj_id = RTLIL::escape_id(argv[i++]);
|
obj_id = RTLIL::escape_id(Tcl_GetString(objv[i++]));
|
||||||
attr_id = RTLIL::escape_id(argv[i++]);
|
attr_id = RTLIL::escape_id(Tcl_GetString(objv[i++]));
|
||||||
|
|
||||||
RTLIL::Module *mod = yosys_design->module(mod_id);
|
RTLIL::Module *mod = yosys_design->module(mod_id);
|
||||||
if (!mod)
|
if (!mod)
|
||||||
|
@ -313,17 +394,35 @@ static int tcl_set_attr(ClientData, Tcl_Interp *interp, int argc, const char *ar
|
||||||
ERROR("object not found")
|
ERROR("object not found")
|
||||||
|
|
||||||
if (string_flag) {
|
if (string_flag) {
|
||||||
obj->set_string_attribute(attr_id, argv[i++]);
|
obj->set_string_attribute(attr_id, Tcl_GetString(objv[i++]));
|
||||||
} else if (int_flag) {
|
} else if (sint_flag || uint_flag) {
|
||||||
obj->attributes[attr_id] = atoi(argv[i++]);
|
RTLIL::Const const_;
|
||||||
|
mp_int value_mp;
|
||||||
|
|
||||||
|
if (Tcl_TakeBignumFromObj(interp, objv[i++], &value_mp))
|
||||||
|
ERROR("non-integral value")
|
||||||
|
|
||||||
|
if (!mp_int_to_const(&value_mp, const_, sint_flag))
|
||||||
|
ERROR("bignum manipulation failed");
|
||||||
|
|
||||||
|
if (sint_flag) {
|
||||||
|
const_.flags |= RTLIL::CONST_FLAG_SIGNED;
|
||||||
|
if (const_.size() < 32)
|
||||||
|
const_.exts(32);
|
||||||
|
} else {
|
||||||
|
if (const_.size() < 32)
|
||||||
|
const_.extu(32);
|
||||||
|
}
|
||||||
|
|
||||||
|
obj->attributes[attr_id] = const_;
|
||||||
} else if (bool_flag) {
|
} else if (bool_flag) {
|
||||||
obj->set_bool_attribute(attr_id, atoi(argv[i++]) != 0);
|
obj->set_bool_attribute(attr_id, atoi(Tcl_GetString(objv[i++])) != 0);
|
||||||
} else if (true_flag) {
|
} else if (true_flag) {
|
||||||
obj->set_bool_attribute(attr_id, true);
|
obj->set_bool_attribute(attr_id, true);
|
||||||
} else if (false_flag) {
|
} else if (false_flag) {
|
||||||
obj->set_bool_attribute(attr_id, false);
|
obj->set_bool_attribute(attr_id, false);
|
||||||
} else {
|
} else {
|
||||||
obj->attributes[attr_id] = Const::from_string(std::string(argv[i++]));
|
obj->attributes[attr_id] = Const::from_string(std::string(Tcl_GetString(objv[i++])));
|
||||||
}
|
}
|
||||||
|
|
||||||
return TCL_OK;
|
return TCL_OK;
|
||||||
|
@ -332,10 +431,14 @@ static int tcl_set_attr(ClientData, Tcl_Interp *interp, int argc, const char *ar
|
||||||
static int tcl_get_param(ClientData, Tcl_Interp *interp, int argc, const char *argv[])
|
static int tcl_get_param(ClientData, Tcl_Interp *interp, int argc, const char *argv[])
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
bool string_flag = false, int_flag = false;
|
bool string_flag = false, bool_flag = false;
|
||||||
|
bool int_flag = false, sint_flag = false, uint_flag = false;
|
||||||
for (i = 1; i < argc; i++) {
|
for (i = 1; i < argc; i++) {
|
||||||
FLAG(string)
|
FLAG(string)
|
||||||
FLAG(int)
|
FLAG(int)
|
||||||
|
FLAG(sint)
|
||||||
|
FLAG(uint)
|
||||||
|
FLAG(bool)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -363,35 +466,36 @@ static int tcl_get_param(ClientData, Tcl_Interp *interp, int argc, const char *a
|
||||||
|
|
||||||
if (string_flag) {
|
if (string_flag) {
|
||||||
Tcl_SetResult(interp, (char *) value.decode_string().c_str(), TCL_VOLATILE);
|
Tcl_SetResult(interp, (char *) value.decode_string().c_str(), TCL_VOLATILE);
|
||||||
} else if (int_flag) {
|
} else if (int_flag || uint_flag || sint_flag) {
|
||||||
if (value.size() > 32)
|
mp_int value_mp;
|
||||||
ERROR("value too large")
|
if (!const_to_mp_int(value, &value_mp, sint_flag, uint_flag))
|
||||||
|
ERROR("bignum manipulation failed");
|
||||||
Tcl_SetResult(interp, (char *) std::to_string(value.as_int()).c_str(), TCL_VOLATILE);
|
Tcl_SetObjResult(interp, Tcl_NewBignumObj(&value_mp));
|
||||||
} else {
|
} else {
|
||||||
Tcl_SetResult(interp, (char *) value.as_string().c_str(), TCL_VOLATILE);
|
Tcl_SetResult(interp, (char *) value.as_string().c_str(), TCL_VOLATILE);
|
||||||
}
|
}
|
||||||
return TCL_OK;
|
return TCL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tcl_set_param(ClientData, Tcl_Interp *interp, int argc, const char *argv[])
|
static int tcl_set_param(ClientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
bool string_flag = false, int_flag = false;
|
bool string_flag = false, sint_flag = false, uint_flag = false;
|
||||||
for (i = 1; i < argc; i++) {
|
for (i = 1; i < objc; i++) {
|
||||||
FLAG(string)
|
FLAG2(string)
|
||||||
FLAG(int)
|
FLAG2(sint)
|
||||||
|
FLAG2(uint)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((i != argc - 4) ||
|
if ((i != objc - 4) ||
|
||||||
(string_flag + int_flag > 1))
|
(string_flag + sint_flag + uint_flag > 1))
|
||||||
ERROR("bad usage: expected \"get_param [-string|-int] <module> <cellid> <paramname> <value>")
|
ERROR("bad usage: expected \"set_param [-string|-sint|-uint] <module> <cellid> <paramname> <value>")
|
||||||
|
|
||||||
IdString mod_id, cell_id, param_id;
|
IdString mod_id, cell_id, param_id;
|
||||||
mod_id = RTLIL::escape_id(argv[i++]);
|
mod_id = RTLIL::escape_id(Tcl_GetString(objv[i++]));
|
||||||
cell_id = RTLIL::escape_id(argv[i++]);
|
cell_id = RTLIL::escape_id(Tcl_GetString(objv[i++]));
|
||||||
param_id = RTLIL::escape_id(argv[i++]);
|
param_id = RTLIL::escape_id(Tcl_GetString(objv[i++]));
|
||||||
|
|
||||||
RTLIL::Module *mod = yosys_design->module(mod_id);
|
RTLIL::Module *mod = yosys_design->module(mod_id);
|
||||||
if (!mod)
|
if (!mod)
|
||||||
|
@ -402,11 +506,29 @@ static int tcl_set_param(ClientData, Tcl_Interp *interp, int argc, const char *a
|
||||||
ERROR("object not found")
|
ERROR("object not found")
|
||||||
|
|
||||||
if (string_flag) {
|
if (string_flag) {
|
||||||
cell->setParam(param_id, Const(std::string(argv[i++])));
|
cell->setParam(param_id, Const(std::string(Tcl_GetString(objv[i++]))));
|
||||||
} else if (int_flag) {
|
} else if (sint_flag || uint_flag) {
|
||||||
cell->setParam(param_id, Const(atoi(argv[i++])));
|
RTLIL::Const const_;
|
||||||
|
mp_int value_mp;
|
||||||
|
|
||||||
|
if (Tcl_TakeBignumFromObj(interp, objv[i++], &value_mp))
|
||||||
|
ERROR("non-integral value")
|
||||||
|
|
||||||
|
if (!mp_int_to_const(&value_mp, const_, sint_flag))
|
||||||
|
ERROR("bignum manipulation failed");
|
||||||
|
|
||||||
|
if (sint_flag) {
|
||||||
|
const_.flags |= RTLIL::CONST_FLAG_SIGNED;
|
||||||
|
if (const_.size() < 32)
|
||||||
|
const_.exts(32);
|
||||||
} else {
|
} else {
|
||||||
cell->setParam(param_id, Const::from_string(std::string(argv[i++])));
|
if (const_.size() < 32)
|
||||||
|
const_.extu(32);
|
||||||
|
}
|
||||||
|
|
||||||
|
cell->setParam(param_id, const_);
|
||||||
|
} else {
|
||||||
|
cell->setParam(param_id, Const::from_string(std::string(Tcl_GetString(objv[i++]))));
|
||||||
}
|
}
|
||||||
return TCL_OK;
|
return TCL_OK;
|
||||||
}
|
}
|
||||||
|
@ -418,9 +540,9 @@ int yosys_tcl_iterp_init(Tcl_Interp *interp)
|
||||||
Tcl_CreateCommand(interp, "yosys", tcl_yosys_cmd, NULL, NULL);
|
Tcl_CreateCommand(interp, "yosys", tcl_yosys_cmd, NULL, NULL);
|
||||||
Tcl_CreateCommand(interp, "rtlil::get_attr", tcl_get_attr, NULL, NULL);
|
Tcl_CreateCommand(interp, "rtlil::get_attr", tcl_get_attr, NULL, NULL);
|
||||||
Tcl_CreateCommand(interp, "rtlil::has_attr", tcl_has_attr, NULL, NULL);
|
Tcl_CreateCommand(interp, "rtlil::has_attr", tcl_has_attr, NULL, NULL);
|
||||||
Tcl_CreateCommand(interp, "rtlil::set_attr", tcl_set_attr, NULL, NULL);
|
Tcl_CreateObjCommand(interp, "rtlil::set_attr", tcl_set_attr, NULL, NULL);
|
||||||
Tcl_CreateCommand(interp, "rtlil::get_param", tcl_get_param, NULL, NULL);
|
Tcl_CreateCommand(interp, "rtlil::get_param", tcl_get_param, NULL, NULL);
|
||||||
Tcl_CreateCommand(interp, "rtlil::set_param", tcl_set_param, NULL, NULL);
|
Tcl_CreateObjCommand(interp, "rtlil::set_param", tcl_set_param, NULL, NULL);
|
||||||
|
|
||||||
// TODO:
|
// TODO:
|
||||||
//
|
//
|
||||||
|
@ -442,6 +564,10 @@ int yosys_tcl_iterp_init(Tcl_Interp *interp)
|
||||||
// unpack
|
// unpack
|
||||||
// pack
|
// pack
|
||||||
|
|
||||||
|
// Note (dev jf 24-12-02): Make log_id escape everything that’s not a valid
|
||||||
|
// verilog identifier before adding any tcl API that returns IdString values
|
||||||
|
// to avoid -option injection
|
||||||
|
|
||||||
return TCL_OK ;
|
return TCL_OK ;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -4,13 +4,60 @@ if {[rtlil::get_attr -string -mod top foo] != "bar"} {
|
||||||
error "bad top module attribute"
|
error "bad top module attribute"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if {[rtlil::get_attr -int -mod top val] != 4294967295} {
|
||||||
|
error "bad top module attribute 2"
|
||||||
|
}
|
||||||
|
|
||||||
|
if {[rtlil::get_attr -sint -mod top val] != -1} {
|
||||||
|
error "bad top module attribute 3"
|
||||||
|
}
|
||||||
|
|
||||||
if {[rtlil::get_attr -bool top w dont_touch] != 1} {
|
if {[rtlil::get_attr -bool top w dont_touch] != 1} {
|
||||||
error "bad w wire attribute"
|
error "bad w wire attribute"
|
||||||
}
|
}
|
||||||
|
|
||||||
if {[rtlil::get_param -int top inst PARAM] != 4} {
|
if {[rtlil::get_param -int top inst PARAM] != -3} {
|
||||||
error "bad parameter"
|
error "bad parameter"
|
||||||
}
|
}
|
||||||
|
if {[rtlil::get_param -uint top inst PARAM] != 4294967293} {
|
||||||
|
error "bad parameter 2"
|
||||||
|
}
|
||||||
|
|
||||||
rtlil::set_attr -true -mod top marked
|
rtlil::set_attr -true -mod top marked
|
||||||
yosys select -assert-any A:marked
|
yosys select -assert-any A:marked
|
||||||
|
|
||||||
|
# write a 32-bit constant with most bits set
|
||||||
|
rtlil::set_attr -mod -uint top f 4294967294
|
||||||
|
# read it back as a signed integer
|
||||||
|
if {[rtlil::get_attr -mod -sint top f] != -2} {
|
||||||
|
error "bad int roundtrip"
|
||||||
|
}
|
||||||
|
# read it back as an unsigned integer (no signedness flag)
|
||||||
|
if {[rtlil::get_attr -mod -int top f] != 4294967294} {
|
||||||
|
error "bad int roundtrip 2"
|
||||||
|
}
|
||||||
|
# read it back as an unsigned integer
|
||||||
|
if {[rtlil::get_attr -mod -uint top f] != 4294967294} {
|
||||||
|
error "bad int roundtrip 3"
|
||||||
|
}
|
||||||
|
|
||||||
|
# write a signed 32-bit constant
|
||||||
|
rtlil::set_attr -mod -sint top f -3
|
||||||
|
# read it back as a signed integer
|
||||||
|
if {[rtlil::get_attr -mod -sint top f] != -3} {
|
||||||
|
error "bad int roundtrip 4"
|
||||||
|
}
|
||||||
|
# read it back as a signed integer (due to signedness flag)
|
||||||
|
if {[rtlil::get_attr -mod -int top f] != -3} {
|
||||||
|
error "bad int roundtrip 5"
|
||||||
|
}
|
||||||
|
# read it back as an unsigned integer
|
||||||
|
if {[rtlil::get_attr -mod -uint top f] != 4294967293} {
|
||||||
|
error "bad int roundtrip 6"
|
||||||
|
}
|
||||||
|
|
||||||
|
# write a constant larger than 32 bits
|
||||||
|
rtlil::set_attr -mod -sint top prime 87178291199
|
||||||
|
if {[rtlil::get_attr -mod -int top prime] != 87178291199} {
|
||||||
|
error "bad int roundtrip 7"
|
||||||
|
}
|
||||||
|
|
|
@ -3,9 +3,10 @@ parameter PARAM = 0;
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
(* foo="bar" *)
|
(* foo="bar" *)
|
||||||
|
(* val=32'hffffffff *)
|
||||||
module top;
|
module top;
|
||||||
(* dont_touch *)
|
(* dont_touch *)
|
||||||
wire w;
|
wire w;
|
||||||
|
|
||||||
m #(.PARAM(4)) inst();
|
m #(.PARAM(-3)) inst();
|
||||||
endmodule
|
endmodule
|
||||||
|
|
Loading…
Reference in New Issue