data/full_repos/permissive/11584509/source/hashcore.v
1: b'%Error: data/full_repos/permissive/11584509/source/hashcore.v:86: Cannot find file containing module: \'sha256_transform\'\n sha256_transform  # (.LOOP(64)) sha256_blk (\n ^~~~~~~~~~~~~~~~\n        ... Looked in:\n             data/full_repos/permissive/11584509/source,data/full_repos/permissive/11584509/sha256_transform\n             data/full_repos/permissive/11584509/source,data/full_repos/permissive/11584509/sha256_transform.v\n             data/full_repos/permissive/11584509/source,data/full_repos/permissive/11584509/sha256_transform.sv\n             sha256_transform\n             sha256_transform.v\n             sha256_transform.sv\n             obj_dir/sha256_transform\n             obj_dir/sha256_transform.v\n             obj_dir/sha256_transform.sv\n%Warning-WIDTH: data/full_repos/permissive/11584509/source/hashcore.v:487: Operator ASSIGN expects 6 bits on the Assign RHS, but Assign RHS\'s CONST \'5\'h0\' generates 5 bits.\n                                                                         : ... In instance hashcore\n reg [5:0] mcount = 5\'d0;  \n                    ^~~~\n                ... Use "/* verilator lint_off WIDTH */" and lint_on around source to disable this message.\n%Error: data/full_repos/permissive/11584509/source/hashcore.v:536: Cannot find file containing module: \'ram\'\n ram # (.ADDRBITS(ADDRBITS)) ram1_blk (ram_addr, ram_clk, ram1_din, ram_wren, ram1_dout);\n ^~~\n%Error: data/full_repos/permissive/11584509/source/hashcore.v:537: Cannot find file containing module: \'ram\'\n ram # (.ADDRBITS(ADDRBITS)) ram2_blk (ram_addr, ram_clk, ram2_din, ram_wren, ram2_dout);\n ^~~\n%Error: data/full_repos/permissive/11584509/source/hashcore.v:538: Cannot find file containing module: \'ram\'\n ram # (.ADDRBITS(ADDRBITS)) ram3_blk (ram_addr, ram_clk, ram3_din, ram_wren, ram3_dout);\n ^~~\n%Error: data/full_repos/permissive/11584509/source/hashcore.v:539: Cannot find file containing module: \'ram\'\n ram # (.ADDRBITS(ADDRBITS)) ram4_blk (ram_addr, ram_clk, ram4_din, ram_wren, ram4_dout);\n ^~~\n%Error: data/full_repos/permissive/11584509/source/hashcore.v:545: Cannot find file containing module: \'salsa\'\n salsa salsa_blk (hash_clk, mixfeedback, X0, X1, Xmix);\n ^~~~~\n%Error: Exiting due to 6 error(s), 1 warning(s)\n'
module hashcore (hash_clk, data1, data2, data3, target, nonce_msb, nonce_out, golden_nonce_out, golden_nonce_match, loadnonce);

	input hash_clk;
	input [255:0] data1;
	input [255:0] data2;
	input [127:0] data3;
	input [31:0] target;
	input [3:0] nonce_msb;
	output [31:0] nonce_out;
	output [31:0] golden_nonce_out;
	output golden_nonce_match;
	input loadnonce;
	
	reg poweron_reset = 1'b1;
	reg reset = 1'b1;

	always @ (posedge hash_clk)
	begin
		poweron_reset <= 1'b0;
		reset <= poweron_reset;
	end
	
	`ifndef ICARUS
	reg [31:0] nonce_prevous_load = 32'hffffffff;
	`endif

	`ifndef NOMULTICORE
		reg [27:0] nonce_cnt = 28'd0;
		wire [31:0] nonce;
		assign nonce = { nonce_msb, nonce_cnt };
	`else
		reg [31:0] nonce = 32'd0;
	`endif

	assign nonce_out = nonce;

	reg [31:0] nonce_1 = 32'd0;
	reg [31:0] nonce_2 = 32'd0;
	reg [31:0] golden_nonce = 32'd0;
	assign golden_nonce_out = golden_nonce;
	reg golden_nonce_match = 1'b0;
	
	reg [255:0] rx_state;
	reg [511:0] rx_input;
	wire [255:0] tx_hash;
	reg [255:0] khash = 256'd0;
	reg [255:0] ihash = 256'd0;
	reg [255:0] ohash = 256'd0;
	`ifdef SIM
		reg [255:0] final_hash = 256'd0;
	`endif
	reg [31:0] blockcnt = 32'd0;
	reg [1023:0] Xbuf = 1024'd0;
	reg [1023:0] MixOut;
	wire [1023:0] MixOutRewire;
	reg [5:0] cnt = 6'd0;
	wire feedback;
	assign feedback = (cnt != 6'b0);
	


	sha256_transform  # (.LOOP(64)) sha256_blk (
		.clk(hash_clk),
		.feedback(feedback),
		.cnt(cnt),
		.rx_state(rx_state),
		.rx_input(rx_input),
		.tx_hash(tx_hash)
	);



	





	reg SMixInRdy_state = 1'b0;
	reg SMixOutRdy_state = 1'b0;
	wire SMixInRdy;
	wire SMixOutRdy;

	reg Set_SMixInRdy = 1'b0;
	reg Clr_SMixInRdy = 1'b0;
	reg Set_SMixOutRdy = 1'b0;
	reg Clr_SMixOutRdy = 1'b0;
	
	always @ (posedge hash_clk)
	begin
		if (Set_SMixInRdy)
			SMixInRdy_state <= 1'b1;
		if (Clr_SMixInRdy)
			SMixInRdy_state <= 1'b0;
		if (Set_SMixOutRdy)
			SMixOutRdy_state <= 1'b1;
		if (Clr_SMixOutRdy)
			SMixOutRdy_state <= 1'b0;
	end
	

	assign SMixInRdy = Clr_SMixInRdy ? 1'b0 : Set_SMixInRdy ? 1'b1 : SMixInRdy_state;
	assign SMixOutRdy = Clr_SMixOutRdy ? 1'b0 : Set_SMixOutRdy ? 1'b1 : SMixOutRdy_state;
		



	



	
	parameter	S_IDLE=0,
				S_H1= 1, S_H2= 2, S_H3= 3, S_H4= 4, S_H5= 5, S_H6= 6,
				S_I1= 7, S_I2= 8, S_I3= 9, S_I4=10, S_I5=11, S_I6=12,
				S_O1=13, S_O2=14, S_O3=15,
				S_B1=16, S_B2=17, S_B3=18, S_B4=19, S_B5=20, S_B6=21,
				S_XX=22,

				S_R1=23, S_R2=24, S_R3=25, S_R4=26, S_R5=27, S_R6=28,
				S_R7=29, S_R8=30, S_R9=31, S_R10=32, S_R11=33, S_R12=34,
				S_R13=35, S_R14=36, S_R15=37, S_R16=38, S_R17=39, S_R18=40;
				
	reg [5:0] state = S_IDLE;
	reg mode = 0;
	always @ (posedge hash_clk)
	begin
		Set_SMixInRdy <= 1'b0;
		Clr_SMixOutRdy <= 1'b0;
		golden_nonce_match <= 1'b0;
		
		if (reset == 1'b1)
			state <= S_IDLE;
		else
		begin
			case (state)
				S_IDLE: begin
					if (SMixOutRdy ||
						!SMixInRdy)
					begin


						rx_state <= 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667;
						rx_input <= { data2, data1 };
						blockcnt <= 32'd1;
						cnt <= 6'd0;
						if (SMixOutRdy)
							mode <= 1'b1;
						else
							mode <= 1'b0;
						state <= S_H1;
					end
				end


				S_H1: begin
					cnt <= cnt + 6'd1;
					if (cnt == 6'd63)
					begin
						cnt <= 6'd0;
						state <= S_H2;
					end
				end
				S_H2: begin
						state <= S_H3;
				end
				S_H3: begin
						rx_state <= tx_hash;


						rx_input <= { 384'h000002800000000000000000000000000000000000000000000000000000000000000000000000000000000080000000,
										mode ? nonce_2 : nonce, data3[95:0] };
						state <= S_H4;
				end
				S_H4: begin
					cnt <= cnt + 6'd1;
					if (cnt == 6'd63)
					begin
						cnt <= 6'd0;
						state <= S_H5;
					end
				end
				S_H5: begin
						state <= S_H6;
				end
				S_H6: begin
						khash <= tx_hash;

						rx_state <= 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667;
						rx_input <= { 256'h3636363636363636363636363636363636363636363636363636363636363636 ,
										tx_hash ^ 256'h3636363636363636363636363636363636363636363636363636363636363636 };
						cnt <= 6'd0;
						if (mode)
							state <= S_R1;
						else
							state <= S_I1;
				end


				S_I1: begin
					cnt <= cnt + 6'd1;
					if (cnt == 6'd63)
					begin
						cnt <= 6'd0;
						state <= S_I2;
					end
				end
				S_I2: begin
						state <= S_I3;
				end
				S_I3: begin
						rx_state <= tx_hash;
						rx_input <= { data2, data1 };
						state <= S_I4;
				end
				S_I4: begin
					cnt <= cnt + 6'd1;
					if (cnt == 6'd63)
					begin
						cnt <= 6'd0;
						state <= S_I5;
					end
				end
				S_I5: begin
						state <= S_I6;
				end
				S_I6: begin
						ihash <= tx_hash;

						rx_state <= 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667;
						rx_input <= { 256'h5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c ,
										khash ^ 256'h5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c };
						cnt <= 6'd0;
						state <= S_O1;
				end


				S_O1: begin
					cnt <= cnt + 6'd1;
					if (cnt == 6'd63)
					begin
						cnt <= 6'd0;
						state <= S_O2;
					end
				end
				S_O2: begin
						state <= S_O3;
				end
				S_O3: begin
						ohash <= tx_hash;

						rx_state <= ihash;

						rx_input <= { 352'h000004a000000000000000000000000000000000000000000000000000000000000000000000000080000000,
										blockcnt, nonce, data3[95:0] };
						blockcnt <= blockcnt + 1;
						cnt <= 6'd0;
						state <= S_B1;
				end


				S_B1: begin
					cnt <= cnt + 6'd1;
					if (cnt == 6'd63)
					begin
						cnt <= 6'd0;
						state <= S_B2;
					end
				end
				S_B2: begin
						state <= S_B3;
				end
				S_B3: begin
						rx_state <= ohash;
						rx_input <= { 256'h0000030000000000000000000000000000000000000000000000000080000000, tx_hash };
						state <= S_B4;
				end
				S_B4: begin
					cnt <= cnt + 6'd1;
					if (cnt == 6'd63)
					begin
						cnt <= 6'd0;
						state <= S_B5;
					end
				end
				S_B5: begin
						state <= S_B6;
				end
				S_B6: begin
						Xbuf[255:0] <= Xbuf[511:256];
						Xbuf[511:256] <= Xbuf[767:512];
						Xbuf[767:512] <= Xbuf[1023:768];
						Xbuf[1023:768] <= tx_hash;


						if (blockcnt == 5)
							state <= S_XX;
						else begin

							rx_state <= ihash;
							rx_input <= { 352'h000004a000000000000000000000000000000000000000000000000000000000000000000000000080000000,
											blockcnt, nonce, data3[95:0] };
							blockcnt <= blockcnt + 1;
							cnt <= 6'd0;
							state <= S_B1;
						end
				end
				S_XX: begin


						Set_SMixInRdy <= 1;
						state <= S_IDLE;
				end
				


				S_R1: begin
					cnt <= cnt + 6'd1;
					if (cnt == 6'd63)
					begin
						cnt <= 6'd0;
						state <= S_R2;
					end
				end
				S_R2: begin
						state <= S_R3;
				end
				S_R3: begin
						rx_state <= tx_hash;
						rx_input <= MixOutRewire[511:0];
						state <= S_R4;
				end
				S_R4: begin
					cnt <= cnt + 6'd1;
					if (cnt == 6'd63)
					begin
						cnt <= 6'd0;
						state <= S_R5;
					end
				end
				S_R5: begin
						state <= S_R6;
				end
				S_R6: begin
						rx_state <= tx_hash;
						rx_input <= MixOutRewire[1023:512];
						state <= S_R7;
				end
				S_R7: begin
					cnt <= cnt + 6'd1;
					if (cnt == 6'd63)
					begin
						cnt <= 6'd0;
						state <= S_R8;
					end
				end
				S_R8: begin
						state <= S_R9;
				end
				S_R9: begin
						rx_state <= tx_hash;

						rx_input <= 512'h00000620000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000001;
						state <= S_R10;
				end
				S_R10: begin
					cnt <= cnt + 6'd1;
					if (cnt == 6'd63)
					begin
						cnt <= 6'd0;
						state <= S_R11;
					end
				end
				S_R11: begin
						state <= S_R12;
				end
				S_R12: begin
						ihash <= tx_hash;

						rx_state <= 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667;
						rx_input <= { 256'h5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c ,
										khash ^ 256'h5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c };
						cnt <= 6'd0;
						state <= S_R13;
				end
				S_R13: begin
					cnt <= cnt + 6'd1;
					if (cnt == 6'd63)
					begin
						cnt <= 6'd0;
						state <= S_R14;
					end
				end
				S_R14: begin
						state <= S_R15;
				end
				S_R15: begin
						rx_state <= tx_hash;
						rx_input <= { 256'h0000030000000000000000000000000000000000000000000000000080000000, ihash };
						state <= S_R16;
				end
				S_R16: begin
					cnt <= cnt + 6'd1;
					if (cnt == 6'd63)
					begin
						cnt <= 6'd0;
						state <= S_R17;
					end
				end
				S_R17: begin
						state <= S_R18;
				end
				S_R18: begin

						`ifdef SIM
							final_hash <= tx_hash;
						`endif

						if ( { tx_hash[231:224], tx_hash[239:232], tx_hash[247:240], tx_hash[255:248] } < target)
						begin
							golden_nonce <= nonce_2;
							golden_nonce_match <= 1'b1;
						end
						state <= S_IDLE;
						mode <= 0;

						Clr_SMixOutRdy <= 1'b1;
				end
			endcase	
		end
	end




	wire [1023:0] X;
	`define IDX(x) (((x)+1)*(32)-1):((x)*(32))
	genvar i;
	generate
	for (i = 0; i < 32; i = i + 1) begin : Xrewire
		wire [31:0] tmp;
		assign tmp = Xbuf[`IDX(i)];
		assign X[`IDX(i)] = { tmp[7:0], tmp[15:8], tmp[23:16], tmp[31:24] };


		wire [31:0] mix;
		assign mix = MixOut[`IDX(i)];
		assign MixOutRewire[`IDX(i)] = { mix[7:0], mix[15:8], mix[23:16], mix[31:24] };
	end
	endgenerate









	parameter R_IDLE=0, R_WRITE=1, R_MIX=2, R_INT=3;
	reg [1:0] mstate = R_IDLE;
	reg [10:0] cycle = 11'd0;
	reg [5:0] mcount = 5'd0;
	reg doneROM = 1'd0;
	reg mixfeedback = 1'b0;
	reg addrsourceMix = 1'b0;

	reg [511:0] X0;
	reg [511:0] X1;
	`ifdef HALFRAM
		reg [511:0] X0Save;
		reg [511:0] X1Save;
		reg	oddAddr = 1'b0;
	`endif
	wire [511:0] Xmix;


	reg [9:0] writeaddr = 10'd0;
	



	
	`ifdef HALFRAM
		parameter ADDRBITS = 9;
	`else
		parameter ADDRBITS = 10;
	`endif

	wire [ADDRBITS-1:0]ram_addr;
	wire [255:0]ram1_din;
	wire [255:0]ram1_dout;
	wire [255:0]ram2_din;
	wire [255:0]ram2_dout;
	wire [255:0]ram3_din;
	wire [255:0]ram3_dout;
	wire [255:0]ram4_din;
	wire [255:0]ram4_dout;
	wire [1023:0]ramout;

	reg ram_wren;
	wire ram_clk;
	assign ram_clk = hash_clk;
	
	`ifdef HALFRAM

		assign ram_addr = addrsourceMix ? Xmix[9:1] : writeaddr[9:1];
	`else

		assign ram_addr = addrsourceMix ? Xmix[9:0] : writeaddr;
	`endif
	ram # (.ADDRBITS(ADDRBITS)) ram1_blk (ram_addr, ram_clk, ram1_din, ram_wren, ram1_dout);
	ram # (.ADDRBITS(ADDRBITS)) ram2_blk (ram_addr, ram_clk, ram2_din, ram_wren, ram2_dout);
	ram # (.ADDRBITS(ADDRBITS)) ram3_blk (ram_addr, ram_clk, ram3_din, ram_wren, ram3_dout);
	ram # (.ADDRBITS(ADDRBITS)) ram4_blk (ram_addr, ram_clk, ram4_din, ram_wren, ram4_dout);
	assign ramout = { ram4_dout, ram3_dout, ram2_dout, ram1_dout };
	assign { ram4_din, ram3_din, ram2_din, ram1_din } = { X1, X0} ;


	
	salsa salsa_blk (hash_clk, mixfeedback, X0, X1, Xmix);


	
	always @ (posedge hash_clk)
	begin
		Set_SMixOutRdy <= 1'b0;
		Clr_SMixInRdy <= 1'b0;
		`ifdef HALFRAM
			oddAddr <= Xmix[0];
		`endif
		`ifdef ICARUS
		if (loadnonce)
		`else
		if (loadnonce || (nonce_prevous_load != data3[127:96]))
		`endif
		begin
			`ifdef NOMULTICORE
				nonce <= data3[127:96];




			`else
				nonce_cnt <= data3[123:96];

			`endif
			`ifndef ICARUS
			nonce_prevous_load <= data3[127:96];
			`endif
		end
		if (reset == 1'b1)
			mstate <= R_IDLE;
		else
		begin
			case (mstate)
				R_IDLE: begin
					writeaddr <= 0;
					mcount <= 0;
					X0 <= X[511:0];
					X1 <= X[1023:512];
					mixfeedback <= 1'b0;
					addrsourceMix <= 1'b0;
					if (SMixInRdy)
						begin
							mstate <= R_WRITE;
							doneROM <= 1'b0;
							ram_wren <= 1'b1;

							Clr_SMixInRdy <= 1;

							nonce_1 <= nonce;
							`ifndef NOMULTICORE
								nonce_cnt <= nonce_cnt + 28'd1;
							`else
								nonce <= nonce + 32'd1;
							`endif
						end
				end
				R_WRITE: begin
					mcount <= mcount + 6'd1;
					ram_wren <= 0;





					if (mcount==0)
					begin
						mixfeedback <= 1'b1;
						if (writeaddr==1023)
							doneROM <= 1'b1;
						writeaddr <= writeaddr + 10'd1;
					end
					if (mcount==4)
						mixfeedback <= 1'b1;
					if (mcount == 3 || mcount == 7)
					begin
						X0 <= X1;
						X1 <= Xmix;
						mixfeedback <= 1'b0;
					end
					if (mcount == 6 && doneROM)
						addrsourceMix <= 1'b1;
					if (mcount == 7)
					begin
						mcount <= 0;
						if (doneROM)
						begin
							cycle <= 0;
							mstate <= R_MIX;
						end
						else
						begin

							`ifdef HALFRAM
								if (!doneROM && !writeaddr[0])
									ram_wren <= 1'b1;
							`else
								if (!doneROM)
									ram_wren <= 1'b1;
							`endif
						end
					end
				end
				R_MIX: begin




					mcount <= mcount + 5'd1;
					if (mcount == 0)
					begin
						`ifdef HALFRAM
							if (oddAddr)
							begin
								X0Save <= X0;
								X0 <= ramout[511:0];
								X1Save <= X1;
								X1 <= ramout[1023:512];
								mixfeedback <= 0;
								mstate <= R_INT;
							end
							else
							begin

								mixfeedback <= 1'b0;
								X0 <= X0 ^ ramout[511:0];
								X1 <= X1 ^ ramout[1023:512];
							end
						`else

							mixfeedback <= 1'b0;
							 X0 <= X0 ^ ramout[511:0];
							 X1 <= X1 ^ ramout[1023:512];
						`endif
					end
					if (mcount==1 || mcount==5)
						mixfeedback <= 1;
					if (mcount == 4 || mcount == 8)
					begin
						mixfeedback <= 1'b0;
						X0 <= X1;
						X1 <= Xmix;
					end
					if (mcount == 8)
					begin
						mcount <= 0;
						cycle <= cycle + 11'd1;
						if (cycle == 1023)
						begin

							MixOut <= { Xmix, X1 };


							Set_SMixOutRdy <= 1'b1;
							nonce_2 <= nonce_1;
							mstate <= R_IDLE;
						end
					end
				end
				`ifdef HALFRAM
				R_INT: begin


					mcount <= mcount + 6'd1;
					if (mcount==1 || mcount==5)
						mixfeedback <= 1'b1;
					if (mcount == 4)
					begin
						mixfeedback <= 0;
						X0 <= X1;
						X1 <= Xmix;
					end
					if (mcount == 8)
					begin
						mixfeedback <= 0;
						X0 <= X1 ^ X0Save;
						X1 <= Xmix ^ X1Save;
						mcount <= 1;
						mstate <= R_MIX;
					end
				end
				`endif
			endcase
		end
	end

endmodule
module hashcore (hash_clk, data1, data2, data3, target, nonce_msb, nonce_out, golden_nonce_out, golden_nonce_match, loadnonce);


	input hash_clk;
	input [255:0] data1;
	input [255:0] data2;
	input [127:0] data3;
	input [31:0] target;
	input [3:0] nonce_msb;
	output [31:0] nonce_out;
	output [31:0] golden_nonce_out;
	output golden_nonce_match;
	input loadnonce;
	
	reg poweron_reset = 1'b1;
	reg reset = 1'b1;

	always @ (posedge hash_clk)
	begin
		poweron_reset <= 1'b0;
		reset <= poweron_reset;
	end
	
	`ifndef ICARUS
	reg [31:0] nonce_prevous_load = 32'hffffffff;
	`endif

	`ifndef NOMULTICORE
		reg [27:0] nonce_cnt = 28'd0;
		wire [31:0] nonce;
		assign nonce = { nonce_msb, nonce_cnt };
	`else
		reg [31:0] nonce = 32'd0;
	`endif

	assign nonce_out = nonce;

	reg [31:0] nonce_1 = 32'd0;
	reg [31:0] nonce_2 = 32'd0;
	reg [31:0] golden_nonce = 32'd0;
	assign golden_nonce_out = golden_nonce;
	reg golden_nonce_match = 1'b0;
	
	reg [255:0] rx_state;
	reg [511:0] rx_input;
	wire [255:0] tx_hash;
	reg [255:0] khash = 256'd0;
	reg [255:0] ihash = 256'd0;
	reg [255:0] ohash = 256'd0;
	`ifdef SIM
		reg [255:0] final_hash = 256'd0;
	`endif
	reg [31:0] blockcnt = 32'd0;
	reg [1023:0] Xbuf = 1024'd0;
	reg [1023:0] MixOut;
	wire [1023:0] MixOutRewire;
	reg [5:0] cnt = 6'd0;
	wire feedback;
	assign feedback = (cnt != 6'b0);
	


	sha256_transform  # (.LOOP(64)) sha256_blk (
		.clk(hash_clk),
		.feedback(feedback),
		.cnt(cnt),
		.rx_state(rx_state),
		.rx_input(rx_input),
		.tx_hash(tx_hash)
	);



	





	reg SMixInRdy_state = 1'b0;
	reg SMixOutRdy_state = 1'b0;
	wire SMixInRdy;
	wire SMixOutRdy;

	reg Set_SMixInRdy = 1'b0;
	reg Clr_SMixInRdy = 1'b0;
	reg Set_SMixOutRdy = 1'b0;
	reg Clr_SMixOutRdy = 1'b0;
	
	always @ (posedge hash_clk)
	begin
		if (Set_SMixInRdy)
			SMixInRdy_state <= 1'b1;
		if (Clr_SMixInRdy)
			SMixInRdy_state <= 1'b0;
		if (Set_SMixOutRdy)
			SMixOutRdy_state <= 1'b1;
		if (Clr_SMixOutRdy)
			SMixOutRdy_state <= 1'b0;
	end
	

	assign SMixInRdy = Clr_SMixInRdy ? 1'b0 : Set_SMixInRdy ? 1'b1 : SMixInRdy_state;
	assign SMixOutRdy = Clr_SMixOutRdy ? 1'b0 : Set_SMixOutRdy ? 1'b1 : SMixOutRdy_state;
		



	



	
	parameter	S_IDLE=0,
				S_H1= 1, S_H2= 2, S_H3= 3, S_H4= 4, S_H5= 5, S_H6= 6,
				S_I1= 7, S_I2= 8, S_I3= 9, S_I4=10, S_I5=11, S_I6=12,
				S_O1=13, S_O2=14, S_O3=15,
				S_B1=16, S_B2=17, S_B3=18, S_B4=19, S_B5=20, S_B6=21,
				S_XX=22,

				S_R1=23, S_R2=24, S_R3=25, S_R4=26, S_R5=27, S_R6=28,
				S_R7=29, S_R8=30, S_R9=31, S_R10=32, S_R11=33, S_R12=34,
				S_R13=35, S_R14=36, S_R15=37, S_R16=38, S_R17=39, S_R18=40;
				
	reg [5:0] state = S_IDLE;
	reg mode = 0;
	always @ (posedge hash_clk)
	begin
		Set_SMixInRdy <= 1'b0;
		Clr_SMixOutRdy <= 1'b0;
		golden_nonce_match <= 1'b0;
		
		if (reset == 1'b1)
			state <= S_IDLE;
		else
		begin
			case (state)
				S_IDLE: begin
					if (SMixOutRdy ||
						!SMixInRdy)
					begin


						rx_state <= 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667;
						rx_input <= { data2, data1 };
						blockcnt <= 32'd1;
						cnt <= 6'd0;
						if (SMixOutRdy)
							mode <= 1'b1;
						else
							mode <= 1'b0;
						state <= S_H1;
					end
				end


				S_H1: begin
					cnt <= cnt + 6'd1;
					if (cnt == 6'd63)
					begin
						cnt <= 6'd0;
						state <= S_H2;
					end
				end
				S_H2: begin
						state <= S_H3;
				end
				S_H3: begin
						rx_state <= tx_hash;


						rx_input <= { 384'h000002800000000000000000000000000000000000000000000000000000000000000000000000000000000080000000,
										mode ? nonce_2 : nonce, data3[95:0] };
						state <= S_H4;
				end
				S_H4: begin
					cnt <= cnt + 6'd1;
					if (cnt == 6'd63)
					begin
						cnt <= 6'd0;
						state <= S_H5;
					end
				end
				S_H5: begin
						state <= S_H6;
				end
				S_H6: begin
						khash <= tx_hash;

						rx_state <= 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667;
						rx_input <= { 256'h3636363636363636363636363636363636363636363636363636363636363636 ,
										tx_hash ^ 256'h3636363636363636363636363636363636363636363636363636363636363636 };
						cnt <= 6'd0;
						if (mode)
							state <= S_R1;
						else
							state <= S_I1;
				end


				S_I1: begin
					cnt <= cnt + 6'd1;
					if (cnt == 6'd63)
					begin
						cnt <= 6'd0;
						state <= S_I2;
					end
				end
				S_I2: begin
						state <= S_I3;
				end
				S_I3: begin
						rx_state <= tx_hash;
						rx_input <= { data2, data1 };
						state <= S_I4;
				end
				S_I4: begin
					cnt <= cnt + 6'd1;
					if (cnt == 6'd63)
					begin
						cnt <= 6'd0;
						state <= S_I5;
					end
				end
				S_I5: begin
						state <= S_I6;
				end
				S_I6: begin
						ihash <= tx_hash;

						rx_state <= 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667;
						rx_input <= { 256'h5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c ,
										khash ^ 256'h5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c };
						cnt <= 6'd0;
						state <= S_O1;
				end


				S_O1: begin
					cnt <= cnt + 6'd1;
					if (cnt == 6'd63)
					begin
						cnt <= 6'd0;
						state <= S_O2;
					end
				end
				S_O2: begin
						state <= S_O3;
				end
				S_O3: begin
						ohash <= tx_hash;

						rx_state <= ihash;

						rx_input <= { 352'h000004a000000000000000000000000000000000000000000000000000000000000000000000000080000000,
										blockcnt, nonce, data3[95:0] };
						blockcnt <= blockcnt + 1;
						cnt <= 6'd0;
						state <= S_B1;
				end


				S_B1: begin
					cnt <= cnt + 6'd1;
					if (cnt == 6'd63)
					begin
						cnt <= 6'd0;
						state <= S_B2;
					end
				end
				S_B2: begin
						state <= S_B3;
				end
				S_B3: begin
						rx_state <= ohash;
						rx_input <= { 256'h0000030000000000000000000000000000000000000000000000000080000000, tx_hash };
						state <= S_B4;
				end
				S_B4: begin
					cnt <= cnt + 6'd1;
					if (cnt == 6'd63)
					begin
						cnt <= 6'd0;
						state <= S_B5;
					end
				end
				S_B5: begin
						state <= S_B6;
				end
				S_B6: begin
						Xbuf[255:0] <= Xbuf[511:256];
						Xbuf[511:256] <= Xbuf[767:512];
						Xbuf[767:512] <= Xbuf[1023:768];
						Xbuf[1023:768] <= tx_hash;


						if (blockcnt == 5)
							state <= S_XX;
						else begin

							rx_state <= ihash;
							rx_input <= { 352'h000004a000000000000000000000000000000000000000000000000000000000000000000000000080000000,
											blockcnt, nonce, data3[95:0] };
							blockcnt <= blockcnt + 1;
							cnt <= 6'd0;
							state <= S_B1;
						end
				end
				S_XX: begin


						Set_SMixInRdy <= 1;
						state <= S_IDLE;
				end
				


				S_R1: begin
					cnt <= cnt + 6'd1;
					if (cnt == 6'd63)
					begin
						cnt <= 6'd0;
						state <= S_R2;
					end
				end
				S_R2: begin
						state <= S_R3;
				end
				S_R3: begin
						rx_state <= tx_hash;
						rx_input <= MixOutRewire[511:0];
						state <= S_R4;
				end
				S_R4: begin
					cnt <= cnt + 6'd1;
					if (cnt == 6'd63)
					begin
						cnt <= 6'd0;
						state <= S_R5;
					end
				end
				S_R5: begin
						state <= S_R6;
				end
				S_R6: begin
						rx_state <= tx_hash;
						rx_input <= MixOutRewire[1023:512];
						state <= S_R7;
				end
				S_R7: begin
					cnt <= cnt + 6'd1;
					if (cnt == 6'd63)
					begin
						cnt <= 6'd0;
						state <= S_R8;
					end
				end
				S_R8: begin
						state <= S_R9;
				end
				S_R9: begin
						rx_state <= tx_hash;

						rx_input <= 512'h00000620000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000001;
						state <= S_R10;
				end
				S_R10: begin
					cnt <= cnt + 6'd1;
					if (cnt == 6'd63)
					begin
						cnt <= 6'd0;
						state <= S_R11;
					end
				end
				S_R11: begin
						state <= S_R12;
				end
				S_R12: begin
						ihash <= tx_hash;

						rx_state <= 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667;
						rx_input <= { 256'h5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c ,
										khash ^ 256'h5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c };
						cnt <= 6'd0;
						state <= S_R13;
				end
				S_R13: begin
					cnt <= cnt + 6'd1;
					if (cnt == 6'd63)
					begin
						cnt <= 6'd0;
						state <= S_R14;
					end
				end
				S_R14: begin
						state <= S_R15;
				end
				S_R15: begin
						rx_state <= tx_hash;
						rx_input <= { 256'h0000030000000000000000000000000000000000000000000000000080000000, ihash };
						state <= S_R16;
				end
				S_R16: begin
					cnt <= cnt + 6'd1;
					if (cnt == 6'd63)
					begin
						cnt <= 6'd0;
						state <= S_R17;
					end
				end
				S_R17: begin
						state <= S_R18;
				end
				S_R18: begin

						`ifdef SIM
							final_hash <= tx_hash;
						`endif

						if ( { tx_hash[231:224], tx_hash[239:232], tx_hash[247:240], tx_hash[255:248] } < target)
						begin
							golden_nonce <= nonce_2;
							golden_nonce_match <= 1'b1;
						end
						state <= S_IDLE;
						mode <= 0;

						Clr_SMixOutRdy <= 1'b1;
				end
			endcase	
		end
	end




	wire [1023:0] X;
	`define IDX(x) (((x)+1)*(32)-1):((x)*(32))
	genvar i;
	generate
	for (i = 0; i < 32; i = i + 1) begin : Xrewire
		wire [31:0] tmp;
		assign tmp = Xbuf[`IDX(i)];
		assign X[`IDX(i)] = { tmp[7:0], tmp[15:8], tmp[23:16], tmp[31:24] };


		wire [31:0] mix;
		assign mix = MixOut[`IDX(i)];
		assign MixOutRewire[`IDX(i)] = { mix[7:0], mix[15:8], mix[23:16], mix[31:24] };
	end
	endgenerate









	parameter R_IDLE=0, R_WRITE=1, R_MIX=2, R_INT=3;
	reg [1:0] mstate = R_IDLE;
	reg [10:0] cycle = 11'd0;
	reg [5:0] mcount = 5'd0;
	reg doneROM = 1'd0;
	reg mixfeedback = 1'b0;
	reg addrsourceMix = 1'b0;

	reg [511:0] X0;
	reg [511:0] X1;
	`ifdef HALFRAM
		reg [511:0] X0Save;
		reg [511:0] X1Save;
		reg	oddAddr = 1'b0;
	`endif
	wire [511:0] Xmix;


	reg [9:0] writeaddr = 10'd0;
	



	
	`ifdef HALFRAM
		parameter ADDRBITS = 9;
	`else
		parameter ADDRBITS = 10;
	`endif

	wire [ADDRBITS-1:0]ram_addr;
	wire [255:0]ram1_din;
	wire [255:0]ram1_dout;
	wire [255:0]ram2_din;
	wire [255:0]ram2_dout;
	wire [255:0]ram3_din;
	wire [255:0]ram3_dout;
	wire [255:0]ram4_din;
	wire [255:0]ram4_dout;
	wire [1023:0]ramout;

	reg ram_wren;
	wire ram_clk;
	assign ram_clk = hash_clk;
	
	`ifdef HALFRAM

		assign ram_addr = addrsourceMix ? Xmix[9:1] : writeaddr[9:1];
	`else

		assign ram_addr = addrsourceMix ? Xmix[9:0] : writeaddr;
	`endif
	ram # (.ADDRBITS(ADDRBITS)) ram1_blk (ram_addr, ram_clk, ram1_din, ram_wren, ram1_dout);
	ram # (.ADDRBITS(ADDRBITS)) ram2_blk (ram_addr, ram_clk, ram2_din, ram_wren, ram2_dout);
	ram # (.ADDRBITS(ADDRBITS)) ram3_blk (ram_addr, ram_clk, ram3_din, ram_wren, ram3_dout);
	ram # (.ADDRBITS(ADDRBITS)) ram4_blk (ram_addr, ram_clk, ram4_din, ram_wren, ram4_dout);
	assign ramout = { ram4_dout, ram3_dout, ram2_dout, ram1_dout };
	assign { ram4_din, ram3_din, ram2_din, ram1_din } = { X1, X0} ;


	
	salsa salsa_blk (hash_clk, mixfeedback, X0, X1, Xmix);


	
	always @ (posedge hash_clk)
	begin
		Set_SMixOutRdy <= 1'b0;
		Clr_SMixInRdy <= 1'b0;
		`ifdef HALFRAM
			oddAddr <= Xmix[0];
		`endif
		`ifdef ICARUS
		if (loadnonce)
		`else
		if (loadnonce || (nonce_prevous_load != data3[127:96]))
		`endif
		begin
			`ifdef NOMULTICORE
				nonce <= data3[127:96];




			`else
				nonce_cnt <= data3[123:96];

			`endif
			`ifndef ICARUS
			nonce_prevous_load <= data3[127:96];
			`endif
		end
		if (reset == 1'b1)
			mstate <= R_IDLE;
		else
		begin
			case (mstate)
				R_IDLE: begin
					writeaddr <= 0;
					mcount <= 0;
					X0 <= X[511:0];
					X1 <= X[1023:512];
					mixfeedback <= 1'b0;
					addrsourceMix <= 1'b0;
					if (SMixInRdy)
						begin
							mstate <= R_WRITE;
							doneROM <= 1'b0;
							ram_wren <= 1'b1;

							Clr_SMixInRdy <= 1;

							nonce_1 <= nonce;
							`ifndef NOMULTICORE
								nonce_cnt <= nonce_cnt + 28'd1;
							`else
								nonce <= nonce + 32'd1;
							`endif
						end
				end
				R_WRITE: begin
					mcount <= mcount + 6'd1;
					ram_wren <= 0;





					if (mcount==0)
					begin
						mixfeedback <= 1'b1;
						if (writeaddr==1023)
							doneROM <= 1'b1;
						writeaddr <= writeaddr + 10'd1;
					end
					if (mcount==4)
						mixfeedback <= 1'b1;
					if (mcount == 3 || mcount == 7)
					begin
						X0 <= X1;
						X1 <= Xmix;
						mixfeedback <= 1'b0;
					end
					if (mcount == 6 && doneROM)
						addrsourceMix <= 1'b1;
					if (mcount == 7)
					begin
						mcount <= 0;
						if (doneROM)
						begin
							cycle <= 0;
							mstate <= R_MIX;
						end
						else
						begin

							`ifdef HALFRAM
								if (!doneROM && !writeaddr[0])
									ram_wren <= 1'b1;
							`else
								if (!doneROM)
									ram_wren <= 1'b1;
							`endif
						end
					end
				end
				R_MIX: begin




					mcount <= mcount + 5'd1;
					if (mcount == 0)
					begin
						`ifdef HALFRAM
							if (oddAddr)
							begin
								X0Save <= X0;
								X0 <= ramout[511:0];
								X1Save <= X1;
								X1 <= ramout[1023:512];
								mixfeedback <= 0;
								mstate <= R_INT;
							end
							else
							begin

								mixfeedback <= 1'b0;
								X0 <= X0 ^ ramout[511:0];
								X1 <= X1 ^ ramout[1023:512];
							end
						`else

							mixfeedback <= 1'b0;
							 X0 <= X0 ^ ramout[511:0];
							 X1 <= X1 ^ ramout[1023:512];
						`endif
					end
					if (mcount==1 || mcount==5)
						mixfeedback <= 1;
					if (mcount == 4 || mcount == 8)
					begin
						mixfeedback <= 1'b0;
						X0 <= X1;
						X1 <= Xmix;
					end
					if (mcount == 8)
					begin
						mcount <= 0;
						cycle <= cycle + 11'd1;
						if (cycle == 1023)
						begin

							MixOut <= { Xmix, X1 };


							Set_SMixOutRdy <= 1'b1;
							nonce_2 <= nonce_1;
							mstate <= R_IDLE;
						end
					end
				end
				`ifdef HALFRAM
				R_INT: begin


					mcount <= mcount + 6'd1;
					if (mcount==1 || mcount==5)
						mixfeedback <= 1'b1;
					if (mcount == 4)
					begin
						mixfeedback <= 0;
						X0 <= X1;
						X1 <= Xmix;
					end
					if (mcount == 8)
					begin
						mixfeedback <= 0;
						X0 <= X1 ^ X0Save;
						X1 <= Xmix ^ X1Save;
						mcount <= 1;
						mstate <= R_MIX;
					end
				end
				`endif
			endcase
		end
	end

endmodule