mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-11-03 21:09:12 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			108 lines
		
	
	
	
		
			1.8 KiB
		
	
	
	
		
			Verilog
		
	
	
	
	
	
			
		
		
	
	
			108 lines
		
	
	
	
		
			1.8 KiB
		
	
	
	
		
			Verilog
		
	
	
	
	
	
`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
 |