task_id: gatesv

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

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

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

endmodule

module stimulus_gen (
	input clk,
	input tb_match,
	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 <= 4'h3;
		@(negedge clk);
		wavedrom_start();
			@(posedge clk) in <= 3;
			@(posedge clk) in <= 6;
			@(posedge clk) in <= 12;
			@(posedge clk) in <= 9;
			@(posedge clk) in <= 5;
		@(negedge clk);
		wavedrom_stop();
		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 [3:0] in;
	logic [2:0] out_both_ref;
	logic [2:0] out_both_dut;
	logic [3:1] out_any_ref;
	logic [3:1] out_any_dut;
	logic [3:0] out_different_ref;
	logic [3: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 four-bit input vector in[3: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 (higher index) are '1'. For example, out_both[2] should indicate if in[2] and in[3] are both 1. Since in[3] has no neighbour to the left, the answer is obvious so we don't need to know out_both[3].
// (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[2] should indicate if in[2] is different from in[3]. For this part, treat the vector as wrapping around, so in[3]'s neighbour to the left is in[0].


prompt:
module top_module(
	input clk,
	input load,
	input [1:0] ena,
	input [99:0] data,
	output reg [99:0] q);

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

	always @(posedge clk) begin
		if (load)
			q <= data;
		else if (ena == 2'h1)
			q <= {q[0], q[99:1]};
		else if (ena == 2'h2)
			q <= {q[98:0], q[99]};
	end
endmodule

module stimulus_gen (
	input clk,
	output reg load,
	output reg[1:0] ena,
	output reg[99:0] data
);

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

	initial begin
		load <= 1;
		@(posedge clk);
		@(posedge clk);
		@(posedge clk);
		repeat(4000) @(posedge clk, negedge clk) begin
			load <= !($random & 31);
			ena <= $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 load;
	logic [1:0] ena;
	logic [99:0] data;
	logic [99:0] q_ref;
	logic [99:0] q_dut;

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

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

	stimulus_gen stim1 (
		.clk,
		.* ,
		.load,
		.ena,
		.data );
	reference_module good1 (
		.clk,
		.load,
		.ena,
		.data,
		.q(q_ref) );

	top_module top_module1 (
		.clk,
		.load,
		.ena,
		.data,
		.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 100-bit left/right rotator, with synchronous load and left/right enable. A rotator shifts-in the shifted-out bit from the other end of the register, unlike a shifter that discards the shifted-out bit and shifts in a zero. If enabled, a rotator rotates the bits around and does not modify/discard them.
// (1) load: Loads shift register with data[99:0] instead of rotating. Synchronous active high.
// (2) ena[1:0]: Synchronous. Chooses whether and which direction to rotate:
//     (a) 2'b01 rotates right by one bit,
//     (b) 2'b10 rotates left by one bit,
//     (c) 2'b00 and 2'b11 do not rotate.
// (3) q: The contents of the rotator.


prompt:
module top_module(
    input d,
    input done_counting,
    input ack,
    input [9:0] state,    // 10-bit one-hot current state
    output B3_next,
    output S_next,
    output S1_next,
    output Count_next,
    output Wait_next,
    output done,
    output counting,
    output shift_ena
 );

test:
`timescale 1 ps/1 ps
`define OK 12
`define INCORRECT 13
module reference_module(
    input d,
    input done_counting,
    input ack,
    input [9:0] state,    // 10-bit one-hot current state
    output B3_next,
    output S_next,
    output S1_next,
    output Count_next,
    output Wait_next,
    output done,
    output counting,
    output shift_ena
 );

	 parameter S=0, S1=1, S11=2, S110=3, B0=4, B1=5, B2=6, B3=7, Count=8, Wait=9;

	assign B3_next = state[B2];
	assign S_next = state[S]&~d | state[S1]&~d | state[S110]&~d | state[Wait]&ack;
	assign S1_next = state[S]&d;
	assign Count_next = state[B3] | state[Count]&~done_counting;
	assign Wait_next = state[Count]&done_counting | state[Wait]&~ack;

	assign done = state[Wait];
	assign counting = state[Count];
	assign shift_ena = |state[B3:B0];

endmodule

module stimulus_gen (
	input clk,
	output reg d, done_counting, ack,
	output reg [9:0] state,
	input tb_match
);
	bit failed = 0;
	bit fail_onehot = 0;

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

	initial begin
		{d, done_counting, ack} <= 3'h0;
		state <= 10'h0;

		repeat(300) @(posedge clk, negedge clk) begin
			{d, done_counting, ack} = $random;
			state <= 1<< ($unsigned($random) % 10);
		end

		@(posedge clk) fail_onehot <= failed;

		repeat(3000) @(posedge clk, negedge clk) begin
			{d, done_counting, ack} = $random;
			state <= $random;
		end

		@(posedge clk);
		if (!fail_onehot && failed) begin
			$display ("Hint: Your circuit passed when given only one-hot inputs, but not with random inputs.");
			$display ("Hint: Are you doing something more complicated than deriving state transition equations by inspection?\n");
		end

		#1 $finish;
	end

endmodule

module tb();

	typedef struct packed {
		int errors;
		int errortime;
		int errors_B3_next;
		int errortime_B3_next;
		int errors_S_next;
		int errortime_S_next;
		int errors_S1_next;
		int errortime_S1_next;
		int errors_Count_next;
		int errortime_Count_next;
		int errors_Wait_next;
		int errortime_Wait_next;
		int errors_done;
		int errortime_done;
		int errors_counting;
		int errortime_counting;
		int errors_shift_ena;
		int errortime_shift_ena;

		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 d;
	logic done_counting;
	logic ack;
	logic [9:0] state;
	logic B3_next_ref;
	logic B3_next_dut;
	logic S_next_ref;
	logic S_next_dut;
	logic S1_next_ref;
	logic S1_next_dut;
	logic Count_next_ref;
	logic Count_next_dut;
	logic Wait_next_ref;
	logic Wait_next_dut;
	logic done_ref;
	logic done_dut;
	logic counting_ref;
	logic counting_dut;
	logic shift_ena_ref;
	logic shift_ena_dut;

	initial begin
		$dumpfile("wave.vcd");
		$dumpvars(1, stim1.clk, tb_mismatch ,d,done_counting,ack,state,B3_next_ref,B3_next_dut,S_next_ref,S_next_dut,S1_next_ref,S1_next_dut,Count_next_ref,Count_next_dut,Wait_next_ref,Wait_next_dut,done_ref,done_dut,counting_ref,counting_dut,shift_ena_ref,shift_ena_dut );
	end

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

	stimulus_gen stim1 (
		.clk,
		.* ,
		.d,
		.done_counting,
		.ack,
		.state );
	reference_module good1 (
		.d,
		.done_counting,
		.ack,
		.state,
		.B3_next(B3_next_ref),
		.S_next(S_next_ref),
		.S1_next(S1_next_ref),
		.Count_next(Count_next_ref),
		.Wait_next(Wait_next_ref),
		.done(done_ref),
		.counting(counting_ref),
		.shift_ena(shift_ena_ref) );

	top_module top_module1 (
		.d,
		.done_counting,
		.ack,
		.state,
		.B3_next(B3_next_dut),
		.S_next(S_next_dut),
		.S1_next(S1_next_dut),
		.Count_next(Count_next_dut),
		.Wait_next(Wait_next_dut),
		.done(done_dut),
		.counting(counting_dut),
		.shift_ena(shift_ena_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_B3_next) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "B3_next", stats1.errors_B3_next, stats1.errortime_B3_next);
		else $display("Hint: Output '%s' has no mismatches.", "B3_next");
		if (stats1.errors_S_next) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "S_next", stats1.errors_S_next, stats1.errortime_S_next);
		else $display("Hint: Output '%s' has no mismatches.", "S_next");
		if (stats1.errors_S1_next) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "S1_next", stats1.errors_S1_next, stats1.errortime_S1_next);
		else $display("Hint: Output '%s' has no mismatches.", "S1_next");
		if (stats1.errors_Count_next) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "Count_next", stats1.errors_Count_next, stats1.errortime_Count_next);
		else $display("Hint: Output '%s' has no mismatches.", "Count_next");
		if (stats1.errors_Wait_next) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "Wait_next", stats1.errors_Wait_next, stats1.errortime_Wait_next);
		else $display("Hint: Output '%s' has no mismatches.", "Wait_next");
		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");
		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_shift_ena) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "shift_ena", stats1.errors_shift_ena, stats1.errortime_shift_ena);
		else $display("Hint: Output '%s' has no mismatches.", "shift_ena");

		$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 = ( { B3_next_ref, S_next_ref, S1_next_ref, Count_next_ref, Wait_next_ref, done_ref, counting_ref, shift_ena_ref } === ( { B3_next_ref, S_next_ref, S1_next_ref, Count_next_ref, Wait_next_ref, done_ref, counting_ref, shift_ena_ref } ^ { B3_next_dut, S_next_dut, S1_next_dut, Count_next_dut, Wait_next_dut, done_dut, counting_dut, shift_ena_dut } ^ { B3_next_ref, S_next_ref, S1_next_ref, Count_next_ref, Wait_next_ref, done_ref, counting_ref, shift_ena_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 (B3_next_ref !== ( B3_next_ref ^ B3_next_dut ^ B3_next_ref ))
		begin if (stats1.errors_B3_next == 0) stats1.errortime_B3_next = $time;
			stats1.errors_B3_next = stats1.errors_B3_next+1'b1; end
		if (S_next_ref !== ( S_next_ref ^ S_next_dut ^ S_next_ref ))
		begin if (stats1.errors_S_next == 0) stats1.errortime_S_next = $time;
			stats1.errors_S_next = stats1.errors_S_next+1'b1; end
		if (S1_next_ref !== ( S1_next_ref ^ S1_next_dut ^ S1_next_ref ))
		begin if (stats1.errors_S1_next == 0) stats1.errortime_S1_next = $time;
			stats1.errors_S1_next = stats1.errors_S1_next+1'b1; end
		if (Count_next_ref !== ( Count_next_ref ^ Count_next_dut ^ Count_next_ref ))
		begin if (stats1.errors_Count_next == 0) stats1.errortime_Count_next = $time;
			stats1.errors_Count_next = stats1.errors_Count_next+1'b1; end
		if (Wait_next_ref !== ( Wait_next_ref ^ Wait_next_dut ^ Wait_next_ref ))
		begin if (stats1.errors_Wait_next == 0) stats1.errortime_Wait_next = $time;
			stats1.errors_Wait_next = stats1.errors_Wait_next+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
		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 (shift_ena_ref !== ( shift_ena_ref ^ shift_ena_dut ^ shift_ena_ref ))
		begin if (stats1.errors_shift_ena == 0) stats1.errortime_shift_ena = $time;
			stats1.errors_shift_ena = stats1.errors_shift_ena+1'b1; end

	end
endmodule

detail_description:
Given the following Moore state machine with 3 input (d, done_counting, ack) and 3 outputs (shift_ena, counting, done). Unless otherwise stated in the diagram below, assume outputs are 0 and inputs are don't cares.

// S () --d=0--> S
// S () --d=1--> S1
// S1 () --d=0--> S
// S1 () --d=1--> S11
// S11 () --d=0--> S110
// S11 () --d=1--> S11
// S110 () --d=0--> S
// S110 () --d=1--> B0
// B0 (shift_ena=1) -- (always go to next cycle) --> B1
// B1 (shift_ena=1) -- (always go to next cycle) --> B2
// B2 (shift_ena=1) -- (always go to next cycle) --> B3
// B3 (shift_ena=1) -- (always go to next cycle) --> Count
// Count (counting=1) --!(done_counting)--> Count
// Count (counting=1) --(done_counting)--> Wait
// Wait (done=1) --ack=0--> Wait
// Wait (done=1) --ack=1--> S

// At reset, the state machine starts in state "S". Derive next-state logic equations and output logic equations by inspection assuming the following one-hot encoding is used: (S, S1, S11, S110, B0, B1, B2, B3, Count, Wait) = (10'b0000000001, 10'b0000000010, 10'b0000000100, ... , 10'b1000000000)

// Derive state transition and output logic equations by inspection assuming a one-hot encoding. Implement only the state transition logic and output logic (the combinational logic portion) for this state machine.

// Write code that generates the following equations:

// - B3_next -- next-state logic for state B3
// - S_next
// - S1_next
// - Count_next
// - Wait_next
// - done -- output logic
// - counting
// - shift_ena


prompt:
module top_module(
	input clk,
	input [7:0] d,
	input areset,
	output reg [7:0] q);

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

	always @(posedge clk, posedge areset)
		if (areset)
			q <= 0;
		else
			q <= d;

endmodule

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

	reg reset;
	assign areset = 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;
		d <= $random;
		@(negedge clk);
		@(negedge clk);
		wavedrom_start("Asynchronous active-high reset");
		reset_test(1);
		repeat(7) @(negedge clk) d <= $random;
		@(posedge clk) reset <= 1;
		@(negedge clk) reset <= 0; d <= $random;
		repeat(2) @(negedge clk) d <= $random;
		wavedrom_stop();

		repeat(400) @(posedge clk, negedge clk) begin
			reset <= !($random & 15);
			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 [7:0] d;
	logic areset;
	logic [7:0] q_ref;
	logic [7:0] q_dut;

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

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

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

	top_module top_module1 (
		.clk,
		.d,
		.areset,
		.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 8 D flip-flops with active high asynchronous reset. The output should be reset to 0. All DFFs should be triggered by the positive edge of clk.


prompt:
module top_module (
	input a,
	input b,
	input c,
	input d,
	output reg out
);

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

    always @(*) begin
        case({a,b,c,d})
            4'h0: out = 0;
            4'h1: out = 0;
            4'h3: out = 1;
            4'h2: out = 1;
            4'h4: out = 1'bx;
            4'h5: out = 0;
            4'h7: out = 0;
            4'h6: out = 0;
            4'hc: out = 1;
            4'hd: out = 1'bx;
            4'hf: out = 1;
            4'he: out = 1;
            4'h8: out = 1;
            4'h9: out = 1'bx;
            4'hb: out = 1;
            4'ha: out = 1;
        endcase
    end
endmodule

module stimulus_gen (
	input clk,
	output reg 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
		int count; count = 0;
		{a,b,c,d} <= 4'b0;
		wavedrom_start();
		repeat(16) @(posedge clk)
			{a,b,c,d} <= count++;
		@(negedge clk) wavedrom_stop();

		repeat(200) @(posedge clk, negedge clk)
			{d,c,b,a} <= $urandom;

		#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 a;
	logic b;
	logic c;
	logic d;
	logic out_ref;
	logic out_dut;

	initial begin
		$dumpfile("wave.vcd");
		$dumpvars(1, stim1.clk, tb_mismatch ,a,b,c,d,out_ref,out_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,
		.out(out_ref) );

	top_module top_module1 (
		.a,
		.b,
		.c,
		.d,
		.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 the circuit described by the Karnaugh map below. d is don't-care, which means you may choose to output whatever value is convenient.

//        ab
// cd   01 00 10 11
//  00 | d | 0 | 1 | 1 |
//  01 | 0 | 0 | d | d |
//  11 | 0 | 1 | 1 | 1 |
//  10 | 0 | 1 | 1 | 1 |


prompt:
module top_module (
	input clk,
	input areset,
	input bump_left,
	input bump_right,
	output walk_left,
	output walk_right
);

test:
`timescale 1 ps/1 ps
`define OK 12
`define INCORRECT 13
module reference_module (
	input clk,
	input areset,
	input bump_left,
	input bump_right,
	output walk_left,
	output walk_right
);
	parameter WL=0, WR=1;
	reg state;
	reg next;

    always_comb begin
		case (state)
			WL: next = bump_left ? WR : WL;
			WR: next = bump_right ? WL: WR;
		endcase
    end

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

	assign walk_left = (state==WL);
	assign walk_right = (state==WR);

endmodule

module stimulus_gen (
	input clk,
	output logic areset,
	output logic bump_left,
	output logic bump_right,
	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'b1;
		{bump_right, bump_left} <= 3'h3;
		wavedrom_start("Asynchronous reset");
		reset_test(1);
		repeat(3) @(posedge clk);
		{bump_right, bump_left} <= 2;
		repeat(2) @(posedge clk);
		{bump_right, bump_left} <= 1;
		repeat(2) @(posedge clk);
		wavedrom_stop();

		@(posedge clk);
		repeat(200) @(posedge clk, negedge clk) begin
			{bump_right, bump_left} <= $random & $random;
			reset <= !($random & 31);
		end

		#1 $finish;
	end

endmodule

module tb();

	typedef struct packed {
		int errors;
		int errortime;
		int errors_walk_left;
		int errortime_walk_left;
		int errors_walk_right;
		int errortime_walk_right;

		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 areset;
	logic bump_left;
	logic bump_right;
	logic walk_left_ref;
	logic walk_left_dut;
	logic walk_right_ref;
	logic walk_right_dut;

	initial begin
		$dumpfile("wave.vcd");
		$dumpvars(1, stim1.clk, tb_mismatch ,clk,areset,bump_left,bump_right,walk_left_ref,walk_left_dut,walk_right_ref,walk_right_dut );
	end

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

	stimulus_gen stim1 (
		.clk,
		.* ,
		.areset,
		.bump_left,
		.bump_right );
	reference_module good1 (
		.clk,
		.areset,
		.bump_left,
		.bump_right,
		.walk_left(walk_left_ref),
		.walk_right(walk_right_ref) );

	top_module top_module1 (
		.clk,
		.areset,
		.bump_left,
		.bump_right,
		.walk_left(walk_left_dut),
		.walk_right(walk_right_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_walk_left) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "walk_left", stats1.errors_walk_left, stats1.errortime_walk_left);
		else $display("Hint: Output '%s' has no mismatches.", "walk_left");
		if (stats1.errors_walk_right) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "walk_right", stats1.errors_walk_right, stats1.errortime_walk_right);
		else $display("Hint: Output '%s' has no mismatches.", "walk_right");

		$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 = ( { walk_left_ref, walk_right_ref } === ( { walk_left_ref, walk_right_ref } ^ { walk_left_dut, walk_right_dut } ^ { walk_left_ref, walk_right_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 (walk_left_ref !== ( walk_left_ref ^ walk_left_dut ^ walk_left_ref ))
		begin if (stats1.errors_walk_left == 0) stats1.errortime_walk_left = $time;
			stats1.errors_walk_left = stats1.errors_walk_left+1'b1; end
		if (walk_right_ref !== ( walk_right_ref ^ walk_right_dut ^ walk_right_ref ))
		begin if (stats1.errors_walk_right == 0) stats1.errortime_walk_right = $time;
			stats1.errors_walk_right = stats1.errors_walk_right+1'b1; end

	end
endmodule

detail_description: The game Lemmings involves critters with fairly simple brains. So simple that we are going to model it using a finite state machine. In the Lemmings' 2D world, Lemmings can be in one of two states: walking left (walk_left is 1) or walking right (walk_right is 1). It will switch directions if it hits an obstacle. In particular, if a Lemming is bumped on the left (by receiving a 1 on bump_left), it will walk right. If it's bumped on the right (by receiving a 1 on bump_right), it will walk left. If it's bumped on both sides at the same time, it will still switch directions. Implement a Moore state machine with two states, two inputs, and one output (internal to the module) that models this behaviour. areset is positive edge triggered asynchronous reseting the Lemming machine to walk left.


prompt:
module top_module (
	input clk,
	input resetn,
	input [3:1] r,
	output [3:1] g
);

test:
`timescale 1 ps/1 ps
`define OK 12
`define INCORRECT 13
module reference_module (
	input clk,
	input resetn,
	input [3:1] r,
	output [3:1] g
);
	parameter A=0, B=1, C=2, D=3;
	reg [1:0] state, next;

	always @(posedge clk) begin
		if (~resetn) state <= A;
		else state <= next;
	end

	always@(state,r) begin
		case (state)
			A: if (r[1]) next = B;
			   else if (r[2]) next = C;
			   else if (r[3]) next = D;
			   else next = A;
			B: next = r[1] ? B : A;
			C: next = r[2] ? C : A;
			D: next = r[3] ? D : A;
			default: next = 'x;
		endcase
	end

	assign g[1] = (state == B);
	assign g[2] = (state == C);
	assign g[3] = (state == D);
endmodule

module stimulus_gen (
	input clk,
	output logic resetn,
	output logic [3:1] r,
	output reg[511:0] wavedrom_title,
	output reg wavedrom_enable,
	input tb_match
);
	reg reset;
	assign resetn = ~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;
		r <= 0;
		@(posedge clk);

		r <= 1;
		reset_test();

		r <= 0;
		wavedrom_start("");
		@(posedge clk) r <= 0;
		@(posedge clk) r <= 7;
		@(posedge clk) r <= 7;
		@(posedge clk) r <= 7;
		@(posedge clk) r <= 6;
		@(posedge clk) r <= 6;
		@(posedge clk) r <= 6;
		@(posedge clk) r <= 4;
		@(posedge clk) r <= 4;
		@(posedge clk) r <= 4;
		@(posedge clk) r <= 0;
		@(posedge clk) r <= 0;
		@(posedge clk) r <= 4;
		@(posedge clk) r <= 6;
		@(posedge clk) r <= 7;
		@(posedge clk) r <= 7;
		@(posedge clk) r <= 7;
		@(negedge clk);
		wavedrom_stop();

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

		repeat(500) @(negedge clk) begin
			reset <= ($random & 63) == 0;
			r <= $random;
		end

		#1 $finish;
	end

endmodule

module tb();

	typedef struct packed {
		int errors;
		int errortime;
		int errors_g;
		int errortime_g;

		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 [3:1] r;
	logic [3:1] g_ref;
	logic [3:1] g_dut;

	initial begin
		$dumpfile("wave.vcd");
		$dumpvars(1, stim1.clk, tb_mismatch ,clk,resetn,r,g_ref,g_dut );
	end

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

	stimulus_gen stim1 (
		.clk,
		.* ,
		.resetn,
		.r );
	reference_module good1 (
		.clk,
		.resetn,
		.r,
		.g(g_ref) );

	top_module top_module1 (
		.clk,
		.resetn,
		.r,
		.g(g_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_g) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "g", stats1.errors_g, stats1.errortime_g);
		else $display("Hint: Output '%s' has no mismatches.", "g");

		$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 = ( { g_ref } === ( { g_ref } ^ { g_dut } ^ { g_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 (g_ref !== ( g_ref ^ g_dut ^ g_ref ))
		begin if (stats1.errors_g == 0) stats1.errortime_g = $time;
			stats1.errors_g = stats1.errors_g+1'b1; end

	end
endmodule

detail_description:
Consider the FSM described by the state diagram shown below:

// A --r1=0,r2=0,r3=0--> A
// A --r1=1--> B
// A --r1=0,r2=1--> C
// A --r1=0,r2=0,r3=0--> D
// B (g1=1) --r1=1--> B
// B (g1=1) --r1=0--> A
// C (g2=1) --r2=1--> C
// C (g2=1) --r2=0--> A

// Resetn is an active-low synchronous reset that resets into state A. This FSM acts as an arbiter circuit, which controls access to some type of resource by three requesting devices. Each device makes its request for the resource by setting a signal _r[i]_ = 1, where _r[i]_ is either _r[1]_, _r[2]_, or _r[3]_. Each r[i] is an input signal to the FSM, and represents one of the three devices. The FSM stays in state _A_ as long as there are no requests. When one or more request occurs, then the FSM decides which device receives a grant to use the resource and changes to a state that sets that device's _g[i]_ signal to 1. Each _g[i]_ is an output from the FSM. There is a priority system, in that device 1 has a higher priority than device 2, and device 3 has the lowest priority. Hence, for example, device 3 will only receive a grant if it is the only device making a request when the FSM is in state _A_. Once a device, _i_, is given a grant by the FSM, that device continues to receive the grant as long as its request, _r[i]_ = 1.

// Write complete Verilog code that represents this FSM. Use separate always blocks for the state table and the state flip-flops, as done in lectures. Describe the FSM outputs, _g[i]_, using either continuous assignment statement(s) or an always block (at your discretion). Assign any state codes that you wish to use.


prompt:
module top_module (
	input clk,
	input reset,
	input in,
	output disc,
	output flag,
	output err);

test:
`timescale 1 ps/1 ps
`define OK 12
`define INCORRECT 13
module reference_module (
	input clk,
	input reset,
	input in,
	output disc,
	output flag,
	output err);

	parameter [3:0] S0=0, S1=1, S2=2, S3=3, S4=4, S5=5, S6=6, SERR=7, SDISC=8, SFLAG=9;
	reg [3:0] state, next;

	assign disc = state == SDISC;
	assign flag = state == SFLAG;
	assign err = state == SERR;

	always @(posedge clk) begin
		case (state)
			S0: state <= in ? S1 : S0;
			S1: state <= in ? S2 : S0;
			S2: state <= in ? S3 : S0;
			S3: state <= in ? S4 : S0;
			S4: state <= in ? S5 : S0;
			S5: state <= in ? S6 : SDISC;
			S6: state <= in ? SERR : SFLAG;
			SERR: state <= in ? SERR : S0;
			SFLAG: state <= in ? S1 : S0;
			SDISC: state <= in ? S1 : S0;
			default: state <= 'x;
		endcase

		if (reset) state <= S0;
	end

endmodule

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

	initial begin
		reset <= 1;
		in <= 0;
		@(posedge clk);
		repeat(800) @(posedge clk, negedge clk) begin
			reset <= !($random & 31);
			in <= |($random&7);
		end
		#1 $finish;
	end

endmodule

module tb();

	typedef struct packed {
		int errors;
		int errortime;
		int errors_disc;
		int errortime_disc;
		int errors_flag;
		int errortime_flag;
		int errors_err;
		int errortime_err;

		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 in;
	logic disc_ref;
	logic disc_dut;
	logic flag_ref;
	logic flag_dut;
	logic err_ref;
	logic err_dut;

	initial begin
		$dumpfile("wave.vcd");
		$dumpvars(1, stim1.clk, tb_mismatch ,clk,reset,in,disc_ref,disc_dut,flag_ref,flag_dut,err_ref,err_dut );
	end

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

	stimulus_gen stim1 (
		.clk,
		.* ,
		.reset,
		.in );
	reference_module good1 (
		.clk,
		.reset,
		.in,
		.disc(disc_ref),
		.flag(flag_ref),
		.err(err_ref) );

	top_module top_module1 (
		.clk,
		.reset,
		.in,
		.disc(disc_dut),
		.flag(flag_dut),
		.err(err_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_disc) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "disc", stats1.errors_disc, stats1.errortime_disc);
		else $display("Hint: Output '%s' has no mismatches.", "disc");
		if (stats1.errors_flag) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "flag", stats1.errors_flag, stats1.errortime_flag);
		else $display("Hint: Output '%s' has no mismatches.", "flag");
		if (stats1.errors_err) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "err", stats1.errors_err, stats1.errortime_err);
		else $display("Hint: Output '%s' has no mismatches.", "err");

		$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 = ( { disc_ref, flag_ref, err_ref } === ( { disc_ref, flag_ref, err_ref } ^ { disc_dut, flag_dut, err_dut } ^ { disc_ref, flag_ref, err_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 (disc_ref !== ( disc_ref ^ disc_dut ^ disc_ref ))
		begin if (stats1.errors_disc == 0) stats1.errortime_disc = $time;
			stats1.errors_disc = stats1.errors_disc+1'b1; end
		if (flag_ref !== ( flag_ref ^ flag_dut ^ flag_ref ))
		begin if (stats1.errors_flag == 0) stats1.errortime_flag = $time;
			stats1.errors_flag = stats1.errors_flag+1'b1; end
		if (err_ref !== ( err_ref ^ err_dut ^ err_ref ))
		begin if (stats1.errors_err == 0) stats1.errortime_err = $time;
			stats1.errors_err = stats1.errors_err+1'b1; end

	end
endmodule

detail_description:
Synchronous HDLC framing involves decoding a continuous bit stream of data to look for bit patterns that indicate the beginning and end of frames (packets). Seeing exactly 6 consecutive 1s (i.e., 01111110) is a "flag" that indicate frame boundaries. To avoid the data stream from accidentally containing "flags", the sender inserts a zero after every 5 consecutive 1s which the receiver must detect and discard. We also need to signal an error if there are 7 or more consecutive 1s. Create a Moore-type finite state machine to recognize these three sequences:

// (1) 0111110: Signal a bit needs to be discarded (disc).
// (2) 01111110: Flag the beginning/end of a frame (flag).
// (3) 01111111...: Error (7 or more 1s) (err).

// When the FSM is reset, it should be in a state that behaves as though the previous input were 0. The reset signal is active high synchronous. The output signals should be asserted for a complete cycle beginning on the clock cycle after the condition occurs.


prompt:
module top_module (
	input sel,
	input [7:0] a,
	input [7:0] b,
	output reg [7:0] out
);

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

	// assign out = (~sel & a) | (sel & b);
    assign out = sel ? a : b;

endmodule

module stimulus_gen (
	input clk,
	output logic sel,
	output logic [7:0] a, b,
	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, sel} <= '0;
		@(negedge clk) wavedrom_start("");
			@(posedge clk, negedge clk) {a,b,sel} <= {8'haa, 8'hbb, 1'b0};
			@(posedge clk, negedge clk) {a,b,sel} <= {8'haa, 8'hbb, 1'b0};
			@(posedge clk, negedge clk) {a,b,sel} <= {8'haa, 8'hbb, 1'b1};
			@(posedge clk, negedge clk) {a,b,sel} <= {8'haa, 8'hbb, 1'b0};
			@(posedge clk, negedge clk) {a,b,sel} <= {8'haa, 8'hbb, 1'b1};
			@(posedge clk, negedge clk) {a,b,sel} <= {8'haa, 8'hbb, 1'b1};

			@(posedge clk, negedge clk) {a, b} <= {8'hff, 8'h00}; sel <= 1'b0;
			@(posedge clk, negedge clk) sel <= 1'b0;
			@(posedge clk, negedge clk) sel <= 1'b1;
			@(posedge clk, negedge clk) sel <= 1'b0;
			@(posedge clk, negedge clk) sel <= 1'b1;
			@(posedge clk, negedge clk) sel <= 1'b1;
		wavedrom_stop();

		repeat(100) @(posedge clk, negedge clk)
			{a,b,sel} <= $urandom;
		$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 sel;
	logic [7:0] a;
	logic [7:0] b;
	logic [7:0] out_ref;
	logic [7:0] out_dut;

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

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

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

	top_module top_module1 (
		.sel,
		.a,
		.b,
		.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:
Find the bug and fix this 8-bit wide 2-to-1 mux.

// module top_module (
//     input sel,
//     input [7:0] a,
//     input [7:0] b,
//     output out  );

//     assign out = (~sel & a) | (sel & b);

// endmodule


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

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

	always @(posedge clk)
		if (reset || q == 999)
			q <= 0;
		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");
		reset_test();
		repeat(5) @(posedge clk);
		wavedrom_stop();

		reset <= 0;

		repeat(989) @(negedge clk);
		wavedrom_start("Wrap around behaviour");
		repeat(14)@(posedge clk);
		wavedrom_stop();

		repeat(2000) @(posedge clk, negedge clk) begin
			reset <= !($random & 127);
		end
		reset <= 0;
		repeat(2000) @(posedge clk);

		#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 [9:0] q_ref;
	logic [9: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: Build a counter that counts from 0 to 999, inclusive, with a period of 1000 cycles. The reset input is active high synchronous, and should reset the counter to 0.


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

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

	always @(negedge clock)
		q <= a;

	always @(*)
		if (clock)
			p = a;
endmodule

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

	always begin
		repeat(3) @(posedge clk);
		clock = ~clock;
	end

// 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 <= 0;
		@(negedge clock) {a} <= 0;
		@(negedge clk) wavedrom_start("Unknown circuit");
			@(posedge clk) {a} <= 0;
			repeat(14) @(posedge clk,negedge clk) a <= ~a;
			repeat(5) @(posedge clk, negedge clk);
			repeat(8) @(posedge clk,negedge clk) a <= ~a;
		wavedrom_stop();

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

endmodule

module tb();

	typedef struct packed {
		int errors;
		int errortime;
		int errors_p;
		int errortime_p;
		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 clock;
	logic a;
	logic p_ref;
	logic p_dut;
	logic q_ref;
	logic q_dut;

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

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

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

	top_module top_module1 (
		.clock,
		.a,
		.p(p_dut),
		.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_p) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "p", stats1.errors_p, stats1.errortime_p);
		else $display("Hint: Output '%s' has no mismatches.", "p");
		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 = ( { p_ref, q_ref } === ( { p_ref, q_ref } ^ { p_dut, q_dut } ^ { p_ref, 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 (p_ref !== ( p_ref ^ p_dut ^ p_ref ))
		begin if (stats1.errors_p == 0) stats1.errortime_p = $time;
			stats1.errors_p = stats1.errors_p+1'b1; 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


prompt:
module top_module (
	input in1,
	input in2,
	output logic out
);

canonical_solution:
	assign out = ~(in1 | in2);
endmodule

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

	assign out = ~(in1 | in2);
endmodule

module stimulus_gen (
	input clk,
	output logic in1, in2
);

	initial begin
		repeat(100) @(posedge clk, negedge clk) begin
			{in1, in2} <= $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 in1;
	logic in2;
	logic out_ref;
	logic out_dut;

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

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

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

	top_module top_module1 (
		.in1,
		.in2,
		.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 a 2-input NOR gate.


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

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

	assign out = { {24{in[7]}}, in };

endmodule

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

	initial begin
		repeat(100) @(posedge clk, negedge clk)
			in <= $random;
		$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 [7:0] in;
	logic [31:0] out_ref;
	logic [31: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: One common place to see a replication operator is when sign-extending a smaller number to a larger one, while preserving its signed value. This is done by replicating the sign bit (the most significant bit) of the smaller number to the left. For example, sign-extending 4'b0101 (5) to 8 bits results in 8'b00000101 (5), while sign-extending 4'b1101 (-3) to 8 bits results in 8'b11111101 (-3). Build a circuit that sign-extends an 8-bit number to 32 bits. This requires a concatenation of 24 copies of the sign bit (i.e., replicate bit[7] 24 times) followed by the 8-bit number itself.


prompt:
module top_module (
	input clk,
	input reset,
	input s,
	input w,
	output reg z
);

test:
`timescale 1 ps/1 ps
`define OK 12
`define INCORRECT 13
module reference_module (
	input clk,
	input reset,
	input s,
	input w,
	output reg z
);
	parameter A=0, B=1, C=2, S10=3, S11=4, S20=5, S21=6, S22=7;
	reg [2:0] state, next;

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

	always_comb begin
		case (state)
			A: next = s ? B : A;
			B: next = w ? S11 : S10;
			C: next = w ? S11 : S10;
			S10: next = w ? S21 : S20;
			S11: next = w ? S22 : S21;
			S20: next = B;
			S21: next = w ? C : B;
			S22: next = w ? B : C;
			default: next = 'x;
		endcase
	end

	assign z = (state == C);

endmodule

module stimulus_gen (
	input clk,
	output logic reset,
	output logic s, w,
	input tb_match
);

	bit spulse_fail = 0;
	bit failed = 0;

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

	initial begin
		reset <= 1;
		s <= 0;
		w <= 0;
		@(posedge clk);
		@(posedge clk);
		reset <= 0;
		@(posedge clk);
		@(posedge clk);

		s <= 1;

		repeat(200) @(posedge clk, negedge clk) begin
			w <= $random;
		end

		reset <= 1;
		@(posedge clk);
		reset <= 0;
		@(posedge clk);
		@(posedge clk);

		repeat(200) @(posedge clk, negedge clk) begin
			w <= $random;
		end

		@(posedge clk)
			spulse_fail <= failed;

		repeat(500) @(negedge clk) begin
			reset <= !($random & 63);
			s <= !($random & 7);
			w <= $random;
		end

		if (failed && !spulse_fail) begin
			$display ("Hint: Your state machine should ignore input 's' after the state A to B transition.");
		end

		#1 $finish;
	end

endmodule

module tb();

	typedef struct packed {
		int errors;
		int errortime;
		int errors_z;
		int errortime_z;

		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 s;
	logic w;
	logic z_ref;
	logic z_dut;

	initial begin
		$dumpfile("wave.vcd");
		$dumpvars(1, stim1.clk, tb_mismatch ,clk,reset,s,w,z_ref,z_dut );
	end

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

	stimulus_gen stim1 (
		.clk,
		.* ,
		.reset,
		.s,
		.w );
	reference_module good1 (
		.clk,
		.reset,
		.s,
		.w,
		.z(z_ref) );

	top_module top_module1 (
		.clk,
		.reset,
		.s,
		.w,
		.z(z_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_z) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "z", stats1.errors_z, stats1.errortime_z);
		else $display("Hint: Output '%s' has no mismatches.", "z");

		$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 = ( { z_ref } === ( { z_ref } ^ { z_dut } ^ { z_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 (z_ref !== ( z_ref ^ z_dut ^ z_ref ))
		begin if (stats1.errors_z == 0) stats1.errortime_z = $time;
			stats1.errors_z = stats1.errors_z+1'b1; end

	end
endmodule

detail_description: Consider a finite state machine with inputs s and w. Assume that the FSM begins in a reset state called A, as depicted below. The FSM remains in state A as long as s = 0, and it moves to state B when s = 1. Once in state B the FSM examines the value of the input w in the next three clock cycles. If w = 1 in exactly two of these clock cycles, then the FSM has to set an output z to 1 in the following clock cycle. Otherwise z has to be 0. The FSM continues checking w for the next three clock cycles, and so on. Use as few states as possible. Note that the s input is used only in state A, so you need to consider just the w input. Assume reset is active high synchronous.


task_id: zero

prompt:
module top_module(
	output zero);

canonical_solution:
	assign zero = 1'b0;

endmodule

test:
`timescale 1 ps/1 ps
`define OK 12
`define INCORRECT 13
module reference_module(
	output zero);

	assign zero = 1'b0;

endmodule

module stimulus_gen (
	input clk,
	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
		wavedrom_start("Output should 0");
		repeat(20) @(posedge clk, negedge clk);
		wavedrom_stop();

		#1 $finish;
	end

endmodule

module tb();

	typedef struct packed {
		int errors;
		int errortime;
		int errors_zero;
		int errortime_zero;

		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 zero_ref;
	logic zero_dut;

	initial begin
		$dumpfile("wave.vcd");
		$dumpvars(1, stim1.clk, tb_mismatch ,zero_ref,zero_dut );
	end

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

	stimulus_gen stim1 (
		.clk,
		.*  );
	reference_module good1 (
		.zero(zero_ref) );

	top_module top_module1 (
		.zero(zero_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_zero) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "zero", stats1.errors_zero, stats1.errortime_zero);
		else $display("Hint: Output '%s' has no mismatches.", "zero");

		$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 = ( { zero_ref } === ( { zero_ref } ^ { zero_dut } ^ { zero_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 (zero_ref !== ( zero_ref ^ zero_dut ^ zero_ref ))
		begin if (stats1.errors_zero == 0) stats1.errortime_zero = $time;
			stats1.errors_zero = stats1.errors_zero+1'b1; end

	end
endmodule

detail_description: Build a circuit that always outputs a LOW.


prompt:
module top_module (
	input cpu_overheated,
	output reg shut_off_computer,
	input arrived,
	input gas_tank_empty,
	output reg keep_driving
);

test:
`timescale 1 ps/1 ps
`define OK 12
`define INCORRECT 13
module reference_module (
	input cpu_overheated,
	output reg shut_off_computer,
	input arrived,
	input gas_tank_empty,
	output reg keep_driving
);

	always @(*) begin
		if (cpu_overheated)
			shut_off_computer = 1;
		else
			shut_off_computer = 0;
	end

	always @(*) begin
		if (~arrived)
			keep_driving = !gas_tank_empty;
		else
			keep_driving = 1'b0;
	end

endmodule

module stimulus_gen (
	input clk,
	output logic cpu_overheated, arrived, gas_tank_empty,
	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

	logic [2:0] s = 3'b010;
	assign {cpu_overheated, arrived, gas_tank_empty} = s;

	initial begin
		@(negedge clk) wavedrom_start("");
		@(posedge clk) s <= 3'b010;
		@(posedge clk) s <= 3'b100;
		@(posedge clk) s <= 3'b100;
		@(posedge clk) s <= 3'b001;
		@(posedge clk) s <= 3'b000;
		@(posedge clk) s <= 3'b100;
		@(posedge clk) s <= 3'b110;
		@(posedge clk) s <= 3'b111;
		@(posedge clk) s <= 3'b111;
		@(posedge clk) s <= 3'b111;
		wavedrom_stop();
		repeat(100) @(posedge clk, negedge clk)
			s <= $urandom;
		$finish;
	end

endmodule

module tb();

	typedef struct packed {
		int errors;
		int errortime;
		int errors_shut_off_computer;
		int errortime_shut_off_computer;
		int errors_keep_driving;
		int errortime_keep_driving;

		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 cpu_overheated;
	logic arrived;
	logic gas_tank_empty;
	logic shut_off_computer_ref;
	logic shut_off_computer_dut;
	logic keep_driving_ref;
	logic keep_driving_dut;

	initial begin
		$dumpfile("wave.vcd");
		$dumpvars(1, stim1.clk, tb_mismatch ,cpu_overheated,arrived,gas_tank_empty,shut_off_computer_ref,shut_off_computer_dut,keep_driving_ref,keep_driving_dut );
	end

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

	stimulus_gen stim1 (
		.clk,
		.* ,
		.cpu_overheated,
		.arrived,
		.gas_tank_empty );
	reference_module good1 (
		.cpu_overheated,
		.arrived,
		.gas_tank_empty,
		.shut_off_computer(shut_off_computer_ref),
		.keep_driving(keep_driving_ref) );

	top_module top_module1 (
		.cpu_overheated,
		.arrived,
		.gas_tank_empty,
		.shut_off_computer(shut_off_computer_dut),
		.keep_driving(keep_driving_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_shut_off_computer) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "shut_off_computer", stats1.errors_shut_off_computer, stats1.errortime_shut_off_computer);
		else $display("Hint: Output '%s' has no mismatches.", "shut_off_computer");
		if (stats1.errors_keep_driving) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "keep_driving", stats1.errors_keep_driving, stats1.errortime_keep_driving);
		else $display("Hint: Output '%s' has no mismatches.", "keep_driving");

		$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 = ( { shut_off_computer_ref, keep_driving_ref } === ( { shut_off_computer_ref, keep_driving_ref } ^ { shut_off_computer_dut, keep_driving_dut } ^ { shut_off_computer_ref, keep_driving_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 (shut_off_computer_ref !== ( shut_off_computer_ref ^ shut_off_computer_dut ^ shut_off_computer_ref ))
		begin if (stats1.errors_shut_off_computer == 0) stats1.errortime_shut_off_computer = $time;
			stats1.errors_shut_off_computer = stats1.errors_shut_off_computer+1'b1; end
		if (keep_driving_ref !== ( keep_driving_ref ^ keep_driving_dut ^ keep_driving_ref ))
		begin if (stats1.errors_keep_driving == 0) stats1.errortime_keep_driving = $time;
			stats1.errors_keep_driving = stats1.errors_keep_driving+1'b1; end

	end
endmodule

detail_description:
Fix any and all bugs in this code:

// module top_module (
//     input      cpu_overheated,
//     output reg shut_off_computer,
//     input      arrived,
//     input      gas_tank_empty,
//     output reg keep_driving  ); //

//     always @(*) begin
//         if (cpu_overheated)
//            shut_off_computer = 1;
//     end

//     always @(*) begin
//         if (~arrived)
//            keep_driving = ~gas_tank_empty;
//     end

// endmodule


prompt:
module top_module(
    input clk,
    input areset,
    input train_valid,
    input train_taken,
    output logic [1:0] state
);

test:
`timescale 1 ps/1 ps
`define OK 12
`define INCORRECT 13
module reference_module(
    input clk,
    input areset,
    input train_valid,
    input train_taken,
    output logic [1:0] state
);
    always @(posedge clk, posedge areset) begin
        if (areset)
            state <= 1;
        else if (train_valid) begin
            if(state < 3 && train_taken)
                state <= state + 1;
            else if(state > 0 && !train_taken)
                state <= state - 1;
        end
    end
endmodule

module stimulus_gen(
	input clk,
	output logic areset,
	output logic train_valid,
	output train_taken,

	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

	reg 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

	assign areset = reset;
	logic train_taken_r;
	assign train_taken = train_valid ? train_taken_r : 1'bx;

	initial begin
		@(posedge clk);
		@(posedge clk) reset <= 1;
		@(posedge clk) reset <= 0;
		train_taken_r <= 1;
		train_valid <= 1;

		wavedrom_start("Asynchronous reset");
			reset_test(1); // Test for asynchronous reset
		wavedrom_stop();
		@(posedge clk) reset <= 1;
		train_taken_r <= 1;
		train_valid <= 0;
		@(posedge clk) reset <= 0;

		wavedrom_start("Count up, then down");
		train_taken_r <= 1;
			@(posedge clk) train_valid <= 1;
			@(posedge clk) train_valid <= 0;
			@(posedge clk) train_valid <= 1;
			@(posedge clk) train_valid <= 1;
			@(posedge clk) train_valid <= 1;
			@(posedge clk) train_valid <= 0;
			@(posedge clk) train_valid <= 1;
		train_taken_r <= 0;
			@(posedge clk) train_valid <= 1;
			@(posedge clk) train_valid <= 0;
			@(posedge clk) train_valid <= 1;
			@(posedge clk) train_valid <= 1;
			@(posedge clk) train_valid <= 1;
			@(posedge clk) train_valid <= 0;
			@(posedge clk) train_valid <= 1;
		wavedrom_stop();

		repeat(1000) @(posedge clk,negedge clk)
			{train_valid, train_taken_r} <= {$urandom} ;

		#1 $finish;
	end

endmodule
module tb();

	typedef struct packed {
		int errors;
		int errortime;
		int errors_state;
		int errortime_state;

		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 areset;
	logic train_valid;
	logic train_taken;
	logic [1:0] state_ref;
	logic [1:0] state_dut;

	initial begin
		$dumpfile("wave.vcd");
		$dumpvars(1, stim1.clk, tb_mismatch ,clk,areset,train_valid,train_taken,state_ref,state_dut );
	end

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

	stimulus_gen stim1 (
		.clk,
		.* ,
		.areset,
		.train_valid,
		.train_taken );
	reference_module good1 (
		.clk,
		.areset,
		.train_valid,
		.train_taken,
		.state(state_ref) );

	top_module top_module1 (
		.clk,
		.areset,
		.train_valid,
		.train_taken,
		.state(state_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_state) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "state", stats1.errors_state, stats1.errortime_state);
		else $display("Hint: Output '%s' has no mismatches.", "state");

		$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 = ( { state_ref } === ( { state_ref } ^ { state_dut } ^ { state_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 (state_ref !== ( state_ref ^ state_dut ^ state_ref ))
		begin if (stats1.errors_state == 0) stats1.errortime_state = $time;
			stats1.errors_state = stats1.errors_state+1'b1; end

	end
endmodule

detail_description: Build a two-bit saturating counter. The counter increments (up to a maximum of 3) when train_valid = 1 and train_taken = 1. It decrements (down to a minimum of 0) when train_valid = 1 and train_taken = 0. When not training (train_valid = 0), the counter keeps its value unchanged. areset is a positive edge triggered asynchronous reset that resets the counter to weakly not-taken (2'b01). Output state[1:0] is the two-bit counter value.


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

canonical_solution:
	assign q = a&b;

endmodule

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

	assign q = a&b;

endmodule

module stimulus_gen (
	input clk,
	output logic a,b,
	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} <= 0;
		@(negedge clk) wavedrom_start("Unknown circuit");
			@(posedge clk) {a,b} <= 0;
			repeat(8) @(posedge clk) {a,b} <= {a,b} + 1;
		@(negedge clk) wavedrom_stop();

		repeat(100) @(posedge clk, negedge clk)
			{a,b} <= $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 b;
	logic q_ref;
	logic q_dut;

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

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

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

	top_module top_module1 (
		.a,
		.b,
		.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 combinational circuit. Read the simulation waveforms to determine what the circuit does, then implement it.

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


task_id: andgate

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

canonical_solution:
	assign out = a & b;

endmodule

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

	assign out = a & b;

endmodule

module stimulus_gen (
	input clk,
	output reg a, b,
	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;
		{a,b} <= 1'b0;
		wavedrom_start("AND gate");
		repeat(10) @(posedge clk)
			{a,b} <= count++;
		wavedrom_stop();

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

		#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 a;
	logic b;
	logic out_ref;
	logic out_dut;

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

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

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

	top_module top_module1 (
		.a,
		.b,
		.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 module that implements an AND gate.


prompt:
module top_module (
	input [15:0] a,
	input [15:0] b,
	input [15:0] c,
	input [15:0] d,
	input [15:0] e,
	input [15:0] f,
	input [15:0] g,
	input [15:0] h,
	input [15:0] i,
	input [3:0] sel,
	output logic [15:0] out
);

test:
`timescale 1 ps/1 ps
`define OK 12
`define INCORRECT 13
module reference_module (
	input [15:0] a,
	input [15:0] b,
	input [15:0] c,
	input [15:0] d,
	input [15:0] e,
	input [15:0] f,
	input [15:0] g,
	input [15:0] h,
	input [15:0] i,
	input [3:0] sel,
	output logic [15:0] out
);

	always @(*) begin
		out = '1;
		case (sel)
			4'h0: out = a;
			4'h1: out = b;
			4'h2: out = c;
			4'h3: out = d;
			4'h4: out = e;
			4'h5: out = f;
			4'h6: out = g;
			4'h7: out = h;
			4'h8: out = i;
		endcase
	end

endmodule

module stimulus_gen (
	input clk,
	output logic [15:0] a,b,c,d,e,f,g,h,i,
	output logic [3:0] sel,
	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,e,f,g,h,i,sel} <= { 16'ha, 16'hb, 16'hc, 16'hd, 16'he, 16'hf, 16'h11, 16'h12, 16'h13, 4'h0 };
		@(negedge clk) wavedrom_start();
			@(posedge clk) sel <= 4'h1;
			@(posedge clk) sel <= 4'h2;
			@(posedge clk) sel <= 4'h3;
			@(posedge clk) sel <= 4'h4;
			@(posedge clk) sel <= 4'h7;
			@(posedge clk) sel <= 4'h8;
			@(posedge clk) sel <= 4'h9;
			@(posedge clk) sel <= 4'ha;
			@(posedge clk) sel <= 4'hb;
		@(negedge clk) wavedrom_stop();

		repeat(200) @(negedge clk, posedge clk) begin
			{a,b,c,d,e,f,g,h,i,sel} <= {$random, $random, $random, $random, $random};
		end
		$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 [15:0] a;
	logic [15:0] b;
	logic [15:0] c;
	logic [15:0] d;
	logic [15:0] e;
	logic [15:0] f;
	logic [15:0] g;
	logic [15:0] h;
	logic [15:0] i;
	logic [3:0] sel;
	logic [15:0] out_ref;
	logic [15:0] out_dut;

	initial begin
		$dumpfile("wave.vcd");
		$dumpvars(1, stim1.clk, tb_mismatch ,a,b,c,d,e,f,g,h,i,sel,out_ref,out_dut );
	end

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

	stimulus_gen stim1 (
		.clk,
		.* ,
		.a,
		.b,
		.c,
		.d,
		.e,
		.f,
		.g,
		.h,
		.i,
		.sel );
	reference_module good1 (
		.a,
		.b,
		.c,
		.d,
		.e,
		.f,
		.g,
		.h,
		.i,
		.sel,
		.out(out_ref) );

	top_module top_module1 (
		.a,
		.b,
		.c,
		.d,
		.e,
		.f,
		.g,
		.h,
		.i,
		.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 16-bit wide, 9-to-1 multiplexer. sel=0 chooses a, sel=1 chooses b, etc. For the unused cases (sel=9 to 15), set all output bits to '1'.


prompt:
module top_module (
	input [4:1] x,
	output logic f
);

test:
`timescale 1 ps/1 ps
`define OK 12
`define INCORRECT 13
module reference_module (
	input [4:1] x,
	output logic f
);

	always_comb begin
		case (x)
			4'h0: f = 1;
			4'h1: f = 1;
			4'h2: f = 0;
			4'h3: f = 0;
			4'h4: f = 1;
			4'h5: f = 1;
			4'h6: f = 1;
			4'h7: f = 0;
			4'h8: f = 0;
			4'h9: f = 0;
			4'ha: f = 0;
			4'hb: f = 0;
			4'hc: f = 1;
			4'hd: f = 0;
			4'he: f = 1;
			4'hf: f = 1;
		endcase
	end

endmodule

module stimulus_gen (
	input clk,
	output logic [4:1] x
);

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

		#1 $finish;
	end

endmodule

module tb();

	typedef struct packed {
		int errors;
		int errortime;
		int errors_f;
		int errortime_f;

		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 [4:1] x;
	logic f_ref;
	logic f_dut;

	initial begin
		$dumpfile("wave.vcd");
		$dumpvars(1, stim1.clk, tb_mismatch ,x,f_ref,f_dut );
	end

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

	stimulus_gen stim1 (
		.clk,
		.* ,
		.x );
	reference_module good1 (
		.x,
		.f(f_ref) );

	top_module top_module1 (
		.x,
		.f(f_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_f) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "f", stats1.errors_f, stats1.errortime_f);
		else $display("Hint: Output '%s' has no mismatches.", "f");

		$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 = ( { f_ref } === ( { f_ref } ^ { f_dut } ^ { f_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 (f_ref !== ( f_ref ^ f_dut ^ f_ref ))
		begin if (stats1.errors_f == 0) stats1.errortime_f = $time;
			stats1.errors_f = stats1.errors_f+1'b1; end

	end
endmodule


prompt:
module top_module(
	output one);

canonical_solution:
	assign one = 1'b1;

endmodule

test:
`timescale 1 ps/1 ps
`define OK 12
`define INCORRECT 13
module reference_module(
	output one);

	assign one = 1'b1;

endmodule

module stimulus_gen (
	input clk,
	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
		wavedrom_start("Output should be 1");
		repeat(20) @(posedge clk, negedge clk);
		wavedrom_stop();

		#1 $finish;
	end

endmodule

module tb();

	typedef struct packed {
		int errors;
		int errortime;
		int errors_one;
		int errortime_one;

		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 one_ref;
	logic one_dut;

	initial begin
		$dumpfile("wave.vcd");
		$dumpvars(1, stim1.clk, tb_mismatch ,one_ref,one_dut );
	end

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

	stimulus_gen stim1 (
		.clk,
		.*  );
	reference_module good1 (
		.one(one_ref) );

	top_module top_module1 (
		.one(one_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_one) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "one", stats1.errors_one, stats1.errortime_one);
		else $display("Hint: Output '%s' has no mismatches.", "one");

		$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 = ( { one_ref } === ( { one_ref } ^ { one_dut } ^ { one_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 (one_ref !== ( one_ref ^ one_dut ^ one_ref ))
		begin if (stats1.errors_one == 0) stats1.errortime_one = $time;
			stats1.errors_one = stats1.errors_one+1'b1; end

	end
endmodule

detail_description: Build a circuit with no inputs and one output. That output should always drive 1 (or logic high).