From e3e1938231ef16ace235f4d958e49913275dcbde Mon Sep 17 00:00:00 2001 From: Julian Blake Kongslie Date: Sun, 18 Apr 2021 17:02:12 -0700 Subject: PDP-8 memory opcodes --- hdl/core.sv | 176 +++++++++++++++++++++++++++++++----------------------------- 1 file changed, 92 insertions(+), 84 deletions(-) (limited to 'hdl') diff --git a/hdl/core.sv b/hdl/core.sv index 919dac9..83f4f01 100644 --- a/hdl/core.sv +++ b/hdl/core.sv @@ -1,7 +1,7 @@ `include "util.svh" module core - #( ADDR_BITS = 14 + #( ADDR_BITS = 12 , DATA_BITS = 12 ) ( input bit clk @@ -20,7 +20,7 @@ bit [DATA_BITS-1:0] mem_read_data; mem #( .ADDR_BITS(ADDR_BITS) , .DATA_BITS(DATA_BITS) - , .INIT_FILE("mem/mem.hex") + , .INIT_FILE("build/mem/hello.hex") ) memory ( .clk(clk) @@ -59,21 +59,28 @@ jtag_uart , .tx_data(tx_data) ); +bit [ADDR_BITS-1:ADDR_BITS-6] page; + bit [ADDR_BITS-1:0] pc; -bit [3:0] opcode; -bit [7:0] operand; +bit [2:0] opcode; +bit [8:0] operand; bit [DATA_BITS-1:0] acc; +bit link; +bit i; +bit z; +bit [6:0] wip; bit [ADDR_BITS-1:0] address; -bit [DATA_BITS-1:0] sign_extended_operand; enum { FETCH , DECODE , INDIRECT , INDIRECTED + , PREINC , AGEN - , MEMORY + , EXEC + , STORE , HALT } state; @@ -83,8 +90,9 @@ always_ff @(posedge clk) begin rx_ready = 0; tx_valid = 0; tx_data = 0; - pc = 0; + pc = 'o200; acc = 0; + link = 0; state = state.first; end else begin if (`lag(tx_ready)) tx_valid = 0; @@ -96,6 +104,7 @@ always_ff @(posedge clk) begin mem_write = 0; if (`lag(mem_ready)) begin state = DECODE; + page = pc[ADDR_BITS-1:ADDR_BITS-6]; ++pc; end end @@ -106,39 +115,21 @@ always_ff @(posedge clk) begin if (`lag(mem_read_valid)) begin state = FETCH; {opcode, operand} = `lag(mem_read_data); - sign_extended_operand = {{(DATA_BITS-8){operand[7]}}, operand}; + {i, z, wip} = operand; + if (z) + address = {page, wip}; + else + address = {5'b0, wip}; case (opcode) - 'h0: begin - if (operand[0]) acc = 0; - if (operand[1]) ++acc; - if (operand[2]) --acc; - if (operand[6]) state = MEMORY; - if (operand[7]) begin - rx_ready = 1; - state = MEMORY; - end - if (operand == 0) state = HALT; - end - 'h1: acc = sign_extended_operand; - 'h2, 'h3: begin - address = {7'b0, operand[6:0]}; - state = operand[7] ? INDIRECT : AGEN; - end - 'h4: if (acc != sign_extended_operand) ++pc; - 'h5: begin - if (operand[7]) begin - address = {7'b0, operand[6:0]}; + 'b000, 'b001, 'b010: state = i ? INDIRECT : AGEN; + 'b011, 'b100: state = i ? INDIRECT : EXEC; + 'b101: begin + if (i) begin state = INDIRECT; end else begin - pc = pc + {{(ADDR_BITS-7){operand[6]}}, operand[6:0]}; + pc = address; end end - 'h6: begin - mem_write_data = acc % 10 + 'h30; - acc = acc / 10; - address = {7'b0, operand[6:0]}; - state = operand[7] ? INDIRECT : AGEN; - end endcase end end @@ -156,73 +147,90 @@ always_ff @(posedge clk) begin mem_write = 0; end if (`lag(mem_read_valid)) begin - address = {{(ADDR_BITS - DATA_BITS){1'b0}}, `lag(mem_read_data)}; - state = AGEN; + if (address[7:3] == 5'b00001) begin + address = {{(ADDR_BITS - DATA_BITS){1'b0}}, `lag(mem_read_data)}; + address += 1; + state = PREINC; + end else begin + address = {{(ADDR_BITS - DATA_BITS){1'b0}}, `lag(mem_read_data)}; + case (opcode) + 'b000, 'b001, 'b010: state = AGEN; + 'b011, 'b100: state = EXEC; + 'b101: begin + pc = address; + state = FETCH; + end + endcase + end end end + PREINC: begin + mem_valid = 1; + mem_write = 1; + mem_write_data = address[DATA_BITS-1:0]; + case (opcode) begin + 'b000, 'b001, 'b010: state = `lag(mem_ready) ? PREINC : AGEN; + 'b011, 'b100, 'b101: state = `lag(mem_ready) ? PREINC : EXEC; + endcase + end + AGEN: begin - mem_valid = 0; - mem_write = 0; - state = FETCH; + mem_valid = 1; case (opcode) - 'h2: begin - mem_valid = 1; - mem_address = address; - state = `lag(mem_ready) ? MEMORY : AGEN; - end - 'h3: begin - mem_valid = 1; - mem_address = address; - mem_write = 1; - mem_write_data = acc; - state = `lag(mem_ready) ? FETCH : AGEN; - end - 'h5: pc = address; - 'h6: begin - mem_valid = 1; - mem_address = address; - mem_write = 1; - state = `lag(mem_ready) ? FETCH : AGEN; - end + 'b000, 'b001, 'b010: mem_write = 0; endcase + mem_address = address; + state = `lag(mem_ready) ? EXEC : AGEN; end - MEMORY: begin + EXEC: begin + automatic bit stall = 0; if (`lag(mem_ready)) begin mem_valid = 0; mem_write = 0; + end else if (mem_valid) begin + stall = 1; end - state = FETCH; case (opcode) - 'h0: begin - if (operand[6]) begin - if (tx_valid) begin - state = MEMORY; - end else begin - tx_valid = 1; - tx_data = acc[7:0]; - end + 'b000, 'b001, 'b010: if (! `lag(mem_read_valid)) stall = 1; + endcase + if (! stall) begin + state = FETCH; + case (opcode) + 'b000: acc &= `lag(mem_read_data); + 'b001: {link, acc} += {1'b0, `lag(mem_read_data)}; + 'b010: begin + mem_valid = 1; + mem_address = address; + mem_write = 1; + mem_write_data = `lag(mem_read_data) + 1; + if (mem_write_data == 0) ++pc; + state = MEMWAIT; end - if (operand[7]) begin - if (`lag(rx_valid)) begin - rx_ready = 0; - acc = {{(DATA_BITS-8){1'b0}}, `lag(rx_data)}; - end else begin - state = MEMORY; - end + 'b011: begin + mem_valid = 1; + mem_address = address; + mem_write = 1; + mem_write_data = acc; + acc = 0; + state = MEMWAIT; end - end - 'h2: begin - if (`lag(mem_read_valid)) begin - acc = acc + `lag(mem_read_data); - end else begin - state = MEMORY; + 'b100: begin + mem_valid = 1; + mem_address = address; + mem_write = 1; + mem_write_data = pc[DATA_BITS-1:0]; + pc = address + 1; + state = MEMWAIT; end - end - endcase + 'b101: pc = address; + endcase + end end + MEMWAIT: state = `lag(mem_ready) ? FETCH : MEMWAIT; + HALT: $finish; endcase end -- cgit v1.2.3