Merge pull request #727 from larsclausen/nb-ec-concat
Handle non-blocking event control to lvalue concatenation
This commit is contained in:
commit
e5abd4bf82
|
|
@ -1,3 +1,6 @@
|
|||
// Check that non-blocking event control assignment to a part select on a vector
|
||||
// array works when using an immediate index.
|
||||
|
||||
module top;
|
||||
reg pass = 1'b1;
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,90 @@
|
|||
// Check that non-blocking event control assignment to a part select on a vector
|
||||
// array works when using a variable index.
|
||||
|
||||
module top;
|
||||
reg pass = 1'b1;
|
||||
|
||||
integer i = 0;
|
||||
integer j = 1;
|
||||
integer count;
|
||||
reg [2:0] icount;
|
||||
reg clk = 0;
|
||||
reg [3:0] in = 4'h0;
|
||||
reg [7:0] result [1:0];
|
||||
|
||||
always #10 clk = ~clk;
|
||||
always #20 in = in + 4'h1;
|
||||
|
||||
initial begin
|
||||
count = 3;
|
||||
i = 0;
|
||||
result[j][i+:4] <= repeat(count) @(posedge clk) in;
|
||||
if ($simtime != 0 || result[j] !== 8'bx) begin
|
||||
$display("Failed repeat(3) blocked at %0t, expected 8'hxx, got %h",
|
||||
$simtime, result[j]);
|
||||
pass = 1'b0;
|
||||
end
|
||||
@(result[j]);
|
||||
if ($simtime != 50 || result[j] !== 8'hx0) begin
|
||||
$display("Failed repeat(3) at %0t, expected 8'hx0, got %h",
|
||||
$simtime, result[j]);
|
||||
pass = 1'b0;
|
||||
end
|
||||
|
||||
#15;
|
||||
count = 0;
|
||||
result[j][i+4+:4] <= repeat(count) @(posedge clk) in;
|
||||
@(result[j]); // Reals happen faster so they can use an #0, vectors are slower.
|
||||
if ($simtime != 65 || result[j] !== 8'h30) begin
|
||||
$display("Failed repeat(0) at %0t, expected 8'h30, got %h",
|
||||
$simtime, result[j]);
|
||||
pass = 1'b0;
|
||||
end
|
||||
|
||||
#20;
|
||||
count = -1;
|
||||
result[j][i+5+:4] <= repeat(count) @(posedge clk) in;
|
||||
@(result[j]); // Reals happen faster so they can use an #0, vectors are slower.
|
||||
if ($simtime != 85 || result[j] !== 8'h90) begin
|
||||
$display("Failed repeat(-1) at %0t, expected 8'h80, got %h",
|
||||
$simtime, result[j]);
|
||||
pass = 1'b0;
|
||||
end
|
||||
|
||||
#20;
|
||||
result[j][i+4+:4] <= @(posedge clk) 4'h0;
|
||||
result[j][i+4+:4] <= @(posedge clk) in; // This one sets the final value.
|
||||
@(result[j]);
|
||||
if ($simtime != 110 || result[j] !== 8'h50) begin
|
||||
$display("Failed @ at %0t, expected 8'h50, got %h",
|
||||
$simtime, result[j]);
|
||||
pass = 1'b0;
|
||||
end
|
||||
|
||||
icount = 3'd2;
|
||||
result[j][i+:4] <= @(posedge clk) 4'h1;
|
||||
result[j][i+4+:4] <= repeat(icount) @(posedge clk) 4'h2;
|
||||
result[j][i+1-:4] <= repeat(3) @(posedge clk) 4'h3;
|
||||
@(result[j]);
|
||||
if ($simtime != 130 || result[j] !== 8'h51) begin
|
||||
$display("Failed first @ at %0t, expected 8'h51, got %h",
|
||||
$simtime, result[j]);
|
||||
pass = 1'b0;
|
||||
end
|
||||
@(result[j]);
|
||||
if ($simtime != 150 || result[j] !== 8'h21) begin
|
||||
$display("Failed second @ at %0t, expected 8'h21, got %h",
|
||||
$simtime, result[j]);
|
||||
pass = 1'b0;
|
||||
end
|
||||
@(result[j]);
|
||||
if ($simtime != 170 || result[j] !== 8'h20) begin
|
||||
$display("Failed third @ at %0t, expected 8'h20, got %h",
|
||||
$simtime, result[j]);
|
||||
pass = 1'b0;
|
||||
end
|
||||
|
||||
if (pass) $display("PASSED");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
// Check that non-blocking event control assignments to concatanations work as
|
||||
// expected.
|
||||
|
||||
module test;
|
||||
reg failed = 1'b0;
|
||||
|
||||
`define check(val, exp) \
|
||||
if (val !== exp) begin \
|
||||
$display("FAILED. %s: expected %b, got %b.", `"val`", exp, val); \
|
||||
failed = 1'b1; \
|
||||
end
|
||||
|
||||
reg [3:0] x;
|
||||
reg [3:0] y;
|
||||
reg [3:0] z[1:0];
|
||||
|
||||
integer i = 0;
|
||||
event e;
|
||||
|
||||
initial begin
|
||||
// Test all of
|
||||
// * vector
|
||||
// * vector part select
|
||||
// * array element
|
||||
// * array element part
|
||||
|
||||
// Immediate index
|
||||
{z[1][1:0],z[0],y[1:0],x} <= @e 12'h5a5;
|
||||
#1
|
||||
// Assignment must not occur until the event is triggered
|
||||
`check(z[1], 4'bxxxx)
|
||||
`check(z[0], 4'bxxxx)
|
||||
`check(y, 4'bxxxx)
|
||||
`check(x, 4'bxxxx)
|
||||
|
||||
->e;
|
||||
`check(z[1], 4'bxx01);
|
||||
`check(z[0], 4'b0110);
|
||||
`check(y, 4'bxx10);
|
||||
`check(x, 4'b0101);
|
||||
|
||||
x = 4'hx;
|
||||
y = 4'hx;
|
||||
z[0] = 4'hx;
|
||||
z[1] = 4'hx;
|
||||
|
||||
// Immediate index reverse order
|
||||
{x,y[1:0],z[0],z[1][1:0]} <= @e 12'ha5a;
|
||||
#1
|
||||
`check(z[1], 4'bxxxx)
|
||||
`check(z[0], 4'bxxxx)
|
||||
`check(y, 4'bxxxx)
|
||||
`check(x, 4'bxxxx)
|
||||
|
||||
->e;
|
||||
`check(z[1], 4'bxx10);
|
||||
`check(z[0], 4'b0110);
|
||||
`check(y, 4'bxx01);
|
||||
`check(x, 4'b1010);
|
||||
|
||||
x = 4'hx;
|
||||
y = 4'hx;
|
||||
z[0] = 4'hx;
|
||||
z[1] = 4'hx;
|
||||
|
||||
// Variable index
|
||||
{z[i+1][i+:2],z[i],y[i+:2],x} <= @e 12'h5a5;
|
||||
#1
|
||||
`check(z[1], 4'bxxxx)
|
||||
`check(z[0], 4'bxxxx)
|
||||
`check(y, 4'bxxxx)
|
||||
`check(x, 4'bxxxx)
|
||||
|
||||
->e;
|
||||
`check(z[1], 4'bxx01);
|
||||
`check(z[0], 4'b0110);
|
||||
`check(y, 4'bxx10);
|
||||
`check(x, 4'b0101);
|
||||
|
||||
x = 4'hx;
|
||||
y = 4'hx;
|
||||
z[0] = 4'hx;
|
||||
z[1] = 4'hx;
|
||||
|
||||
// Variable index reverse order
|
||||
{x,y[i+:2],z[i],z[i+1][i+:2]} <= @e 12'ha5a;
|
||||
#1
|
||||
`check(z[1], 4'bxxxx)
|
||||
`check(z[0], 4'bxxxx)
|
||||
`check(y, 4'bxxxx)
|
||||
`check(x, 4'bxxxx)
|
||||
|
||||
->e;
|
||||
`check(z[1], 4'bxx10);
|
||||
`check(z[0], 4'b0110);
|
||||
`check(y, 4'bxx01);
|
||||
`check(x, 4'b1010);
|
||||
|
||||
if (!failed) begin
|
||||
$display("PASSED");
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -185,6 +185,7 @@ ca_time_smtm normal ivltests gold=ca_time_smtm.gold
|
|||
nb_array_pv normal ivltests
|
||||
nb_ec_array normal ivltests
|
||||
nb_ec_array_pv normal ivltests
|
||||
nb_ec_array_pv2 normal ivltests
|
||||
nb_ec_pv normal ivltests
|
||||
nb_ec_pv2 normal ivltests
|
||||
nb_ec_real normal ivltests
|
||||
|
|
|
|||
|
|
@ -676,6 +676,7 @@ muxtest normal ivltests # Validates that X sel and inputs same, output not X
|
|||
named_event_no_edges CE ivltests
|
||||
nb_assign normal ivltests
|
||||
nb_delay normal ivltests
|
||||
nb_ec_concat normal ivltests
|
||||
nblkorder normal ivltests # Validates Non-blocking order determinism
|
||||
negative_genvar normal ivltests
|
||||
negvalue normal ivltests gold=negvalue.gold
|
||||
|
|
|
|||
|
|
@ -179,6 +179,8 @@ static void assign_to_array_word(ivl_signal_t lsig, ivl_expr_t word_ix,
|
|||
/* If needed use the global error state. */
|
||||
if (part_off_ex) {
|
||||
fprintf(vvp_out, " %%flag_mov 4, %d;\n", error_flag);
|
||||
fprintf(vvp_out, " %%ix/mov 3, %d;\n", word_ix_reg);
|
||||
clr_word(word_ix_reg);
|
||||
}
|
||||
fprintf(vvp_out, " %%assign/vec4/a/e v%p, %d;\n", lsig, part_off_reg);
|
||||
|
||||
|
|
@ -203,8 +205,6 @@ static void assign_to_array_word(ivl_signal_t lsig, ivl_expr_t word_ix,
|
|||
clr_word(delay_index);
|
||||
}
|
||||
|
||||
if (nevents != 0) fprintf(vvp_out, " %%evctl/c;\n");
|
||||
|
||||
clr_flag(error_flag);
|
||||
if (part_off_reg)
|
||||
clr_word(part_off_reg);
|
||||
|
|
@ -279,7 +279,6 @@ static void assign_to_lvector(ivl_lval_t lval,
|
|||
draw_eval_expr_into_integer(part_off_ex, offset_index);
|
||||
fprintf(vvp_out, " %s/vec4/off/e v%p_%lu, %d;\n",
|
||||
assign_op, sig, use_word, offset_index);
|
||||
fprintf(vvp_out, " %%evctl/c;\n");
|
||||
|
||||
clr_word(offset_index);
|
||||
|
||||
|
|
@ -312,7 +311,6 @@ static void assign_to_lvector(ivl_lval_t lval,
|
|||
fprintf(vvp_out, " %%flag_set/imm 4, 0;\n");
|
||||
fprintf(vvp_out, " %s/vec4/off/e v%p_%lu, %d;\n",
|
||||
assign_op, sig, use_word, offset_index);
|
||||
fprintf(vvp_out, " %%evctl/c;\n");
|
||||
clr_word(offset_index);
|
||||
|
||||
} else {
|
||||
|
|
@ -346,8 +344,6 @@ static void assign_to_lvector(ivl_lval_t lval,
|
|||
/* Event control delay... */
|
||||
fprintf(vvp_out, " %s/vec4/e v%p_%lu;\n",
|
||||
assign_op, sig, use_word);
|
||||
fprintf(vvp_out, " %%evctl/c;\n");
|
||||
|
||||
} else {
|
||||
/*
|
||||
* The %assign can only take a 32 bit delay. For a larger
|
||||
|
|
@ -593,6 +589,9 @@ static int show_stmt_assign_nb(ivl_statement_t net)
|
|||
}
|
||||
}
|
||||
|
||||
if (nevents)
|
||||
fprintf(vvp_out, " %%evctl/c;\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1349,8 +1349,6 @@ bool of_ASSIGN_VEC4E(vthread_t thr, vvp_code_t cp)
|
|||
schedule_evctl(ptr, value, 0, sig->value_size(), thr->event, thr->ecount);
|
||||
}
|
||||
|
||||
thr->event = 0;
|
||||
thr->ecount = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue