OpenCores
URL https://opencores.org/ocsvn/hive/hive/trunk

Subversion Repositories hive

[/] [hive/] [trunk/] [v01.09/] [boot_code/] [boot_code_v_stacks.h] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 ericw
/*
2
--------------------------------------------------------------------------------
3
 
4
Module : boot_code.h
5
 
6
--------------------------------------------------------------------------------
7
 
8
Function:
9
- Boot code for a processor core.
10
 
11
Instantiates:
12
- Nothing.
13
 
14
Notes:
15
- For testing (@ core.v):
16
  CLR_BASE              = 'h0;
17
  CLR_SPAN              = 2;  // gives 4 instructions
18
  INTR_BASE             = 'h20;  // 'd32
19
  INTR_SPAN             = 2;  // gives 4 instructions
20
 
21
 
22
--------------------------------------------------------------------------------
23
*/
24
 
25
        /*
26
        -------------------------
27
        -- external parameters --
28
        -------------------------
29
        */
30
        `include "op_encode.h"
31
        `include "reg_set_addr.h"
32
 
33
        /*
34
        ------------------------------------------------------------
35
        -- defines that make programming code more human readable --
36
        ------------------------------------------------------------
37
        */
38
        `define s0                              2'd0
39
        `define s1                              2'd1
40
        `define s2                              2'd2
41
        `define s3                              2'd3
42
        `define _                               1'b0
43
        `define P                               1'b1
44
        //
45
        `define op_rd_i         op_rd_i[9:4]
46
        `define op_rd_ix                op_rd_ix[9:4]
47
        `define op_wr_i         op_wr_i[9:4]
48
        `define op_wr_ix                op_wr_ix[9:4]
49
        //
50
        `define op_jmp_ie               op_jmp_ie[9:5]
51
        `define op_jmp_iez      op_jmp_iez[9:5]
52
        `define op_jmp_il               op_jmp_il[9:5]
53
        `define op_jmp_ilz      op_jmp_ilz[9:5]
54
        `define op_jmp_ile      op_jmp_ile[9:5]
55
        `define op_jmp_ilez     op_jmp_ilez[9:5]
56
        `define op_jmp_iug      op_jmp_iug[9:5]
57
        `define op_jmp_igz      op_jmp_igz[9:5]
58
        `define op_jmp_iuge     op_jmp_iuge[9:5]
59
        `define op_jmp_igez     op_jmp_igez[9:5]
60
        `define op_jmp_igl      op_jmp_igl[9:5]
61
        `define op_jmp_iglz     op_jmp_iglz[9:5]
62
        //
63
        `define op_jmp_i                op_jmp_i[9:6]
64
        //
65
        `define op_byt_i                op_byt_i[9:8]
66
        //
67
        `define op_shl_i                op_shl_i[9:6]
68
        `define op_shl_iu               op_shl_iu[9:6]
69
        //
70
        `define op_add_i                op_add_i[9:6]
71
 
72
        /*
73
        ----------------------------------------
74
        -- initialize: fill with default data --
75
        ----------------------------------------
76
        */
77
        integer i;
78
 
79
        initial begin
80
 
81
/*      // fill with nop (some compilers need this)
82
        for ( i = 0; i < CAPACITY; i = i+1 ) begin
83
                ram[i] = { op_nop, `_, `_, `s0, `s0 };
84
        end
85
*/
86
 
87
        /*
88
        ---------------
89
        -- boot code --
90
        ---------------
91
        */
92
 
93
 
94
        // Thread 0 : test stack 1 for depth and error reporting
95
        // Thread 1 : test stack 1 clear instruction
96
        // All other threads : loop forever
97
 
98
        ///////////////
99
        // clr space //
100
        ///////////////
101
 
102
        // thread 0
103
        i='h0;   ram[i] = {  op_lit_u,              `_, `_, `s0, `s2 };  // lit => s2
104
        i=i+1;   ram[i] = 16'h100                                     ;  // addr
105
        i=i+1;   ram[i] = {  op_gto,                `P, `_, `s2, `s0 };  // goto, pop s2 (addr)
106
        //
107
        // thread 1
108
        i='h4;   ram[i] = {  op_lit_u,              `_, `_, `s0, `s2 };  // lit => s2
109
        i=i+1;   ram[i] = 16'h200                                     ;  // addr
110
        i=i+1;   ram[i] = {  op_gto,                `P, `_, `s2, `s0 };  // goto, pop s2 (addr)
111
        // and the rest (are here on Gilligan's Isle)
112
        i='h8;   ram[i] = { `op_jmp_i,       -6'h1, `_, `_, `s0, `s0 };  // loop forever
113
        i=i+4;   ram[i] = { `op_jmp_i,       -6'h1, `_, `_, `s0, `s0 };  // loop forever
114
        i=i+4;   ram[i] = { `op_jmp_i,       -6'h1, `_, `_, `s0, `s0 };  // loop forever
115
        i=i+4;   ram[i] = { `op_jmp_i,       -6'h1, `_, `_, `s0, `s0 };  // loop forever
116
        i=i+4;   ram[i] = { `op_jmp_i,       -6'h1, `_, `_, `s0, `s0 };  // loop forever
117
        i=i+4;   ram[i] = { `op_jmp_i,       -6'h1, `_, `_, `s0, `s0 };  // loop forever
118
 
119
 
120
        ////////////////
121
        // intr space //
122
        ////////////////
123
 
124
        ///////////////////////
125
        // code & data space //
126
        ///////////////////////
127
 
128
 
129
        // test correct stack depth and error reporting, result in s0
130
        // Correct functioning is s0 = 'd6 ('h6).
131
        //
132
        // s0 : final test result
133
        // s1 : test stack
134
        // s2 : sub addr
135
        // s3 : running test result, subroutine return address
136
        //
137
        // setup running test result:
138
        i='h100; ram[i] = { `op_byt_i,        8'd0, `_, `_, `s0, `s3 };  // 0=>s3
139
        // check for no stack errors
140
        i=i+1;   ram[i] = {  op_lit_u,              `_, `_, `s0, `s2 };  // lit => s2
141
        i=i+1;   ram[i] = 16'h910                                     ;  // addr
142
        i=i+1;   ram[i] = {  op_gsb,                `P, `_, `s2, `s3 };  // gsb, pop s2 (addr)
143
        i=i+1;   ram[i] = { `op_jmp_iez,      5'd1, `_, `_, `s0, `s0 };  // (s0==0) ? skip
144
        i=i+1;   ram[i] = { `op_add_i,       -6'd2, `_, `P, `s0, `s3 };  // s3-2=>s3, pop s3 (Y)
145
        i=i+1;   ram[i] = { `op_add_i,        6'd1, `P, `P, `s0, `s3 };  // s3+1=>s3, pop both
146
        // fill s1
147
        i=i+1;   ram[i] = {  op_lit_u,              `_, `_, `s0, `s2 };  // lit => s2
148
        i=i+1;   ram[i] = 16'h940                                     ;  // addr
149
        i=i+1;   ram[i] = {  op_gsb,                `P, `_, `s2, `s3 };  // gsb, pop s2 (addr)
150
        // check for push error
151
        i=i+1;   ram[i] = {  op_lit_u,              `_, `_, `s0, `s2 };  // lit => s2
152
        i=i+1;   ram[i] = 16'h910                                     ;  // addr
153
        i=i+1;   ram[i] = {  op_gsb,                `P, `_, `s2, `s3 };  // gsb, pop s2 (addr)
154
        i=i+1;   ram[i] = { `op_shl_iu,      -6'd8, `_, `P, `s0, `s0 };  // s0>>8=>s0, pop s0
155
        i=i+1;   ram[i] = { `op_jmp_iez,      5'd1, `_, `_, `s0, `s0 };  // (s0==0) ? skip
156
        i=i+1;   ram[i] = { `op_add_i,       -6'd2, `_, `P, `s0, `s3 };  // s3-2=>s3, pop s3
157
        i=i+1;   ram[i] = { `op_add_i,        6'd1, `P, `P, `s0, `s3 };  // s3+1=>s3, pop both
158
        // pop&push s/b OK
159
        i=i+1;   ram[i] = {  op_cpy,                `_, `P, `s2, `s1 };  // s2=>s1
160
        // check for no stack errors
161
        i=i+1;   ram[i] = {  op_lit_u,              `_, `_, `s0, `s2 };  // lit => s2
162
        i=i+1;   ram[i] = 16'h910                                     ;  // addr
163
        i=i+1;   ram[i] = {  op_gsb,                `P, `_, `s2, `s3 };  // gsb, pop s2 (addr)
164
        i=i+1;   ram[i] = { `op_jmp_iez,      5'd1, `_, `_, `s0, `s0 };  // (s0==0) ? skip
165
        i=i+1;   ram[i] = { `op_add_i,       -6'd2, `_, `P, `s0, `s3 };  // s3-2=>s3, pop s3
166
        i=i+1;   ram[i] = { `op_add_i,        6'd1, `P, `P, `s0, `s3 };  // s3+1=>s3, pop both
167
        // s/b one push over the line
168
        i=i+1;   ram[i] = {  op_cpy,                `_, `_, `s2, `s1 };  // s2=>s1
169
        // check for a push error
170
        i=i+1;   ram[i] = {  op_lit_u,              `_, `_, `s0, `s2 };  // lit => s2
171
        i=i+1;   ram[i] = 16'h910                                     ;  // addr
172
        i=i+1;   ram[i] = {  op_gsb,                `P, `_, `s2, `s3 };  // gsb, pop s2 (addr)
173
        i=i+1;   ram[i] = { `op_shl_iu,      -6'd8, `_, `P, `s0, `s0 };  // s0>>8=>s0, pop s0
174
        i=i+1;   ram[i] = { `op_jmp_iglz,     5'd1, `_, `_, `s0, `s0 };  // (s0<>0) ? skip
175
        i=i+1;   ram[i] = { `op_add_i,       -6'd2, `_, `P, `s0, `s3 };  // s3-2=>s3, pop s3
176
        i=i+1;   ram[i] = { `op_add_i,        6'd1, `P, `P, `s0, `s3 };  // s3+1=>s3, pop both
177
        // empty s1
178
        i=i+1;   ram[i] = {  op_lit_u,              `_, `_, `s0, `s2 };  // lit => s2
179
        i=i+1;   ram[i] = 16'h950                                     ;  // addr
180
        i=i+1;   ram[i] = {  op_gsb,                `P, `_, `s2, `s3 };  // gsb, pop s2 (addr)
181
        // check for no stack errors
182
        i=i+1;   ram[i] = {  op_lit_u,              `_, `_, `s0, `s2 };  // lit => s2
183
        i=i+1;   ram[i] = 16'h910                                     ;  // addr
184
        i=i+1;   ram[i] = {  op_gsb,                `P, `_, `s2, `s3 };  // gsb, pop s2 (addr)
185
        i=i+1;   ram[i] = { `op_jmp_iez,      5'd1, `_, `_, `s0, `s0 };  // (s0==0) ? skip
186
        i=i+1;   ram[i] = { `op_add_i,       -6'd2, `_, `P, `s0, `s3 };  // s3-2=>s3, pop s3
187
        i=i+1;   ram[i] = { `op_add_i,        6'd1, `P, `P, `s0, `s3 };  // s3+1=>s3, pop both
188
        // s/b one pop under the line
189
        i=i+1;   ram[i] = {  op_pop,                `_, `P, `s0, `s1 };  // pop s1
190
        // check for a pop error
191
        i=i+1;   ram[i] = {  op_lit_u,              `_, `_, `s0, `s2 };  // lit => s2
192
        i=i+1;   ram[i] = 16'h910                                     ;  // addr
193
        i=i+1;   ram[i] = {  op_gsb,                `P, `_, `s2, `s3 };  // gsb, pop s2 (addr)
194
        i=i+1;   ram[i] = { `op_shl_i,       6'd24, `_, `P, `s0, `s0 };  // s0<<24=>s0, pop s0
195
        i=i+1;   ram[i] = { `op_jmp_iglz,     5'd1, `_, `_, `s0, `s0 };  // (s0<>0) ? skip
196
        i=i+1;   ram[i] = { `op_add_i,       -6'd2, `_, `P, `s0, `s3 };  // s3-2=>s3, pop s3
197
        i=i+1;   ram[i] = { `op_add_i,        6'd1, `P, `P, `s0, `s3 };  // s3+1=>s3, pop both
198
        // s3=>s0, loop forever
199
        i=i+1;   ram[i] = {  op_cpy,                `P, `P, `s3, `s0 };  // s3=>s0, pop both
200
        i=i+1;   ram[i] = { `op_jmp_i,       -6'h1, `_, `_, `s0, `s0 };  // loop forever
201
 
202
 
203
        // test stack clearing, result in s0
204
        // Correct functioning is s0 = 'd2 ('h2).
205
        //
206
        // s0 : final test result
207
        // s1 : test stack
208
        // s2 : sub addr
209
        // s3 : running test result, subroutine return address
210
        //
211
        // setup running test result:
212
        i='h200; ram[i] = { `op_byt_i,        8'd0, `_, `_, `s0, `s3 };  // 0=>s3
213
        // check for no stack errors
214
        i=i+1;   ram[i] = {  op_lit_u,              `_, `_, `s0, `s2 };  // lit => s2
215
        i=i+1;   ram[i] = 16'h910                                     ;  // addr
216
        i=i+1;   ram[i] = {  op_gsb,                `P, `_, `s2, `s3 };  // gsb, pop s2 (addr)
217
        i=i+1;   ram[i] = { `op_jmp_iez,      5'd1, `_, `_, `s0, `s0 };  // (s0==0) ? skip
218
        i=i+1;   ram[i] = { `op_add_i,       -6'd2, `_, `P, `s0, `s3 };  // s3-2=>s3, pop s3 (Y)
219
        i=i+1;   ram[i] = { `op_add_i,        6'd1, `P, `P, `s0, `s3 };  // s3+1=>s3, pop both
220
        // fill s1
221
        i=i+1;   ram[i] = {  op_lit_u,              `_, `_, `s0, `s2 };  // lit => s2
222
        i=i+1;   ram[i] = 16'h940                                     ;  // addr
223
        i=i+1;   ram[i] = {  op_gsb,                `P, `_, `s2, `s3 };  // gsb, pop s2 (addr)
224
        // save s3
225
        i=i+1;   ram[i] = {  op_lit_u,              `_, `_, `s0, `s2 };  // lit => s2
226
        i=i+1;   ram[i] = 16'ha00                                     ;  // addr
227
        i=i+1;   ram[i] = { `op_wr_i,         4'd0, `P, `_, `s2, `s3 };  // write s3=>(s2+offset), pop s2
228
        // clear all stacks
229
        i=i+1;   ram[i] = {  op_cls,                `_, `_, `s0, `s0 };  // clear stacks
230
        // restore s3
231
        i=i+1;   ram[i] = {  op_lit_u,              `_, `_, `s0, `s2 };  // lit => s2
232
        i=i+1;   ram[i] = 16'ha00                                     ;  // addr
233
        i=i+1;   ram[i] = { `op_rd_i,         4'd0, `P, `_, `s2, `s3 };  // read (s2+offset) => s3, pop s2
234
        // fill s1 again
235
        i=i+1;   ram[i] = {  op_lit_u,              `_, `_, `s0, `s2 };  // lit => s2
236
        i=i+1;   ram[i] = 16'h940                                     ;  // addr
237
        i=i+1;   ram[i] = {  op_gsb,                `P, `_, `s2, `s3 };  // gsb, pop s2 (addr)
238
        // check for no stack errors
239
        i=i+1;   ram[i] = {  op_lit_u,              `_, `_, `s0, `s2 };  // lit => s2
240
        i=i+1;   ram[i] = 16'h910                                     ;  // addr
241
        i=i+1;   ram[i] = {  op_gsb,                `P, `_, `s2, `s3 };  // gsb, pop s2 (addr)
242
        i=i+1;   ram[i] = { `op_jmp_iez,      5'd1, `_, `_, `s0, `s0 };  // (s0==0) ? skip
243
        i=i+1;   ram[i] = { `op_add_i,       -6'd2, `_, `P, `s0, `s3 };  // s3-2=>s3, pop s3
244
        i=i+1;   ram[i] = { `op_add_i,        6'd1, `P, `P, `s0, `s3 };  // s3+1=>s3, pop both
245
        // s3=>s0, loop forever
246
        i=i+1;   ram[i] = {  op_cpy,                `P, `P, `s3, `s0 };  // s3=>s0, pop both
247
        i=i+1;   ram[i] = { `op_jmp_i,       -6'h1, `_, `_, `s0, `s0 };  // loop forever
248
 
249
 
250
        /////////////////
251
        // subroutines //
252
        /////////////////
253
 
254
 
255
        // sub : read & clear opcode errors for this thread => s0, return to (s3)
256
        i='h900; ram[i] = {  op_lit_u,              `_, `_, `s0, `s2 };  // lit => s2
257
        i=i+1;   ram[i] = REG_BASE_ADDR                               ;  // reg base addr
258
        i=i+1;   ram[i] = { `op_rd_i, THRD_ID_ADDR, `_, `_, `s2, `s0 };  // read (s2+offset)=>s0
259
        i=i+1;   ram[i] = {  op_shl_u,              `_, `P, `s0, `s0 };  // 1<<s0=>s0, pop s0
260
        i=i+1;   ram[i] = { `op_rd_i,   OP_ER_ADDR, `_, `_, `s2, `s3 };  // read (s2+offset)=>s3
261
        i=i+1;   ram[i] = {  op_and,                `P, `P, `s3, `s0 };  // s0&s3=>s0, pop both
262
        i=i+1;   ram[i] = { `op_wr_i,   OP_ER_ADDR, `P, `_, `s2, `s0 };  // write s0=>(s2+offset), pop s2
263
        i=i+1;   ram[i] = {  op_gto,                `P, `_, `s3, `s0 };  // return to (s3), pop s3
264
 
265
 
266
        // sub : read & clear stack errors for this thread => s0, return to (s3)
267
        i='h910; ram[i] = {  op_lit_u,              `_, `_, `s0, `s2 };  // lit => s2
268
        i=i+1;   ram[i] = REG_BASE_ADDR                               ;  // reg base addr
269
        i=i+1;   ram[i] = { `op_rd_i, THRD_ID_ADDR, `_, `_, `s2, `s0 };  // read (s2+offset)=>s0
270
        i=i+1;   ram[i] = {  op_shl_u,              `_, `P, `s0, `s0 };  // 1<<s0=>s0, pop s0
271
        i=i+1;   ram[i] = {  op_cpy,                `_, `_, `s0, `s3 };  // s0=>s3
272
        i=i+1;   ram[i] = { `op_shl_i,        6'd8, `_, `P, `s0, `s3 };  // s3<<8=>s3, pop s3
273
        i=i+1;   ram[i] = {  op_or,                 `P, `P, `s3, `s0 };  // s0|s3=>s0, pop both
274
        i=i+1;   ram[i] = { `op_rd_i,  STK_ER_ADDR, `_, `_, `s2, `s3 };  // read (s2+offset)=>s3
275
        i=i+1;   ram[i] = {  op_and,                `P, `P, `s3, `s0 };  // s0&s3=>s0, pop both
276
        i=i+1;   ram[i] = { `op_wr_i,  STK_ER_ADDR, `P, `_, `s2, `s0 };  // write s0=>(s2+offset), pop s2
277
        i=i+1;   ram[i] = {  op_gto,                `P, `_, `s3, `s0 };  // return to (s3), pop s3
278
 
279
 
280
        // sub : read 32 bit GPIO => s0, return to (s3)
281
        i='h920; ram[i] = {  op_lit_u,              `_, `_, `s0, `s1 };  // lit => s1
282
        i=i+1;   ram[i] = REG_BASE_ADDR                               ;  // reg base addr
283
        i=i+1;   ram[i] = { `op_rd_i,   IO_LO_ADDR, `_, `_, `s1, `s0 };  // read (s1+offset) => s0
284
        i=i+1;   ram[i] = { `op_rd_ix,  IO_HI_ADDR, `P, `P, `s1, `s0 };  // read (s1+offset) => s0, pop s1 & s0
285
        i=i+1;   ram[i] = {  op_gto,                `P, `_, `s3, `s0 };  // return, pop s3
286
 
287
 
288
        // sub : write s0 => 32 bit GPIO, return to (s3)
289
        i='h930; ram[i] = {  op_lit_u,              `_, `_, `s0, `s1 };  // lit => s1
290
        i=i+1;   ram[i] = REG_BASE_ADDR                               ;  // reg base addr
291
        i=i+1;   ram[i] = { `op_wr_i,   IO_LO_ADDR, `_, `_, `s1, `s0 };  // write s0 => (s1+offset)
292
        i=i+1;   ram[i] = { `op_wr_ix,  IO_HI_ADDR, `P, `_, `s1, `s0 };  // write s0 => (s1+offset), pop s1
293
        i=i+1;   ram[i] = {  op_gto,                `P, `_, `s3, `s0 };  // return, pop s3
294
 
295
        // sub : loop until empty s1 is full, return to (s3)
296
        // loop setup:
297
        i='h940; ram[i] = { `op_byt_i,       8'd32, `_, `_, `s0, `s2 };  // 32=>s2
298
        // loop
299
        i=i+1;   ram[i] = { `op_add_i,       -6'd1, `_, `P, `s0, `s2 };  // s2--=>s2, pop s2
300
        i=i+1;   ram[i] = {  op_cpy,                `_, `_, `s2, `s1 };  // s2=>s1
301
        i=i+1;   ram[i] = { `op_jmp_igz,     -5'd3, `_, `_, `s0, `s2 };  // (s2>0) ? do again
302
        i=i+1;   ram[i] = {  op_gto,                `P, `P, `s3, `s2 };  // return, pop s3 & s2
303
 
304
        // sub : loop until full s1 is empty, return to (s3)
305
        // loop setup:
306
        i='h950; ram[i] = { `op_byt_i,       8'd32, `_, `_, `s0, `s2 };  // 32=>s2
307
        // loop
308
        i=i+1;   ram[i] = { `op_add_i,       -6'd1, `_, `P, `s0, `s2 };  // s2+1=>s2, pop s2
309
        i=i+1;   ram[i] = {  op_pop,                `_, `P, `s0, `s1 };  // pop s1
310
        i=i+1;   ram[i] = { `op_jmp_igz,     -5'd3, `_, `_, `s0, `s2 };  // (s2>0) ? do again
311
        i=i+1;   ram[i] = {  op_gto,                `P, `P, `s3, `s2 };  // return, pop s3 & s2
312
 
313
 
314
        end

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.