You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

348 lines
15 KiB

table SIN_WAVE 16 1024 {
0, 201, 402, 603, 804, 1005, 1206, 1406,
1607, 1808, 2009, 2209, 2410, 2610, 2811, 3011,
3211, 3411, 3611, 3811, 4011, 4210, 4409, 4608,
4807, 5006, 5205, 5403, 5601, 5799, 5997, 6195,
6392, 6589, 6786, 6982, 7179, 7375, 7571, 7766,
7961, 8156, 8351, 8545, 8739, 8932, 9126, 9319,
9511, 9703, 9895, 10087, 10278, 10469, 10659, 10849,
11038, 11227, 11416, 11604, 11792, 11980, 12166, 12353,
12539, 12724, 12909, 13094, 13278, 13462, 13645, 13827,
14009, 14191, 14372, 14552, 14732, 14911, 15090, 15268,
15446, 15623, 15799, 15975, 16150, 16325, 16499, 16672,
16845, 17017, 17189, 17360, 17530, 17699, 17868, 18036,
18204, 18371, 18537, 18702, 18867, 19031, 19194, 19357,
19519, 19680, 19840, 20000, 20159, 20317, 20474, 20631,
20787, 20942, 21096, 21249, 21402, 21554, 21705, 21855,
22004, 22153, 22301, 22448, 22594, 22739, 22883, 23027,
23169, 23311, 23452, 23592, 23731, 23869, 24006, 24143,
24278, 24413, 24546, 24679, 24811, 24942, 25072, 25201,
25329, 25456, 25582, 25707, 25831, 25954, 26077, 26198,
26318, 26437, 26556, 26673, 26789, 26905, 27019, 27132,
27244, 27355, 27466, 27575, 27683, 27790, 27896, 28001,
28105, 28208, 28309, 28410, 28510, 28608, 28706, 28802,
28897, 28992, 29085, 29177, 29268, 29358, 29446, 29534,
29621, 29706, 29790, 29873, 29955, 30036, 30116, 30195,
30272, 30349, 30424, 30498, 30571, 30643, 30713, 30783,
30851, 30918, 30984, 31049,
31113, 31175, 31236, 31297,
31356, 31413, 31470, 31525, 31580, 31633, 31684, 31735,
31785, 31833, 31880, 31926, 31970, 32014, 32056, 32097,
32137, 32176, 32213, 32249, 32284, 32318, 32350, 32382,
32412, 32441, 32468, 32495, 32520, 32544, 32567, 32588,
32609, 32628, 32646, 32662, 32678, 32692, 32705, 32717,
32727, 32736, 32744, 32751, 32757, 32761, 32764, 32766,
32767, 32766, 32764, 32761, 32757, 32751, 32744, 32736,
32727, 32717, 32705, 32692, 32678, 32662, 32646, 32628,
32609, 32588, 32567, 32544, 32520, 32495, 32468, 32441,
32412, 32382, 32350, 32318, 32284, 32249, 32213, 32176,
32137, 32097, 32056, 32014, 31970, 31926, 31880, 31833,
31785, 31735, 31684, 31633, 31580, 31525, 31470, 31413,
31356, 31297, 31236, 31175, 31113, 31049, 30984, 30918,
30851, 30783, 30713, 30643, 30571, 30498, 30424, 30349,
30272, 30195, 30116, 30036, 29955, 29873, 29790, 29706,
29621, 29534, 29446, 29358, 29268, 29177, 29085, 28992,
28897, 28802, 28706, 28608, 28510, 28410, 28309, 28208,
28105, 28001, 27896, 27790, 27683, 27575, 27466, 27355,
27244, 27132, 27019, 26905, 26789, 26673, 26556, 26437,
26318, 26198, 26077, 25954, 25831, 25707, 25582, 25456,
25329, 25201, 25072, 24942, 24811, 24679, 24546, 24413,
24278, 24143, 24006, 23869, 23731, 23592, 23452, 23311,
23169, 23027, 22883, 22739, 22594, 22448, 22301, 22153,
22004, 21855, 21705, 21554, 21402, 21249, 21096, 20942,
20787, 20631, 20474, 20317, 20159, 20000, 19840, 19680,
19519, 19357, 19194, 19031, 18867, 18702, 18537, 18371,
18204, 18036, 17868, 17699, 17530, 17360, 17189, 17017,
16845, 16672, 16499, 16325, 16150, 15975, 15799, 15623,
15446, 15268, 15090, 14911, 14732, 14552, 14372, 14191,
14009, 13827, 13645, 13462, 13278, 13094, 12909, 12724,
12539, 12353, 12166, 11980, 11792, 11604, 11416, 11227,
11038, 10849, 10659, 10469, 10278, 10087, 9895, 9703,
9511, 9319, 9126, 8932, 8739, 8545, 8351, 8156,
7961, 7766, 7571, 7375, 7179, 6982, 6786, 6589,
6392, 6195, 5997, 5799, 5601, 5403, 5205, 5006,
4807, 4608, 4409, 4210, 4011, 3811, 3611, 3411,
3211, 3011, 2811, 2610, 2410, 2209, 2009, 1808,
1607, 1406, 1206, 1005, 804, 603, 402, 201,
0, 65335, 65134, 64933, 64732, 64531, 64330, 64130,
63929, 63728, 63527, 63327, 63126, 62926, 62725, 62525,
62325, 62125, 61925, 61725, 61525, 61326, 61127, 60928,
60729, 60530, 60331, 60133, 59935, 59737, 59539, 59341,
59144, 58947, 58750, 58554, 58357, 58161, 57965, 57770,
57575, 57380, 57185, 56991, 56797, 56604, 56410, 56217,
56025, 55833, 55641, 55449, 55258, 55067, 54877, 54687,
54498, 54309, 54120, 53932, 53744, 53556, 53370, 53183,
52997, 52812, 52627, 52442, 52258, 52074, 51891, 51709,
51527, 51345, 51164, 50984, 50804, 50625, 50446, 50268,
50090, 49913, 49737, 49561, 49386, 49211, 49037, 48864,
48691, 48519, 48347, 48176, 48006, 47837, 47668, 47500,
47332, 47165, 46999, 46834, 46669, 46505, 46342, 46179,
46017, 45856, 45696, 45536, 45377, 45219, 45062, 44905,
44749, 44594, 44440, 44287, 44134, 43982, 43831, 43681,
43532, 43383, 43235, 43088, 42942, 42797, 42653, 42509,
42367, 42225, 42084, 41944, 41805, 41667, 41530, 41393,
41258, 41123, 40990, 40857, 40725, 40594, 40464, 40335,
40207, 40080, 39954, 39829, 39705, 39582, 39459, 39338,
39218, 39099, 38980, 38863, 38747, 38631, 38517, 38404,
38292, 38181, 38070, 37961, 37853, 37746, 37640, 37535,
37431, 37328, 37227, 37126, 37026, 36928, 36830, 36734,
36639, 36544, 36451, 36359, 36268, 36178, 36090, 36002,
35915, 35830, 35746, 35663, 35581, 35500, 35420, 35341,
35264, 35187, 35112, 35038, 34965, 34893, 34823, 34753,
34685, 34618, 34552, 34487, 34423, 34361, 34300, 34239,
34180, 34123, 34066, 34011, 33956, 33903, 33852, 33801,
33751, 33703, 33656, 33610, 33566, 33522, 33480, 33439,
33399, 33360, 33323, 33287, 33252, 33218, 33186, 33154,
33124, 33095, 33068, 33041, 33016, 32992, 32969, 32948,
32927, 32908, 32890, 32874, 32858, 32844, 32831, 32819,
32809, 32800, 32792, 32785, 32779, 32775, 32772, 32770,
32769, 32770, 32772, 32775, 32779, 32785, 32792, 32800,
32809, 32819, 32831, 32844, 32858, 32874, 32890, 32908,
32927, 32948, 32969, 32992, 33016, 33041, 33068, 33095,
33124, 33154, 33186, 33218, 33252, 33287, 33323, 33360,
33399, 33439, 33480, 33522, 33566, 33610, 33656, 33703,
33751, 33801, 33852, 33903, 33956, 34011, 34066, 34123,
34180, 34239, 34300, 34361, 34423, 34487, 34552, 34618,
34685, 34753, 34823, 34893, 34965, 35038, 35112, 35187,
35264, 35341, 35420, 35500, 35581, 35663, 35746, 35830,
35915, 36002, 36090, 36178, 36268, 36359, 36451, 36544,
36639, 36734, 36830, 36928, 37026, 37126, 37227, 37328,
37431, 37535, 37640, 37746, 37853, 37961, 38070, 38181,
38292, 38404, 38517, 38631, 38747, 38863, 38980, 39099,
39218, 39338, 39459, 39582, 39705, 39829, 39954, 40080,
40207, 40335, 40464, 40594, 40725, 40857, 40990, 41123,
41258, 41393, 41530, 41667, 41805, 41944, 42084, 42225,
42367, 42509, 42653, 42797, 42942, 43088, 43235, 43383,
43532, 43681, 43831, 43982, 44134, 44287, 44440, 44594,
44749, 44905, 45062, 45219, 45377, 45536, 45696, 45856,
46017, 46179, 46342, 46505, 46669, 46834, 46999, 47165,
47332, 47500, 47668, 47837, 48006, 48176, 48347, 48519,
48691, 48864, 49037, 49211, 49386, 49561, 49737, 49913,
50090, 50268, 50446, 50625, 50804, 50984, 51164, 51345,
51527, 51709, 51891, 52074, 52258, 52442, 52627, 52812,
52997, 53183, 53370, 53556, 53744, 53932, 54120, 54309,
54498, 54687, 54877, 55067, 55258, 55449, 55641, 55833,
56025, 56217, 56410, 56604, 56797, 56991, 57185, 57380,
57575, 57770, 57965, 58161, 58357, 58554, 58750, 58947,
59144, 59341, 59539, 59737, 59935, 60133, 60331, 60530,
60729, 60928, 61127, 61326, 61525, 61725, 61925, 62125,
62325, 62525, 62725, 62926, 63126, 63327, 63527, 63728,
63929, 64130, 64330, 64531, 64732, 64933, 65134, 65335
}
regfile FFT_REG 64 2 fftv
regfile FFT_REG_SIMD 128 2 fftsv
function [31:0] FFT_VAR_SHIFT([31:0] data, [3:0] sh)
{
assign FFT_VAR_SHIFT = TIEmux(sh,
data[31:0],
{data[30:0], 1'b0},
{data[29:0], 2'b0},
{data[28:0], 3'b0},
{data[27:0], 4'b0},
{data[26:0], 5'b0},
{data[25:0], 6'b0},
{data[24:0], 7'b0},
{data[23:0], 8'b0},
{data[22:0], 9'b0},
{data[21:0], 10'b0},
{data[20:0], 11'b0},
{data[19:0], 12'b0},
{data[18:0], 13'b0},
{data[17:0], 14'b0},
{data[16:0], 15'b0}
);
}
operation FFT_SIMD_LOAD {in AR *base, in AR offset, out FFT_REG_SIMD data} {out VAddr, in MemDataIn128}
{
assign VAddr = TIEadd(base, {offset[30:0], 1'b0}, 1'b0);
wire [15:0] o1 = MemDataIn128[15:0];
wire [15:0] o2 = MemDataIn128[31:16];
wire [15:0] o3 = MemDataIn128[47:32];
wire [15:0] o4 = MemDataIn128[63:48];
wire [15:0] o5 = MemDataIn128[79:64];
wire [15:0] o6 = MemDataIn128[95:80];
wire [15:0] o7 = MemDataIn128[111:96];
wire [15:0] o8 = MemDataIn128[127:112];
assign data = {o1, o2, o3, o4, o5, o6, o7, o8 };
}
operation FFT_SIMD_STORE {in AR *base, in AR offset, in FFT_REG_SIMD data} {out VAddr, out MemDataOut128}
{
assign VAddr = TIEadd(base, {offset[30:0], 1'b0}, 1'b0);
wire [15:0] o1 = data[15:0];
wire [15:0] o2 = data[31:16];
wire [15:0] o3 = data[47:32];
wire [15:0] o4 = data[63:48];
wire [15:0] o5 = data[79:64];
wire [15:0] o6 = data[95:80];
wire [15:0] o7 = data[111:96];
wire [15:0] o8 = data[127:112];
assign MemDataOut128 = {o1, o2, o3, o4, o5, o6, o7, o8 };
}
operation FFT_SHIFT_CHECK {in AR *base, in AR offset, out AR needs_shift} {out VAddr, in MemDataIn128}
{
assign VAddr = TIEadd(base, offset[31:1], 1'b0);
wire [15:0] o1 = MemDataIn128[15:0];
wire [15:0] o2 = MemDataIn128[31:16];
wire [15:0] o3 = MemDataIn128[47:32];
wire [15:0] o4 = MemDataIn128[63:48];
wire [15:0] o5 = MemDataIn128[79:64];
wire [15:0] o6 = MemDataIn128[95:80];
wire [15:0] o7 = MemDataIn128[111:96];
wire [15:0] o8 = MemDataIn128[127:112];
wire s1 = (!o1[15] && o1[14]) || (o1[15] && (!o1[14] || o1[13:0] == 14'b0));
wire s2 = (!o2[15] && o2[14]) || (o2[15] && (!o2[14] || o2[13:0] == 14'b0));
wire s3 = (!o3[15] && o3[14]) || (o3[15] && (!o3[14] || o3[13:0] == 14'b0));
wire s4 = (!o4[15] && o4[14]) || (o4[15] && (!o4[14] || o4[13:0] == 14'b0));
wire s5 = (!o5[15] && o5[14]) || (o5[15] && (!o5[14] || o5[13:0] == 14'b0));
wire s6 = (!o6[15] && o6[14]) || (o6[15] && (!o6[14] || o6[13:0] == 14'b0));
wire s7 = (!o7[15] && o7[14]) || (o7[15] && (!o7[14] || o7[13:0] == 14'b0));
wire s8 = (!o8[15] && o8[14]) || (o8[15] && (!o8[14] || o8[13:0] == 14'b0));
assign needs_shift = {31'b0, s1 || s2 || s3 || s4 || s5 || s6 || s7 || s8 };
}
operation FFT_BIT_REVERSE {inout AR m, out AR mr, in AR mm} {}
{
wire [15:0] x = TIEadd(m, 1'b0, 1'b1);
assign mr = {
TIEmux(mm[3:0], 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, x[0]),
TIEmux(mm[3:0], 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, x[0], x[1]),
TIEmux(mm[3:0], 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, x[0], x[1], x[2]),
TIEmux(mm[3:0], 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, x[0], x[1], x[2], x[3]),
TIEmux(mm[3:0], 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, x[0], x[1], x[2], x[3], x[4]),
TIEmux(mm[3:0], 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, x[0], x[1], x[2], x[3], x[4], x[5]),
TIEmux(mm[3:0], 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, x[0], x[1], x[2], x[3], x[4], x[5], x[6]),
TIEmux(mm[3:0], 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7]),
TIEmux(mm[3:0], 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], x[8]),
TIEmux(mm[3:0], 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], x[8], x[9]),
TIEmux(mm[3:0], 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], x[8], x[9], x[10]),
TIEmux(mm[3:0], 1'b0, 1'b0, 1'b0, 1'b0, x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], x[8], x[9], x[10],x[11]),
TIEmux(mm[3:0], 1'b0, 1'b0, 1'b0, x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], x[8], x[9], x[10],x[11],x[12]),
TIEmux(mm[3:0], 1'b0, 1'b0, x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], x[8], x[9], x[10],x[11],x[12],x[13]),
TIEmux(mm[3:0], 1'b0, x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], x[8], x[9], x[10],x[11],x[12],x[13],x[14])
};
assign m = x;
}
function [31:0] FFT_TWIDDLE ([31:0] j, [0:0] shift, [0:0] inverse)
{
// 256 = N_WAVE / 4
wire [9:0] idx = TIEadd(j, 256, 1'b0);
wire [15:0] sin = SIN_WAVE[j];
wire [15:0] wr1 = SIN_WAVE[idx];
wire [15:0] wi1 = TIEadd(~sin, 16'b0, 1'b1);
wire [15:0] wi2 = TIEmux(inverse, wi1, sin);
assign FFT_TWIDDLE = {
TIEmux(shift, wr1, {wr1[15], wr1[15:1]}),
TIEmux(shift, wi2, {wi2[15], wi2[15:1]})
};
}
function [63:0] FFT_BUTTERFLY ([63:0] data, [15:0] wr, [15:0] wi, [0:0] shift) {
// operands real parts
wire [15:0] r1 = data[63:48];
wire [15:0] r2 = data[47:32];
// operands imaginary parts
wire [15:0] i1 = data[31:16];
wire [15:0] i2 = data[15:0];
// odd real part
wire [31:0] oddr1 = TIEmul(wr, r2, 1'b1);
wire [15:0] oddr1s = oddr1[30:15];
wire [31:0] oddr2 = TIEmul(wi, i2, 1'b1);
wire [15:0] oddr2s = oddr2[30:15];
wire [15:0] oddr = TIEadd(oddr1s, ~oddr2s, 1'b1);
// odd imaginary part
wire [31:0] oddi1 = TIEmul(wr, i2, 1'b1);
wire [15:0] oddi1s = oddi1[30:15];
wire [31:0] oddi2 = TIEmul(wi, r2, 1'b1);
wire [15:0] oddi2s = oddi2[30:15];
wire [15:0] oddi = TIEadd(oddi1s, oddi2s, 1'b0);
// even parts
wire [15:0] evenr = TIEmux(shift[0], r1, {r1[15], r1[15:1]});
wire [15:0] eveni = TIEmux(shift[0], i1, {i1[15], i1[15:1]});
// final result
wire [15:0] resr1 = TIEadd(evenr, oddr, 1'b0);
wire [15:0] resr2 = TIEadd(evenr, ~oddr, 1'b1);
wire [15:0] resi1 = TIEadd(eveni, oddi, 1'b0);
wire [15:0] resi2 = TIEadd(eveni, ~oddi, 1'b1);
assign FFT_BUTTERFLY = { resr1, resr2, resi1, resi2 };
}
operation FFT_CALC {inout FFT_REG data, in AR i, in BR shift, in BR inverse} {}
{
wire [31:0] twiddle = FFT_TWIDDLE(i, shift, inverse);
wire [15:0] wr = twiddle[31:16];
wire [15:0] wi = twiddle[15:0];
assign data = FFT_BUTTERFLY(data, wr, wi, shift);
}
// 4 butterflies at once
operation FFT_SIMD_FIRST {inout FFT_REG_SIMD fr, inout FFT_REG_SIMD fi, in BR shift} {}
{
wire [15:0] wr = TIEmux(shift, 16'h7fff, 16'h3fff);
wire [15:0] wi = 16'b0;
wire [63:0] res1 = FFT_butterfly({fr[127:96], fi[127:96]}, wr, wi, shift);
wire [63:0] res2 = FFT_butterfly({fr[95:64], fi[95:64]}, wr, wi, shift);
wire [63:0] res3 = FFT_butterfly({fr[63:32], fi[63:32]}, wr, wi, shift);
wire [63:0] res4 = FFT_butterfly({fr[31:0], fi[31:0]}, wr, wi, shift);
assign fr = { res1[63:32], res2[63:32], res3[63:32], res4[63:32] };
assign fi = { res1[31:0], res2[31:0], res3[31:0], res4[31:0] };
}
//--------------------------------------------------------------------------
//
// Immediate Ranges
//
//--------------------------------------------------------------------------
immediate_range ST.FFT_REG_immed2 -32 24 8
immediate_range LD.FFT_REG_immed2 -32 24 8
//--------------------------------------------------------------------------
//
// FLIX Formats and Slots
//
// flix64_0, format width 64 bits, 2 slots
format flix64_0 64 { flix64_0_slot0, flix64_0_slot1, flix64_0_slot2 }
slot_opcodes flix64_0_slot0 { MOVI, J, ADDX2, L16SI, S16I, FFT_BIT_REVERSE, S32I, L32I, FFT_SHIFT_CHECK, OR, NOP, ADD, FFT_CALC, FFT_SIMD_LOAD, FFT_SIMD_STORE }
slot_opcodes flix64_0_slot1 { SSL, SLL, MOVI, ADDX2, NOP, ADDI.N, ANDBC, ADD, MOV.N, J }
slot_opcodes flix64_0_slot2 { S32I, ADDI.N, L32I, L16SI, ADDX2, NOP, FFT_SHIFT_CHECK, J, MOVI, SSL, MOV.N, S16I, FFT_SIMD_LOAD, FFT_SIMD_STORE }
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
//
// Ctypes
//
//--------------------------------------------------------------------------
ctype FFT_REG 64 64 FFT_REG default
ctype FFT_REG_SIMD 128 128 FFT_REG_SIMD default