From 0553c4839c06011bd044f69b4913e5c793fdd2ec Mon Sep 17 00:00:00 2001 From: Julian Blake Kongslie Date: Sun, 27 Feb 2022 17:21:05 -0800 Subject: Initial commit. --- hdl/command_parser.sv | 109 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 hdl/command_parser.sv (limited to 'hdl/command_parser.sv') diff --git a/hdl/command_parser.sv b/hdl/command_parser.sv new file mode 100644 index 0000000..5c49db9 --- /dev/null +++ b/hdl/command_parser.sv @@ -0,0 +1,109 @@ +`include "defs.svh" + +module command_parser + #( TAG = 0 + ) ( input bit clock + , input bit reset + + , output bit uart_ready + , input bit uart_valid + , input uart_byte_t uart_data + + , input bit echo_ready + , output bit echo_valid + , output uart_byte_t echo_data + + , input bit command_ready + , output bit command_valid + , output ram_command_t command_data + ); + + bit input_byte_valid; + uart_byte_t input_byte; + + (* syn_encoding = "one-hot" *) enum int unsigned + { READ_ADDRESS_OR_COMMAND + , READ_DATA + } state; + + always @(posedge clock) begin + if (reset) begin + uart_ready = 0; + command_valid = 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) begin + command_valid = 0; + command_data.address = 0; + command_data.write = 0; + for (int i = 0; i < `RAM_LINE_WORDS; i = i + 1) begin + command_data.data[i] = 0; + command_data.mask[i] = ~0; + end + command_data.tag = TAG; + end + 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_data.address = command_data.address << 4; + command_data.address[$clog2(`RAM_LINE_WORDS)+:4] = input_byte - "0"; + end else if (input_byte >= "a" && input_byte <= "f") begin + command_data.address = command_data.address << 4; + command_data.address[$clog2(`RAM_LINE_WORDS)+:4] = input_byte - "a" + 10; + end else if (input_byte >= "A" && input_byte <= "F") begin + command_data.address = command_data.address << 4; + command_data.address[$clog2(`RAM_LINE_WORDS)+:4] = input_byte - "A" + 10; + end else if (input_byte == "?") begin + command_valid = 1; + command_data.write = 0; + command_data.data = 0; + end else if (input_byte == "=") begin + command_data.write = 1; + command_data.data = 0; + state = READ_DATA; + end else begin + command_data.address = 0; + command_data.write = 0; + command_data.data = 0; + end + end + + READ_DATA: begin + automatic bit [$bits(command_data.data)-1:0] flat_data = command_data.data; + flat_data = flat_data << 4; + if (input_byte >= "0" && input_byte <= "9") begin + flat_data[3:0] = input_byte - "0"; + command_data.data = flat_data; + end else if (input_byte >= "a" && input_byte <= "f") begin + flat_data[3:0] = input_byte - "a" + 10; + command_data.data = flat_data; + end else if (input_byte >= "A" && input_byte <= "F") begin + flat_data[3:0] = input_byte - "A" + 10; + command_data.data = flat_data; + end else begin + command_valid = 1; + state = state.first; + end + end + + endcase + input_byte_valid = 0; + end + + uart_ready = !echo_valid && !input_byte_valid; + end + end + +endmodule -- cgit v1.2.3