| 1 |
4 |
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 stuff --
|
| 28 |
|
|
--------------------
|
| 29 |
|
|
*/
|
| 30 |
|
|
`include "op_encode.h"
|
| 31 |
|
|
`include "reg_set_addr.h"
|
| 32 |
|
|
`include "boot_code_defs.h"
|
| 33 |
|
|
|
| 34 |
|
|
/*
|
| 35 |
|
|
----------------------------------------
|
| 36 |
|
|
-- initialize: fill with default data --
|
| 37 |
|
|
----------------------------------------
|
| 38 |
|
|
*/
|
| 39 |
|
|
integer i;
|
| 40 |
|
|
|
| 41 |
|
|
initial begin
|
| 42 |
|
|
|
| 43 |
|
|
/* // fill with nop (some compilers need this)
|
| 44 |
|
|
for ( i = 0; i < CAPACITY; i = i+1 ) begin
|
| 45 |
|
|
ram[i] = { `nop, `s0, `s0 };
|
| 46 |
|
|
end
|
| 47 |
|
|
*/
|
| 48 |
|
|
|
| 49 |
|
|
/*
|
| 50 |
|
|
---------------
|
| 51 |
|
|
-- boot code --
|
| 52 |
|
|
---------------
|
| 53 |
|
|
*/
|
| 54 |
|
|
|
| 55 |
|
|
|
| 56 |
|
|
/*
|
| 57 |
|
|
------------
|
| 58 |
|
|
-- TEST 0 --
|
| 59 |
|
|
------------
|
| 60 |
|
|
*/
|
| 61 |
|
|
|
| 62 |
|
|
// Log base 2
|
| 63 |
|
|
// Thread 0 : Get input 32 bit GPIO, calculate log2, output 32 bit GPIO.
|
| 64 |
|
|
// Other threads : do nothing, loop forever
|
| 65 |
|
|
|
| 66 |
|
|
///////////////
|
| 67 |
|
|
// clr space //
|
| 68 |
|
|
///////////////
|
| 69 |
|
|
|
| 70 |
|
|
i='h0; ram[i] = { `lit_u, `__, `s1 }; // s1=addr
|
| 71 |
|
|
i=i+1; ram[i] = 16'h0040 ; //
|
| 72 |
|
|
i=i+1; ram[i] = { `gto, `P1, `__ }; // goto, pop s1 (addr)
|
| 73 |
|
|
//
|
| 74 |
|
|
i='h04; ram[i] = { `jmp_ie, -4'd1, `s0, `s0 }; // loop forever
|
| 75 |
|
|
i='h08; ram[i] = { `jmp_ie, -4'd1, `s0, `s0 }; // loop forever
|
| 76 |
|
|
i='h0c; ram[i] = { `jmp_ie, -4'd1, `s0, `s0 }; // loop forever
|
| 77 |
|
|
i='h10; ram[i] = { `jmp_ie, -4'd1, `s0, `s0 }; // loop forever
|
| 78 |
|
|
i='h14; ram[i] = { `jmp_ie, -4'd1, `s0, `s0 }; // loop forever
|
| 79 |
|
|
i='h18; ram[i] = { `jmp_ie, -4'd1, `s0, `s0 }; // loop forever
|
| 80 |
|
|
i='h1c; ram[i] = { `jmp_ie, -4'd1, `s0, `s0 }; // loop forever
|
| 81 |
|
|
|
| 82 |
|
|
////////////////
|
| 83 |
|
|
// intr space //
|
| 84 |
|
|
////////////////
|
| 85 |
|
|
|
| 86 |
|
|
///////////////////////
|
| 87 |
|
|
// code & data space //
|
| 88 |
|
|
///////////////////////
|
| 89 |
|
|
|
| 90 |
|
|
// read & write 32 bit GPIO data to & from s0
|
| 91 |
|
|
i='h40; ram[i] = { `lit_u, `__, `s3 }; // s3=addr
|
| 92 |
|
|
i=i+1; ram[i] = 16'h0080 ; //
|
| 93 |
|
|
i=i+1; ram[i] = { `gsb, `P3, `s3 }; // gsb, pop s3 (addr)
|
| 94 |
|
|
// do s0=log2(s0)
|
| 95 |
|
|
i=i+1; ram[i] = { `lit_u, `__, `s3 }; // s3=addr
|
| 96 |
|
|
i=i+1; ram[i] = 16'h0090 ; //
|
| 97 |
|
|
i=i+1; ram[i] = { `gsb, `P3, `s7 }; // gsb, pop s3 (addr)
|
| 98 |
|
|
// write s0 data to 32 bit GPIO
|
| 99 |
|
|
i=i+1; ram[i] = { `lit_u, `__, `s3 }; // s3=addr
|
| 100 |
|
|
i=i+1; ram[i] = 16'h0070 ; //
|
| 101 |
|
|
i=i+1; ram[i] = { `gsb, `P3, `s3 }; // gsb, pop s3 (addr)
|
| 102 |
|
|
// loop forever
|
| 103 |
|
|
i=i+1; ram[i] = { `jmp_ie, -4'd1, `s0, `s0 }; // loop forever
|
| 104 |
|
|
|
| 105 |
|
|
|
| 106 |
|
|
// sub : read 32 bit GPIO => s0, return to (s3)
|
| 107 |
|
|
i='h60; ram[i] = { `dat_is, `IO_LO, `s1 }; // s1=reg addr
|
| 108 |
|
|
i=i+1; ram[i] = { `reg_rs, `P1, `s0 }; // s0=(s1), pop s1
|
| 109 |
|
|
i=i+1; ram[i] = { `dat_is, `IO_HI, `s1 }; // s1=reg addr
|
| 110 |
|
|
i=i+1; ram[i] = { `reg_rh, `P1, `P0 }; // s0=(s1), pop both
|
| 111 |
|
|
i=i+1; ram[i] = { `gto, `P3, `__ }; // return, pop s3
|
| 112 |
|
|
|
| 113 |
|
|
|
| 114 |
|
|
// sub : write s0 => 32 bit GPIO, return to (s3)
|
| 115 |
|
|
i='h70; ram[i] = { `dat_is, `IO_LO, `s1 }; // s1=reg addr
|
| 116 |
|
|
i=i+1; ram[i] = { `reg_w, `P1, `s0 }; // (s1)=s0, pop s1
|
| 117 |
|
|
i=i+1; ram[i] = { `dat_is, `IO_HI, `s1 }; // s1=reg addr
|
| 118 |
|
|
i=i+1; ram[i] = { `reg_wh, `P1, `s0 }; // (s1)=s0, pop s1
|
| 119 |
|
|
i=i+1; ram[i] = { `gto, `P3, `__ }; // return, pop s3
|
| 120 |
|
|
|
| 121 |
|
|
|
| 122 |
|
|
// sub : read & write 32 bit GPIO => s0, return to (s3)
|
| 123 |
|
|
i='h80; ram[i] = { `dat_is, `IO_LO, `s1 }; // s1=reg addr
|
| 124 |
|
|
i=i+1; ram[i] = { `reg_rs, `s1, `s0 }; // s0=(s1)
|
| 125 |
|
|
i=i+1; ram[i] = { `reg_w, `P1, `s0 }; // (s1)=s0, pop s1
|
| 126 |
|
|
i=i+1; ram[i] = { `dat_is, `IO_HI, `s1 }; // s1=reg addr
|
| 127 |
|
|
i=i+1; ram[i] = { `reg_rh, `s1, `P0 }; // s0=(s1), pop s0
|
| 128 |
|
|
i=i+1; ram[i] = { `reg_wh, `P1, `s0 }; // (s1)=s0, pop s1
|
| 129 |
|
|
i=i+1; ram[i] = { `gto, `P3, `__ }; // return, pop s3
|
| 130 |
|
|
|
| 131 |
|
|
|
| 132 |
|
|
|
| 133 |
|
|
// sub : s0=log2(s0), return to (s7)
|
| 134 |
|
|
//
|
| 135 |
|
|
// input is in[31:0] an unsigned 32 bit integer
|
| 136 |
|
|
// output is c[31:27].m[26:0] unsigned fixed decimal
|
| 137 |
|
|
//
|
| 138 |
|
|
// s0 : input, normalize, square, output
|
| 139 |
|
|
// s1 : lzc, result
|
| 140 |
|
|
// s2 :
|
| 141 |
|
|
// s3 :
|
| 142 |
|
|
// s4 :
|
| 143 |
|
|
// s5 :
|
| 144 |
|
|
// s6 : loop index
|
| 145 |
|
|
// s7 : sub return address
|
| 146 |
|
|
//
|
| 147 |
|
|
// (input=0)? is an error, return
|
| 148 |
|
|
i='h90; ram[i] = { `jmp_inz, 6'd1, `s0 }; // (s0!=0) ? skip return
|
| 149 |
|
|
i=i+1; ram[i] = { `gto, `P7, `__ }; // return to (s7), pop s7
|
| 150 |
|
|
// normalize
|
| 151 |
|
|
i=i+1; ram[i] = { `lzc, `s0, `s1 }; // s1=lzc(s0)
|
| 152 |
|
|
i=i+1; ram[i] = { `shl_s, `s1, `P0 }; // s0<<=s1 (normalize)
|
| 153 |
|
|
// loop setup
|
| 154 |
|
|
i=i+1; ram[i] = { `dat_is, 6'd26, `s6 }; // s6=26 (loop index)
|
| 155 |
|
|
// loop start
|
| 156 |
|
|
i=i+1; ram[i] = { `mul_xu, `s0, `P0 }; // s0*=s0
|
| 157 |
|
|
i=i+1; ram[i] = { `shl_is, 6'd1, `P1 }; // s1<<=1
|
| 158 |
|
|
// jump start
|
| 159 |
|
|
i=i+1; ram[i] = { `jmp_ilz, 6'd2, `s0 }; // (s0[31]==1) ? jump
|
| 160 |
|
|
i=i+1; ram[i] = { `shl_is, 6'd1, `P0 }; // s0<<=1
|
| 161 |
|
|
i=i+1; ram[i] = { `add_is, 6'd1, `P1 }; // s1++
|
| 162 |
|
|
// jump end
|
| 163 |
|
|
i=i+1; ram[i] = { `add_is, -6'd1, `P6 }; // s6--
|
| 164 |
|
|
i=i+1; ram[i] = { `jmp_inlz, -6'd7, `s6 }; // (s6>=0) ? do again
|
| 165 |
|
|
// loop end
|
| 166 |
|
|
// cleanup, return
|
| 167 |
|
|
i=i+1; ram[i] = { `not, `P1, `P0 }; // s0=~s1, pop both
|
| 168 |
|
|
i=i+1; ram[i] = { `gto, `P7, `P6 }; // return, pop s7 & s6
|
| 169 |
|
|
// end sub
|
| 170 |
|
|
|
| 171 |
|
|
end
|