data/full_repos/permissive/143584361/projects/aFPGA/00_user_logic/parser/cmd_parser.v
data/verilator_xmls/deff3c0a-ef6d-423f-a30a-14dce0f6a8f9.xml
module cmd_parser
#(	
	parameter	UART_DATA_WIDTH = 8,
	parameter	UART_ADDR_WIDTH = 2,
	parameter	SYS_UART_DATA_MULT = 4,
	parameter	SYS_DATA_WIDTH = UART_DATA_WIDTH*SYS_UART_DATA_MULT
)
(
	output	wire						receive_valid_cmd,
	input	wire						sys_clk, sys_rst_n,
	input	wire	[5:1]				sys_key_fn,

	input	wire [SYS_DATA_WIDTH-1:0]	adc_ddr_write_addr,
	input	wire [SYS_DATA_WIDTH-1:0]	adc_ddr_write_addr_mask,

	output	reg							audio_sample_en,

	output	reg	[SYS_DATA_WIDTH-1:0]	npu_inst_part,
	output	reg							npu_inst_part_en,	

	output	reg	[SYS_DATA_WIDTH-1:0]	sys_uart_write_data,
	output	reg							sys_uart_write_data_valid,
	input								sys_uart_write_data_permitted,
	input		[UART_DATA_WIDTH-1:0]	sys_uart_read_data,
	output	reg							sys_uart_read_data_req,
	input								sys_uart_read_data_permitted,

	output	reg	[SYS_DATA_WIDTH-1:0]	sys_ddr_write_addr,
	output	reg	[SYS_DATA_WIDTH-1:0]	sys_ddr_write_data,
	output	reg							sys_ddr_write_data_valid,
	output	reg							sys_ddr_write_burst_begin,
	input								sys_ddr_write_data_permitted,
	output	reg	[SYS_DATA_WIDTH-1:0]	sys_ddr_read_addr,
	input		[SYS_DATA_WIDTH-1:0]	sys_ddr_read_data,
	input								sys_ddr_read_data_valid,
	output	reg							sys_ddr_read_burst_begin,
	output	reg							sys_ddr_read_data_req,
	input								sys_ddr_read_data_permitted
);
	


reg		[3:0]	read_cnt;
reg		[127:0]	uart_cmd_shift;
always @(posedge sys_clk)
	if(!sys_rst_n)
	begin
		uart_cmd_shift <= 0;
		read_cnt <= 0;
	end
	else 
	begin
		case(read_cnt)

			0: begin
				if(sys_uart_read_data_permitted)
				begin
					read_cnt <= 1;
					sys_uart_read_data_req <= 0;
				end
			end
			

			1: begin
				read_cnt <= 2;
				uart_cmd_shift <= {uart_cmd_shift[119:0], 
									sys_uart_read_data[7:0]
								};
				sys_uart_read_data_req <= 1;
			end
			

			2: begin
				read_cnt <= 3;
				sys_uart_read_data_req <= 0;
			end
			

			3: 	read_cnt <= 0;
			
			default:
				read_cnt <= 0;
		endcase
	end





	reg		[31:0]		send_back_cnt;
	
	reg					test_uart_cmd;
	reg					read_ddr_cmd;
	reg					write_ddr_cmd;
	reg					cont_read_cmd;
	reg					cont_write_cmd;
	reg					adc_read_cmd;
	reg					audio_sample_cmd;
	reg					measure_ram_cmd;
	reg					npu_inst_cmd;
	always @(posedge sys_clk)
	begin
		test_uart_cmd <= (uart_cmd_shift[79:40]==40'H68656C6C6F && (read_cnt==3));	
		read_ddr_cmd <= (uart_cmd_shift[79:40]==40'H725F646472 && (read_cnt==3));
		write_ddr_cmd <= (uart_cmd_shift[111:72]==40'H775F646472 && (read_cnt==3));
		cont_read_cmd <= (uart_cmd_shift[111:72]==40'H636F6E7472  && (read_cnt==3));
		cont_write_cmd <= (uart_cmd_shift[111:72]==40'H636F6E7477 && (read_cnt==3));
		adc_read_cmd <= (uart_cmd_shift[111:72]==40'H6372616463 && (read_cnt==3));
		audio_sample_cmd <= (uart_cmd_shift[79:40]==40'H617564696F && (read_cnt==3));
		measure_ram_cmd <= (uart_cmd_shift[111:72]==40'H6D73646472 && (read_cnt==3));
		npu_inst_cmd <= (uart_cmd_shift[79:40]==40'H6E70757374 && (read_cnt==3));
	end
	
	assign				receive_valid_cmd = (npu_inst_cmd|test_uart_cmd|read_ddr_cmd|write_ddr_cmd|cont_read_cmd|cont_write_cmd|adc_read_cmd|audio_sample_cmd|measure_ram_cmd);
	reg		[8:0]		receive_cmd_type;
	always @(posedge sys_clk)
		if(receive_valid_cmd)
			receive_cmd_type <= {npu_inst_cmd, measure_ram_cmd, audio_sample_cmd, adc_read_cmd, cont_write_cmd, cont_read_cmd, write_ddr_cmd, read_ddr_cmd, test_uart_cmd};
	



	reg		[SYS_DATA_WIDTH-1:0]	sys_ddr_read_data_reg;
	reg								sys_ddr_read_data_valid_reg;
	always @(posedge sys_clk)
	begin
		sys_ddr_read_data_reg <= sys_ddr_read_data;
		sys_ddr_read_data_valid_reg <= sys_ddr_read_data_valid;
	end


	reg		[127:0]		uart_cmd_shift_reg;
	always @(posedge sys_clk)
		if(receive_valid_cmd)
			uart_cmd_shift_reg <= uart_cmd_shift;

	reg		sys_uart_write_data_permitted_reg;
	always @(posedge sys_clk)
		sys_uart_write_data_permitted_reg <= sys_uart_write_data_permitted;
	





	reg		[4:0]		ddr_wr_state;
	reg		[31:0]		ddr_wr_number;
	reg		[31:0]		ddr_wr_time;
	always @(posedge sys_clk)
		if(!sys_rst_n)
		begin
			sys_ddr_read_data_req <= 0;
			sys_ddr_write_data_valid <= 0;
			sys_ddr_read_burst_begin <= 0;
			sys_ddr_write_burst_begin <= 0;
			ddr_wr_state <= 0;

			audio_sample_en <= 0;		

			npu_inst_part_en <= 0;
		end
		else
		begin
			case(ddr_wr_state)
				0:	begin
					sys_ddr_read_data_req <= 0;
					sys_ddr_write_data_valid <= 0;
					sys_ddr_read_burst_begin <= 0;
					sys_ddr_write_burst_begin <= 0;

					npu_inst_part_en <= 0;


					if(read_ddr_cmd)
						ddr_wr_state <= 1;

					else if(write_ddr_cmd)
						ddr_wr_state <= 3;

					else if(cont_write_cmd)
					begin
						ddr_wr_state <= 5;
						ddr_wr_number <= 0;
					end

					else if(cont_read_cmd)
					begin
						ddr_wr_state <= 7;
						ddr_wr_number <= 0;
					end

					else if(adc_read_cmd)
					begin
						ddr_wr_state <= 10;
						ddr_wr_number <= 0;
					end

					else if(audio_sample_cmd)
					begin
						ddr_wr_state <= 13;
						ddr_wr_number <= 0;
						audio_sample_en <= 1;
					end

					else if(measure_ram_cmd)
					begin
						ddr_wr_state <= 14;
						ddr_wr_number <= 0;
						ddr_wr_time <= 0;
					end

					else if(npu_inst_cmd)
					begin
						ddr_wr_state <= 18;
					end
				end
				

				1: begin

					if(sys_ddr_read_data_permitted)
					begin	
						sys_ddr_read_addr <= uart_cmd_shift_reg[39:8];
						sys_ddr_read_data_req <= 1;
						sys_ddr_read_burst_begin <= 1;
						ddr_wr_state <= 2;
					end
				end
				
				2: begin
					sys_ddr_read_burst_begin <= 0;

					if(sys_ddr_read_data_permitted)
					begin	

						sys_ddr_read_data_req <= 0;
						ddr_wr_state <= 0;
					end
				end	
					

				3: begin

					if(sys_ddr_write_data_permitted)
					begin
						sys_ddr_write_addr <= uart_cmd_shift_reg[71:40];
						sys_ddr_write_data <= uart_cmd_shift_reg[39:8];
						sys_ddr_write_data_valid <= 1;
						sys_ddr_write_burst_begin <= 1;
						ddr_wr_state <= 4;
					end
				end
				
				4: begin
					sys_ddr_write_burst_begin <= 0;

					if(sys_ddr_write_data_permitted)
					begin	


						sys_ddr_write_data_valid <= 0;
						ddr_wr_state <= 0;
					end
				end	
				
				

				5: begin

					if(sys_ddr_write_data_permitted)
					begin
						sys_ddr_write_addr <= uart_cmd_shift_reg[71:40];
						sys_ddr_write_data <= uart_cmd_shift_reg[71:40];
						sys_ddr_write_data_valid <= 1;
						sys_ddr_write_burst_begin <= 1;
						ddr_wr_state <= 6;

						ddr_wr_number <= ddr_wr_number+1;
					end
				end
				
				6: begin
					sys_ddr_write_burst_begin <= 0;

					if(sys_ddr_write_data_permitted)
					begin	
						sys_ddr_write_addr <= sys_ddr_write_addr+1;
						sys_ddr_write_data <= sys_ddr_write_data+1;
						if(ddr_wr_number<uart_cmd_shift_reg[39:8])
						begin
							sys_ddr_write_data_valid <= 1;
							ddr_wr_number <= ddr_wr_number+1;
						end
						else 
						begin
							sys_ddr_write_data_valid <= 0;
							ddr_wr_state <= 0;
						end
					end
				end	
				

				7: begin

					if(sys_ddr_read_data_permitted)
					begin	
						sys_ddr_read_addr <= uart_cmd_shift_reg[71:40];
						sys_ddr_read_data_req <= 1;
						sys_ddr_read_burst_begin <= 1;
						ddr_wr_state <= 8;

						ddr_wr_number <= ddr_wr_number+1;
					end
				end
				
				8: begin
					sys_ddr_read_burst_begin <= 0;

					if(sys_ddr_read_data_permitted)
					begin	

						if(ddr_wr_number<uart_cmd_shift_reg[39:8])
						begin

							if(sys_uart_write_data_permitted_reg)
							begin
								sys_ddr_read_addr <= sys_ddr_read_addr+1;
								sys_ddr_read_data_req <= 1;

								ddr_wr_number <= ddr_wr_number+1;
							end


							else
							begin
								sys_ddr_read_data_req <= 0;
								ddr_wr_state <= 9;
							end
						end

						else 
						begin
							sys_ddr_read_data_req <= 0;
							ddr_wr_state <= 0;
						end
					end
				end	
				
				9: begin

					if(sys_uart_write_data_permitted_reg)
					begin	
						sys_ddr_read_addr <= sys_ddr_read_addr+1;
						sys_ddr_read_data_req <= 1;
						sys_ddr_read_burst_begin <= 1;
						ddr_wr_state <= 8;

						ddr_wr_number <= ddr_wr_number+1;
					end
				end

				

				10: begin

					if(sys_ddr_read_data_permitted)
					begin	
						sys_ddr_read_addr <= ((adc_ddr_write_addr-uart_cmd_shift_reg[39:8])&adc_ddr_write_addr_mask);
						sys_ddr_read_data_req <= 1;
						sys_ddr_read_burst_begin <= 1;
						ddr_wr_state <= 11;

						ddr_wr_number <= ddr_wr_number+1;
					end
				end
				
				11: begin
					sys_ddr_read_burst_begin <= 0;

					if(sys_ddr_read_data_permitted)
					begin	

						if(ddr_wr_number<uart_cmd_shift_reg[39:8])
						begin

							if(sys_uart_write_data_permitted_reg)
							begin
								sys_ddr_read_addr <= ((sys_ddr_read_addr+1)&adc_ddr_write_addr_mask);
								sys_ddr_read_data_req <= 1;

								ddr_wr_number <= ddr_wr_number+1;
							end


							else
							begin
								sys_ddr_read_data_req <= 0;
								ddr_wr_state <= 12;
							end
						end

						else 
						begin
							sys_ddr_read_data_req <= 0;
							ddr_wr_state <= 0;
						end
					end
				end	
				
				12: begin

					if(sys_uart_write_data_permitted_reg)
					begin	
						sys_ddr_read_addr <= ((sys_ddr_read_addr+1)&adc_ddr_write_addr_mask);
						sys_ddr_read_data_req <= 1;
						sys_ddr_read_burst_begin <= 1;
						ddr_wr_state <= 11;

						ddr_wr_number <= ddr_wr_number+1;
					end
				end
				
				13: begin

					if(ddr_wr_number>=uart_cmd_shift_reg[39:8])
					begin
						audio_sample_en <= 0;
						ddr_wr_number <= 0;
						ddr_wr_state <= 0;
					end
					else
						ddr_wr_number <= ddr_wr_number + 1;
				end
				

				14: begin
					ddr_wr_time <= ddr_wr_time + 1;

					if(sys_ddr_write_data_permitted)
					begin
						sys_ddr_write_addr <= uart_cmd_shift_reg[71:40];
						sys_ddr_write_data <= uart_cmd_shift_reg[71:40];
						sys_ddr_write_data_valid <= 1;
						ddr_wr_state <= 15;

						ddr_wr_number <= ddr_wr_number+1;
					end
				end
				
				15: begin
					ddr_wr_time <= ddr_wr_time + 1;

					if(sys_ddr_write_data_permitted)
					begin	
						sys_ddr_write_addr <= sys_ddr_write_addr+1;
						sys_ddr_write_data <= sys_ddr_write_data+1;
						if(ddr_wr_number<uart_cmd_shift_reg[39:8])
						begin
							sys_ddr_write_data_valid <= 1;
							ddr_wr_number <= ddr_wr_number+1;
						end
						else 
						begin
							sys_ddr_write_data_valid <= 0;
							ddr_wr_state <= 16;
							ddr_wr_number <= 0;
						end
					end
				end	
				
				16: begin
					ddr_wr_time <= ddr_wr_time + 1;

					if(sys_ddr_read_data_permitted)
					begin
						sys_ddr_read_addr <= uart_cmd_shift_reg[71:40];
						sys_ddr_read_data_req <= 1;
						ddr_wr_state <= 17;

						ddr_wr_number <= ddr_wr_number+1;
					end
				end
				
				17: begin
					ddr_wr_time <= ddr_wr_time + 1;

					if(sys_ddr_read_data_permitted)
					begin	
						sys_ddr_read_addr <= sys_ddr_read_addr+1;
						if(ddr_wr_number<uart_cmd_shift_reg[39:8])
						begin
							sys_ddr_read_data_req <= 1;
							ddr_wr_number <= ddr_wr_number+1;
						end
						else 
						begin
							sys_ddr_read_data_req <= 0;
							ddr_wr_state <= 0;
						end
					end
				end	
				

				18: begin
					npu_inst_part <= uart_cmd_shift_reg[39:8];
					npu_inst_part_en <= 1;
					ddr_wr_state <= 0;
				end

				
				default: begin
					sys_ddr_read_data_req <= 0;
					sys_ddr_write_data_valid <= 0;
					sys_ddr_read_burst_begin <= 0;
					sys_ddr_write_burst_begin <= 0;
					ddr_wr_state <= 0;
				end
			endcase
		end



reg		[4:0]	pkt_state;
reg		[31:0]	pkt_cnt;
always @(posedge sys_clk)
	if(!sys_rst_n)
	begin
		pkt_state <= 0;
		sys_uart_write_data_valid <= 0;
	end
	else
	begin
		case(pkt_state)
			0: begin
				sys_uart_write_data_valid <= 0;
				if(test_uart_cmd)
				begin
					pkt_cnt <= 0;
					pkt_state <= 1;
				end
				else if(read_ddr_cmd)
				begin
					pkt_cnt <= 0;
					pkt_state <= 2;
				end
				else if(write_ddr_cmd)
				begin
					pkt_cnt <= 0;
					pkt_state <= 3;
				end
				else if(cont_read_cmd)
				begin
					pkt_cnt <= 0;
					pkt_state <= 4;
				end
				else if(cont_write_cmd)
				begin
					pkt_cnt <= 0;
					pkt_state <= 5;
				end
				else if(adc_read_cmd)
				begin
					pkt_cnt <= 0;
					pkt_state <= 6;
				end
				else if(audio_sample_cmd)
				begin
					pkt_cnt <= 0;
					pkt_state <= 7;
				end
				else if(measure_ram_cmd)
				begin
					pkt_cnt <= 0;
					pkt_state <= 8;
				end
				else if(npu_inst_cmd)
				begin
					pkt_cnt <= 0;
					pkt_state <= 11;
				end
			end
			

			1: begin
				if(pkt_cnt >= (uart_cmd_shift_reg[39:8]+3))
				begin
					pkt_state <= 0;
					sys_uart_write_data_valid <= 0;
				end
				else
				begin
					if(sys_uart_write_data_permitted_reg)
					begin
						if(pkt_cnt==0) 		sys_uart_write_data <= 32'H68656C6C;
						else if(pkt_cnt==1)	sys_uart_write_data <= 32'H6F776F72;
						else if(pkt_cnt==2)	sys_uart_write_data <= 32'H6C646868;
						else				sys_uart_write_data <= pkt_cnt-3;
						pkt_cnt <= pkt_cnt + 1;
					end
					sys_uart_write_data_valid <= sys_uart_write_data_permitted_reg;
				end
			end
			

			2 : begin
				if(pkt_cnt >= 2)
				begin
					pkt_state <= 0;
					sys_uart_write_data_valid <= 0;
				end
				else 
				begin
					if(pkt_cnt==0)
					begin
						if(sys_uart_write_data_permitted_reg)
						begin
							sys_uart_write_data <= 32'H72646472;
							pkt_cnt <= pkt_cnt + 1;
							sys_uart_write_data_valid <= 1;
						end
						else
							sys_uart_write_data_valid <= 0;
					end
					else if(sys_ddr_read_data_valid_reg)
					begin
						sys_uart_write_data <= sys_key_fn[2]? sys_ddr_read_data_reg : {sys_ddr_read_data_reg[15:0], sys_ddr_read_data_reg[31:16]};	
						pkt_cnt <= pkt_cnt + 1;
						sys_uart_write_data_valid <= 1;
					end
					else
						sys_uart_write_data_valid <= 0;
				end
			end
			

			3: begin
				if(pkt_cnt >= 1)
				begin
					pkt_state <= 0;
					sys_uart_write_data_valid <= 0;
				end
				else if(sys_uart_write_data_permitted_reg)
				begin
					sys_uart_write_data <= 32'H77646472;
					pkt_cnt <= pkt_cnt + 1;
					sys_uart_write_data_valid <= 1;
				end
				else
					sys_uart_write_data_valid <= 0;
			end
			

			4: begin
				if(pkt_cnt >= uart_cmd_shift_reg[39:8]+1)
				begin
					pkt_state <= 0;
					sys_uart_write_data_valid <= 0;
				end
				else 
				begin

					if(pkt_cnt==0)
					begin
						if(sys_uart_write_data_permitted_reg)
						begin
							sys_uart_write_data <= 32'H72636F6E;
							pkt_cnt <= pkt_cnt + 1;
							sys_uart_write_data_valid <= 1;
						end
						else
							sys_uart_write_data_valid <= 0;
					end
					else if(sys_ddr_read_data_valid_reg)
					begin
						sys_uart_write_data <= sys_key_fn[2]? sys_ddr_read_data_reg : {sys_ddr_read_data_reg[15:0], sys_ddr_read_data_reg[31:16]};	
						pkt_cnt <= pkt_cnt + 1;
						sys_uart_write_data_valid <= 1;
					end
					else
						sys_uart_write_data_valid <= 0;
				end
			end
			

			5: begin
				if(pkt_cnt >= 1)
				begin
					pkt_state <= 0;
					sys_uart_write_data_valid <= 0;
				end
				else if(sys_uart_write_data_permitted_reg)
				begin
					sys_uart_write_data <= 32'H77636F6E;
					pkt_cnt <= pkt_cnt + 1;
					sys_uart_write_data_valid <= 1;
				end
				else
					sys_uart_write_data_valid <= 0;
			end
			

			6: begin
				if(pkt_cnt >= uart_cmd_shift_reg[39:8]+1)
				begin
					pkt_state <= 0;
					sys_uart_write_data_valid <= 0;
				end
				else 
				begin

					if(pkt_cnt==0)
					begin
						if(sys_uart_write_data_permitted_reg)
						begin
							sys_uart_write_data <= 32'H72616463;
							pkt_cnt <= pkt_cnt + 1;
							sys_uart_write_data_valid <= 1;
						end
						else
							sys_uart_write_data_valid <= 0;
					end
					else if(sys_ddr_read_data_valid_reg)
					begin
						sys_uart_write_data <= sys_key_fn[2]? sys_ddr_read_data_reg : {sys_ddr_read_data_reg[15:0], sys_ddr_read_data_reg[31:16]};	
						pkt_cnt <= pkt_cnt + 1;
						sys_uart_write_data_valid <= 1;
					end
					else
						sys_uart_write_data_valid <= 0;
				end
			end

			7: begin
				if(pkt_cnt >= 1)
				begin
					pkt_state <= 0;
					sys_uart_write_data_valid <= 0;
				end
				else if(sys_uart_write_data_permitted_reg)
				begin
					sys_uart_write_data <= 32'H61756469;
					pkt_cnt <= pkt_cnt + 1;
					sys_uart_write_data_valid <= 1;
				end
				else
					sys_uart_write_data_valid <= 0;
			end

			8: begin

				if(ddr_wr_state>=15 && ddr_wr_number<=17)
				begin
					pkt_state <= 9;
					pkt_cnt <= 0;
				end
			end
			9: begin

				if(ddr_wr_state==0)
				begin
					pkt_state <= 10;
					pkt_cnt <= 0;
				end
			end
			10: begin

				if(pkt_cnt >= 2)
				begin
					pkt_state <= 0;
					sys_uart_write_data_valid <= 0;
				end

				else 
				begin
					if(pkt_cnt==0)
					begin
						if(sys_uart_write_data_permitted_reg)
						begin
							sys_uart_write_data <= 32'H6D646472;
							pkt_cnt <= pkt_cnt + 1;
							sys_uart_write_data_valid <= 1;
						end
					end
					else if(pkt_cnt == 1)
					begin
						if(sys_uart_write_data_permitted_reg)
						begin
							sys_uart_write_data <= ddr_wr_time;
							pkt_cnt <= pkt_cnt + 1;
							sys_uart_write_data_valid <= 1;
						end
					end
				end
			end

			11: begin
				if(pkt_cnt >= 1)
				begin
					pkt_state <= 0;
					sys_uart_write_data_valid <= 0;
				end
				else if(sys_uart_write_data_permitted_reg)
				begin
					sys_uart_write_data <= 32'H696e7374;
					pkt_cnt <= pkt_cnt + 1;
					sys_uart_write_data_valid <= 1;
				end
				else
					sys_uart_write_data_valid <= 0;
			end

			default: begin
				pkt_state <= 0;
				sys_uart_write_data_valid <= 0;
			end

		endcase
	end


endmodule
module cmd_parser
#(	
	parameter	UART_DATA_WIDTH = 8,
	parameter	UART_ADDR_WIDTH = 2,
	parameter	SYS_UART_DATA_MULT = 4,
	parameter	SYS_DATA_WIDTH = UART_DATA_WIDTH*SYS_UART_DATA_MULT
)
(
	output	wire						receive_valid_cmd,
	input	wire						sys_clk, sys_rst_n,
	input	wire	[5:1]				sys_key_fn,

	input	wire [SYS_DATA_WIDTH-1:0]	adc_ddr_write_addr,
	input	wire [SYS_DATA_WIDTH-1:0]	adc_ddr_write_addr_mask,

	output	reg							audio_sample_en,

	output	reg	[SYS_DATA_WIDTH-1:0]	npu_inst_part,
	output	reg							npu_inst_part_en,	

	output	reg	[SYS_DATA_WIDTH-1:0]	sys_uart_write_data,
	output	reg							sys_uart_write_data_valid,
	input								sys_uart_write_data_permitted,
	input		[UART_DATA_WIDTH-1:0]	sys_uart_read_data,
	output	reg							sys_uart_read_data_req,
	input								sys_uart_read_data_permitted,

	output	reg	[SYS_DATA_WIDTH-1:0]	sys_ddr_write_addr,
	output	reg	[SYS_DATA_WIDTH-1:0]	sys_ddr_write_data,
	output	reg							sys_ddr_write_data_valid,
	output	reg							sys_ddr_write_burst_begin,
	input								sys_ddr_write_data_permitted,
	output	reg	[SYS_DATA_WIDTH-1:0]	sys_ddr_read_addr,
	input		[SYS_DATA_WIDTH-1:0]	sys_ddr_read_data,
	input								sys_ddr_read_data_valid,
	output	reg							sys_ddr_read_burst_begin,
	output	reg							sys_ddr_read_data_req,
	input								sys_ddr_read_data_permitted
);

	


reg		[3:0]	read_cnt;
reg		[127:0]	uart_cmd_shift;
always @(posedge sys_clk)
	if(!sys_rst_n)
	begin
		uart_cmd_shift <= 0;
		read_cnt <= 0;
	end
	else 
	begin
		case(read_cnt)

			0: begin
				if(sys_uart_read_data_permitted)
				begin
					read_cnt <= 1;
					sys_uart_read_data_req <= 0;
				end
			end
			

			1: begin
				read_cnt <= 2;
				uart_cmd_shift <= {uart_cmd_shift[119:0], 
									sys_uart_read_data[7:0]
								};
				sys_uart_read_data_req <= 1;
			end
			

			2: begin
				read_cnt <= 3;
				sys_uart_read_data_req <= 0;
			end
			

			3: 	read_cnt <= 0;
			
			default:
				read_cnt <= 0;
		endcase
	end





	reg		[31:0]		send_back_cnt;
	
	reg					test_uart_cmd;
	reg					read_ddr_cmd;
	reg					write_ddr_cmd;
	reg					cont_read_cmd;
	reg					cont_write_cmd;
	reg					adc_read_cmd;
	reg					audio_sample_cmd;
	reg					measure_ram_cmd;
	reg					npu_inst_cmd;
	always @(posedge sys_clk)
	begin
		test_uart_cmd <= (uart_cmd_shift[79:40]==40'H68656C6C6F && (read_cnt==3));	
		read_ddr_cmd <= (uart_cmd_shift[79:40]==40'H725F646472 && (read_cnt==3));
		write_ddr_cmd <= (uart_cmd_shift[111:72]==40'H775F646472 && (read_cnt==3));
		cont_read_cmd <= (uart_cmd_shift[111:72]==40'H636F6E7472  && (read_cnt==3));
		cont_write_cmd <= (uart_cmd_shift[111:72]==40'H636F6E7477 && (read_cnt==3));
		adc_read_cmd <= (uart_cmd_shift[111:72]==40'H6372616463 && (read_cnt==3));
		audio_sample_cmd <= (uart_cmd_shift[79:40]==40'H617564696F && (read_cnt==3));
		measure_ram_cmd <= (uart_cmd_shift[111:72]==40'H6D73646472 && (read_cnt==3));
		npu_inst_cmd <= (uart_cmd_shift[79:40]==40'H6E70757374 && (read_cnt==3));
	end
	
	assign				receive_valid_cmd = (npu_inst_cmd|test_uart_cmd|read_ddr_cmd|write_ddr_cmd|cont_read_cmd|cont_write_cmd|adc_read_cmd|audio_sample_cmd|measure_ram_cmd);
	reg		[8:0]		receive_cmd_type;
	always @(posedge sys_clk)
		if(receive_valid_cmd)
			receive_cmd_type <= {npu_inst_cmd, measure_ram_cmd, audio_sample_cmd, adc_read_cmd, cont_write_cmd, cont_read_cmd, write_ddr_cmd, read_ddr_cmd, test_uart_cmd};
	



	reg		[SYS_DATA_WIDTH-1:0]	sys_ddr_read_data_reg;
	reg								sys_ddr_read_data_valid_reg;
	always @(posedge sys_clk)
	begin
		sys_ddr_read_data_reg <= sys_ddr_read_data;
		sys_ddr_read_data_valid_reg <= sys_ddr_read_data_valid;
	end


	reg		[127:0]		uart_cmd_shift_reg;
	always @(posedge sys_clk)
		if(receive_valid_cmd)
			uart_cmd_shift_reg <= uart_cmd_shift;

	reg		sys_uart_write_data_permitted_reg;
	always @(posedge sys_clk)
		sys_uart_write_data_permitted_reg <= sys_uart_write_data_permitted;
	





	reg		[4:0]		ddr_wr_state;
	reg		[31:0]		ddr_wr_number;
	reg		[31:0]		ddr_wr_time;
	always @(posedge sys_clk)
		if(!sys_rst_n)
		begin
			sys_ddr_read_data_req <= 0;
			sys_ddr_write_data_valid <= 0;
			sys_ddr_read_burst_begin <= 0;
			sys_ddr_write_burst_begin <= 0;
			ddr_wr_state <= 0;

			audio_sample_en <= 0;		

			npu_inst_part_en <= 0;
		end
		else
		begin
			case(ddr_wr_state)
				0:	begin
					sys_ddr_read_data_req <= 0;
					sys_ddr_write_data_valid <= 0;
					sys_ddr_read_burst_begin <= 0;
					sys_ddr_write_burst_begin <= 0;

					npu_inst_part_en <= 0;


					if(read_ddr_cmd)
						ddr_wr_state <= 1;

					else if(write_ddr_cmd)
						ddr_wr_state <= 3;

					else if(cont_write_cmd)
					begin
						ddr_wr_state <= 5;
						ddr_wr_number <= 0;
					end

					else if(cont_read_cmd)
					begin
						ddr_wr_state <= 7;
						ddr_wr_number <= 0;
					end

					else if(adc_read_cmd)
					begin
						ddr_wr_state <= 10;
						ddr_wr_number <= 0;
					end

					else if(audio_sample_cmd)
					begin
						ddr_wr_state <= 13;
						ddr_wr_number <= 0;
						audio_sample_en <= 1;
					end

					else if(measure_ram_cmd)
					begin
						ddr_wr_state <= 14;
						ddr_wr_number <= 0;
						ddr_wr_time <= 0;
					end

					else if(npu_inst_cmd)
					begin
						ddr_wr_state <= 18;
					end
				end
				

				1: begin

					if(sys_ddr_read_data_permitted)
					begin	
						sys_ddr_read_addr <= uart_cmd_shift_reg[39:8];
						sys_ddr_read_data_req <= 1;
						sys_ddr_read_burst_begin <= 1;
						ddr_wr_state <= 2;
					end
				end
				
				2: begin
					sys_ddr_read_burst_begin <= 0;

					if(sys_ddr_read_data_permitted)
					begin	

						sys_ddr_read_data_req <= 0;
						ddr_wr_state <= 0;
					end
				end	
					

				3: begin

					if(sys_ddr_write_data_permitted)
					begin
						sys_ddr_write_addr <= uart_cmd_shift_reg[71:40];
						sys_ddr_write_data <= uart_cmd_shift_reg[39:8];
						sys_ddr_write_data_valid <= 1;
						sys_ddr_write_burst_begin <= 1;
						ddr_wr_state <= 4;
					end
				end
				
				4: begin
					sys_ddr_write_burst_begin <= 0;

					if(sys_ddr_write_data_permitted)
					begin	


						sys_ddr_write_data_valid <= 0;
						ddr_wr_state <= 0;
					end
				end	
				
				

				5: begin

					if(sys_ddr_write_data_permitted)
					begin
						sys_ddr_write_addr <= uart_cmd_shift_reg[71:40];
						sys_ddr_write_data <= uart_cmd_shift_reg[71:40];
						sys_ddr_write_data_valid <= 1;
						sys_ddr_write_burst_begin <= 1;
						ddr_wr_state <= 6;

						ddr_wr_number <= ddr_wr_number+1;
					end
				end
				
				6: begin
					sys_ddr_write_burst_begin <= 0;

					if(sys_ddr_write_data_permitted)
					begin	
						sys_ddr_write_addr <= sys_ddr_write_addr+1;
						sys_ddr_write_data <= sys_ddr_write_data+1;
						if(ddr_wr_number<uart_cmd_shift_reg[39:8])
						begin
							sys_ddr_write_data_valid <= 1;
							ddr_wr_number <= ddr_wr_number+1;
						end
						else 
						begin
							sys_ddr_write_data_valid <= 0;
							ddr_wr_state <= 0;
						end
					end
				end	
				

				7: begin

					if(sys_ddr_read_data_permitted)
					begin	
						sys_ddr_read_addr <= uart_cmd_shift_reg[71:40];
						sys_ddr_read_data_req <= 1;
						sys_ddr_read_burst_begin <= 1;
						ddr_wr_state <= 8;

						ddr_wr_number <= ddr_wr_number+1;
					end
				end
				
				8: begin
					sys_ddr_read_burst_begin <= 0;

					if(sys_ddr_read_data_permitted)
					begin	

						if(ddr_wr_number<uart_cmd_shift_reg[39:8])
						begin

							if(sys_uart_write_data_permitted_reg)
							begin
								sys_ddr_read_addr <= sys_ddr_read_addr+1;
								sys_ddr_read_data_req <= 1;

								ddr_wr_number <= ddr_wr_number+1;
							end


							else
							begin
								sys_ddr_read_data_req <= 0;
								ddr_wr_state <= 9;
							end
						end

						else 
						begin
							sys_ddr_read_data_req <= 0;
							ddr_wr_state <= 0;
						end
					end
				end	
				
				9: begin

					if(sys_uart_write_data_permitted_reg)
					begin	
						sys_ddr_read_addr <= sys_ddr_read_addr+1;
						sys_ddr_read_data_req <= 1;
						sys_ddr_read_burst_begin <= 1;
						ddr_wr_state <= 8;

						ddr_wr_number <= ddr_wr_number+1;
					end
				end

				

				10: begin

					if(sys_ddr_read_data_permitted)
					begin	
						sys_ddr_read_addr <= ((adc_ddr_write_addr-uart_cmd_shift_reg[39:8])&adc_ddr_write_addr_mask);
						sys_ddr_read_data_req <= 1;
						sys_ddr_read_burst_begin <= 1;
						ddr_wr_state <= 11;

						ddr_wr_number <= ddr_wr_number+1;
					end
				end
				
				11: begin
					sys_ddr_read_burst_begin <= 0;

					if(sys_ddr_read_data_permitted)
					begin	

						if(ddr_wr_number<uart_cmd_shift_reg[39:8])
						begin

							if(sys_uart_write_data_permitted_reg)
							begin
								sys_ddr_read_addr <= ((sys_ddr_read_addr+1)&adc_ddr_write_addr_mask);
								sys_ddr_read_data_req <= 1;

								ddr_wr_number <= ddr_wr_number+1;
							end


							else
							begin
								sys_ddr_read_data_req <= 0;
								ddr_wr_state <= 12;
							end
						end

						else 
						begin
							sys_ddr_read_data_req <= 0;
							ddr_wr_state <= 0;
						end
					end
				end	
				
				12: begin

					if(sys_uart_write_data_permitted_reg)
					begin	
						sys_ddr_read_addr <= ((sys_ddr_read_addr+1)&adc_ddr_write_addr_mask);
						sys_ddr_read_data_req <= 1;
						sys_ddr_read_burst_begin <= 1;
						ddr_wr_state <= 11;

						ddr_wr_number <= ddr_wr_number+1;
					end
				end
				
				13: begin

					if(ddr_wr_number>=uart_cmd_shift_reg[39:8])
					begin
						audio_sample_en <= 0;
						ddr_wr_number <= 0;
						ddr_wr_state <= 0;
					end
					else
						ddr_wr_number <= ddr_wr_number + 1;
				end
				

				14: begin
					ddr_wr_time <= ddr_wr_time + 1;

					if(sys_ddr_write_data_permitted)
					begin
						sys_ddr_write_addr <= uart_cmd_shift_reg[71:40];
						sys_ddr_write_data <= uart_cmd_shift_reg[71:40];
						sys_ddr_write_data_valid <= 1;
						ddr_wr_state <= 15;

						ddr_wr_number <= ddr_wr_number+1;
					end
				end
				
				15: begin
					ddr_wr_time <= ddr_wr_time + 1;

					if(sys_ddr_write_data_permitted)
					begin	
						sys_ddr_write_addr <= sys_ddr_write_addr+1;
						sys_ddr_write_data <= sys_ddr_write_data+1;
						if(ddr_wr_number<uart_cmd_shift_reg[39:8])
						begin
							sys_ddr_write_data_valid <= 1;
							ddr_wr_number <= ddr_wr_number+1;
						end
						else 
						begin
							sys_ddr_write_data_valid <= 0;
							ddr_wr_state <= 16;
							ddr_wr_number <= 0;
						end
					end
				end	
				
				16: begin
					ddr_wr_time <= ddr_wr_time + 1;

					if(sys_ddr_read_data_permitted)
					begin
						sys_ddr_read_addr <= uart_cmd_shift_reg[71:40];
						sys_ddr_read_data_req <= 1;
						ddr_wr_state <= 17;

						ddr_wr_number <= ddr_wr_number+1;
					end
				end
				
				17: begin
					ddr_wr_time <= ddr_wr_time + 1;

					if(sys_ddr_read_data_permitted)
					begin	
						sys_ddr_read_addr <= sys_ddr_read_addr+1;
						if(ddr_wr_number<uart_cmd_shift_reg[39:8])
						begin
							sys_ddr_read_data_req <= 1;
							ddr_wr_number <= ddr_wr_number+1;
						end
						else 
						begin
							sys_ddr_read_data_req <= 0;
							ddr_wr_state <= 0;
						end
					end
				end	
				

				18: begin
					npu_inst_part <= uart_cmd_shift_reg[39:8];
					npu_inst_part_en <= 1;
					ddr_wr_state <= 0;
				end

				
				default: begin
					sys_ddr_read_data_req <= 0;
					sys_ddr_write_data_valid <= 0;
					sys_ddr_read_burst_begin <= 0;
					sys_ddr_write_burst_begin <= 0;
					ddr_wr_state <= 0;
				end
			endcase
		end



reg		[4:0]	pkt_state;
reg		[31:0]	pkt_cnt;
always @(posedge sys_clk)
	if(!sys_rst_n)
	begin
		pkt_state <= 0;
		sys_uart_write_data_valid <= 0;
	end
	else
	begin
		case(pkt_state)
			0: begin
				sys_uart_write_data_valid <= 0;
				if(test_uart_cmd)
				begin
					pkt_cnt <= 0;
					pkt_state <= 1;
				end
				else if(read_ddr_cmd)
				begin
					pkt_cnt <= 0;
					pkt_state <= 2;
				end
				else if(write_ddr_cmd)
				begin
					pkt_cnt <= 0;
					pkt_state <= 3;
				end
				else if(cont_read_cmd)
				begin
					pkt_cnt <= 0;
					pkt_state <= 4;
				end
				else if(cont_write_cmd)
				begin
					pkt_cnt <= 0;
					pkt_state <= 5;
				end
				else if(adc_read_cmd)
				begin
					pkt_cnt <= 0;
					pkt_state <= 6;
				end
				else if(audio_sample_cmd)
				begin
					pkt_cnt <= 0;
					pkt_state <= 7;
				end
				else if(measure_ram_cmd)
				begin
					pkt_cnt <= 0;
					pkt_state <= 8;
				end
				else if(npu_inst_cmd)
				begin
					pkt_cnt <= 0;
					pkt_state <= 11;
				end
			end
			

			1: begin
				if(pkt_cnt >= (uart_cmd_shift_reg[39:8]+3))
				begin
					pkt_state <= 0;
					sys_uart_write_data_valid <= 0;
				end
				else
				begin
					if(sys_uart_write_data_permitted_reg)
					begin
						if(pkt_cnt==0) 		sys_uart_write_data <= 32'H68656C6C;
						else if(pkt_cnt==1)	sys_uart_write_data <= 32'H6F776F72;
						else if(pkt_cnt==2)	sys_uart_write_data <= 32'H6C646868;
						else				sys_uart_write_data <= pkt_cnt-3;
						pkt_cnt <= pkt_cnt + 1;
					end
					sys_uart_write_data_valid <= sys_uart_write_data_permitted_reg;
				end
			end
			

			2 : begin
				if(pkt_cnt >= 2)
				begin
					pkt_state <= 0;
					sys_uart_write_data_valid <= 0;
				end
				else 
				begin
					if(pkt_cnt==0)
					begin
						if(sys_uart_write_data_permitted_reg)
						begin
							sys_uart_write_data <= 32'H72646472;
							pkt_cnt <= pkt_cnt + 1;
							sys_uart_write_data_valid <= 1;
						end
						else
							sys_uart_write_data_valid <= 0;
					end
					else if(sys_ddr_read_data_valid_reg)
					begin
						sys_uart_write_data <= sys_key_fn[2]? sys_ddr_read_data_reg : {sys_ddr_read_data_reg[15:0], sys_ddr_read_data_reg[31:16]};	
						pkt_cnt <= pkt_cnt + 1;
						sys_uart_write_data_valid <= 1;
					end
					else
						sys_uart_write_data_valid <= 0;
				end
			end
			

			3: begin
				if(pkt_cnt >= 1)
				begin
					pkt_state <= 0;
					sys_uart_write_data_valid <= 0;
				end
				else if(sys_uart_write_data_permitted_reg)
				begin
					sys_uart_write_data <= 32'H77646472;
					pkt_cnt <= pkt_cnt + 1;
					sys_uart_write_data_valid <= 1;
				end
				else
					sys_uart_write_data_valid <= 0;
			end
			

			4: begin
				if(pkt_cnt >= uart_cmd_shift_reg[39:8]+1)
				begin
					pkt_state <= 0;
					sys_uart_write_data_valid <= 0;
				end
				else 
				begin

					if(pkt_cnt==0)
					begin
						if(sys_uart_write_data_permitted_reg)
						begin
							sys_uart_write_data <= 32'H72636F6E;
							pkt_cnt <= pkt_cnt + 1;
							sys_uart_write_data_valid <= 1;
						end
						else
							sys_uart_write_data_valid <= 0;
					end
					else if(sys_ddr_read_data_valid_reg)
					begin
						sys_uart_write_data <= sys_key_fn[2]? sys_ddr_read_data_reg : {sys_ddr_read_data_reg[15:0], sys_ddr_read_data_reg[31:16]};	
						pkt_cnt <= pkt_cnt + 1;
						sys_uart_write_data_valid <= 1;
					end
					else
						sys_uart_write_data_valid <= 0;
				end
			end
			

			5: begin
				if(pkt_cnt >= 1)
				begin
					pkt_state <= 0;
					sys_uart_write_data_valid <= 0;
				end
				else if(sys_uart_write_data_permitted_reg)
				begin
					sys_uart_write_data <= 32'H77636F6E;
					pkt_cnt <= pkt_cnt + 1;
					sys_uart_write_data_valid <= 1;
				end
				else
					sys_uart_write_data_valid <= 0;
			end
			

			6: begin
				if(pkt_cnt >= uart_cmd_shift_reg[39:8]+1)
				begin
					pkt_state <= 0;
					sys_uart_write_data_valid <= 0;
				end
				else 
				begin

					if(pkt_cnt==0)
					begin
						if(sys_uart_write_data_permitted_reg)
						begin
							sys_uart_write_data <= 32'H72616463;
							pkt_cnt <= pkt_cnt + 1;
							sys_uart_write_data_valid <= 1;
						end
						else
							sys_uart_write_data_valid <= 0;
					end
					else if(sys_ddr_read_data_valid_reg)
					begin
						sys_uart_write_data <= sys_key_fn[2]? sys_ddr_read_data_reg : {sys_ddr_read_data_reg[15:0], sys_ddr_read_data_reg[31:16]};	
						pkt_cnt <= pkt_cnt + 1;
						sys_uart_write_data_valid <= 1;
					end
					else
						sys_uart_write_data_valid <= 0;
				end
			end

			7: begin
				if(pkt_cnt >= 1)
				begin
					pkt_state <= 0;
					sys_uart_write_data_valid <= 0;
				end
				else if(sys_uart_write_data_permitted_reg)
				begin
					sys_uart_write_data <= 32'H61756469;
					pkt_cnt <= pkt_cnt + 1;
					sys_uart_write_data_valid <= 1;
				end
				else
					sys_uart_write_data_valid <= 0;
			end

			8: begin

				if(ddr_wr_state>=15 && ddr_wr_number<=17)
				begin
					pkt_state <= 9;
					pkt_cnt <= 0;
				end
			end
			9: begin

				if(ddr_wr_state==0)
				begin
					pkt_state <= 10;
					pkt_cnt <= 0;
				end
			end
			10: begin

				if(pkt_cnt >= 2)
				begin
					pkt_state <= 0;
					sys_uart_write_data_valid <= 0;
				end

				else 
				begin
					if(pkt_cnt==0)
					begin
						if(sys_uart_write_data_permitted_reg)
						begin
							sys_uart_write_data <= 32'H6D646472;
							pkt_cnt <= pkt_cnt + 1;
							sys_uart_write_data_valid <= 1;
						end
					end
					else if(pkt_cnt == 1)
					begin
						if(sys_uart_write_data_permitted_reg)
						begin
							sys_uart_write_data <= ddr_wr_time;
							pkt_cnt <= pkt_cnt + 1;
							sys_uart_write_data_valid <= 1;
						end
					end
				end
			end

			11: begin
				if(pkt_cnt >= 1)
				begin
					pkt_state <= 0;
					sys_uart_write_data_valid <= 0;
				end
				else if(sys_uart_write_data_permitted_reg)
				begin
					sys_uart_write_data <= 32'H696e7374;
					pkt_cnt <= pkt_cnt + 1;
					sys_uart_write_data_valid <= 1;
				end
				else
					sys_uart_write_data_valid <= 0;
			end

			default: begin
				pkt_state <= 0;
				sys_uart_write_data_valid <= 0;
			end

		endcase
	end


endmodule