From 6fb37d5f47629817a5092da40217bde5ca0ed4fa Mon Sep 17 00:00:00 2001 From: Julian Blake Kongslie Date: Sun, 4 Apr 2021 14:16:27 -0700 Subject: Very fancy improved Fibonacci machine, with HDL convert-to-ASCII functionality --- asm.rb | 4 +++- hdl/top.sv | 11 +++++++++ mem/mem.hex | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++---------- 3 files changed, 80 insertions(+), 13 deletions(-) diff --git a/asm.rb b/asm.rb index 80bbd67..b883510 100755 --- a/asm.rb +++ b/asm.rb @@ -2,10 +2,11 @@ OPCODES = { "acc=" => 0x000, - "load" => 0x100, + "ladd" => 0x100, "store" => 0x200, "ifeq" => 0x300, "jmp" => 0x400, + "ascii" => 0x500, "++acc" => 0xf01, "--acc" => 0xf02, "++idx" => 0xf04, @@ -27,6 +28,7 @@ ARGF.each_line() do | line | op = 0x000 refs = [] line.scan(/\S+/).each() do | word | + break if word =~ /^#/ if word =~ /^0(\d+)$/ op |= $1.to_i(8) elsif word =~ /^-0(\d+)$/ diff --git a/hdl/top.sv b/hdl/top.sv index 35279d4..4cb5e30 100644 --- a/hdl/top.sv +++ b/hdl/top.sv @@ -120,6 +120,11 @@ always_ff @(posedge clk) begin 'h2: state = AGEN; '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; + end 'hf: begin if (operand[0]) ++acc; if (operand[1]) --acc; @@ -152,6 +157,12 @@ always_ff @(posedge clk) begin mem_write_data = acc; state = `mem_ready ? FETCH : AGEN; end + 'h5: begin + mem_valid = 1; + mem_address = {2'b0, idx + sign_extended_operand}; + mem_write = 1; + state = `mem_ready ? FETCH : AGEN; + end endcase end diff --git a/mem/mem.hex b/mem/mem.hex index 63038e3..d30c5b6 100644 --- a/mem/mem.hex +++ b/mem/mem.hex @@ -1,25 +1,79 @@ @0 -000 // loop: acc= 0 -140 // load 0x40 +// Reset state is acc=0 idx=0 + +000 // loop: acc= 0 # Print from 0x70 until we find a 0x00 byte +170 // ladd 0x70 300 // ifeq 0 402 // jmp fib f44 // ++idx tx 4fa // jmp loop -f20 // fib: idx -240 // store 0x40 +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 -241 // store 0x41 +271 // store 0x71 # 0x71 is 1 000 // fibloop: acc= 0 -140 // load 0x40 -f44 // tx ++idx -140 // load 0x40 -241 // store 0x41 -4fa // jmp fibloop +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 + +@6c + +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 -@40 +@70 -048 // H +048 // H # later: start of in-memory Fib sequence 065 // e 06c // l 06c // l -- cgit v1.2.3