| 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 "boot_code_defs.h"
|
| 31 |
|
|
`include "op_encode.h"
|
| 32 |
|
|
`include "reg_set_addr.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=exp2(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=exp2(s0), return to (s7)
|
| 134 |
|
|
//
|
| 135 |
|
|
// input is c[31:27].m[26:0] unsigned fixed decimal
|
| 136 |
|
|
// output is out[31:0] an unsigned 32 bit integer
|
| 137 |
|
|
//
|
| 138 |
|
|
// s0 : input, output
|
| 139 |
|
|
// s1 : running multiply
|
| 140 |
|
|
// s2 : running root
|
| 141 |
|
|
// s3 : fudge factor
|
| 142 |
|
|
// s4 :
|
| 143 |
|
|
// s5 :
|
| 144 |
|
|
// s6 : loop index
|
| 145 |
|
|
// s7 : sub return addr
|
| 146 |
|
|
//
|
| 147 |
|
|
// setup
|
| 148 |
|
|
i='h90; ram[i] = { `flp, `s0, `P0 }; // flp(s0) (to examine lsbs via msb)
|
| 149 |
|
|
i=i+1; ram[i] = { `psu_i, 6'd31, `s1 }; // s1=0x8000,0000 (starting value = 1)
|
| 150 |
|
|
i=i+1; ram[i] = { `cpy, `s1, `s2 }; // s2=0x8000,000b (starting root = 2^2^-27)
|
| 151 |
|
|
i=i+1; ram[i] = { `add_is, 6'hb, `P2 }; //
|
| 152 |
|
|
i=i+1; ram[i] = { `lit_u, `__, `s3 }; // s3=0x173c,e500 (fudge factor bits)
|
| 153 |
|
|
i=i+1; ram[i] = 16'he500 ; //
|
| 154 |
|
|
i=i+1; ram[i] = { `lit_h, `__, `P3 }; //
|
| 155 |
|
|
i=i+1; ram[i] = 16'h173c ; //
|
| 156 |
|
|
i=i+1; ram[i] = { `dat_is, 6'd26, `s6 }; // s6=26 (loop index)
|
| 157 |
|
|
// loop start
|
| 158 |
|
|
// jump 0 start
|
| 159 |
|
|
i=i+1; ram[i] = { `jmp_inlz, 6'd2, `s0 }; // (s0[31]==0) ? jump +2 (skip running mult)
|
| 160 |
|
|
i=i+1; ram[i] = { `mul_xu, `s2, `P1 }; // s1*=s2
|
| 161 |
|
|
i=i+1; ram[i] = { `shl_is, 6'd1, `P1 }; // s1<<=1 (so msb=1)
|
| 162 |
|
|
// jump 0 end
|
| 163 |
|
|
i=i+1; ram[i] = { `mul_xu, `s2, `P2 }; // s2*=s2 (square to get next root)
|
| 164 |
|
|
i=i+1; ram[i] = { `shl_is, 6'd1, `P2 }; // s2<<=1 (so msb=1 & lsb=0)
|
| 165 |
|
|
// jump 1 start
|
| 166 |
|
|
i=i+1; ram[i] = { `jmp_inlz, 6'd1, `s3 }; // (s3[31]==0) ? jump +1 (no fudge bit)
|
| 167 |
|
|
i=i+1; ram[i] = { `add_is, 6'd1, `P2 }; // s2++ (set lsb of running root)
|
| 168 |
|
|
// jump 1 end
|
| 169 |
|
|
i=i+1; ram[i] = { `shl_is, 6'd1, `P0 }; // s0<<=1 (get next input bit)
|
| 170 |
|
|
i=i+1; ram[i] = { `shl_is, 6'd1, `P3 }; // s2<<=1 (get next fudge bit)
|
| 171 |
|
|
i=i+1; ram[i] = { `add_is, -6'd1, `P6 }; // s6-- (loop index--)
|
| 172 |
|
|
i=i+1; ram[i] = { `jmp_inlz, -6'd11, `s6 }; // (s6>=0) ? jump -11 (loop again)
|
| 173 |
|
|
// loop end
|
| 174 |
|
|
// final shift
|
| 175 |
|
|
i=i+1; ram[i] = { `flp, `s0, `P0 }; // flp(s0) (flip remaining bits)
|
| 176 |
|
|
i=i+1; ram[i] = { `add_is, -6'd31, `P0 }; // s0-=31
|
| 177 |
|
|
i=i+1; ram[i] = { `shl_u, `P0, `P1 }; // s1<<=s0, pop s0
|
| 178 |
|
|
// cleanup, return
|
| 179 |
|
|
i=i+1; ram[i] = { `cpy, `P1, `s0 }; // s0=s1, pop s1 (move)
|
| 180 |
|
|
i=i+1; ram[i] = { `pop, 8'b01000110 }; // pop s2, s3, s6
|
| 181 |
|
|
i=i+1; ram[i] = { `gto, `P7, `__ }; // return, pop s7
|
| 182 |
|
|
// end sub
|
| 183 |
|
|
|
| 184 |
|
|
end
|