diff options
| author | Julian Blake Kongslie | 2022-03-13 16:51:03 -0700 |
|---|---|---|
| committer | Julian Blake Kongslie | 2022-03-13 16:51:03 -0700 |
| commit | f747a526b97b29a0479c62c4ecea285f1f5f2fde (patch) | |
| tree | 7c389b4b62a97f8d0fa87c14f1682ea858c6ae94 /hdl/command_parser.sv | |
| parent | Add memory arbiter and broadcast in between command UART and DRAM. (diff) | |
| download | multipdp8-f747a526b97b29a0479c62c4ecea285f1f5f2fde.tar.xz | |
Change command parser to support bulk download script.
Diffstat (limited to '')
| -rw-r--r-- | hdl/command_parser.sv | 113 |
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; |
