Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ignore delay statements in processes #46

Merged
merged 2 commits into from
Sep 21, 2024
Merged
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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/build/
.*
!/.git*
13 changes: 12 additions & 1 deletion src/initial_eval.cc
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,9 @@ inline constexpr slang::DiagCode ParallelBlockUnsupported(DiagSubsystem::Netlist
inline constexpr slang::DiagCode TODO(DiagSubsystem::Netlist, 102);
inline constexpr slang::DiagCode BadEvaluation(DiagSubsystem::Netlist, 103);

EvalVisitor::EvalVisitor(Compilation *compilation)
EvalVisitor::EvalVisitor(Compilation *compilation, bool ignore_timing)
: context(ASTContext(compilation->getRoot(), LookupLocation::max), /* HACK */ ast::EvalFlags::IsScript)
, ignore_timing(ignore_timing)
{
context.pushEmptyFrame();
}
Expand Down Expand Up @@ -684,6 +685,16 @@ ER EvalVisitor::visit(const ImmediateAssertionStatement &stmt)
return ER::Success;
}

ER EvalVisitor::visit(const TimedStatement &stmt)
{
if (!ignore_timing) // call unimplemented
return visit(static_cast<const Statement &>(stmt));

// ignore timing and visit inner statement
ER result = stmt.stmt.visit(*this);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can't access SynthesisSettings here unless we make a provision for it. It's okay to ignore timed statements here unconditionally as the initial visitor will be reworked later anyway (it will be folded into the generic procedural visitor)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

got it

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry for the delay in communicating, i was away last week.

i took another look at this last night and it's going to be messy. the problem is that ProceduralVisitor needs access to settings. But Procedural visitor is constructed in multiple contexts that then would also need access to settings and so on. Adding further constructor arguments, which are in some cases a pretty long list, to all of these seems clunky. i'd be adding 10-20 lines of boilerplate to forward a bool to a single line of code. so i stopped for the moment to see if you had any thoughts.

do you have a better way to do this? is this what you want to see?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The visitor already holds a reference to NetlistContext, I think we should add a way to get the settings from that, i.e. a new SynthesisSettings &settings; field

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was in the area so I've made the change in c53bd23

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i was able to rebase on that change and it helped. i was also able to implement the feature in the ER EvalVistor easily enough (even if it is temporary)

i did add a 2nd commit that adds a basic .gitignore if you like it, other wish we can drop it.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, great, .gitignore looks useful

return result;
}

ER EvalVisitor::visit(const EmptyStatement&)
{
return ER::Success;
Expand Down
5 changes: 4 additions & 1 deletion src/initial_eval.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace SlangInitial {
struct EvalVisitor {
public:
slang::ast::EvalContext context;
EvalVisitor(slang::ast::Compilation *compilation);
EvalVisitor(slang::ast::Compilation *compilation, bool ignore_timing = false);

using ER = slang::ast::Statement::EvalResult;

Expand All @@ -33,11 +33,14 @@ struct EvalVisitor {
ER visit(const slang::ast::ForeverLoopStatement &stmt);
ER visit(const slang::ast::ExpressionStatement &stmt);
ER visit(const slang::ast::ImmediateAssertionStatement &stmt);
ER visit(const slang::ast::TimedStatement &stmt);
ER visit(const slang::ast::EmptyStatement &stmt);
ER visit(const slang::ast::Statement &);

// to let clients choose the display handling
virtual void handleDisplay(const slang::ast::CallExpression &call,
const std::vector<slang::ConstantValue> &args);

bool ignore_timing;
};
};
17 changes: 14 additions & 3 deletions src/slang_frontend.cc
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ struct SynthesisSettings {
std::optional<bool> compat_mode;
std::optional<bool> keep_hierarchy;
std::optional<bool> best_effort_hierarchy;
std::optional<bool> ignore_timing;

enum HierMode {
NONE,
Expand All @@ -61,6 +62,8 @@ struct SynthesisSettings {
"Keep hierarchy (experimental; may crash)");
cmdLine.add("--best-effort-hierarchy", best_effort_hierarchy,
"Keep hierarchy in a 'best effort' mode");
cmdLine.add("--ignore-timing", ignore_timing,
"Ignore delays for synthesis");
}
};

Expand Down Expand Up @@ -1236,6 +1239,14 @@ struct ProceduralVisitor : public ast::ASTVisitor<ProceduralVisitor, true, false
}
}

void handle(const ast::TimedStatement &stmt)
{
if (netlist.settings.ignore_timing.value_or(false))
stmt.stmt.visit(*this);
else
unimplemented(stmt);
}

void handle(const ast::Statement &stmt)
{
unimplemented(stmt);
Expand Down Expand Up @@ -1854,8 +1865,8 @@ struct PopulateNetlist : public TimingPatternInterpretor, public ast::ASTVisitor
RTLIL::Module *mod;
int print_priority;

InitialEvalVisitor(ast::Compilation *compilation, RTLIL::Module *mod)
: SlangInitial::EvalVisitor(compilation), mod(mod), print_priority(0) {}
InitialEvalVisitor(ast::Compilation *compilation, RTLIL::Module *mod, bool ignore_timing=false)
: SlangInitial::EvalVisitor(compilation, ignore_timing), mod(mod), print_priority(0) {}

void handleDisplay(const slang::ast::CallExpression &call, const std::vector<slang::ConstantValue> &args) {
auto cell = mod->addCell(NEW_ID, ID($print));
Expand Down Expand Up @@ -1899,7 +1910,7 @@ struct PopulateNetlist : public TimingPatternInterpretor, public ast::ASTVisitor
} initial_eval;

PopulateNetlist(NetlistContext &netlist)
: netlist(netlist), settings(netlist.settings), initial_eval(&netlist.compilation, netlist.canvas) {}
: netlist(netlist), settings(netlist.settings), initial_eval(&netlist.compilation, netlist.canvas, netlist.settings.ignore_timing.value_or(false)) {}

void handle_comb_like_process(const ast::ProceduralBlockSymbol &symbol, const ast::Statement &body)
{
Expand Down
44 changes: 44 additions & 0 deletions tests/various/delays.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
`timescale 1ns/1ps

module top(input wire clk);

wire #10 a;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Huh, you can insert delay statements here?!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

indeed, this is a "net delay", 28.16 in the 2023 LRM. i've sure never used this, i just checked the BNF for where-ever it was possible and where slang might put in some AST node.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agree on settings, will take a little bit to add this. no problem.

wire #(10+0) b;
wire #(10+0, 1+1) c;
wire #(10+0, 1+1, 2+2) d;

assign #10 a = b;
assign #(10+1) b = c;

reg ra, rb;
always @(posedge clk) begin
#1;
#1 ra <= a;
rb <= #1 a;
end

logic la, lb;
always @(*) begin
#10;
#10 la = a;
lb = #10 a;
end

logic lc, ld;
initial begin
#10;
#10 lc = ra;
ld = #10 ra;
end

int foo;

initial begin
#10 foo = 32'h0;
$display(foo);
#10 foo = 32'hdeadbeef;
$display(foo);
end


endmodule
1 change: 1 addition & 0 deletions tests/various/delays.ys
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
read_slang --ignore-timing delays.sv
Loading