From 6a031fb49d595726da16adcf868475b1e104d60d Mon Sep 17 00:00:00 2001 From: Julian Blake Kongslie Date: Sun, 4 Apr 2021 16:20:24 -0700 Subject: Remove idx, add indirect jumps, renumber opcodes so NOP=0, add absolute labels to asm.rb --- asm.rb | 31 ++++++------ hdl/top.sv | 65 +++++++++++++------------ mem/mem.hex | 154 +++++++++++++++++++++++++++++++++--------------------------- 3 files changed, 133 insertions(+), 117 deletions(-) diff --git a/asm.rb b/asm.rb index c3a0125..4883edb 100755 --- a/asm.rb +++ b/asm.rb @@ -2,20 +2,17 @@ OPCODES = { "i" => 0x080, - "acc=" => 0x000, - "ladd" => 0x100, - "store" => 0x200, - "ifeq" => 0x300, - "jmp" => 0x400, - "ascii" => 0x500, - "++acc" => 0xf01, - "--acc" => 0xf02, - "++idx" => 0xf04, - "--idx" => 0xf08, - "swap" => 0xf10, - "idx" => 0xf20, - "tx" => 0xf40, - "halt" => 0xf80, + "acc=" => 0x100, + "ladd" => 0x200, + "store" => 0x300, + "ifeq" => 0x400, + "jmp" => 0x500, + "ascii" => 0x600, + "cla" => 0x001, + "++acc" => 0x002, + "--acc" => 0x004, + "tx" => 0x040, + "halt" => 0x080, } Line = Struct.new(:opcode, :refs, :code) @@ -56,9 +53,11 @@ end $code.each_with_index() do | line, i | op = line.opcode line.refs.each() do | ref | - if $labels.key?(ref) + if ref =~ /^@(.+)$/ and $labels.key?($1) + op |= $labels[$1] + elsif $labels.key?(ref) target = $labels[ref] - (i + 1) - target += 0x100 if target < 0 + target += 0x80 if target < 0 op |= target else throw "I don't understand #{ref.inspect()}" diff --git a/hdl/top.sv b/hdl/top.sv index 00d0cab..71a5a48 100644 --- a/hdl/top.sv +++ b/hdl/top.sv @@ -68,7 +68,6 @@ bit [DATA_BITS-1:0] pc; bit [3:0] opcode; 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; @@ -91,10 +90,9 @@ always_ff @(posedge clk) begin tx_data = 0; pc = 0; acc = 0; - idx = 0; state = state.first; end else begin - `ifdef DEBUG $display("s=%0d pc=%x (acc=%x idx=%x) (mem %b:%x)", state, pc, acc, idx, `mem_read_valid, `mem_read_data); `endif + `ifdef DEBUG $display("s=%0d pc=%x (acc=%x) (mem %b:%x)", state, pc, acc, `mem_read_valid, `mem_read_data); `endif if (`tx_ready) tx_valid = 0; case (state) @@ -118,29 +116,33 @@ always_ff @(posedge clk) begin sign_extended_operand = {{(DATA_BITS-8){operand[7]}}, operand}; `ifdef DEBUG $display("\tdecode %x:%x", opcode, operand); `endif case (opcode) - 'h0: acc = sign_extended_operand; - 'h1, 'h2: begin + 'h0: begin + if (operand[0]) acc = 0; + if (operand[1]) ++acc; + if (operand[2]) --acc; + if (operand[6]) state = MEMORY; + if (operand[7]) state = HALT; + end + 'h1: acc = sign_extended_operand; + 'h2, 'h3: 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; + 'h4: if (acc != sign_extended_operand) ++pc; 'h5: begin + if (operand[7]) begin + address = {7'b0, operand[6:0]}; + state = INDIRECT; + end else begin + pc = pc + {{(ADDR_BITS-7){operand[6]}}, operand[6:0]}; + 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 - 'hf: begin - if (operand[0]) ++acc; - if (operand[1]) --acc; - if (operand[2]) ++idx; - if (operand[3]) --idx; - if (operand[4]) {idx, acc} = {acc, idx}; - if (operand[5]) idx = acc; - if (operand[6]) state = MEMORY; - if (operand[7]) state = HALT; - end endcase end end @@ -169,21 +171,22 @@ always_ff @(posedge clk) begin state = FETCH; `ifdef DEBUG $display("\tagen"); `endif case (opcode) - 'h1: begin + 'h2: begin mem_valid = 1; - mem_address = address + idx; + mem_address = address; state = `mem_ready ? MEMORY : AGEN; end - 'h2: begin + 'h3: begin mem_valid = 1; - mem_address = address + idx; + mem_address = address; mem_write = 1; mem_write_data = acc; state = `mem_ready ? FETCH : AGEN; end - 'h5: begin + 'h5: pc = address; + 'h6: begin mem_valid = 1; - mem_address = address + idx; + mem_address = address; mem_write = 1; state = `mem_ready ? FETCH : AGEN; end @@ -198,14 +201,7 @@ always_ff @(posedge clk) begin state = FETCH; `ifdef DEBUG $display("\tstall"); `endif case (opcode) - 'h1: begin - if (`mem_read_valid) begin - acc = acc + `mem_read_data; - end else begin - state = MEMORY; - end - end - 'hf: begin + 'h0: begin if (operand[6]) begin if (tx_valid) begin state = MEMORY; @@ -215,6 +211,13 @@ always_ff @(posedge clk) begin end end end + 'h2: begin + if (`mem_read_valid) begin + acc = acc + `mem_read_data; + end else begin + state = MEMORY; + end + end endcase end diff --git a/mem/mem.hex b/mem/mem.hex index 07023a8..4d5700f 100644 --- a/mem/mem.hex +++ b/mem/mem.hex @@ -1,76 +1,90 @@ @0 -// Reset state is acc=0 idx=0 +10d // acc= @fib # for the toy indirect jump to fib +369 // store 0x69 +170 // acc= 0x70 +36a // store 0x6a +001 // loop: cla +2ea // ladd i 0x6a +400 // ifeq 0 +5e9 // jmp i 0x69 # toy indirect jump to fib +040 // tx +003 // cla ++acc +26a // ladd 0x6a +36a // store 0x6a +577 // jmp loop +36a // fib: store 0x6a # zero, it is known +370 // store 0x70 # 0x70 is now beginning of Fibonacci sequence (0) +003 // cla ++acc +371 // store 0x71 # 0x71 is 1 +170 // fibloop: acc= 0x70 +26a // ladd 0x6a +369 // store 0x69 +001 // cla +2e9 // ladd i 0x69 # next fib number to print +66b // ascii 0x6b # LSB of ASCII rep +66c // ascii 0x6c +66d // ascii 0x6d +66e // ascii 0x6e # MSB of ASCII rep +104 // acc= 4 +369 // store 0x69 +005 // scan: cla --acc +269 // ladd 0x69 +4ff // ifeq -1 +508 // jmp print +369 // store 0x69 +16b // acc= 0x6b +269 // ladd 0x69 +368 // store 0x68 +001 // cla +2e8 // ladd i 0x68 +430 // ifeq 0x30 +574 // jmp scan +16b // print: acc= 0x6b +269 // ladd 0x69 +368 // store 0x68 +001 // cla +2e8 // ladd i 0x68 +040 // tx +005 // cla --acc +269 // ladd 0x69 +4ff // ifeq -1 +502 // jmp space +369 // store 0x69 +574 // jmp print +120 // space: acc= 0x20 +040 // tx +170 // acc= 0x70 +26a // ladd 0x6a +369 // store 0x69 +003 // cla ++acc +269 // ladd 0x69 # compute &fib[i+1] +368 // store 0x68 +003 // cla ++acc +268 // ladd 0x68 # compute &fib[i+2] +367 // store 0x67 +001 // cla +2e9 // ladd i 0x69 +2e8 // ladd i 0x68 # compute fib[i+2] +3e7 // store i 0x67 # store it +003 // cla ++acc +26a // ladd 0x6a +432 // ifeq 50 +502 // jmp fullydone +36a // store 0x6a +548 // jmp fibloop +121 // fullydone: acc= 0x21 +040 // tx +080 // halt -000 // loop: acc= 0 # Print from 0x70 until we find a 0x00 byte -170 // ladd i 0x6a -300 // ifeq 0 -402 // jmp fib -f44 // ++idx tx -4fa // jmp loop -f20 // fib: idx # N.B. acc is 0 at this point (we got here from ifeq 0) -270 // store 0x70 # 0x70 is now beginning of Fibonacci sequence (0) -001 // acc= 1 -271 // store 0x71 # 0x71 is 1 -000 // fibloop: acc= 0 -f10 // swap -332 // ifeq 50 -42b // jmp fullydone -26f // store 0x6f # 0x6f is current index into Fibonacci sequence -f10 // swap -170 // ladd 0x70 # Load next unprinted number in Fibonacci sequence -f10 // swap -000 // acc= 0 -f10 // swap -56b // ascii 0x6b # LSB of ASCII rep -56c // ascii 0x6c -56d // ascii 0x6d -56e // ascii 0x6e # MSB of ASCII rep -004 // acc= 4 -f10 // swap -f08 // scan: --idx -000 // acc= 0 -16b // ladd 0x6b -f10 // swap -300 // ifeq 0 -412 // jmp allzeroes -f10 // swap -330 // ifeq 0x30 -4f7 // jmp scan -f40 // done: tx -f10 // swap -300 // ifeq 0 -404 // jmp space -f12 // --acc swap -000 // acc= 0 -16b // ladd 0x6b -4f8 // jmp done -020 // space: acc= 0x20 -f40 // tx -000 // acc= 0 -f20 // idx -16f // ladd 0x6f -f10 // swap -402 // jmp nextfib -f10 // allzeroes: swap -4ef // jmp done -170 // nextfib: ladd 0x70 # Load just-printed Fibonacci number -171 // ladd 0x71 # Add about-to-print Fibonacci number -272 // store 0x72 # Store n+2 Fibonacci number -f04 // ++idx -4d1 // jmp fibloop -021 // fullydone: acc= 0x21 -f40 // tx -f80 // halt - -@6a - -070 // 6a: constant 0x070 -000 // 6b: LSB of ASCII rep -000 // 6c: USB of ASCII rep -000 // 6d: USB of ASCII rep -000 // 6e: MSB of ASCII rep -000 // 6f: next index to store in memory image of Fibonacci sequence +// 67: scratch (pointer to fib[i+2]) +// 68: scratch (pointer to fib[i+1]) +// 69: scratch (pointer to fib[i]) (j) +// 6a: i +// 6b: LSB of ASCII rep +// 6c: USB of ASCII rep +// 6d: USB of ASCII rep +// 6e: MSB of ASCII rep @70 -- cgit v1.2.3