Consider the FSM described by the state diagram shown below:

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

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

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

module top_module (
	input clk,
	input resetn,
	input [3:1] r,
	output [3:1] g
);
	parameter A=0, B=1, C=2, D=3;
	reg [1:0] state, next;

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

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

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

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

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

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

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

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

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

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

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

	endtask

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

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

	task wavedrom_stop;
		#1;
	endtask

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

		r <= 1;
		reset_test();

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

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

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

		#1 $finish;
	end

endmodule

module tb();

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

		int clocks;
	} stats;

	stats stats1;

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

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

	logic resetn;
	logic [3:1] r;
	logic [3:1] g_ref;
	logic [3:1] g_dut;

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

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

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

	top_module top_module1 (
		.clk,
		.resetn,
		.r,
		.g(g_dut) );

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

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

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

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

		stats1.clocks++;
		if (!tb_match) begin
			if (stats1.errors == 0) stats1.errortime = $time;
			stats1.errors++;
		end
		if (g_ref !== ( g_ref ^ g_dut ^ g_ref ))
		begin if (stats1.errors_g == 0) stats1.errortime_g = $time;
			stats1.errors_g = stats1.errors_g+1'b1; end

	end
endmodule


Build a decade counter that counts from 0 through 9, inclusive, with a period of 10. The reset input is active high synchronous, and should reset the counter to 0.

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

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

endmodule

`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 == 9)
			q <= 0;
		else
			q <= q+1;

endmodule

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

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

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

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

	endtask

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

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

	task wavedrom_stop;
		#1;
	endtask

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

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

endmodule

module tb();

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

		int clocks;
	} stats;

	stats stats1;

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

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

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

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

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

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

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

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

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

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

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

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

	end
endmodule


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.

module top_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

`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


Create a one-bit wide, 2-to-1 multiplexer. When sel=0, choose a. When sel=1, choose b.

module top_module (
	input a,
	input b,
	input sel,
	output out
);

	assign out = sel ? b : a;

endmodule

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

	assign out = sel ? b : a;

endmodule

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

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

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

	task wavedrom_stop;
		#1;
	endtask

	initial begin
		{a, b, sel} <= 3'b000;
		@(negedge clk) wavedrom_start("Sel chooses between a and b");
			@(posedge clk) {a, b, sel} <= 3'b000;
			@(posedge clk) {a, b, sel} <= 3'b100;
			@(posedge clk) {a, b, sel} <= 3'b110;
			@(posedge clk) {a, b, sel} <= 3'b111;
			@(posedge clk) {a, b, sel} <= 3'b011;
			@(posedge clk) {a, b, sel} <= 3'b001;
			@(posedge clk) {a, b, sel} <= 3'b100;
			@(posedge clk) {a, b, sel} <= 3'b101;
			@(posedge clk) {a, b, sel} <= 3'b110;
			@(posedge clk) {a, b, sel} <= 3'b111;
		@(negedge clk) wavedrom_stop();
		repeat(100) @(posedge clk, negedge clk)
			{a,b,sel} <= $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 a;
	logic b;
	logic sel;
	logic out_ref;
	logic out_dut;

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

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

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

	top_module top_module1 (
		.a,
		.b,
		.sel,
		.out(out_dut) );

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

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

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

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

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

	end
endmodule


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

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

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

endmodule

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

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

endmodule

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

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

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

	task wavedrom_stop;
		#1;
	endtask

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

endmodule

module tb();

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

		int clocks;
	} stats;

	stats stats1;

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

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

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

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

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

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

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

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

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

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

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

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

	end
endmodule


Given the state-assigned table shown below, implement the finite-state machine. Reset should synchronous active high reset the FSM to state 000.

// Present state y[2:0] | Next state y[2:0] x=0, Next state y[2:0] x=1, Output z
// 000 | 000, 001 | 0
// 001 | 001, 100 | 0
// 010 | 010, 001 | 0
// 011 | 001, 010 | 1
// 100 | 011, 100 | 1

module top_module (
	input clk,
	input reset,
	input x,
	output reg z
);
	parameter A=0, B=1, C=2, D=3, E=4;
	reg [2:0] state, next;

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

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

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

endmodule

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

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

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

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

endmodule

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

	initial begin
		reset = 1;
		x = 0;
		@(posedge clk);
		@(posedge clk);
		reset = 0;
		@(posedge clk);
		@(posedge clk);

		repeat(500) @(negedge clk) begin
			reset <= !($random & 63);
			x <= $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 x;
	logic z_ref;
	logic z_dut;

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

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

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

	top_module top_module1 (
		.clk,
		.reset,
		.x,
		.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


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).

module top_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

`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


Create 8 D flip-flops with active high synchronous reset. The flip-flops must be reset to 0x34 rather than zero. All DFFs should be triggered by the negative edge of clk.

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

	always @(negedge clk)
		if (reset)
			q <= 8'h34;
		else
			q <= d;

endmodule

`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 @(negedge clk)
		if (reset)
			q <= 8'h34;
		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;
		@(negedge clk);
		@(negedge clk);
		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


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.

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

	assign parity = ^in;

endmodule

`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


The following is the state transition table for a Moore state machine with one input, one output, and four states. Use the following state encoding: A=2'b00, B=2'b01, C=2'b10, D=2'b11.Implement only the state transition logic and output logic (the combinational logic portion) for this state machine. Given the current state (state), compute the next_state and output (out) based on the state transition table.
// 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

module top_module (
	input in,
	input [1:0] state,
	output reg [1:0] next_state,
	output out
);
	parameter A=0, B=1, C=2, D=3;

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

	assign out = (state==D);

endmodule

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

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

	assign out = (state==D);

endmodule

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

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

		#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 [1:0] state;
	logic [1:0] next_state_ref;
	logic [1: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


The module can be described by the following simulation waveform:

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

module top_module(
	input x,
	input y,
	output z);

	assign z = ~(x^y);

endmodule

`timescale 1 ps/1 ps
`define OK 12
`define INCORRECT 13
module reference_module(
	input x,
	input y,
	output z);

	assign z = ~(x^y);

endmodule

module stimulus_gen (
	input clk,
	output logic x,
	output logic y,
	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
		{x,y} <= 0;
		@(negedge clk) wavedrom_start();
			@(posedge clk) {y,x} <= 0;
			@(posedge clk) {y,x} <= 1;
			@(posedge clk) {y,x} <= 2;
			@(posedge clk) {y,x} <= 3;
		@(negedge clk) wavedrom_stop();
		repeat(100) @(posedge clk, negedge clk)
			{x, y} <= $random % 4;
		#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 x;
	logic y;
	logic z_ref;
	logic z_dut;

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

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

	stimulus_gen stim1 (
		.clk,
		.* ,
		.x,
		.y );
	reference_module good1 (
		.x,
		.y,
		.z(z_ref) );

	top_module top_module1 (
		.x,
		.y,
		.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


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.

module top_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

`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


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

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

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

endmodule

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

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

endmodule

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

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

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

	task wavedrom_stop;
		#1;
	endtask

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

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

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

	endtask

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

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

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

endmodule

module tb();

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

		int clocks;
	} stats;

	stats stats1;

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

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

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

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

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

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

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

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

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

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

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

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

	end
endmodule


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.

module top_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

`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


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

// time            clock           a               p               q
// 0ns             0               0               x               x
// 5ns             0               0               x               x
// 10ns            0               0               x               x
// 15ns            0               0               x               x
// 20ns            0               0               x               x
// 25ns            1               0               0               x
// 30ns            1               0               0               x
// 35ns            1               0               0               x
// 40ns            1               0               0               x
// 45ns            1               0               0               x
// 50ns            1               0               0               x
// 55ns            0               0               0               0
// 60ns            0               0               0               0
// 65ns            0               0               0               0
// 70ns            0               1               0               0
// 75ns            0               0               0               0
// 80ns            0               1               0               0
// 85ns            1               0               0               0
// 90ns            1               1               1               0
// 95ns            1               0               0               0
// 100ns           1               1               1               0
// 105ns           1               0               0               0
// 110ns           1               1               1               0
// 115ns           0               0               1               1
// 120ns           0               1               1               1
// 125ns           0               0               1               1
// 130ns           0               1               1               1
// 135ns           0               0               1               1
// 140ns           0               0               1               1
// 145ns           1               0               0               1
// 150ns           1               0               0               1
// 155ns           1               0               0               1
// 160ns           1               0               0               1
// 165ns           1               1               1               1
// 170ns           1               0               0               1
// 175ns           0               1               0               0
// 180ns           0               0               0               0
// 185ns           0               1               0               0
// 190ns           0               0               0               0

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

	always @(negedge clock)
		q <= a;

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

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

	always @(negedge clock)
		q <= a;

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

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

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

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

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

	task wavedrom_stop;
		#1;
	endtask

	initial begin
		a <= 0;
		@(negedge clock) {a} <= 0;
		@(negedge clk) wavedrom_start("Unknown circuit");
			@(posedge clk) {a} <= 0;
			repeat(14) @(posedge clk,negedge clk) a <= ~a;
			repeat(5) @(posedge clk, negedge clk);
			repeat(8) @(posedge clk,negedge clk) a <= ~a;
		wavedrom_stop();

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

endmodule

module tb();

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

		int clocks;
	} stats;

	stats stats1;

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

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

	logic clock;
	logic a;
	logic p_ref;
	logic p_dut;
	logic q_ref;
	logic q_dut;

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

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

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

	top_module top_module1 (
		.clock,
		.a,
		.p(p_dut),
		.q(q_dut) );

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

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

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

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

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

	end
endmodule


Rule 90 is a one-dimensional cellular automaton with interesting properties. The rules are simple. There is a one-dimensional array of cells (on or off). At each time step, the next state of each cell is the XOR of the cell's two current neighbours:
// Left | Center | Right | Center's next state
// 1 | 1 | 1 | 0
// 1 | 1 | 0 | 1
// 1 | 0 | 1 | 0
// 1 | 0 | 0 | 1
// 0 | 1 | 1 | 1
// 0 | 1 | 0 | 0
// 0 | 0 | 1 | 1
// 0 | 0 | 0 | 0
// In this circuit, create a 512-cell system (q[511:0]), and advance by one time step each clock cycle. The load input indicates the state of the system should be loaded with data[511:0]. Assume the boundaries (q[-1] and q[512]) are both zero (off).

module top_module(
	input clk,
	input load,
	input [511:0] data,
	output reg [511:0] q);

	always @(posedge clk) begin
		if (load)
			q <= data;
		else begin
			q <= q[$bits(q)-1:1] ^ {q[$bits(q)-2:0], 1'b0} ;
		end
	end
endmodule

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

	always @(posedge clk) begin
		if (load)
			q <= data;
		else begin
			q <= q[$bits(q)-1:1] ^ {q[$bits(q)-2:0], 1'b0} ;
		end
	end
endmodule

module stimulus_gen (
	input clk,
	output reg load,
	output reg[511:0] data,
	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
		data <= 0;
		data[0] <= 1'b1;
		load <= 1;
		@(posedge clk); wavedrom_start("Sierpiński triangle: See Hint.");
		@(posedge clk);
		@(posedge clk);
		load <= 0;
		repeat(10) @(posedge clk);
		wavedrom_stop();

		data <= 0;
		data[256] <= 1'b1;
		load <= 1;
		@(posedge clk);
		@(posedge clk);
		@(posedge clk);
		load <= 0;
		repeat(1000) @(posedge clk) begin
		end
		data <= 512'h1000000000000001;
		load <= 1;
		@(posedge clk);
		load <= 0;
		repeat(1000) @(posedge clk) begin
		end

		data <= $random;
		load <= 1;
		@(posedge clk);
		load <= 0;
		repeat(1000) @(posedge clk) begin
		end

		data <= 0;
		load <= 1;
		repeat(20) @(posedge clk);
		repeat(2) @(posedge clk) data <= data + 2;
		@(posedge clk) begin
			load <= 0;
			data <= data + 1;
		end
		repeat(20) @(posedge clk) data <= data + 1;
		repeat(500) @(posedge clk) begin
		end

		#1 $finish;
	end

endmodule

module tb();

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

		int clocks;
	} stats;

	stats stats1;

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

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

	logic load;
	logic [511:0] data;
	logic [511:0] q_ref;
	logic [511:0] q_dut;

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

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

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

	top_module top_module1 (
		.clk,
		.load,
		.data,
		.q(q_dut) );

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

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

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

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

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

	end
endmodule


Create a circuit that has two 2-bit inputs A[1:0] and B[1:0], and produces an output z. The value of z should be 1 if A = B, otherwise z should be 0.

module top_module(
	input [1:0] A,
	input [1:0] B,
	output z);

	assign z = A[1:0]==B[1:0];

endmodule

`timescale 1 ps/1 ps
`define OK 12
`define INCORRECT 13
/*
	Midterm 2015 Question 1k. 2-bit equality comparator.
*/
module reference_module(
	input [1:0] A,
	input [1:0] B,
	output z);

	assign z = A[1:0]==B[1:0];

endmodule

module stimulus_gen (
	input clk,
	output logic [1:0] A,
	output logic [1:0] B
);

	always @(posedge clk, negedge clk)
		{A, B} <= $random % 16;

	initial begin
		repeat(1000) @(negedge clk);
		#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 [1:0] A;
	logic [1:0] B;
	logic z_ref;
	logic z_dut;

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

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

	stimulus_gen stim1 (
		.clk,
		.* ,
		.A,
		.B );
	reference_module good1 (
		.A,
		.B,
		.z(z_ref) );

	top_module top_module1 (
		.A,
		.B,
		.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


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

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

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

endmodule

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

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

endmodule

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

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

endmodule

module tb();

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

		int clocks;
	} stats;

	stats stats1;

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

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

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

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

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

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

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

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

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

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

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

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

	end
endmodule


Implement a D latch using an always block.

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

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

endmodule

`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


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

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

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

endmodule

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

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

endmodule

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

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

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

endmodule

module tb();

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

		int clocks;
	} stats;

	stats stats1;

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

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

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

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

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

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

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

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

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

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

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

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

	end
endmodule


Create a 16-bit wide, 9-to-1 multiplexer. sel=0 chooses a, sel=1 chooses b, etc. For the unused cases (sel=9 to 15), set all output bits to '1'.

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

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

endmodule

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

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

endmodule

module stimulus_gen (
	input clk,
	output logic [15:0] a,b,c,d,e,f,g,h,i,
	output logic [3:0] sel,
	output reg[511:0] wavedrom_title,
	output reg wavedrom_enable
);

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

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

	task wavedrom_stop;
		#1;
	endtask

	initial begin
		{a,b,c,d,e,f,g,h,i,sel} <= { 16'ha, 16'hb, 16'hc, 16'hd, 16'he, 16'hf, 16'h11, 16'h12, 16'h13, 4'h0 };
		@(negedge clk) wavedrom_start();
			@(posedge clk) sel <= 4'h1;
			@(posedge clk) sel <= 4'h2;
			@(posedge clk) sel <= 4'h3;
			@(posedge clk) sel <= 4'h4;
			@(posedge clk) sel <= 4'h7;
			@(posedge clk) sel <= 4'h8;
			@(posedge clk) sel <= 4'h9;
			@(posedge clk) sel <= 4'ha;
			@(posedge clk) sel <= 4'hb;
		@(negedge clk) wavedrom_stop();

		repeat(200) @(negedge clk, posedge clk) begin
			{a,b,c,d,e,f,g,h,i,sel} <= {$random, $random, $random, $random, $random};
		end
		$finish;
	end

endmodule

module tb();

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

		int clocks;
	} stats;

	stats stats1;

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

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

	logic [15:0] a;
	logic [15:0] b;
	logic [15:0] c;
	logic [15:0] d;
	logic [15:0] e;
	logic [15:0] f;
	logic [15:0] g;
	logic [15:0] h;
	logic [15:0] i;
	logic [3:0] sel;
	logic [15:0] out_ref;
	logic [15:0] out_dut;

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

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

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

	top_module top_module1 (
		.a,
		.b,
		.c,
		.d,
		.e,
		.f,
		.g,
		.h,
		.i,
		.sel,
		.out(out_dut) );

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

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

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

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

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

	end
endmodule


Build a circuit that has two 3-bit inputs that computes the bitwise-OR of the two vectors, the logical-OR of the two vectors, and the inverse (NOT) of both vectors. Place the inverse of b in the upper half of out_not (i.e., bits [5:3]), and the inverse of a in the lower half.

module top_module(
	input [2:0] a,
	input [2:0] b,
	output [2:0] out_or_bitwise,
	output out_or_logical,
	output [5:0] out_not
);

	assign out_or_bitwise = a | b;
	assign out_or_logical = a || b;
	assign out_not = {~b,~a};

endmodule

`timescale 1 ps/1 ps
`define OK 12
`define INCORRECT 13
module reference_module(
	input [2:0] a,
	input [2:0] b,
	output [2:0] out_or_bitwise,
	output out_or_logical,
	output [5:0] out_not
);

	assign out_or_bitwise = a | b;
	assign out_or_logical = a || b;
	assign out_not = {~b,~a};

endmodule

module stimulus_gen (
	input clk,
	output reg [2: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
		int count; count = 6'h38;
		{b, a} <= 6'b0;
		@(negedge clk);
		wavedrom_start();
		repeat(30) @(posedge clk)
			{b, a} <= count++;
		wavedrom_stop();

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

		#1 $finish;
	end

endmodule

module tb();

	typedef struct packed {
		int errors;
		int errortime;
		int errors_out_or_bitwise;
		int errortime_out_or_bitwise;
		int errors_out_or_logical;
		int errortime_out_or_logical;
		int errors_out_not;
		int errortime_out_not;

		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] a;
	logic [2:0] b;
	logic [2:0] out_or_bitwise_ref;
	logic [2:0] out_or_bitwise_dut;
	logic out_or_logical_ref;
	logic out_or_logical_dut;
	logic [5:0] out_not_ref;
	logic [5:0] out_not_dut;

	initial begin
		$dumpfile("wave.vcd");
		$dumpvars(1, stim1.clk, tb_mismatch ,a,b,out_or_bitwise_ref,out_or_bitwise_dut,out_or_logical_ref,out_or_logical_dut,out_not_ref,out_not_dut );
	end

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

	stimulus_gen stim1 (
		.clk,
		.* ,
		.a,
		.b );
	reference_module good1 (
		.a,
		.b,
		.out_or_bitwise(out_or_bitwise_ref),
		.out_or_logical(out_or_logical_ref),
		.out_not(out_not_ref) );

	top_module top_module1 (
		.a,
		.b,
		.out_or_bitwise(out_or_bitwise_dut),
		.out_or_logical(out_or_logical_dut),
		.out_not(out_not_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_or_bitwise) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "out_or_bitwise", stats1.errors_out_or_bitwise, stats1.errortime_out_or_bitwise);
		else $display("Hint: Output '%s' has no mismatches.", "out_or_bitwise");
		if (stats1.errors_out_or_logical) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "out_or_logical", stats1.errors_out_or_logical, stats1.errortime_out_or_logical);
		else $display("Hint: Output '%s' has no mismatches.", "out_or_logical");
		if (stats1.errors_out_not) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "out_not", stats1.errors_out_not, stats1.errortime_out_not);
		else $display("Hint: Output '%s' has no mismatches.", "out_not");

		$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_or_bitwise_ref, out_or_logical_ref, out_not_ref } === ( { out_or_bitwise_ref, out_or_logical_ref, out_not_ref } ^ { out_or_bitwise_dut, out_or_logical_dut, out_not_dut } ^ { out_or_bitwise_ref, out_or_logical_ref, out_not_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_or_bitwise_ref !== ( out_or_bitwise_ref ^ out_or_bitwise_dut ^ out_or_bitwise_ref ))
		begin if (stats1.errors_out_or_bitwise == 0) stats1.errortime_out_or_bitwise = $time;
			stats1.errors_out_or_bitwise = stats1.errors_out_or_bitwise+1'b1; end
		if (out_or_logical_ref !== ( out_or_logical_ref ^ out_or_logical_dut ^ out_or_logical_ref ))
		begin if (stats1.errors_out_or_logical == 0) stats1.errortime_out_or_logical = $time;
			stats1.errors_out_or_logical = stats1.errors_out_or_logical+1'b1; end
		if (out_not_ref !== ( out_not_ref ^ out_not_dut ^ out_not_ref ))
		begin if (stats1.errors_out_not == 0) stats1.errortime_out_not = $time;
			stats1.errors_out_not = stats1.errors_out_not+1'b1; end

	end
endmodule


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

module top_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

`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