mirror of
https://github.com/YosysHQ/yosys
synced 2025-05-10 17:25:49 +00:00
Merge 068dd77a14
into 5aa9bfbf7d
This commit is contained in:
commit
3e1fbe3a42
14 changed files with 72 additions and 103 deletions
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
@ -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");
|
||||
|
@ -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++) {
|
||||
|
@ -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") {
|
||||
|
@ -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));
|
||||
|
@ -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:;
|
||||
}
|
||||
|
||||
|
@ -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)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -310,8 +339,7 @@ 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)
|
||||
|
@ -319,14 +347,12 @@ struct CheckPass : public Pass {
|
|||
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();
|
||||
|
@ -405,8 +431,7 @@ struct CheckPass : public Pass {
|
|||
|
||||
prev = bit;
|
||||
}
|
||||
log_warning("%s", message.c_str());
|
||||
counter++;
|
||||
bad(message.c_str());
|
||||
}
|
||||
|
||||
if (initdrv)
|
||||
|
@ -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)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
module d_ff_gates(d,clk,q,q_bar);
|
||||
input d,clk;
|
||||
output q, q_bar;
|
||||
|
||||
wire n1,n2,n3,q_bar_n;
|
||||
wire cn,dn,n4,n5,n6;
|
||||
|
||||
// First Latch
|
||||
not (n1,d);
|
||||
|
||||
nand (n2,d,clk);
|
||||
nand (n3,n1,clk);
|
||||
|
||||
nand (dn,q_bar_n,n2);
|
||||
nand (q_bar_n,dn,n3);
|
||||
|
||||
// Second Latch
|
||||
not (cn,clk);
|
||||
|
||||
not (n4,dn);
|
||||
|
||||
nand (n5,dn,cn);
|
||||
nand (n6,n4,cn);
|
||||
|
||||
nand (q,q_bar,n5);
|
||||
nand (q_bar,q,n6);
|
||||
|
||||
|
||||
endmodule
|
|
@ -1,15 +0,0 @@
|
|||
module d_latch_gates(d,clk,q,q_bar);
|
||||
input d,clk;
|
||||
output q, q_bar;
|
||||
|
||||
wire n1,n2,n3;
|
||||
|
||||
not (n1,d);
|
||||
|
||||
nand (n2,d,clk);
|
||||
nand (n3,n1,clk);
|
||||
|
||||
nand (q,q_bar,n2);
|
||||
nand (q_bar,q,n3);
|
||||
|
||||
endmodule
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
@ -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];
|
||||
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue