summaryrefslogtreecommitdiff
path: root/hdl
diff options
context:
space:
mode:
Diffstat (limited to 'hdl')
-rw-r--r--hdl/core.sv259
-rw-r--r--hdl/top.sv5
2 files changed, 177 insertions, 87 deletions
diff --git a/hdl/core.sv b/hdl/core.sv
index b607e4b..34a1e44 100644
--- a/hdl/core.sv
+++ b/hdl/core.sv
@@ -1,7 +1,7 @@
1`include "util.svh" 1`include "util.svh"
2 2
3module core 3module core
4 #( ADDR_BITS = 12 4 #( ADDR_BITS = 15
5 , DATA_BITS = 12 5 , DATA_BITS = 12
6 ) 6 )
7 ( input bit clk 7 ( input bit clk
@@ -9,7 +9,7 @@ module core
9 9
10 , input bit [2:0] switch_df 10 , input bit [2:0] switch_df
11 , input bit [2:0] switch_if 11 , input bit [2:0] switch_if
12 , input bit [ADDR_BITS-1:0] switch_sr 12 , input bit [ADDR_BITS-3-1:0] switch_sr
13 , input bit switch_start 13 , input bit switch_start
14 , input bit switch_load_add 14 , input bit switch_load_add
15 , input bit switch_dep 15 , input bit switch_dep
@@ -20,8 +20,8 @@ module core
20 , input bit switch_sing_inst 20 , input bit switch_sing_inst
21 21
22 // verilator lint_off UNDRIVEN 22 // verilator lint_off UNDRIVEN
23 , output bit [ADDR_BITS-1:0] led_pc 23 , output bit [ADDR_BITS-3-1:0] led_pc
24 , output bit [ADDR_BITS-1:0] led_memaddr 24 , output bit [ADDR_BITS-3-1:0] led_memaddr
25 , output bit [DATA_BITS-1:0] led_memdata 25 , output bit [DATA_BITS-1:0] led_memdata
26 , output bit [DATA_BITS-1:0] led_acc 26 , output bit [DATA_BITS-1:0] led_acc
27 , output bit [DATA_BITS-1:0] led_mq 27 , output bit [DATA_BITS-1:0] led_mq
@@ -70,9 +70,7 @@ bit [ADDR_BITS-1:0] mem_address;
70bit [DATA_BITS-1:0] mem_write_data; 70bit [DATA_BITS-1:0] mem_write_data;
71assign led_current_address = mem_valid; 71assign led_current_address = mem_valid;
72 72
73assign led_df = switch_df; // FIXME actually implement DF and IF 73assign led_memaddr = mem_address[ADDR_BITS-3-1:0];
74assign led_if = switch_if;
75assign led_memaddr = mem_address;
76 74
77bit mem_read_valid; 75bit mem_read_valid;
78bit [DATA_BITS-1:0] mem_read_data; 76bit [DATA_BITS-1:0] mem_read_data;
@@ -80,8 +78,8 @@ bit [DATA_BITS-1:0] mem_read_data;
80mem 78mem
81 #( .ADDR_BITS(ADDR_BITS) 79 #( .ADDR_BITS(ADDR_BITS)
82 , .DATA_BITS(DATA_BITS) 80 , .DATA_BITS(DATA_BITS)
83// , .INIT_FILE("mem/focal69.loaded.hex") 81 , .INIT_FILE("mem/focal69.loaded.hex")
84 , .INIT_FILE("build/mem/hello.hex") 82// , .INIT_FILE("build/mem/hello.hex")
85 ) 83 )
86 memory 84 memory
87 ( .clk(clk) 85 ( .clk(clk)
@@ -120,14 +118,23 @@ jtag_uart
120 , .tx_data(tx_data) 118 , .tx_data(tx_data)
121 ); 119 );
122 120
123bit [ADDR_BITS-1:7] page; 121bit [ADDR_BITS-3-1:7] page;
124 122
125bit [ADDR_BITS-1:0] pc; 123bit [2:0] data_field;
124bit [2:0] data_field_saved;
125bit [2:0] inst_field;
126bit [2:0] inst_field_buffer;
127bit [2:0] inst_field_saved;
128bit [ADDR_BITS-3-1:0] pc;
129assign led_pc = pc;
126bit [2:0] opcode; 130bit [2:0] opcode;
127bit [8:0] operand; 131bit [8:0] operand;
128bit [DATA_BITS-1:0] acc; 132bit [DATA_BITS-1:0] acc;
129bit link; 133bit link;
130 134
135assign led_df = data_field;
136assign led_if = inst_field;
137
131assign led_acc = acc; 138assign led_acc = acc;
132assign led_link = link; 139assign led_link = link;
133 140
@@ -163,16 +170,21 @@ enum
163 , EXEC 170 , EXEC
164 , MEMWAIT 171 , MEMWAIT
165 , HALT 172 , HALT
173 , DEPOSIT
166 } state; 174 } state;
167 175
168assign led_fetch = state == FETCH || state == DECODE; 176assign led_fetch = state == FETCH;
169assign led_execute = state == AGEN || state == EXEC; 177assign led_execute = state == DECODE || state == AGEN || state == EXEC;
170assign led_defer = state == INDIRECT || state == INDIRECTED || state == PREINC; 178assign led_defer = state == INDIRECT || state == INDIRECTED || state == PREINC;
171assign led_pause = state == MEMWAIT || state == HALT; 179assign led_pause = state == MEMWAIT || state == HALT;
172 180
173always_ff @(posedge clk) begin 181always_ff @(posedge clk) begin
174 if (reset) begin 182 if (reset) begin
183`ifdef SYNTHESIS
175 run = 0; 184 run = 0;
185`else
186 run = 1;
187`endif
176 int_enable = 0; 188 int_enable = 0;
177 int_delay = 0; 189 int_delay = 0;
178 switch_start_observed = 0; 190 switch_start_observed = 0;
@@ -184,8 +196,12 @@ always_ff @(posedge clk) begin
184 rx_ready = 0; 196 rx_ready = 0;
185 tx_valid = 0; 197 tx_valid = 0;
186 tx_data = 0; 198 tx_data = 0;
199 data_field = 0;
200 data_field_saved = 0;
201 inst_field = 0;
202 inst_field_buffer = 0;
203 inst_field_saved = 0;
187 pc = 'o200; 204 pc = 'o200;
188 led_pc = pc;
189 acc = 0; 205 acc = 0;
190 link = 1; 206 link = 1;
191 tti_int_enable = 0; 207 tti_int_enable = 0;
@@ -208,22 +224,42 @@ always_ff @(posedge clk) begin
208 224
209 if (switch_load_add && !switch_load_add_observed) begin 225 if (switch_load_add && !switch_load_add_observed) begin
210 switch_load_add_observed = 1; 226 switch_load_add_observed = 1;
227 data_field = switch_df;
228 inst_field = switch_if;
229 inst_field_buffer = switch_if;
211 pc = switch_sr; 230 pc = switch_sr;
212 led_pc = pc;
213 end 231 end
214 232
215 if (!switch_load_add) 233 if (!switch_load_add)
216 switch_load_add_observed = 0; 234 switch_load_add_observed = 0;
217 235
236`ifdef HISTORIC_SWITCH_BEHAVIOUR
237 if (switch_dep)
238 switch_dep_observed = 1;
239
240 if (!switch_dep && switch_dep_observed) begin
241`else
218 if (switch_dep && !switch_dep_observed) begin 242 if (switch_dep && !switch_dep_observed) begin
219 switch_dep_observed = 1; 243 switch_dep_observed = 1;
244`endif
245 state = DEPOSIT;
246 mem_valid = 1;
247 mem_address = {inst_field, pc};
248 mem_write = 1;
249 mem_write_data = switch_sr;
250 led_memdata = mem_write_data;
251 run = 1;
220 end 252 end
221 253
222 if (!switch_dep) 254 if (!switch_dep)
223 switch_dep_observed = 0; 255 switch_dep_observed = 0;
224 256
225 if (switch_exam && !switch_exam_observed) begin 257 if (switch_exam && !switch_exam_observed) begin
226 switch_exam_observed = 1; 258 if (!run) begin
259 switch_exam_observed = 1;
260 state = FETCH;
261 run = 1;
262 end
227 end 263 end
228 264
229 if (!switch_exam) 265 if (!switch_exam)
@@ -250,12 +286,11 @@ always_ff @(posedge clk) begin
250 case (state) 286 case (state)
251 FETCH: begin 287 FETCH: begin
252 mem_valid = 1; 288 mem_valid = 1;
253 mem_address = pc; 289 mem_address = {inst_field, pc};
254 mem_write = 0; 290 mem_write = 0;
255 if (`lag(mem_ready)) begin 291 if (`lag(mem_ready)) begin
256 state = DECODE; 292 state = DECODE;
257 page = pc[ADDR_BITS-1:7]; 293 page = pc[ADDR_BITS-3-1:7];
258 led_pc = pc;
259 ++pc; 294 ++pc;
260 end 295 end
261 end 296 end
@@ -265,18 +300,27 @@ always_ff @(posedge clk) begin
265 go = 0; 300 go = 0;
266 mem_valid = 0; 301 mem_valid = 0;
267 mem_write = 0; 302 mem_write = 0;
268 if (int_enable && int_request) begin 303 if (!switch_exam_observed && (int_enable && int_request)) begin
269 int_enable = 0; 304 int_enable = 0;
270 int_delay = 0; 305 int_delay = 0;
306 data_field_saved = data_field;
307 inst_field_saved = inst_field;
308 data_field = 0;
309 inst_field = 0;
310 inst_field_buffer = 0;
271 --pc; 311 --pc;
272 opcode = 'b100; 312 opcode = 'b100;
273 operand = 'b000000; 313 operand = 'b000000000;
274 go = 1; 314 go = 1;
275 end else if (`lag(mem_read_valid)) begin 315 end else if (`lag(mem_read_valid)) begin
276 state = FETCH; 316 state = FETCH;
277 led_memdata = `lag(mem_read_data); 317 led_memdata = `lag(mem_read_data);
278 {opcode, operand} = `lag(mem_read_data); 318 {opcode, operand} = `lag(mem_read_data);
279 go = 1; 319 if (switch_exam_observed) begin
320 run = 0;
321 end else begin
322 go = 1;
323 end
280 end 324 end
281 if (go) begin 325 if (go) begin
282 int_enable = int_delay; 326 int_enable = int_delay;
@@ -286,9 +330,9 @@ always_ff @(posedge clk) begin
286 // verilator lint_on WIDTH 330 // verilator lint_on WIDTH
287 {i, z, wip} = operand; 331 {i, z, wip} = operand;
288 if (z) 332 if (z)
289 address = {page, wip}; 333 address = {inst_field, page, wip};
290 else 334 else
291 address = {5'b0, wip}; 335 address = {inst_field, 5'b0, wip};
292 case (opcode) 336 case (opcode)
293 'o0, 'o1, 'o2: state = i ? INDIRECT : AGEN; 337 'o0, 'o1, 'o2: state = i ? INDIRECT : AGEN;
294 'o3, 'o4: state = i ? INDIRECT : EXEC; 338 'o3, 'o4: state = i ? INDIRECT : EXEC;
@@ -296,7 +340,8 @@ always_ff @(posedge clk) begin
296 if (i) begin 340 if (i) begin
297 state = INDIRECT; 341 state = INDIRECT;
298 end else begin 342 end else begin
299 pc = address; 343 pc = address[ADDR_BITS-3-1:0];
344 inst_field = inst_field_buffer;
300 end 345 end
301 end 346 end
302 'o7: begin 347 'o7: begin
@@ -358,73 +403,98 @@ always_ff @(posedge clk) begin
358 endcase 403 endcase
359 end 404 end
360 'o6: begin 405 'o6: begin
361 case (operand[8:3]) 406 case (operand[8:6])
362 'o00: begin 407 'o0: begin
363 case (operand[2:0]) 408 case (operand[5:3])
364 'o0: begin 409 'o0: begin
365 if (int_enable) 410 case (operand[2:0])
366 ++pc; 411 'o0: begin
367 int_enable = 0; 412 if (int_enable)
368 int_delay = 0; 413 ++pc;
369 end 414 int_enable = 0;
370 'o1: int_delay = 1; 415 int_delay = 0;
371 'o2: begin 416 end
372 int_enable = 0; 417 'o1: int_delay = 1;
373 int_delay = 0; 418 'o2: begin
419 int_enable = 0;
420 int_delay = 0;
421 end
422 'o3: begin
423 if (int_request)
424 ++pc;
425 end
426 'o4: acc = {link, 1'b0/*gt*/, int_request, 1'b0/*ii*/, int_enable, 1'b0/*u*/, 3'b0/*if*/, 3'b0/*df*/};
427 'o5: begin
428 link = acc[11];
429 if (acc[7]) begin
430 int_delay = 1;
431 end else begin
432 int_enable = 0;
433 int_delay = 0;
434 end
435 end
436 'o7: begin
437 int_enable = 0;
438 int_delay = 0;
439 acc = 0;
440 link = 1;
441 tx_valid = 0;
442 tti_valid = 0;
443 end
444 default: $display("%o: unsupported 600%o op", pc-1, operand[2:0]);
445 endcase
374 end 446 end
375 'o3: begin 447 'o3: begin
376 if (int_request) 448 case (operand[2:0])
377 ++pc; 449 'o1: if (tti_valid) pc++;
378 end 450 'o5: begin
379 'o4: acc = {link, 1'b0/*gt*/, int_request, 1'b0/*ii*/, int_enable, 1'b0/*u*/, 3'b0/*if*/, 3'b0/*df*/}; 451 tti_int_enable = acc[0];
380 'o5: begin 452 end
381 link = acc[11]; 453 'o6: begin
382 if (acc[7]) begin 454 acc = tti_data;
383 int_delay = 1; 455 tti_valid = 0;
384 end else begin 456 end
385 int_enable = 0; 457 default: begin
386 int_delay = 0; 458 $display("%o: unsupported keyboard op %o", pc-1, operand[2:0]);
387 end 459 $finish;
388 end 460 end
389 'o7: begin 461 endcase
390 int_enable = 0;
391 int_delay = 0;
392 acc = 0;
393 link = 1;
394 tx_valid = 0;
395 tti_valid = 0;
396 end
397 default: $display("%o: unsupported 600%o op", pc-1, operand[2:0]);
398 endcase
399 end
400 'o03: begin
401 case (operand[2:0])
402 'o1: if (tti_valid) pc++;
403 'o5: begin
404 tti_int_enable = acc[0];
405 end 462 end
406 'o6: begin 463 'o4: begin
407 acc = tti_data; 464 case (operand[2:0])
408 tti_valid = 0; 465 'o1: if (!tx_valid) pc++;
466 'o6: begin
467 tx_valid = 1;
468 tx_data = {1'b0, acc[6:0]};
469 end
470 default: begin
471 $display("%o: unsupported tty op %o", pc-1, operand[2:0]);
472 $finish;
473 end
474 endcase
409 end 475 end
410 default: begin 476 default: begin
411 $display("%o: unsupported keyboard op %o", pc-1, operand[2:0]); 477 $display("%o: unsupported device %o (operation %o)", pc-1, operand[8:3], operand[2:0]);
412 $finish;
413 end 478 end
414 endcase 479 endcase
415 end 480 end
416 'o04: begin 481 'o2: begin
417 case (operand[2:0]) 482 if (operand[0])
418 'o1: if (!tx_valid) pc++; 483 data_field = operand[5:3];
419 'o6: begin 484 if (operand[1])
420 tx_valid = 1; 485 inst_field_buffer = operand[5:3];
421 tx_data = {1'b0, acc[6:0]}; 486 if (operand[2]) begin
487 if (operand[3] && operand[4])
488 acc = acc | {6'b0, inst_field_saved, data_field_saved};
489 else if (operand[3])
490 acc = acc | {6'b0, data_field, 3'b0};
491 else if (operand[4])
492 acc = acc | {6'b0, inst_field, 3'b0};
493 if (operand[5]) begin
494 data_field = data_field_saved;
495 inst_field_buffer = inst_field_saved;
422 end 496 end
423 default: begin 497 end
424 $display("%o: unsupported tty op %o", pc-1, operand[2:0]);
425 $finish;
426 end
427 endcase
428 end 498 end
429 default: begin 499 default: begin
430 $display("%o: unsupported device %o (operation %o)", pc-1, operand[8:3], operand[2:0]); 500 $display("%o: unsupported device %o (operation %o)", pc-1, operand[8:3], operand[2:0]);
@@ -454,17 +524,19 @@ always_ff @(posedge clk) begin
454 if (`lag(mem_read_valid)) begin 524 if (`lag(mem_read_valid)) begin
455 if (address[7:3] == 5'b00001) begin 525 if (address[7:3] == 5'b00001) begin
456 led_memdata = `lag(mem_read_data); 526 led_memdata = `lag(mem_read_data);
457 address = {{(ADDR_BITS - DATA_BITS){1'b0}}, `lag(mem_read_data)}; 527 address = {3'b0, `lag(mem_read_data)};
458 address += 1; 528 address += 1;
529 address[ADDR_BITS-1:ADDR_BITS-3] = data_field;
459 state = PREINC; 530 state = PREINC;
460 end else begin 531 end else begin
461 led_memdata = `lag(mem_read_data); 532 led_memdata = `lag(mem_read_data);
462 address = {{(ADDR_BITS - DATA_BITS){1'b0}}, `lag(mem_read_data)}; 533 address = {data_field, `lag(mem_read_data)};
463 case (opcode) 534 case (opcode)
464 'o0, 'o1, 'o2: state = AGEN; 535 'o0, 'o1, 'o2: state = AGEN;
465 'o3, 'o4: state = EXEC; 536 'o3, 'o4: state = EXEC;
466 'o5: begin 537 'o5: begin
467 pc = address; 538 pc = address[ADDR_BITS-3-1:0];
539 inst_field = inst_field_buffer;
468 state = FETCH; 540 state = FETCH;
469 end 541 end
470 endcase 542 endcase
@@ -532,10 +604,14 @@ always_ff @(posedge clk) begin
532 mem_write = 1; 604 mem_write = 1;
533 mem_write_data = pc[DATA_BITS-1:0]; 605 mem_write_data = pc[DATA_BITS-1:0];
534 led_memdata = mem_write_data; 606 led_memdata = mem_write_data;
535 pc = address + 1; 607 pc = address[ADDR_BITS-3-1:0] + 1;
608 inst_field = inst_field_buffer;
536 state = MEMWAIT; 609 state = MEMWAIT;
537 end 610 end
538 'o5: pc = address; 611 'o5: begin
612 pc = address[ADDR_BITS-3-1:0];
613 inst_field = inst_field_buffer;
614 end
539 endcase 615 endcase
540 end 616 end
541 end 617 end
@@ -547,6 +623,15 @@ always_ff @(posedge clk) begin
547 $display("\nhalt state reached"); 623 $display("\nhalt state reached");
548 $finish; 624 $finish;
549 end 625 end
626
627 DEPOSIT: begin
628 if (`lag(mem_ready)) begin
629 state = FETCH;
630 page = pc[ADDR_BITS-3-1:7];
631 ++pc;
632 run = 0;
633 end
634 end
550 endcase 635 endcase
551 636
552 if (switch_sing_step) 637 if (switch_sing_step)
diff --git a/hdl/top.sv b/hdl/top.sv
index 67e3437..2dd52ab 100644
--- a/hdl/top.sv
+++ b/hdl/top.sv
@@ -73,8 +73,13 @@ assign switch_dep = switch[3][3];
73assign switch_exam = switch[3][4]; 73assign switch_exam = switch[3][4];
74assign switch_cont = switch[3][5]; 74assign switch_cont = switch[3][5];
75assign switch_stop = switch[3][6]; 75assign switch_stop = switch[3][6];
76`ifdef HISTORIC_SWITCH_BEHAVIOUR
77assign switch_sing_step = !switch[3][7];
78assign switch_sing_inst = !switch[3][8];
79`else
76assign switch_sing_step = switch[3][7]; 80assign switch_sing_step = switch[3][7];
77assign switch_sing_inst = switch[3][8]; 81assign switch_sing_inst = switch[3][8];
82`endif
78 83
79bit [11:0] led_pc; 84bit [11:0] led_pc;
80bit [11:0] led_memaddr; 85bit [11:0] led_memaddr;