Merge pull request #611 from larsclausen/bits-types
Support calling $bits() with built-in data types
This commit is contained in:
commit
b1fb4a6117
22
elab_expr.cc
22
elab_expr.cc
|
|
@ -1727,9 +1727,25 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope,
|
|||
|
||||
uint64_t use_width = 0;
|
||||
if (PETypename*type_expr = dynamic_cast<PETypename*>(expr)) {
|
||||
ivl_type_t tmp_type = type_expr->get_type()->elaborate_type(des, scope);
|
||||
ivl_assert(*this, tmp_type);
|
||||
use_width = tmp_type->packed_width();
|
||||
ivl_type_t data_type = type_expr->get_type()->elaborate_type(des, scope);
|
||||
ivl_assert(*this, data_type);
|
||||
use_width = 1;
|
||||
while (const netuarray_t *utype =
|
||||
dynamic_cast<const netuarray_t*>(data_type)) {
|
||||
const vector<netrange_t> &dims = utype->static_dimensions();
|
||||
for (size_t i = 0; i < dims.size(); i++)
|
||||
use_width *= dims[i].width();
|
||||
data_type = utype->element_type();
|
||||
}
|
||||
if (!data_type->packed()) {
|
||||
use_width = 0;
|
||||
cerr << get_fileline() << ": error: "
|
||||
<< "Invalid data type for $bits()."
|
||||
<< endl;
|
||||
des->errors++;
|
||||
} else {
|
||||
use_width *= data_type->packed_width();
|
||||
}
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": PECallFunction::elaborate_sfunc_: "
|
||||
<< " Packed width of type argument is " << use_width << endl;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,34 @@
|
|||
// Check that passing a data type to $bits works as expected
|
||||
|
||||
module test;
|
||||
|
||||
bit failed = 1'b0;
|
||||
|
||||
`define check(type, value) \
|
||||
if ($bits(type) !== value) begin \
|
||||
$display("FAILED: $bits(", `"type`", ") is %0d", $bits(type), " expected %0d", value); \
|
||||
failed = 1'b1; \
|
||||
end
|
||||
|
||||
typedef int T1;
|
||||
typedef int T2[3:0];
|
||||
|
||||
initial begin
|
||||
`check(reg, 1);
|
||||
`check(logic, 1);
|
||||
`check(bit, 1);
|
||||
`check(logic [3:0], 4);
|
||||
`check(byte, 8);
|
||||
`check(shortint, 16);
|
||||
`check(int, 32);
|
||||
`check(longint, 64);
|
||||
`check(struct packed { int x; shortint y; }, 32 + 16);
|
||||
`check(T1, 32);
|
||||
`check(T2, 4 * 32);
|
||||
|
||||
if (failed == 1'b0) begin
|
||||
$display("PASSED");
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -101,6 +101,7 @@ assign_op_type normal,-g2009 ivltests
|
|||
bitp1 normal,-g2005-sv ivltests
|
||||
bits normal,-g2005-sv ivltests
|
||||
bits2 normal,-g2005-sv ivltests
|
||||
bits3 normal,-g2005-sv ivltests
|
||||
br884 normal,-g2009 ivltests
|
||||
br917a normal,-g2009 ivltests
|
||||
br917b normal,-g2009 ivltests
|
||||
|
|
|
|||
8
parse.y
8
parse.y
|
|
@ -3743,12 +3743,10 @@ expr_primary_or_typename
|
|||
|
||||
/* There are a few special cases (notably $bits argument) where the
|
||||
expression may be a type name. Let the elaborator sort this out. */
|
||||
| TYPE_IDENTIFIER
|
||||
{ pform_set_type_referenced(@1, $1.text);
|
||||
PETypename*tmp = new PETypename($1.type);
|
||||
FILE_NAME(tmp,@1);
|
||||
| data_type
|
||||
{ PETypename*tmp = new PETypename($1);
|
||||
FILE_NAME(tmp, @1);
|
||||
$$ = tmp;
|
||||
delete[]$1.text;
|
||||
}
|
||||
|
||||
;
|
||||
|
|
|
|||
Loading…
Reference in New Issue