summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Blake Kongslie2021-04-04 16:20:24 -0700
committerJulian Blake Kongslie2021-04-04 16:20:24 -0700
commit6a031fb49d595726da16adcf868475b1e104d60d (patch)
tree354dc4ca0978261b804533f91cf9298937c0a4ee
parentAdd indirect memory operations. (diff)
downloadnoncpu-6a031fb49d595726da16adcf868475b1e104d60d.tar.xz
Remove idx, add indirect jumps, renumber opcodes so NOP=0, add absolute labels to asm.rb
-rwxr-xr-xasm.rb31
-rw-r--r--hdl/top.sv65
-rw-r--r--mem/mem.hex154
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 @@
2 2
3OPCODES = { 3OPCODES = {
4 "i" => 0x080, 4 "i" => 0x080,
5 "acc=" => 0x000, 5 "acc=" => 0x100,
6 "ladd" => 0x100, 6 "ladd" => 0x200,
7 "store" => 0x200, 7 "store" => 0x300,
8 "ifeq" => 0x300, 8 "ifeq" => 0x400,
9 "jmp" => 0x400, 9 "jmp" => 0x500,
10 "ascii" => 0x500, 10 "ascii" => 0x600,
11 "++acc" => 0xf01, 11 "cla" => 0x001,
12 "--acc" => 0xf02, 12 "++acc" => 0x002,
13 "++idx" => 0xf04, 13 "--acc" => 0x004,
14 "--idx" => 0xf08, 14 "tx" => 0x040,
15 "swap" => 0xf10, 15 "halt" => 0x080,
16 "idx" => 0xf20,
17 "tx" => 0xf40,
18 "halt" => 0xf80,
19 } 16 }
20 17
21Line = Struct.new(:opcode, :refs, :code) 18Line = Struct.new(:opcode, :refs, :code)
@@ -56,9 +53,11 @@ end
56$code.each_with_index() do | line, i | 53$code.each_with_index() do | line, i |
57 op = line.opcode 54 op = line.opcode
58 line.refs.each() do | ref | 55 line.refs.each() do | ref |
59 if $labels.key?(ref) 56 if ref =~ /^@(.+)$/ and $labels.key?($1)
57 op |= $labels[$1]
58 elsif $labels.key?(ref)
60 target = $labels[ref] - (i + 1) 59 target = $labels[ref] - (i + 1)
61 target += 0x100 if target < 0 60 target += 0x80 if target < 0
62 op |= target 61 op |= target
63 else 62 else
64 throw "I don't understand #{ref.inspect()}" 63 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;
68bit [3:0] opcode; 68bit [3:0] opcode;
69bit [7:0] operand; 69bit [7:0] operand;
70bit [DATA_BITS-1:0] acc; 70bit [DATA_BITS-1:0] acc;
71bit [DATA_BITS-1:0] idx;
72 71
73bit [ADDR_BITS-1:0] address; 72bit [ADDR_BITS-1:0] address;
74bit [DATA_BITS-1:0] sign_extended_operand; 73bit [DATA_BITS-1:0] sign_extended_operand;
@@ -91,10 +90,9 @@ always_ff @(posedge clk) begin
91 tx_data = 0; 90 tx_data = 0;
92 pc = 0; 91 pc = 0;
93 acc = 0; 92 acc = 0;
94 idx = 0;
95 state = state.first; 93 state = state.first;
96 end else begin 94 end else begin
97 `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 95 `ifdef DEBUG $display("s=%0d pc=%x (acc=%x) (mem %b:%x)", state, pc, acc, `mem_read_valid, `mem_read_data); `endif
98 if (`tx_ready) tx_valid = 0; 96 if (`tx_ready) tx_valid = 0;
99 97
100 case (state) 98 case (state)
@@ -118,29 +116,33 @@ always_ff @(posedge clk) begin
118 sign_extended_operand = {{(DATA_BITS-8){operand[7]}}, operand}; 116 sign_extended_operand = {{(DATA_BITS-8){operand[7]}}, operand};
119 `ifdef DEBUG $display("\tdecode %x:%x", opcode, operand); `endif 117 `ifdef DEBUG $display("\tdecode %x:%x", opcode, operand); `endif
120 case (opcode) 118 case (opcode)
121 'h0: acc = sign_extended_operand; 119 'h0: begin
122 'h1, 'h2: begin 120 if (operand[0]) acc = 0;
121 if (operand[1]) ++acc;
122 if (operand[2]) --acc;
123 if (operand[6]) state = MEMORY;
124 if (operand[7]) state = HALT;
125 end
126 'h1: acc = sign_extended_operand;
127 'h2, 'h3: begin
123 address = {7'b0, operand[6:0]}; 128 address = {7'b0, operand[6:0]};
124 state = operand[7] ? INDIRECT : AGEN; 129 state = operand[7] ? INDIRECT : AGEN;
125 end 130 end
126 'h3: if (acc != sign_extended_operand) ++pc; 131 'h4: if (acc != sign_extended_operand) ++pc;
127 'h4: pc = pc + sign_extended_operand;
128 'h5: begin 132 'h5: begin
133 if (operand[7]) begin
134 address = {7'b0, operand[6:0]};
135 state = INDIRECT;
136 end else begin
137 pc = pc + {{(ADDR_BITS-7){operand[6]}}, operand[6:0]};
138 end
139 end
140 'h6: begin
129 mem_write_data = acc % 10 + 'h30; 141 mem_write_data = acc % 10 + 'h30;
130 acc = acc / 10; 142 acc = acc / 10;
131 address = {7'b0, operand[6:0]}; 143 address = {7'b0, operand[6:0]};
132 state = operand[7] ? INDIRECT : AGEN; 144 state = operand[7] ? INDIRECT : AGEN;
133 end 145 end
134 'hf: begin
135 if (operand[0]) ++acc;
136 if (operand[1]) --acc;
137 if (operand[2]) ++idx;
138 if (operand[3]) --idx;
139 if (operand[4]) {idx, acc} = {acc, idx};
140 if (operand[5]) idx = acc;
141 if (operand[6]) state = MEMORY;
142 if (operand[7]) state = HALT;
143 end
144 endcase 146 endcase
145 end 147 end
146 end 148 end
@@ -169,21 +171,22 @@ always_ff @(posedge clk) begin
169 state = FETCH; 171 state = FETCH;
170 `ifdef DEBUG $display("\tagen"); `endif 172 `ifdef DEBUG $display("\tagen"); `endif
171 case (opcode) 173 case (opcode)
172 'h1: begin 174 'h2: begin
173 mem_valid = 1; 175 mem_valid = 1;
174 mem_address = address + idx; 176 mem_address = address;
175 state = `mem_ready ? MEMORY : AGEN; 177 state = `mem_ready ? MEMORY : AGEN;
176 end 178 end
177 'h2: begin 179 'h3: begin
178 mem_valid = 1; 180 mem_valid = 1;
179 mem_address = address + idx; 181 mem_address = address;
180 mem_write = 1; 182 mem_write = 1;
181 mem_write_data = acc; 183 mem_write_data = acc;
182 state = `mem_ready ? FETCH : AGEN; 184 state = `mem_ready ? FETCH : AGEN;
183 end 185 end
184 'h5: begin 186 'h5: pc = address;
187 'h6: begin
185 mem_valid = 1; 188 mem_valid = 1;
186 mem_address = address + idx; 189 mem_address = address;
187 mem_write = 1; 190 mem_write = 1;
188 state = `mem_ready ? FETCH : AGEN; 191 state = `mem_ready ? FETCH : AGEN;
189 end 192 end
@@ -198,14 +201,7 @@ always_ff @(posedge clk) begin
198 state = FETCH; 201 state = FETCH;
199 `ifdef DEBUG $display("\tstall"); `endif 202 `ifdef DEBUG $display("\tstall"); `endif
200 case (opcode) 203 case (opcode)
201 'h1: begin 204 'h0: begin
202 if (`mem_read_valid) begin
203 acc = acc + `mem_read_data;
204 end else begin
205 state = MEMORY;
206 end
207 end
208 'hf: begin
209 if (operand[6]) begin 205 if (operand[6]) begin
210 if (tx_valid) begin 206 if (tx_valid) begin
211 state = MEMORY; 207 state = MEMORY;
@@ -215,6 +211,13 @@ always_ff @(posedge clk) begin
215 end 211 end
216 end 212 end
217 end 213 end
214 'h2: begin
215 if (`mem_read_valid) begin
216 acc = acc + `mem_read_data;
217 end else begin
218 state = MEMORY;
219 end
220 end
218 endcase 221 endcase
219 end 222 end
220 223
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 @@
1@0 1@0
2 2
3// Reset state is acc=0 idx=0 310d // acc= @fib # for the toy indirect jump to fib
4369 // store 0x69
5170 // acc= 0x70
636a // store 0x6a
7001 // loop: cla
82ea // ladd i 0x6a
9400 // ifeq 0
105e9 // jmp i 0x69 # toy indirect jump to fib
11040 // tx
12003 // cla ++acc
1326a // ladd 0x6a
1436a // store 0x6a
15577 // jmp loop
1636a // fib: store 0x6a # zero, it is known
17370 // store 0x70 # 0x70 is now beginning of Fibonacci sequence (0)
18003 // cla ++acc
19371 // store 0x71 # 0x71 is 1
20170 // fibloop: acc= 0x70
2126a // ladd 0x6a
22369 // store 0x69
23001 // cla
242e9 // ladd i 0x69 # next fib number to print
2566b // ascii 0x6b # LSB of ASCII rep
2666c // ascii 0x6c
2766d // ascii 0x6d
2866e // ascii 0x6e # MSB of ASCII rep
29104 // acc= 4
30369 // store 0x69
31005 // scan: cla --acc
32269 // ladd 0x69
334ff // ifeq -1
34508 // jmp print
35369 // store 0x69
3616b // acc= 0x6b
37269 // ladd 0x69
38368 // store 0x68
39001 // cla
402e8 // ladd i 0x68
41430 // ifeq 0x30
42574 // jmp scan
4316b // print: acc= 0x6b
44269 // ladd 0x69
45368 // store 0x68
46001 // cla
472e8 // ladd i 0x68
48040 // tx
49005 // cla --acc
50269 // ladd 0x69
514ff // ifeq -1
52502 // jmp space
53369 // store 0x69
54574 // jmp print
55120 // space: acc= 0x20
56040 // tx
57170 // acc= 0x70
5826a // ladd 0x6a
59369 // store 0x69
60003 // cla ++acc
61269 // ladd 0x69 # compute &fib[i+1]
62368 // store 0x68
63003 // cla ++acc
64268 // ladd 0x68 # compute &fib[i+2]
65367 // store 0x67
66001 // cla
672e9 // ladd i 0x69
682e8 // ladd i 0x68 # compute fib[i+2]
693e7 // store i 0x67 # store it
70003 // cla ++acc
7126a // ladd 0x6a
72432 // ifeq 50
73502 // jmp fullydone
7436a // store 0x6a
75548 // jmp fibloop
76121 // fullydone: acc= 0x21
77040 // tx
78080 // halt
4 79
5000 // loop: acc= 0 # Print from 0x70 until we find a 0x00 byte 80// 67: scratch (pointer to fib[i+2])
6170 // ladd i 0x6a 81// 68: scratch (pointer to fib[i+1])
7300 // ifeq 0 82// 69: scratch (pointer to fib[i]) (j)
8402 // jmp fib 83// 6a: i
9f44 // ++idx tx 84// 6b: LSB of ASCII rep
104fa // jmp loop 85// 6c: USB of ASCII rep
11f20 // fib: idx # N.B. acc is 0 at this point (we got here from ifeq 0) 86// 6d: USB of ASCII rep
12270 // store 0x70 # 0x70 is now beginning of Fibonacci sequence (0) 87// 6e: MSB of ASCII rep
13001 // acc= 1
14271 // store 0x71 # 0x71 is 1
15000 // fibloop: acc= 0
16f10 // swap
17332 // ifeq 50
1842b // jmp fullydone
1926f // store 0x6f # 0x6f is current index into Fibonacci sequence
20f10 // swap
21170 // ladd 0x70 # Load next unprinted number in Fibonacci sequence
22f10 // swap
23000 // acc= 0
24f10 // swap
2556b // ascii 0x6b # LSB of ASCII rep
2656c // ascii 0x6c
2756d // ascii 0x6d
2856e // ascii 0x6e # MSB of ASCII rep
29004 // acc= 4
30f10 // swap
31f08 // scan: --idx
32000 // acc= 0
3316b // ladd 0x6b
34f10 // swap
35300 // ifeq 0
36412 // jmp allzeroes
37f10 // swap
38330 // ifeq 0x30
394f7 // jmp scan
40f40 // done: tx
41f10 // swap
42300 // ifeq 0
43404 // jmp space
44f12 // --acc swap
45000 // acc= 0
4616b // ladd 0x6b
474f8 // jmp done
48020 // space: acc= 0x20
49f40 // tx
50000 // acc= 0
51f20 // idx
5216f // ladd 0x6f
53f10 // swap
54402 // jmp nextfib
55f10 // allzeroes: swap
564ef // jmp done
57170 // nextfib: ladd 0x70 # Load just-printed Fibonacci number
58171 // ladd 0x71 # Add about-to-print Fibonacci number
59272 // store 0x72 # Store n+2 Fibonacci number
60f04 // ++idx
614d1 // jmp fibloop
62021 // fullydone: acc= 0x21
63f40 // tx
64f80 // halt
65
66@6a
67
68070 // 6a: constant 0x070
69000 // 6b: LSB of ASCII rep
70000 // 6c: USB of ASCII rep
71000 // 6d: USB of ASCII rep
72000 // 6e: MSB of ASCII rep
73000 // 6f: next index to store in memory image of Fibonacci sequence
74 88
75@70 89@70
76 90