Skip to content
Open
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 passes/sat/async2sync.cc
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,10 @@ struct Async2syncPass : public Pass {
initvals.remove_init(ff.sig_q);

Wire *new_d = module->addWire(NEW_ID, ff.width);
new_d->set_src_attribute(cell->get_src_attribute());

Wire *new_q = module->addWire(NEW_ID, ff.width);
new_q->set_src_attribute(cell->get_src_attribute());

SigSpec sig_set = ff.sig_set;
SigSpec sig_clr = ff.sig_clr;
Expand Down Expand Up @@ -199,7 +202,10 @@ struct Async2syncPass : public Pass {
initvals.remove_init(ff.sig_q);

Wire *new_d = module->addWire(NEW_ID, ff.width);
new_d->set_src_attribute(cell->get_src_attribute());

Wire *new_q = module->addWire(NEW_ID, ff.width);
new_q->set_src_attribute(cell->get_src_attribute());

if (ff.pol_aload) {
if (!ff.is_fine) {
Expand Down Expand Up @@ -232,6 +238,7 @@ struct Async2syncPass : public Pass {
initvals.remove_init(ff.sig_q);

Wire *new_q = module->addWire(NEW_ID, ff.width);
new_q->set_src_attribute(cell->get_src_attribute());

if (ff.pol_arst) {
if (!ff.is_fine)
Expand Down Expand Up @@ -266,10 +273,13 @@ struct Async2syncPass : public Pass {
initvals.remove_init(ff.sig_q);

Wire *new_q = module->addWire(NEW_ID, ff.width);
new_q->set_src_attribute(cell->get_src_attribute());

Wire *new_d;

if (ff.has_aload) {
new_d = module->addWire(NEW_ID, ff.width);
new_d->set_src_attribute(cell->get_src_attribute());
if (ff.pol_aload) {
if (!ff.is_fine)
module->addMux(NEW_ID, new_q, ff.sig_ad, ff.sig_aload, new_d);
Expand Down
56 changes: 56 additions & 0 deletions tests/sat/async2sync.ys
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# has_arst path
read_verilog << EOT
module top(input clk, arst, d, output reg q);
always @(posedge clk or posedge arst)
if (arst) q <= 0;
else q <= d;
endmodule
EOT
proc
async2sync
select -assert-count 1 w:$auto$async2sync* a:src=* %i
design -reset

# has_sr path
read_verilog << EOT
module sr(input clk, set, clr, d, output reg q);
always @(posedge clk or posedge set or posedge clr)
if (clr) q <= 0;
else if (set) q <= 1;
else q <= d;
endmodule
EOT
proc
async2sync
select -assert-count 2 w:$auto$async2sync* a:src=* %i
design -reset

# has_aload path
read_verilog << EOT
module aload(input clk, aload, d, ad, output reg q);
always @(posedge clk or posedge aload)
if (aload) q <= ad;
else q <= d;
endmodule
EOT
proc
async2sync
select -assert-count 2 w:$auto$async2sync* a:src=* %i
design -reset

# latch path
read_verilog << EOT
module latch(input en, arst, d, output reg q);
always @(*)
if (arst) q <= 0;
else if (en) q <= d;
endmodule
EOT
proc
async2sync
# latch with async reset path creates 2 wires (new_q + new_d from has_arst handling)
select -assert-count 2 w:$auto$async2sync* a:src=* %i
design -reset
# a latch where has_aload is false (no async load) cannot be tested here
# because proc optimizes it away into muxes before async2sync runs,
# leaving no latch cell for async2sync to process.