diff options
| author | Julian Blake Kongslie | 2021-04-04 14:53:31 -0700 |
|---|---|---|
| committer | Julian Blake Kongslie | 2021-04-04 14:53:31 -0700 |
| commit | 3b1e7cfbd6ef2e520702a90c4d0ac8e102f19d9a (patch) | |
| tree | 6430b583e0013e2f0812b7285cb3ead6633243ec | |
| parent | Very fancy improved Fibonacci machine, with HDL convert-to-ASCII functionality (diff) | |
| download | noncpu-3b1e7cfbd6ef2e520702a90c4d0ac8e102f19d9a.tar.xz | |
Add indirect memory operations.
Diffstat (limited to '')
| -rwxr-xr-x | asm.rb | 1 | ||||
| -rw-r--r-- | hdl/top.sv | 36 | ||||
| -rw-r--r-- | mem/mem.hex | 5 |
3 files changed, 34 insertions, 8 deletions
| @@ -1,6 +1,7 @@ | |||
| 1 | #!/usr/bin/ruby -w | 1 | #!/usr/bin/ruby -w |
| 2 | 2 | ||
| 3 | OPCODES = { | 3 | OPCODES = { |
| 4 | "i" => 0x080, | ||
| 4 | "acc=" => 0x000, | 5 | "acc=" => 0x000, |
| 5 | "ladd" => 0x100, | 6 | "ladd" => 0x100, |
| 6 | "store" => 0x200, | 7 | "store" => 0x200, |
| @@ -70,11 +70,14 @@ bit [7:0] operand; | |||
| 70 | bit [DATA_BITS-1:0] acc; | 70 | bit [DATA_BITS-1:0] acc; |
| 71 | bit [DATA_BITS-1:0] idx; | 71 | bit [DATA_BITS-1:0] idx; |
| 72 | 72 | ||
| 73 | bit [ADDR_BITS-1:0] address; | ||
| 73 | bit [DATA_BITS-1:0] sign_extended_operand; | 74 | bit [DATA_BITS-1:0] sign_extended_operand; |
| 74 | 75 | ||
| 75 | enum | 76 | enum |
| 76 | { FETCH | 77 | { FETCH |
| 77 | , DECODE | 78 | , DECODE |
| 79 | , INDIRECT | ||
| 80 | , INDIRECTED | ||
| 78 | , AGEN | 81 | , AGEN |
| 79 | , MEMORY | 82 | , MEMORY |
| 80 | , HALT | 83 | , HALT |
| @@ -116,14 +119,17 @@ always_ff @(posedge clk) begin | |||
| 116 | `ifdef DEBUG $display("\tdecode %x:%x", opcode, operand); `endif | 119 | `ifdef DEBUG $display("\tdecode %x:%x", opcode, operand); `endif |
| 117 | case (opcode) | 120 | case (opcode) |
| 118 | 'h0: acc = sign_extended_operand; | 121 | 'h0: acc = sign_extended_operand; |
| 119 | 'h1: state = AGEN; | 122 | 'h1, 'h2: begin |
| 120 | 'h2: state = AGEN; | 123 | address = {7'b0, operand[6:0]}; |
| 124 | state = operand[7] ? INDIRECT : AGEN; | ||
| 125 | end | ||
| 121 | 'h3: if (acc != sign_extended_operand) ++pc; | 126 | 'h3: if (acc != sign_extended_operand) ++pc; |
| 122 | 'h4: pc = pc + sign_extended_operand; | 127 | 'h4: pc = pc + sign_extended_operand; |
| 123 | 'h5: begin | 128 | 'h5: begin |
| 124 | mem_write_data = acc % 10 + 'h30; | 129 | mem_write_data = acc % 10 + 'h30; |
| 125 | acc = acc / 10; | 130 | acc = acc / 10; |
| 126 | state = AGEN; | 131 | address = {7'b0, operand[6:0]}; |
| 132 | state = operand[7] ? INDIRECT : AGEN; | ||
| 127 | end | 133 | end |
| 128 | 'hf: begin | 134 | 'hf: begin |
| 129 | if (operand[0]) ++acc; | 135 | if (operand[0]) ++acc; |
| @@ -139,6 +145,24 @@ always_ff @(posedge clk) begin | |||
| 139 | end | 145 | end |
| 140 | end | 146 | end |
| 141 | 147 | ||
| 148 | INDIRECT: begin | ||
| 149 | mem_valid = 1; | ||
| 150 | mem_write = 0; | ||
| 151 | mem_address = address; | ||
| 152 | state = `mem_ready ? INDIRECTED : INDIRECT; | ||
| 153 | end | ||
| 154 | |||
| 155 | INDIRECTED: begin | ||
| 156 | if (`mem_ready) begin | ||
| 157 | mem_valid = 0; | ||
| 158 | mem_write = 0; | ||
| 159 | end | ||
| 160 | if (`mem_read_valid) begin | ||
| 161 | address = `mem_read_data; | ||
| 162 | state = AGEN; | ||
| 163 | end | ||
| 164 | end | ||
| 165 | |||
| 142 | AGEN: begin | 166 | AGEN: begin |
| 143 | mem_valid = 0; | 167 | mem_valid = 0; |
| 144 | mem_write = 0; | 168 | mem_write = 0; |
| @@ -147,19 +171,19 @@ always_ff @(posedge clk) begin | |||
| 147 | case (opcode) | 171 | case (opcode) |
| 148 | 'h1: begin | 172 | 'h1: begin |
| 149 | mem_valid = 1; | 173 | mem_valid = 1; |
| 150 | mem_address = {2'b0, idx + sign_extended_operand}; | 174 | mem_address = address + idx; |
| 151 | state = `mem_ready ? MEMORY : AGEN; | 175 | state = `mem_ready ? MEMORY : AGEN; |
| 152 | end | 176 | end |
| 153 | 'h2: begin | 177 | 'h2: begin |
| 154 | mem_valid = 1; | 178 | mem_valid = 1; |
| 155 | mem_address = {2'b0, idx + sign_extended_operand}; | 179 | mem_address = address + idx; |
| 156 | mem_write = 1; | 180 | mem_write = 1; |
| 157 | mem_write_data = acc; | 181 | mem_write_data = acc; |
| 158 | state = `mem_ready ? FETCH : AGEN; | 182 | state = `mem_ready ? FETCH : AGEN; |
| 159 | end | 183 | end |
| 160 | 'h5: begin | 184 | 'h5: begin |
| 161 | mem_valid = 1; | 185 | mem_valid = 1; |
| 162 | mem_address = {2'b0, idx + sign_extended_operand}; | 186 | mem_address = address + idx; |
| 163 | mem_write = 1; | 187 | mem_write = 1; |
| 164 | state = `mem_ready ? FETCH : AGEN; | 188 | state = `mem_ready ? FETCH : AGEN; |
| 165 | end | 189 | 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 @@ | |||
| 3 | // Reset state is acc=0 idx=0 | 3 | // Reset state is acc=0 idx=0 |
| 4 | 4 | ||
| 5 | 000 // loop: acc= 0 # Print from 0x70 until we find a 0x00 byte | 5 | 000 // loop: acc= 0 # Print from 0x70 until we find a 0x00 byte |
| 6 | 170 // ladd 0x70 | 6 | 170 // ladd i 0x6a |
| 7 | 300 // ifeq 0 | 7 | 300 // ifeq 0 |
| 8 | 402 // jmp fib | 8 | 402 // jmp fib |
| 9 | f44 // ++idx tx | 9 | f44 // ++idx tx |
| @@ -63,8 +63,9 @@ f04 // ++idx | |||
| 63 | f40 // tx | 63 | f40 // tx |
| 64 | f80 // halt | 64 | f80 // halt |
| 65 | 65 | ||
| 66 | @6c | 66 | @6a |
| 67 | 67 | ||
| 68 | 070 // 6a: constant 0x070 | ||
| 68 | 000 // 6b: LSB of ASCII rep | 69 | 000 // 6b: LSB of ASCII rep |
| 69 | 000 // 6c: USB of ASCII rep | 70 | 000 // 6c: USB of ASCII rep |
| 70 | 000 // 6d: USB of ASCII rep | 71 | 000 // 6d: USB of ASCII rep |
