diff options
Diffstat (limited to 'hdl/core.sv')
| -rw-r--r-- | hdl/core.sv | 143 |
1 files changed, 86 insertions, 57 deletions
diff --git a/hdl/core.sv b/hdl/core.sv index a71e318..8bbea98 100644 --- a/hdl/core.sv +++ b/hdl/core.sv | |||
| @@ -1,60 +1,84 @@ | |||
| 1 | `include "defs.svh" | ||
| 2 | |||
| 1 | `ifdef SYNTHESIS | 3 | `ifdef SYNTHESIS |
| 2 | `define lag(x) x | 4 | `define lag(x) x |
| 3 | `else | 5 | `else |
| 4 | `define lag(x) $past(x) | 6 | `define lag(x) $past(x) |
| 5 | `endif | 7 | `endif |
| 6 | 8 | ||
| 9 | `define DATA_BITS 12 | ||
| 10 | |||
| 7 | module mem | 11 | module mem |
| 8 | ( input bit clk | 12 | ( input bit clk |
| 9 | , input bit reset | 13 | , input bit reset |
| 10 | 14 | ||
| 11 | , output bit ready | 15 | , output bit command_ready |
| 12 | , input bit valid | 16 | , input bit command_valid |
| 13 | , input bit write | 17 | , input pdp_command_t command_data |
| 14 | , input bit [ADDR_BITS-1:0] address | ||
| 15 | , input bit [DATA_BITS-1:0] write_data | ||
| 16 | 18 | ||
| 19 | , input bit read_ready | ||
| 17 | , output bit read_valid | 20 | , output bit read_valid |
| 18 | , output bit [DATA_BITS-1:0] read_data | 21 | , output pdp_read_response_t read_data |
| 19 | ); | 22 | ); |
| 20 | 23 | ||
| 21 | parameter ADDR_BITS; | ||
| 22 | parameter DATA_BITS; | ||
| 23 | parameter INIT_FILE; | 24 | parameter INIT_FILE; |
| 24 | 25 | ||
| 25 | bit [DATA_BITS-1:0] storage [0:(1<<ADDR_BITS)-1]; | 26 | bit hold_valid; |
| 27 | pdp_command_t hold; | ||
| 28 | |||
| 29 | bit [`DATA_BITS-1:0] storage [0:(1 << `PDP_ADDRESS_BITS)-1]; | ||
| 26 | initial $readmemh(INIT_FILE, storage); | 30 | initial $readmemh(INIT_FILE, storage); |
| 27 | 31 | ||
| 28 | always_ff @(posedge clk) begin | 32 | always_ff @(posedge clk) begin |
| 29 | if (reset) begin | 33 | if (reset) begin |
| 30 | ready = 0; | 34 | command_ready = 0; |
| 31 | read_valid = 0; | 35 | read_valid = 0; |
| 36 | hold_valid = 0; | ||
| 32 | end else begin | 37 | end else begin |
| 33 | read_valid = 0; | 38 | if (read_ready) read_valid = 0; |
| 34 | if (ready && `lag(valid)) begin | 39 | |
| 35 | if (`lag(write)) begin | 40 | if (command_ready && command_valid) begin |
| 36 | storage[`lag(address)] = `lag(write_data); | 41 | hold_valid = 1; |
| 37 | end else begin | 42 | hold = command_data; |
| 38 | read_valid = 1; | 43 | end |
| 39 | read_data = storage[`lag(address)]; | 44 | |
| 45 | if (hold_valid && hold.write) begin | ||
| 46 | // for (int i = 0; i < `RAM_LINE_WORDS; ++i) begin | ||
| 47 | if (hold.mask[0]) begin | ||
| 48 | automatic pdp_word_address_t addr = 0; | ||
| 49 | addr[`PDP_ADDRESS_BITS-1:$clog2(`RAM_LINE_WORDS)] = hold.address; | ||
| 50 | // if (`RAM_LINE_WORDS != 1) | ||
| 51 | // addr[$clog2(`RAM_LINE_WORDS)-1:0] = i; | ||
| 52 | storage[addr] = hold.data[/*i*/0]; | ||
| 53 | end | ||
| 54 | // end | ||
| 55 | hold_valid = 0; | ||
| 56 | end else if (hold_valid && !read_valid) begin | ||
| 57 | read_valid = 1; | ||
| 58 | read_data.address = hold.address; | ||
| 59 | /*for (int i = 0; i < `RAM_LINE_WORDS; ++i)*/ begin | ||
| 60 | automatic pdp_word_address_t addr = 0; | ||
| 61 | addr[`PDP_ADDRESS_BITS-1:$clog2(`RAM_LINE_WORDS)] = hold.address; | ||
| 62 | // if (`RAM_LINE_WORDS != 1) | ||
| 63 | // addr[$clog2(`RAM_LINE_WORDS)-1:0] = i; | ||
| 64 | read_data.data[/*i*/0] = storage[addr]; | ||
| 40 | end | 65 | end |
| 66 | hold_valid = 0; | ||
| 41 | end | 67 | end |
| 42 | ready = 1; | 68 | |
| 69 | command_ready = !hold_valid; | ||
| 43 | end | 70 | end |
| 44 | end | 71 | end |
| 45 | 72 | ||
| 46 | endmodule | 73 | endmodule |
| 47 | 74 | ||
| 48 | module core | 75 | module core |
| 49 | #( ADDR_BITS = 15 | ||
| 50 | , DATA_BITS = 12 | ||
| 51 | ) | ||
| 52 | ( input bit clk | 76 | ( input bit clk |
| 53 | , input bit reset | 77 | , input bit reset |
| 54 | 78 | ||
| 55 | , input bit [2:0] switch_df | 79 | , input bit [2:0] switch_df |
| 56 | , input bit [2:0] switch_if | 80 | , input bit [2:0] switch_if |
| 57 | , input bit [ADDR_BITS-3-1:0] switch_sr | 81 | , input bit [`PDP_ADDRESS_BITS-3-1:0] switch_sr |
| 58 | , input bit switch_start | 82 | , input bit switch_start |
| 59 | , input bit switch_load_add | 83 | , input bit switch_load_add |
| 60 | , input bit switch_dep | 84 | , input bit switch_dep |
| @@ -65,11 +89,11 @@ module core | |||
| 65 | , input bit switch_sing_inst | 89 | , input bit switch_sing_inst |
| 66 | 90 | ||
| 67 | // verilator lint_off UNDRIVEN | 91 | // verilator lint_off UNDRIVEN |
| 68 | , output bit [ADDR_BITS-3-1:0] led_pc | 92 | , output bit [`PDP_ADDRESS_BITS-3-1:0] led_pc |
| 69 | , output bit [ADDR_BITS-3-1:0] led_memaddr | 93 | , output bit [`PDP_ADDRESS_BITS-3-1:0] led_memaddr |
| 70 | , output bit [DATA_BITS-1:0] led_memdata | 94 | , output bit [`DATA_BITS-1:0] led_memdata |
| 71 | , output bit [DATA_BITS-1:0] led_acc | 95 | , output bit [`DATA_BITS-1:0] led_acc |
| 72 | , output bit [DATA_BITS-1:0] led_mq | 96 | , output bit [`DATA_BITS-1:0] led_mq |
| 73 | , output bit led_and | 97 | , output bit led_and |
| 74 | , output bit led_tad | 98 | , output bit led_tad |
| 75 | , output bit led_isz | 99 | , output bit led_isz |
| @@ -137,32 +161,37 @@ assign led_ion = int_enable; | |||
| 137 | bit mem_ready; | 161 | bit mem_ready; |
| 138 | bit mem_valid; | 162 | bit mem_valid; |
| 139 | bit mem_write; | 163 | bit mem_write; |
| 140 | bit [ADDR_BITS-1:0] mem_address; | 164 | bit [`PDP_ADDRESS_BITS-1:0] mem_address; |
| 141 | bit [DATA_BITS-1:0] mem_write_data; | 165 | bit [`DATA_BITS-1:0] mem_write_data; |
| 142 | assign led_current_address = mem_valid; | 166 | assign led_current_address = mem_valid; |
| 143 | 167 | ||
| 144 | assign led_memaddr = mem_address[ADDR_BITS-3-1:0]; | 168 | assign led_memaddr = mem_address[`PDP_ADDRESS_BITS-3-1:0]; |
| 145 | 169 | ||
| 146 | bit mem_read_valid; | 170 | bit mem_read_valid; |
| 147 | bit [DATA_BITS-1:0] mem_read_data; | 171 | bit [`DATA_BITS-1:0] mem_read_data; |
| 172 | |||
| 173 | pdp_command_t mem_command; | ||
| 174 | pdp_read_response_t mem_response; | ||
| 175 | |||
| 176 | assign mem_command.address = mem_address; | ||
| 177 | assign mem_command.write = mem_write; | ||
| 178 | assign mem_command.data = mem_write_data; | ||
| 179 | assign mem_command.mask = ~0; | ||
| 180 | assign mem_read_data = mem_response.data; | ||
| 148 | 181 | ||
| 149 | mem | 182 | mem |
| 150 | #( .ADDR_BITS(ADDR_BITS) | 183 | #( .INIT_FILE("mem/focal69.loaded.hex") |
| 151 | , .DATA_BITS(DATA_BITS) | 184 | ) memory |
| 152 | , .INIT_FILE("mem/focal69.loaded.hex") | ||
| 153 | ) | ||
| 154 | memory | ||
| 155 | ( .clk(clk) | 185 | ( .clk(clk) |
| 156 | , .reset(reset) | 186 | , .reset(reset) |
| 157 | 187 | ||
| 158 | , .ready(mem_ready) | 188 | , .command_ready(mem_ready) |
| 159 | , .valid(mem_valid) | 189 | , .command_valid(mem_valid) |
| 160 | , .address(mem_address) | 190 | , .command_data(mem_command) |
| 161 | , .write(mem_write) | ||
| 162 | , .write_data(mem_write_data) | ||
| 163 | 191 | ||
| 192 | , .read_ready(1) | ||
| 164 | , .read_valid(mem_read_valid) | 193 | , .read_valid(mem_read_valid) |
| 165 | , .read_data(mem_read_data) | 194 | , .read_data(mem_response) |
| 166 | ); | 195 | ); |
| 167 | 196 | ||
| 168 | bit rx_ready; | 197 | bit rx_ready; |
| @@ -191,19 +220,19 @@ alt_jtag_atlantic | |||
| 191 | , .t_ena(rx_valid) | 220 | , .t_ena(rx_valid) |
| 192 | ); | 221 | ); |
| 193 | 222 | ||
| 194 | bit [ADDR_BITS-3-1:7] page; | 223 | bit [`PDP_ADDRESS_BITS-3-1:7] page; |
| 195 | 224 | ||
| 196 | bit [2:0] data_field; | 225 | bit [2:0] data_field; |
| 197 | bit [2:0] data_field_saved; | 226 | bit [2:0] data_field_saved; |
| 198 | bit [2:0] inst_field; | 227 | bit [2:0] inst_field; |
| 199 | bit [2:0] inst_field_buffer; | 228 | bit [2:0] inst_field_buffer; |
| 200 | bit [2:0] inst_field_saved; | 229 | bit [2:0] inst_field_saved; |
| 201 | bit [ADDR_BITS-3-1:0] pc; | 230 | bit [`PDP_ADDRESS_BITS-3-1:0] pc; |
| 202 | bit [ADDR_BITS-3-1:0] next_pc; | 231 | bit [`PDP_ADDRESS_BITS-3-1:0] next_pc; |
| 203 | assign led_pc = pc; | 232 | assign led_pc = pc; |
| 204 | bit [2:0] opcode; | 233 | bit [2:0] opcode; |
| 205 | bit [8:0] operand; | 234 | bit [8:0] operand; |
| 206 | bit [DATA_BITS-1:0] acc; | 235 | bit [`DATA_BITS-1:0] acc; |
| 207 | bit link; | 236 | bit link; |
| 208 | 237 | ||
| 209 | assign led_df = data_field; | 238 | assign led_df = data_field; |
| @@ -223,7 +252,7 @@ assign led_opr = opcode == 7; | |||
| 223 | 252 | ||
| 224 | bit tti_int_enable; | 253 | bit tti_int_enable; |
| 225 | bit tti_valid; | 254 | bit tti_valid; |
| 226 | bit [DATA_BITS-1:0] tti_data; | 255 | bit [`DATA_BITS-1:0] tti_data; |
| 227 | 256 | ||
| 228 | bit [15:0] tto_delay; | 257 | bit [15:0] tto_delay; |
| 229 | bit tto_int_enable; | 258 | bit tto_int_enable; |
| @@ -233,7 +262,7 @@ bit tto_flag_old; | |||
| 233 | bit i; | 262 | bit i; |
| 234 | bit z; | 263 | bit z; |
| 235 | bit [6:0] wip; | 264 | bit [6:0] wip; |
| 236 | bit [ADDR_BITS-1:0] address; | 265 | bit [`PDP_ADDRESS_BITS-1:0] address; |
| 237 | 266 | ||
| 238 | bit can_skip; | 267 | bit can_skip; |
| 239 | bit skip; | 268 | bit skip; |
| @@ -398,7 +427,7 @@ always_ff @(posedge clk) begin | |||
| 398 | mem_write = 0; | 427 | mem_write = 0; |
| 399 | if (`lag(mem_ready)) begin | 428 | if (`lag(mem_ready)) begin |
| 400 | state = DECODE; | 429 | state = DECODE; |
| 401 | page = pc[ADDR_BITS-3-1:7]; | 430 | page = pc[`PDP_ADDRESS_BITS-3-1:7]; |
| 402 | next_pc = pc + 1; | 431 | next_pc = pc + 1; |
| 403 | end | 432 | end |
| 404 | end | 433 | end |
| @@ -454,7 +483,7 @@ always_ff @(posedge clk) begin | |||
| 454 | if (i) begin | 483 | if (i) begin |
| 455 | state = INDIRECT; | 484 | state = INDIRECT; |
| 456 | end else begin | 485 | end else begin |
| 457 | next_pc = address[ADDR_BITS-3-1:0]; | 486 | next_pc = address[`PDP_ADDRESS_BITS-3-1:0]; |
| 458 | inst_field = inst_field_buffer; | 487 | inst_field = inst_field_buffer; |
| 459 | end | 488 | end |
| 460 | end | 489 | end |
| @@ -681,7 +710,7 @@ always_ff @(posedge clk) begin | |||
| 681 | led_memdata = `lag(mem_read_data); | 710 | led_memdata = `lag(mem_read_data); |
| 682 | address = {3'b0, `lag(mem_read_data)}; | 711 | address = {3'b0, `lag(mem_read_data)}; |
| 683 | address += 1; | 712 | address += 1; |
| 684 | address[ADDR_BITS-1:ADDR_BITS-3] = data_field; | 713 | address[`PDP_ADDRESS_BITS-1:`PDP_ADDRESS_BITS-3] = data_field; |
| 685 | state = PREINC; | 714 | state = PREINC; |
| 686 | end else begin | 715 | end else begin |
| 687 | led_memdata = `lag(mem_read_data); | 716 | led_memdata = `lag(mem_read_data); |
| @@ -690,7 +719,7 @@ always_ff @(posedge clk) begin | |||
| 690 | 'o0, 'o1, 'o2: state = AGEN; | 719 | 'o0, 'o1, 'o2: state = AGEN; |
| 691 | 'o3, 'o4: state = EXEC; | 720 | 'o3, 'o4: state = EXEC; |
| 692 | 'o5: begin | 721 | 'o5: begin |
| 693 | next_pc = address[ADDR_BITS-3-1:0]; | 722 | next_pc = address[`PDP_ADDRESS_BITS-3-1:0]; |
| 694 | $display("indirect jump to %o", next_pc); | 723 | $display("indirect jump to %o", next_pc); |
| 695 | inst_field = inst_field_buffer; | 724 | inst_field = inst_field_buffer; |
| 696 | state = RETIRE; | 725 | state = RETIRE; |
| @@ -703,7 +732,7 @@ always_ff @(posedge clk) begin | |||
| 703 | PREINC: begin | 732 | PREINC: begin |
| 704 | mem_valid = 1; | 733 | mem_valid = 1; |
| 705 | mem_write = 1; | 734 | mem_write = 1; |
| 706 | mem_write_data = address[DATA_BITS-1:0]; | 735 | mem_write_data = address[`DATA_BITS-1:0]; |
| 707 | led_memdata = mem_write_data; | 736 | led_memdata = mem_write_data; |
| 708 | $display("preinc [%o] <- %o", mem_address, mem_write_data); | 737 | $display("preinc [%o] <- %o", mem_address, mem_write_data); |
| 709 | case (opcode) | 738 | case (opcode) |
| @@ -762,15 +791,15 @@ always_ff @(posedge clk) begin | |||
| 762 | mem_valid = 1; | 791 | mem_valid = 1; |
| 763 | mem_address = address; | 792 | mem_address = address; |
| 764 | mem_write = 1; | 793 | mem_write = 1; |
| 765 | mem_write_data = next_pc[DATA_BITS-1:0]; | 794 | mem_write_data = next_pc[`DATA_BITS-1:0]; |
| 766 | led_memdata = mem_write_data; | 795 | led_memdata = mem_write_data; |
| 767 | $display("store [%o] <- %o", mem_address, mem_write_data); | 796 | $display("store [%o] <- %o", mem_address, mem_write_data); |
| 768 | next_pc = address[ADDR_BITS-3-1:0] + 1; | 797 | next_pc = address[`PDP_ADDRESS_BITS-3-1:0] + 1; |
| 769 | inst_field = inst_field_buffer; | 798 | inst_field = inst_field_buffer; |
| 770 | state = MEMWAIT; | 799 | state = MEMWAIT; |
| 771 | end | 800 | end |
| 772 | 'o5: begin | 801 | 'o5: begin |
| 773 | next_pc = address[ADDR_BITS-3-1:0]; | 802 | next_pc = address[`PDP_ADDRESS_BITS-3-1:0]; |
| 774 | inst_field = inst_field_buffer; | 803 | inst_field = inst_field_buffer; |
| 775 | end | 804 | end |
| 776 | endcase | 805 | endcase |
| @@ -788,7 +817,7 @@ always_ff @(posedge clk) begin | |||
| 788 | DEPOSIT: begin | 817 | DEPOSIT: begin |
| 789 | if (`lag(mem_ready)) begin | 818 | if (`lag(mem_ready)) begin |
| 790 | state = FETCH; // Not a retired instruction; go directly to decode | 819 | state = FETCH; // Not a retired instruction; go directly to decode |
| 791 | page = pc[ADDR_BITS-3-1:7]; | 820 | page = pc[`PDP_ADDRESS_BITS-3-1:7]; |
| 792 | ++pc; // Not a skip; normal part of panel deposit (because we are skipping RETIRE) | 821 | ++pc; // Not a skip; normal part of panel deposit (because we are skipping RETIRE) |
| 793 | run = 0; | 822 | run = 0; |
| 794 | end | 823 | end |
