summaryrefslogtreecommitdiff
path: root/hdl
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--hdl/command_parser.sv113
1 files changed, 90 insertions, 23 deletions
diff --git a/hdl/command_parser.sv b/hdl/command_parser.sv
index 5c49db9..cf4fe65 100644
--- a/hdl/command_parser.sv
+++ b/hdl/command_parser.sv
@@ -21,29 +21,32 @@ module command_parser
21 bit input_byte_valid; 21 bit input_byte_valid;
22 uart_byte_t input_byte; 22 uart_byte_t input_byte;
23 23
24 bit [`RAM_ADDRESS_BITS:0] zero_count;
25
24 (* syn_encoding = "one-hot" *) enum int unsigned 26 (* syn_encoding = "one-hot" *) enum int unsigned
25 { READ_ADDRESS_OR_COMMAND 27 { READ_COMMAND
28 , READ_ADDRESS
26 , READ_DATA 29 , READ_DATA
30 , READ_ZERO_COUNT
31 , ZERO_MEMORY
27 } state; 32 } state;
28 33
29 always @(posedge clock) begin 34 always @(posedge clock) begin
30 if (reset) begin 35 if (reset) begin
31 uart_ready = 0; 36 uart_ready = 0;
32 command_valid = 0; 37 command_valid = 0;
38 for (int i = 0; i < `RAM_LINE_WORDS; i = i + 1)
39 command_data.mask[i] = ~0;
40 command_data.tag = TAG;
33 input_byte_valid = 0; 41 input_byte_valid = 0;
34 input_byte = 0; 42 input_byte = 0;
43 zero_count = 0;
35 state = state.first; 44 state = state.first;
36 end else begin 45 end else begin
37 if (echo_ready) echo_valid = 0; 46 if (echo_ready) echo_valid = 0;
38 if (command_ready && command_valid) begin 47 if (command_ready && command_valid) begin
39 command_valid = 0; 48 command_valid = 0;
40 command_data.address = 0; 49 ++command_data.address;
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 50 end
48 if (uart_ready && uart_valid) begin 51 if (uart_ready && uart_valid) begin
49 echo_valid = 1; 52 echo_valid = 1;
@@ -52,10 +55,42 @@ module command_parser
52 input_byte = uart_data; 55 input_byte = uart_data;
53 end 56 end
54 57
55 if (!command_valid && input_byte_valid) begin 58 if (!command_valid) begin
56 case (state) 59 case (state)
57 60
58 READ_ADDRESS_OR_COMMAND: begin 61 READ_COMMAND: if (input_byte_valid) begin
62 case (input_byte)
63
64 "@": begin
65 command_data.address = 0;
66 state = READ_ADDRESS;
67 end
68
69 "?": begin
70 command_valid = 1;
71 command_data.write = 0;
72 end
73
74 "=": begin
75 command_data.write = 1;
76 for (int i = 0; i < `RAM_LINE_WORDS; i = i + 1)
77 command_data.data[i] = 0;
78 state = READ_DATA;
79 end
80
81 "!": begin
82 command_data.write = 1;
83 for (int i = 0; i < `RAM_LINE_WORDS; i = i + 1)
84 command_data.data[i] = 0;
85 zero_count = 0;
86 state = READ_ZERO_COUNT;
87 end
88
89 endcase
90 input_byte_valid = 0;
91 end
92
93 READ_ADDRESS: if (input_byte_valid) begin
59 if (input_byte >= "0" && input_byte <= "9") begin 94 if (input_byte >= "0" && input_byte <= "9") begin
60 command_data.address = command_data.address << 4; 95 command_data.address = command_data.address << 4;
61 command_data.address[$clog2(`RAM_LINE_WORDS)+:4] = input_byte - "0"; 96 command_data.address[$clog2(`RAM_LINE_WORDS)+:4] = input_byte - "0";
@@ -65,22 +100,13 @@ module command_parser
65 end else if (input_byte >= "A" && input_byte <= "F") begin 100 end else if (input_byte >= "A" && input_byte <= "F") begin
66 command_data.address = command_data.address << 4; 101 command_data.address = command_data.address << 4;
67 command_data.address[$clog2(`RAM_LINE_WORDS)+:4] = input_byte - "A" + 10; 102 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 103 end else begin
77 command_data.address = 0; 104 state = state.first;
78 command_data.write = 0;
79 command_data.data = 0;
80 end 105 end
106 input_byte_valid = 0;
81 end 107 end
82 108
83 READ_DATA: begin 109 READ_DATA: if (input_byte_valid) begin
84 automatic bit [$bits(command_data.data)-1:0] flat_data = command_data.data; 110 automatic bit [$bits(command_data.data)-1:0] flat_data = command_data.data;
85 flat_data = flat_data << 4; 111 flat_data = flat_data << 4;
86 if (input_byte >= "0" && input_byte <= "9") begin 112 if (input_byte >= "0" && input_byte <= "9") begin
@@ -96,10 +122,51 @@ module command_parser
96 command_valid = 1; 122 command_valid = 1;
97 state = state.first; 123 state = state.first;
98 end 124 end
125 input_byte_valid = 0;
126 end
127
128 READ_ZERO_COUNT: if (input_byte_valid) begin
129 if (input_byte >= "0" && input_byte <= "9") begin
130 zero_count = zero_count << 4;
131 zero_count[3:0] = input_byte - "0";
132 end else if (input_byte >= "a" && input_byte <= "f") begin
133 zero_count = zero_count << 4;
134 zero_count[3:0] = input_byte - "a" + 10;
135 end else if (input_byte >= "A" && input_byte <= "F") begin
136 zero_count = zero_count << 4;
137 zero_count[3:0] = input_byte - "A" + 10;
138 end else begin
139 state = ZERO_MEMORY;
140 end
141 input_byte_valid = 0;
142 end
143
144`ifdef SLOW_ZEROING
145 ZERO_MEMORY: if (!echo_valid) begin
146 if (zero_count == 0) begin
147 echo_valid = 1;
148 echo_data = "\n";
149 state = state.first;
150 end else begin
151 echo_valid = 1;
152 echo_data = ".";
153 command_valid = 1;
154 --zero_count;
155 end
156 end
157`else
158 ZERO_MEMORY: begin
159 if (zero_count == 0) begin
160 state = state.first;
161 end else begin
162 command_valid = 1;
163 if (--zero_count == 0)
164 state = state.first;
165 end
99 end 166 end
167`endif
100 168
101 endcase 169 endcase
102 input_byte_valid = 0;
103 end 170 end
104 171
105 uart_ready = !echo_valid && !input_byte_valid; 172 uart_ready = !echo_valid && !input_byte_valid;