Merge pull request #981 from larsclausen/automatic-2state

vvp: Initialize automatic 2-state vectors to 0
This commit is contained in:
Cary R 2023-08-05 17:44:30 -07:00 committed by GitHub
commit d660ca7179
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 77 additions and 20 deletions

View File

@ -0,0 +1,35 @@
// Check that automatic 2-state variables are initialized to 0.
module test;
bit failed = 1'b0;
function automatic int f(int x);
int a;
if (a !== 0) begin
failed = 1'b1;
end
return x;
endfunction
task automatic t;
int a;
if (a !== 0) begin
failed = 1'b1;
end
endtask
initial begin
int x;
t;
x = f(10);
if (failed) begin
$display("FAILED");
end else begin
$display("PASSED");
end
end
endmodule

View File

@ -60,6 +60,7 @@ sv_array_assign_fail1 vvp_tests/sv_array_assign_fail1.json
sv_array_assign_fail2 vvp_tests/sv_array_assign_fail2.json
sv_array_cassign6 vvp_tests/sv_array_cassign6.json
sv_array_cassign7 vvp_tests/sv_array_cassign7.json
sv_automatic_2state vvp_tests/sv_automatic_2state.json
sv_const1 vvp_tests/sv_const1.json
sv_const2 vvp_tests/sv_const2.json
sv_const3 vvp_tests/sv_const3.json

View File

@ -0,0 +1,5 @@
{
"type" : "normal",
"source" : "sv_automatic_2state.v",
"iverilog-args" : [ "-g2005-sv" ]
}

View File

@ -1794,17 +1794,29 @@ void vvp_vector4_t::change_z2x()
}
}
void vvp_vector4_t::set_to_x()
void vvp_vector4_t::fill_bits(vvp_bit4_t bit)
{
/* note: this relies on the bit encoding for the vvp_bit4_t. */
static const unsigned long init_atable[4] = {
WORD_0_ABITS,
WORD_1_ABITS,
WORD_Z_ABITS,
WORD_X_ABITS };
static const unsigned long init_btable[4] = {
WORD_0_BBITS,
WORD_1_BBITS,
WORD_Z_BBITS,
WORD_X_BBITS };
if (size_ <= BITS_PER_WORD) {
abits_val_ = vvp_vector4_t::WORD_X_ABITS;
bbits_val_ = vvp_vector4_t::WORD_X_BBITS;
abits_val_ = init_atable[bit];
bbits_val_ = init_btable[bit];
} else {
unsigned words = (size_+BITS_PER_WORD-1) / BITS_PER_WORD;
for (unsigned idx = 0 ; idx < words ; idx += 1) {
abits_ptr_[idx] = vvp_vector4_t::WORD_X_ABITS;
bbits_ptr_[idx] = vvp_vector4_t::WORD_X_BBITS;
}
unsigned words = (size_ + BITS_PER_WORD - 1) / BITS_PER_WORD;
for (unsigned idx = 0; idx < words; idx += 1) {
abits_ptr_[idx] = init_atable[bit];
bbits_ptr_[idx] = init_btable[bit];
}
}
}

View File

@ -312,8 +312,11 @@ class vvp_vector4_t {
// Change all Z bits to X bits.
void change_z2x();
// Set all bits to the specified value.
void fill_bits(vvp_bit4_t bit);
// Change all bits to X bits.
void set_to_x();
void set_to_x() { fill_bits(BIT4_X); }
// Display the value into the buf as a string.
char*as_string(char*buf, size_t buf_len) const;

View File

@ -333,12 +333,9 @@ const vvp_vector4_t& vvp_fun_signal4_sa::vec4_unfiltered_value() const
vvp_fun_signal4_aa::vvp_fun_signal4_aa(unsigned wid, vvp_bit4_t init)
{
/* To make init work we would need to save it and then use the
* saved value when we ran reset_instance(). For now just make
* sure it matches the value we use in reset_instance(). */
assert(init == BIT4_X);
context_idx_ = vpip_add_item_to_context(this, vpip_peek_context_scope());
size_ = wid;
init_ = init;
}
vvp_fun_signal4_aa::~vvp_fun_signal4_aa()
@ -348,7 +345,7 @@ vvp_fun_signal4_aa::~vvp_fun_signal4_aa()
void vvp_fun_signal4_aa::alloc_instance(vvp_context_t context)
{
vvp_set_context_item(context, context_idx_, new vvp_vector4_t(size_));
vvp_set_context_item(context, context_idx_, new vvp_vector4_t(size_, init_));
}
void vvp_fun_signal4_aa::reset_instance(vvp_context_t context)
@ -356,7 +353,7 @@ void vvp_fun_signal4_aa::reset_instance(vvp_context_t context)
vvp_vector4_t*bits = static_cast<vvp_vector4_t*>
(vvp_get_context_item(context, context_idx_));
bits->set_to_x();
bits->fill_bits(init_);
}
#ifdef CHECK_WITH_VALGRIND

View File

@ -190,6 +190,7 @@ class vvp_fun_signal4_aa : public vvp_fun_signal_vec, public automatic_signal_ba
private:
unsigned context_idx_;
unsigned size_;
vvp_bit4_t init_;
};
class vvp_fun_signal_real : public vvp_fun_signal_base {

View File

@ -176,15 +176,18 @@ void compile_variable(char*label, char*name,
vvp_net_t*net = new vvp_net_t;
vvp_bit4_t init;
if (vpi_type_code == vpiIntVar)
init = BIT4_0;
else
init = BIT4_X;
if (vpip_peek_current_scope()->is_automatic()) {
vvp_fun_signal4_aa*tmp = new vvp_fun_signal4_aa(wid);
vvp_fun_signal4_aa*tmp = new vvp_fun_signal4_aa(wid, init);
net->fil = tmp;
net->fun = tmp;
} else if (vpi_type_code == vpiIntVar) {
net->fil = new vvp_wire_vec4(wid, BIT4_0);
net->fun = new vvp_fun_signal4_sa(wid);
} else {
net->fil = new vvp_wire_vec4(wid, BIT4_X);
net->fil = new vvp_wire_vec4(wid, init);
net->fun = new vvp_fun_signal4_sa(wid);
}
vvp_signal_value*vfil = dynamic_cast<vvp_signal_value*>(net->fil);