summaryrefslogtreecommitdiff
path: root/hdl/command_parser.sv
diff options
context:
space:
mode:
Diffstat (limited to 'hdl/command_parser.sv')
-rw-r--r--hdl/command_parser.sv109
1 files changed, 109 insertions, 0 deletions
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 @@
1`include "defs.svh"
2
3module command_parser
4 #( TAG = 0
5 ) ( input bit clock
6 , input bit reset
7
8 , output bit uart_ready
9 , input bit uart_valid
10 , input uart_byte_t uart_data
11
12 , input bit echo_ready
13 , output bit echo_valid
14 , output uart_byte_t echo_data
15
16 , input bit command_ready
17 , output bit command_valid
18 , output ram_command_t command_data
19 );
20
21 bit input_byte_valid;
22 uart_byte_t input_byte;
23
24 (* syn_encoding = "one-hot" *) enum int unsigned
25 { READ_ADDRESS_OR_COMMAND
26 , READ_DATA
27 } state;
28
29 always @(posedge clock) begin
30 if (reset) begin
31 uart_ready = 0;
32 command_valid = 0;
33 input_byte_valid = 0;
34 input_byte = 0;
35 state = state.first;
36 end else begin
37 if (echo_ready) echo_valid = 0;
38 if (command_ready && command_valid) begin
39 command_valid = 0;
40 command_data.address = 0;
41 command_data.write = 0;
42 for (int i = 0; i < `RAM_LINE_WORDS; i = i + 1) begin
43 command_data.data[i] = 0;
44 command_data.mask[i] = ~0;
45 end
46 command_data.tag = TAG;
47 end
48 if (uart_ready && uart_valid) begin
49 echo_valid = 1;
50 echo_data = uart_data;
51 input_byte_valid = 1;
52 input_byte = uart_data;
53 end
54
55 if (!command_valid && input_byte_valid) begin
56 case (state)
57
58 READ_ADDRESS_OR_COMMAND: begin
59 if (input_byte >= "0" && input_byte <= "9") begin
60 command_data.address = command_data.address << 4;
61 command_data.address[$clog2(`RAM_LINE_WORDS)+:4] = input_byte - "0";
62 end else if (input_byte >= "a" && input_byte <= "f") begin
63 command_data.address = command_data.address << 4;
64 command_data.address[$clog2(`RAM_LINE_WORDS)+:4] = input_byte - "a" + 10;
65 end else if (input_byte >= "A" && input_byte <= "F") begin
66 command_data.address = command_data.address << 4;
67 command_data.address[$clog2(`RAM_LINE_WORDS)+:4] = input_byte - "A" + 10;
68 end else if (input_byte == "?") begin
69 command_valid = 1;
70 command_data.write = 0;
71 command_data.data = 0;
72 end else if (input_byte == "=") begin
73 command_data.write = 1;
74 command_data.data = 0;
75 state = READ_DATA;
76 end else begin
77 command_data.address = 0;
78 command_data.write = 0;
79 command_data.data = 0;
80 end
81 end
82
83 READ_DATA: begin
84 automatic bit [$bits(command_data.data)-1:0] flat_data = command_data.data;
85 flat_data = flat_data << 4;
86 if (input_byte >= "0" && input_byte <= "9") begin
87 flat_data[3:0] = input_byte - "0";
88 command_data.data = flat_data;
89 end else if (input_byte >= "a" && input_byte <= "f") begin
90 flat_data[3:0] = input_byte - "a" + 10;
91 command_data.data = flat_data;
92 end else if (input_byte >= "A" && input_byte <= "F") begin
93 flat_data[3:0] = input_byte - "A" + 10;
94 command_data.data = flat_data;
95 end else begin
96 command_valid = 1;
97 state = state.first;
98 end
99 end
100
101 endcase
102 input_byte_valid = 0;
103 end
104
105 uart_ready = !echo_valid && !input_byte_valid;
106 end
107 end
108
109endmodule