mirror of https://github.com/YosysHQ/yosys.git
Merge pull request #1177 from YosysHQ/clifford/async
Fix clk2fflogic adff reset semantic to negative hold time on reset
This commit is contained in:
commit
c66b4b9131
|
@ -253,6 +253,13 @@ struct Clk2fflogicPass : public Pass {
|
||||||
SigSpec qval = module->Mux(NEW_ID, past_q, past_d, clock_edge);
|
SigSpec qval = module->Mux(NEW_ID, past_q, past_d, clock_edge);
|
||||||
Const rstval = cell->parameters["\\ARST_VALUE"];
|
Const rstval = cell->parameters["\\ARST_VALUE"];
|
||||||
|
|
||||||
|
Wire *past_arst = module->addWire(NEW_ID);
|
||||||
|
module->addFf(NEW_ID, arst, past_arst);
|
||||||
|
if (cell->parameters["\\ARST_POLARITY"].as_bool())
|
||||||
|
arst = module->LogicOr(NEW_ID, arst, past_arst);
|
||||||
|
else
|
||||||
|
arst = module->LogicAnd(NEW_ID, arst, past_arst);
|
||||||
|
|
||||||
if (cell->parameters["\\ARST_POLARITY"].as_bool())
|
if (cell->parameters["\\ARST_POLARITY"].as_bool())
|
||||||
module->addMux(NEW_ID, qval, rstval, arst, sig_q);
|
module->addMux(NEW_ID, qval, rstval, arst, sig_q);
|
||||||
else
|
else
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
*.v
|
||||||
|
*.log
|
||||||
|
*.out
|
|
@ -0,0 +1,11 @@
|
||||||
|
#!/bin/bash
|
||||||
|
set -ex
|
||||||
|
../../yosys -q -o async_syn.v -p 'synth; rename uut syn' async.v
|
||||||
|
../../yosys -q -o async_prp.v -p 'prep; rename uut prp' async.v
|
||||||
|
../../yosys -q -o async_a2s.v -p 'prep; async2sync; rename uut a2s' async.v
|
||||||
|
../../yosys -q -o async_ffl.v -p 'prep; clk2fflogic; rename uut ffl' async.v
|
||||||
|
iverilog -o async_sim -DTESTBENCH async.v async_???.v
|
||||||
|
vvp -N async_sim > async.out
|
||||||
|
tail async.out
|
||||||
|
grep PASS async.out
|
||||||
|
rm -f async_???.v async_sim async.out async.vcd
|
|
@ -0,0 +1,108 @@
|
||||||
|
`define MAXQ 2
|
||||||
|
module uut (
|
||||||
|
input clk,
|
||||||
|
input d, r, e,
|
||||||
|
output [`MAXQ:0] q
|
||||||
|
);
|
||||||
|
reg q0;
|
||||||
|
always @(posedge clk) begin
|
||||||
|
if (r)
|
||||||
|
q0 <= 0;
|
||||||
|
else if (e)
|
||||||
|
q0 <= d;
|
||||||
|
end
|
||||||
|
|
||||||
|
reg q1;
|
||||||
|
always @(posedge clk, posedge r) begin
|
||||||
|
if (r)
|
||||||
|
q1 <= 0;
|
||||||
|
else if (e)
|
||||||
|
q1 <= d;
|
||||||
|
end
|
||||||
|
|
||||||
|
reg q2;
|
||||||
|
always @(posedge clk, negedge r) begin
|
||||||
|
if (!r)
|
||||||
|
q2 <= 0;
|
||||||
|
else if (!e)
|
||||||
|
q2 <= d;
|
||||||
|
end
|
||||||
|
|
||||||
|
assign q = {q2, q1, q0};
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
`ifdef TESTBENCH
|
||||||
|
module \$ff #(
|
||||||
|
parameter integer WIDTH = 1
|
||||||
|
) (
|
||||||
|
input [WIDTH-1:0] D,
|
||||||
|
output reg [WIDTH-1:0] Q
|
||||||
|
);
|
||||||
|
wire sysclk = testbench.sysclk;
|
||||||
|
always @(posedge sysclk)
|
||||||
|
Q <= D;
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module testbench;
|
||||||
|
reg sysclk;
|
||||||
|
always #5 sysclk = (sysclk === 1'b0);
|
||||||
|
|
||||||
|
reg clk;
|
||||||
|
always @(posedge sysclk) clk = (clk === 1'b0);
|
||||||
|
|
||||||
|
reg d, r, e;
|
||||||
|
|
||||||
|
wire [`MAXQ:0] q_uut;
|
||||||
|
uut uut (.clk(clk), .d(d), .r(r), .e(e), .q(q_uut));
|
||||||
|
|
||||||
|
wire [`MAXQ:0] q_syn;
|
||||||
|
syn syn (.clk(clk), .d(d), .r(r), .e(e), .q(q_syn));
|
||||||
|
|
||||||
|
wire [`MAXQ:0] q_prp;
|
||||||
|
prp prp (.clk(clk), .d(d), .r(r), .e(e), .q(q_prp));
|
||||||
|
|
||||||
|
wire [`MAXQ:0] q_a2s;
|
||||||
|
a2s a2s (.clk(clk), .d(d), .r(r), .e(e), .q(q_a2s));
|
||||||
|
|
||||||
|
wire [`MAXQ:0] q_ffl;
|
||||||
|
ffl ffl (.clk(clk), .d(d), .r(r), .e(e), .q(q_ffl));
|
||||||
|
|
||||||
|
task printq;
|
||||||
|
reg [5*8-1:0] msg;
|
||||||
|
begin
|
||||||
|
msg = "OK";
|
||||||
|
if (q_uut !== q_syn) msg = "SYN";
|
||||||
|
if (q_uut !== q_prp) msg = "PRP";
|
||||||
|
if (q_uut !== q_a2s) msg = "A2S";
|
||||||
|
if (q_uut !== q_ffl) msg = "FFL";
|
||||||
|
$display("%6t %b %b %b %b %b %s", $time, q_uut, q_syn, q_prp, q_a2s, q_ffl, msg);
|
||||||
|
if (msg != "OK") $finish;
|
||||||
|
end
|
||||||
|
endtask
|
||||||
|
|
||||||
|
initial if(0) begin
|
||||||
|
$dumpfile("async.vcd");
|
||||||
|
$dumpvars(0, testbench);
|
||||||
|
end
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
@(posedge clk);
|
||||||
|
d <= 0;
|
||||||
|
r <= 0;
|
||||||
|
e <= 0;
|
||||||
|
@(posedge clk);
|
||||||
|
e <= 1;
|
||||||
|
@(posedge clk);
|
||||||
|
e <= 0;
|
||||||
|
repeat (10000) begin
|
||||||
|
@(posedge clk);
|
||||||
|
printq;
|
||||||
|
d <= $random;
|
||||||
|
r <= $random;
|
||||||
|
e <= $random;
|
||||||
|
end
|
||||||
|
$display("PASS");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
`endif
|
|
@ -4,11 +4,9 @@ for x in *.ys; do
|
||||||
echo "Running $x.."
|
echo "Running $x.."
|
||||||
../../yosys -ql ${x%.ys}.log $x
|
../../yosys -ql ${x%.ys}.log $x
|
||||||
done
|
done
|
||||||
# Run any .sh files in this directory (with the exception of the file - run-test.sh
|
for s in *.sh; do
|
||||||
shell_tests=$(echo *.sh | sed -e 's/run-test.sh//')
|
if [ "$s" != "run-test.sh" ]; then
|
||||||
if [ "$shell_tests" ]; then
|
echo "Running $s.."
|
||||||
for s in $shell_tests; do
|
bash $s
|
||||||
echo "Running $s.."
|
fi
|
||||||
bash $s
|
done
|
||||||
done
|
|
||||||
fi
|
|
||||||
|
|
Loading…
Reference in New Issue