| `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 |