Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions kernel/log.cc
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,16 @@ void log_file_error(const string &filename, int lineno,
logv_file_error(filename, lineno, format, ap);
}

std::string fmt(const char *format, ...)
{
std::string s;
va_list ap;
va_start(ap, format);
s = vstringf(format, ap);
va_end(ap);
return s;
}

void log(const char *format, ...)
{
va_list ap;
Expand Down
1 change: 1 addition & 0 deletions kernel/log.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ void logv_warning_noprefix(const char *format, va_list ap);
[[noreturn]] void logv_error(const char *format, va_list ap);
[[noreturn]] void logv_file_error(const string &filename, int lineno, const char *format, va_list ap);

std::string fmt(const char *format, ...) YS_ATTRIBUTE(format(printf, 1, 2));
void log(const char *format, ...) YS_ATTRIBUTE(format(printf, 1, 2));
void log_header(RTLIL::Design *design, const char *format, ...) YS_ATTRIBUTE(format(printf, 2, 3));
void log_warning(const char *format, ...) YS_ATTRIBUTE(format(printf, 1, 2));
Expand Down
69 changes: 49 additions & 20 deletions passes/cmds/check.cc
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN

struct CheckPass : public Pass {
enum Mode {
Permissive,
Smart,
Assert,
};
CheckPass() : Pass("check", "check for obvious problems in the design") { }
void help() override
{
Expand Down Expand Up @@ -59,6 +64,10 @@ struct CheckPass : public Pass {
log(" -assert\n");
log(" produce a runtime error if any problems are found in the current design\n");
log("\n");
log(" -permissive\n");
log(" treat even severe problems as just warnings.\n");
log(" Used to be the default behavior\n");
log("\n");
log(" -force-detailed-loop-check\n");
log(" for the detection of combinatorial loops, use a detailed connectivity\n");
log(" model for all internal cells for which it is available. This disables\n");
Expand All @@ -68,14 +77,27 @@ struct CheckPass : public Pass {
}
void execute(std::vector<std::string> args, RTLIL::Design *design) override
{
// Number of all problems (warnings and errors)
int counter = 0;
bool noinit = false;
bool initdrv = false;
bool mapped = false;
bool allow_tbuf = false;
bool assert_mode = false;
bool force_detailed_loop_check = false;
bool suggest_detail = false;
Mode mode = Mode::Smart;
if (design->scratchpad_get_bool("check.permissive"))
mode = Mode::Permissive;
// log_error always terminates and it's a huge hassle to refactor
std::vector<std::string> errors;
std::function<void(std::string)> bad = [&errors, &counter](std::string message) {
counter++;
errors.push_back(message);
};
std::function<void(std::string)> warn = [&counter](std::string message) {
counter++;
log_warning("%s", message.c_str());
};

size_t argidx;
for (argidx = 1; argidx < args.size(); argidx++) {
Expand All @@ -95,8 +117,12 @@ struct CheckPass : public Pass {
allow_tbuf = true;
continue;
}
if (args[argidx] == "-permissive") {
mode = Mode::Permissive;
continue;
}
if (args[argidx] == "-assert") {
assert_mode = true;
mode = Mode::Assert;
continue;
}
if (args[argidx] == "-force-detailed-loop-check") {
Expand All @@ -109,6 +135,11 @@ struct CheckPass : public Pass {

log_header(design, "Executing CHECK pass (checking for obvious problems).\n");

if (mode == Mode::Permissive)
bad = warn;
if (mode == Mode::Assert)
warn = bad;

for (auto module : design->selected_whole_modules_warn())
{
log("Checking module %s...\n", log_id(module));
Expand Down Expand Up @@ -246,8 +277,7 @@ struct CheckPass : public Pass {
{
if (mapped && cell->type.begins_with("$") && design->module(cell->type) == nullptr) {
if (allow_tbuf && cell->type == ID($_TBUF_)) goto cell_allowed;
log_warning("Cell %s.%s is an unmapped internal cell of type %s.\n", log_id(module), log_id(cell), log_id(cell->type));
counter++;
warn(fmt("Cell %s.%s is an unmapped internal cell of type %s.\n", log_id(module), log_id(cell), log_id(cell->type)));
cell_allowed:;
}

Expand Down Expand Up @@ -299,8 +329,7 @@ struct CheckPass : public Pass {
if (initval[i] == State::S0 || initval[i] == State::S1)
init_bits.insert(sigmap(SigBit(wire, i)));
if (noinit) {
log_warning("Wire %s.%s has an unprocessed 'init' attribute.\n", log_id(module), log_id(wire));
counter++;
warn(fmt("Wire %s.%s has an unprocessed 'init' attribute.\n", log_id(module), log_id(wire)));
}
}
}
Expand All @@ -310,23 +339,20 @@ struct CheckPass : public Pass {
string message = stringf("Drivers conflicting with a constant %s driver:\n", log_signal(state));
for (auto str : wire_drivers[state])
message += stringf(" %s\n", str.c_str());
log_warning("%s", message.c_str());
counter++;
bad(message);
}

for (auto it : wire_drivers)
if (wire_drivers_count[it.first] > 1) {
string message = stringf("multiple conflicting drivers for %s.%s:\n", log_id(module), log_signal(it.first));
for (auto str : it.second)
message += stringf(" %s\n", str.c_str());
log_warning("%s", message.c_str());
counter++;
bad(message);
}

for (auto bit : used_wires)
if (!wire_drivers.count(bit)) {
log_warning("Wire %s.%s is used but has no driver.\n", log_id(module), log_signal(bit));
counter++;
warn(fmt("Wire %s.%s is used but has no driver.\n", log_id(module), log_signal(bit)));
}

topo.sort();
Expand Down Expand Up @@ -386,7 +412,7 @@ struct CheckPass : public Pass {

message += stringf(" cell %s (%s)%s\n", log_id(driver), log_id(driver->type), driver_src.c_str());

if (!coarsened_cells.count(driver)) {
if (!coarsened_cells.count(driver)) {
MatchingEdgePrinter printer(message, sigmap, prev, bit);
printer.add_edges_from_cell(driver);
} else {
Expand All @@ -400,13 +426,12 @@ struct CheckPass : public Pass {
std::string src_attr = wire->get_src_attribute();
wire_src = stringf(" source: %s", src_attr.c_str());
}
message += stringf(" wire %s%s\n", log_signal(SigBit(wire, pair.second)), wire_src.c_str());
message += stringf(" wire %s%s\n", log_signal(SigBit(wire, pair.second)), wire_src.c_str());
}

prev = bit;
}
log_warning("%s", message.c_str());
counter++;
bad(message.c_str());
}

if (initdrv)
Expand All @@ -424,8 +449,7 @@ struct CheckPass : public Pass {
init_sig.sort_and_unify();

for (auto chunk : init_sig.chunks()) {
log_warning("Wire %s.%s has 'init' attribute and is not driven by an FF cell.\n", log_id(module), log_signal(chunk));
counter++;
warn(fmt("Wire %s.%s has 'init' attribute and is not driven by an FF cell.\n", log_id(module), log_signal(chunk)));
}
}
}
Expand All @@ -435,8 +459,13 @@ struct CheckPass : public Pass {
if (suggest_detail)
log("Consider re-running with '-force-detailed-loop-check' to rule out false positives.\n");

if (assert_mode && counter > 0)
log_error("Found %d problems in 'check -assert'.\n", counter);
if (errors.size()) {
std::string err_message;
for (auto error : errors)
err_message += error + "\n";
err_message += fmt("Found %zu severe problems in 'check'.\n", errors.size());
log_error("%s", err_message.c_str());
}
}
} CheckPass;

Expand Down
2 changes: 0 additions & 2 deletions passes/cmds/logger.cc
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,6 @@ struct LoggerPass : public Pass {
std::string type = args[++argidx];
if (type!="error" && type!="warning" && type!="log")
log_cmd_error("Expect command require type to be 'log', 'warning' or 'error' !\n");
if (type=="error" && log_expect_error.size()>0)
log_cmd_error("Only single error message can be expected !\n");
std::string pattern = args[++argidx];
if (pattern.front() == '\"' && pattern.back() == '\"') pattern = pattern.substr(1, pattern.size() - 2);
int count = atoi(args[++argidx].c_str());
Expand Down
29 changes: 0 additions & 29 deletions tests/asicworld/code_hdl_models_d_ff_gates.v

This file was deleted.

15 changes: 0 additions & 15 deletions tests/asicworld/code_hdl_models_d_latch_gates.v

This file was deleted.

25 changes: 0 additions & 25 deletions tests/hana/test_intermout.v
Original file line number Diff line number Diff line change
Expand Up @@ -182,31 +182,6 @@ assign w2 = w1;
assign out = w2;
endmodule


// test_intermout_bufrm_7_test.v
module f15_test(in1, in2, out);
input in1, in2;
output out;
// Y with cluster of f15_mybuf instances at the junction

wire w1, w2, w3, w4, w5, w6, w7, w8, w9, w10;
assign w1 = in1;
assign w2 = w1;
assign w5 = in2;
assign w6 = w5;
assign w10 = w9;
assign out = w10;

f15_mybuf _f15_mybuf0(w2, w3);
f15_mybuf _f15_mybuf1(w3, w4);

f15_mybuf _f15_mybuf2(w6, w7);
f15_mybuf _f15_mybuf3(w7, w4);

f15_mybuf _f15_mybuf4(w4, w8);
f15_mybuf _f15_mybuf5(w8, w9);
endmodule

module f15_mybuf(in, out);
input in;
output out;
Expand Down
2 changes: 1 addition & 1 deletion tests/memories/wide_all.v
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ module test(
reg [7:0] mem[3:254];

assign rd[7:0] = mem[{ra, 1'b0}];
assign rd[15:0] = mem[{ra, 1'b1}];
assign rd[15:8] = mem[{ra, 1'b1}];

initial begin
mem[5] = 8'h12;
Expand Down
4 changes: 3 additions & 1 deletion tests/simple_abc9/abc9.v
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ module abc9_test008_sub(input a, output b);
assign b = ~a;
endmodule

scratchpad -set check.permissive true
module abc9_test009(inout io, input oe);
reg latch;
always @(io or oe)
Expand Down Expand Up @@ -80,7 +81,7 @@ assign io = oe ? ~latch : 8'bz;
endmodule

module abc9_test013(inout [3:0] io, input oe);
reg [3:0] latch;
reg [7:0] latch;
always @(io or oe)
if (!oe)
latch[3:0] <= io[3:0];
Expand All @@ -104,6 +105,7 @@ always @(io or oe)
assign io[3:0] = oe ? ~latch[3:0] : 4'bz;
assign io[7:4] = !oe ? {latch[4], latch[7:3]} : 4'bz;
endmodule
scratchpad -set check.permissive false

module abc9_test015(input a, output b, input c);
assign b = ~a;
Expand Down
4 changes: 1 addition & 3 deletions tests/various/check_2.ys
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,5 @@ module top(input clk, input a, input b, output [9:0] x);
endmodule
EOF
hierarchy -top top
logger -expect error "found logic loop in module top:" 1
prep
logger -expect warning "found logic loop in module top:" 1
logger -expect error "Found 1 problems in 'check -assert'" 1
check -assert
5 changes: 2 additions & 3 deletions tests/various/check_3.ys
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ module pingpong(input wire [1:0] x, output wire [3:0] y1, output wire [3:0] y2);
endmodule
EOF
hierarchy -top pingpong
logger -expect error "found logic loop in module pingpong:" 1
logger -expect error "Found [0-9]+ severe problems in 'check'" 1
prep
logger -nowarn "found logic loop in module pingpong:"
logger -expect error "Found [0-9]+ problems in 'check -assert'" 1
check -assert
2 changes: 1 addition & 1 deletion tests/various/check_4.ys
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,5 @@ opt -keepdc
memory_dff
opt_clean
logger -nowarn "found logic loop in module pingpong:"
logger -expect error "Found [0-9]+ problems in 'check -assert'" 1
logger -expect error "Found [0-9]+ severe problems in 'check'" 1
check -assert
6 changes: 3 additions & 3 deletions tests/various/constant_drive_conflict.ys
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ EOT

hierarchy -top top; proc

logger -expect warning "Drivers conflicting with a constant" 1
logger -expect error "Drivers conflicting with a constant" 1
logger -expect log "Found and reported 1 problems." 1
check
logger -check-expected
Expand All @@ -26,7 +26,7 @@ EOT

hierarchy -top top; proc

logger -expect warning "Drivers conflicting with a constant" 1
logger -expect error "Drivers conflicting with a constant" 1
logger -expect log "Found and reported 1 problems." 1
check
logger -check-expected
Expand All @@ -45,7 +45,7 @@ EOT

hierarchy -top top

logger -expect warning "Drivers conflicting with a constant" 1
logger -expect error "Drivers conflicting with a constant" 1
logger -expect log "Found and reported 1 problems." 1
check
logger -check-expected
1 change: 1 addition & 0 deletions tests/various/dynamic_part_select.ys
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ design -copy-from gate -as gate gate
miter -equiv -make_assert -make_outcmp -flatten gold gate equiv
sat -prove-asserts -show-public -verify -set-init-zero equiv

scratchpad -set check.permissive true
###
## Part select with obvious latch, expected to fail due comparison with old shift&mask AST transformation
design -reset
Expand Down
Loading