Commentary, Closes #2177.

This commit is contained in:
Wilson Snyder 2020-03-05 19:09:58 -05:00
parent dab1cb610a
commit c108f5def9
4 changed files with 50 additions and 37 deletions

View File

@ -1936,6 +1936,39 @@ when your source changes it will automatically run all of these steps. See
the examples directory in the distribution.
=head1 EVALUATION LOOP
When using SystemC, when Verilator is evaluated is managed by the SystemC
kernel, and for the most part can be ignored. When using C++, the user
must call eval(), or eval_step() and eval_end_step().
1. When there is a single design instantiated at the C++ level that need to
evaluate, just call designp->eval().
2. When there are multiple designs instantiated each at the C++ level that
need to evaluate, call first_designp->eval_step() then ->eval_step() on all
other designs. Then call ->eval_end_step() on the first design then all
other designs. If there is only a single design, you would call
eval_step() then eval_end_step(); in fact eval() described above is just a
wrapper which calls these two functions.
When eval() is called Verilator looks for changes in clock signals and
evaluates related sequential always blocks, such as computing always_ff @
(posedge...) outputs. Then Verilator evaluates combinatorial logic.
Note combinatorial logic is not computed before sequential always blocks
are computed (for speed reasons). Therefore it is best to set any non-clock
inputs up with a separate eval() call before changing clocks().
Alternatively, if all always_ff statements use only the posedge of clocks,
or all inputs go directly to always_ff statements, as is typical, then you
can change non-clock inputs on the negative edge of the input clock, which
will be faster as there will be fewer eval() calls.
For more information on evaluation, see docs/internals.adoc in the
distribution.
=head1 BENCHMARKING & OPTIMIZATION
For best performance, run Verilator with the "-O3 --x-assign fast
@ -2212,7 +2245,7 @@ example:
Note signals are read and written as member variables of the lower module.
You call the eval() method to evaluate the model. When the simulation is
complete call the final() method to wrap up any SystemVerilog final blocks,
and complete any assertions.
and complete any assertions. See L</"EVALUATION LOOP">.
=head1 CONNECTING TO SYSTEMC
@ -5335,7 +5368,7 @@ L<verilator_coverage>, L<verilator_gantt>, L<verilator_profcfunc>, L<make>,
L<verilator --help> which is the source for this document,
and internals.txt in the distribution.
and docs/internals.adoc in the distribution.
=cut

View File

@ -46,7 +46,6 @@ int main(int argc, char** argv, char** env) {
// Set some inputs
top->reset_l = !0;
top->fastclk = 0;
top->clk = 0;
top->in_small = 1;
top->in_quad = 0x1234;
@ -58,22 +57,22 @@ int main(int argc, char** argv, char** env) {
while (!Verilated::gotFinish()) {
main_time++; // Time passes...
// Toggle clocks and such
top->fastclk = !top->fastclk;
if ((main_time % 10) == 3) {
top->clk = 1;
}
if ((main_time % 10) == 8) {
top->clk = 0;
}
if (main_time > 1 && main_time < 10) {
top->reset_l = !1; // Assert reset
} else {
top->reset_l = !0; // Deassert reset
}
// Toggle a fast (time/2 period) clock
top->clk = !top->clk;
// Assign some other inputs
top->in_quad += 0x12;
// Toggle control signals on an edge that doesn't correspond
// to where the controls are sampled; in this example we do
// this only on a negedge of clk, because we know
// reset is not sampled there.
if (!top->clk) {
if (main_time > 1 && main_time < 10) {
top->reset_l = !1; // Assert reset
} else {
top->reset_l = !0; // Deassert reset
}
// Assign some other inputs
top->in_quad += 0x12;
}
// Evaluate model
// (If you have multiple models being simulated in the same

View File

@ -7,25 +7,10 @@
module sub
(
input clk,
input fastclk,
input reset_l
);
// Example counter/flop
reg [31:0] count_f;
always_ff @ (posedge fastclk) begin
if (!reset_l) begin
/*AUTORESET*/
// Beginning of autoreset for uninitialized flops
count_f <= 32'h0;
// End of automatics
end
else begin
count_f <= count_f + 1;
end
end
// Another example flop
reg [31:0] count_c;
always_ff @ (posedge clk) begin
if (!reset_l) begin
@ -37,8 +22,6 @@ module sub
else begin
count_c <= count_c + 1;
if (count_c >= 3) begin
$display("[%0t] fastclk is %0d times faster than clk\n",
$time, count_f/count_c);
// This write is a magic value the Makefile uses to make sure the
// test completes successfully.
$write("*-* All Finished *-*\n");

View File

@ -11,7 +11,6 @@ module top
(
// Declare some signals so we can see how I/O works
input clk,
input fastclk,
input reset_l,
output wire [1:0] out_small,
@ -31,7 +30,6 @@ module top
sub sub (/*AUTOINST*/
// Inputs
.clk (clk),
.fastclk (fastclk),
.reset_l (reset_l));
// Print some stuff as an example