From 3b1e7cfbd6ef2e520702a90c4d0ac8e102f19d9a Mon Sep 17 00:00:00 2001 From: Julian Blake Kongslie Date: Sun, 4 Apr 2021 14:53:31 -0700 Subject: Add indirect memory operations. --- asm.rb | 1 + hdl/top.sv | 36 ++++++++++++++++++++++++++++++------ mem/mem.hex | 5 +++-- 3 files changed, 34 insertions(+), 8 deletions(-) diff --git a/asm.rb b/asm.rb index b883510..c3a0125 100755 --- a/asm.rb +++ b/asm.rb @@ -1,6 +1,7 @@ #!/usr/bin/ruby -w OPCODES = { + "i" => 0x080, "acc=" => 0x000, "ladd" => 0x100, "store" => 0x200, diff --git a/hdl/top.sv b/hdl/top.sv index 4cb5e30..00d0cab 100644 --- a/hdl/top.sv +++ b/hdl/top.sv @@ -70,11 +70,14 @@ bit [7:0] operand; bit [DATA_BITS-1:0] acc; bit [DATA_BITS-1:0] idx; +bit [ADDR_BITS-1:0] address; bit [DATA_BITS-1:0] sign_extended_operand; enum { FETCH , DECODE + , INDIRECT + , INDIRECTED , AGEN , MEMORY , HALT @@ -116,14 +119,17 @@ always_ff @(posedge clk) begin `ifdef DEBUG $display("\tdecode %x:%x", opcode, operand); `endif case (opcode) 'h0: acc = sign_extended_operand; - 'h1: state = AGEN; - 'h2: state = AGEN; + 'h1, 'h2: begin + address = {7'b0, operand[6:0]}; + state = operand[7] ? INDIRECT : AGEN; + end 'h3: if (acc != sign_extended_operand) ++pc; 'h4: pc = pc + sign_extended_operand; 'h5: begin mem_write_data = acc % 10 + 'h30; acc = acc / 10; - state = AGEN; + address = {7'b0, operand[6:0]}; + state = operand[7] ? INDIRECT : AGEN; end 'hf: begin if (operand[0]) ++acc; @@ -139,6 +145,24 @@ always_ff @(posedge clk) begin end end + INDIRECT: begin + mem_valid = 1; + mem_write = 0; + mem_address = address; + state = `mem_ready ? INDIRECTED : INDIRECT; + end + + INDIRECTED: begin + if (`mem_ready) begin + mem_valid = 0; + mem_write = 0; + end + if (`mem_read_valid) begin + address = `mem_read_data; + state = AGEN; + end + end + AGEN: begin mem_valid = 0; mem_write = 0; @@ -147,19 +171,19 @@ always_ff @(posedge clk) begin case (opcode) 'h1: begin mem_valid = 1; - mem_address = {2'b0, idx + sign_extended_operand}; + mem_address = address + idx; state = `mem_ready ? MEMORY : AGEN; end 'h2: begin mem_valid = 1; - mem_address = {2'b0, idx + sign_extended_operand}; + mem_address = address + idx; mem_write = 1; mem_write_data = acc; state = `mem_ready ? FETCH : AGEN; end 'h5: begin mem_valid = 1; - mem_address = {2'b0, idx + sign_extended_operand}; + mem_address = address + idx; mem_write = 1; state = `mem_ready ? FETCH : AGEN; end diff --git a/mem/mem.hex b/mem/mem.hex index d30c5b6..07023a8 100644 --- a/mem/mem.hex +++ b/mem/mem.hex @@ -3,7 +3,7 @@ // Reset state is acc=0 idx=0 000 // loop: acc= 0 # Print from 0x70 until we find a 0x00 byte -170 // ladd 0x70 +170 // ladd i 0x6a 300 // ifeq 0 402 // jmp fib f44 // ++idx tx @@ -63,8 +63,9 @@ f04 // ++idx f40 // tx f80 // halt -@6c +@6a +070 // 6a: constant 0x070 000 // 6b: LSB of ASCII rep 000 // 6c: USB of ASCII rep 000 // 6d: USB of ASCII rep -- cgit v1.2.3