From 529c1cc2496e24c6282c3fa9e0a45272b7f500b6 Mon Sep 17 00:00:00 2001 From: Julian Blake Kongslie Date: Sun, 2 May 2021 16:58:46 -0700 Subject: Add a bunch of microcoded instructions. This is a minimum viable PDP-8 that can print "Hello, world!" and halt. --- hdl/core.sv | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 90 insertions(+), 3 deletions(-) (limited to 'hdl/core.sv') diff --git a/hdl/core.sv b/hdl/core.sv index 5bee974..02ff231 100644 --- a/hdl/core.sv +++ b/hdl/core.sv @@ -115,6 +115,7 @@ always_ff @(posedge clk) begin if (`lag(mem_read_valid)) begin state = FETCH; {opcode, operand} = `lag(mem_read_data); + $display("%d decode %x: %b %b", $time, pc-1, opcode, operand); {i, z, wip} = operand; if (z) address = {page, wip}; @@ -130,6 +131,89 @@ always_ff @(posedge clk) begin pc = address; end end + 'b111: begin + casez (operand) + 'b0????????: begin + automatic bit cla, cll, cma, cml, rar, ral, bsw, iac; + {cla, cll, cma, cml, rar, ral, bsw, iac} = operand[7:0]; + if (cla) acc = 0; + if (cll) link = 0; + if (cma) acc = ~acc; + if (cml) link = ~link; + if (iac) {link, acc} += 1; + if (rar && !ral) begin + {link, acc} = {acc[0], link, acc[11:1]}; + if (bsw) {link, acc} = {acc[0], link, acc[11:1]}; + end + if (ral && !rar) begin + {link, acc} = {acc, link}; + if (bsw) {link, acc} = {acc, link}; + end + if (bsw && !(rar || ral)) acc = {acc[5:0], acc[11:6]}; + end + 'b1????0??0: begin + automatic bit cla, sma, sza, snl, osr, hlt; + automatic bit skip; + {cla, sma, sza, snl, osr, hlt} = {operand[7:4], operand[2:1]}; + skip = 0; + if (sma && acc[11]) skip = 1; + if (sza && acc == 0) skip = 1; + if (snl && link != 0) skip = 1; + if (skip) pc++; + if (cla) acc = 0; + if (osr) begin + $display("unsupported front panel switch test"); + $finish; + end + if (hlt) state = HALT; + end + 'b1????1??0: begin + automatic bit cla, spa, sna, szl, osr, hlt; + automatic bit skip; + {cla, spa, sna, szl, osr, hlt} = {operand[7:4], operand[2:1]}; + skip = 1; + if (spa && acc[11]) skip = 0; + if (sna && acc == 0) skip = 0; + if (szl && link != 0) skip = 0; + if (skip && (spa || sna || szl)) pc++; + if (cla) acc = 0; + if (osr) begin + $display("unsupported front panel switch test"); + $finish; + end + if (hlt) state = HALT; + end + default: begin + $display("%d decoded unknown opcode %x: %b %b", $time, pc-1, opcode, operand); + $finish; + end + endcase + end + 'b110: begin + case (operand[8:3]) + 'b000100: begin + case (operand[2:0]) + 'b001: if (!tx_valid) pc++; + 'b110: begin + tx_valid = 1; + tx_data = {1'b0, acc[6:0]}; + end + default: begin + $display("unsupported device op %b", operand[2:0]); + $finish; + end + endcase + end + default: begin + $display("unsupported device %b", operand[8:3]); + $finish; + end + endcase + end + default: begin + $display("%d decoded unknown opcode %x: %b %b", $time, pc-1, opcode, operand); + $finish; + end endcase end end @@ -170,8 +254,8 @@ always_ff @(posedge clk) begin mem_write = 1; mem_write_data = address[DATA_BITS-1:0]; case (opcode) - 'b000, 'b001, 'b010: state = `lag(mem_ready) ? PREINC : AGEN; - 'b011, 'b100, 'b101: state = `lag(mem_ready) ? PREINC : EXEC; + 'b000, 'b001, 'b010: state = `lag(mem_ready) ? AGEN : PREINC; + 'b011, 'b100, 'b101: state = `lag(mem_ready) ? EXEC : PREINC; endcase end @@ -231,7 +315,10 @@ always_ff @(posedge clk) begin MEMWAIT: state = `lag(mem_ready) ? FETCH : MEMWAIT; - HALT: $finish; + HALT: begin + $display("%d halt state reached", $time); + $finish; + end endcase end end -- cgit v1.2.3