diff options
Diffstat (limited to 'hdl/top.sv')
| -rw-r--r-- | hdl/top.sv | 65 |
1 files changed, 34 insertions, 31 deletions
| @@ -68,7 +68,6 @@ bit [DATA_BITS-1:0] pc; | |||
| 68 | bit [3:0] opcode; | 68 | bit [3:0] opcode; |
| 69 | bit [7:0] operand; | 69 | bit [7:0] operand; |
| 70 | bit [DATA_BITS-1:0] acc; | 70 | bit [DATA_BITS-1:0] acc; |
| 71 | bit [DATA_BITS-1:0] idx; | ||
| 72 | 71 | ||
| 73 | bit [ADDR_BITS-1:0] address; | 72 | bit [ADDR_BITS-1:0] address; |
| 74 | bit [DATA_BITS-1:0] sign_extended_operand; | 73 | bit [DATA_BITS-1:0] sign_extended_operand; |
| @@ -91,10 +90,9 @@ always_ff @(posedge clk) begin | |||
| 91 | tx_data = 0; | 90 | tx_data = 0; |
| 92 | pc = 0; | 91 | pc = 0; |
| 93 | acc = 0; | 92 | acc = 0; |
| 94 | idx = 0; | ||
| 95 | state = state.first; | 93 | state = state.first; |
| 96 | end else begin | 94 | end else begin |
| 97 | `ifdef DEBUG $display("s=%0d pc=%x (acc=%x idx=%x) (mem %b:%x)", state, pc, acc, idx, `mem_read_valid, `mem_read_data); `endif | 95 | `ifdef DEBUG $display("s=%0d pc=%x (acc=%x) (mem %b:%x)", state, pc, acc, `mem_read_valid, `mem_read_data); `endif |
| 98 | if (`tx_ready) tx_valid = 0; | 96 | if (`tx_ready) tx_valid = 0; |
| 99 | 97 | ||
| 100 | case (state) | 98 | case (state) |
| @@ -118,29 +116,33 @@ always_ff @(posedge clk) begin | |||
| 118 | sign_extended_operand = {{(DATA_BITS-8){operand[7]}}, operand}; | 116 | sign_extended_operand = {{(DATA_BITS-8){operand[7]}}, operand}; |
| 119 | `ifdef DEBUG $display("\tdecode %x:%x", opcode, operand); `endif | 117 | `ifdef DEBUG $display("\tdecode %x:%x", opcode, operand); `endif |
| 120 | case (opcode) | 118 | case (opcode) |
| 121 | 'h0: acc = sign_extended_operand; | 119 | 'h0: begin |
| 122 | 'h1, 'h2: begin | 120 | if (operand[0]) acc = 0; |
| 121 | if (operand[1]) ++acc; | ||
| 122 | if (operand[2]) --acc; | ||
| 123 | if (operand[6]) state = MEMORY; | ||
| 124 | if (operand[7]) state = HALT; | ||
| 125 | end | ||
| 126 | 'h1: acc = sign_extended_operand; | ||
| 127 | 'h2, 'h3: begin | ||
| 123 | address = {7'b0, operand[6:0]}; | 128 | address = {7'b0, operand[6:0]}; |
| 124 | state = operand[7] ? INDIRECT : AGEN; | 129 | state = operand[7] ? INDIRECT : AGEN; |
| 125 | end | 130 | end |
| 126 | 'h3: if (acc != sign_extended_operand) ++pc; | 131 | 'h4: if (acc != sign_extended_operand) ++pc; |
| 127 | 'h4: pc = pc + sign_extended_operand; | ||
| 128 | 'h5: begin | 132 | 'h5: begin |
| 133 | if (operand[7]) begin | ||
| 134 | address = {7'b0, operand[6:0]}; | ||
| 135 | state = INDIRECT; | ||
| 136 | end else begin | ||
| 137 | pc = pc + {{(ADDR_BITS-7){operand[6]}}, operand[6:0]}; | ||
| 138 | end | ||
| 139 | end | ||
| 140 | 'h6: begin | ||
| 129 | mem_write_data = acc % 10 + 'h30; | 141 | mem_write_data = acc % 10 + 'h30; |
| 130 | acc = acc / 10; | 142 | acc = acc / 10; |
| 131 | address = {7'b0, operand[6:0]}; | 143 | address = {7'b0, operand[6:0]}; |
| 132 | state = operand[7] ? INDIRECT : AGEN; | 144 | state = operand[7] ? INDIRECT : AGEN; |
| 133 | end | 145 | end |
| 134 | 'hf: begin | ||
| 135 | if (operand[0]) ++acc; | ||
| 136 | if (operand[1]) --acc; | ||
| 137 | if (operand[2]) ++idx; | ||
| 138 | if (operand[3]) --idx; | ||
| 139 | if (operand[4]) {idx, acc} = {acc, idx}; | ||
| 140 | if (operand[5]) idx = acc; | ||
| 141 | if (operand[6]) state = MEMORY; | ||
| 142 | if (operand[7]) state = HALT; | ||
| 143 | end | ||
| 144 | endcase | 146 | endcase |
| 145 | end | 147 | end |
| 146 | end | 148 | end |
| @@ -169,21 +171,22 @@ always_ff @(posedge clk) begin | |||
| 169 | state = FETCH; | 171 | state = FETCH; |
| 170 | `ifdef DEBUG $display("\tagen"); `endif | 172 | `ifdef DEBUG $display("\tagen"); `endif |
| 171 | case (opcode) | 173 | case (opcode) |
| 172 | 'h1: begin | 174 | 'h2: begin |
| 173 | mem_valid = 1; | 175 | mem_valid = 1; |
| 174 | mem_address = address + idx; | 176 | mem_address = address; |
| 175 | state = `mem_ready ? MEMORY : AGEN; | 177 | state = `mem_ready ? MEMORY : AGEN; |
| 176 | end | 178 | end |
| 177 | 'h2: begin | 179 | 'h3: begin |
| 178 | mem_valid = 1; | 180 | mem_valid = 1; |
| 179 | mem_address = address + idx; | 181 | mem_address = address; |
| 180 | mem_write = 1; | 182 | mem_write = 1; |
| 181 | mem_write_data = acc; | 183 | mem_write_data = acc; |
| 182 | state = `mem_ready ? FETCH : AGEN; | 184 | state = `mem_ready ? FETCH : AGEN; |
| 183 | end | 185 | end |
| 184 | 'h5: begin | 186 | 'h5: pc = address; |
| 187 | 'h6: begin | ||
| 185 | mem_valid = 1; | 188 | mem_valid = 1; |
| 186 | mem_address = address + idx; | 189 | mem_address = address; |
| 187 | mem_write = 1; | 190 | mem_write = 1; |
| 188 | state = `mem_ready ? FETCH : AGEN; | 191 | state = `mem_ready ? FETCH : AGEN; |
| 189 | end | 192 | end |
| @@ -198,14 +201,7 @@ always_ff @(posedge clk) begin | |||
| 198 | state = FETCH; | 201 | state = FETCH; |
| 199 | `ifdef DEBUG $display("\tstall"); `endif | 202 | `ifdef DEBUG $display("\tstall"); `endif |
| 200 | case (opcode) | 203 | case (opcode) |
| 201 | 'h1: begin | 204 | 'h0: begin |
| 202 | if (`mem_read_valid) begin | ||
| 203 | acc = acc + `mem_read_data; | ||
| 204 | end else begin | ||
| 205 | state = MEMORY; | ||
| 206 | end | ||
| 207 | end | ||
| 208 | 'hf: begin | ||
| 209 | if (operand[6]) begin | 205 | if (operand[6]) begin |
| 210 | if (tx_valid) begin | 206 | if (tx_valid) begin |
| 211 | state = MEMORY; | 207 | state = MEMORY; |
| @@ -215,6 +211,13 @@ always_ff @(posedge clk) begin | |||
| 215 | end | 211 | end |
| 216 | end | 212 | end |
| 217 | end | 213 | end |
| 214 | 'h2: begin | ||
| 215 | if (`mem_read_valid) begin | ||
| 216 | acc = acc + `mem_read_data; | ||
| 217 | end else begin | ||
| 218 | state = MEMORY; | ||
| 219 | end | ||
| 220 | end | ||
| 218 | endcase | 221 | endcase |
| 219 | end | 222 | end |
| 220 | 223 | ||
