prompt:
module top_module(
	input clk,
	input reset,
	output reg [3:0] q);

test:
`timescale 1 ps/1 ps
`define OK 12
`define INCORRECT 13
module reference_module(
	input clk,
	input reset,
	output reg [3:0] q);

	always @(posedge clk)
		if (reset || q == 10)
			q <= 1;
		else
			q <= q+1;

endmodule

module stimulus_gen (
	input clk,
	output reg reset,
	output reg[511:0] wavedrom_title,
	output reg wavedrom_enable,
	input tb_match
);

	task reset_test(input async=0);
		bit arfail, srfail, datafail;

		@(posedge clk);
		@(posedge clk) reset <= 0;
		repeat(3) @(posedge clk);

		@(negedge clk) begin datafail = !tb_match ; reset <= 1; end
		@(posedge clk) arfail = !tb_match;
		@(posedge clk) begin
			srfail = !tb_match;
			reset <= 0;
		end
		if (srfail)
			$display("Hint: Your reset doesn't seem to be working.");
		else if (arfail && (async || !datafail))
			$display("Hint: Your reset should be %0s, but doesn't appear to be.", async ? "asynchronous" : "synchronous");
		// Don't warn about synchronous reset if the half-cycle before is already wrong. It's more likely
		// a functionality error than the reset being implemented asynchronously.

	endtask

// Add two ports to module stimulus_gen:
//    output [511:0] wavedrom_title
//    output reg wavedrom_enable

	task wavedrom_start(input[511:0] title = "");
	endtask

	task wavedrom_stop;
		#1;
	endtask

	initial begin
		reset <= 1;
		wavedrom_start("Synchronous reset and counting.");
		reset_test();
		repeat(12) @(posedge clk);
		wavedrom_stop();
		@(posedge clk);

		repeat(400) @(posedge clk, negedge clk) begin
			reset <= !($random & 31);
		end
		#1 $finish;
	end

endmodule

module tb();

	typedef struct packed {
		int errors;
		int errortime;
		int errors_q;
		int errortime_q;

		int clocks;
	} stats;

	stats stats1;

	wire[511:0] wavedrom_title;
	wire wavedrom_enable;
	int wavedrom_hide_after_time;

	reg clk=0;
	initial forever
		#5 clk = ~clk;

	logic reset;
	logic [3:0] q_ref;
	logic [3:0] q_dut;

	initial begin
		$dumpfile("wave.vcd");
		$dumpvars(1, stim1.clk, tb_mismatch ,clk,reset,q_ref,q_dut );
	end

	wire tb_match;		// Verification
	wire tb_mismatch = ~tb_match;

	stimulus_gen stim1 (
		.clk,
		.* ,
		.reset );
	reference_module good1 (
		.clk,
		.reset,
		.q(q_ref) );

	top_module top_module1 (
		.clk,
		.reset,
		.q(q_dut) );

	bit strobe = 0;
	task wait_for_end_of_timestep;
		repeat(5) begin
			strobe <= !strobe;  // Try to delay until the very end of the time step.
			@(strobe);
		end
	endtask

	final begin
		if (stats1.errors_q) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "q", stats1.errors_q, stats1.errortime_q);
		else $display("Hint: Output '%s' has no mismatches.", "q");

		$display("Hint: Total mismatched samples is %1d out of %1d samples\n", stats1.errors, stats1.clocks);
		$display("Simulation finished at %0d ps", $time);
		$display("Mismatches: %1d in %1d samples", stats1.errors, stats1.clocks);
	end

	// Verification: XORs on the right makes any X in good_vector match anything, but X in dut_vector will only match X.
	assign tb_match = ( { q_ref } === ( { q_ref } ^ { q_dut } ^ { q_ref } ) );
	// Use explicit sensitivity list here. @(*) causes NetProc::nex_input() to be called when trying to compute
	// the sensitivity list of the @(strobe) process, which isn't implemented.
	always @(posedge clk, negedge clk) begin

		stats1.clocks++;
		if (!tb_match) begin
			if (stats1.errors == 0) stats1.errortime = $time;
			stats1.errors++;
		end
		if (q_ref !== ( q_ref ^ q_dut ^ q_ref ))
		begin if (stats1.errors_q == 0) stats1.errortime_q = $time;
			stats1.errors_q = stats1.errors_q+1'b1; end

	end
endmodule

detail_description: Make a decade counter that counts 1 through 10, inclusive. The reset input is active high synchronous, and should reset the counter to 1.


prompt:
module top_module (
	input clk,
	input in,
	output logic out
);

test:
`timescale 1 ps/1 ps
`define OK 12
`define INCORRECT 13
module reference_module (
	input clk,
	input in,
	output logic out
);

	initial
		out = 0;

	always@(posedge clk) begin
		out <= in ^ out;
	end

endmodule

module stimulus_gen (
	input clk,
	output logic in
);

	initial begin
		repeat(100) @(posedge clk, negedge clk) begin
			in <= $random;
		end

		#1 $finish;
	end

endmodule

module tb();

	typedef struct packed {
		int errors;
		int errortime;
		int errors_out;
		int errortime_out;

		int clocks;
	} stats;

	stats stats1;

	wire[511:0] wavedrom_title;
	wire wavedrom_enable;
	int wavedrom_hide_after_time;

	reg clk=0;
	initial forever
		#5 clk = ~clk;

	logic in;
	logic out_ref;
	logic out_dut;

	initial begin
		$dumpfile("wave.vcd");
		$dumpvars(1, stim1.clk, tb_mismatch ,clk,in,out_ref,out_dut );
	end

	wire tb_match;		// Verification
	wire tb_mismatch = ~tb_match;

	stimulus_gen stim1 (
		.clk,
		.* ,
		.in );
	reference_module good1 (
		.clk,
		.in,
		.out(out_ref) );

	top_module top_module1 (
		.clk,
		.in,
		.out(out_dut) );

	bit strobe = 0;
	task wait_for_end_of_timestep;
		repeat(5) begin
			strobe <= !strobe;  // Try to delay until the very end of the time step.
			@(strobe);
		end
	endtask

	final begin
		if (stats1.errors_out) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "out", stats1.errors_out, stats1.errortime_out);
		else $display("Hint: Output '%s' has no mismatches.", "out");

		$display("Hint: Total mismatched samples is %1d out of %1d samples\n", stats1.errors, stats1.clocks);
		$display("Simulation finished at %0d ps", $time);
		$display("Mismatches: %1d in %1d samples", stats1.errors, stats1.clocks);
	end

	// Verification: XORs on the right makes any X in good_vector match anything, but X in dut_vector will only match X.
	assign tb_match = ( { out_ref } === ( { out_ref } ^ { out_dut } ^ { out_ref } ) );
	// Use explicit sensitivity list here. @(*) causes NetProc::nex_input() to be called when trying to compute
	// the sensitivity list of the @(strobe) process, which isn't implemented.
	always @(posedge clk, negedge clk) begin

		stats1.clocks++;
		if (!tb_match) begin
			if (stats1.errors == 0) stats1.errortime = $time;
			stats1.errors++;
		end
		if (out_ref !== ( out_ref ^ out_dut ^ out_ref ))
		begin if (stats1.errors_out == 0) stats1.errortime_out = $time;
			stats1.errors_out = stats1.errors_out+1'b1; end

	end
endmodule

detail_description: Implement in Verilog the following circuit: A D flip-flop takes as input the output of a two-input XOR. The flip-flop is positive edge triggered by clk, but there is no reset. The XOR takes as input 'in' along with the output 'out' of the flip-flop.


prompt:
module top_module (
	input clk,
	input in,
	input areset,
	output out
);

test:
`timescale 1 ps/1 ps
`define OK 12
`define INCORRECT 13
module reference_module (
	input clk,
	input in,
	input areset,
	output out
);
	parameter A=0, B=1;
	reg state;
	reg next;

    always_comb begin
		case (state)
			A: next = in ? A : B;
			B: next = in ? B : A;
		endcase
    end

    always @(posedge clk, posedge areset) begin
		if (areset) state <= B;
        else state <= next;
	end

	assign out = (state==B);

endmodule

module stimulus_gen (
	input clk,
	output logic in,
	output logic areset,
	output reg[511:0] wavedrom_title,
	output reg wavedrom_enable,
	input tb_match
);
	reg reset;
	assign areset = reset;
	task reset_test(input async=0);
		bit arfail, srfail, datafail;

		@(posedge clk);
		@(posedge clk) reset <= 0;
		repeat(3) @(posedge clk);

		@(negedge clk) begin datafail = !tb_match ; reset <= 1; end
		@(posedge clk) arfail = !tb_match;
		@(posedge clk) begin
			srfail = !tb_match;
			reset <= 0;
		end
		if (srfail)
			$display("Hint: Your reset doesn't seem to be working.");
		else if (arfail && (async || !datafail))
			$display("Hint: Your reset should be %0s, but doesn't appear to be.", async ? "asynchronous" : "synchronous");
		// Don't warn about synchronous reset if the half-cycle before is already wrong. It's more likely
		// a functionality error than the reset being implemented asynchronously.

	endtask

// Add two ports to module stimulus_gen:
//    output [511:0] wavedrom_title
//    output reg wavedrom_enable

	task wavedrom_start(input[511:0] title = "");
	endtask

	task wavedrom_stop;
		#1;
	endtask

	initial begin
		reset <= 1;
		in <= 0;
		@(posedge clk) reset <= 0; in <= 0;
		@(posedge clk) in <= 1;
		wavedrom_start();
			reset_test(1);
			@(posedge clk) in <= 0;
			@(posedge clk) in <= 0;
			@(posedge clk) in <= 0;
			@(posedge clk) in <= 1;
			@(posedge clk) in <= 1;
		@(negedge clk);
		wavedrom_stop();
		repeat(200) @(posedge clk, negedge clk) begin
			in <= $random;
			reset <= !($random & 7);
		end

		#1 $finish;
	end

endmodule

module tb();

	typedef struct packed {
		int errors;
		int errortime;
		int errors_out;
		int errortime_out;

		int clocks;
	} stats;

	stats stats1;

	wire[511:0] wavedrom_title;
	wire wavedrom_enable;
	int wavedrom_hide_after_time;

	reg clk=0;
	initial forever
		#5 clk = ~clk;

	logic in;
	logic areset;
	logic out_ref;
	logic out_dut;

	initial begin
		$dumpfile("wave.vcd");
		$dumpvars(1, stim1.clk, tb_mismatch ,clk,in,areset,out_ref,out_dut );
	end

	wire tb_match;		// Verification
	wire tb_mismatch = ~tb_match;

	stimulus_gen stim1 (
		.clk,
		.* ,
		.in,
		.areset );
	reference_module good1 (
		.clk,
		.in,
		.areset,
		.out(out_ref) );

	top_module top_module1 (
		.clk,
		.in,
		.areset,
		.out(out_dut) );

	bit strobe = 0;
	task wait_for_end_of_timestep;
		repeat(5) begin
			strobe <= !strobe;  // Try to delay until the very end of the time step.
			@(strobe);
		end
	endtask

	final begin
		if (stats1.errors_out) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "out", stats1.errors_out, stats1.errortime_out);
		else $display("Hint: Output '%s' has no mismatches.", "out");

		$display("Hint: Total mismatched samples is %1d out of %1d samples\n", stats1.errors, stats1.clocks);
		$display("Simulation finished at %0d ps", $time);
		$display("Mismatches: %1d in %1d samples", stats1.errors, stats1.clocks);
	end

	// Verification: XORs on the right makes any X in good_vector match anything, but X in dut_vector will only match X.
	assign tb_match = ( { out_ref } === ( { out_ref } ^ { out_dut } ^ { out_ref } ) );
	// Use explicit sensitivity list here. @(*) causes NetProc::nex_input() to be called when trying to compute
	// the sensitivity list of the @(strobe) process, which isn't implemented.
	always @(posedge clk, negedge clk) begin

		stats1.clocks++;
		if (!tb_match) begin
			if (stats1.errors == 0) stats1.errortime = $time;
			stats1.errors++;
		end
		if (out_ref !== ( out_ref ^ out_dut ^ out_ref ))
		begin if (stats1.errors_out == 0) stats1.errortime_out = $time;
			stats1.errors_out = stats1.errors_out+1'b1; end

	end
endmodule

detail_description:
Consider the follow Moore machine with the diagram described below:

// B (1) --0--> A
// B (1) --1--> B
// A (0) --0--> B
// A (0) --1--> A

// Write Verilog implementing this state machine. It should asynchronously reset into state B if reset if high.


prompt:
module top_module (
	input [7:0] code,
	output reg [3:0] out,
	output reg valid
);

test:
`timescale 1 ps/1 ps
`define OK 12
`define INCORRECT 13
module reference_module (
	input [7:0] code,
	output reg [3:0] out,
	output reg valid
);
//	uhh.. make a case statement: maps scancode to 0-9, but accidentally infer a latch?
//  and have one of the entries be wrong? (duplicate case, using different base!)
	always @(*) begin
		out = 0;
		valid = 1;
		case (code)
			8'h45: out = 0;
			8'h16: out = 1;
			8'h1e: out = 2;
			8'h26: out = 3;
			8'h25: out = 4;
			8'h2e: out = 5;
			8'h36: out = 6;
			8'h3d: out = 7;
			8'h3e: out = 8;
			8'h46: out = 9;
			default: valid = 0;
		endcase
	end

endmodule

module stimulus_gen (
	input clk,
	output logic [7:0] code,
	output reg[511:0] wavedrom_title,
	output reg wavedrom_enable,
	input tb_match
);

// Add two ports to module stimulus_gen:
//    output [511:0] wavedrom_title
//    output reg wavedrom_enable

	task wavedrom_start(input[511:0] title = "");
	endtask

	task wavedrom_stop;
		#1;
	endtask

	initial begin
		code <= 8'h45;
		@(negedge clk) wavedrom_start("Decode scancodes");
			@(posedge clk) code <= 8'h45;
			@(posedge clk) code <= 8'h03;
			@(posedge clk) code <= 8'h46;
			@(posedge clk) code <= 8'h16;
			@(posedge clk) code <= 8'd26;
			@(posedge clk) code <= 8'h1e;
			@(posedge clk) code <= 8'h25;
			@(posedge clk) code <= 8'h26;
			@(posedge clk) code <= 8'h2e;
			@(posedge clk) code <= $random;
			@(posedge clk) code <= 8'h36;
			@(posedge clk) code <= $random;
			@(posedge clk) code <= 8'h3d;
			@(posedge clk) code <= 8'h3e;
			@(posedge clk) code <= 8'h45;
			@(posedge clk) code <= 8'h46;
			@(posedge clk) code <= $random;
			@(posedge clk) code <= $random;
			@(posedge clk) code <= $random;
			@(posedge clk) code <= $random;
		wavedrom_stop();

		repeat(1000) @(posedge clk, negedge clk) begin
			code <= $urandom;
		end

		$finish;
	end

endmodule

module tb();

	typedef struct packed {
		int errors;
		int errortime;
		int errors_out;
		int errortime_out;
		int errors_valid;
		int errortime_valid;

		int clocks;
	} stats;

	stats stats1;

	wire[511:0] wavedrom_title;
	wire wavedrom_enable;
	int wavedrom_hide_after_time;

	reg clk=0;
	initial forever
		#5 clk = ~clk;

	logic [7:0] code;
	logic [3:0] out_ref;
	logic [3:0] out_dut;
	logic valid_ref;
	logic valid_dut;

	initial begin
		$dumpfile("wave.vcd");
		$dumpvars(1, stim1.clk, tb_mismatch ,code,out_ref,out_dut,valid_ref,valid_dut );
	end

	wire tb_match;		// Verification
	wire tb_mismatch = ~tb_match;

	stimulus_gen stim1 (
		.clk,
		.* ,
		.code );
	reference_module good1 (
		.code,
		.out(out_ref),
		.valid(valid_ref) );

	top_module top_module1 (
		.code,
		.out(out_dut),
		.valid(valid_dut) );

	bit strobe = 0;
	task wait_for_end_of_timestep;
		repeat(5) begin
			strobe <= !strobe;  // Try to delay until the very end of the time step.
			@(strobe);
		end
	endtask

	final begin
		if (stats1.errors_out) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "out", stats1.errors_out, stats1.errortime_out);
		else $display("Hint: Output '%s' has no mismatches.", "out");
		if (stats1.errors_valid) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "valid", stats1.errors_valid, stats1.errortime_valid);
		else $display("Hint: Output '%s' has no mismatches.", "valid");

		$display("Hint: Total mismatched samples is %1d out of %1d samples\n", stats1.errors, stats1.clocks);
		$display("Simulation finished at %0d ps", $time);
		$display("Mismatches: %1d in %1d samples", stats1.errors, stats1.clocks);
	end

	// Verification: XORs on the right makes any X in good_vector match anything, but X in dut_vector will only match X.
	assign tb_match = ( { out_ref, valid_ref } === ( { out_ref, valid_ref } ^ { out_dut, valid_dut } ^ { out_ref, valid_ref } ) );
	// Use explicit sensitivity list here. @(*) causes NetProc::nex_input() to be called when trying to compute
	// the sensitivity list of the @(strobe) process, which isn't implemented.
	always @(posedge clk, negedge clk) begin

		stats1.clocks++;
		if (!tb_match) begin
			if (stats1.errors == 0) stats1.errortime = $time;
			stats1.errors++;
		end
		if (out_ref !== ( out_ref ^ out_dut ^ out_ref ))
		begin if (stats1.errors_out == 0) stats1.errortime_out = $time;
			stats1.errors_out = stats1.errors_out+1'b1; end
		if (valid_ref !== ( valid_ref ^ valid_dut ^ valid_ref ))
		begin if (stats1.errors_valid == 0) stats1.errortime_valid = $time;
			stats1.errors_valid = stats1.errors_valid+1'b1; end

	end
endmodule

detail_description: This combinational circuit is supposed to recognize 8-bit keyboard scancodes for keys 0 through 9. It should indicate whether one of the 10 cases were recognized (valid), and if so, which key was detected. If the 8-bit input is 8'h45, 8'h16, 8'h1e, 8'h26, 8'h25, 8'h2e, 8'h36, 8'h3d, 8'h3e, or 8'h46, the 4-bit output will be set to 0, 1, 2, 3, 4, 5, 6, 7, 8, or 9 respectively, the 1-bit valid would be set to 1. If the input does not match any of the cases, both output signals would be set to 0.


prompt:
module top_module(
	input clk,
	input resetn,
	input [1:0] byteena,
	input [15:0] d,
	output reg [15:0] q);

test:
`timescale 1 ps/1 ps
`define OK 12
`define INCORRECT 13
module reference_module(
	input clk,
	input resetn,
	input [1:0] byteena,
	input [15:0] d,
	output reg [15:0] q);

	always @(posedge clk) begin
		if (!resetn)
			q <= 0;
		else begin
			if (byteena[0])
				q[7:0] <= d[7:0];
			if (byteena[1])
				q[15:8] <= d[15:8];
		end
	end

endmodule

module stimulus_gen (
	input clk,
	output reg [15:0] d, output reg [1:0] byteena,
	output reg resetn,
	output reg[511:0] wavedrom_title,
	output reg wavedrom_enable,
	input tb_match
);
	reg reset;
	assign resetn = ~reset;

// Add two ports to module stimulus_gen:
//    output [511:0] wavedrom_title
//    output reg wavedrom_enable

	task wavedrom_start(input[511:0] title = "");
	endtask

	task wavedrom_stop;
		#1;
	endtask

	task reset_test(input async=0);
		bit arfail, srfail, datafail;

		@(posedge clk);
		@(posedge clk) reset <= 0;
		repeat(3) @(posedge clk);

		@(negedge clk) begin datafail = !tb_match ; reset <= 1; end
		@(posedge clk) arfail = !tb_match;
		@(posedge clk) begin
			srfail = !tb_match;
			reset <= 0;
		end
		if (srfail)
			$display("Hint: Your reset doesn't seem to be working.");
		else if (arfail && (async || !datafail))
			$display("Hint: Your reset should be %0s, but doesn't appear to be.", async ? "asynchronous" : "synchronous");
		// Don't warn about synchronous reset if the half-cycle before is already wrong. It's more likely
		// a functionality error than the reset being implemented asynchronously.

	endtask

	initial begin
		reset <= 1;
		byteena <= 2'b11;
		d <= 16'habcd;
		@(posedge clk);
		wavedrom_start("Synchronous active-low reset");
		reset_test(0);
		repeat(2) @(posedge clk);
		wavedrom_stop();
		@(posedge clk);

		byteena <= 2'b11;
		d <= $random;
		@(posedge clk);
		@(negedge clk);
		wavedrom_start("DFF with byte enables");
		repeat(10) @(posedge clk) begin
			d <= $random;
			byteena <= byteena + 1;
		end
		wavedrom_stop();

		repeat(400) @(posedge clk, negedge clk) begin
			byteena[0] <= ($random & 3) != 0;
			byteena[1] <= ($random & 3) != 0;
			d <= $random;
		end
		#1 $finish;
	end

endmodule

module tb();

	typedef struct packed {
		int errors;
		int errortime;
		int errors_q;
		int errortime_q;

		int clocks;
	} stats;

	stats stats1;

	wire[511:0] wavedrom_title;
	wire wavedrom_enable;
	int wavedrom_hide_after_time;

	reg clk=0;
	initial forever
		#5 clk = ~clk;

	logic resetn;
	logic [1:0] byteena;
	logic [15:0] d;
	logic [15:0] q_ref;
	logic [15:0] q_dut;

	initial begin
		$dumpfile("wave.vcd");
		$dumpvars(1, stim1.clk, tb_mismatch ,clk,resetn,byteena,d,q_ref,q_dut );
	end

	wire tb_match;		// Verification
	wire tb_mismatch = ~tb_match;

	stimulus_gen stim1 (
		.clk,
		.* ,
		.resetn,
		.byteena,
		.d );
	reference_module good1 (
		.clk,
		.resetn,
		.byteena,
		.d,
		.q(q_ref) );

	top_module top_module1 (
		.clk,
		.resetn,
		.byteena,
		.d,
		.q(q_dut) );

	bit strobe = 0;
	task wait_for_end_of_timestep;
		repeat(5) begin
			strobe <= !strobe;  // Try to delay until the very end of the time step.
			@(strobe);
		end
	endtask

	final begin
		if (stats1.errors_q) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "q", stats1.errors_q, stats1.errortime_q);
		else $display("Hint: Output '%s' has no mismatches.", "q");

		$display("Hint: Total mismatched samples is %1d out of %1d samples\n", stats1.errors, stats1.clocks);
		$display("Simulation finished at %0d ps", $time);
		$display("Mismatches: %1d in %1d samples", stats1.errors, stats1.clocks);
	end

	// Verification: XORs on the right makes any X in good_vector match anything, but X in dut_vector will only match X.
	assign tb_match = ( { q_ref } === ( { q_ref } ^ { q_dut } ^ { q_ref } ) );
	// Use explicit sensitivity list here. @(*) causes NetProc::nex_input() to be called when trying to compute
	// the sensitivity list of the @(strobe) process, which isn't implemented.
	always @(posedge clk, negedge clk) begin

		stats1.clocks++;
		if (!tb_match) begin
			if (stats1.errors == 0) stats1.errortime = $time;
			stats1.errors++;
		end
		if (q_ref !== ( q_ref ^ q_dut ^ q_ref ))
		begin if (stats1.errors_q == 0) stats1.errortime_q = $time;
			stats1.errors_q = stats1.errors_q+1'b1; end

	end
endmodule

detail_description: Create 16 D flip-flops. It's sometimes useful to only modify parts of a group of flip-flops. The byte-enable inputs control whether each byte of the 16 registers should be written to on that cycle. byteena[1] controls the upper byte d[15:8], while byteena[0] controls the lower byte d[7:0]. resetn is a synchronous, active-low reset. All DFFs should be triggered by the positive edge of clk.


prompt:
module top_module (
	input in,
	input [9:0] state,
	output [9:0] next_state,
	output out1,
	output out2);

test:
`timescale 1 ps/1 ps
`define OK 12
`define INCORRECT 13
module reference_module (
	input in,
	input [9:0] state,
	output [9:0] next_state,
	output out1,
	output out2);

	assign out1 = state[8] | state[9];
	assign out2 = state[7] | state[9];

	assign next_state[0] = !in && (|state[4:0] | state[7] | state[8] | state[9]);
	assign next_state[1] = in && (state[0] | state[8] | state[9]);
	assign next_state[2] = in && state[1];
	assign next_state[3] = in && state[2];
	assign next_state[4] = in && state[3];
	assign next_state[5] = in && state[4];
	assign next_state[6] = in && state[5];
	assign next_state[7] = in && (state[6] | state[7]);
	assign next_state[8] = !in && state[5];
	assign next_state[9] = !in && state[6];

endmodule

module stimulus_gen (
	input clk,
	output logic in,
	output logic [9:0] state,
	input tb_match,
	input [9:0] next_state_ref,
	input [9:0] next_state_dut,
	output reg[511:0] wavedrom_title,
	output reg wavedrom_enable
);

// Add two ports to module stimulus_gen:
//    output [511:0] wavedrom_title
//    output reg wavedrom_enable

	task wavedrom_start(input[511:0] title = "");
	endtask

	task wavedrom_stop;
		#1;
	endtask

	int errored1 = 0;
	int errored2 = 0;
	int onehot_error = 0;
	reg [9:0] state_error = 10'h0;

	initial begin
		repeat(2) @(posedge clk);
		forever @(posedge clk, negedge clk)
			state_error <= state_error | (next_state_ref^next_state_dut);
	end

	initial begin
		state <= 0;

		@(negedge clk) wavedrom_start();
		for (int i=0;i<10;i++) begin
			@(negedge clk, posedge clk);
			state <= 1<< i;
			in <= 0;
		end
		for (int i=0;i<10;i++) begin
			@(negedge clk, posedge clk);
			state <= 1<< i;
			in <= 1;
		end
		@(negedge clk) wavedrom_stop();

		// Test the one-hot cases first.
		repeat(200) @(posedge clk, negedge clk) begin
			state <= 1<< ($unsigned($random) % 10);
			in <= $random;
			if (!tb_match) onehot_error++;
		end

		// Two-hot.
		errored1 = 0;
		repeat(400) @(posedge clk, negedge clk) begin
			state <= (1<< ($unsigned($random) % 10)) | (1<< ($unsigned($random) % 10));
			in <= $random;
			if (!tb_match)
				errored1++;
		end

		if (!onehot_error && errored1)
			$display ("Hint: Your circuit passed when given only one-hot inputs, but not with two-hot inputs.");

		// Random.
		errored2 = 0;
		repeat(800) @(posedge clk, negedge clk) begin
			state <= $random;
			in <= $random;
			if (!tb_match)
				errored2++;
		end
		if (!onehot_error && errored2)
			$display ("Hint: Your circuit passed when given only one-hot inputs, but not with random inputs.");

		if (!onehot_error && (errored1 || errored2))
			$display("Hint: Are you doing something more complicated than deriving state transition equations by inspection?\n");

		for (int i=0;i<$bits(state_error);i++)
			$display("Hint: next_state[%0d] is %s.", i, (state_error[i] === 1'b0) ? "correct": "incorrect");

		#1 $finish;
	end

endmodule

module tb();

	typedef struct packed {
		int errors;
		int errortime;
		int errors_next_state;
		int errortime_next_state;
		int errors_out1;
		int errortime_out1;
		int errors_out2;
		int errortime_out2;

		int clocks;
	} stats;

	stats stats1;

	wire[511:0] wavedrom_title;
	wire wavedrom_enable;
	int wavedrom_hide_after_time;

	reg clk=0;
	initial forever
		#5 clk = ~clk;

	logic in;
	logic [9:0] state;
	logic [9:0] next_state_ref;
	logic [9:0] next_state_dut;
	logic out1_ref;
	logic out1_dut;
	logic out2_ref;
	logic out2_dut;

	initial begin
		$dumpfile("wave.vcd");
		$dumpvars(1, stim1.clk, tb_mismatch ,in,state,next_state_ref,next_state_dut,out1_ref,out1_dut,out2_ref,out2_dut );
	end

	wire tb_match;		// Verification
	wire tb_mismatch = ~tb_match;

	stimulus_gen stim1 (
		.clk,
		.* ,
		.in,
		.state );
	reference_module good1 (
		.in,
		.state,
		.next_state(next_state_ref),
		.out1(out1_ref),
		.out2(out2_ref) );

	top_module top_module1 (
		.in,
		.state,
		.next_state(next_state_dut),
		.out1(out1_dut),
		.out2(out2_dut) );

	bit strobe = 0;
	task wait_for_end_of_timestep;
		repeat(5) begin
			strobe <= !strobe;  // Try to delay until the very end of the time step.
			@(strobe);
		end
	endtask

	final begin
		if (stats1.errors_next_state) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "next_state", stats1.errors_next_state, stats1.errortime_next_state);
		else $display("Hint: Output '%s' has no mismatches.", "next_state");
		if (stats1.errors_out1) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "out1", stats1.errors_out1, stats1.errortime_out1);
		else $display("Hint: Output '%s' has no mismatches.", "out1");
		if (stats1.errors_out2) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "out2", stats1.errors_out2, stats1.errortime_out2);
		else $display("Hint: Output '%s' has no mismatches.", "out2");

		$display("Hint: Total mismatched samples is %1d out of %1d samples\n", stats1.errors, stats1.clocks);
		$display("Simulation finished at %0d ps", $time);
		$display("Mismatches: %1d in %1d samples", stats1.errors, stats1.clocks);
	end

	// Verification: XORs on the right makes any X in good_vector match anything, but X in dut_vector will only match X.
	assign tb_match = ( { next_state_ref, out1_ref, out2_ref } === ( { next_state_ref, out1_ref, out2_ref } ^ { next_state_dut, out1_dut, out2_dut } ^ { next_state_ref, out1_ref, out2_ref } ) );
	// Use explicit sensitivity list here. @(*) causes NetProc::nex_input() to be called when trying to compute
	// the sensitivity list of the @(strobe) process, which isn't implemented.
	always @(posedge clk, negedge clk) begin

		stats1.clocks++;
		if (!tb_match) begin
			if (stats1.errors == 0) stats1.errortime = $time;
			stats1.errors++;
		end
		if (next_state_ref !== ( next_state_ref ^ next_state_dut ^ next_state_ref ))
		begin if (stats1.errors_next_state == 0) stats1.errortime_next_state = $time;
			stats1.errors_next_state = stats1.errors_next_state+1'b1; end
		if (out1_ref !== ( out1_ref ^ out1_dut ^ out1_ref ))
		begin if (stats1.errors_out1 == 0) stats1.errortime_out1 = $time;
			stats1.errors_out1 = stats1.errors_out1+1'b1; end
		if (out2_ref !== ( out2_ref ^ out2_dut ^ out2_ref ))
		begin if (stats1.errors_out2 == 0) stats1.errortime_out2 = $time;
			stats1.errors_out2 = stats1.errors_out2+1'b1; end

	end
endmodule

detail_description:
Given the follow state machine with 1 input and 2 outputs (the outputs are given as "(out1, out2)"):

// S0 (0, 0) --0--> S0
// S0 (0, 0) --1--> S1
// S1 (0, 0) --0--> S0
// S1 (0, 0) --1--> S2
// S2 (0, 0) --0--> S0
// S2 (0, 0) --1--> S3
// S3 (0, 0) --0--> S0
// S3 (0, 0) --1--> S4
// S4 (0, 0) --0--> S0
// S4 (0, 0) --1--> S5
// S5 (0, 0) --0--> S8
// S5 (0, 0) --1--> S6
// S6 (0, 0) --0--> S9
// S6 (0, 0) --1--> S7
// S7 (0, 1) --0--> S0
// S7 (0, 1) --1--> S7
// S8 (1, 0) --0--> S0
// S8 (1, 0) --1--> S1
// S9 (1, 1) --0--> S0
// S9 (1, 1) --1--> S1

// Suppose this state machine uses one-hot encoding, where state[0] through state[9] correspond to the states S0 though S9, respectively. The outputs are zero unless otherwise specified.

// Write Verilog implementing the state transition logic and output logic portions of the state machine (but not the state flip-flops). You are given the current state in state[9:0] and must produce next_state[9:0] and the two outputs. Derive the logic equations by inspection assuming a one-hot encoding.


task_id: conditional

prompt:
module top_module (
	input [7:0] a,
	input [7:0] b,
	input [7:0] c,
	input [7:0] d,
	output reg [7:0] min
);

test:
`timescale 1 ps/1 ps
`define OK 12
`define INCORRECT 13
module reference_module (
	input [7:0] a,
	input [7:0] b,
	input [7:0] c,
	input [7:0] d,
	output reg [7:0] min
);

	always_comb begin
		min = a;
		if (min > b) min = b;
		if (min > c) min = c;
		if (min > d) min = d;
	end

endmodule

module stimulus_gen (
	input clk,
	output logic [7:0] a, b, c, d,
	output reg[511:0] wavedrom_title,
	output reg wavedrom_enable
);

// Add two ports to module stimulus_gen:
//    output [511:0] wavedrom_title
//    output reg wavedrom_enable

	task wavedrom_start(input[511:0] title = "");
	endtask

	task wavedrom_stop;
		#1;
	endtask

 	initial begin
 		{a,b,c,d} <= {8'h1, 8'h2, 8'h3, 8'h4};
 		@(negedge clk);
 		wavedrom_start();
	 		@(posedge clk) {a,b,c,d} <= {8'h1, 8'h2, 8'h3, 8'h4};
	 		@(posedge clk) {a,b,c,d} <= {8'h11, 8'h2, 8'h3, 8'h4};
	 		@(posedge clk) {a,b,c,d} <= {8'h11, 8'h12, 8'h3, 8'h4};
	 		@(posedge clk) {a,b,c,d} <= {8'h11, 8'h12, 8'h13, 8'h4};
	 		@(posedge clk) {a,b,c,d} <= {8'h11, 8'h12, 8'h13, 8'h14};
 		@(negedge clk);
 		wavedrom_stop();
		repeat(100) @(posedge clk, negedge clk)
			{a,b,c,d} <= $random;
		$finish;
	end

endmodule

module tb();

	typedef struct packed {
		int errors;
		int errortime;
		int errors_min;
		int errortime_min;

		int clocks;
	} stats;

	stats stats1;

	wire[511:0] wavedrom_title;
	wire wavedrom_enable;
	int wavedrom_hide_after_time;

	reg clk=0;
	initial forever
		#5 clk = ~clk;

	logic [7:0] a;
	logic [7:0] b;
	logic [7:0] c;
	logic [7:0] d;
	logic [7:0] min_ref;
	logic [7:0] min_dut;

	initial begin
		$dumpfile("wave.vcd");
		$dumpvars(1, stim1.clk, tb_mismatch ,a,b,c,d,min_ref,min_dut );
	end

	wire tb_match;		// Verification
	wire tb_mismatch = ~tb_match;

	stimulus_gen stim1 (
		.clk,
		.* ,
		.a,
		.b,
		.c,
		.d );
	reference_module good1 (
		.a,
		.b,
		.c,
		.d,
		.min(min_ref) );

	top_module top_module1 (
		.a,
		.b,
		.c,
		.d,
		.min(min_dut) );

	bit strobe = 0;
	task wait_for_end_of_timestep;
		repeat(5) begin
			strobe <= !strobe;  // Try to delay until the very end of the time step.
			@(strobe);
		end
	endtask

	final begin
		if (stats1.errors_min) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "min", stats1.errors_min, stats1.errortime_min);
		else $display("Hint: Output '%s' has no mismatches.", "min");

		$display("Hint: Total mismatched samples is %1d out of %1d samples\n", stats1.errors, stats1.clocks);
		$display("Simulation finished at %0d ps", $time);
		$display("Mismatches: %1d in %1d samples", stats1.errors, stats1.clocks);
	end

	// Verification: XORs on the right makes any X in good_vector match anything, but X in dut_vector will only match X.
	assign tb_match = ( { min_ref } === ( { min_ref } ^ { min_dut } ^ { min_ref } ) );
	// Use explicit sensitivity list here. @(*) causes NetProc::nex_input() to be called when trying to compute
	// the sensitivity list of the @(strobe) process, which isn't implemented.
	always @(posedge clk, negedge clk) begin

		stats1.clocks++;
		if (!tb_match) begin
			if (stats1.errors == 0) stats1.errortime = $time;
			stats1.errors++;
		end
		if (min_ref !== ( min_ref ^ min_dut ^ min_ref ))
		begin if (stats1.errors_min == 0) stats1.errortime_min = $time;
			stats1.errors_min = stats1.errors_min+1'b1; end

	end
endmodule

detail_description: Given four unsigned numbers, find the minimum. Unsigned numbers can be compared with standard comparison operators (a < b).


prompt:
module top_module (
	input [3:0] in,
	output out_and,
	output out_or,
	output out_xor
);

test:
`timescale 1 ps/1 ps
`define OK 12
`define INCORRECT 13
module reference_module (
	input [3:0] in,
	output out_and,
	output out_or,
	output out_xor
);

	assign out_and = ∈
	assign out_or = |in;
	assign out_xor = ^in;

endmodule

module stimulus_gen (
	input clk,
	output logic [3:0] in,
	output reg[511:0] wavedrom_title,
	output reg wavedrom_enable
);

// Add two ports to module stimulus_gen:
//    output [511:0] wavedrom_title
//    output reg wavedrom_enable

	task wavedrom_start(input[511:0] title = "");
	endtask

	task wavedrom_stop;
		#1;
	endtask

	initial begin
		in <= 0;
		@(negedge clk) wavedrom_start("All combinations");
			@(posedge clk);
			repeat(15) @(posedge clk) in <= in + 1;
		@(negedge clk) wavedrom_stop();
		repeat(200) @(posedge clk, negedge clk)
			in <= $random;
		$finish;
	end

endmodule

module tb();

	typedef struct packed {
		int errors;
		int errortime;
		int errors_out_and;
		int errortime_out_and;
		int errors_out_or;
		int errortime_out_or;
		int errors_out_xor;
		int errortime_out_xor;

		int clocks;
	} stats;

	stats stats1;

	wire[511:0] wavedrom_title;
	wire wavedrom_enable;
	int wavedrom_hide_after_time;

	reg clk=0;
	initial forever
		#5 clk = ~clk;

	logic [3:0] in;
	logic out_and_ref;
	logic out_and_dut;
	logic out_or_ref;
	logic out_or_dut;
	logic out_xor_ref;
	logic out_xor_dut;

	initial begin
		$dumpfile("wave.vcd");
		$dumpvars(1, stim1.clk, tb_mismatch ,in,out_and_ref,out_and_dut,out_or_ref,out_or_dut,out_xor_ref,out_xor_dut );
	end

	wire tb_match;		// Verification
	wire tb_mismatch = ~tb_match;

	stimulus_gen stim1 (
		.clk,
		.* ,
		.in );
	reference_module good1 (
		.in,
		.out_and(out_and_ref),
		.out_or(out_or_ref),
		.out_xor(out_xor_ref) );

	top_module top_module1 (
		.in,
		.out_and(out_and_dut),
		.out_or(out_or_dut),
		.out_xor(out_xor_dut) );

	bit strobe = 0;
	task wait_for_end_of_timestep;
		repeat(5) begin
			strobe <= !strobe;  // Try to delay until the very end of the time step.
			@(strobe);
		end
	endtask

	final begin
		if (stats1.errors_out_and) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "out_and", stats1.errors_out_and, stats1.errortime_out_and);
		else $display("Hint: Output '%s' has no mismatches.", "out_and");
		if (stats1.errors_out_or) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "out_or", stats1.errors_out_or, stats1.errortime_out_or);
		else $display("Hint: Output '%s' has no mismatches.", "out_or");
		if (stats1.errors_out_xor) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "out_xor", stats1.errors_out_xor, stats1.errortime_out_xor);
		else $display("Hint: Output '%s' has no mismatches.", "out_xor");

		$display("Hint: Total mismatched samples is %1d out of %1d samples\n", stats1.errors, stats1.clocks);
		$display("Simulation finished at %0d ps", $time);
		$display("Mismatches: %1d in %1d samples", stats1.errors, stats1.clocks);
	end

	// Verification: XORs on the right makes any X in good_vector match anything, but X in dut_vector will only match X.
	assign tb_match = ( { out_and_ref, out_or_ref, out_xor_ref } === ( { out_and_ref, out_or_ref, out_xor_ref } ^ { out_and_dut, out_or_dut, out_xor_dut } ^ { out_and_ref, out_or_ref, out_xor_ref } ) );
	// Use explicit sensitivity list here. @(*) causes NetProc::nex_input() to be called when trying to compute
	// the sensitivity list of the @(strobe) process, which isn't implemented.
	always @(posedge clk, negedge clk) begin

		stats1.clocks++;
		if (!tb_match) begin
			if (stats1.errors == 0) stats1.errortime = $time;
			stats1.errors++;
		end
		if (out_and_ref !== ( out_and_ref ^ out_and_dut ^ out_and_ref ))
		begin if (stats1.errors_out_and == 0) stats1.errortime_out_and = $time;
			stats1.errors_out_and = stats1.errors_out_and+1'b1; end
		if (out_or_ref !== ( out_or_ref ^ out_or_dut ^ out_or_ref ))
		begin if (stats1.errors_out_or == 0) stats1.errortime_out_or = $time;
			stats1.errors_out_or = stats1.errors_out_or+1'b1; end
		if (out_xor_ref !== ( out_xor_ref ^ out_xor_dut ^ out_xor_ref ))
		begin if (stats1.errors_out_xor == 0) stats1.errortime_out_xor = $time;
			stats1.errors_out_xor = stats1.errors_out_xor+1'b1; end

	end
endmodule

detail_description:
Build a combinational circuit with four inputs, in[3:0]. There are 3 outputs:
// (1) out_and: output of a 4-input AND gate.
// (2) out_or: output of a 4-input OR gate.
// (3) out_xor: output of a 4-input XOR gate.


prompt:
module top_module(
	input wire clk,
	input wire reset,
	input wire data,
    output wire [3:0] count,
    output reg counting,
    output reg done,
    input wire ack );

test:
`timescale 1 ps/1 ps
`define OK 12
`define INCORRECT 13
`default_nettype none
module reference_module(
	input wire clk,
	input wire reset,
	input wire data,
    output wire [3:0] count,
    output reg counting,
    output reg done,
    input wire ack );

	typedef enum logic[3:0] {
		S, S1, S11, S110, B0, B1, B2, B3, Count, Wait
	} States;

	States state, next;

	reg shift_ena;
	reg [9:0] fcount;
	reg [3:0] scount;
	wire done_counting = (scount == 0) && (fcount == 999);

	always_comb begin
		case (state)
			S: next = States'(data ? S1: S);
			S1: next = States'(data ? S11: S);
			S11: next = States'(data ? S11 : S110);
			S110: next = States'(data ? B0 : S);
			B0: next = B1;
			B1: next = B2;
			B2: next = B3;
			B3: next = Count;
			Count: next = States'(done_counting ? Wait : Count);
			Wait: next = States'(ack ? S : Wait);
			default: next = States'(4'bx);
		endcase
	end

	always @(posedge clk) begin
		if (reset) state <= S;
		else state <= next;
	end

	always_comb begin
		shift_ena = 0; counting = 0; done = 0;
		if (state == B0 || state == B1 || state == B2 || state == B3)
			shift_ena = 1;
		if (state == Count)
			counting = 1;
		if (state == Wait)
			done = 1;

		if (|state === 1'bx) begin
			{shift_ena, counting, done} = 'x;
		end
	end

	// Shift register
	always @(posedge clk) begin
		if (shift_ena)
			scount <= {scount[2:0], data};
		else if (counting && fcount == 999)
			scount <= scount - 1'b1;
	end

	// Fast counter
	always @(posedge clk)
		if (!counting)
			fcount <= 10'h0;
		else if (fcount == 999)
			fcount <= 10'h0;
		else
			fcount <= fcount + 1'b1;

	assign count = counting ? scount : 'x;

endmodule

module stimulus_gen (
	input wire clk,
	output reg reset,
	output reg data,
	output reg ack,
	input wire tb_match,
	input wire counting_dut
);
	bit failed = 0;
	int counting_cycles = 0;

	always @(posedge clk, negedge clk)
		if (!tb_match)
			failed <= 1;

	always @(posedge clk)
		if (counting_dut)
			counting_cycles++;

	initial begin

		@(posedge clk);
		failed <= 0;
		reset <= 1;
		data <= 0;
		ack <= 1'bx;
		@(posedge clk)
			data <= 1;
			reset <= 0;
		@(posedge clk) data <= 0;
		@(posedge clk) data <= 0;
		@(posedge clk) data <= 1;
		@(posedge clk) data <= 1;
		@(posedge clk) data <= 0;
		@(posedge clk) data <= 1;
		@(posedge clk) data <= 0;
		@(posedge clk) data <= 0;
		@(posedge clk) data <= 0;
		@(posedge clk) data <= 1;
		@(posedge clk);
			data <= 1'bx;
		repeat(2000) @(posedge clk);
			ack <= 1'b0;
		repeat(3) @(posedge clk);
			ack <= 1'b1;
		@(posedge clk);
			ack <= 1'b0;
			data <= 1'b1;
		if (counting_cycles != 2000)
			$display("Hint: The first test case should count for 2000 cycles. Your circuit counted %0d", counting_cycles);
		counting_cycles <= 0;
		@(posedge clk);
			ack <= 1'bx;
			data <= 1'b1;
		@(posedge clk);
			data <= 1'b0;
		@(posedge clk);
			data <= 1'b1;
		@(posedge clk);	data <= 1'b1;
		@(posedge clk);	data <= 1'b1;
		@(posedge clk);	data <= 1'b1;
		@(posedge clk);	data <= 1'b0;
		repeat(14800) @(posedge clk);
		ack <= 1'b0;
		repeat(400) @(posedge clk);

		if (counting_cycles != 15000)
			$display("Hint: The second test case should count for 15000 cycles. Your circuit counted %0d", counting_cycles);
		counting_cycles <= 0;

		if (failed)
			$display("Hint: Your FSM didn't pass the sample timing diagram posted with the problem statement. Perhaps try debugging that?");

		repeat(1000) @(posedge clk, negedge clk) begin
			reset <= !($random & 8191);
			data <= $random;
			ack <= !($random & 31);
		end
		repeat(100000) @(posedge clk) begin
			reset <= !($random & 8191);
			data <= $random;
			ack <= !($random & 31);
		end

		#1 $finish;
	end

endmodule
module tb();

	typedef struct packed {
		int errors;
		int errortime;
		int errors_count;
		int errortime_count;
		int errors_counting;
		int errortime_counting;
		int errors_done;
		int errortime_done;

		int clocks;
	} stats;

	stats stats1;

	wire[511:0] wavedrom_title;
	wire wavedrom_enable;
	int wavedrom_hide_after_time;

	reg clk=0;
	initial forever
		#5 clk = ~clk;

	logic reset;
	logic data;
	logic ack;
	logic [3:0] count_ref;
	logic [3:0] count_dut;
	logic counting_ref;
	logic counting_dut;
	logic done_ref;
	logic done_dut;

	initial begin
		$dumpfile("wave.vcd");
		$dumpvars(1, stim1.clk, tb_mismatch ,clk,reset,data,ack,count_ref,count_dut,counting_ref,counting_dut,done_ref,done_dut );
	end

	wire tb_match;		// Verification
	wire tb_mismatch = ~tb_match;

	stimulus_gen stim1 (
		.clk,
		.* ,
		.reset,
		.data,
		.ack );
	reference_module good1 (
		.clk,
		.reset,
		.data,
		.ack,
		.count(count_ref),
		.counting(counting_ref),
		.done(done_ref) );

	top_module top_module1 (
		.clk,
		.reset,
		.data,
		.ack,
		.count(count_dut),
		.counting(counting_dut),
		.done(done_dut) );

	bit strobe = 0;
	task wait_for_end_of_timestep;
		repeat(5) begin
			strobe <= !strobe;  // Try to delay until the very end of the time step.
			@(strobe);
		end
	endtask

	final begin
		if (stats1.errors_count) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "count", stats1.errors_count, stats1.errortime_count);
		else $display("Hint: Output '%s' has no mismatches.", "count");
		if (stats1.errors_counting) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "counting", stats1.errors_counting, stats1.errortime_counting);
		else $display("Hint: Output '%s' has no mismatches.", "counting");
		if (stats1.errors_done) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "done", stats1.errors_done, stats1.errortime_done);
		else $display("Hint: Output '%s' has no mismatches.", "done");

		$display("Hint: Total mismatched samples is %1d out of %1d samples\n", stats1.errors, stats1.clocks);
		$display("Simulation finished at %0d ps", $time);
		$display("Mismatches: %1d in %1d samples", stats1.errors, stats1.clocks);
	end

	// Verification: XORs on the right makes any X in good_vector match anything, but X in dut_vector will only match X.
	assign tb_match = ( { count_ref, counting_ref, done_ref } === ( { count_ref, counting_ref, done_ref } ^ { count_dut, counting_dut, done_dut } ^ { count_ref, counting_ref, done_ref } ) );
	// Use explicit sensitivity list here. @(*) causes NetProc::nex_input() to be called when trying to compute
	// the sensitivity list of the @(strobe) process, which isn't implemented.
	always @(posedge clk, negedge clk) begin

		stats1.clocks++;
		if (!tb_match) begin
			if (stats1.errors == 0) stats1.errortime = $time;
			stats1.errors++;
		end
		if (count_ref !== ( count_ref ^ count_dut ^ count_ref ))
		begin if (stats1.errors_count == 0) stats1.errortime_count = $time;
			stats1.errors_count = stats1.errors_count+1'b1; end
		if (counting_ref !== ( counting_ref ^ counting_dut ^ counting_ref ))
		begin if (stats1.errors_counting == 0) stats1.errortime_counting = $time;
			stats1.errors_counting = stats1.errors_counting+1'b1; end
		if (done_ref !== ( done_ref ^ done_dut ^ done_ref ))
		begin if (stats1.errors_done == 0) stats1.errortime_done = $time;
			stats1.errors_done = stats1.errors_done+1'b1; end

	end
endmodule

detail_description:
We want to create a timer with one input that:

// (1) is started when a particular input pattern (1101) is detected,
// (2) shifts in 4 more bits to determine the duration to delay,
// (3) waits for the counters to finish counting, and
// (4) notifies the user and waits for the user to acknowledge the timer.

// The serial data is available on the data input pin. When the pattern 1101 is received, the circuit must then shift in the next 4 bits, most-significant-bit first. These 4 bits determine the duration of the timer delay, referred to as delay[3:0]. After that, the state machine asserts its counting output to indicate it is counting. Once the 1101 and delay[3:0] have been read, the circuit no longer looks at the data input until it resumes searching after everything else is done.

// The state machine must count for exactly (delay[3:0] + 1) * 1000 clock cycles. e.g., delay=0 means count 1000 cycles, and delay=5 means count 6000 cycles. Also output the current remaining time. This should be equal to delay for 1000 cycles, then delay-1 for 1000 cycles, and so on until it is 0 for 1000 cycles.

// When the circuit isn't counting, the count[3:0] output is don't-care (whatever value is convenient for you to implement). At that point, the circuit must assert done to notify the user the timer has timed out, and waits until input ack is 1 before being reset to look for the next occurrence of the start sequence (1101).

// The circuit should reset into a state where it begins searching for the input sequence 1101. The reset signal is active high synchronous.


prompt:
module top_module (
	input clk,
	input reset,
	input [3:1] s,
	output reg fr3,
	output reg fr2,
	output reg fr1,
	output reg dfr
);

test:
`timescale 1 ps/1 ps
`define OK 12
`define INCORRECT 13
module reference_module (
	input clk,
	input reset,
	input [3:1] s,
	output reg fr3,
	output reg fr2,
	output reg fr1,
	output reg dfr
);
	parameter A2=0, B1=1, B2=2, C1=3, C2=4, D1=5;
	reg [2:0] state, next;

	always @(posedge clk) begin
		if (reset) state <= A2;
		else state <= next;
	end

	always@(*) begin
		case (state)
			A2: next = s[1] ? B1 : A2;
			B1: next = s[2] ? C1 : (s[1] ? B1 : A2);
			B2: next = s[2] ? C1 : (s[1] ? B2 : A2);
			C1: next = s[3] ? D1 : (s[2] ? C1 : B2);
			C2: next = s[3] ? D1 : (s[2] ? C2 : B2);
			D1: next = s[3] ? D1 : C2;
			default: next = 'x;
		endcase
	end
	reg [3:0] fr;
	assign {fr3, fr2, fr1, dfr} = fr;
	always_comb begin
		case (state)
			A2: fr = 4'b1111;
			B1: fr = 4'b0110;
			B2: fr = 4'b0111;
			C1: fr = 4'b0010;
			C2: fr = 4'b0011;
			D1: fr = 4'b0000;
			default: fr = 'x;
		endcase
	end

endmodule

module stimulus_gen (
	input clk,
	output logic reset,
	output logic [3:1] s,
	output reg[511:0] wavedrom_title,
	output reg wavedrom_enable,
	input tb_match
);

// Add two ports to module stimulus_gen:
//    output [511:0] wavedrom_title
//    output reg wavedrom_enable

	task wavedrom_start(input[511:0] title = "");
	endtask

	task wavedrom_stop;
		#1;
	endtask

	task reset_test(input async=0);
		bit arfail, srfail, datafail;

		@(posedge clk);
		@(posedge clk) reset <= 0;
		repeat(3) @(posedge clk);

		@(negedge clk) begin datafail = !tb_match ; reset <= 1; end
		@(posedge clk) arfail = !tb_match;
		@(posedge clk) begin
			srfail = !tb_match;
			reset <= 0;
		end
		if (srfail)
			$display("Hint: Your reset doesn't seem to be working.");
		else if (arfail && (async || !datafail))
			$display("Hint: Your reset should be %0s, but doesn't appear to be.", async ? "asynchronous" : "synchronous");
		// Don't warn about synchronous reset if the half-cycle before is already wrong. It's more likely
		// a functionality error than the reset being implemented asynchronously.

	endtask

	wire [3:0][2:0] val = { 3'h7, 3'h3, 3'h1, 3'h0 };
	integer sval;
	initial begin
		reset <= 1;
		s <= 1;
		reset_test();

		@(posedge clk) s <= 0;
		@(posedge clk) s <= 0;
		@(negedge clk) wavedrom_start("Water rises to highest level, then down to lowest level.");
			@(posedge clk) s <= 0;
			@(posedge clk) s <= 1;
			@(posedge clk) s <= 3;
			@(posedge clk) s <= 7;
			@(posedge clk) s <= 7;
			@(posedge clk) s <= 3;
			@(posedge clk) s <= 3;
			@(posedge clk) s <= 1;
			@(posedge clk) s <= 1;
			@(posedge clk) s <= 0;
			@(posedge clk) s <= 0;
		@(negedge clk) wavedrom_stop();

		sval = 0;
		repeat(1000) begin
			@(posedge clk);
				sval = sval + (sval == 3 ? 0 : $random&1);
				s <= val[sval];
			@(negedge clk);
				sval = sval - (sval == 0 ? 0 : $random&1);
				s <= val[sval];
		end

		$finish;
	end

endmodule

module tb();

	typedef struct packed {
		int errors;
		int errortime;
		int errors_fr3;
		int errortime_fr3;
		int errors_fr2;
		int errortime_fr2;
		int errors_fr1;
		int errortime_fr1;
		int errors_dfr;
		int errortime_dfr;

		int clocks;
	} stats;

	stats stats1;

	wire[511:0] wavedrom_title;
	wire wavedrom_enable;
	int wavedrom_hide_after_time;

	reg clk=0;
	initial forever
		#5 clk = ~clk;

	logic reset;
	logic [3:1] s;
	logic fr3_ref;
	logic fr3_dut;
	logic fr2_ref;
	logic fr2_dut;
	logic fr1_ref;
	logic fr1_dut;
	logic dfr_ref;
	logic dfr_dut;

	initial begin
		$dumpfile("wave.vcd");
		$dumpvars(1, stim1.clk, tb_mismatch ,clk,reset,s,fr3_ref,fr3_dut,fr2_ref,fr2_dut,fr1_ref,fr1_dut,dfr_ref,dfr_dut );
	end

	wire tb_match;		// Verification
	wire tb_mismatch = ~tb_match;

	stimulus_gen stim1 (
		.clk,
		.* ,
		.reset,
		.s );
	reference_module good1 (
		.clk,
		.reset,
		.s,
		.fr3(fr3_ref),
		.fr2(fr2_ref),
		.fr1(fr1_ref),
		.dfr(dfr_ref) );

	top_module top_module1 (
		.clk,
		.reset,
		.s,
		.fr3(fr3_dut),
		.fr2(fr2_dut),
		.fr1(fr1_dut),
		.dfr(dfr_dut) );

	bit strobe = 0;
	task wait_for_end_of_timestep;
		repeat(5) begin
			strobe <= !strobe;  // Try to delay until the very end of the time step.
			@(strobe);
		end
	endtask

	final begin
		if (stats1.errors_fr3) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "fr3", stats1.errors_fr3, stats1.errortime_fr3);
		else $display("Hint: Output '%s' has no mismatches.", "fr3");
		if (stats1.errors_fr2) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "fr2", stats1.errors_fr2, stats1.errortime_fr2);
		else $display("Hint: Output '%s' has no mismatches.", "fr2");
		if (stats1.errors_fr1) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "fr1", stats1.errors_fr1, stats1.errortime_fr1);
		else $display("Hint: Output '%s' has no mismatches.", "fr1");
		if (stats1.errors_dfr) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "dfr", stats1.errors_dfr, stats1.errortime_dfr);
		else $display("Hint: Output '%s' has no mismatches.", "dfr");

		$display("Hint: Total mismatched samples is %1d out of %1d samples\n", stats1.errors, stats1.clocks);
		$display("Simulation finished at %0d ps", $time);
		$display("Mismatches: %1d in %1d samples", stats1.errors, stats1.clocks);
	end

	// Verification: XORs on the right makes any X in good_vector match anything, but X in dut_vector will only match X.
	assign tb_match = ( { fr3_ref, fr2_ref, fr1_ref, dfr_ref } === ( { fr3_ref, fr2_ref, fr1_ref, dfr_ref } ^ { fr3_dut, fr2_dut, fr1_dut, dfr_dut } ^ { fr3_ref, fr2_ref, fr1_ref, dfr_ref } ) );
	// Use explicit sensitivity list here. @(*) causes NetProc::nex_input() to be called when trying to compute
	// the sensitivity list of the @(strobe) process, which isn't implemented.
	always @(posedge clk, negedge clk) begin

		stats1.clocks++;
		if (!tb_match) begin
			if (stats1.errors == 0) stats1.errortime = $time;
			stats1.errors++;
		end
		if (fr3_ref !== ( fr3_ref ^ fr3_dut ^ fr3_ref ))
		begin if (stats1.errors_fr3 == 0) stats1.errortime_fr3 = $time;
			stats1.errors_fr3 = stats1.errors_fr3+1'b1; end
		if (fr2_ref !== ( fr2_ref ^ fr2_dut ^ fr2_ref ))
		begin if (stats1.errors_fr2 == 0) stats1.errortime_fr2 = $time;
			stats1.errors_fr2 = stats1.errors_fr2+1'b1; end
		if (fr1_ref !== ( fr1_ref ^ fr1_dut ^ fr1_ref ))
		begin if (stats1.errors_fr1 == 0) stats1.errortime_fr1 = $time;
			stats1.errors_fr1 = stats1.errors_fr1+1'b1; end
		if (dfr_ref !== ( dfr_ref ^ dfr_dut ^ dfr_ref ))
		begin if (stats1.errors_dfr == 0) stats1.errortime_dfr = $time;
			stats1.errors_dfr = stats1.errors_dfr+1'b1; end

	end
endmodule

detail_description:
A large reservior of water serves several users. In order to keep the level of water succificently high, three sensors are placed vertically at 5-inch intervals. When the water level is above the highest sensor s[3], the input flow rate should be zero. When the level is below the lowest sensor s[1], the flow rate should be at maximum (both Nominal flow valve and Supplemental flow valve opened). The flow rate when the level is between the upper and lower sensors is determined by two factors: the water level and the level previous to the last sensor change. Each water level has a nominal flow rate associated with it as show in the table below. If the sensor change indicates that the previous level was lower than the current level, the flow rate should be increased by opening the Supplemental flow valve (controlled by dfr).
// Water Level | Sensors Asserted | Nominal Flow Rate Inputs to be Asserted
// Above s[3] | s[1], s[2], s[3] | None
// Between s[3] and s[2] | s[1], s[2] | fr1
// Between s[2] and s[1]  | s[1] | fr1, fr2
// Below s[1] | None | fr1, fr2, fr3
// Also include an active-high synchronous reset that resets the state machine to a state equivalent to if the water level had been low for a long time (no sensors asserted, and all four outputs asserted).


prompt:
module top_module (
	input [1023:0] in,
	input [7:0] sel,
	output [3:0] out
);

test:
`timescale 1 ps/1 ps
`define OK 12
`define INCORRECT 13
module reference_module (
	input [1023:0] in,
	input [7:0] sel,
	output [3:0] out
);

	assign out = {in[sel*4+3], in[sel*4+2], in[sel*4+1], in[sel*4+0]};

endmodule

module stimulus_gen (
	input clk,
	output logic [1023:0] in,
	output logic [7:0] sel
);

	always @(posedge clk, negedge clk) begin
		for (int i=0;i<32; i++)
			in[i*32+:32] <= $random;
		sel <= $random;
	end

	initial begin
		repeat(1000) @(negedge clk);
		$finish;
	end

endmodule

module tb();

	typedef struct packed {
		int errors;
		int errortime;
		int errors_out;
		int errortime_out;

		int clocks;
	} stats;

	stats stats1;

	wire[511:0] wavedrom_title;
	wire wavedrom_enable;
	int wavedrom_hide_after_time;

	reg clk=0;
	initial forever
		#5 clk = ~clk;

	logic [1023:0] in;
	logic [7:0] sel;
	logic [3:0] out_ref;
	logic [3:0] out_dut;

	initial begin
		$dumpfile("wave.vcd");
		$dumpvars(1, stim1.clk, tb_mismatch ,in,sel,out_ref,out_dut );
	end

	wire tb_match;		// Verification
	wire tb_mismatch = ~tb_match;

	stimulus_gen stim1 (
		.clk,
		.* ,
		.in,
		.sel );
	reference_module good1 (
		.in,
		.sel,
		.out(out_ref) );

	top_module top_module1 (
		.in,
		.sel,
		.out(out_dut) );

	bit strobe = 0;
	task wait_for_end_of_timestep;
		repeat(5) begin
			strobe <= !strobe;  // Try to delay until the very end of the time step.
			@(strobe);
		end
	endtask

	final begin
		if (stats1.errors_out) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "out", stats1.errors_out, stats1.errortime_out);
		else $display("Hint: Output '%s' has no mismatches.", "out");

		$display("Hint: Total mismatched samples is %1d out of %1d samples\n", stats1.errors, stats1.clocks);
		$display("Simulation finished at %0d ps", $time);
		$display("Mismatches: %1d in %1d samples", stats1.errors, stats1.clocks);
	end

	// Verification: XORs on the right makes any X in good_vector match anything, but X in dut_vector will only match X.
	assign tb_match = ( { out_ref } === ( { out_ref } ^ { out_dut } ^ { out_ref } ) );
	// Use explicit sensitivity list here. @(*) causes NetProc::nex_input() to be called when trying to compute
	// the sensitivity list of the @(strobe) process, which isn't implemented.
	always @(posedge clk, negedge clk) begin

		stats1.clocks++;
		if (!tb_match) begin
			if (stats1.errors == 0) stats1.errortime = $time;
			stats1.errors++;
		end
		if (out_ref !== ( out_ref ^ out_dut ^ out_ref ))
		begin if (stats1.errors_out == 0) stats1.errortime_out = $time;
			stats1.errors_out = stats1.errors_out+1'b1; end

	end
endmodule

detail_description: Create a 4-bit wide, 256-to-1 multiplexer. The 256 4-bit inputs are all packed into a single 1024-bit input vector. sel=0 should select bits in[3:0], sel=1 selects bits in[7:4], sel=2 selects bits in[11:8], etc.


task_id: hadd

prompt:
module top_module (
	input a,
	input b,
	output sum,
	output cout
);

canonical_solution:
	assign {cout, sum} = a+b;

endmodule

test:
`timescale 1 ps/1 ps
`define OK 12
`define INCORRECT 13
module reference_module (
	input a,
	input b,
	output sum,
	output cout
);

	assign {cout, sum} = a+b;

endmodule

module stimulus_gen (
	input clk,
	output logic a,b
);

	always @(posedge clk, negedge clk)
		{a,b} <= $random;

	initial begin
		repeat(100) @(negedge clk);
		$finish;
	end

endmodule
module tb();

	typedef struct packed {
		int errors;
		int errortime;
		int errors_sum;
		int errortime_sum;
		int errors_cout;
		int errortime_cout;

		int clocks;
	} stats;

	stats stats1;

	wire[511:0] wavedrom_title;
	wire wavedrom_enable;
	int wavedrom_hide_after_time;

	reg clk=0;
	initial forever
		#5 clk = ~clk;

	logic a;
	logic b;
	logic sum_ref;
	logic sum_dut;
	logic cout_ref;
	logic cout_dut;

	initial begin
		$dumpfile("wave.vcd");
		$dumpvars(1, stim1.clk, tb_mismatch ,a,b,sum_ref,sum_dut,cout_ref,cout_dut );
	end

	wire tb_match;		// Verification
	wire tb_mismatch = ~tb_match;

	stimulus_gen stim1 (
		.clk,
		.* ,
		.a,
		.b );
	reference_module good1 (
		.a,
		.b,
		.sum(sum_ref),
		.cout(cout_ref) );

	top_module top_module1 (
		.a,
		.b,
		.sum(sum_dut),
		.cout(cout_dut) );

	bit strobe = 0;
	task wait_for_end_of_timestep;
		repeat(5) begin
			strobe <= !strobe;  // Try to delay until the very end of the time step.
			@(strobe);
		end
	endtask

	final begin
		if (stats1.errors_sum) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "sum", stats1.errors_sum, stats1.errortime_sum);
		else $display("Hint: Output '%s' has no mismatches.", "sum");
		if (stats1.errors_cout) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "cout", stats1.errors_cout, stats1.errortime_cout);
		else $display("Hint: Output '%s' has no mismatches.", "cout");

		$display("Hint: Total mismatched samples is %1d out of %1d samples\n", stats1.errors, stats1.clocks);
		$display("Simulation finished at %0d ps", $time);
		$display("Mismatches: %1d in %1d samples", stats1.errors, stats1.clocks);
	end

	// Verification: XORs on the right makes any X in good_vector match anything, but X in dut_vector will only match X.
	assign tb_match = ( { sum_ref, cout_ref } === ( { sum_ref, cout_ref } ^ { sum_dut, cout_dut } ^ { sum_ref, cout_ref } ) );
	// Use explicit sensitivity list here. @(*) causes NetProc::nex_input() to be called when trying to compute
	// the sensitivity list of the @(strobe) process, which isn't implemented.
	always @(posedge clk, negedge clk) begin

		stats1.clocks++;
		if (!tb_match) begin
			if (stats1.errors == 0) stats1.errortime = $time;
			stats1.errors++;
		end
		if (sum_ref !== ( sum_ref ^ sum_dut ^ sum_ref ))
		begin if (stats1.errors_sum == 0) stats1.errortime_sum = $time;
			stats1.errors_sum = stats1.errors_sum+1'b1; end
		if (cout_ref !== ( cout_ref ^ cout_dut ^ cout_ref ))
		begin if (stats1.errors_cout == 0) stats1.errortime_cout = $time;
			stats1.errors_cout = stats1.errors_cout+1'b1; end

	end
endmodule

detail_description: Create a half adder. A half adder adds two bits (with no carry-in) and produces a sum and carry-out.


prompt:
module top_module (
	input clk,
	input a,
	output reg [2:0] q
);

test:
`timescale 1 ps/1 ps
`define OK 12
`define INCORRECT 13
module reference_module (
	input clk,
	input a,
	output reg [2:0] q
);

	always @(posedge clk)
		if (a)
			q <= 4;
		else if (q == 6)
			q <= 0;
		else
			q <= q + 1'b1;

endmodule

module stimulus_gen (
	input clk,
	output logic a,
	output reg[511:0] wavedrom_title,
	output reg wavedrom_enable
);

// Add two ports to module stimulus_gen:
//    output [511:0] wavedrom_title
//    output reg wavedrom_enable

	task wavedrom_start(input[511:0] title = "");
	endtask

	task wavedrom_stop;
		#1;
	endtask

	initial begin
		a <= 1;
		@(negedge clk) {a} <= 1;
		@(negedge clk) wavedrom_start("Unknown circuit");
			repeat(2) @(posedge clk);
			@(posedge clk) {a} <= 0;
			repeat(11) @(posedge clk);
			@(negedge clk) a <= 1;
			repeat(5) @(posedge clk, negedge clk);
			a <= 0;
			repeat(4) @(posedge clk);
		wavedrom_stop();

		repeat(200) @(posedge clk, negedge clk)
			a <= &((5)'($urandom));
		$finish;
	end

endmodule

module tb();

	typedef struct packed {
		int errors;
		int errortime;
		int errors_q;
		int errortime_q;

		int clocks;
	} stats;

	stats stats1;

	wire[511:0] wavedrom_title;
	wire wavedrom_enable;
	int wavedrom_hide_after_time;

	reg clk=0;
	initial forever
		#5 clk = ~clk;

	logic a;
	logic [2:0] q_ref;
	logic [2:0] q_dut;

	initial begin
		$dumpfile("wave.vcd");
		$dumpvars(1, stim1.clk, tb_mismatch ,clk,a,q_ref,q_dut );
	end

	wire tb_match;		// Verification
	wire tb_mismatch = ~tb_match;

	stimulus_gen stim1 (
		.clk,
		.* ,
		.a );
	reference_module good1 (
		.clk,
		.a,
		.q(q_ref) );

	top_module top_module1 (
		.clk,
		.a,
		.q(q_dut) );

	bit strobe = 0;
	task wait_for_end_of_timestep;
		repeat(5) begin
			strobe <= !strobe;  // Try to delay until the very end of the time step.
			@(strobe);
		end
	endtask

	final begin
		if (stats1.errors_q) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "q", stats1.errors_q, stats1.errortime_q);
		else $display("Hint: Output '%s' has no mismatches.", "q");

		$display("Hint: Total mismatched samples is %1d out of %1d samples\n", stats1.errors, stats1.clocks);
		$display("Simulation finished at %0d ps", $time);
		$display("Mismatches: %1d in %1d samples", stats1.errors, stats1.clocks);
	end

	// Verification: XORs on the right makes any X in good_vector match anything, but X in dut_vector will only match X.
	assign tb_match = ( { q_ref } === ( { q_ref } ^ { q_dut } ^ { q_ref } ) );
	// Use explicit sensitivity list here. @(*) causes NetProc::nex_input() to be called when trying to compute
	// the sensitivity list of the @(strobe) process, which isn't implemented.
	always @(posedge clk, negedge clk) begin

		stats1.clocks++;
		if (!tb_match) begin
			if (stats1.errors == 0) stats1.errortime = $time;
			stats1.errors++;
		end
		if (q_ref !== ( q_ref ^ q_dut ^ q_ref ))
		begin if (stats1.errors_q == 0) stats1.errortime_q = $time;
			stats1.errors_q = stats1.errors_q+1'b1; end

	end
endmodule

detail_description:
This is a sequential circuit. Read the simulation waveforms to determine what the circuit does, then implement it.

// time            clk             a               q
// 0ns             0               1               x
// 5ns             1               1               4
// 10ns            0               1               4
// 15ns            1               1               4
// 20ns            0               1               4
// 25ns            1               1               4
// 30ns            0               1               4
// 35ns            1               1               4
// 40ns            0               1               4
// 45ns            1               0               4
// 50ns            0               0               4
// 55ns            1               0               5
// 60ns            0               0               5
// 65ns            1               0               6
// 70ns            0               0               6
// 75ns            1               0               0
// 80ns            0               0               0
// 85ns            1               0               1
// 90ns            0               0               1


prompt:
module top_module (
	input clk,
	input j,
	input k,
	output reg Q
);

test:
`timescale 1 ps/1 ps
`define OK 12
`define INCORRECT 13
module reference_module (
	input clk,
	input j,
	input k,
	output reg Q
);

	always @(posedge clk)
		Q <= j&~Q | ~k&Q;

endmodule

module stimulus_gen (
	input clk,
	output logic j, k,
	output reg[511:0] wavedrom_title,
	output reg wavedrom_enable
);

// Add two ports to module stimulus_gen:
//    output [511:0] wavedrom_title
//    output reg wavedrom_enable

	task wavedrom_start(input[511:0] title = "");
	endtask

	task wavedrom_stop;
		#1;
	endtask

	initial begin
		{j,k} <= 1;

		@(negedge clk) wavedrom_start();
			@(posedge clk) {j,k} <= 2'h1;
			@(posedge clk) {j,k} <= 2'h2;
			@(posedge clk) {j,k} <= 2'h3;
			@(posedge clk) {j,k} <= 2'h3;
			@(posedge clk) {j,k} <= 2'h3;
			@(posedge clk) {j,k} <= 2'h0;
			@(posedge clk) {j,k} <= 2'h0;
			@(posedge clk) {j,k} <= 2'h0;
			@(posedge clk) {j,k} <= 2'h2;
			@(posedge clk) {j,k} <= 2'h2;
		@(negedge clk) wavedrom_stop();
		repeat(400) @(posedge clk, negedge clk)
			{j,k} <= $random;
		$finish;
	end

endmodule

module tb();

	typedef struct packed {
		int errors;
		int errortime;
		int errors_Q;
		int errortime_Q;

		int clocks;
	} stats;

	stats stats1;

	wire[511:0] wavedrom_title;
	wire wavedrom_enable;
	int wavedrom_hide_after_time;

	reg clk=0;
	initial forever
		#5 clk = ~clk;

	logic j;
	logic k;
	logic Q_ref;
	logic Q_dut;

	initial begin
		$dumpfile("wave.vcd");
		$dumpvars(1, stim1.clk, tb_mismatch ,clk,j,k,Q_ref,Q_dut );
	end

	wire tb_match;		// Verification
	wire tb_mismatch = ~tb_match;

	stimulus_gen stim1 (
		.clk,
		.* ,
		.j,
		.k );
	reference_module good1 (
		.clk,
		.j,
		.k,
		.Q(Q_ref) );

	top_module top_module1 (
		.clk,
		.j,
		.k,
		.Q(Q_dut) );

	bit strobe = 0;
	task wait_for_end_of_timestep;
		repeat(5) begin
			strobe <= !strobe;  // Try to delay until the very end of the time step.
			@(strobe);
		end
	endtask

	final begin
		if (stats1.errors_Q) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "Q", stats1.errors_Q, stats1.errortime_Q);
		else $display("Hint: Output '%s' has no mismatches.", "Q");

		$display("Hint: Total mismatched samples is %1d out of %1d samples\n", stats1.errors, stats1.clocks);
		$display("Simulation finished at %0d ps", $time);
		$display("Mismatches: %1d in %1d samples", stats1.errors, stats1.clocks);
	end

	// Verification: XORs on the right makes any X in good_vector match anything, but X in dut_vector will only match X.
	assign tb_match = ( { Q_ref } === ( { Q_ref } ^ { Q_dut } ^ { Q_ref } ) );
	// Use explicit sensitivity list here. @(*) causes NetProc::nex_input() to be called when trying to compute
	// the sensitivity list of the @(strobe) process, which isn't implemented.
	always @(posedge clk, negedge clk) begin

		stats1.clocks++;
		if (!tb_match) begin
			if (stats1.errors == 0) stats1.errortime = $time;
			stats1.errors++;
		end
		if (Q_ref !== ( Q_ref ^ Q_dut ^ Q_ref ))
		begin if (stats1.errors_Q == 0) stats1.errortime_Q = $time;
			stats1.errors_Q = stats1.errors_Q+1'b1; end

	end
endmodule

detail_description:
A JK flip-flop has the below truth table. Note: Qold is the output of the flip-flop before the positive clock edge.
// J | K | Q
// 0 | 0 | Qold
// 0 | 1 | 0
// 1 | 0 | 1
// 1 | 1 | ~Qold


task_id: ringer

prompt:
module top_module(
	input ring,
	input vibrate_mode,
	output ringer,
	output motor
);

test:
`timescale 1 ps/1 ps
`define OK 12
`define INCORRECT 13
module reference_module(
	input ring,
	input vibrate_mode,
	output ringer,
	output motor
);

	assign ringer = ring & ~vibrate_mode;
	assign motor = ring & vibrate_mode;

endmodule

module stimulus_gen (
	input clk,
	output reg ring, vibrate_mode,
	output reg[511:0] wavedrom_title,
	output reg wavedrom_enable
);

// Add two ports to module stimulus_gen:
//    output [511:0] wavedrom_title
//    output reg wavedrom_enable

	task wavedrom_start(input[511:0] title = "");
	endtask

	task wavedrom_stop;
		#1;
	endtask

	initial begin
		int count; count = 0;
		{vibrate_mode,ring} <= 1'b0;
		wavedrom_start();
		repeat(10) @(posedge clk)
			{vibrate_mode,ring} <= count++;
		wavedrom_stop();

		#1 $finish;
	end

endmodule

module tb();

	typedef struct packed {
		int errors;
		int errortime;
		int errors_ringer;
		int errortime_ringer;
		int errors_motor;
		int errortime_motor;

		int clocks;
	} stats;

	stats stats1;

	wire[511:0] wavedrom_title;
	wire wavedrom_enable;
	int wavedrom_hide_after_time;

	reg clk=0;
	initial forever
		#5 clk = ~clk;

	logic ring;
	logic vibrate_mode;
	logic ringer_ref;
	logic ringer_dut;
	logic motor_ref;
	logic motor_dut;

	initial begin
		$dumpfile("wave.vcd");
		$dumpvars(1, stim1.clk, tb_mismatch ,ring,vibrate_mode,ringer_ref,ringer_dut,motor_ref,motor_dut );
	end

	wire tb_match;		// Verification
	wire tb_mismatch = ~tb_match;

	stimulus_gen stim1 (
		.clk,
		.* ,
		.ring,
		.vibrate_mode );
	reference_module good1 (
		.ring,
		.vibrate_mode,
		.ringer(ringer_ref),
		.motor(motor_ref) );

	top_module top_module1 (
		.ring,
		.vibrate_mode,
		.ringer(ringer_dut),
		.motor(motor_dut) );

	bit strobe = 0;
	task wait_for_end_of_timestep;
		repeat(5) begin
			strobe <= !strobe;  // Try to delay until the very end of the time step.
			@(strobe);
		end
	endtask

	final begin
		if (stats1.errors_ringer) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "ringer", stats1.errors_ringer, stats1.errortime_ringer);
		else $display("Hint: Output '%s' has no mismatches.", "ringer");
		if (stats1.errors_motor) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "motor", stats1.errors_motor, stats1.errortime_motor);
		else $display("Hint: Output '%s' has no mismatches.", "motor");

		$display("Hint: Total mismatched samples is %1d out of %1d samples\n", stats1.errors, stats1.clocks);
		$display("Simulation finished at %0d ps", $time);
		$display("Mismatches: %1d in %1d samples", stats1.errors, stats1.clocks);
	end

	// Verification: XORs on the right makes any X in good_vector match anything, but X in dut_vector will only match X.
	assign tb_match = ( { ringer_ref, motor_ref } === ( { ringer_ref, motor_ref } ^ { ringer_dut, motor_dut } ^ { ringer_ref, motor_ref } ) );
	// Use explicit sensitivity list here. @(*) causes NetProc::nex_input() to be called when trying to compute
	// the sensitivity list of the @(strobe) process, which isn't implemented.
	always @(posedge clk, negedge clk) begin

		stats1.clocks++;
		if (!tb_match) begin
			if (stats1.errors == 0) stats1.errortime = $time;
			stats1.errors++;
		end
		if (ringer_ref !== ( ringer_ref ^ ringer_dut ^ ringer_ref ))
		begin if (stats1.errors_ringer == 0) stats1.errortime_ringer = $time;
			stats1.errors_ringer = stats1.errors_ringer+1'b1; end
		if (motor_ref !== ( motor_ref ^ motor_dut ^ motor_ref ))
		begin if (stats1.errors_motor == 0) stats1.errortime_motor = $time;
			stats1.errors_motor = stats1.errors_motor+1'b1; end

	end
endmodule

detail_description: Suppose you are designing a circuit to control a cellphone's ringer and vibration motor. Whenever the phone needs to ring from an incoming call (input ring), your circuit must either turn on the ringer (output ringer = 1) or the motor (output motor = 1), but not both. If the phone is in vibrate mode (input vibrate_mode = 1), turn on the motor. Otherwise, turn on the ringer.


prompt:
module top_module (
	input clk,
	input in,
	input reset,
	output done
);

test:
`timescale 1 ps/1 ps
`define OK 12
`define INCORRECT 13
module reference_module (
	input clk,
	input in,
	input reset,
	output done
);
	parameter B0=0, B1=1, B2=2, B3=3, B4=4, B5=5, B6=6, B7=7, START=8, STOP=9, DONE=10, ERR=11;
	reg [3:0] state;
	reg [3:0] next;

    always_comb begin
		case (state)
			START: next = in ? START : B0;	// start bit is 0
			B0: next = B1;
			B1: next = B2;
			B2: next = B3;
			B3: next = B4;
			B4: next = B5;
			B5: next = B6;
			B6: next = B7;
			B7: next = STOP;
			STOP: next = in ? DONE : ERR;  // stop bit is 1. Idle state is 1.
			DONE: next = in ? START : B0;
			ERR: next = in ? START : ERR;
		endcase
    end

    always @(posedge clk) begin
		if (reset) state <= START;
        else state <= next;
	end

	assign done = (state==DONE);

endmodule

module stimulus_gen (
	input clk,
	output logic in,
	output logic reset
);

	initial begin
		reset <= 1;
		in <= 1;
		@(posedge clk);
		reset <= 0;
		in <= 0;
		repeat(9) @(posedge clk);
		in <= 1;
		@(posedge clk);
		in <= 0;
		repeat(9) @(posedge clk);
		in <= 1;
		@(posedge clk);
		in <= 0;
		repeat(10) @(posedge clk);
		in <= 1;
		@(posedge clk);
		in <= 0;
		repeat(10) @(posedge clk);
		in <= 1;
		@(posedge clk);
		in <= 0;
		repeat(9) @(posedge clk);
		in <= 1;
		@(posedge clk);

		repeat(800) @(posedge clk, negedge clk) begin
			in <= $random;
			reset <= !($random & 31);
		end

		#1 $finish;
	end

endmodule

module tb();

	typedef struct packed {
		int errors;
		int errortime;
		int errors_done;
		int errortime_done;

		int clocks;
	} stats;

	stats stats1;

	wire[511:0] wavedrom_title;
	wire wavedrom_enable;
	int wavedrom_hide_after_time;

	reg clk=0;
	initial forever
		#5 clk = ~clk;

	logic in;
	logic reset;
	logic done_ref;
	logic done_dut;

	initial begin
		$dumpfile("wave.vcd");
		$dumpvars(1, stim1.clk, tb_mismatch ,clk,in,reset,done_ref,done_dut );
	end

	wire tb_match;		// Verification
	wire tb_mismatch = ~tb_match;

	stimulus_gen stim1 (
		.clk,
		.* ,
		.in,
		.reset );
	reference_module good1 (
		.clk,
		.in,
		.reset,
		.done(done_ref) );

	top_module top_module1 (
		.clk,
		.in,
		.reset,
		.done(done_dut) );

	bit strobe = 0;
	task wait_for_end_of_timestep;
		repeat(5) begin
			strobe <= !strobe;  // Try to delay until the very end of the time step.
			@(strobe);
		end
	endtask

	final begin
		if (stats1.errors_done) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "done", stats1.errors_done, stats1.errortime_done);
		else $display("Hint: Output '%s' has no mismatches.", "done");

		$display("Hint: Total mismatched samples is %1d out of %1d samples\n", stats1.errors, stats1.clocks);
		$display("Simulation finished at %0d ps", $time);
		$display("Mismatches: %1d in %1d samples", stats1.errors, stats1.clocks);
	end

	// Verification: XORs on the right makes any X in good_vector match anything, but X in dut_vector will only match X.
	assign tb_match = ( { done_ref } === ( { done_ref } ^ { done_dut } ^ { done_ref } ) );
	// Use explicit sensitivity list here. @(*) causes NetProc::nex_input() to be called when trying to compute
	// the sensitivity list of the @(strobe) process, which isn't implemented.
	always @(posedge clk, negedge clk) begin

		stats1.clocks++;
		if (!tb_match) begin
			if (stats1.errors == 0) stats1.errortime = $time;
			stats1.errors++;
		end
		if (done_ref !== ( done_ref ^ done_dut ^ done_ref ))
		begin if (stats1.errors_done == 0) stats1.errortime_done = $time;
			stats1.errors_done = stats1.errors_done+1'b1; end

	end
endmodule

detail_description: In many (older) serial communications protocols, each data byte is sent along with a start bit and a stop bit, to help the receiver delimit bytes from the stream of bits. One common scheme is to use one start bit (0), 8 data bits, and 1 stop bit (1). The line is also at logic 1 when nothing is being transmitted (idle). Design a finite state machine that will identify when bytes have been correctly received when given a stream of bits. It needs to identify the start bit, wait for all 8 data bits, then verify that the stop bit was correct. If the stop bit does not appear when expected, the FSM must wait until it finds a stop bit before attempting to receive the next byte. Include a active-high synchronous reset. Note that the serial protocol sends the least significant bit first.


task_id: timer

prompt:
module top_module(
	input clk,
	input load,
	input [9:0] data,
	output tc
);

test:
`timescale 1 ps/1 ps
`define OK 12
`define INCORRECT 13
module reference_module(
	input clk,
	input load,
	input [9:0] data,
	output tc
);
	logic [9:0] count_value;

	always @(posedge clk)
		if(load) count_value <= data;
		else if(count_value != 0) count_value <= count_value - 1;

	assign tc = count_value == 0;

endmodule

module stimulus_gen(
	input clk,
	output logic load,
	output logic [9:0] data,
	input tb_match,
	output reg[511:0] wavedrom_title,
	output reg wavedrom_enable,
	output int wavedrom_hide_after_time
);

// Add two ports to module stimulus_gen:
//    output [511:0] wavedrom_title
//    output reg wavedrom_enable

	task wavedrom_start(input[511:0] title = "");
	endtask

	task wavedrom_stop;
		#1;
	endtask

	initial begin
		load <= 1'b0;
		wavedrom_start("Count 3, then 10 cycles");
			@(posedge clk) {data, load} <= {10'd3, 1'b1};
			@(posedge clk) {data, load} <= {10'hx, 1'b0};
			@(posedge clk) load <= 0;
			@(posedge clk) load <= 0;
			@(posedge clk) load <= 0;
			@(posedge clk) {data, load} <= {10'd10, 1'b1};
			@(posedge clk) {data, load} <= {10'hx, 1'b0};
			repeat(12) @(posedge clk);
		wavedrom_stop();

		@(posedge clk) {load, data} <= {1'b1, 10'h10};
		@(posedge clk) {load, data} <= {1'b0, 10'h10};
		@(posedge clk) {load, data} <= {1'b1, 10'h0};   // Load 0
		@(posedge clk) {load, data} <= {1'b1, 10'h3ff}; // Load 1023
		@(posedge clk) {load, data} <= {1'b0, 10'h0};
		repeat(1040) @(posedge clk);

		repeat(2500) @(posedge clk) begin
			load <= !($urandom & 10'hf);
			data <= $urandom_range(0,32);
		end

		#1 $finish;
	end

endmodule
module tb();

	typedef struct packed {
		int errors;
		int errortime;
		int errors_tc;
		int errortime_tc;

		int clocks;
	} stats;

	stats stats1;

	wire[511:0] wavedrom_title;
	wire wavedrom_enable;
	int wavedrom_hide_after_time;

	reg clk=0;
	initial forever
		#5 clk = ~clk;

	logic load;
	logic [9:0] data;
	logic tc_ref;
	logic tc_dut;

	initial begin
		$dumpfile("wave.vcd");
		$dumpvars(1, stim1.clk, tb_mismatch ,clk,load,data,tc_ref,tc_dut );
	end

	wire tb_match;		// Verification
	wire tb_mismatch = ~tb_match;

	stimulus_gen stim1 (
		.clk,
		.* ,
		.load,
		.data );
	reference_module good1 (
		.clk,
		.load,
		.data,
		.tc(tc_ref) );

	top_module top_module1 (
		.clk,
		.load,
		.data,
		.tc(tc_dut) );

	bit strobe = 0;
	task wait_for_end_of_timestep;
		repeat(5) begin
			strobe <= !strobe;  // Try to delay until the very end of the time step.
			@(strobe);
		end
	endtask

	final begin
		if (stats1.errors_tc) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "tc", stats1.errors_tc, stats1.errortime_tc);
		else $display("Hint: Output '%s' has no mismatches.", "tc");

		$display("Hint: Total mismatched samples is %1d out of %1d samples\n", stats1.errors, stats1.clocks);
		$display("Simulation finished at %0d ps", $time);
		$display("Mismatches: %1d in %1d samples", stats1.errors, stats1.clocks);
	end

	// Verification: XORs on the right makes any X in good_vector match anything, but X in dut_vector will only match X.
	assign tb_match = ( { tc_ref } === ( { tc_ref } ^ { tc_dut } ^ { tc_ref } ) );
	// Use explicit sensitivity list here. @(*) causes NetProc::nex_input() to be called when trying to compute
	// the sensitivity list of the @(strobe) process, which isn't implemented.
	always @(posedge clk, negedge clk) begin

		stats1.clocks++;
		if (!tb_match) begin
			if (stats1.errors == 0) stats1.errortime = $time;
			stats1.errors++;
		end
		if (tc_ref !== ( tc_ref ^ tc_dut ^ tc_ref ))
		begin if (stats1.errors_tc == 0) stats1.errortime_tc = $time;
			stats1.errors_tc = stats1.errors_tc+1'b1; end

	end
endmodule

detail_description:
Implement a timer that counts down for a given number of clock cycles, then asserts a signal to indicate that the given duration has elapsed. A good way to implement this is with a down-counter that asserts an output signal when the count becomes 0. At each clock cycle:
// (1) If load = 1, load the internal counter with the 10-bit data, the number of clock cycles the timer should count before timing out. The counter can be loaded at any time, including when it is still counting and has not yet reached 0.
// (2) If load = 0, the internal counter should decrement by 1. The output signal tc ("terminal count") indicates whether the internal counter has reached 0. Once the internal counter has reached 0, it should stay 0 (stop counting) until the counter is loaded again.


prompt:
module top_module (
	input clk,
	input a,
	output reg q
);

test:
`timescale 1 ps/1 ps
`define OK 12
`define INCORRECT 13
module reference_module (
	input clk,
	input a,
	output reg q
);

	always @(posedge clk)
		q <= ~a;

endmodule

module stimulus_gen (
	input clk,
	output logic a,
	output reg[511:0] wavedrom_title,
	output reg wavedrom_enable
);

// Add two ports to module stimulus_gen:
//    output [511:0] wavedrom_title
//    output reg wavedrom_enable

	task wavedrom_start(input[511:0] title = "");
	endtask

	task wavedrom_stop;
		#1;
	endtask

	initial begin
		@(posedge clk) {a} <= 0;
		@(negedge clk) wavedrom_start("Unknown circuit");
			@(posedge clk) {a} <= 0;
			repeat(10) @(posedge clk) a <= $urandom;
		wavedrom_stop();

		repeat(100) @(posedge clk, negedge clk)
			a <= $urandom;
		$finish;
	end

endmodule

module tb();

	typedef struct packed {
		int errors;
		int errortime;
		int errors_q;
		int errortime_q;

		int clocks;
	} stats;

	stats stats1;

	wire[511:0] wavedrom_title;
	wire wavedrom_enable;
	int wavedrom_hide_after_time;

	reg clk=0;
	initial forever
		#5 clk = ~clk;

	logic a;
	logic q_ref;
	logic q_dut;

	initial begin
		$dumpfile("wave.vcd");
		$dumpvars(1, stim1.clk, tb_mismatch ,clk,a,q_ref,q_dut );
	end

	wire tb_match;		// Verification
	wire tb_mismatch = ~tb_match;

	stimulus_gen stim1 (
		.clk,
		.* ,
		.a );
	reference_module good1 (
		.clk,
		.a,
		.q(q_ref) );

	top_module top_module1 (
		.clk,
		.a,
		.q(q_dut) );

	bit strobe = 0;
	task wait_for_end_of_timestep;
		repeat(5) begin
			strobe <= !strobe;  // Try to delay until the very end of the time step.
			@(strobe);
		end
	endtask

	final begin
		if (stats1.errors_q) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "q", stats1.errors_q, stats1.errortime_q);
		else $display("Hint: Output '%s' has no mismatches.", "q");

		$display("Hint: Total mismatched samples is %1d out of %1d samples\n", stats1.errors, stats1.clocks);
		$display("Simulation finished at %0d ps", $time);
		$display("Mismatches: %1d in %1d samples", stats1.errors, stats1.clocks);
	end

	// Verification: XORs on the right makes any X in good_vector match anything, but X in dut_vector will only match X.
	assign tb_match = ( { q_ref } === ( { q_ref } ^ { q_dut } ^ { q_ref } ) );
	// Use explicit sensitivity list here. @(*) causes NetProc::nex_input() to be called when trying to compute
	// the sensitivity list of the @(strobe) process, which isn't implemented.
	always @(posedge clk, negedge clk) begin

		stats1.clocks++;
		if (!tb_match) begin
			if (stats1.errors == 0) stats1.errortime = $time;
			stats1.errors++;
		end
		if (q_ref !== ( q_ref ^ q_dut ^ q_ref ))
		begin if (stats1.errors_q == 0) stats1.errortime_q = $time;
			stats1.errors_q = stats1.errors_q+1'b1; end

	end
endmodule

detail_description:
This is a sequential circuit. Read the simulation waveforms to determine what the circuit does, then implement it.

// time            clk             a               q
// 0ns             0               x               x
// 5ns             1               0               x
// 10ns            0               0               x
// 15ns            1               0               1
// 20ns            0               0               1
// 25ns            1               0               1
// 30ns            0               0               1
// 35ns            1               1               1
// 40ns            0               1               1
// 45ns            1               1               0
// 50ns            0               1               0
// 55ns            1               1               0
// 60ns            0               1               0
// 65ns            1               1               0
// 70ns            0               1               0
// 75ns            1               1               0
// 80ns            0               1               0
// 85ns            1               1               0
// 90ns            0               1               0


prompt:
module top_module (
	input [99:0] in,
	output [98:0] out_both,
	output [99:1] out_any,
	output [99:0] out_different
);

test:
`timescale 1 ps/1 ps
`define OK 12
`define INCORRECT 13
module reference_module (
	input [99:0] in,
	output [98:0] out_both,
	output [99:1] out_any,
	output [99:0] out_different
);

	assign out_both = in & in[99:1];
	assign out_any = in | in[99:1];
	assign out_different = in^{in[0], in[99:1]};

endmodule

module stimulus_gen (
	input clk,
	input tb_match,
	output logic [99:0] in
);

	initial begin
		in <= $random;
		repeat(100) begin
			@(negedge clk) in <= $random;
			@(posedge clk) in <= $random;
		end
		#1 $finish;
	end

endmodule

module tb();

	typedef struct packed {
		int errors;
		int errortime;
		int errors_out_both;
		int errortime_out_both;
		int errors_out_any;
		int errortime_out_any;
		int errors_out_different;
		int errortime_out_different;

		int clocks;
	} stats;

	stats stats1;

	wire[511:0] wavedrom_title;
	wire wavedrom_enable;
	int wavedrom_hide_after_time;

	reg clk=0;
	initial forever
		#5 clk = ~clk;

	logic [99:0] in;
	logic [98:0] out_both_ref;
	logic [98:0] out_both_dut;
	logic [99:1] out_any_ref;
	logic [99:1] out_any_dut;
	logic [99:0] out_different_ref;
	logic [99:0] out_different_dut;

	initial begin
		$dumpfile("wave.vcd");
		$dumpvars(1, stim1.clk, tb_mismatch ,in,out_both_ref,out_both_dut,out_any_ref,out_any_dut,out_different_ref,out_different_dut );
	end

	wire tb_match;		// Verification
	wire tb_mismatch = ~tb_match;

	stimulus_gen stim1 (
		.clk,
		.* ,
		.in );
	reference_module good1 (
		.in,
		.out_both(out_both_ref),
		.out_any(out_any_ref),
		.out_different(out_different_ref) );

	top_module top_module1 (
		.in,
		.out_both(out_both_dut),
		.out_any(out_any_dut),
		.out_different(out_different_dut) );

	bit strobe = 0;
	task wait_for_end_of_timestep;
		repeat(5) begin
			strobe <= !strobe;  // Try to delay until the very end of the time step.
			@(strobe);
		end
	endtask

	final begin
		if (stats1.errors_out_both) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "out_both", stats1.errors_out_both, stats1.errortime_out_both);
		else $display("Hint: Output '%s' has no mismatches.", "out_both");
		if (stats1.errors_out_any) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "out_any", stats1.errors_out_any, stats1.errortime_out_any);
		else $display("Hint: Output '%s' has no mismatches.", "out_any");
		if (stats1.errors_out_different) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "out_different", stats1.errors_out_different, stats1.errortime_out_different);
		else $display("Hint: Output '%s' has no mismatches.", "out_different");

		$display("Hint: Total mismatched samples is %1d out of %1d samples\n", stats1.errors, stats1.clocks);
		$display("Simulation finished at %0d ps", $time);
		$display("Mismatches: %1d in %1d samples", stats1.errors, stats1.clocks);
	end

	// Verification: XORs on the right makes any X in good_vector match anything, but X in dut_vector will only match X.
	assign tb_match = ( { out_both_ref, out_any_ref, out_different_ref } === ( { out_both_ref, out_any_ref, out_different_ref } ^ { out_both_dut, out_any_dut, out_different_dut } ^ { out_both_ref, out_any_ref, out_different_ref } ) );
	// Use explicit sensitivity list here. @(*) causes NetProc::nex_input() to be called when trying to compute
	// the sensitivity list of the @(strobe) process, which isn't implemented.
	always @(posedge clk, negedge clk) begin

		stats1.clocks++;
		if (!tb_match) begin
			if (stats1.errors == 0) stats1.errortime = $time;
			stats1.errors++;
		end
		if (out_both_ref !== ( out_both_ref ^ out_both_dut ^ out_both_ref ))
		begin if (stats1.errors_out_both == 0) stats1.errortime_out_both = $time;
			stats1.errors_out_both = stats1.errors_out_both+1'b1; end
		if (out_any_ref !== ( out_any_ref ^ out_any_dut ^ out_any_ref ))
		begin if (stats1.errors_out_any == 0) stats1.errortime_out_any = $time;
			stats1.errors_out_any = stats1.errors_out_any+1'b1; end
		if (out_different_ref !== ( out_different_ref ^ out_different_dut ^ out_different_ref ))
		begin if (stats1.errors_out_different == 0) stats1.errortime_out_different = $time;
			stats1.errors_out_different = stats1.errors_out_different+1'b1; end

	end
endmodule

detail_description:
You are given a 100-bit input vector in[99:0]. We want to know some relationships between each bit and its neighbour:
// (1) out_both: Each bit of this output vector should indicate whether both the corresponding input bit and its neighbour to the left are '1'. For example, out_both[98] should indicate if in[98] and in[99] are both 1. Since in[99] has no neighbour to the left, the answer is obvious so we don't need to know out_both[99].
// (2) out_any: Each bit of this output vector should indicate whether any of the corresponding input bit and its neighbour to the right are '1'. For example, out_any[2] should indicate if either in[2] or in[1] are 1. Since in[0] has no neighbour to the right, the answer is obvious so we don't need to know out_any[0].
// (3) out_different: Each bit of this output vector should indicate whether the corresponding input bit is different from its neighbour to the left. For example, out_different[98] should indicate if in[98] is different from in[99]. For this part, treat the vector as wrapping around, so in[99]'s neighbour to the left is in[0].


prompt:
module top_module (
	input [99:0] in,
	output reg [99:0] out
);

test:
`timescale 1 ps/1 ps
`define OK 12
`define INCORRECT 13
module reference_module (
	input [99:0] in,
	output reg [99:0] out
);

	always_comb
		for (int i=0;i<$bits(out);i++)
			out[i] = in[$bits(out)-i-1];

endmodule

module stimulus_gen (
	input clk,
	output logic [99:0] in
);

	always @(posedge clk, negedge clk)
		in <= {$random, $random, $random, $random};

	initial begin
		repeat(100) @(negedge clk);
		$finish;
	end

endmodule

module tb();

	typedef struct packed {
		int errors;
		int errortime;
		int errors_out;
		int errortime_out;

		int clocks;
	} stats;

	stats stats1;

	wire[511:0] wavedrom_title;
	wire wavedrom_enable;
	int wavedrom_hide_after_time;

	reg clk=0;
	initial forever
		#5 clk = ~clk;

	logic [99:0] in;
	logic [99:0] out_ref;
	logic [99:0] out_dut;

	initial begin
		$dumpfile("wave.vcd");
		$dumpvars(1, stim1.clk, tb_mismatch ,in,out_ref,out_dut );
	end

	wire tb_match;		// Verification
	wire tb_mismatch = ~tb_match;

	stimulus_gen stim1 (
		.clk,
		.* ,
		.in );
	reference_module good1 (
		.in,
		.out(out_ref) );

	top_module top_module1 (
		.in,
		.out(out_dut) );

	bit strobe = 0;
	task wait_for_end_of_timestep;
		repeat(5) begin
			strobe <= !strobe;  // Try to delay until the very end of the time step.
			@(strobe);
		end
	endtask

	final begin
		if (stats1.errors_out) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "out", stats1.errors_out, stats1.errortime_out);
		else $display("Hint: Output '%s' has no mismatches.", "out");

		$display("Hint: Total mismatched samples is %1d out of %1d samples\n", stats1.errors, stats1.clocks);
		$display("Simulation finished at %0d ps", $time);
		$display("Mismatches: %1d in %1d samples", stats1.errors, stats1.clocks);
	end

	// Verification: XORs on the right makes any X in good_vector match anything, but X in dut_vector will only match X.
	assign tb_match = ( { out_ref } === ( { out_ref } ^ { out_dut } ^ { out_ref } ) );
	// Use explicit sensitivity list here. @(*) causes NetProc::nex_input() to be called when trying to compute
	// the sensitivity list of the @(strobe) process, which isn't implemented.
	always @(posedge clk, negedge clk) begin

		stats1.clocks++;
		if (!tb_match) begin
			if (stats1.errors == 0) stats1.errortime = $time;
			stats1.errors++;
		end
		if (out_ref !== ( out_ref ^ out_dut ^ out_ref ))
		begin if (stats1.errors_out == 0) stats1.errortime_out = $time;
			stats1.errors_out = stats1.errors_out+1'b1; end

	end
endmodule

detail_description: Given a 100-bit input vector [99:0], reverse its bit ordering.


task_id: countslow

prompt:
module top_module(
	input clk,
	input slowena,
	input reset,
	output reg [3:0] q);

test:
`timescale 1 ps/1 ps
`define OK 12
`define INCORRECT 13
module reference_module(
	input clk,
	input slowena,
	input reset,
	output reg [3:0] q);

	always @(posedge clk)
		if (reset)
			q <= 0;
		else if (slowena) begin
			if (q == 9)
				q <= 0;
			else
				q <= q+1;
		end

endmodule

module stimulus_gen (
	input clk,
	output reg slowena,
	output reg reset,
	output reg[511:0] wavedrom_title,
	output reg wavedrom_enable,
	input tb_match
);

	task reset_test(input async=0);
		bit arfail, srfail, datafail;

		@(posedge clk);
		@(posedge clk) reset <= 0;
		repeat(3) @(posedge clk);

		@(negedge clk) begin datafail = !tb_match ; reset <= 1; end
		@(posedge clk) arfail = !tb_match;
		@(posedge clk) begin
			srfail = !tb_match;
			reset <= 0;
		end
		if (srfail)
			$display("Hint: Your reset doesn't seem to be working.");
		else if (arfail && (async || !datafail))
			$display("Hint: Your reset should be %0s, but doesn't appear to be.", async ? "asynchronous" : "synchronous");
		// Don't warn about synchronous reset if the half-cycle before is already wrong. It's more likely
		// a functionality error than the reset being implemented asynchronously.

	endtask

// Add two ports to module stimulus_gen:
//    output [511:0] wavedrom_title
//    output reg wavedrom_enable

	task wavedrom_start(input[511:0] title = "");
	endtask

	task wavedrom_stop;
		#1;
	endtask

	reg hint1;
	initial begin
		reset <= 1;
		slowena <= 1;
		wavedrom_start("Synchronous reset and counting.");
		reset_test();
		repeat(12) @(posedge clk);
		wavedrom_stop();
		@(posedge clk);

		//wavedrom_start("Testing.");
		reset <= 1;
		@(posedge clk);
		reset <= 0;
		repeat(9) @(posedge clk);
		slowena <= 0;
		@(negedge clk) hint1 = tb_match;
		repeat(3) @(posedge clk);
		if (hint1 && !tb_match) begin
			$display ("Hint: What is supposed to happen when the counter is 9 and not enabled?");
		end
		//wavedrom_stop();
		slowena <= 1;
		reset <= 1;
		@(posedge clk);
		reset <= 0;

		wavedrom_start("Enable/disable");
		repeat(15) @(posedge clk) slowena <= !($random & 1);
		wavedrom_stop();
		@(posedge clk);

		repeat(400) @(posedge clk, negedge clk) begin
			slowena <= !($random&3);
			reset <= !($random & 31);
		end
		#1 $finish;
	end

endmodule

module tb();

	typedef struct packed {
		int errors;
		int errortime;
		int errors_q;
		int errortime_q;

		int clocks;
	} stats;

	stats stats1;

	wire[511:0] wavedrom_title;
	wire wavedrom_enable;
	int wavedrom_hide_after_time;

	reg clk=0;
	initial forever
		#5 clk = ~clk;

	logic slowena;
	logic reset;
	logic [3:0] q_ref;
	logic [3:0] q_dut;

	initial begin
		$dumpfile("wave.vcd");
		$dumpvars(1, stim1.clk, tb_mismatch ,clk,slowena,reset,q_ref,q_dut );
	end

	wire tb_match;		// Verification
	wire tb_mismatch = ~tb_match;

	stimulus_gen stim1 (
		.clk,
		.* ,
		.slowena,
		.reset );
	reference_module good1 (
		.clk,
		.slowena,
		.reset,
		.q(q_ref) );

	top_module top_module1 (
		.clk,
		.slowena,
		.reset,
		.q(q_dut) );

	bit strobe = 0;
	task wait_for_end_of_timestep;
		repeat(5) begin
			strobe <= !strobe;  // Try to delay until the very end of the time step.
			@(strobe);
		end
	endtask

	final begin
		if (stats1.errors_q) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "q", stats1.errors_q, stats1.errortime_q);
		else $display("Hint: Output '%s' has no mismatches.", "q");

		$display("Hint: Total mismatched samples is %1d out of %1d samples\n", stats1.errors, stats1.clocks);
		$display("Simulation finished at %0d ps", $time);
		$display("Mismatches: %1d in %1d samples", stats1.errors, stats1.clocks);
	end

	// Verification: XORs on the right makes any X in good_vector match anything, but X in dut_vector will only match X.
	assign tb_match = ( { q_ref } === ( { q_ref } ^ { q_dut } ^ { q_ref } ) );
	// Use explicit sensitivity list here. @(*) causes NetProc::nex_input() to be called when trying to compute
	// the sensitivity list of the @(strobe) process, which isn't implemented.
	always @(posedge clk, negedge clk) begin

		stats1.clocks++;
		if (!tb_match) begin
			if (stats1.errors == 0) stats1.errortime = $time;
			stats1.errors++;
		end
		if (q_ref !== ( q_ref ^ q_dut ^ q_ref ))
		begin if (stats1.errors_q == 0) stats1.errortime_q = $time;
			stats1.errors_q = stats1.errors_q+1'b1; end

	end
endmodule

detail_description: Build a decade counter that counts from 0 through 9, inclusive, with a period of 10. The reset input is active high synchronous, and should reset the counter to 0. We want to be able to pause the counter rather than always incrementing every clock cycle, so the "slowena" input if high indicates when the counter should increment.