data/full_repos/permissive/117436613/mmix/decoder.sv
 line:45: before: "parameter"
1: b'%Error: data/full_repos/permissive/117436613/mmix/decoder.sv:23: Cannot find include file: mmix_defs.sv\n`include "mmix_defs.sv" \n         ^~~~~~~~~~~~~~\n        ... Looked in:\n             data/full_repos/permissive/117436613/mmix,data/full_repos/permissive/117436613/mmix_defs.sv\n             data/full_repos/permissive/117436613/mmix,data/full_repos/permissive/117436613/mmix_defs.sv.v\n             data/full_repos/permissive/117436613/mmix,data/full_repos/permissive/117436613/mmix_defs.sv.sv\n             mmix_defs.sv\n             mmix_defs.sv.v\n             mmix_defs.sv.sv\n             obj_dir/mmix_defs.sv\n             obj_dir/mmix_defs.sv.v\n             obj_dir/mmix_defs.sv.sv\n%Error: data/full_repos/permissive/117436613/mmix/decoder.sv:41: syntax error, unexpected \'=\', expecting \',\' or \';\'\n internal_opcode internal_op[0:255] = \'{\n                                    ^\n%Error: Exiting due to 2 error(s)\n'
module inst_decoder(
	input	fetch			head,
	input wire [7:0]	G, L,
	input wire [60:0]	S, O,
	input logic[63:0]	J, I, Q,
	
	output logic		stall,

	output logic[7:0]		new_L,
	output logic[60:0]	new_O, new_S,

	output control			data,
	input  values			operands
	);

	internal_opcode internal_op[0:255] = '{
		trap,fcmp,funeq,funeq,fadd,fix,fsub,fix,
		flot,flot,flot,flot,flot,flot,flot,flot,
		fmul,feps,feps,feps,fdiv,fsqrt,frem,fint,
		mul,mul,mulu,mulu,div,div,divu,divu,
		add,add,addu,addu,sub,sub,subu,subu,
		addu,addu,addu,addu,addu,addu,addu,addu,
		cmp,cmp,cmpu,cmpu,sub,sub,subu,subu,
		shl,shl,shlu,shlu,shr,shr,shru,shru,
		br,br,br,br,br,br,br,br,
		br,br,br,br,br,br,br,br,
		pbr,pbr,pbr,pbr,pbr,pbr,pbr,pbr,
		pbr,pbr,pbr,pbr,pbr,pbr,pbr,pbr,
		cset,cset,cset,cset,cset,cset,cset,cset,
		cset,cset,cset,cset,cset,cset,cset,cset,
		zset,zset,zset,zset,zset,zset,zset,zset,
		zset,zset,zset,zset,zset,zset,zset,zset,
		ld,ld,ld,ld,ld,ld,ld,ld,
		ld,ld,ld,ld,ld,ld,ld,ld,
		ld,ld,ld,ld,cswap,cswap,ldunc,ldunc,
		ldvts,ldvts,preld,preld,prego,prego,go,go,
		pst,pst,pst,pst,pst,pst,pst,pst,
		pst,pst,pst,pst,st,st,st,st,
		pst,pst,pst,pst,st,st,st,st,
		syncd,syncd,prest,prest,syncid,syncid,pushgo,pushgo,
		or_,or_,orn,orn,nor_,nor_,xor_,xor_,
		and_,and_,andn,andn,nand_,nand_,nxor,nxor,
		bdif,bdif,wdif,wdif,tdif,tdif,odif,odif,
		mux,mux,sadd,sadd,mor,mor,mor,mor,
		set,set,set,set,addu,addu,addu,addu,
		or_,or_,or_,or_,andn,andn,andn,andn,
		jmp,jmp,pushj,pushj,set,set,put,put,
		pop,resume,save,unsave,sync,noop,get,trip
	};
	
	logic support[0:255] = '{
		1, 0, 0, 0, 0, 0, 0, 0,
		0, 0, 0, 0, 0, 0, 0, 0,
		0, 0, 0, 0, 0, 0, 0, 0,
		0, 0, 0, 0, 0, 0, 0, 0,
		1, 1, 1, 1, 1, 1, 1, 1,
		1, 1, 1, 1, 1, 1, 1, 1,
		1, 1, 1, 1, 1, 1, 1, 1,
		1, 1, 1, 1, 1, 1, 1, 1,
		1, 1, 1, 1, 1, 1, 1, 1,
		1, 1, 1, 1, 1, 1, 1, 1,
		1, 1, 1, 1, 1, 1, 1, 1,
		1, 1, 1, 1, 1, 1, 1, 1,
		1, 1, 1, 1, 1, 1, 1, 1,
		1, 1, 1, 1, 1, 1, 1, 1,
		1, 1, 1, 1, 1, 1, 1, 1,
		1, 1, 1, 1, 1, 1, 1, 1,
		1, 1, 1, 1, 1, 1, 1, 1,
		1, 1, 1, 1, 1, 1, 1, 1,
		0, 0, 0, 0, 1, 1, 0, 0,
		1, 1, 0, 0, 0, 0, 1, 1,
		1, 1, 1, 1, 1, 1, 1, 1,
		1, 1, 1, 1, 1, 1, 1, 1,
		0, 0, 0, 0, 1, 1, 0, 0,
		1, 1, 0, 0, 0, 0, 1, 1,
		1, 1, 1, 1, 1, 1, 1, 1,
		1, 1, 1, 1, 1, 1, 1, 1,
		0, 0, 0, 0, 0, 0, 0, 0,
		0, 0, 0, 0, 0, 0, 0, 0,
		1, 1, 1, 1, 1, 1, 1, 1,
		1, 1, 1, 1, 1, 1, 1, 1,
		1, 1, 1, 1, 1, 1, 1, 1,
		1, 1, 1, 1, 1, 0, 1, 1
	};
	








	parameter X_is_dest_bit   = 'h20;
	parameter rel_addr_bit    = 'h40;
	parameter ctl_change_bit  = 'h80;

	reg [7:0] flags[0:255] = '{
		'h8a,'h2a,'h2a,'h2a,'h2a,'h26,'h2a,'h26,
		'h26,'h25,'h26,'h25,'h26,'h25,'h26,'h25,
		'h2a,'h2a,'h2a,'h2a,'h2a,'h26,'h2a,'h26,
		'h2a,'h29,'h2a,'h29,'h2a,'h29,'h2a,'h29,
		'h2a,'h29,'h2a,'h29,'h2a,'h29,'h2a,'h29,
		'h2a,'h29,'h2a,'h29,'h2a,'h29,'h2a,'h29,
		'h2a,'h29,'h2a,'h29,'h26,'h25,'h26,'h25,
		'h2a,'h29,'h2a,'h29,'h2a,'h29,'h2a,'h29,
		'h50,'h50,'h50,'h50,'h50,'h50,'h50,'h50,
		'h50,'h50,'h50,'h50,'h50,'h50,'h50,'h50,
		'h50,'h50,'h50,'h50,'h50,'h50,'h50,'h50,
		'h50,'h50,'h50,'h50,'h50,'h50,'h50,'h50,
		'h3a,'h39,'h3a,'h39,'h3a,'h39,'h3a,'h39,
		'h3a,'h39,'h3a,'h39,'h3a,'h39,'h3a,'h39,
		'h2a,'h29,'h2a,'h29,'h2a,'h29,'h2a,'h29,
		'h2a,'h29,'h2a,'h29,'h2a,'h29,'h2a,'h29,
		'h2a,'h29,'h2a,'h29,'h2a,'h29,'h2a,'h29,
		'h2a,'h29,'h2a,'h29,'h2a,'h29,'h2a,'h29,
		'h2a,'h29,'h2a,'h29,'h3a,'h39,'h2a,'h29,
		'h2a,'h29,'h0a,'h09,'h0a,'h09,'haa,'ha9,
		'h1a,'h19,'h1a,'h19,'h1a,'h19,'h1a,'h19,
		'h1a,'h19,'h1a,'h19,'h1a,'h19,'h1a,'h19,
		'h1a,'h19,'h1a,'h19,'h0a,'h09,'h1a,'h19,
		'h0a,'h09,'h0a,'h09,'h0a,'h09,'haa,'ha9,
		'h2a,'h29,'h2a,'h29,'h2a,'h29,'h2a,'h29,
		'h2a,'h29,'h2a,'h29,'h2a,'h29,'h2a,'h29,
		'h2a,'h29,'h2a,'h29,'h2a,'h29,'h2a,'h29,
		'h2a,'h29,'h2a,'h29,'h2a,'h29,'h2a,'h29,
		'h20,'h20,'h20,'h20,'h30,'h30,'h30,'h30,
		'h30,'h30,'h30,'h30,'h30,'h30,'h30,'h30,
		'hc0,'hc0,'he0,'he0,'h60,'h60,'h02,'h01,
		'h80,'h80,'h00,'h02,'h01,'h00,'h20,'h8a
	};

	reg [7:0] third_operand[0:255] = '{
		0,rA,0,0,rA,rA,rA,rA,
		rA,rA,rA,rA,rA,rA,rA,rA,
		rA,rE,rE,rE,rA,rA,rA,rA,
		rA,rA,0,0,rA,rA,rD,rD,
		rA,rA,0,0,rA,rA,0,0,
		0,0,0,0,0,0,0,0,
		0,0,0,0,rA,rA,0,0,
		rA,rA,0,0,0,0,0,0,
		0,0,0,0,0,0,0,0,
		0,0,0,0,0,0,0,0,
		0,0,0,0,0,0,0,0,
		0,0,0,0,0,0,0,0,
		0,0,0,0,0,0,0,0,
		0,0,0,0,0,0,0,0,
		0,0,0,0,0,0,0,0,
		0,0,0,0,0,0,0,0,
		0,0,0,0,0,0,0,0,
		0,0,0,0,0,0,0,0,
		0,0,0,0,0,0,0,0,
		0,0,0,0,0,0,0,0,
		rA,rA,0,0,rA,rA,0,0,
		rA,rA,0,0,0,0,0,0,
		rA,rA,0,0,0,0,0,0,
		0,0,0,0,0,0,0,0,
		0,0,0,0,0,0,0,0,
		0,0,0,0,0,0,0,0,
		0,0,0,0,0,0,0,0,
		rM,rM,0,0,0,0,0,0,
		0,0,0,0,0,0,0,0,
		0,0,0,0,0,0,0,0,
		0,0,0,0,0,0,0,0,
		rJ,0,0,0,0,0,0,255
	};


	mmix_opcode		op;
	internal_opcode	i;
	reg [7:0]		f;


	assign data.loc = head.loc;


	
	assign {data.op, data.xx, data.yy, data.zz} = head.inst;
	

	logic pop_unsave;
	logic decrease_gamma;
	logic increase_gamma;
	
	spec	yy_y;
	spec zz_z;
	
	yy_zz_decoder yy_zz_dec(
		.f			(f),
		.loc		(head.loc),
		.inst		(head.inst),
		.G			(G),
		.L			(L),
		.O			(O),
		.i,
		.y			(yy_y),
		.z			(zz_z)
	);

	
	always_comb begin
	
		pop_unsave = 0;
		decrease_gamma = 0;
		increase_gamma = 0;
		
		stall = 0;
		
		new_L = L;
		new_S = S;
		new_O = O;
		
		op = data.op;











		if ((op == TRIP) && head.loc[63]) begin
			f = 0;
			i = noop;
		end else begin
			f = flags[op];
			if (~support[op])
				i = trap;
			else
				i = internal_op[op];
		end
		
		data.i = i;
		data.ra = '{ 0, 0, 0 };
		data.x = '{ 0, 0, 0, 0};
		data.a = '{ 0, 0, 0, 0};


		data.ren_x = 0;
		data.mem_x = 0;
		data.ren_a = 0;
		data.interrupt = head.interrupt;
		data.interim = 0;
		data.go = '{ data.loc + 4, 0, 0, 0};
		data.owner = 0;
		





















		
		if (f & X_is_dest_bit) begin
			if (data.xx >= G) begin

					data.ren_x = 1;
					data.x = '{0, 0, 2'b01, data.xx};
			end else if (data.xx < L) begin

					data.ren_x = 1;
					data.x = '{0, 0, 2'b10, (O + data.xx) & lring_mask };

			end
		end
		
		if ((f & X_is_dest_bit) && (data.xx >= L) && (data.xx < G)) begin

			


			if (((S - O - L - 1) & lring_mask) == 0) begin

				data.b = '{ 0, 2, S & lring_mask };
				data.ra = '{0, 0, 0};
				data.i = incgamma;
				new_S = S + 1;
				data.y = '{ S << 3, 0, 0 };
				data.z = '{ 0, 0, 0 };
				data.mem_x = 1;
				data.x = '{ 0, 0, 0, 0 };
				op = STOU;
				data.interim = 1;
				data.stack_alert = 1;
			end else begin

				data.b = '{ 0, 2, S & lring_mask };
				data.ra = '{0, 0, 0};
				data.i = incrl;
				data.x = '{0, 1, 2'b10, (O + L) & lring_mask};
				new_L = L + 1'b1;
				data.y = '{ 0, 0, 0 };
				data.z = '{ 0, 0, 0 };
				data.mem_x = 0;
				op = SETH;
				data.interim = 1;
				data.stack_alert = 0;
			end
		end else begin

			
			data.mem_x = 0;
			data.interim = 0;
			data.stack_alert = 0;
			

			
			if (head.resuming != 0) begin
				if (head.resuming[0]) begin
					data.y = '{ 0, 2'b01, rY };
					data.z = '{ 0, 2'b01, rZ };
				end else begin
					data.y = '{ 0, 2'b01, rYY };
					data.z = '{ 0, 2'b01, rZZ };
				end
				if (head.resuming >= 3) begin
					data.ra = '{ 0, 2'b01, rA };
				end
				data.b = '{ 0, 0, 0 };

			end else begin

				data.z = zz_z;
				
				if ((op[7:4] == 4'he) && (i != set)) begin
					if (data.xx >= G) begin
						data.y = '{ 0, 1, data.xx};
					end else begin
						data.y = '{ 0, 2, (O + data.xx) & lring_mask };
					end
				end else begin
					data.y = yy_y;
				end
				

				if (f & 8'h10) begin
					if (data.xx >= G) begin
						data.b = '{ 0, 1, data.xx};
					end else if (data.xx < L) begin
						data.b = '{ 0, 2, (O + data.xx) & lring_mask };
					end else begin
						data.b = '{ 0, 0, 0 };
					end
				end else if ((op & 'hfe) == STCO) begin
					data.b = '{ data.xx, 0, 0 };
				end else begin
					data.b = '{ 0, 0, 0 };
				end

				if (third_operand[op] && (i != trap)) begin
					if (third_operand[op] == rA || third_operand[op] == rE) begin
						data.ra = '{ 0, 1, rA };
					end else begin
						data.ra = '{ 0, 0, 0 };
					end
					if (third_operand[op] != rA) begin
						data.b = '{ 0, 1, third_operand[op] };
					end
				end else begin
					data.ra = '{ 0, 0, 0 };
				end
			
			end

			case (i)
			st:
				begin
					
				end
			pst:
				begin
					data.mem_x = 1;

				end
			ld:
				begin

				end

			put: begin
					if ((data.yy != 0) || (data.xx >= 32)) begin
						data.interrupt[B_BIT] = 1;
						data.i = noop;
					end else begin
						if ((data.xx >= 9) && (data.xx <= 11))	begin
							data.interrupt[B_BIT] = 1;
							data.i = noop;
						end else if ((data.xx >= 8) && (data.xx <= 18) && ~data.loc[63]) begin
							data.interrupt[K_BIT] = 1;
							data.i = noop;
						end else begin


							data.ren_x = 1;
							data.x = '{ 0, 0, 2'b01, data.xx };
						end
					end
				end
			get: begin
					if ((data.yy != 0) || (data.zz >= 32)) begin
						data.interrupt[B_BIT] = 1;
						data.i = noop;
					end else begin
						case (data.zz)
						rO: data.z.o = O << 3;
						rS: data.z.o = S << 3;
						rG: data.z.o = G;
						rL: data.z.o = L;
						rI: data.z.o = I;
						rQ: data.z.o = Q;
						default: data.z = '{0, 2'b01, data.zz };
						endcase
					end
				end
			pushgo, pushj: begin
				if ((data.xx >= G) && (((S - O - L - 1) & lring_mask) == 0)) begin



			      data.i = incgamma;
			      new_S = S + 1;
			      data.b = '{ 0, 2'b10, S & lring_mask};
			      data.y = '{ S << 3, 2'b00, 0 };
			      data.z = '{ 0, 0, 0};
			      data.mem_x = 1;

			      op = STOU;
			      data.interim = 1;
					data.stack_alert = 1;
				end else begin
					if (data.xx >= G) begin
						data.ren_x = 1;
						data.x = '{ L, 1, 2'b10, (O + L) & lring_mask };
						data.ren_a = 1;
						data.a = '{ data.loc + 4, 1, 2'b01, rJ };


						new_L = 0;
						new_O = O + L + 1;
					end else begin

						data.x.known = 1;
						data.x.o = data.xx;
						data.ren_a = 1;
						data.a = '{ data.loc + 4, 1, 2'b01, rJ };


						new_L = L - data.xx - 1'b1;
						new_O = O + data.xx + 1'b1;
					end
				end
			end
			pop: begin
				if (data.xx && L >= data.xx)
					data.y = '{ 0, 2'b10, (O + data.xx - 1) & lring_mask};

				pop_unsave = 1;
			end
			trap: begin
					data.ra = '{ 0, 2'b01, rT};
					data.b = '{ 0, 2'b01, 255};
					data.ren_x = 1;
					data.x = '{ J, 1, 2'b01, 255};
					data.ren_a = 1;
					data.a = '{ 0, 0, 2'b01, rBB};
					if (f & X_is_dest_bit)
						data.interrupt[26:19] = RESUME_SET;
					else
						data.interrupt[26:19] = 'h80;
				end
			resume: begin
					if (data.zz) begin
						if (~data.loc[63]) begin
							data.interrupt[K_BIT] = 1;
							data.i = noop;
						end else begin



							data.y = '{ 0, 2'b01, rWW};
							data.z = '{ 0, 2'b01, rXX};
							data.b = '{ 0, 2'b01, rBB};
							data.ra = '{ 0, 2'b01, 255};
							
							data.go = '{ 0, 0, 0, 0};
							data.a = '{ 0, 0, 2'b01, rK };
							data.ren_a = 1;
							data.x = '{ 0, 0, 2'b01, 255 };
							data.ren_x = 1;
							
							if (~operands.y.valid || ~operands.z.valid)
								stall = 1;
							else begin
								if (~operands.z.o[63]) begin
									data.i = resum;

									case (operands.z.o[63:56])
									RESUME_SET: begin
										data.interrupt[15:8] = operands.z.o[55:48];


										end



									default: begin

											data.interrupt[B_BIT] = 1;
											data.i = noop;
										end
									endcase
								end
							end
						end
					end else begin

					end
				end
			unsave: begin
					if (data.interrupt[B_BIT]) begin
						data.i = noop;
					end else begin
						data.interim = 1;
						op = LDOU;
						data.i = unsav;
						case (data.xx)
						0: begin
								if (~operands.z.valid) begin
									stall = 1;
								end else begin

									data.ren_a = 1;
									data.a = '{ 0, 0, 2'b01, rA };
									new_O = operands.z.o[63:3];
									new_S = operands.z.o[63:3];
									new_L = 0;
								end
							end
						1, 2: begin
								data.ren_x = 1;
								data.x = '{ 0, 0, 2'b01, data.yy};
								new_O = O - 1;
								new_S = O - 1;
								data.z = '{ new_O << 3, 0, 0};
							end
						3: begin
								data.i = unsave;
								data.interim = 0;
								op = UNSAVE;
								

								pop_unsave = 1;
							end
						default: begin
								data.interim = 0;
								data.i = noop;
								data.interrupt[B_BIT] = 1;
							end
						endcase
					end
				end
			save: begin
					if (data.xx < G) begin
						data.interrupt[B_BIT] = 1;
						data.i = noop;
					end else begin
						if (((S - O - L - 1) & lring_mask) == 0) begin
							increase_gamma = 1;
						end else begin
							data.interim = 1;
							data.i = sav;

							data.ra = '{ 0, 2'b01, rA };
							case (data.zz)
							0: begin
									data.ren_x = 1;
									data.x = '{ L, 1, 2'b10, (O + L) & lring_mask };
									new_L = 0;
									new_O = O + L + 1;
								end
							1, 2: begin
									if (O != S) begin
										increase_gamma = 1;
									end else begin
										op = STOU;

										data.z.o = O << 3;
										new_S = O + 1;
										new_O = new_S;
										if ((data.zz == 2) && (data.yy > rZ)) begin
											data.i = save;
											data.interim = 0;
											data.ren_a = 1;
											data.a = '{ 0, 0, 2'b01, data.xx };
											data.b = { { G, 24'b0, operands.ra.o[31:0] }, 2'b00, 8'b0 };
										end else begin
											data.b = '{ 0, 2'b01, data.yy };
										end
									end
								end
							default: begin
									data.interim = 0;
									data.i = noop;
									data.interrupt[B_BIT] = 1;
								end
							endcase
						end
					end
				end
			sync: begin

				end
			endcase
		
		end
		
		if (pop_unsave) begin
			if (S == O) begin

				decrease_gamma = 1;
			end else begin

				data.ra = '{ 0, 2'b10, (O - 1) & lring_mask };
				if (~operands.ra.valid)
					stall = 1;
				else begin

					if ((O - S) <= operands.ra.o[7:0]) begin

						decrease_gamma = 1;
					end else begin
						new_O = O - operands.ra.o[7:0] - 1'b1;
						new_L = operands.ra.o[7:0] + (data.xx <= L ? data.xx : L + 1'b1);
						if (new_L > G)
							new_L = G;
						if (operands.ra.o[7:0] < new_L) begin
							data.ren_x = 1;

							data.x = '{0, 0, 2'b10, (O - 1) & lring_mask };
						end
						data.z.o = head.inst[15:0] << 2;
					end
				end
			end
		end

		if (decrease_gamma) begin
			data.i = decgamma;
			new_S = S - 1;
			data.y = '{ new_S << 3, 2'b00, 0 };

			data.x = '{ 0, 0, 2'b10, new_S & lring_mask };
			op = LDOU;

			data.z = '{ 0, 0, 0 };
			data.b = '{ 0, 0, 0 };

			data.ren_x = 1;
			data.interim = 1;
		end
		
		if (increase_gamma) begin

			data.b = '{ 0, 2, S & lring_mask };
			data.ra = '{0, 0, 0};
			data.i = incgamma;
			new_S = S + 1;
			data.y = '{ S << 3, 0, 0 };
			data.z = '{ 0, 0, 0 };

			data.x = '{ 0, 0, 0, 0 };
			op = STOU;
			data.interim = 1;

		end
		
	end
	
endmodule
module inst_decoder(
	input	fetch			head,
	input wire [7:0]	G, L,
	input wire [60:0]	S, O,
	input logic[63:0]	J, I, Q,
	
	output logic		stall,

	output logic[7:0]		new_L,
	output logic[60:0]	new_O, new_S,

	output control			data,
	input  values			operands
	);


	internal_opcode internal_op[0:255] = '{
		trap,fcmp,funeq,funeq,fadd,fix,fsub,fix,
		flot,flot,flot,flot,flot,flot,flot,flot,
		fmul,feps,feps,feps,fdiv,fsqrt,frem,fint,
		mul,mul,mulu,mulu,div,div,divu,divu,
		add,add,addu,addu,sub,sub,subu,subu,
		addu,addu,addu,addu,addu,addu,addu,addu,
		cmp,cmp,cmpu,cmpu,sub,sub,subu,subu,
		shl,shl,shlu,shlu,shr,shr,shru,shru,
		br,br,br,br,br,br,br,br,
		br,br,br,br,br,br,br,br,
		pbr,pbr,pbr,pbr,pbr,pbr,pbr,pbr,
		pbr,pbr,pbr,pbr,pbr,pbr,pbr,pbr,
		cset,cset,cset,cset,cset,cset,cset,cset,
		cset,cset,cset,cset,cset,cset,cset,cset,
		zset,zset,zset,zset,zset,zset,zset,zset,
		zset,zset,zset,zset,zset,zset,zset,zset,
		ld,ld,ld,ld,ld,ld,ld,ld,
		ld,ld,ld,ld,ld,ld,ld,ld,
		ld,ld,ld,ld,cswap,cswap,ldunc,ldunc,
		ldvts,ldvts,preld,preld,prego,prego,go,go,
		pst,pst,pst,pst,pst,pst,pst,pst,
		pst,pst,pst,pst,st,st,st,st,
		pst,pst,pst,pst,st,st,st,st,
		syncd,syncd,prest,prest,syncid,syncid,pushgo,pushgo,
		or_,or_,orn,orn,nor_,nor_,xor_,xor_,
		and_,and_,andn,andn,nand_,nand_,nxor,nxor,
		bdif,bdif,wdif,wdif,tdif,tdif,odif,odif,
		mux,mux,sadd,sadd,mor,mor,mor,mor,
		set,set,set,set,addu,addu,addu,addu,
		or_,or_,or_,or_,andn,andn,andn,andn,
		jmp,jmp,pushj,pushj,set,set,put,put,
		pop,resume,save,unsave,sync,noop,get,trip
	};
	
	logic support[0:255] = '{
		1, 0, 0, 0, 0, 0, 0, 0,
		0, 0, 0, 0, 0, 0, 0, 0,
		0, 0, 0, 0, 0, 0, 0, 0,
		0, 0, 0, 0, 0, 0, 0, 0,
		1, 1, 1, 1, 1, 1, 1, 1,
		1, 1, 1, 1, 1, 1, 1, 1,
		1, 1, 1, 1, 1, 1, 1, 1,
		1, 1, 1, 1, 1, 1, 1, 1,
		1, 1, 1, 1, 1, 1, 1, 1,
		1, 1, 1, 1, 1, 1, 1, 1,
		1, 1, 1, 1, 1, 1, 1, 1,
		1, 1, 1, 1, 1, 1, 1, 1,
		1, 1, 1, 1, 1, 1, 1, 1,
		1, 1, 1, 1, 1, 1, 1, 1,
		1, 1, 1, 1, 1, 1, 1, 1,
		1, 1, 1, 1, 1, 1, 1, 1,
		1, 1, 1, 1, 1, 1, 1, 1,
		1, 1, 1, 1, 1, 1, 1, 1,
		0, 0, 0, 0, 1, 1, 0, 0,
		1, 1, 0, 0, 0, 0, 1, 1,
		1, 1, 1, 1, 1, 1, 1, 1,
		1, 1, 1, 1, 1, 1, 1, 1,
		0, 0, 0, 0, 1, 1, 0, 0,
		1, 1, 0, 0, 0, 0, 1, 1,
		1, 1, 1, 1, 1, 1, 1, 1,
		1, 1, 1, 1, 1, 1, 1, 1,
		0, 0, 0, 0, 0, 0, 0, 0,
		0, 0, 0, 0, 0, 0, 0, 0,
		1, 1, 1, 1, 1, 1, 1, 1,
		1, 1, 1, 1, 1, 1, 1, 1,
		1, 1, 1, 1, 1, 1, 1, 1,
		1, 1, 1, 1, 1, 0, 1, 1
	};
	








	parameter X_is_dest_bit   = 'h20;
	parameter rel_addr_bit    = 'h40;
	parameter ctl_change_bit  = 'h80;

	reg [7:0] flags[0:255] = '{
		'h8a,'h2a,'h2a,'h2a,'h2a,'h26,'h2a,'h26,
		'h26,'h25,'h26,'h25,'h26,'h25,'h26,'h25,
		'h2a,'h2a,'h2a,'h2a,'h2a,'h26,'h2a,'h26,
		'h2a,'h29,'h2a,'h29,'h2a,'h29,'h2a,'h29,
		'h2a,'h29,'h2a,'h29,'h2a,'h29,'h2a,'h29,
		'h2a,'h29,'h2a,'h29,'h2a,'h29,'h2a,'h29,
		'h2a,'h29,'h2a,'h29,'h26,'h25,'h26,'h25,
		'h2a,'h29,'h2a,'h29,'h2a,'h29,'h2a,'h29,
		'h50,'h50,'h50,'h50,'h50,'h50,'h50,'h50,
		'h50,'h50,'h50,'h50,'h50,'h50,'h50,'h50,
		'h50,'h50,'h50,'h50,'h50,'h50,'h50,'h50,
		'h50,'h50,'h50,'h50,'h50,'h50,'h50,'h50,
		'h3a,'h39,'h3a,'h39,'h3a,'h39,'h3a,'h39,
		'h3a,'h39,'h3a,'h39,'h3a,'h39,'h3a,'h39,
		'h2a,'h29,'h2a,'h29,'h2a,'h29,'h2a,'h29,
		'h2a,'h29,'h2a,'h29,'h2a,'h29,'h2a,'h29,
		'h2a,'h29,'h2a,'h29,'h2a,'h29,'h2a,'h29,
		'h2a,'h29,'h2a,'h29,'h2a,'h29,'h2a,'h29,
		'h2a,'h29,'h2a,'h29,'h3a,'h39,'h2a,'h29,
		'h2a,'h29,'h0a,'h09,'h0a,'h09,'haa,'ha9,
		'h1a,'h19,'h1a,'h19,'h1a,'h19,'h1a,'h19,
		'h1a,'h19,'h1a,'h19,'h1a,'h19,'h1a,'h19,
		'h1a,'h19,'h1a,'h19,'h0a,'h09,'h1a,'h19,
		'h0a,'h09,'h0a,'h09,'h0a,'h09,'haa,'ha9,
		'h2a,'h29,'h2a,'h29,'h2a,'h29,'h2a,'h29,
		'h2a,'h29,'h2a,'h29,'h2a,'h29,'h2a,'h29,
		'h2a,'h29,'h2a,'h29,'h2a,'h29,'h2a,'h29,
		'h2a,'h29,'h2a,'h29,'h2a,'h29,'h2a,'h29,
		'h20,'h20,'h20,'h20,'h30,'h30,'h30,'h30,
		'h30,'h30,'h30,'h30,'h30,'h30,'h30,'h30,
		'hc0,'hc0,'he0,'he0,'h60,'h60,'h02,'h01,
		'h80,'h80,'h00,'h02,'h01,'h00,'h20,'h8a
	};

	reg [7:0] third_operand[0:255] = '{
		0,rA,0,0,rA,rA,rA,rA,
		rA,rA,rA,rA,rA,rA,rA,rA,
		rA,rE,rE,rE,rA,rA,rA,rA,
		rA,rA,0,0,rA,rA,rD,rD,
		rA,rA,0,0,rA,rA,0,0,
		0,0,0,0,0,0,0,0,
		0,0,0,0,rA,rA,0,0,
		rA,rA,0,0,0,0,0,0,
		0,0,0,0,0,0,0,0,
		0,0,0,0,0,0,0,0,
		0,0,0,0,0,0,0,0,
		0,0,0,0,0,0,0,0,
		0,0,0,0,0,0,0,0,
		0,0,0,0,0,0,0,0,
		0,0,0,0,0,0,0,0,
		0,0,0,0,0,0,0,0,
		0,0,0,0,0,0,0,0,
		0,0,0,0,0,0,0,0,
		0,0,0,0,0,0,0,0,
		0,0,0,0,0,0,0,0,
		rA,rA,0,0,rA,rA,0,0,
		rA,rA,0,0,0,0,0,0,
		rA,rA,0,0,0,0,0,0,
		0,0,0,0,0,0,0,0,
		0,0,0,0,0,0,0,0,
		0,0,0,0,0,0,0,0,
		0,0,0,0,0,0,0,0,
		rM,rM,0,0,0,0,0,0,
		0,0,0,0,0,0,0,0,
		0,0,0,0,0,0,0,0,
		0,0,0,0,0,0,0,0,
		rJ,0,0,0,0,0,0,255
	};


	mmix_opcode		op;
	internal_opcode	i;
	reg [7:0]		f;


	assign data.loc = head.loc;


	
	assign {data.op, data.xx, data.yy, data.zz} = head.inst;
	

	logic pop_unsave;
	logic decrease_gamma;
	logic increase_gamma;
	
	spec	yy_y;
	spec zz_z;
	
	yy_zz_decoder yy_zz_dec(
		.f			(f),
		.loc		(head.loc),
		.inst		(head.inst),
		.G			(G),
		.L			(L),
		.O			(O),
		.i,
		.y			(yy_y),
		.z			(zz_z)
	);

	
	always_comb begin
	
		pop_unsave = 0;
		decrease_gamma = 0;
		increase_gamma = 0;
		
		stall = 0;
		
		new_L = L;
		new_S = S;
		new_O = O;
		
		op = data.op;











		if ((op == TRIP) && head.loc[63]) begin
			f = 0;
			i = noop;
		end else begin
			f = flags[op];
			if (~support[op])
				i = trap;
			else
				i = internal_op[op];
		end
		
		data.i = i;
		data.ra = '{ 0, 0, 0 };
		data.x = '{ 0, 0, 0, 0};
		data.a = '{ 0, 0, 0, 0};


		data.ren_x = 0;
		data.mem_x = 0;
		data.ren_a = 0;
		data.interrupt = head.interrupt;
		data.interim = 0;
		data.go = '{ data.loc + 4, 0, 0, 0};
		data.owner = 0;
		





















		
		if (f & X_is_dest_bit) begin
			if (data.xx >= G) begin

					data.ren_x = 1;
					data.x = '{0, 0, 2'b01, data.xx};
			end else if (data.xx < L) begin

					data.ren_x = 1;
					data.x = '{0, 0, 2'b10, (O + data.xx) & lring_mask };

			end
		end
		
		if ((f & X_is_dest_bit) && (data.xx >= L) && (data.xx < G)) begin

			


			if (((S - O - L - 1) & lring_mask) == 0) begin

				data.b = '{ 0, 2, S & lring_mask };
				data.ra = '{0, 0, 0};
				data.i = incgamma;
				new_S = S + 1;
				data.y = '{ S << 3, 0, 0 };
				data.z = '{ 0, 0, 0 };
				data.mem_x = 1;
				data.x = '{ 0, 0, 0, 0 };
				op = STOU;
				data.interim = 1;
				data.stack_alert = 1;
			end else begin

				data.b = '{ 0, 2, S & lring_mask };
				data.ra = '{0, 0, 0};
				data.i = incrl;
				data.x = '{0, 1, 2'b10, (O + L) & lring_mask};
				new_L = L + 1'b1;
				data.y = '{ 0, 0, 0 };
				data.z = '{ 0, 0, 0 };
				data.mem_x = 0;
				op = SETH;
				data.interim = 1;
				data.stack_alert = 0;
			end
		end else begin

			
			data.mem_x = 0;
			data.interim = 0;
			data.stack_alert = 0;
			

			
			if (head.resuming != 0) begin
				if (head.resuming[0]) begin
					data.y = '{ 0, 2'b01, rY };
					data.z = '{ 0, 2'b01, rZ };
				end else begin
					data.y = '{ 0, 2'b01, rYY };
					data.z = '{ 0, 2'b01, rZZ };
				end
				if (head.resuming >= 3) begin
					data.ra = '{ 0, 2'b01, rA };
				end
				data.b = '{ 0, 0, 0 };

			end else begin

				data.z = zz_z;
				
				if ((op[7:4] == 4'he) && (i != set)) begin
					if (data.xx >= G) begin
						data.y = '{ 0, 1, data.xx};
					end else begin
						data.y = '{ 0, 2, (O + data.xx) & lring_mask };
					end
				end else begin
					data.y = yy_y;
				end
				

				if (f & 8'h10) begin
					if (data.xx >= G) begin
						data.b = '{ 0, 1, data.xx};
					end else if (data.xx < L) begin
						data.b = '{ 0, 2, (O + data.xx) & lring_mask };
					end else begin
						data.b = '{ 0, 0, 0 };
					end
				end else if ((op & 'hfe) == STCO) begin
					data.b = '{ data.xx, 0, 0 };
				end else begin
					data.b = '{ 0, 0, 0 };
				end

				if (third_operand[op] && (i != trap)) begin
					if (third_operand[op] == rA || third_operand[op] == rE) begin
						data.ra = '{ 0, 1, rA };
					end else begin
						data.ra = '{ 0, 0, 0 };
					end
					if (third_operand[op] != rA) begin
						data.b = '{ 0, 1, third_operand[op] };
					end
				end else begin
					data.ra = '{ 0, 0, 0 };
				end
			
			end

			case (i)
			st:
				begin
					
				end
			pst:
				begin
					data.mem_x = 1;

				end
			ld:
				begin

				end

			put: begin
					if ((data.yy != 0) || (data.xx >= 32)) begin
						data.interrupt[B_BIT] = 1;
						data.i = noop;
					end else begin
						if ((data.xx >= 9) && (data.xx <= 11))	begin
							data.interrupt[B_BIT] = 1;
							data.i = noop;
						end else if ((data.xx >= 8) && (data.xx <= 18) && ~data.loc[63]) begin
							data.interrupt[K_BIT] = 1;
							data.i = noop;
						end else begin


							data.ren_x = 1;
							data.x = '{ 0, 0, 2'b01, data.xx };
						end
					end
				end
			get: begin
					if ((data.yy != 0) || (data.zz >= 32)) begin
						data.interrupt[B_BIT] = 1;
						data.i = noop;
					end else begin
						case (data.zz)
						rO: data.z.o = O << 3;
						rS: data.z.o = S << 3;
						rG: data.z.o = G;
						rL: data.z.o = L;
						rI: data.z.o = I;
						rQ: data.z.o = Q;
						default: data.z = '{0, 2'b01, data.zz };
						endcase
					end
				end
			pushgo, pushj: begin
				if ((data.xx >= G) && (((S - O - L - 1) & lring_mask) == 0)) begin



			      data.i = incgamma;
			      new_S = S + 1;
			      data.b = '{ 0, 2'b10, S & lring_mask};
			      data.y = '{ S << 3, 2'b00, 0 };
			      data.z = '{ 0, 0, 0};
			      data.mem_x = 1;

			      op = STOU;
			      data.interim = 1;
					data.stack_alert = 1;
				end else begin
					if (data.xx >= G) begin
						data.ren_x = 1;
						data.x = '{ L, 1, 2'b10, (O + L) & lring_mask };
						data.ren_a = 1;
						data.a = '{ data.loc + 4, 1, 2'b01, rJ };


						new_L = 0;
						new_O = O + L + 1;
					end else begin

						data.x.known = 1;
						data.x.o = data.xx;
						data.ren_a = 1;
						data.a = '{ data.loc + 4, 1, 2'b01, rJ };


						new_L = L - data.xx - 1'b1;
						new_O = O + data.xx + 1'b1;
					end
				end
			end
			pop: begin
				if (data.xx && L >= data.xx)
					data.y = '{ 0, 2'b10, (O + data.xx - 1) & lring_mask};

				pop_unsave = 1;
			end
			trap: begin
					data.ra = '{ 0, 2'b01, rT};
					data.b = '{ 0, 2'b01, 255};
					data.ren_x = 1;
					data.x = '{ J, 1, 2'b01, 255};
					data.ren_a = 1;
					data.a = '{ 0, 0, 2'b01, rBB};
					if (f & X_is_dest_bit)
						data.interrupt[26:19] = RESUME_SET;
					else
						data.interrupt[26:19] = 'h80;
				end
			resume: begin
					if (data.zz) begin
						if (~data.loc[63]) begin
							data.interrupt[K_BIT] = 1;
							data.i = noop;
						end else begin



							data.y = '{ 0, 2'b01, rWW};
							data.z = '{ 0, 2'b01, rXX};
							data.b = '{ 0, 2'b01, rBB};
							data.ra = '{ 0, 2'b01, 255};
							
							data.go = '{ 0, 0, 0, 0};
							data.a = '{ 0, 0, 2'b01, rK };
							data.ren_a = 1;
							data.x = '{ 0, 0, 2'b01, 255 };
							data.ren_x = 1;
							
							if (~operands.y.valid || ~operands.z.valid)
								stall = 1;
							else begin
								if (~operands.z.o[63]) begin
									data.i = resum;

									case (operands.z.o[63:56])
									RESUME_SET: begin
										data.interrupt[15:8] = operands.z.o[55:48];


										end



									default: begin

											data.interrupt[B_BIT] = 1;
											data.i = noop;
										end
									endcase
								end
							end
						end
					end else begin

					end
				end
			unsave: begin
					if (data.interrupt[B_BIT]) begin
						data.i = noop;
					end else begin
						data.interim = 1;
						op = LDOU;
						data.i = unsav;
						case (data.xx)
						0: begin
								if (~operands.z.valid) begin
									stall = 1;
								end else begin

									data.ren_a = 1;
									data.a = '{ 0, 0, 2'b01, rA };
									new_O = operands.z.o[63:3];
									new_S = operands.z.o[63:3];
									new_L = 0;
								end
							end
						1, 2: begin
								data.ren_x = 1;
								data.x = '{ 0, 0, 2'b01, data.yy};
								new_O = O - 1;
								new_S = O - 1;
								data.z = '{ new_O << 3, 0, 0};
							end
						3: begin
								data.i = unsave;
								data.interim = 0;
								op = UNSAVE;
								

								pop_unsave = 1;
							end
						default: begin
								data.interim = 0;
								data.i = noop;
								data.interrupt[B_BIT] = 1;
							end
						endcase
					end
				end
			save: begin
					if (data.xx < G) begin
						data.interrupt[B_BIT] = 1;
						data.i = noop;
					end else begin
						if (((S - O - L - 1) & lring_mask) == 0) begin
							increase_gamma = 1;
						end else begin
							data.interim = 1;
							data.i = sav;

							data.ra = '{ 0, 2'b01, rA };
							case (data.zz)
							0: begin
									data.ren_x = 1;
									data.x = '{ L, 1, 2'b10, (O + L) & lring_mask };
									new_L = 0;
									new_O = O + L + 1;
								end
							1, 2: begin
									if (O != S) begin
										increase_gamma = 1;
									end else begin
										op = STOU;

										data.z.o = O << 3;
										new_S = O + 1;
										new_O = new_S;
										if ((data.zz == 2) && (data.yy > rZ)) begin
											data.i = save;
											data.interim = 0;
											data.ren_a = 1;
											data.a = '{ 0, 0, 2'b01, data.xx };
											data.b = { { G, 24'b0, operands.ra.o[31:0] }, 2'b00, 8'b0 };
										end else begin
											data.b = '{ 0, 2'b01, data.yy };
										end
									end
								end
							default: begin
									data.interim = 0;
									data.i = noop;
									data.interrupt[B_BIT] = 1;
								end
							endcase
						end
					end
				end
			sync: begin

				end
			endcase
		
		end
		
		if (pop_unsave) begin
			if (S == O) begin

				decrease_gamma = 1;
			end else begin

				data.ra = '{ 0, 2'b10, (O - 1) & lring_mask };
				if (~operands.ra.valid)
					stall = 1;
				else begin

					if ((O - S) <= operands.ra.o[7:0]) begin

						decrease_gamma = 1;
					end else begin
						new_O = O - operands.ra.o[7:0] - 1'b1;
						new_L = operands.ra.o[7:0] + (data.xx <= L ? data.xx : L + 1'b1);
						if (new_L > G)
							new_L = G;
						if (operands.ra.o[7:0] < new_L) begin
							data.ren_x = 1;

							data.x = '{0, 0, 2'b10, (O - 1) & lring_mask };
						end
						data.z.o = head.inst[15:0] << 2;
					end
				end
			end
		end

		if (decrease_gamma) begin
			data.i = decgamma;
			new_S = S - 1;
			data.y = '{ new_S << 3, 2'b00, 0 };

			data.x = '{ 0, 0, 2'b10, new_S & lring_mask };
			op = LDOU;

			data.z = '{ 0, 0, 0 };
			data.b = '{ 0, 0, 0 };

			data.ren_x = 1;
			data.interim = 1;
		end
		
		if (increase_gamma) begin

			data.b = '{ 0, 2, S & lring_mask };
			data.ra = '{0, 0, 0};
			data.i = incgamma;
			new_S = S + 1;
			data.y = '{ S << 3, 0, 0 };
			data.z = '{ 0, 0, 0 };

			data.x = '{ 0, 0, 0, 0 };
			op = STOU;
			data.interim = 1;

		end
		
	end
	
endmodule