prompt:
module top_module (
	input clk,
	input [7:0] in,
	input reset,
	output [23:0] out_bytes,
	output done
);

test:
`timescale 1 ps/1 ps
`define OK 12
`define INCORRECT 13
module reference_module (
	input clk,
	input [7:0] in,
	input reset,
	output [23:0] out_bytes,
	output done
);
	parameter BYTE1=0, BYTE2=1, BYTE3=2, DONE=3;
	reg [1:0] state;
	reg [1:0] next;

    wire in3 = in[3];

    always_comb begin
		case (state)
			BYTE1: next = in3 ? BYTE2 : BYTE1;
			BYTE2: next = BYTE3;
			BYTE3: next = DONE;
			DONE: next = in3 ? BYTE2 : BYTE1;
		endcase
    end

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

	assign done = (state==DONE);

	reg [23:0] out_bytes_r;
	always @(posedge clk)
		out_bytes_r <= {out_bytes_r[15:0], in};

	// Implementations may vary: Allow user to do anything while the output doesn't have to be valid.
	assign out_bytes = done ? out_bytes_r : 'x;

endmodule

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

	initial begin
		repeat(200) @(negedge clk) begin
			in <= $random;
			reset <= !($random & 31);
		end
		reset <= 1'b0;
		in <= '0;
		repeat(10) @(posedge clk);

		repeat(200) begin
			in <= $random;
			in[3] <= 1'b1;
			@(posedge clk);
			in <= $random;
			@(posedge clk);
			in <= $random;
			@(posedge clk);
		end

		#1 $finish;
	end

endmodule

module tb();

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

		int clocks;
	} stats;

	stats stats1;

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

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

	logic [7:0] in;
	logic reset;
	logic [23:0] out_bytes_ref;
	logic [23:0] out_bytes_dut;
	logic done_ref;
	logic done_dut;

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

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

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

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

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

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

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

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

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

	end
endmodule

detail_description:
We want a finite state machine that will search for message boundaries when given an input byte stream. The algorithm we'll use is to discard bytes until we see one with in[3]=1. We then assume that this is byte 1 of a message, and signal the receipt of a message once all 3 bytes have been received (done). The FSM should signal done in the cycle immediately after the third byte of each message was successfully received.

// Implement the datapath module that will output the 24-bit (3 byte) message whenever a packet is received (out_bytes[23:16] is the first byte, out_bytes[15:8] is the second byte, etc.). The reset signal is active high synchronous. out_bytes needs to be valid whenever the done signal is asserted. You may output anything at other times (i.e., don't-care).

// Waveform example:
// time            clk             reset           in[7:0]         done            out_bytes
// 0ns             0               1                0              x                    x
// 5ns             1               1                0              0                    x
// 10ns            0               1                0              0                    x
// 15ns            1               0               2c              0                    x
// 20ns            0               0               2c              0                    x
// 25ns            1               0               81              0                    x
// 30ns            0               0               81              0                    x
// 35ns            1               0                9              0                    x
// 40ns            0               0                9              0                    x
// 45ns            1               0               6b              1               2c8109
// 50ns            0               0               6b              1               2c8109
// 55ns            1               0                d              0                    x
// 60ns            0               0                d              0                    x
// 65ns            1               0               8d              0                    x
// 70ns            0               0               8d              0                    x
// 75ns            1               0               6d              1               6b0d8d
// 80ns            0               0               6d              1               6b0d8d
// 85ns            1               0               12              0                    x
// 90ns            0               0               12              0                    x
// 95ns            1               0                1              0                    x
// 100ns           0               0                1              0                    x
// 105ns           1               0                d              1               6d1201
// 110ns           0               0                d              1               6d1201
// 115ns           1               0               76              0                    x
// 120ns           0               0               76              0                    x
// 125ns           1               0               3d              0                    x
// 130ns           0               0               3d              0                    x
// 135ns           1               0               ed              1                d763d
// 140ns           0               0               ed              1                d763d
// 145ns           1               0               8c              0                    x
// 150ns           0               0               8c              0                    x
// 155ns           1               0               f9              0                    x
// 160ns           0               0               f9              0                    x
// 165ns           1               0               ce              1               ed8cf9
// 170ns           0               0               ce              1               ed8cf9
// 175ns           1               0               c5              0                    x
// 180ns           0               0               c5              0                    x
// 185ns           1               0               aa              0                    x
// 190ns           0               0               aa              0                    x


task_id: edgedetect

prompt:
module top_module(
	input clk,
	input [7:0] in,
	output reg [7:0] pedge);

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

	reg [7:0] d_last;

	always @(posedge clk) begin
		d_last <= in;
		pedge <= in & ~d_last;
	end

endmodule

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

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

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

	task wavedrom_stop;
		#1;
	endtask

	initial begin
		in <= 0;
		@(posedge clk);
		wavedrom_start("");
		repeat(2) @(posedge clk);
		in <= 1;
		repeat(4) @(posedge clk);
		in <= 0;
		repeat(4) @(negedge clk);
		in <= 6;
		repeat(2) @(negedge clk);
		in <= 0;
		repeat(2) @(posedge clk);
		wavedrom_stop();

		repeat(200)
			@(posedge clk, negedge clk) in <= $random;
		$finish;
	end

endmodule

module tb();

	typedef struct packed {
		int errors;
		int errortime;
		int errors_pedge;
		int errortime_pedge;

		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 [7:0] pedge_ref;
	logic [7:0] pedge_dut;

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

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

	stimulus_gen stim1 (
		.clk,
		.* ,
		.in );
	reference_module good1 (
		.clk,
		.in,
		.pedge(pedge_ref) );

	top_module top_module1 (
		.clk,
		.in,
		.pedge(pedge_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_pedge) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "pedge", stats1.errors_pedge, stats1.errortime_pedge);
		else $display("Hint: Output '%s' has no mismatches.", "pedge");

		$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 = ( { pedge_ref } === ( { pedge_ref } ^ { pedge_dut } ^ { pedge_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 (pedge_ref !== ( pedge_ref ^ pedge_dut ^ pedge_ref ))
		begin if (stats1.errors_pedge == 0) stats1.errortime_pedge = $time;
			stats1.errors_pedge = stats1.errors_pedge+1'b1; end

	end
endmodule

detail_description: For each bit in an 8-bit vector, detect when the input signal changes from 0 in one clock cycle to 1 the next (similar to positive edge detection). The output bit should be set the cycle after a 0 to 1 transition occurs.


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

canonical_solution:
	assign q = c | b;

endmodule

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

	assign q = c | b;

endmodule

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

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

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

	task wavedrom_stop;
		#1;
	endtask

	initial begin
		{a,b,c,d} <= 0;
		@(negedge clk) wavedrom_start("Unknown circuit");
			@(posedge clk) {a,b,c,d} <= 0;
			repeat(18) @(posedge clk, negedge clk) {a,b,c,d} <= {a,b,c,d} + 1;
		wavedrom_stop();

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

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

	top_module top_module1 (
		.a,
		.b,
		.c,
		.d,
		.q(q_dut) );

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

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

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

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

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

	end
endmodule


prompt:
module top_module (
	input clk,
	input [7:0] in,
	input reset,
	output done
);

test:
`timescale 1 ps/1 ps
`define OK 12
`define INCORRECT 13
module reference_module (
	input clk,
	input [7:0] in,
	input reset,
	output done
);
	parameter BYTE1=0, BYTE2=1, BYTE3=2, DONE=3;
	reg [1:0] state;
	reg [1:0] next;

    wire in3 = in[3];

    always_comb begin
		case (state)
			BYTE1: next = in3 ? BYTE2 : BYTE1;
			BYTE2: next = BYTE3;
			BYTE3: next = DONE;
			DONE: next = in3 ? BYTE2 : BYTE1;
		endcase
    end

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

	assign done = (state==DONE);

endmodule

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

	initial begin
		repeat(200) @(negedge clk) begin
			in <= $random;
			reset <= !($random & 31);
		end

		#1 $finish;
	end

endmodule

module tb();

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

		int clocks;
	} stats;

	stats stats1;

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

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

	logic [7:0] in;
	logic reset;
	logic done_ref;
	logic done_dut;

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

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

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

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

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

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

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

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

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

	end
endmodule

detail_description: The PS/2 mouse protocol sends messages that are three bytes long. However, within a continuous byte stream, it's not obvious where messages start and end. The only indication is that the first byte of each three byte message always has in[3]=1 (but in[3] of the other two bytes may be 1 or 0 depending on data). We want a finite state machine that will search for message boundaries when given an input byte stream. The algorithm we'll use is to discard bytes until we see one with in[3]=1. We then assume that this is byte 1 of a message, and signal the receipt of a message once all 3 bytes have been received (done). The FSM should signal done in the cycle immediately after the third byte of each message was successfully received. Reset should be active high synchronous.


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

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

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

endmodule

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

// 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;
		@(negedge clk);

		wavedrom_start("Reset and counting");
		reset_test();

		repeat(3) @(posedge clk);
		wavedrom_stop();

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

endmodule

module tb();

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

		int clocks;
	} stats;

	stats stats1;

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

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

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

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

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

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

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

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

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

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

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

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

	end
endmodule

detail_description: Build a 4-bit binary counter that counts from 0 through 15, inclusive, with a period of 16. The reset input is active high synchronous, and should reset the counter to 0.


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

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

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

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

	assign out = (state==D);

endmodule

module stimulus_gen (
	input clk,
	output logic in,
	output logic 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;
		in <= 0;
		@(posedge clk) reset <= 0; in <= 1;
		@(posedge clk) in <= 0;
		@(posedge clk) in <= 1;
		wavedrom_start();
			@(posedge clk) in <= 0;
			@(posedge clk) in <= 1;
			@(posedge clk);
			@(negedge clk) reset <= 1;
			@(posedge clk) reset <= 0;
			@(posedge clk) in <= 1;
			@(posedge clk) in <= 1;
			@(posedge clk) in <= 0;
			@(posedge clk) in <= 1;
			@(posedge clk) in <= 0;
			@(posedge clk) in <= 1;
			@(posedge clk) in <= 1;
			@(posedge clk) in <= 1;
		@(negedge clk);
		wavedrom_stop();
		repeat(200) @(posedge clk, negedge clk) begin
			in <= $random;
			reset <= !($random & 31);
		end

		#1 $finish;
	end

endmodule

module tb();

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

		int clocks;
	} stats;

	stats stats1;

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

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

	logic in;
	logic reset;
	logic out_ref;
	logic out_dut;

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

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

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

	top_module top_module1 (
		.clk,
		.in,
		.reset,
		.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:
The following is the state transition table for a Moore state machine with one input, one output, and four states. Implement this state machine. Include a synchronous active high reset that resets the FSM to state A.
// State | Next state in=0, Next state in=1 | Output
// A | A, B | 0
// B | C, B | 0
// C | A, D | 0
// D | C, B | 1


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

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

    assign next_state[A] = (state[A] | state[C]) & ~in;
    assign next_state[B] = (state[A] | state[B] | state[D]) & in;
    assign next_state[C] = (state[B] | state[D]) & ~in;
    assign next_state[D] = state[C] & in;

	assign out = (state[D]);

endmodule

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

	int errored1 = 0;
	int onehot_error = 0;

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

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

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

		#1 $finish;
	end

endmodule

module tb();

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

		int clocks;
	} stats;

	stats stats1;

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

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

	logic in;
	logic [3:0] state;
	logic [3:0] next_state_ref;
	logic [3:0] next_state_dut;
	logic out_ref;
	logic out_dut;

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

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

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

	top_module top_module1 (
		.in,
		.state,
		.next_state(next_state_dut),
		.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_next_state) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "next_state", stats1.errors_next_state, stats1.errortime_next_state);
		else $display("Hint: Output '%s' has no mismatches.", "next_state");
		if (stats1.errors_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 = ( { next_state_ref, out_ref } === ( { next_state_ref, out_ref } ^ { next_state_dut, out_dut } ^ { next_state_ref, 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 (next_state_ref !== ( next_state_ref ^ next_state_dut ^ next_state_ref ))
		begin if (stats1.errors_next_state == 0) stats1.errortime_next_state = $time;
			stats1.errors_next_state = stats1.errors_next_state+1'b1; end
		if (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:
The following is the state transition table for a Moore state machine with one input, one output, and four states. Use the following one-hot state encoding: A=4'b0001, B=4'b0010, C=4'b0100, D=4'b1000. 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.
// State | Next state in=0, Next state in=1 | Output
// A | A, B | 0
// B | C, B | 0
// C | A, D | 0
// D | C, B | 1


prompt:
module top_module (
	input d,
	input ena,
	output logic q
);

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

	always@(*) begin
		if (ena)
			q = d;
	end

endmodule

module stimulus_gen (
	input clk,
	output logic d, ena
);

	initial begin
		repeat(100) @(posedge clk, negedge clk) begin
			{d,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 d;
	logic ena;
	logic q_ref;
	logic q_dut;

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

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

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

	top_module top_module1 (
		.d,
		.ena,
		.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: Implement a D latch using an always block.


task_id: edgecapture

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

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

	reg [31:0] d_last;

	always @(posedge clk) begin
		d_last <= in;
		if (reset)
			out <= '0;
		else
			out <= out | (~in & d_last);
	end

endmodule

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

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

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

	task wavedrom_stop;
		#1;
	endtask

	initial begin
		in <= 0;
		reset <= 1;
		@(posedge clk);
		reset <= 1;
		in = 0;
		@(negedge clk) wavedrom_start("Example");
		repeat(1) @(posedge clk);
		reset = 0;
		@(posedge clk) in = 32'h2;
		repeat(4) @(posedge clk);
		in = 32'he;
		repeat(2) @(posedge clk);
		in = 0;
		@(posedge clk) in = 32'h2;
		repeat(2) @(posedge clk);
		reset = 1;
		@(posedge clk);
		reset = 0; in = 0;
		repeat(3) @(posedge clk);

		@(negedge clk) wavedrom_stop();

		@(negedge clk) wavedrom_start("");
		repeat(2) @(posedge clk);
		in <= 1;
		repeat(2) @(posedge clk);
		in <= 0;
		repeat(2) @(negedge clk);
		in <= 6;
		repeat(1) @(negedge clk);
		in <= 0;
		repeat(2) @(posedge clk);
		in <= 32'h10;
		repeat(2) @(posedge clk);
		reset <= 1;
		repeat(1) @(posedge clk);
		in <= 32'h0;
		repeat(1) @(posedge clk);
		reset <= 0;
		repeat(1) @(posedge clk);
		reset <= 1;
		in <= 32'h20;
		repeat(1) @(posedge clk);
		reset <= 0;
		in <= 32'h00;

		repeat(2) @(posedge clk);

		@(negedge clk) wavedrom_stop();

		repeat(200)
			@(posedge clk, negedge clk) begin
				in <= $random;
				reset <= !($random & 15);
			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 reset;
	logic [31:0] in;
	logic [31:0] out_ref;
	logic [31:0] out_dut;

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

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

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

	top_module top_module1 (
		.clk,
		.reset,
		.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: For each bit in a 32-bit vector, capture when the input signal changes from 1 in one clock cycle to 0 the next. "Capture" means that the output will remain 1 until the register is reset (active high synchronous reset).


prompt:
module top_module (
	input [15:0] scancode,
	output reg left,
	output reg down,
	output reg right,
	output reg up
);

test:
`timescale 1 ps/1 ps
`define OK 12
`define INCORRECT 13
module reference_module (
	input [15:0] scancode,
	output reg left,
	output reg down,
	output reg right,
	output reg up
);

	always @(*) begin
		{up, left, down, right} = 0;
		case (scancode)
			16'he06b: left = 1;
			16'he072: down = 1;
			16'he074: right = 1;
			16'he075: up = 1;
		endcase
	end

endmodule

module stimulus_gen (
	input clk,
	output logic [15:0] scancode,
	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
		@(negedge clk) wavedrom_start("Recognize arrow keys");
			@(posedge clk) scancode <= 16'h0;
			@(posedge clk) scancode <= 16'h1;
			@(posedge clk) scancode <= 16'he075;
			@(posedge clk) scancode <= 16'he06b;
			@(posedge clk) scancode <= 16'he06c;
			@(posedge clk) scancode <= 16'he072;
			@(posedge clk) scancode <= 16'he074;
			@(posedge clk) scancode <= 16'he076;
			@(posedge clk) scancode <= 16'hffff;
		@(negedge clk) wavedrom_stop();

		repeat(30000) @(posedge clk, negedge clk) begin
			scancode <= $urandom;
		end
		$finish;
	end

endmodule

module tb();

	typedef struct packed {
		int errors;
		int errortime;
		int errors_left;
		int errortime_left;
		int errors_down;
		int errortime_down;
		int errors_right;
		int errortime_right;
		int errors_up;
		int errortime_up;

		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] scancode;
	logic left_ref;
	logic left_dut;
	logic down_ref;
	logic down_dut;
	logic right_ref;
	logic right_dut;
	logic up_ref;
	logic up_dut;

	initial begin
		$dumpfile("wave.vcd");
		$dumpvars(1, stim1.clk, tb_mismatch ,scancode,left_ref,left_dut,down_ref,down_dut,right_ref,right_dut,up_ref,up_dut );
	end

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

	stimulus_gen stim1 (
		.clk,
		.* ,
		.scancode );
	reference_module good1 (
		.scancode,
		.left(left_ref),
		.down(down_ref),
		.right(right_ref),
		.up(up_ref) );

	top_module top_module1 (
		.scancode,
		.left(left_dut),
		.down(down_dut),
		.right(right_dut),
		.up(up_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_left) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "left", stats1.errors_left, stats1.errortime_left);
		else $display("Hint: Output '%s' has no mismatches.", "left");
		if (stats1.errors_down) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "down", stats1.errors_down, stats1.errortime_down);
		else $display("Hint: Output '%s' has no mismatches.", "down");
		if (stats1.errors_right) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "right", stats1.errors_right, stats1.errortime_right);
		else $display("Hint: Output '%s' has no mismatches.", "right");
		if (stats1.errors_up) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "up", stats1.errors_up, stats1.errortime_up);
		else $display("Hint: Output '%s' has no mismatches.", "up");

		$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 = ( { left_ref, down_ref, right_ref, up_ref } === ( { left_ref, down_ref, right_ref, up_ref } ^ { left_dut, down_dut, right_dut, up_dut } ^ { left_ref, down_ref, right_ref, up_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 (left_ref !== ( left_ref ^ left_dut ^ left_ref ))
		begin if (stats1.errors_left == 0) stats1.errortime_left = $time;
			stats1.errors_left = stats1.errors_left+1'b1; end
		if (down_ref !== ( down_ref ^ down_dut ^ down_ref ))
		begin if (stats1.errors_down == 0) stats1.errortime_down = $time;
			stats1.errors_down = stats1.errors_down+1'b1; end
		if (right_ref !== ( right_ref ^ right_dut ^ right_ref ))
		begin if (stats1.errors_right == 0) stats1.errortime_right = $time;
			stats1.errors_right = stats1.errors_right+1'b1; end
		if (up_ref !== ( up_ref ^ up_dut ^ up_ref ))
		begin if (stats1.errors_up == 0) stats1.errortime_up = $time;
			stats1.errors_up = stats1.errors_up+1'b1; end

	end
endmodule

detail_description:
Suppose you're building a circuit to process scancodes from a PS/2 keyboard for a game. Given the last two bytes of scancodes received, you need to indicate whether one of the arrow keys on the keyboard have been pressed. This involves a fairly simple mapping, which can be implemented as a case statement (or if-elseif) with four cases.
// Scancode[15:0] | Arrow key
// 16'he06b | left arrow
// 16'he072 | down arrow
// 16'he074 | right arrow
// 16'he075 | up arrow
// Anything else | none
// Your circuit has one 16-bit input, and four outputs. Build this circuit that recognizes these four scancodes and asserts the correct output.


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

canonical_solution:
	assign out = in;

endmodule

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

	assign out = in;

endmodule

module stimulus_gen (
	input clk,
	output reg in = 0
);

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

		#1 $finish;
	end

endmodule

module tb();

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

		int clocks;
	} stats;

	stats stats1;

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

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

	logic in;
	logic out_ref;
	logic out_dut;

	initial begin
		$dumpfile("wave.vcd");
		$dumpvars(1, stim1.clk, tb_mismatch ,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: The module assigns the output port to the same value as the input port combinationally.


prompt:
module top_module (
	input [2:0] in,
	output [1:0] out
);

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

	assign out = in[0]+in[1]+in[2];

endmodule

module stimulus_gen (
	input clk,
	output logic [2: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 <= 7;
		@(negedge clk);
		wavedrom_start();
			repeat(9) @(posedge clk) in <= in + 1'b1;
		@(negedge clk);
		wavedrom_stop();
		repeat(200) @(posedge clk, negedge clk)
			in <= $random;
		$finish;
	end

endmodule

module tb();

	typedef struct packed {
		int errors;
		int errortime;
		int errors_out;
		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 [2:0] in;
	logic [1:0] out_ref;
	logic [1: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: A "population count" circuit counts the number of '1's in an input vector. Build a population count circuit for a 3-bit input vector.


task_id: vectorr

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

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

	assign {out[0],out[1],out[2],out[3],out[4],out[5],out[6],out[7]} = in;

endmodule

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

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

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

	task wavedrom_stop;
		#1;
	endtask

	initial begin
		in <= 0;
		@(negedge clk) wavedrom_start();
			@(posedge clk) in <= 8'h1;
			@(posedge clk) in <= 8'h2;
			@(posedge clk) in <= 8'h4;
			@(posedge clk) in <= 8'h8;
			@(posedge clk) in <= 8'h80;
			@(posedge clk) in <= 8'hc0;
			@(posedge clk) in <= 8'he0;
			@(posedge clk) in <= 8'hf0;
		@(negedge clk) wavedrom_stop();

		repeat(200) @(posedge clk, negedge clk)
			in <= $random;
		$finish;
	end

endmodule

module tb();

	typedef struct packed {
		int errors;
		int errortime;
		int errors_out;
		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 [7:0] out_ref;
	logic [7:0] out_dut;

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

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

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

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

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

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

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

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

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

	end
endmodule

detail_description: Given an 8-bit input vector [7:0], reverse its bit ordering.


prompt:
module top_module(
	input clk,
	input [7:0] d,
	input reset,
	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 reset,
	output reg [7:0] q);

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

endmodule

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

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

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

	task wavedrom_stop;
		#1;
	endtask

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

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

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

	endtask

	initial begin
		reset <= 1;
		d <= $random;
		wavedrom_start("Synchronous active-high reset");
		reset_test();
		repeat(10) @(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 reset;
	logic [7:0] q_ref;
	logic [7:0] q_dut;

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

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

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

	top_module top_module1 (
		.clk,
		.d,
		.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: Create 8 D flip-flops with active high synchronous reset setting the output to zero. All DFFs should be triggered by the positive edge of clk.


prompt:
module top_module (
	input clk,
	input resetn,
	input x,
	input y,
	output f,
	output g
);

test:
`timescale 1 ps/1 ps
`define OK 12
`define INCORRECT 13
module reference_module (
	input clk,
	input resetn,
	input x,
	input y,
	output f,
	output g
);
	parameter A=0, B=1, S0=2, S1=3, S10=4, G1=5, G2=6, P0=7, P1=8;
	reg [3:0] state, next;

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

	always_comb begin
		case (state)
			A: next = B;
			B: next = S0;
			S0: next = x ? S1 : S0;
			S1: next = x ? S1 : S10;
			S10: next = x? G1 : S0;
			G1: next = y ? P1 : G2;
			G2: next = y ? P1 : P0;
			P0: next = P0;
			P1: next = P1;
			default: next = 'x;
		endcase
	end

	assign f = (state == B);
	assign g = (state == G1) || (state == G2) || (state == P1);
endmodule

module stimulus_gen (
	input clk,
	output logic resetn,
	output logic x, y
);

	initial begin
		resetn = 0;
		x = 0;
		y = 0;
		@(posedge clk);
		@(posedge clk);
		resetn = 1;
		repeat(500) @(negedge clk) begin
			resetn <= ($random & 31) != 0;
			{x,y} <= $random;
		end

		#1 $finish;
	end

endmodule

module tb();

	typedef struct packed {
		int errors;
		int errortime;
		int errors_f;
		int errortime_f;
		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 x;
	logic y;
	logic f_ref;
	logic f_dut;
	logic g_ref;
	logic g_dut;

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

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

	stimulus_gen stim1 (
		.clk,
		.* ,
		.resetn,
		.x,
		.y );
	reference_module good1 (
		.clk,
		.resetn,
		.x,
		.y,
		.f(f_ref),
		.g(g_ref) );

	top_module top_module1 (
		.clk,
		.resetn,
		.x,
		.y,
		.f(f_dut),
		.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_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");
		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 = ( { f_ref, g_ref } === ( { f_ref, g_ref } ^ { f_dut, g_dut } ^ { f_ref, 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 (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
		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 a finite state machine that is used to control some type of motor. The FSM has inputs x and y, which come from the motor, and produces outputs f and g, which control the motor. There is also a clock input called clk and a reset input (synchronous, active low) called resetn. The FSM has to work as follows. As long as the reset input is asserted, the FSM stays in a beginning state, called state A. When the reset signal is de-asserted, then after the next clock edge the FSM has to set the output f to 1 for one clock cycle. Then, the FSM has to monitor the x input. When x has produced the values 1, 0, 1 in three successive clock cycles, then g should be set to 1 on the following clock cycle. While maintaining g = 1 the FSM has to monitor the y input. If y has the value 1 within at most two clock cycles, then the FSM should maintain g = 1 permanently (that is, until reset). But if y does not become 1 within two clock cycles, then the FSM should set g = 0 permanently (until reset).


prompt:
module top_module (
	input [7:0] a,
	input [7:0] b,
	output [7:0] s,
	output overflow
);

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

	wire [8:0] sum = a+b;
	assign s = sum[7:0];
	assign overflow = !(a[7]^b[7]) && (a[7] != s[7]);

endmodule

module stimulus_gen (
	input clk,
	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} <= 0;
		@(negedge clk) wavedrom_start();
			@(posedge clk) {a, b} <= 16'h0;
			@(posedge clk) {a, b} <= 16'h0070;
			@(posedge clk) {a, b} <= 16'h7070;
			@(posedge clk) {a, b} <= 16'h7090;
			@(posedge clk) {a, b} <= 16'h9070;
			@(posedge clk) {a, b} <= 16'h9090;
			@(posedge clk) {a, b} <= 16'h90ff;
		@(negedge clk) wavedrom_stop();
		repeat(100) @(posedge clk, negedge clk)
			{a,b} <= $random;

		$finish;
	end

endmodule

module tb();

	typedef struct packed {
		int errors;
		int errortime;
		int errors_s;
		int errortime_s;
		int errors_overflow;
		int errortime_overflow;

		int clocks;
	} stats;

	stats stats1;

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

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

	logic [7:0] a;
	logic [7:0] b;
	logic [7:0] s_ref;
	logic [7:0] s_dut;
	logic overflow_ref;
	logic overflow_dut;

	initial begin
		$dumpfile("wave.vcd");
		$dumpvars(1, stim1.clk, tb_mismatch ,a,b,s_ref,s_dut,overflow_ref,overflow_dut );
	end

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

	stimulus_gen stim1 (
		.clk,
		.* ,
		.a,
		.b );
	reference_module good1 (
		.a,
		.b,
		.s(s_ref),
		.overflow(overflow_ref) );

	top_module top_module1 (
		.a,
		.b,
		.s(s_dut),
		.overflow(overflow_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_s) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "s", stats1.errors_s, stats1.errortime_s);
		else $display("Hint: Output '%s' has no mismatches.", "s");
		if (stats1.errors_overflow) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "overflow", stats1.errors_overflow, stats1.errortime_overflow);
		else $display("Hint: Output '%s' has no mismatches.", "overflow");

		$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 = ( { s_ref, overflow_ref } === ( { s_ref, overflow_ref } ^ { s_dut, overflow_dut } ^ { s_ref, overflow_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 (s_ref !== ( s_ref ^ s_dut ^ s_ref ))
		begin if (stats1.errors_s == 0) stats1.errortime_s = $time;
			stats1.errors_s = stats1.errors_s+1'b1; end
		if (overflow_ref !== ( overflow_ref ^ overflow_dut ^ overflow_ref ))
		begin if (stats1.errors_overflow == 0) stats1.errortime_overflow = $time;
			stats1.errors_overflow = stats1.errors_overflow+1'b1; end

	end
endmodule

detail_description: Assume that you have two 8-bit 2's complement numbers, a[7:0] and b[7:0]. These numbers are added to produce s[7:0]. Also compute whether a (signed) overflow has occurred.


prompt:
module top_module (
	input a,
	input b,
	input c,
	input d,
	output out_sop,
	output out_pos
);

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

	wire pos0, pos1;
	assign out_sop = c&d | ~a&~b&c;
	assign pos0 = c & (~b|d)&(~a|b);
	assign pos1 = c & (~b|d)&(~a|d);

	assign out_pos = (pos0 == pos1) ? pos0 : 1'bx;
endmodule

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

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

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

	task wavedrom_stop;
		#1;
	endtask

	bit fail = 0;
	bit fail1 = 0;
	always @(posedge clk, negedge clk)
		if (!tb_match)
			fail = 1;

	initial begin
		@(posedge clk) {a,b,c,d} <= 0;
		@(posedge clk) {a,b,c,d} <= 1;
		@(posedge clk) {a,b,c,d} <= 2;
		@(posedge clk) {a,b,c,d} <= 4;
		@(posedge clk) {a,b,c,d} <= 5;
		@(posedge clk) {a,b,c,d} <= 6;
		@(posedge clk) {a,b,c,d} <= 7;
		@(posedge clk) {a,b,c,d} <= 9;
		@(posedge clk) {a,b,c,d} <= 10;
		@(posedge clk) {a,b,c,d} <= 13;
		@(posedge clk) {a,b,c,d} <= 14;
		@(posedge clk) {a,b,c,d} <= 15;
		@(posedge clk) fail1 = fail;

		//@(negedge clk) wavedrom_start();
			for (int i=0;i<16;i++)
				@(posedge clk)
					{a,b,c,d} <= i;
		//@(negedge clk) wavedrom_stop();

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

		if (fail && ~fail1)
			$display("Hint: Your circuit passes on the 12 required input combinations, but doesn't match the don't-care cases. Are you using minimal SOP and POS?");

		$finish;
	end

endmodule

module tb();

	typedef struct packed {
		int errors;
		int errortime;
		int errors_out_sop;
		int errortime_out_sop;
		int errors_out_pos;
		int errortime_out_pos;

		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_sop_ref;
	logic out_sop_dut;
	logic out_pos_ref;
	logic out_pos_dut;

	initial begin
		$dumpfile("wave.vcd");
		$dumpvars(1, stim1.clk, tb_mismatch ,a,b,c,d,out_sop_ref,out_sop_dut,out_pos_ref,out_pos_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_sop(out_sop_ref),
		.out_pos(out_pos_ref) );

	top_module top_module1 (
		.a,
		.b,
		.c,
		.d,
		.out_sop(out_sop_dut),
		.out_pos(out_pos_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_sop) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "out_sop", stats1.errors_out_sop, stats1.errortime_out_sop);
		else $display("Hint: Output '%s' has no mismatches.", "out_sop");
		if (stats1.errors_out_pos) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "out_pos", stats1.errors_out_pos, stats1.errortime_out_pos);
		else $display("Hint: Output '%s' has no mismatches.", "out_pos");

		$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_sop_ref, out_pos_ref } === ( { out_sop_ref, out_pos_ref } ^ { out_sop_dut, out_pos_dut } ^ { out_sop_ref, out_pos_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_sop_ref !== ( out_sop_ref ^ out_sop_dut ^ out_sop_ref ))
		begin if (stats1.errors_out_sop == 0) stats1.errortime_out_sop = $time;
			stats1.errors_out_sop = stats1.errors_out_sop+1'b1; end
		if (out_pos_ref !== ( out_pos_ref ^ out_pos_dut ^ out_pos_ref ))
		begin if (stats1.errors_out_pos == 0) stats1.errortime_out_pos = $time;
			stats1.errors_out_pos = stats1.errors_out_pos+1'b1; end

	end
endmodule

detail_description: A single-output digital system with four inputs (a,b,c,d) generates a logic-1 when 2, 7, or 15 appears on the inputs, and a logic-0 when 0, 1, 4, 5, 6, 9, 10, 13, or 14 appears. The input conditions for the numbers 3, 8, 11, and 12 never occur in this system. For example, 7 corresponds to a,b,c,d being set to 0,1,1,1, respectively. Determine the output out_sop in minimum sum-of-products form, and the output out_pos in minimum product-of-sums form.


prompt:
module top_module (
	input [6:1] y,
	input w,
	output Y2,
	output Y4
);

test:
`timescale 1 ps/1 ps
`define OK 12
`define INCORRECT 13
module reference_module (
	input [6:1] y,
	input w,
	output Y2,
	output Y4
);
	assign Y2 = y[1]&~w;
	assign Y4 = (y[2]|y[3]|y[5]|y[6]) & w;

endmodule

module stimulus_gen (
	input clk,
	output logic[6:1] y,
	output logic w,
	input tb_match
);

	int errored1 = 0;
	int onehot_error = 0;
	int temp;

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

		// Random.
		errored1 = 0;
		repeat(400) @(posedge clk, negedge clk) begin
			do
				temp = $random;
			while ( !{temp[6:5],temp[3:2]} == !{temp[4],temp[1]} );
			// Make y[4,1] and y[6,5,3,2] mutually exclusive, so we can accept Y4=(~y[1] & ~y[4]) &w as a valid answer too.

			y[6:1] <= temp[6:1];
			w <= $random;
			if (!tb_match)
				errored1++;
		end
		if (!onehot_error && errored1)
			$display ("Hint: Your circuit passed when given only one-hot inputs, but not with semi-random inputs.");

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

		#1 $finish;
	end

endmodule

module tb();

	typedef struct packed {
		int errors;
		int errortime;
		int errors_Y2;
		int errortime_Y2;
		int errors_Y4;
		int errortime_Y4;

		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 [6:1] y;
	logic w;
	logic Y2_ref;
	logic Y2_dut;
	logic Y4_ref;
	logic Y4_dut;

	initial begin
		$dumpfile("wave.vcd");
		$dumpvars(1, stim1.clk, tb_mismatch ,y,w,Y2_ref,Y2_dut,Y4_ref,Y4_dut );
	end

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

	stimulus_gen stim1 (
		.clk,
		.* ,
		.y,
		.w );
	reference_module good1 (
		.y,
		.w,
		.Y2(Y2_ref),
		.Y4(Y4_ref) );

	top_module top_module1 (
		.y,
		.w,
		.Y2(Y2_dut),
		.Y4(Y4_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_Y2) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "Y2", stats1.errors_Y2, stats1.errortime_Y2);
		else $display("Hint: Output '%s' has no mismatches.", "Y2");
		if (stats1.errors_Y4) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "Y4", stats1.errors_Y4, stats1.errortime_Y4);
		else $display("Hint: Output '%s' has no mismatches.", "Y4");

		$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 = ( { Y2_ref, Y4_ref } === ( { Y2_ref, Y4_ref } ^ { Y2_dut, Y4_dut } ^ { Y2_ref, Y4_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 (Y2_ref !== ( Y2_ref ^ Y2_dut ^ Y2_ref ))
		begin if (stats1.errors_Y2 == 0) stats1.errortime_Y2 = $time;
			stats1.errors_Y2 = stats1.errors_Y2+1'b1; end
		if (Y4_ref !== ( Y4_ref ^ Y4_dut ^ Y4_ref ))
		begin if (stats1.errors_Y4 == 0) stats1.errortime_Y4 = $time;
			stats1.errors_Y4 = stats1.errors_Y4+1'b1; end

	end
endmodule

detail_description:
Consider the state machine shown below:

// A (0) --0--> B
// A (0) --1--> A
// B (0) --0--> C
// B (0) --1--> D
// C (0) --0--> E
// C (0) --1--> D
// D (0) --0--> F
// D (0) --1--> A
// E (1) --0--> E
// E (1) --1--> D
// F (1) --0--> C
// F (1) --1--> D

// Resets into state A. For this part, assume that a one-hot code is used with the state assignment y[6:1] = 000001, 000010, 000100, 001000, 010000, 100000 for states A, B,..., F, respectively.

// Write Verilog for the next-state signals Y2 and Y4 corresponding to signal y[2] and y[4]. Derive the logic equations by inspection assuming a one-hot encoding.


task_id: reduction

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

canonical_solution:
	assign parity = ^in;

endmodule

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

	assign parity = ^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_parity;
		int errortime_parity;

		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 parity_ref;
	logic parity_dut;

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

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

	stimulus_gen stim1 (
		.clk,
		.* ,
		.in );
	reference_module good1 (
		.in,
		.parity(parity_ref) );

	top_module top_module1 (
		.in,
		.parity(parity_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_parity) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "parity", stats1.errors_parity, stats1.errortime_parity);
		else $display("Hint: Output '%s' has no mismatches.", "parity");

		$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 = ( { parity_ref } === ( { parity_ref } ^ { parity_dut } ^ { parity_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 (parity_ref !== ( parity_ref ^ parity_dut ^ parity_ref ))
		begin if (stats1.errors_parity == 0) stats1.errortime_parity = $time;
			stats1.errors_parity = stats1.errors_parity+1'b1; end

	end
endmodule

detail_description: Parity checking is often used as a simple method of detecting errors when transmitting data through an imperfect channel. Create a circuit that will compute a parity bit for a 8-bit byte (which will add a 9th bit to the byte). We will use "even" parity, where the parity bit is just the XOR of all 8 data bits.


task_id: gates

prompt:
module top_module (
	input a,
	input b,
	output out_and,
	output out_or,
	output out_xor,
	output out_nand,
	output out_nor,
	output out_xnor,
	output out_anotb
);

test:
`timescale 1 ps/1 ps
`define OK 12
`define INCORRECT 13
module reference_module (
	input a,
	input b,
	output out_and,
	output out_or,
	output out_xor,
	output out_nand,
	output out_nor,
	output out_xnor,
	output out_anotb
);

	assign out_and = a&b;
	assign out_or = a|b;
	assign out_xor = a^b;
	assign out_nand = ~(a&b);
	assign out_nor = ~(a|b);
	assign out_xnor = a^~b;
	assign out_anotb = 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
		@(negedge clk) {a,b} <= 0;
		wavedrom_start();
			@(posedge clk) {a,b} <= 0;
			@(posedge clk) {a,b} <= 1;
			@(posedge clk) {a,b} <= 2;
			@(posedge clk) {a,b} <= 3;
			@(negedge clk);
		wavedrom_stop();
		repeat(200) @(posedge clk, negedge clk)
		{a,b} <= $random;
		$finish;
	end

endmodule

module tb();

	typedef struct packed {
		int errors;
		int errortime;
		int errors_out_and;
		int errortime_out_and;
		int errors_out_or;
		int errortime_out_or;
		int errors_out_xor;
		int errortime_out_xor;
		int errors_out_nand;
		int errortime_out_nand;
		int errors_out_nor;
		int errortime_out_nor;
		int errors_out_xnor;
		int errortime_out_xnor;
		int errors_out_anotb;
		int errortime_out_anotb;

		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_and_ref;
	logic out_and_dut;
	logic out_or_ref;
	logic out_or_dut;
	logic out_xor_ref;
	logic out_xor_dut;
	logic out_nand_ref;
	logic out_nand_dut;
	logic out_nor_ref;
	logic out_nor_dut;
	logic out_xnor_ref;
	logic out_xnor_dut;
	logic out_anotb_ref;
	logic out_anotb_dut;

	initial begin
		$dumpfile("wave.vcd");
		$dumpvars(1, stim1.clk, tb_mismatch ,a,b,out_and_ref,out_and_dut,out_or_ref,out_or_dut,out_xor_ref,out_xor_dut,out_nand_ref,out_nand_dut,out_nor_ref,out_nor_dut,out_xnor_ref,out_xnor_dut,out_anotb_ref,out_anotb_dut );
	end

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

	stimulus_gen stim1 (
		.clk,
		.* ,
		.a,
		.b );
	reference_module good1 (
		.a,
		.b,
		.out_and(out_and_ref),
		.out_or(out_or_ref),
		.out_xor(out_xor_ref),
		.out_nand(out_nand_ref),
		.out_nor(out_nor_ref),
		.out_xnor(out_xnor_ref),
		.out_anotb(out_anotb_ref) );

	top_module top_module1 (
		.a,
		.b,
		.out_and(out_and_dut),
		.out_or(out_or_dut),
		.out_xor(out_xor_dut),
		.out_nand(out_nand_dut),
		.out_nor(out_nor_dut),
		.out_xnor(out_xnor_dut),
		.out_anotb(out_anotb_dut) );

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

	final begin
		if (stats1.errors_out_and) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "out_and", stats1.errors_out_and, stats1.errortime_out_and);
		else $display("Hint: Output '%s' has no mismatches.", "out_and");
		if (stats1.errors_out_or) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "out_or", stats1.errors_out_or, stats1.errortime_out_or);
		else $display("Hint: Output '%s' has no mismatches.", "out_or");
		if (stats1.errors_out_xor) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "out_xor", stats1.errors_out_xor, stats1.errortime_out_xor);
		else $display("Hint: Output '%s' has no mismatches.", "out_xor");
		if (stats1.errors_out_nand) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "out_nand", stats1.errors_out_nand, stats1.errortime_out_nand);
		else $display("Hint: Output '%s' has no mismatches.", "out_nand");
		if (stats1.errors_out_nor) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "out_nor", stats1.errors_out_nor, stats1.errortime_out_nor);
		else $display("Hint: Output '%s' has no mismatches.", "out_nor");
		if (stats1.errors_out_xnor) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "out_xnor", stats1.errors_out_xnor, stats1.errortime_out_xnor);
		else $display("Hint: Output '%s' has no mismatches.", "out_xnor");
		if (stats1.errors_out_anotb) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "out_anotb", stats1.errors_out_anotb, stats1.errortime_out_anotb);
		else $display("Hint: Output '%s' has no mismatches.", "out_anotb");

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

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

		stats1.clocks++;
		if (!tb_match) begin
			if (stats1.errors == 0) stats1.errortime = $time;
			stats1.errors++;
		end
		if (out_and_ref !== ( out_and_ref ^ out_and_dut ^ out_and_ref ))
		begin if (stats1.errors_out_and == 0) stats1.errortime_out_and = $time;
			stats1.errors_out_and = stats1.errors_out_and+1'b1; end
		if (out_or_ref !== ( out_or_ref ^ out_or_dut ^ out_or_ref ))
		begin if (stats1.errors_out_or == 0) stats1.errortime_out_or = $time;
			stats1.errors_out_or = stats1.errors_out_or+1'b1; end
		if (out_xor_ref !== ( out_xor_ref ^ out_xor_dut ^ out_xor_ref ))
		begin if (stats1.errors_out_xor == 0) stats1.errortime_out_xor = $time;
			stats1.errors_out_xor = stats1.errors_out_xor+1'b1; end
		if (out_nand_ref !== ( out_nand_ref ^ out_nand_dut ^ out_nand_ref ))
		begin if (stats1.errors_out_nand == 0) stats1.errortime_out_nand = $time;
			stats1.errors_out_nand = stats1.errors_out_nand+1'b1; end
		if (out_nor_ref !== ( out_nor_ref ^ out_nor_dut ^ out_nor_ref ))
		begin if (stats1.errors_out_nor == 0) stats1.errortime_out_nor = $time;
			stats1.errors_out_nor = stats1.errors_out_nor+1'b1; end
		if (out_xnor_ref !== ( out_xnor_ref ^ out_xnor_dut ^ out_xnor_ref ))
		begin if (stats1.errors_out_xnor == 0) stats1.errortime_out_xnor = $time;
			stats1.errors_out_xnor = stats1.errors_out_xnor+1'b1; end
		if (out_anotb_ref !== ( out_anotb_ref ^ out_anotb_dut ^ out_anotb_ref ))
		begin if (stats1.errors_out_anotb == 0) stats1.errortime_out_anotb = $time;
			stats1.errors_out_anotb = stats1.errors_out_anotb+1'b1; end

	end
endmodule

detail_description:
Build a combinational circuit with two inputs, a and b. There are 7 outputs, each with a logic gate driving it:
// (1) out_and: a and b
// (2) out_or: a or b
// (3) out_xor: a xor b
// (4) out_nand: a nand b
// (5) out_nor: a nor b
// (6) out_xnor: a xnor b
// (7) out_anotb: a and-not b


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

test:
`timescale 1 ps/1 ps
`define OK 12
`define INCORRECT 13
// hdlbits_prop {len: 5}
module reference_module (
	input a,
	input b,
	input c,
	input d,
	output out,
	output out_n );

	wire w1, w2;
	assign w1 = a&b;
	assign w2 = c&d;
	assign out = w1|w2;
	assign out_n = ~out;

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
		{a,b,c,d} = 4'h0;
		@(negedge clk);
		wavedrom_start("Exhaustive test");
		repeat(20) @(posedge clk, negedge clk)
			{d,c,b,a} <= {d,c,b,a} + 1'b1;
		wavedrom_stop();
		repeat(100) @(posedge clk, negedge clk) begin
			{a,b,c,d} <= $random;
		end

		#1 $finish;
	end

endmodule

module tb();

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

		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;
	logic out_n_ref;
	logic out_n_dut;

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

	top_module top_module1 (
		.a,
		.b,
		.c,
		.d,
		.out(out_dut),
		.out_n(out_n_dut) );

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

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

		$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_n_ref } === ( { out_ref, out_n_ref } ^ { out_dut, out_n_dut } ^ { out_ref, out_n_ref } ) );
	// Use explicit sensitivity list here. @(*) causes NetProc::nex_input() to be called when trying to compute
	// the sensitivity list of the @(strobe) process, which isn't implemented.
	always @(posedge clk, negedge clk) begin

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

	end
endmodule

detail_description:
Implement the following circuit. Create two intermediate wires (named anything you want) to connect the AND and OR gates together. Note that the wire that feeds the NOT gate is really wire `out`, so you do not necessarily need to declare a third wire here. Notice how wires are driven by exactly one source (output of a gate), but can feed multiple inputs.

// The circuit is composed of two layers. The first layer, counting from the input, is two AND gates: one whose input is connected to a and b, and the second is connected to c and d. The second layer there is an OR gate to OR the two AND outputs, connected the output 'out'. Additionally, there is an inverted output 'out_n'.


prompt:
module top_module(
	input p1a,
	input p1b,
	input p1c,
	input p1d,
	input p1e,
	input p1f,
	output p1y,
	input p2a,
	input p2b,
	input p2c,
	input p2d,
	output p2y
);

test:
`timescale 1 ps/1 ps
`define OK 12
`define INCORRECT 13
module reference_module(
	input p1a,
	input p1b,
	input p1c,
	input p1d,
	input p1e,
	input p1f,
	output p1y,
	input p2a,
	input p2b,
	input p2c,
	input p2d,
	output p2y
);

	assign p1y = &{p1a, p1b, p1c} | &{p1d, p1e, p1f};
	assign p2y = &{p2a, p2b} | &{p2c, p2d};

endmodule

module stimulus_gen (
	input clk,
	output reg p1a, p1b, p1c, p1d, p1e, p1f,
	output reg p2a, p2b, p2c, p2d,
	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;
		{p1a,p1b,p1c,p1d,p1e,p1f} <= 4'h0;
		{p2a,p2b,p2c,p2d} <= 4'h0;
		wavedrom_start();
		repeat(20) @(posedge clk) begin
			{p1a,p1b,p1c,p1d,p1e,p1f} <= {count[2:0], count[3:1]};
			{p2a,p2b,p2c,p2d} <= count;
			count = count + 1;
		end
		wavedrom_stop();

		repeat(400) @(posedge clk,negedge clk) begin
			{p1a,p1b,p1c,p1d,p2a,p2b,p2c,p2d} <= $random;
		end

		#1 $finish;
	end

endmodule

module tb();

	typedef struct packed {
		int errors;
		int errortime;
		int errors_p1y;
		int errortime_p1y;
		int errors_p2y;
		int errortime_p2y;

		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 p1a;
	logic p1b;
	logic p1c;
	logic p1d;
	logic p1e;
	logic p1f;
	logic p2a;
	logic p2b;
	logic p2c;
	logic p2d;
	logic p1y_ref;
	logic p1y_dut;
	logic p2y_ref;
	logic p2y_dut;

	initial begin
		$dumpfile("wave.vcd");
		$dumpvars(1, stim1.clk, tb_mismatch ,p1a,p1b,p1c,p1d,p1e,p1f,p2a,p2b,p2c,p2d,p1y_ref,p1y_dut,p2y_ref,p2y_dut );
	end

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

	stimulus_gen stim1 (
		.clk,
		.* ,
		.p1a,
		.p1b,
		.p1c,
		.p1d,
		.p1e,
		.p1f,
		.p2a,
		.p2b,
		.p2c,
		.p2d );
	reference_module good1 (
		.p1a,
		.p1b,
		.p1c,
		.p1d,
		.p1e,
		.p1f,
		.p2a,
		.p2b,
		.p2c,
		.p2d,
		.p1y(p1y_ref),
		.p2y(p2y_ref) );

	top_module top_module1 (
		.p1a,
		.p1b,
		.p1c,
		.p1d,
		.p1e,
		.p1f,
		.p2a,
		.p2b,
		.p2c,
		.p2d,
		.p1y(p1y_dut),
		.p2y(p2y_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_p1y) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "p1y", stats1.errors_p1y, stats1.errortime_p1y);
		else $display("Hint: Output '%s' has no mismatches.", "p1y");
		if (stats1.errors_p2y) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "p2y", stats1.errors_p2y, stats1.errortime_p2y);
		else $display("Hint: Output '%s' has no mismatches.", "p2y");

		$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 = ( { p1y_ref, p2y_ref } === ( { p1y_ref, p2y_ref } ^ { p1y_dut, p2y_dut } ^ { p1y_ref, p2y_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 (p1y_ref !== ( p1y_ref ^ p1y_dut ^ p1y_ref ))
		begin if (stats1.errors_p1y == 0) stats1.errortime_p1y = $time;
			stats1.errors_p1y = stats1.errors_p1y+1'b1; end
		if (p2y_ref !== ( p2y_ref ^ p2y_dut ^ p2y_ref ))
		begin if (stats1.errors_p2y == 0) stats1.errortime_p2y = $time;
			stats1.errors_p2y = stats1.errors_p2y+1'b1; end

	end
endmodule

detail_description:
The 7458 is a chip with four AND gates and two OR gates. Create a module in Verilog with the same functionality as the 7458 chip. It has 10 inputs and 2 outputs. You may choose to use an `assign` statement to drive each of the output wires, or you may choose to declare (four) wires for use as intermediate signals, where each internal wire is driven by the output of one of the AND gates.

// In this circuit, p1y should be the OR of two 3-input AND gates: one that ANDs p1a, p1b, and p1c, and the second that ANDs p1d, p1e, and p1f. The output p2y is the OR of two 2-input AND gates: one that ANDs p2a and p2b, and the second that ANDs p2c and p2d.


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

test:
`timescale 1 ps/1 ps
`define OK 12
`define INCORRECT 13
module reference_module (
	input clk,
	input reset,
	input w,
	output z
);
	parameter A=0,B=1,C=2,D=3,E=4,F=5;
	reg[2:0] state, next;

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

	always_comb begin
		case (state)
			A: next = w ? B : A;
			B: next = w ? C : D;
			C: next = w ? E : D;
			D: next = w ? F : A;
			E: next = w ? E : D;
			F: next = w ? C : D;
			default: next = 'x;
		endcase
	end

	assign z = (state == E) || (state == F);

endmodule

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

	initial begin
		repeat(200) @(negedge clk) begin
			reset <= ($random & 'h1f) == 0;
			w <= $random;
		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 w;
	logic z_ref;
	logic z_dut;

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

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

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

	top_module top_module1 (
		.clk,
		.reset,
		.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 the state machine shown below:

// A (0) --1--> B
// A (0) --0--> A
// B (0) --1--> C
// B (0) --0--> D
// C (0) --1--> E
// C (0) --0--> D
// D (0) --1--> F
// D (0) --0--> A
// E (1) --1--> E
// E (1) --0--> D
// F (1) --1--> C
// F (1) --0--> D

// Reset resets into state A and is synchronous active-high.

// Write complete Verilog code that represents this FSM. Use separate **always** blocks for the state table and the state flip-flops. Describe the FSM output, which is called _z_, using either continuous assignment statement(s) or an **always** block (at your discretion). Assign any state codes that you wish to use.