prompt:
module top_module(
	input clk,
	input reset,
	input ena,
	output reg pm,
	output reg [7:0] hh,
	output reg [7:0] mm,
	output reg [7:0] ss);

test:
`timescale 1 ps/1 ps
`define OK 12
`define INCORRECT 13
module reference_module(
	input clk,
	input reset,
	input ena,
	output reg pm,
	output reg [7:0] hh,
	output reg [7:0] mm,
	output reg [7:0] ss);

	wire [6:0] enable = {
		{hh[7:0],mm[7:0],ss[7:0]}==24'h115959,
		{hh[3:0],mm[7:0],ss[7:0]}==20'h95959,
		{mm[7:0],ss[7:0]}==16'h5959,
		{mm[3:0],ss[7:0]}==12'h959,
		ss[7:0]==8'h59,
		ss[3:0] == 4'h9,
		1'b1};

	always @(posedge clk)
		if (reset)
			{pm,hh,mm,ss} <= 25'h0120000;
		else if (ena) begin
			if (enable[0] && ss[3:0] == 9) ss[3:0] <= 0;
			else if (enable[0]) ss[3:0] <= ss[3:0] + 1;

			if (enable[1] && ss[7:4] == 4'h5) ss[7:4] <= 0;
			else if (enable[1]) ss[7:4] <= ss[7:4] + 1;

			if (enable[2] && mm[3:0] == 9) mm[3:0] <= 0;
			else if (enable[2]) mm[3:0] <= mm[3:0] + 1;

			if (enable[3] && mm[7:4] == 4'h5) mm[7:4] <= 0;
			else if (enable[3]) mm[7:4] <= mm[7:4] + 1;

			if (enable[4] && hh[3:0] == 4'h9) hh[3:0] <= 0;
			else if (enable[4]) hh[3:0] <= hh[3:0] + 1;

			if (enable[4] && hh[7:0] == 8'h12) hh[7:0] <= 8'h1;
			else if (enable[5]) hh[7:4] <= hh[7:4] + 1;

			if (enable[6]) pm <= ~pm;
		end
endmodule

module stimulus_gen (
	input clk,
	output reg reset,
	output reg ena,
	input [7:0] hh_dut, mm_dut, ss_dut,
	input pm_dut,
	input tb_match,
	output reg[511:0] wavedrom_title,
	output reg wavedrom_enable
);
	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

	logic bcd_fail = 0;
	logic reset_fail = 0;

	always @(posedge clk) begin
		if ((hh_dut[3:0] >= 4'ha) ||
			(hh_dut[7:4] >= 4'ha) ||
			(mm_dut[3:0] >= 4'ha) ||
			(mm_dut[7:4] >= 4'ha) ||
			(ss_dut[3:0] >= 4'ha) ||
			(ss_dut[7:4] >= 4'ha))
			bcd_fail <= 1'b1;
	end

	initial begin
		reset <= 1;
		ena <= 1;
		wavedrom_start("Reset and count to 10");
		reset_test();
		repeat(12) @(posedge clk);
		wavedrom_stop();
		ena <= 1'b1;
		reset <= 1'b1;
		@(posedge clk);
		@(posedge clk)
			if (!tb_match) begin
				$display("Hint: Clock seems to reset to %02x:%02x:%02x %s (Should be 12:00:00 AM).", hh_dut, mm_dut, ss_dut, pm_dut ? "PM": "AM");
				reset_fail <= 1'b1;
			end

		reset <= 1'b0;
		@(posedge clk);
		@(posedge clk);
		@(posedge clk);
		ena <= 1'b0;
		reset <= 1'b1;
		@(posedge clk);
		@(posedge clk)
			if (!tb_match && !reset_fail)
				$display("Hint: Reset has higher priority than enable and should occur even if not enabled.");

		repeat(400) @(posedge clk, negedge clk) begin
			reset <= !($random & 31);
			ena <= !($random & 3);
		end
		reset <= 1;
		@(posedge clk) begin
			{reset, ena} <= 2'b1;
		end

		repeat(55) @(posedge clk);
		wavedrom_start("Minute roll-over");
		repeat(10) @(posedge clk);
		wavedrom_stop();

		repeat(3530) @(posedge clk);
		wavedrom_start("Hour roll-over");
		repeat(10) @(posedge clk);
		wavedrom_stop();

		repeat(39590) @(posedge clk);
		wavedrom_start("PM roll-over");
		repeat(10) @(posedge clk);
		wavedrom_stop();

		repeat(132745) @(posedge clk);
		repeat(50) @(posedge clk, negedge clk) begin
			ena <= !($random & 7);
		end
		reset <= 1'b1;
		repeat(5) @(posedge clk);

		if (bcd_fail)
			$display("Hint: Non-BCD values detected. Are you sure you're using two-digit BCD representation for hh, mm, and ss?");

		#1 $finish;
	end

endmodule

module tb();

	typedef struct packed {
		int errors;
		int errortime;
		int errors_pm;
		int errortime_pm;
		int errors_hh;
		int errortime_hh;
		int errors_mm;
		int errortime_mm;
		int errors_ss;
		int errortime_ss;

		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 ena;
	logic pm_ref;
	logic pm_dut;
	logic [7:0] hh_ref;
	logic [7:0] hh_dut;
	logic [7:0] mm_ref;
	logic [7:0] mm_dut;
	logic [7:0] ss_ref;
	logic [7:0] ss_dut;

	initial begin
		$dumpfile("wave.vcd");
		$dumpvars(1, stim1.clk, tb_mismatch ,clk,reset,ena,pm_ref,pm_dut,hh_ref,hh_dut,mm_ref,mm_dut,ss_ref,ss_dut );
	end

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

	stimulus_gen stim1 (
		.clk,
		.* ,
		.reset,
		.ena );
	reference_module good1 (
		.clk,
		.reset,
		.ena,
		.pm(pm_ref),
		.hh(hh_ref),
		.mm(mm_ref),
		.ss(ss_ref) );

	top_module top_module1 (
		.clk,
		.reset,
		.ena,
		.pm(pm_dut),
		.hh(hh_dut),
		.mm(mm_dut),
		.ss(ss_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_pm) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "pm", stats1.errors_pm, stats1.errortime_pm);
		else $display("Hint: Output '%s' has no mismatches.", "pm");
		if (stats1.errors_hh) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "hh", stats1.errors_hh, stats1.errortime_hh);
		else $display("Hint: Output '%s' has no mismatches.", "hh");
		if (stats1.errors_mm) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "mm", stats1.errors_mm, stats1.errortime_mm);
		else $display("Hint: Output '%s' has no mismatches.", "mm");
		if (stats1.errors_ss) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "ss", stats1.errors_ss, stats1.errortime_ss);
		else $display("Hint: Output '%s' has no mismatches.", "ss");

		$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 = ( { pm_ref, hh_ref, mm_ref, ss_ref } === ( { pm_ref, hh_ref, mm_ref, ss_ref } ^ { pm_dut, hh_dut, mm_dut, ss_dut } ^ { pm_ref, hh_ref, mm_ref, ss_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 (pm_ref !== ( pm_ref ^ pm_dut ^ pm_ref ))
		begin if (stats1.errors_pm == 0) stats1.errortime_pm = $time;
			stats1.errors_pm = stats1.errors_pm+1'b1; end
		if (hh_ref !== ( hh_ref ^ hh_dut ^ hh_ref ))
		begin if (stats1.errors_hh == 0) stats1.errortime_hh = $time;
			stats1.errors_hh = stats1.errors_hh+1'b1; end
		if (mm_ref !== ( mm_ref ^ mm_dut ^ mm_ref ))
		begin if (stats1.errors_mm == 0) stats1.errortime_mm = $time;
			stats1.errors_mm = stats1.errors_mm+1'b1; end
		if (ss_ref !== ( ss_ref ^ ss_dut ^ ss_ref ))
		begin if (stats1.errors_ss == 0) stats1.errortime_ss = $time;
			stats1.errors_ss = stats1.errors_ss+1'b1; end

	end
endmodule

detail_description: Create a set of counters suitable for use as a 12-hour clock (with am/pm indicator). Your counters are clocked by a fast-running clk, with a pulse on ena whenever your clock should increment (i.e., once per second, while "clk" is much faster than once per second). The signal "pm" is asserted if the clock is PM, or is otherwise AM. hh, mm, and ss are two BCD (Binary-Coded Decimal) digits each for hours (01-12), minutes (00-59), and seconds (00-59). Reset is the active high synchronous signal that resets the clock to "12:00 AM." Reset has higher priority than enable and can occur even when not enabled.


prompt:
module top_module (
	input clk,
	input w,
	input R,
	input E,
	input L,
	output reg Q
);

test:
`timescale 1 ps/1 ps
`define OK 12
`define INCORRECT 13
module reference_module (
	input clk,
	input w,
	input R,
	input E,
	input L,
	output reg Q
);

	always @(posedge clk)
		if (L)
			Q <= R;
		else if (E)
			Q <= w;

endmodule

module stimulus_gen (
	input clk,
	output logic w, R, E, L
);

	initial begin
		repeat(200) @(posedge clk, negedge clk) begin
			{w,R,E,L} <= $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 w;
	logic R;
	logic E;
	logic L;
	logic Q_ref;
	logic Q_dut;

	initial begin
		$dumpfile("wave.vcd");
		$dumpvars(1, stim1.clk, tb_mismatch ,clk,w,R,E,L,Q_ref,Q_dut );
	end

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

	stimulus_gen stim1 (
		.clk,
		.* ,
		.w,
		.R,
		.E,
		.L );
	reference_module good1 (
		.clk,
		.w,
		.R,
		.E,
		.L,
		.Q(Q_ref) );

	top_module top_module1 (
		.clk,
		.w,
		.R,
		.E,
		.L,
		.Q(Q_dut) );

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

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

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

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

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

	end
endmodule

detail_description: Consider an n-bit shift register circuit. Inputs E are for enabling shift, R for value to load, L is asserted when it should load, and w is the input to the first stage of the shift register. Write a Verilog module named top_module for one stage of this circuit, including both the flip-flop and multiplexers.


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

test:
`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

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


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

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

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

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

	assign walk_left = (state==WL);
	assign walk_right = (state==WR);
	assign aaah = (state == FALLL) || (state == FALLR);

endmodule

module stimulus_gen (
	input clk,
	output logic areset,
	output logic bump_left,
	output logic bump_right,
	output logic ground,
	output reg[511:0] wavedrom_title,
	output reg wavedrom_enable,
	input tb_match
);
	reg reset;
	assign areset = reset;

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

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

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

	endtask

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

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

	task wavedrom_stop;
		#1;
	endtask

	initial begin
		reset <= 1'b1;
		{bump_left, bump_right, ground} <= 3'h1;
		reset_test(1);
		{bump_right, bump_left} <= 3'h0;
		wavedrom_start("Falling");
		repeat(3) @(posedge clk);
		{bump_right, bump_left, ground} <= 0;
		repeat(3) @(posedge clk);
		{bump_right, bump_left, ground} <= 3;
		repeat(2) @(posedge clk);
		{bump_right, bump_left, ground} <= 0;
		repeat(3) @(posedge clk);
		{bump_right, bump_left, ground} <= 1;
		repeat(2) @(posedge clk);
		wavedrom_stop();

		reset <= 1'b1;
		@(posedge clk);
		repeat(400) @(posedge clk, negedge clk) begin
			{bump_right, bump_left} <= $random & $random;
			ground <= |($random & 7);
			reset <= !($random & 31);
		end

		#1 $finish;
	end

endmodule

module tb();

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

		int clocks;
	} stats;

	stats stats1;

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

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

	logic areset;
	logic bump_left;
	logic bump_right;
	logic ground;
	logic walk_left_ref;
	logic walk_left_dut;
	logic walk_right_ref;
	logic walk_right_dut;
	logic aaah_ref;
	logic aaah_dut;

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

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

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

	top_module top_module1 (
		.clk,
		.areset,
		.bump_left,
		.bump_right,
		.ground,
		.walk_left(walk_left_dut),
		.walk_right(walk_right_dut),
		.aaah(aaah_dut) );

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

	final begin
		if (stats1.errors_walk_left) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "walk_left", stats1.errors_walk_left, stats1.errortime_walk_left);
		else $display("Hint: Output '%s' has no mismatches.", "walk_left");
		if (stats1.errors_walk_right) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "walk_right", stats1.errors_walk_right, stats1.errortime_walk_right);
		else $display("Hint: Output '%s' has no mismatches.", "walk_right");
		if (stats1.errors_aaah) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "aaah", stats1.errors_aaah, stats1.errortime_aaah);
		else $display("Hint: Output '%s' has no mismatches.", "aaah");

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

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

		stats1.clocks++;
		if (!tb_match) begin
			if (stats1.errors == 0) stats1.errortime = $time;
			stats1.errors++;
		end
		if (walk_left_ref !== ( walk_left_ref ^ walk_left_dut ^ walk_left_ref ))
		begin if (stats1.errors_walk_left == 0) stats1.errortime_walk_left = $time;
			stats1.errors_walk_left = stats1.errors_walk_left+1'b1; end
		if (walk_right_ref !== ( walk_right_ref ^ walk_right_dut ^ walk_right_ref ))
		begin if (stats1.errors_walk_right == 0) stats1.errortime_walk_right = $time;
			stats1.errors_walk_right = stats1.errors_walk_right+1'b1; end
		if (aaah_ref !== ( aaah_ref ^ aaah_dut ^ aaah_ref ))
		begin if (stats1.errors_aaah == 0) stats1.errortime_aaah = $time;
			stats1.errors_aaah = stats1.errors_aaah+1'b1; end

	end
endmodule

detail_description:
The game Lemmings involves critters with fairly simple brains. So simple that we are going to model it using a finite state machine. In the Lemmings' 2D world, Lemmings can be in one of two states: walking left (walk_left is 1) or walking right (walk_right is 1). It will switch directions if it hits an obstacle. In particular, if a Lemming is bumped on the left (by receiving a 1 on bump_left), it will walk right. If it's bumped on the right (by receiving a 1 on bump_right), it will walk left. If it's bumped on both sides at the same time, it will still switch directions.
// In addition to walking left and right and changing direction when bumped, when ground=0, the Lemming will fall and say "aaah!". When the ground reappears (ground=1), the Lemming will resume walking in the same direction as before the fall. Being bumped while falling does not affect the walking direction, and being bumped in the same cycle as ground disappears (but not yet falling), or when the ground reappears while still falling, also does not affect the walking direction.
// Implement a Moore state machine that models this behaviour. areset is positive edge triggered asynchronous reseting the Lemming machine to walk left.


prompt:
module top_module (
	input clk,
	input areset,
	input x,
	output z
);

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

	parameter A=0,B=1,C=2;
	reg [1:0] state;
	always @(posedge clk, posedge areset) begin
		if (areset)
			state <= A;
		else begin
			case (state)
				A: state <= x ? C : A;
				B: state <= x ? B : C;
				C: state <= x ? B : C;
			endcase
		end
	end

	assign z = (state == C);

endmodule

module stimulus_gen (
	input clk,
	output logic x,
	output logic areset,
	output reg[511:0] wavedrom_title,
	output reg wavedrom_enable,
	input tb_match
);
	reg reset;
	assign areset = reset;

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

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

	task wavedrom_stop;
		#1;
	endtask

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

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

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

	endtask

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

		@(negedge clk) wavedrom_start();
			@(posedge clk) {reset,x} <= 2'h2;
			@(posedge clk) {reset,x} <= 2'h0;
			@(posedge clk) {reset,x} <= 2'h0;
			@(posedge clk) {reset,x} <= 2'h1;
			@(posedge clk) {reset,x} <= 2'h0;
			@(posedge clk) {reset,x} <= 2'h1;
			@(posedge clk) {reset,x} <= 2'h1;
			@(posedge clk) {reset,x} <= 2'h0;
			@(posedge clk) {reset,x} <= 2'h0;
		@(negedge clk) wavedrom_stop();
		repeat(400) @(posedge clk, negedge clk)
			{reset,x} <= {($random&31) == 0, ($random&1)==0 };

		$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 areset;
	logic x;
	logic z_ref;
	logic z_dut;

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

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

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

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

detail_description: You are to design a one-input one-output serial 2's complementer Moore state machine. The input (x) is a series of bits (one per clock cycle) beginning with the least-significant bit of the number, and the output (Z) is the 2's complement of the input. The machine will accept input numbers of arbitrary length. The circuit requires a positive edge triggered asynchronous reset. The conversion begins when Reset is released and stops when Reset is asserted.


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

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

	assign out = {in[7:0], in[15:8], in[23:16], in[31:24]};

endmodule

module stimulus_gen (
	input clk,
	output logic [31: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
		wavedrom_start("Random inputs");
		repeat(10) @(posedge clk, negedge clk)
			in <= $random;
		wavedrom_stop();
		repeat(100) @(posedge clk, negedge clk)
			in <= $random;
		$finish;
	end

endmodule

module tb();

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

		int clocks;
	} stats;

	stats stats1;

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

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

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

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

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

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

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

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

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

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

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

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

	end
endmodule

detail_description: Build a circuit that reverses the byte order of a 32-bit vector.


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

test:
`timescale 1 ps/1 ps
`define OK 12
`define INCORRECT 13
module reference_module(
	input [3:1] y,
	input w,
	output reg Y2);

	always_comb begin
		case ({y, w})
			4'h0: Y2 = 1'b0;
			4'h1: Y2 = 1'b0;
			4'h2: Y2 = 1'b1;
			4'h3: Y2 = 1'b1;
			4'h4: Y2 = 1'b0;
			4'h5: Y2 = 1'b1;
			4'h6: Y2 = 1'b0;
			4'h7: Y2 = 1'b0;
			4'h8: Y2 = 1'b0;
			4'h9: Y2 = 1'b1;
			4'ha: Y2 = 1'b1;
			4'hb: Y2 = 1'b1;
			default: Y2 = 1'bx;
		endcase
	end

endmodule

module stimulus_gen (
	input clk,
	output reg [3:1] y,
	output reg w
);

	initial begin
		repeat(100) @(posedge clk, negedge clk) begin
			{y,w} <= $random;
		end

		#1 $finish;
	end

endmodule

module tb();

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

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

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

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

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

	top_module top_module1 (
		.y,
		.w,
		.Y2(Y2_dut) );

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

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

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

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

		stats1.clocks++;
		if (!tb_match) begin
			if (stats1.errors == 0) stats1.errortime = $time;
			stats1.errors++;
		end
		if (Y2_ref !== ( Y2_ref ^ Y2_dut ^ Y2_ref ))
		begin if (stats1.errors_Y2 == 0) stats1.errortime_Y2 = $time;
			stats1.errors_Y2 = stats1.errors_Y2+1'b1; end

	end
endmodule

detail_description:
Consider the state machine shown below:

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

// Assume that you want to Implement the FSM using three flip-flops and state codes y[3:1] = 000, 001, ..., 101 for states A, B, ..., F, respectively. Implement just the next-state logic for y[2] in Verilog. The output Y2 is y[2].


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

canonical_solution:
	assign out = (a | b | c);

endmodule

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

	assign out = (a | b | c);

endmodule

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

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

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

	task wavedrom_stop;
		#1;
	endtask

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

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

		#1 $finish;
	end

endmodule

module tb();

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

		int clocks;
	} stats;

	stats stats1;

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

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

	logic a;
	logic b;
	logic c;
	logic out_ref;
	logic out_dut;

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

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

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

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

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

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

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

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

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

	end
endmodule

detail_description:
Implement the circuit described by the Karnaugh map below.
//        a
// bc   0 1
//  00 | 0 | 1 |
//  01 | 1 | 1 |
//  11 | 1 | 1 |
//  10 | 1 | 1 |


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

canonical_solution:
	assign q = ~a^b^c^d;

endmodule

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

	assign q = ~a^b^c^d;

endmodule

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

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

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

	task wavedrom_stop;
		#1;
	endtask

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

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

endmodule

module tb();

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

		int clocks;
	} stats;

	stats stats1;

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

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

	logic a;
	logic b;
	logic c;
	logic d;
	logic q_ref;
	logic q_dut;

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

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

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

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

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

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

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

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

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

	end
endmodule


prompt:
module top_module (
	input a,
	input b,
	input sel_b1,
	input sel_b2,
	output out_assign,
	output reg out_always
);

test:
`timescale 1 ps/1 ps
`define OK 12
`define INCORRECT 13
module reference_module (
	input a,
	input b,
	input sel_b1,
	input sel_b2,
	output out_assign,
	output reg out_always
);

	assign out_assign = (sel_b1 & sel_b2) ? b : a;
	always @(*) out_always = (sel_b1 & sel_b2) ? b : a;

endmodule

module stimulus_gen (
	input clk,
	output logic a,b,sel_b1, sel_b2,
	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_b1, sel_b2} <= 4'b000;
		@(negedge clk) wavedrom_start("");
			@(posedge clk, negedge clk) {a,b,sel_b1,sel_b2} <= 4'b0100;
			@(posedge clk, negedge clk) {a,b,sel_b1,sel_b2} <= 4'b1000;
			@(posedge clk, negedge clk) {a,b,sel_b1,sel_b2} <= 4'b1101;
			@(posedge clk, negedge clk) {a,b,sel_b1,sel_b2} <= 4'b0001;
			@(posedge clk, negedge clk) {a,b,sel_b1,sel_b2} <= 4'b0110;
			@(posedge clk, negedge clk) {a,b,sel_b1,sel_b2} <= 4'b1010;
			@(posedge clk, negedge clk) {a,b,sel_b1,sel_b2} <= 4'b1111;
			@(posedge clk, negedge clk) {a,b,sel_b1,sel_b2} <= 4'b0011;
			@(posedge clk, negedge clk) {a,b,sel_b1,sel_b2} <= 4'b0111;
			@(posedge clk, negedge clk) {a,b,sel_b1,sel_b2} <= 4'b1011;
			@(posedge clk, negedge clk) {a,b,sel_b1,sel_b2} <= 4'b1111;
			@(posedge clk, negedge clk) {a,b,sel_b1,sel_b2} <= 4'b0011;
		wavedrom_stop();
		repeat(100) @(posedge clk, negedge clk)
			{a,b,sel_b1,sel_b2} <= $urandom;
		$finish;
	end

endmodule

module tb();

	typedef struct packed {
		int errors;
		int errortime;
		int errors_out_assign;
		int errortime_out_assign;
		int errors_out_always;
		int errortime_out_always;

		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_b1;
	logic sel_b2;
	logic out_assign_ref;
	logic out_assign_dut;
	logic out_always_ref;
	logic out_always_dut;

	initial begin
		$dumpfile("wave.vcd");
		$dumpvars(1, stim1.clk, tb_mismatch ,a,b,sel_b1,sel_b2,out_assign_ref,out_assign_dut,out_always_ref,out_always_dut );
	end

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

	stimulus_gen stim1 (
		.clk,
		.* ,
		.a,
		.b,
		.sel_b1,
		.sel_b2 );
	reference_module good1 (
		.a,
		.b,
		.sel_b1,
		.sel_b2,
		.out_assign(out_assign_ref),
		.out_always(out_always_ref) );

	top_module top_module1 (
		.a,
		.b,
		.sel_b1,
		.sel_b2,
		.out_assign(out_assign_dut),
		.out_always(out_always_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_assign) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "out_assign", stats1.errors_out_assign, stats1.errortime_out_assign);
		else $display("Hint: Output '%s' has no mismatches.", "out_assign");
		if (stats1.errors_out_always) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "out_always", stats1.errors_out_always, stats1.errortime_out_always);
		else $display("Hint: Output '%s' has no mismatches.", "out_always");

		$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_assign_ref, out_always_ref } === ( { out_assign_ref, out_always_ref } ^ { out_assign_dut, out_always_dut } ^ { out_assign_ref, out_always_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_assign_ref !== ( out_assign_ref ^ out_assign_dut ^ out_assign_ref ))
		begin if (stats1.errors_out_assign == 0) stats1.errortime_out_assign = $time;
			stats1.errors_out_assign = stats1.errors_out_assign+1'b1; end
		if (out_always_ref !== ( out_always_ref ^ out_always_dut ^ out_always_ref ))
		begin if (stats1.errors_out_always == 0) stats1.errortime_out_always = $time;
			stats1.errors_out_always = stats1.errors_out_always+1'b1; end

	end
endmodule

detail_description: Build a 2-to-1 mux that chooses between a and b. Choose b if both sel_b1 and sel_b2 are true. Otherwise, choose a. Do the same twice, once using assign statements and once using a procedural if statement.


prompt:
module top_module (
	input clk,
	input enable,
	input S,
	input A,
	input B,
	input C,
	output reg Z
);

test:
`timescale 1 ps/1 ps
`define OK 12
`define INCORRECT 13
module reference_module (
	input clk,
	input enable,
	input S,
	input A,
	input B,
	input C,
	output reg Z
);

	reg [7:0] q;
	always @(posedge clk) begin
		if (enable)
			q <= {q[6:0], S};
	end

	assign Z = q[ {A, B, C} ];

endmodule

module stimulus_gen (
	input clk,
	output logic S, enable,
	output logic A, B, C,
	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
		enable <= 0;
		{A,B,C} <= 0;
		S <= 1'bx;
		@(negedge clk) wavedrom_start("A 3-input AND gate");
			@(posedge clk);
			@(posedge clk) enable <= 1; S <= 1;
			@(posedge clk) S <= 0;
			@(posedge clk) S <= 0;
			@(posedge clk) S <= 0;
			@(posedge clk) S <= 0;
			@(posedge clk) S <= 0;
			@(posedge clk) S <= 0;
			@(posedge clk) S <= 0;
			@(posedge clk) enable <= 0; S <= 1'bx;
			{A,B,C} <= 5;
			@(posedge clk) {A,B,C} <= 6;
			@(posedge clk) {A,B,C} <= 7;
			@(posedge clk) {A,B,C} <= 0;
			@(posedge clk) {A,B,C} <= 1;
		@(negedge clk) wavedrom_stop();

		repeat(500) @(posedge clk, negedge clk) begin
			{A,B,C,S} <= $random;
			enable <= ($random&3) == 0;
		end

		$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 enable;
	logic S;
	logic A;
	logic B;
	logic C;
	logic Z_ref;
	logic Z_dut;

	initial begin
		$dumpfile("wave.vcd");
		$dumpvars(1, stim1.clk, tb_mismatch ,clk,enable,S,A,B,C,Z_ref,Z_dut );
	end

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

	stimulus_gen stim1 (
		.clk,
		.* ,
		.enable,
		.S,
		.A,
		.B,
		.C );
	reference_module good1 (
		.clk,
		.enable,
		.S,
		.A,
		.B,
		.C,
		.Z(Z_ref) );

	top_module top_module1 (
		.clk,
		.enable,
		.S,
		.A,
		.B,
		.C,
		.Z(Z_dut) );

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

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

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

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

		stats1.clocks++;
		if (!tb_match) begin
			if (stats1.errors == 0) stats1.errortime = $time;
			stats1.errors++;
		end
		if (Z_ref !== ( Z_ref ^ Z_dut ^ Z_ref ))
		begin if (stats1.errors_Z == 0) stats1.errortime_Z = $time;
			stats1.errors_Z = stats1.errors_Z+1'b1; end

	end
endmodule

detail_description: In this question, you will design a circuit for an 8x1 memory, where writing to the memory is accomplished by shifting-in bits, and reading is "random access", as in a typical RAM. You will then use the circuit to realize a 3-input logic function. First, create an 8-bit shift register with 8 D-type flip-flops. Label the flip-flop outputs from Q[0]...Q[7]. The shift register input should be called S, which feeds the input of Q[0] (MSB is shifted in first). The enable input is synchronous active high and controls whether to shift. Extend the circuit to have 3 additional inputs A,B,C and an output Z. The circuit's behaviour should be as follows: when ABC is 000, Z=Q[0], when ABC is 001, Z=Q[1], and so on. Your circuit should contain ONLY the 8-bit shift register, and multiplexers.


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

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

	always @(posedge clk, posedge areset) begin
		if (areset)
			q <= 0;
		else if (load)
			q <= data;
		else if (ena)
			q <= q[3:1];
	end
endmodule

module stimulus_gen (
	input clk,
	output areset,
	output reg load,
	output reg ena,
	output reg[3:0] data,

	output reg[511:0] wavedrom_title,
	output reg wavedrom_enable,
	input tb_match
);
	reg reset;
	assign areset = reset;

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

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

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

	endtask

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

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

	task wavedrom_stop;
		#1;
	endtask

	initial begin
		{load, ena, reset, data} <= 7'h40;
		@(posedge clk) {load, ena, reset, data} <= 7'h4f;
		wavedrom_start("Load and reset");
		@(posedge clk) {load, ena, reset, data} <= 7'h0x;
		@(posedge clk) {load, ena, reset, data} <= 7'h2x;
		@(posedge clk) {load, ena, reset, data} <= 7'h2x;
		@(posedge clk) {load, ena, reset, data} <= 7'h0x;
		reset_test(1);
		@(posedge clk);
		@(posedge clk);
		wavedrom_stop();

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

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

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

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

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

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

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

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

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

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

	end
endmodule

detail_description:
Build a 4-bit shift register (right shift), with asynchronous positive edge triggered areset, synchronous active high signals load, and enable.
// (1) areset: Resets shift register to zero.
// (2) load: Loads shift register with data[3:0] instead of shifting.
// (3) ena: Shift right (q[3] becomes zero, q[0] is shifted out and disappears).
// (4) q: The contents of the shift register. If both the load and ena inputs are asserted (1), the load input has higher priority.


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

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

	always @(posedge clk) begin
		if (load)
			q <= data;
		else if (ena) case (amount)
			2'b00: q <= {q[62:0], 1'b0};
			2'b01: q <= {q[55:0], 8'b0};
			2'b10: q <= {q[63], q[63:1]};
			2'b11: q <= {{8{q[63]}}, q[63:8]};
			default: q <= 64'hx;
		endcase
	end
endmodule

module stimulus_gen (
	input clk,
	output reg load,
	output reg ena,
	output reg[1:0] amount,
	output reg[63: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
		load <= 1;
		ena <= 0;
		data <= 'x;
		amount <= 0;
		@(posedge clk) data <= 64'h000100;
		wavedrom_start("Shifting");
			@(posedge clk) load <= 0; ena <= 1;
							amount <= 2;
			@(posedge clk) amount <= 2;
			@(posedge clk) amount <= 2;
			@(posedge clk) amount <= 1;
			@(posedge clk) amount <= 1;
			@(posedge clk) amount <= 0;
			@(posedge clk) amount <= 0;
			@(posedge clk) amount <= 3;
			@(posedge clk) amount <= 3;
			@(posedge clk) amount <= 2;
			@(posedge clk) amount <= 2;
			@(negedge clk);
		wavedrom_stop();

		@(posedge clk); load <= 1; data <= 64'hx;
		@(posedge clk); load <= 1; data <= 64'h80000000_00000000;
		wavedrom_start("Arithmetic right shift");
			@(posedge clk) load <= 0; ena <= 1;
							amount <= 2;
			@(posedge clk) amount <= 2;
			@(posedge clk) amount <= 2;
			@(posedge clk) amount <= 2;
			@(posedge clk) amount <= 2;
			@(negedge clk);
		wavedrom_stop();

		@(posedge clk);
		@(posedge clk);

		repeat(4000) @(posedge clk, negedge clk) begin
			load <= !($random & 31);
			ena <= |($random & 15);
			amount <= $random;
			data <= {$random,$random};
		end
		#1 $finish;
	end

endmodule

module tb();

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

		int clocks;
	} stats;

	stats stats1;

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

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

	logic load;
	logic ena;
	logic [1:0] amount;
	logic [63:0] data;
	logic [63:0] q_ref;
	logic [63:0] q_dut;

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

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

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

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

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

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

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

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

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

	end
endmodule

detail_description:
Build a 64-bit arithmetic shift register, with synchronous load. The shifter can shift both left and right, and by 1 or 8 bit positions, selected by "amount." Assume the right shit is an arithmetic right shift.

// Signals are defined as below:
// (1) load: Loads shift register with data[63:0] instead of shifting. Active high.
// (2) ena: Chooses whether to shift. Active high.
// (3) amount: Chooses which direction and how much to shift.
//     (a) 2'b00: shift left by 1 bit.
//     (b) 2'b01: shift left by 8 bits.
//     (c) 2'b10: shift right by 1 bit.
//     (d) 2'b11: shift right by 8 bits.
// (4) q: The contents of the shifter.


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

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

	always@(posedge clk) begin
		if (r)
			q <= 0;
		else
			q <= d;
	end

endmodule

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

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

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

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

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

	top_module top_module1 (
		.clk,
		.d,
		.r,
		.q(q_dut) );

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

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

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

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

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

	end
endmodule

detail_description: Implement a simple D flip flop with active high synchronous reset (reset output to 0).


prompt:
module top_module (
	input clk,
	input aresetn,
	input x,
	output reg z
);

test:
`timescale 1 ps/1 ps
`define OK 12
`define INCORRECT 13
module reference_module (
	input clk,
	input aresetn,
	input x,
	output reg z
);
	parameter S=0, S1=1, S10=2;
	reg[1:0] state, next;

	always@(posedge clk, negedge aresetn)
		if (!aresetn)
			state <= S;
		else
			state <= next;

	always_comb begin
		case (state)
			S: next = x ? S1 : S;
			S1: next = x ? S1 : S10;
			S10: next = x ? S1 : S;
			default: next = 'x;
		endcase
	end

	always_comb begin
		case (state)
			S: z = 0;
			S1: z = 0;
			S10: z = x;
			default: z = 'x;
		endcase
	end

endmodule

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

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

		@(negedge clk) wavedrom_start();
			@(posedge clk) x <= 0;
			@(posedge clk) x <= 0;
			@(posedge clk) x <= 0;
			@(posedge clk) x <= 1;
			@(posedge clk) x <= 0;
			@(posedge clk) x <= 1;
			@(posedge clk) x <= 0;
			@(posedge clk) x <= 1;
			@(posedge clk) x <= 1;
			@(posedge clk) x <= 0;
			@(posedge clk) x <= 1;
			@(posedge clk) x <= 0;
		@(negedge clk) wavedrom_stop();

		repeat(400) @(posedge clk, negedge clk) begin
			x <= $random;
			reset <= ($random&31) == 0;
		end

		$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 aresetn;
	logic x;
	logic z_ref;
	logic z_dut;

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

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

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

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

detail_description: Implement a Mealy-type finite state machine that recognizes the sequence "101" on an input signal named x. Your FSM should have an output signal, z, that is asserted to logic-1 when the "101" sequence is detected. Your FSM should also have a negative edge triggered asynchronous reset. You may only have 3 states in your state machine. Your FSM should recognize overlapping sequences.


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

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

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

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

	assign out = (state==B);

endmodule

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

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

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

	endtask

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

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

	task wavedrom_stop;
		#1;
	endtask

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

		#1 $finish;
	end

endmodule

module tb();

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

		int clocks;
	} stats;

	stats stats1;

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

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

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

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

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

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

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

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

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

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

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

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

	end
endmodule

detail_description:
This is a Moore state machine with two states, one input, and one output. Implement this state machine in Verilog. The reset state is B and reset is active-high synchronous.

// B (out=1) --in=0--> A
// B (out=1) --in=1--> B
// A (out=0) --in=0--> B
// A (out=0) --in=1--> A


prompt:
module top_module(
	output out);

canonical_solution:
	assign out = 1'b0;

endmodule

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

	assign out = 1'b0;

endmodule

module stimulus_gen (
	input clk
);

	initial begin
		repeat(100) @(posedge clk, negedge clk) begin

		end

		#1 $finish;
	end

endmodule

module tb();

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

		int clocks;
	} stats;

	stats stats1;

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

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

	logic out_ref;
	logic out_dut;

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

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

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

	top_module top_module1 (
		.out(out_dut) );

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

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

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

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

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

	end
endmodule

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


task_id: countbcd

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

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

	wire [3:0] enable = { q[11:0]==12'h999, q[7:0]==8'h99, q[3:0] == 4'h9, 1'b1};
	assign ena = enable[3:1];
	always @(posedge clk)
		for (int i=0;i<4;i++) begin
			if (reset || (q[i*4 +:4] == 9 && enable[i]))
				q[i*4 +:4] <= 0;
			else if (enable[i])
				q[i*4 +:4] <= q[i*4 +:4]+1;
		end

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;
		reset_test();
		repeat(2) @(posedge clk);
		@(negedge clk);
		wavedrom_start("Counting");
			repeat(12) @(posedge clk);
		@(negedge clk);
		wavedrom_stop();
		repeat(71) @(posedge clk);
		@(negedge clk) wavedrom_start("100 rollover");
			repeat(16) @(posedge clk);
		@(negedge clk) wavedrom_stop();
		repeat(400) @(posedge clk, negedge clk)
			reset <= !($random & 31);
		repeat(19590) @(posedge clk);
		reset <= 1'b1;
		repeat(5) @(posedge clk);
		#1 $finish;
	end

endmodule

module tb();

	typedef struct packed {
		int errors;
		int errortime;
		int errors_ena;
		int errortime_ena;
		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:1] ena_ref;
	logic [3:1] ena_dut;
	logic [15:0] q_ref;
	logic [15:0] q_dut;

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

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

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

	top_module top_module1 (
		.clk,
		.reset,
		.ena(ena_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_ena) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "ena", stats1.errors_ena, stats1.errortime_ena);
		else $display("Hint: Output '%s' has no mismatches.", "ena");
		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 = ( { ena_ref, q_ref } === ( { ena_ref, q_ref } ^ { ena_dut, q_dut } ^ { ena_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 (ena_ref !== ( ena_ref ^ ena_dut ^ ena_ref ))
		begin if (stats1.errors_ena == 0) stats1.errortime_ena = $time;
			stats1.errors_ena = stats1.errors_ena+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

detail_description: Build a 4-digit BCD (binary-coded decimal) counter. Each decimal digit is encoded using 4 bits: q[3:0] is the ones digit, q[7:4] is the tens digit, etc. For digits [3:1], also output an enable signal indicating when each of the upper three digits should be incremented. Include a synchronous active-high reset.


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

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

	always_comb  begin
		out = 0;
		for (int i=0;i<255;i++)
			out = out + in[i];
	end

endmodule

module stimulus_gen (
	input clk,
	output logic [254: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 <= 255'h0;
		wavedrom_start("");
		@(posedge clk, negedge clk) in <= 255'h0;
		@(posedge clk, negedge clk) in <= 255'h0;
		@(posedge clk, negedge clk) in <= 255'h1;
		@(posedge clk, negedge clk) in <= 255'h1;
		@(posedge clk, negedge clk) in <= 255'h3;
		@(posedge clk, negedge clk) in <= 255'h3;
		@(posedge clk, negedge clk) in <= 255'h7;
		@(posedge clk, negedge clk) in <= 255'haaaa;
		@(posedge clk, negedge clk) in <= 255'hf00000;
		@(posedge clk, negedge clk) in <= 255'h0;
		wavedrom_stop();
		repeat (200) @(posedge clk, negedge clk) begin
			in <= {$random, $random, $random, $random, $random, $random, $random, $random};
		end
		@(posedge clk);
		in <= '0;
		@(posedge clk)
		in <= '1;
		@(posedge clk)
		#1 $finish;
	end

endmodule

module tb();

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

		int clocks;
	} stats;

	stats stats1;

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

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

	logic [254:0] in;
	logic [7:0] out_ref;
	logic [7:0] out_dut;

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

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

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

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

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

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

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

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

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

	end
endmodule

detail_description: A "population count" circuit counts the number of '1's in an input vector. Build a population count circuit for a 255-bit input vector.


prompt:
module top_module (
	input clk,
	input x,
	input [2:0] y,
	output reg Y0,
	output reg z
);

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

	always_comb begin
		case ({y[2:0], x})
			4'h0: Y0 = 0;
			4'h1: Y0 = 1;
			4'h2: Y0 = 1;
			4'h3: Y0 = 0;
			4'h4: Y0 = 0;
			4'h5: Y0 = 1;
			4'h6: Y0 = 1;
			4'h7: Y0 = 0;
			4'h8: Y0 = 1;
			4'h9: Y0 = 0;
			default: Y0 = 1'bx;
		endcase

		case (y[2:0])
			3'h0: z = 0;
			3'h1: z = 0;
			3'h2: z = 0;
			3'h3: z = 1;
			3'h4: z = 1;
			default: z = 1'bx;
		endcase
	end

endmodule

module stimulus_gen (
	input clk,
	output logic x,
	output logic [2:0] y
);

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

		#1 $finish;
	end

endmodule

module tb();

	typedef struct packed {
		int errors;
		int errortime;
		int errors_Y0;
		int errortime_Y0;
		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 [2:0] y;
	logic Y0_ref;
	logic Y0_dut;
	logic z_ref;
	logic z_dut;

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

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

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

	top_module top_module1 (
		.clk,
		.x,
		.y,
		.Y0(Y0_dut),
		.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_Y0) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "Y0", stats1.errors_Y0, stats1.errortime_Y0);
		else $display("Hint: Output '%s' has no mismatches.", "Y0");
		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 = ( { Y0_ref, z_ref } === ( { Y0_ref, z_ref } ^ { Y0_dut, z_dut } ^ { Y0_ref, 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 (Y0_ref !== ( Y0_ref ^ Y0_dut ^ Y0_ref ))
		begin if (stats1.errors_Y0 == 0) stats1.errortime_Y0 = $time;
			stats1.errors_Y0 = stats1.errors_Y0+1'b1; end
		if (z_ref !== ( z_ref ^ z_dut ^ z_ref ))
		begin if (stats1.errors_z == 0) stats1.errortime_z = $time;
			stats1.errors_z = stats1.errors_z+1'b1; end

	end
endmodule

detail_description:
Given the state-assigned table shown below, implement the logic functions Y[0] and z.
// 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


task_id: thermostat

prompt:
module top_module(
	input mode,
	input too_cold,
	input too_hot,
	input fan_on,
	output heater,
	output aircon,
	output fan
);

test:
`timescale 1 ps/1 ps
`define OK 12
`define INCORRECT 13
module reference_module(
	input mode,
	input too_cold,
	input too_hot,
	input fan_on,
	output heater,
	output aircon,
	output fan
);

	assign fan = (mode ? too_cold : too_hot) | fan_on;
	assign heater = (mode & too_cold);
	assign aircon = (~mode & too_hot);

endmodule

module stimulus_gen (
	input clk,
	output reg too_cold, too_hot, mode, fan_on,
	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
		{too_cold, too_hot, mode, fan_on} <= 4'b0010;
		@(negedge clk);
		wavedrom_start("Winter");
			@(posedge clk) {too_cold, too_hot, mode, fan_on} <= 4'b0010;
			@(posedge clk) {too_cold, too_hot, mode, fan_on} <= 4'b0010;
			@(posedge clk) {too_cold, too_hot, mode, fan_on} <= 4'b1010;
			@(posedge clk) {too_cold, too_hot, mode, fan_on} <= 4'b1011;
			@(posedge clk) {too_cold, too_hot, mode, fan_on} <= 4'b0010;
			@(posedge clk) {too_cold, too_hot, mode, fan_on} <= 4'b0011;
			@(posedge clk) {too_cold, too_hot, mode, fan_on} <= 4'b0010;
			@(posedge clk) {too_cold, too_hot, mode, fan_on} <= 4'b0110;
			@(posedge clk) {too_cold, too_hot, mode, fan_on} <= 4'b1110;
			@(posedge clk) {too_cold, too_hot, mode, fan_on} <= 4'b0111;
			@(posedge clk) {too_cold, too_hot, mode, fan_on} <= 4'b1111;
		@(negedge clk) wavedrom_stop();

		{too_cold, too_hot, mode, fan_on} <= 4'b0000;
		@(negedge clk);
		wavedrom_start("Summer");
			@(posedge clk) {too_cold, too_hot, mode, fan_on} <= 4'b0000;
			@(posedge clk) {too_cold, too_hot, mode, fan_on} <= 4'b0000;
			@(posedge clk) {too_cold, too_hot, mode, fan_on} <= 4'b0100;
			@(posedge clk) {too_cold, too_hot, mode, fan_on} <= 4'b0101;
			@(posedge clk) {too_cold, too_hot, mode, fan_on} <= 4'b0000;
			@(posedge clk) {too_cold, too_hot, mode, fan_on} <= 4'b0001;
			@(posedge clk) {too_cold, too_hot, mode, fan_on} <= 4'b0000;
			@(posedge clk) {too_cold, too_hot, mode, fan_on} <= 4'b1000;
			@(posedge clk) {too_cold, too_hot, mode, fan_on} <= 4'b1100;
			@(posedge clk) {too_cold, too_hot, mode, fan_on} <= 4'b1001;
			@(posedge clk) {too_cold, too_hot, mode, fan_on} <= 4'b1101;
		@(negedge clk) wavedrom_stop();

		repeat(200)
			@(posedge clk, negedge clk) {too_cold, too_hot, mode, fan_on} <= $random;

		#1 $finish;
	end

endmodule

module tb();

	typedef struct packed {
		int errors;
		int errortime;
		int errors_heater;
		int errortime_heater;
		int errors_aircon;
		int errortime_aircon;
		int errors_fan;
		int errortime_fan;

		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 mode;
	logic too_cold;
	logic too_hot;
	logic fan_on;
	logic heater_ref;
	logic heater_dut;
	logic aircon_ref;
	logic aircon_dut;
	logic fan_ref;
	logic fan_dut;

	initial begin
		$dumpfile("wave.vcd");
		$dumpvars(1, stim1.clk, tb_mismatch ,mode,too_cold,too_hot,fan_on,heater_ref,heater_dut,aircon_ref,aircon_dut,fan_ref,fan_dut );
	end

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

	stimulus_gen stim1 (
		.clk,
		.* ,
		.mode,
		.too_cold,
		.too_hot,
		.fan_on );
	reference_module good1 (
		.mode,
		.too_cold,
		.too_hot,
		.fan_on,
		.heater(heater_ref),
		.aircon(aircon_ref),
		.fan(fan_ref) );

	top_module top_module1 (
		.mode,
		.too_cold,
		.too_hot,
		.fan_on,
		.heater(heater_dut),
		.aircon(aircon_dut),
		.fan(fan_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_heater) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "heater", stats1.errors_heater, stats1.errortime_heater);
		else $display("Hint: Output '%s' has no mismatches.", "heater");
		if (stats1.errors_aircon) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "aircon", stats1.errors_aircon, stats1.errortime_aircon);
		else $display("Hint: Output '%s' has no mismatches.", "aircon");
		if (stats1.errors_fan) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "fan", stats1.errors_fan, stats1.errortime_fan);
		else $display("Hint: Output '%s' has no mismatches.", "fan");

		$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 = ( { heater_ref, aircon_ref, fan_ref } === ( { heater_ref, aircon_ref, fan_ref } ^ { heater_dut, aircon_dut, fan_dut } ^ { heater_ref, aircon_ref, fan_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 (heater_ref !== ( heater_ref ^ heater_dut ^ heater_ref ))
		begin if (stats1.errors_heater == 0) stats1.errortime_heater = $time;
			stats1.errors_heater = stats1.errors_heater+1'b1; end
		if (aircon_ref !== ( aircon_ref ^ aircon_dut ^ aircon_ref ))
		begin if (stats1.errors_aircon == 0) stats1.errortime_aircon = $time;
			stats1.errors_aircon = stats1.errors_aircon+1'b1; end
		if (fan_ref !== ( fan_ref ^ fan_dut ^ fan_ref ))
		begin if (stats1.errors_fan == 0) stats1.errortime_fan = $time;
			stats1.errors_fan = stats1.errors_fan+1'b1; end

	end
endmodule

detail_description: A heating/cooling thermostat controls both a heater (during winter) and an air conditioner (during summer). Implement a circuit that will turn on and off the heater, air conditioning, and blower fan as appropriate. The thermostat can be in one of two modes: heating (mode = 1) and cooling (mode = 0). In heating mode, turn the heater on when it is too cold (too_cold = 1) but do not use the air conditioner. In cooling mode, turn the air conditioner on when it is too hot (too_hot = 1), but do not turn on the heater. When the heater or air conditioner are on, also turn on the fan to circulate the air. In addition, the user can also request the fan to turn on (fan_on = 1), even if the heater and air conditioner are off.


prompt:
module top_module (
	input [5:0] y,
	input w,
	output Y1,
	output Y3
);

test:
`timescale 1 ps/1 ps
`define OK 12
`define INCORRECT 13
module reference_module (
	input [5:0] y,
	input w,
	output Y1,
	output Y3
);
	assign Y1 = y[0]&w;
	assign Y3 = (y[1]|y[2]|y[4]|y[5]) & ~w;

endmodule

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

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

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

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

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

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

		#1 $finish;
	end

endmodule

module tb();

	typedef struct packed {
		int errors;
		int errortime;
		int errors_Y1;
		int errortime_Y1;
		int errors_Y3;
		int errortime_Y3;

		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 [5:0] y;
	logic w;
	logic Y1_ref;
	logic Y1_dut;
	logic Y3_ref;
	logic Y3_dut;

	initial begin
		$dumpfile("wave.vcd");
		$dumpvars(1, stim1.clk, tb_mismatch ,y,w,Y1_ref,Y1_dut,Y3_ref,Y3_dut );
	end

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

	stimulus_gen stim1 (
		.clk,
		.* ,
		.y,
		.w );
	reference_module good1 (
		.y,
		.w,
		.Y1(Y1_ref),
		.Y3(Y3_ref) );

	top_module top_module1 (
		.y,
		.w,
		.Y1(Y1_dut),
		.Y3(Y3_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_Y1) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "Y1", stats1.errors_Y1, stats1.errortime_Y1);
		else $display("Hint: Output '%s' has no mismatches.", "Y1");
		if (stats1.errors_Y3) $display("Hint: Output '%s' has %0d mismatches. First mismatch occurred at time %0d.", "Y3", stats1.errors_Y3, stats1.errortime_Y3);
		else $display("Hint: Output '%s' has no mismatches.", "Y3");

		$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 = ( { Y1_ref, Y3_ref } === ( { Y1_ref, Y3_ref } ^ { Y1_dut, Y3_dut } ^ { Y1_ref, Y3_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 (Y1_ref !== ( Y1_ref ^ Y1_dut ^ Y1_ref ))
		begin if (stats1.errors_Y1 == 0) stats1.errortime_Y1 = $time;
			stats1.errors_Y1 = stats1.errors_Y1+1'b1; end
		if (Y3_ref !== ( Y3_ref ^ Y3_dut ^ Y3_ref ))
		begin if (stats1.errors_Y3 == 0) stats1.errortime_Y3 = $time;
			stats1.errors_Y3 = stats1.errors_Y3+1'b1; end

	end
endmodule

detail_description:
// Consider the state machine shown below:

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

// Assume that a one-hot code is used with the state assignment y[5:0] = 000001(A), 000010(B), 000100(C), 001000(D), 010000(E), 100000(F)

// Write a Verilog for the signal Y1, which is the input of state flip-flop y[1], for the signal Y3, which is the input of state flip-flop y[3]. Derive the Verilog by inspection assuming a one-hot encoding.