diff options
Diffstat (limited to 'hdl/core.sv')
| -rw-r--r-- | hdl/core.sv | 87 |
1 files changed, 76 insertions, 11 deletions
diff --git a/hdl/core.sv b/hdl/core.sv index 14660f5..b607e4b 100644 --- a/hdl/core.sv +++ b/hdl/core.sv | |||
| @@ -50,12 +50,18 @@ module core | |||
| 50 | ); | 50 | ); |
| 51 | 51 | ||
| 52 | bit run; | 52 | bit run; |
| 53 | bit int_enable; | ||
| 54 | bit int_delay; | ||
| 55 | bit int_request; | ||
| 56 | |||
| 53 | bit switch_start_observed; | 57 | bit switch_start_observed; |
| 54 | bit switch_load_add_observed; | 58 | bit switch_load_add_observed; |
| 55 | bit switch_dep_observed; | 59 | bit switch_dep_observed; |
| 56 | bit switch_exam_observed; | 60 | bit switch_exam_observed; |
| 57 | bit switch_cont_observed; | 61 | bit switch_cont_observed; |
| 62 | |||
| 58 | assign led_run = run; | 63 | assign led_run = run; |
| 64 | assign led_ion = int_enable; | ||
| 59 | 65 | ||
| 60 | bit mem_ready; | 66 | bit mem_ready; |
| 61 | bit mem_valid; | 67 | bit mem_valid; |
| @@ -134,14 +140,19 @@ assign led_jmp = opcode == 5; | |||
| 134 | assign led_iot = opcode == 6; | 140 | assign led_iot = opcode == 6; |
| 135 | assign led_opr = opcode == 7; | 141 | assign led_opr = opcode == 7; |
| 136 | 142 | ||
| 137 | bit kbd_valid; | 143 | bit tti_int_enable; |
| 138 | bit [DATA_BITS-1:0] kbd_data; | 144 | bit tti_valid; |
| 145 | bit [DATA_BITS-1:0] tti_data; | ||
| 139 | 146 | ||
| 140 | bit i; | 147 | bit i; |
| 141 | bit z; | 148 | bit z; |
| 142 | bit [6:0] wip; | 149 | bit [6:0] wip; |
| 143 | bit [ADDR_BITS-1:0] address; | 150 | bit [ADDR_BITS-1:0] address; |
| 144 | 151 | ||
| 152 | assign int_request = | ||
| 153 | (tti_int_enable && tti_valid) | ||
| 154 | ; | ||
| 155 | |||
| 145 | enum | 156 | enum |
| 146 | { FETCH | 157 | { FETCH |
| 147 | , DECODE | 158 | , DECODE |
| @@ -162,6 +173,8 @@ assign led_pause = state == MEMWAIT || state == HALT; | |||
| 162 | always_ff @(posedge clk) begin | 173 | always_ff @(posedge clk) begin |
| 163 | if (reset) begin | 174 | if (reset) begin |
| 164 | run = 0; | 175 | run = 0; |
| 176 | int_enable = 0; | ||
| 177 | int_delay = 0; | ||
| 165 | switch_start_observed = 0; | 178 | switch_start_observed = 0; |
| 166 | switch_load_add_observed = 0; | 179 | switch_load_add_observed = 0; |
| 167 | switch_dep_observed = 0; | 180 | switch_dep_observed = 0; |
| @@ -175,12 +188,15 @@ always_ff @(posedge clk) begin | |||
| 175 | led_pc = pc; | 188 | led_pc = pc; |
| 176 | acc = 0; | 189 | acc = 0; |
| 177 | link = 1; | 190 | link = 1; |
| 178 | kbd_valid = 0; | 191 | tti_int_enable = 0; |
| 192 | tti_valid = 0; | ||
| 179 | state = state.first; | 193 | state = state.first; |
| 180 | end else begin | 194 | end else begin |
| 181 | if (switch_start && !switch_start_observed) begin | 195 | if (switch_start && !switch_start_observed) begin |
| 182 | switch_start_observed = 1; | 196 | switch_start_observed = 1; |
| 183 | run = 1; | 197 | run = 1; |
| 198 | int_enable = 0; | ||
| 199 | int_delay = 0; | ||
| 184 | mem_valid = 0; | 200 | mem_valid = 0; |
| 185 | acc = 0; | 201 | acc = 0; |
| 186 | link = 1; | 202 | link = 1; |
| @@ -226,8 +242,8 @@ always_ff @(posedge clk) begin | |||
| 226 | 242 | ||
| 227 | if (`lag(tx_ready)) tx_valid = 0; | 243 | if (`lag(tx_ready)) tx_valid = 0; |
| 228 | if (rx_ready && `lag(rx_valid)) begin | 244 | if (rx_ready && `lag(rx_valid)) begin |
| 229 | kbd_valid = 1; | 245 | tti_valid = 1; |
| 230 | kbd_data = {4'b0, 1'b1, `lag(rx_data[6:0])}; | 246 | tti_data = {4'b0, 1'b1, `lag(rx_data[6:0])}; |
| 231 | end | 247 | end |
| 232 | 248 | ||
| 233 | if (run) begin | 249 | if (run) begin |
| @@ -245,12 +261,25 @@ always_ff @(posedge clk) begin | |||
| 245 | end | 261 | end |
| 246 | 262 | ||
| 247 | DECODE: begin | 263 | DECODE: begin |
| 264 | automatic bit go; | ||
| 265 | go = 0; | ||
| 248 | mem_valid = 0; | 266 | mem_valid = 0; |
| 249 | mem_write = 0; | 267 | mem_write = 0; |
| 250 | if (`lag(mem_read_valid)) begin | 268 | if (int_enable && int_request) begin |
| 269 | int_enable = 0; | ||
| 270 | int_delay = 0; | ||
| 271 | --pc; | ||
| 272 | opcode = 'b100; | ||
| 273 | operand = 'b000000; | ||
| 274 | go = 1; | ||
| 275 | end else if (`lag(mem_read_valid)) begin | ||
| 251 | state = FETCH; | 276 | state = FETCH; |
| 252 | led_memdata = `lag(mem_read_data); | 277 | led_memdata = `lag(mem_read_data); |
| 253 | {opcode, operand} = `lag(mem_read_data); | 278 | {opcode, operand} = `lag(mem_read_data); |
| 279 | go = 1; | ||
| 280 | end | ||
| 281 | if (go) begin | ||
| 282 | int_enable = int_delay; | ||
| 254 | // $display("%o: decode %o %o", pc-1, opcode, operand); | 283 | // $display("%o: decode %o %o", pc-1, opcode, operand); |
| 255 | // verilator lint_off WIDTH | 284 | // verilator lint_off WIDTH |
| 256 | // $display("%o %b %o 0000", 14'(pc-1), link, acc); | 285 | // $display("%o %b %o 0000", 14'(pc-1), link, acc); |
| @@ -332,16 +361,51 @@ always_ff @(posedge clk) begin | |||
| 332 | case (operand[8:3]) | 361 | case (operand[8:3]) |
| 333 | 'o00: begin | 362 | 'o00: begin |
| 334 | case (operand[2:0]) | 363 | case (operand[2:0]) |
| 335 | 'o0, 'o1: ; | 364 | 'o0: begin |
| 365 | if (int_enable) | ||
| 366 | ++pc; | ||
| 367 | int_enable = 0; | ||
| 368 | int_delay = 0; | ||
| 369 | end | ||
| 370 | 'o1: int_delay = 1; | ||
| 371 | 'o2: begin | ||
| 372 | int_enable = 0; | ||
| 373 | int_delay = 0; | ||
| 374 | end | ||
| 375 | 'o3: begin | ||
| 376 | if (int_request) | ||
| 377 | ++pc; | ||
| 378 | end | ||
| 379 | 'o4: acc = {link, 1'b0/*gt*/, int_request, 1'b0/*ii*/, int_enable, 1'b0/*u*/, 3'b0/*if*/, 3'b0/*df*/}; | ||
| 380 | 'o5: begin | ||
| 381 | link = acc[11]; | ||
| 382 | if (acc[7]) begin | ||
| 383 | int_delay = 1; | ||
| 384 | end else begin | ||
| 385 | int_enable = 0; | ||
| 386 | int_delay = 0; | ||
| 387 | end | ||
| 388 | end | ||
| 389 | 'o7: begin | ||
| 390 | int_enable = 0; | ||
| 391 | int_delay = 0; | ||
| 392 | acc = 0; | ||
| 393 | link = 1; | ||
| 394 | tx_valid = 0; | ||
| 395 | tti_valid = 0; | ||
| 396 | end | ||
| 336 | default: $display("%o: unsupported 600%o op", pc-1, operand[2:0]); | 397 | default: $display("%o: unsupported 600%o op", pc-1, operand[2:0]); |
| 337 | endcase | 398 | endcase |
| 338 | end | 399 | end |
| 339 | 'o03: begin | 400 | 'o03: begin |
| 340 | case (operand[2:0]) | 401 | case (operand[2:0]) |
| 341 | 'o1: if (kbd_valid) pc++; | 402 | 'o1: if (tti_valid) pc++; |
| 403 | 'o5: begin | ||
| 404 | tti_int_enable = acc[0]; | ||
| 405 | end | ||
| 342 | 'o6: begin | 406 | 'o6: begin |
| 343 | acc = kbd_data; | 407 | acc = tti_data; |
| 344 | kbd_valid = 0; | 408 | tti_valid = 0; |
| 345 | end | 409 | end |
| 346 | default: begin | 410 | default: begin |
| 347 | $display("%o: unsupported keyboard op %o", pc-1, operand[2:0]); | 411 | $display("%o: unsupported keyboard op %o", pc-1, operand[2:0]); |
| @@ -479,6 +543,7 @@ always_ff @(posedge clk) begin | |||
| 479 | MEMWAIT: state = `lag(mem_ready) ? FETCH : MEMWAIT; | 543 | MEMWAIT: state = `lag(mem_ready) ? FETCH : MEMWAIT; |
| 480 | 544 | ||
| 481 | HALT: begin | 545 | HALT: begin |
| 546 | run = 0; | ||
| 482 | $display("\nhalt state reached"); | 547 | $display("\nhalt state reached"); |
| 483 | $finish; | 548 | $finish; |
| 484 | end | 549 | end |
| @@ -490,7 +555,7 @@ always_ff @(posedge clk) begin | |||
| 490 | if (state == FETCH && switch_sing_inst) | 555 | if (state == FETCH && switch_sing_inst) |
| 491 | run = 0; | 556 | run = 0; |
| 492 | 557 | ||
| 493 | rx_ready = !kbd_valid; | 558 | rx_ready = !tti_valid; |
| 494 | end | 559 | end |
| 495 | end | 560 | end |
| 496 | end | 561 | end |
