module command_parser ( input bit clock , input bit resetn , output bit uart_ready , input bit uart_valid , input bit [7:0] uart_data , input bit echo_ready , output bit echo_valid , output bit [7:0] echo_data , input bit command_ready , output bit command_valid , output bit [23:0] command_address , output bit command_write , output bit [15:0] command_data ); bit input_byte_valid; bit [7:0] input_byte; (* syn_encoding = "one-hot" *) enum int unsigned { READ_ADDRESS_OR_COMMAND , READ_DATA_1 , READ_DATA_2 , READ_DATA_3 , READ_DATA_4 } state; always @(posedge clock) begin if (!resetn) begin uart_ready = 0; command_valid = 0; command_address = 0; command_write = 0; command_data = 0; input_byte_valid = 0; input_byte = 0; state = state.first; end else begin if (echo_ready) echo_valid = 0; if (command_ready) command_valid = 0; if (uart_ready && uart_valid) begin echo_valid = 1; echo_data = uart_data; input_byte_valid = 1; input_byte = uart_data; end if (!command_valid && input_byte_valid) begin case (state) READ_ADDRESS_OR_COMMAND: begin if (input_byte >= "0" && input_byte <= "9") begin command_address = command_address << 4; command_address[3:0] = input_byte - "0"; end else if (input_byte >= "a" && input_byte <= "f") begin command_address = command_address << 4; command_address[3:0] = input_byte - "a" + 10; end else if (input_byte >= "A" && input_byte <= "F") begin command_address = command_address << 4; command_address[3:0] = input_byte - "A" + 10; end else if (input_byte == "?") begin command_valid = 1; command_write = 0; command_data = 0; end else if (input_byte == "=") begin command_write = 1; command_data = 0; state = READ_DATA_1; end end READ_DATA_1, READ_DATA_2, READ_DATA_3, READ_DATA_4: begin if (input_byte >= "0" && input_byte <= "9") begin command_data = command_data << 4; command_data[3:0] = input_byte - "0"; state = state.next; end else if (input_byte >= "a" && input_byte <= "f") begin command_data = command_data << 4; command_data[3:0] = input_byte - "a" + 10; state = state.next; end else if (input_byte >= "A" && input_byte <= "F") begin command_data = command_data << 4; command_data[3:0] = input_byte - "A" + 10; state = state.next; end else begin state = state.first; end command_valid = state == state.first; end endcase input_byte_valid = 0; end uart_ready = !echo_valid && !input_byte_valid; end end endmodule