From ca0c557e2c61e2fc6cc97482a17f68fd2ee61392 Mon Sep 17 00:00:00 2001 From: Julian Blake Kongslie Date: Sun, 5 Dec 2021 15:16:41 -0800 Subject: Implement DF and IF, and Dep and Exam switches. --- PLAN | 12 --- hdl/core.sv | 259 ++++++++++++++++++++++++++++++++++++------------------ hdl/top.sv | 5 ++ mem/hello.pal | 1 + mem/jtag_uart.hex | 12 +-- mem/typescript | 10 +-- 6 files changed, 189 insertions(+), 110 deletions(-) diff --git a/PLAN b/PLAN index 2283c2f..e9689e2 100644 --- a/PLAN +++ b/PLAN @@ -1,11 +1,5 @@ Turn on blinkenlights from the PDP core -Implement switch features: - Deposit - needs a state machine - [pc++] = switch_sr - Examine - needs a state machine - led_memdata = [pc++] - Implement remaining TTY output instructions Jules thinks clock is most likely interrupt source @@ -17,9 +11,3 @@ Sources of interrupts observed: TTO ready for output interrupt - this looks like a very likely candidate TTI input ready interrupt - this looks like a very likely candidate Looks like these happen even when there is no input available - might be caused by the program itself doing something a little funny - -Implement IF/DF fields - Will need to update behaviour of switch_load_add - -Add a macro for reversing polarity of switch_sing_step and switch_sing_inst and -making switch_dep happen on key lift instead of key press 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 @@ `include "util.svh" module core - #( ADDR_BITS = 12 + #( ADDR_BITS = 15 , DATA_BITS = 12 ) ( input bit clk @@ -9,7 +9,7 @@ module core , input bit [2:0] switch_df , input bit [2:0] switch_if - , input bit [ADDR_BITS-1:0] switch_sr + , input bit [ADDR_BITS-3-1:0] switch_sr , input bit switch_start , input bit switch_load_add , input bit switch_dep @@ -20,8 +20,8 @@ module core , input bit switch_sing_inst // verilator lint_off UNDRIVEN - , output bit [ADDR_BITS-1:0] led_pc - , output bit [ADDR_BITS-1:0] led_memaddr + , output bit [ADDR_BITS-3-1:0] led_pc + , output bit [ADDR_BITS-3-1:0] led_memaddr , output bit [DATA_BITS-1:0] led_memdata , output bit [DATA_BITS-1:0] led_acc , output bit [DATA_BITS-1:0] led_mq @@ -70,9 +70,7 @@ bit [ADDR_BITS-1:0] mem_address; bit [DATA_BITS-1:0] mem_write_data; assign led_current_address = mem_valid; -assign led_df = switch_df; // FIXME actually implement DF and IF -assign led_if = switch_if; -assign led_memaddr = mem_address; +assign led_memaddr = mem_address[ADDR_BITS-3-1:0]; bit mem_read_valid; bit [DATA_BITS-1:0] mem_read_data; @@ -80,8 +78,8 @@ bit [DATA_BITS-1:0] mem_read_data; mem #( .ADDR_BITS(ADDR_BITS) , .DATA_BITS(DATA_BITS) -// , .INIT_FILE("mem/focal69.loaded.hex") - , .INIT_FILE("build/mem/hello.hex") + , .INIT_FILE("mem/focal69.loaded.hex") +// , .INIT_FILE("build/mem/hello.hex") ) memory ( .clk(clk) @@ -120,14 +118,23 @@ jtag_uart , .tx_data(tx_data) ); -bit [ADDR_BITS-1:7] page; +bit [ADDR_BITS-3-1:7] page; -bit [ADDR_BITS-1:0] pc; +bit [2:0] data_field; +bit [2:0] data_field_saved; +bit [2:0] inst_field; +bit [2:0] inst_field_buffer; +bit [2:0] inst_field_saved; +bit [ADDR_BITS-3-1:0] pc; +assign led_pc = pc; bit [2:0] opcode; bit [8:0] operand; bit [DATA_BITS-1:0] acc; bit link; +assign led_df = data_field; +assign led_if = inst_field; + assign led_acc = acc; assign led_link = link; @@ -163,16 +170,21 @@ enum , EXEC , MEMWAIT , HALT + , DEPOSIT } state; -assign led_fetch = state == FETCH || state == DECODE; -assign led_execute = state == AGEN || state == EXEC; +assign led_fetch = state == FETCH; +assign led_execute = state == DECODE || state == AGEN || state == EXEC; assign led_defer = state == INDIRECT || state == INDIRECTED || state == PREINC; assign led_pause = state == MEMWAIT || state == HALT; always_ff @(posedge clk) begin if (reset) begin +`ifdef SYNTHESIS run = 0; +`else + run = 1; +`endif int_enable = 0; int_delay = 0; switch_start_observed = 0; @@ -184,8 +196,12 @@ always_ff @(posedge clk) begin rx_ready = 0; tx_valid = 0; tx_data = 0; + data_field = 0; + data_field_saved = 0; + inst_field = 0; + inst_field_buffer = 0; + inst_field_saved = 0; pc = 'o200; - led_pc = pc; acc = 0; link = 1; tti_int_enable = 0; @@ -208,22 +224,42 @@ always_ff @(posedge clk) begin if (switch_load_add && !switch_load_add_observed) begin switch_load_add_observed = 1; + data_field = switch_df; + inst_field = switch_if; + inst_field_buffer = switch_if; pc = switch_sr; - led_pc = pc; end if (!switch_load_add) switch_load_add_observed = 0; +`ifdef HISTORIC_SWITCH_BEHAVIOUR + if (switch_dep) + switch_dep_observed = 1; + + if (!switch_dep && switch_dep_observed) begin +`else if (switch_dep && !switch_dep_observed) begin switch_dep_observed = 1; +`endif + state = DEPOSIT; + mem_valid = 1; + mem_address = {inst_field, pc}; + mem_write = 1; + mem_write_data = switch_sr; + led_memdata = mem_write_data; + run = 1; end if (!switch_dep) switch_dep_observed = 0; if (switch_exam && !switch_exam_observed) begin - switch_exam_observed = 1; + if (!run) begin + switch_exam_observed = 1; + state = FETCH; + run = 1; + end end if (!switch_exam) @@ -250,12 +286,11 @@ always_ff @(posedge clk) begin case (state) FETCH: begin mem_valid = 1; - mem_address = pc; + mem_address = {inst_field, pc}; mem_write = 0; if (`lag(mem_ready)) begin state = DECODE; - page = pc[ADDR_BITS-1:7]; - led_pc = pc; + page = pc[ADDR_BITS-3-1:7]; ++pc; end end @@ -265,18 +300,27 @@ always_ff @(posedge clk) begin go = 0; mem_valid = 0; mem_write = 0; - if (int_enable && int_request) begin + if (!switch_exam_observed && (int_enable && int_request)) begin int_enable = 0; int_delay = 0; + data_field_saved = data_field; + inst_field_saved = inst_field; + data_field = 0; + inst_field = 0; + inst_field_buffer = 0; --pc; opcode = 'b100; - operand = 'b000000; + operand = 'b000000000; go = 1; end else if (`lag(mem_read_valid)) begin state = FETCH; led_memdata = `lag(mem_read_data); {opcode, operand} = `lag(mem_read_data); - go = 1; + if (switch_exam_observed) begin + run = 0; + end else begin + go = 1; + end end if (go) begin int_enable = int_delay; @@ -286,9 +330,9 @@ always_ff @(posedge clk) begin // verilator lint_on WIDTH {i, z, wip} = operand; if (z) - address = {page, wip}; + address = {inst_field, page, wip}; else - address = {5'b0, wip}; + address = {inst_field, 5'b0, wip}; case (opcode) 'o0, 'o1, 'o2: state = i ? INDIRECT : AGEN; 'o3, 'o4: state = i ? INDIRECT : EXEC; @@ -296,7 +340,8 @@ always_ff @(posedge clk) begin if (i) begin state = INDIRECT; end else begin - pc = address; + pc = address[ADDR_BITS-3-1:0]; + inst_field = inst_field_buffer; end end 'o7: begin @@ -358,73 +403,98 @@ always_ff @(posedge clk) begin endcase end 'o6: begin - case (operand[8:3]) - 'o00: begin - case (operand[2:0]) + case (operand[8:6]) + 'o0: begin + case (operand[5:3]) 'o0: begin - if (int_enable) - ++pc; - int_enable = 0; - int_delay = 0; - end - 'o1: int_delay = 1; - 'o2: begin - int_enable = 0; - int_delay = 0; + case (operand[2:0]) + 'o0: begin + if (int_enable) + ++pc; + int_enable = 0; + int_delay = 0; + end + 'o1: int_delay = 1; + 'o2: begin + int_enable = 0; + int_delay = 0; + end + 'o3: begin + if (int_request) + ++pc; + end + 'o4: acc = {link, 1'b0/*gt*/, int_request, 1'b0/*ii*/, int_enable, 1'b0/*u*/, 3'b0/*if*/, 3'b0/*df*/}; + 'o5: begin + link = acc[11]; + if (acc[7]) begin + int_delay = 1; + end else begin + int_enable = 0; + int_delay = 0; + end + end + 'o7: begin + int_enable = 0; + int_delay = 0; + acc = 0; + link = 1; + tx_valid = 0; + tti_valid = 0; + end + default: $display("%o: unsupported 600%o op", pc-1, operand[2:0]); + endcase end 'o3: begin - if (int_request) - ++pc; - end - 'o4: acc = {link, 1'b0/*gt*/, int_request, 1'b0/*ii*/, int_enable, 1'b0/*u*/, 3'b0/*if*/, 3'b0/*df*/}; - 'o5: begin - link = acc[11]; - if (acc[7]) begin - int_delay = 1; - end else begin - int_enable = 0; - int_delay = 0; - end - end - 'o7: begin - int_enable = 0; - int_delay = 0; - acc = 0; - link = 1; - tx_valid = 0; - tti_valid = 0; - end - default: $display("%o: unsupported 600%o op", pc-1, operand[2:0]); - endcase - end - 'o03: begin - case (operand[2:0]) - 'o1: if (tti_valid) pc++; - 'o5: begin - tti_int_enable = acc[0]; + case (operand[2:0]) + 'o1: if (tti_valid) pc++; + 'o5: begin + tti_int_enable = acc[0]; + end + 'o6: begin + acc = tti_data; + tti_valid = 0; + end + default: begin + $display("%o: unsupported keyboard op %o", pc-1, operand[2:0]); + $finish; + end + endcase end - 'o6: begin - acc = tti_data; - tti_valid = 0; + 'o4: begin + case (operand[2:0]) + 'o1: if (!tx_valid) pc++; + 'o6: begin + tx_valid = 1; + tx_data = {1'b0, acc[6:0]}; + end + default: begin + $display("%o: unsupported tty op %o", pc-1, operand[2:0]); + $finish; + end + endcase end default: begin - $display("%o: unsupported keyboard op %o", pc-1, operand[2:0]); - $finish; + $display("%o: unsupported device %o (operation %o)", pc-1, operand[8:3], operand[2:0]); end endcase end - 'o04: begin - case (operand[2:0]) - 'o1: if (!tx_valid) pc++; - 'o6: begin - tx_valid = 1; - tx_data = {1'b0, acc[6:0]}; + 'o2: begin + if (operand[0]) + data_field = operand[5:3]; + if (operand[1]) + inst_field_buffer = operand[5:3]; + if (operand[2]) begin + if (operand[3] && operand[4]) + acc = acc | {6'b0, inst_field_saved, data_field_saved}; + else if (operand[3]) + acc = acc | {6'b0, data_field, 3'b0}; + else if (operand[4]) + acc = acc | {6'b0, inst_field, 3'b0}; + if (operand[5]) begin + data_field = data_field_saved; + inst_field_buffer = inst_field_saved; end - default: begin - $display("%o: unsupported tty op %o", pc-1, operand[2:0]); - $finish; - end - endcase + end end default: begin $display("%o: unsupported device %o (operation %o)", pc-1, operand[8:3], operand[2:0]); @@ -454,17 +524,19 @@ always_ff @(posedge clk) begin if (`lag(mem_read_valid)) begin if (address[7:3] == 5'b00001) begin led_memdata = `lag(mem_read_data); - address = {{(ADDR_BITS - DATA_BITS){1'b0}}, `lag(mem_read_data)}; + address = {3'b0, `lag(mem_read_data)}; address += 1; + address[ADDR_BITS-1:ADDR_BITS-3] = data_field; state = PREINC; end else begin led_memdata = `lag(mem_read_data); - address = {{(ADDR_BITS - DATA_BITS){1'b0}}, `lag(mem_read_data)}; + address = {data_field, `lag(mem_read_data)}; case (opcode) 'o0, 'o1, 'o2: state = AGEN; 'o3, 'o4: state = EXEC; 'o5: begin - pc = address; + pc = address[ADDR_BITS-3-1:0]; + inst_field = inst_field_buffer; state = FETCH; end endcase @@ -532,10 +604,14 @@ always_ff @(posedge clk) begin mem_write = 1; mem_write_data = pc[DATA_BITS-1:0]; led_memdata = mem_write_data; - pc = address + 1; + pc = address[ADDR_BITS-3-1:0] + 1; + inst_field = inst_field_buffer; state = MEMWAIT; end - 'o5: pc = address; + 'o5: begin + pc = address[ADDR_BITS-3-1:0]; + inst_field = inst_field_buffer; + end endcase end end @@ -547,6 +623,15 @@ always_ff @(posedge clk) begin $display("\nhalt state reached"); $finish; end + + DEPOSIT: begin + if (`lag(mem_ready)) begin + state = FETCH; + page = pc[ADDR_BITS-3-1:7]; + ++pc; + run = 0; + end + end endcase 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]; assign switch_exam = switch[3][4]; assign switch_cont = switch[3][5]; assign switch_stop = switch[3][6]; +`ifdef HISTORIC_SWITCH_BEHAVIOUR +assign switch_sing_step = !switch[3][7]; +assign switch_sing_inst = !switch[3][8]; +`else assign switch_sing_step = switch[3][7]; assign switch_sing_inst = switch[3][8]; +`endif bit [11:0] led_pc; bit [11:0] led_memaddr; diff --git a/mem/hello.pal b/mem/hello.pal index da1c711..89383ba 100644 --- a/mem/hello.pal +++ b/mem/hello.pal @@ -39,6 +39,7 @@ INT, KRB TLS TSF JMP .-1 + RMF ION JMP I Z 000 $ diff --git a/mem/jtag_uart.hex b/mem/jtag_uart.hex index 480fb71..0544e6f 100644 --- a/mem/jtag_uart.hex +++ b/mem/jtag_uart.hex @@ -2,13 +2,13 @@ // od -An -tx1 - 31 2e 31 30 20 53 45 54 20 58 30 3d 30 0d 31 2e - 32 30 20 53 45 54 20 58 31 3d 31 0d 31 2e 33 30 + 31 2e 31 30 20 53 45 54 20 58 30 3d 30 0a 31 2e + 32 30 20 53 45 54 20 58 31 3d 31 0a 31 2e 33 30 20 46 4f 52 20 58 3d 31 2c 31 30 3b 20 44 4f 20 - 32 0d 32 2e 31 20 54 59 50 45 20 58 30 2c 21 0d + 32 0a 32 2e 31 20 54 59 50 45 20 58 30 2c 21 0a 32 2e 32 20 53 45 54 20 58 32 3d 58 30 2b 58 31 - 0d 32 2e 33 20 53 45 54 20 58 30 3d 58 31 0d 32 - 2e 34 20 53 45 54 20 58 31 3d 58 32 0d 32 2e 35 - 20 52 45 54 55 52 4e 0d 47 4f 20 31 2e 31 30 0d + 0a 32 2e 33 20 53 45 54 20 58 30 3d 58 31 0a 32 + 2e 34 20 53 45 54 20 58 31 3d 58 32 0a 32 2e 35 + 20 52 45 54 55 52 4e 0a 47 4f 20 31 2e 31 30 0a 00 diff --git a/mem/typescript b/mem/typescript index 647298f..f5f1186 100644 --- a/mem/typescript +++ b/mem/typescript @@ -1,6 +1,6 @@ -Script started on 2021-05-09 16:17:42-07:00 [TERM="xterm-256color" TTY="/dev/pts/3" COLUMNS="94" LINES="85"] +Script started on 2021-05-09 16:17:42-07:00 [TERM="xterm-256color" TTY="/dev/pts/3" COLUMNS="94" LINES="85"] [?2004h]0;debian:~/src/noncpu/memjblake@debian:~/src/noncpu/main/mem/$ pdp8 -[?2004l +[?2004l PDP-8 simulator V3.8-1 sim> at ptr binldr.rim sim> boot btr @@ -40045,7 +40045,7 @@ PC L AC MQ ea IR 02670 1 0000 0000 SPA SNA sim> quit Goodbye -[?2004h]0;debian:~/src/noncpu/memjblake@debian:~/src/noncpu/main/mem/$ vi [?2004l +[?2004h]0;debian:~/src/noncpu/memjblake@debian:~/src/noncpu/main/mem/$ vi [?2004l exit - -Script done on 2021-05-09 16:22:58-07:00 [COMMAND_EXIT_CODE="0"] + +Script done on 2021-05-09 16:22:58-07:00 [COMMAND_EXIT_CODE="0"] -- cgit v1.2.3