Add --no-order-clock-delay to work around bug613.

This commit is contained in:
Wilson Snyder 2013-09-30 16:52:43 -04:00
parent d2b007005d
commit 27686d8c2f
7 changed files with 168 additions and 1 deletions

View File

@ -6,6 +6,8 @@ indicates the contributor was also the author of the fix; Thanks!
* Verilator 3.853 devel
**** Add --no-order-clock-delay to work around bug613. [Charlie Brej]
* Verilator 3.852 2013-09-29

View File

@ -299,6 +299,7 @@ descriptions in the next sections for more information.
-O3 High performance optimizations
-O<optimization-letter> Selectable optimizations
-o <executable> Name of final executable
--no-order-clock-delay Disable ordering clock enable assignments
--output-split <bytes> Split .cpp files into pieces
--output-split-cfuncs <statements> Split .cpp functions
--output-split-ctrace <statements> Split tracing functions
@ -789,6 +790,12 @@ mappings of optimizations to -O letters.
Specify the name for the final executable built if using --exe. Defaults
to the --prefix if not specified.
=item --no-order-clock-delay
Rarely needed. Disables a bug fix for ordering of clock enables with
delayed assignments. This flag should only be used when suggested by the
developers.
=item --output-split I<bytes>
Enables splitting the output .cpp/.sp files into multiple outputs. When a

View File

@ -738,6 +738,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char
else if ( onoff (sw, "-l2name", flag/*ref*/) ) { m_l2Name = flag; }
else if ( onoff (sw, "-lint-only", flag/*ref*/) ) { m_lintOnly = flag; }
else if ( !strcmp (sw, "-no-pins64") ) { m_pinsBv = 33; }
else if ( onoff (sw, "-order-clock-delay", flag/*ref*/) ) { m_orderClockDly = flag; }
else if ( !strcmp (sw, "-pins64") ) { m_pinsBv = 65; }
else if ( onoff (sw, "-pins-sc-uint", flag/*ref*/) ){ m_pinsScUint = flag; if (!m_pinsScBigUint) m_pinsBv = 65; }
else if ( onoff (sw, "-pins-sc-biguint", flag/*ref*/) ){ m_pinsScBigUint = flag; m_pinsBv = 513; }
@ -1203,6 +1204,7 @@ V3Options::V3Options() {
m_lintOnly = false;
m_makeDepend = true;
m_makePhony = false;
m_orderClockDly = true;
m_outFormatOk = false;
m_warnFatal = true;
m_pinsBv = 65;

View File

@ -74,6 +74,7 @@ class V3Options {
bool m_inhibitSim; // main switch: --inhibit-sim
bool m_l2Name; // main switch: --l2name
bool m_lintOnly; // main switch: --lint-only
bool m_orderClockDly;// main switch: --order-clock-delay
bool m_outFormatOk; // main switch: --cc, --sc or --sp was specified
bool m_warnFatal; // main switch: --warnFatal
bool m_pinsScUint; // main switch: --pins-sc-uint
@ -214,6 +215,7 @@ class V3Options {
bool trace() const { return m_trace; }
bool traceDups() const { return m_traceDups; }
bool traceUnderscore() const { return m_traceUnderscore; }
bool orderClockDly() const { return m_orderClockDly; }
bool outFormatOk() const { return m_outFormatOk; }
bool keepTempFiles() const { return (V3Error::debugDefault()!=0); }
bool warnFatal() const { return m_warnFatal; }

View File

@ -1161,7 +1161,11 @@ void OrderVisitor::processCircular() {
// it is generated by delayed assignment, we need the loop. If
// it is combinatorial, we do not (and indeed it will break
// other tests such as t_gated_clk_1.
if (vvertexp->isDelayed()) {
if (!v3Global.opt.orderClockDly()) {
UINFO(5,"Circular Clock, no-order-clock-delay "<<vvertexp<<endl);
nodeMarkCircular(vvertexp, NULL);
}
else if (vvertexp->isDelayed()) {
UINFO(5,"Circular Clock, delayed "<<vvertexp<<endl);
nodeMarkCircular(vvertexp, NULL);
}

View File

@ -0,0 +1,19 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003-2009 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
compile (
verilator_flags2=>["-no-order-clock-delay"],
);
execute (
check_finished => 1
);
ok(1);
1;

View File

@ -0,0 +1,131 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2005 by Wilson Snyder.
module t (clk);
input clk;
reg [0:0] d1;
reg [2:0] d3;
reg [7:0] d8;
wire [0:0] q1;
wire [2:0] q3;
wire [7:0] q8;
// verilator lint_off UNOPTFLAT
reg ena;
// verilator lint_on UNOPTFLAT
condff #(12) condff
(.clk(clk), .sen(1'b0), .ena(ena),
.d({d8,d3,d1}),
.q({q8,q3,q1}));
integer cyc; initial cyc=1;
always @ (posedge clk) begin
if (cyc!=0) begin
//$write("%x %x %x %x\n", cyc, q8, q3, q1);
cyc <= cyc + 1;
if (cyc==1) begin
d1 <= 1'b1; d3<=3'h1; d8<=8'h11;
ena <= 1'b1;
end
if (cyc==2) begin
d1 <= 1'b0; d3<=3'h2; d8<=8'h33;
ena <= 1'b0;
end
if (cyc==3) begin
d1 <= 1'b1; d3<=3'h3; d8<=8'h44;
ena <= 1'b1;
// PROPER ANSWER is 8'h11, but we are negative-testing
//if (q8 != 8'h11) $stop;
if (q8 != 8'h33) $stop;
end
if (cyc==4) begin
d1 <= 1'b1; d3<=3'h4; d8<=8'h77;
ena <= 1'b1;
// PROPER ANSWER is 8'h11, but we are negative-testing
//if (q8 != 8'h11) $stop;
if (q8 != 8'h33) $stop;
end
if (cyc==5) begin
d1 <= 1'b1; d3<=3'h0; d8<=8'h88;
ena <= 1'b1;
// PROPER ANSWER is 8'h44, but we are negative-testing
//if (q8 != 8'h44) $stop;
end
if (cyc==6) begin
// PROPER ANSWER is 8'h77, but we are negative-testing
//if (q8 != 8'h77) $stop;
end
if (cyc==7) begin
// PROPER ANSWER is 8'h88, but we are negative-testing
//if (q8 != 8'h88) $stop;
end
//
if (cyc==20) begin
$write("*-* All Finished *-*\n");
$finish;
end
end
end
endmodule
module condff (clk, sen, ena, d, q);
parameter WIDTH = 1;
input clk;
input sen;
input ena;
input [WIDTH-1:0] d;
output [WIDTH-1:0] q;
condffimp #(.WIDTH(WIDTH))
imp (.clk(clk), .sen(sen), .ena(ena), .d(d), .q(q));
endmodule
module condffimp (clk, sen, ena, d, q);
parameter WIDTH = 1;
input clk;
input sen;
input ena;
input [WIDTH-1:0] d;
output reg [WIDTH-1:0] q;
wire gatedclk;
clockgate clockgate (.clk(clk), .sen(sen), .ena(ena), .gatedclk(gatedclk));
always @(posedge gatedclk) begin
if (gatedclk === 1'bX) begin
q <= {WIDTH{1'bX}};
end
else begin
q <= d;
end
end
endmodule
module clockgate (clk, sen, ena, gatedclk);
input clk;
input sen;
input ena;
output gatedclk;
reg ena_b;
wire gatedclk = clk & ena_b;
// verilator lint_off COMBDLY
always @(clk or ena or sen) begin
if (~clk) begin
ena_b <= ena | sen;
end
else begin
if ((clk^sen)===1'bX) ena_b <= 1'bX;
end
end
// verilator lint_on COMBDLY
endmodule