├── LICENSE ├── README.md ├── RTL └── GACT │ ├── Ascii2Nt.v │ ├── Ascii2Param.v │ ├── BRAM.v │ ├── BTLogic.v │ ├── DP_BRAM.v │ ├── FIFOWithCount.v │ ├── GACTTop.v │ ├── Nt2Param.v │ ├── README.md │ ├── SmithWatermanArray.v │ ├── SmithWatermanPE.v │ ├── get_alignments.py │ ├── mux_1OfN.v │ ├── run_test.sh │ ├── tb_GACTTop.v │ └── test_data │ ├── query.1.hex │ ├── query.10.hex │ ├── query.2.hex │ ├── query.3.hex │ ├── query.4.hex │ ├── query.5.hex │ ├── query.6.hex │ ├── query.7.hex │ ├── query.8.hex │ ├── query.9.hex │ ├── query.hex │ ├── query_320.txt │ ├── ref.1.hex │ ├── ref.10.hex │ ├── ref.2.hex │ ├── ref.3.hex │ ├── ref.4.hex │ ├── ref.5.hex │ ├── ref.6.hex │ ├── ref.7.hex │ ├── ref.8.hex │ ├── ref.9.hex │ ├── ref.hex │ ├── ref_320.txt │ └── test_align.txt └── software ├── .gitignore ├── CMakeLists.txt ├── Chameleon.cpp ├── Chameleon.h ├── ConfigFile.cpp ├── ConfigFile.h ├── DRAM.cpp ├── DRAM.h ├── Darwin.bond ├── Darwin.sln ├── Darwin.vcxproj ├── Darwin.vcxproj.filters ├── Index.cpp ├── Index.h ├── Processor.cpp ├── Processor.h ├── README.md ├── ReadMe.txt ├── data ├── sample_reads.fa └── sample_ref.fa ├── extender.cpp ├── filter.cpp ├── graph.h ├── main.cpp ├── ntcoding.cpp ├── ntcoding.h ├── params.cfg ├── printer.cpp ├── seed_pos_table.cpp ├── seed_pos_table.h ├── seeder.cpp └── sender.cpp /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Yatish Turakhia, Gill Bejerano and William Dally 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # darwin 2 | Darwin: A co-processor for long read alignment 3 | 4 | ## Introduction 5 | 6 | This repository provides the software for performing reference-guided or de novo assembly of long reads using algorithms as described in the Darwin manuscript (see reference below). It also provides the RTL code for accelerating the GACT algorithm in hardware (FPGA/ASIC). Refer to the README.md files in software/ and RTL/GACT/ folders to get started. 7 | 8 | ## Citing Darwin 9 | * Assembly algorithms and GACT hardware described in: 10 | 11 | * Yatish Turakhia, Gill Bejerano, and William J. Dally. "Darwin: A Genomics Co-processor Provides up to 15,000 X Acceleration on Long Read Assembly." Proceedings of the Twenty-Third International Conference on Architectural Support for Programming Languages and Operating Systems (ASPLOS). ACM, 2018. [DOI: 10.1145/3173162.3173193] 12 | 13 | * Faster seed table construction using AVX instructions in software: 14 | 15 | * Roman Snytsar and Yatish Turakhia. "Parallel approach to sliding window sums." arXiv preprint, [arXiv:1811.10074], 2018. 16 | 17 | 18 | ## Acknowledgment 19 | 20 | * Roman Snytsar ([@mirounga]) for his help restructing the software code to work with the Intel TBB library and for implementing faster seed table construction using AVX instructions. 21 | * George Horrell ([@georgehorrell]) for implementing faster GACT algorithm in software using AVX instructions. 22 | * Sneha D. Goenka ([@gsneha26]) for fixing bugs in GACT RTL. 23 | 24 | [arXiv:1811.10074]: https://arxiv.org/abs/1811.10074 25 | [@mirounga]: https://github.com/mirounga 26 | [@georgehorrell]: https://github.com/georgehorrell 27 | [@gsneha26]: https://github.com/gsneha26 28 | -------------------------------------------------------------------------------- /RTL/GACT/Ascii2Nt.v: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2018 Yatish Turakhia, Sneha D. Goenka, Gill Bejerano and William Dally 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | // Converting ASCII characters to Nucleotide bases 26 | module Ascii2Nt ( 27 | input [7:0] ascii, 28 | input complement, 29 | output reg [3:0] nt); 30 | 31 | localparam A=1, C=2, G=3, T=4, N=0; 32 | 33 | always @(*) begin 34 | case ({ascii}) 35 | 8'h61 : nt = (complement) ? T : A; //8h'61 - ASCII for a 36 | 8'h41 : nt = (complement) ? T : A; //8h'41 - ASCII for A 37 | 8'h63 : nt = (complement) ? G : C; //8h'63 - ASCII for c 38 | 8'h43 : nt = (complement) ? G : C; //8h'43 - ASCII for C 39 | 8'h67 : nt = (complement) ? C : G; //8h'67 - ASCII for g 40 | 8'h47 : nt = (complement) ? C : G; //8h'47 - ASCII for G 41 | 8'h74 : nt = (complement) ? A : T; //8h'74 - ASCII for t 42 | 8'h54 : nt = (complement) ? A : T; //8h'54 - ASCII for T 43 | 8'h6e : nt = N; 44 | 8'h4e : nt = N; 45 | default : nt = N; 46 | endcase 47 | end 48 | endmodule 49 | -------------------------------------------------------------------------------- /RTL/GACT/Ascii2Param.v: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2018 Yatish Turakhia, Sneha D. Goenka, Gill Bejerano and William Dally 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | module Ascii2Param #( 26 | parameter PE_WIDTH = 10 27 | ) 28 | ( 29 | input [7:0] ascii, 30 | input [12*PE_WIDTH-1:0] in_param, 31 | output reg [7*PE_WIDTH-1:0] out_param); 32 | 33 | always @(*) begin 34 | case ({ascii}) 35 | 8'h61 : out_param = {in_param[12*PE_WIDTH-1:8*PE_WIDTH], {(PE_WIDTH){1'b0}}, in_param[2*PE_WIDTH-1:0]}; 36 | 8'h41 : out_param = {in_param[12*PE_WIDTH-1:8*PE_WIDTH], {(PE_WIDTH){1'b0}}, in_param[2*PE_WIDTH-1:0]}; 37 | 8'h63 : out_param = {in_param[11*PE_WIDTH-1:10*PE_WIDTH], in_param[8*PE_WIDTH-1:5*PE_WIDTH], {(PE_WIDTH){1'b0}}, in_param[2*PE_WIDTH-1:0]}; 38 | 8'h43 : out_param = {in_param[11*PE_WIDTH-1:10*PE_WIDTH], in_param[8*PE_WIDTH-1:5*PE_WIDTH], {(PE_WIDTH){1'b0}}, in_param[2*PE_WIDTH-1:0]}; 39 | 8'h67 : out_param = {in_param[10*PE_WIDTH-1:9*PE_WIDTH], in_param[7*PE_WIDTH-1:6*PE_WIDTH], in_param[5*PE_WIDTH-1:3*PE_WIDTH], {(PE_WIDTH){1'b0}}, in_param[2*PE_WIDTH-1:0]}; 40 | 8'h47 : out_param = {in_param[10*PE_WIDTH-1:9*PE_WIDTH], in_param[7*PE_WIDTH-1:6*PE_WIDTH], in_param[5*PE_WIDTH-1:3*PE_WIDTH], {(PE_WIDTH){1'b0}}, in_param[2*PE_WIDTH-1:0]}; 41 | 8'h74 : out_param = {in_param[9*PE_WIDTH-1:8*PE_WIDTH], in_param[6*PE_WIDTH-1:5*PE_WIDTH], in_param[4*PE_WIDTH-1:2*PE_WIDTH], {(PE_WIDTH){1'b0}}, in_param[2*PE_WIDTH-1:0]}; 42 | 8'h54 : out_param = {in_param[9*PE_WIDTH-1:8*PE_WIDTH], in_param[6*PE_WIDTH-1:5*PE_WIDTH], in_param[4*PE_WIDTH-1:2*PE_WIDTH], {(PE_WIDTH){1'b0}}, in_param[2*PE_WIDTH-1:0]}; 43 | default : out_param = {{(5*PE_WIDTH){1'b0}}, in_param[2*PE_WIDTH-1:0]}; 44 | endcase 45 | end 46 | 47 | endmodule 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /RTL/GACT/BRAM.v: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2018 Yatish Turakhia, Sneha D. Goenka, Gill Bejerano and William Dally 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | module BRAM #( 26 | parameter ADDR_WIDTH = 4, 27 | parameter DATA_WIDTH = 8, 28 | parameter MEM_INIT_FILE = "" 29 | ) 30 | ( 31 | input clk, 32 | input [ADDR_WIDTH-1:0] addr, 33 | input write_en, 34 | input [DATA_WIDTH-1:0] data_in, 35 | output reg [DATA_WIDTH-1:0] data_out); 36 | 37 | reg [DATA_WIDTH-1:0] mem [0:2**ADDR_WIDTH-1]; 38 | 39 | integer i; 40 | 41 | initial begin 42 | // for ( i = 0; i < 2**ADDR_WIDTH; i = i + 1) begin 43 | // mem[i] <= 0; 44 | // end 45 | if (MEM_INIT_FILE != "") begin 46 | $readmemh(MEM_INIT_FILE, mem); 47 | end 48 | end 49 | 50 | 51 | always @(posedge clk) begin 52 | if (write_en == 1) 53 | mem[addr] <= data_in; 54 | data_out <= mem[addr]; 55 | end 56 | 57 | endmodule 58 | 59 | 60 | -------------------------------------------------------------------------------- /RTL/GACT/BTLogic.v: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2018 Yatish Turakhia, Sneha D. Goenka, Gill Bejerano and William Dally 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | module BTLogic #( 26 | parameter ADDR_WIDTH = 20, 27 | parameter REF_LEN_WIDTH = 12, 28 | parameter LOG_NUM_PE = 6 29 | ) 30 | ( 31 | input clk, 32 | input rst, 33 | input start, 34 | 35 | input [REF_LEN_WIDTH-1:0] ref_length, 36 | input [ADDR_WIDTH-1:0] max_score_mod_addr, 37 | input [ADDR_WIDTH-1:0] max_score_addr, 38 | input [LOG_NUM_PE-1:0] max_score_pe, 39 | input [1:0] max_score_pe_state, 40 | input [3:0] input_dir, 41 | input [3:0] input_dir_diag, 42 | 43 | output reg [ADDR_WIDTH-1:0] next_addr, 44 | output reg [LOG_NUM_PE-1:0] next_pe, 45 | output wire [ADDR_WIDTH-1:0] next_addr_diag, 46 | output wire [LOG_NUM_PE-1:0] next_pe_diag, 47 | output wire addr_valid, 48 | output wire [1:0] dir, 49 | output wire dir_valid, 50 | output reg [REF_LEN_WIDTH-1:0] H_offset, 51 | input [REF_LEN_WIDTH-1:0] max_H_offset, 52 | output reg [REF_LEN_WIDTH-1:0] V_offset, 53 | input [REF_LEN_WIDTH-1:0] max_V_offset, 54 | output reg [ADDR_WIDTH+LOG_NUM_PE-1:0] num_tb_steps, 55 | output done 56 | ); 57 | 58 | localparam MAX_PE = (2**LOG_NUM_PE) - 1; 59 | 60 | reg [ADDR_WIDTH-1:0] mod_count; 61 | reg [1:0] next_pe_state; 62 | 63 | reg [ADDR_WIDTH-1:0] mod_next_addr; 64 | 65 | reg [REF_LEN_WIDTH-1:0] reg_ref_length; 66 | 67 | reg [2:0] state; 68 | reg [2:0] next_state; 69 | 70 | localparam WAIT=0, BLOCK1=1, BLOCK2=2, CALC=3, DONE=4; 71 | localparam ZERO=0, M=3, V=1, H=2; 72 | 73 | wire [LOG_NUM_PE-1:0] next_pe_decr_mod; 74 | wire [ADDR_WIDTH-1:0] next_addr_mod; 75 | 76 | wire [REF_LEN_WIDTH-1:0] next_V_offset; 77 | wire [REF_LEN_WIDTH-1:0] next_H_offset; 78 | 79 | assign done = (state == DONE); 80 | assign dir_valid = (state == CALC) && (dir != 0); 81 | assign addr_valid = (next_state == CALC); 82 | assign dir = next_pe_state; 83 | 84 | assign next_pe_decr_mod = (next_pe == 0) ? MAX_PE : (next_pe - 1); 85 | assign next_addr_mod = (next_pe == 0) ? (next_addr - reg_ref_length - 1) : (next_addr - 1); 86 | 87 | assign next_addr_diag = next_addr_mod; 88 | assign next_pe_diag = next_pe_decr_mod; 89 | 90 | assign next_V_offset = ((next_pe_state == M) || (next_pe_state == V)) ? (V_offset + 1) : V_offset; 91 | assign next_H_offset = ((next_pe_state == M) || (next_pe_state == H)) ? (H_offset + 1) : H_offset; 92 | 93 | always @(posedge clk) begin 94 | mod_next_addr <= mod_count; //?? 95 | end 96 | 97 | always @(posedge clk) begin 98 | if (rst) begin 99 | state <= WAIT; 100 | end 101 | else begin 102 | state <= next_state; 103 | case (state) 104 | WAIT: begin 105 | mod_count <= max_score_mod_addr; 106 | next_addr <= max_score_addr; 107 | next_pe <= max_score_pe; 108 | next_pe_state <= max_score_pe_state; 109 | reg_ref_length <= ref_length; 110 | H_offset <= 0; 111 | V_offset <= 0; 112 | num_tb_steps <= 0; 113 | end 114 | BLOCK1: begin 115 | end 116 | BLOCK2: begin 117 | end 118 | CALC: begin 119 | H_offset <= next_H_offset; 120 | V_offset <= next_V_offset; 121 | num_tb_steps <= num_tb_steps + (dir != 0); 122 | if (next_pe_state == M) begin 123 | //terminating condition 124 | if (((next_pe == 0) && (next_addr <= reg_ref_length)) || (mod_next_addr == 0)) begin 125 | next_pe_state <= ZERO; 126 | end 127 | //otherwise 128 | else begin 129 | mod_count <= mod_count - 1; 130 | if (next_pe == 0) begin 131 | next_addr <= next_addr - reg_ref_length - 1; 132 | next_pe <= MAX_PE; 133 | end 134 | else begin 135 | next_addr <= next_addr - 1; 136 | next_pe <= next_pe - 1; 137 | end 138 | next_pe_state <= input_dir_diag[1:0]; 139 | end 140 | end 141 | else if (next_pe_state == V) begin 142 | if (next_pe == 0) begin 143 | next_pe <= MAX_PE; 144 | end 145 | else begin 146 | next_pe <= next_pe - 1; 147 | end 148 | if ((next_pe == 0) && (next_addr <= reg_ref_length)) begin 149 | next_pe_state <= ZERO; 150 | end 151 | else begin 152 | if (next_pe == 0) begin 153 | next_addr <= next_addr - reg_ref_length; 154 | end 155 | if (input_dir[2] == 0) begin 156 | next_pe_state <= V; 157 | end 158 | else begin 159 | next_pe_state <= M; 160 | end 161 | end 162 | end 163 | else if (next_pe_state == H) begin 164 | next_addr <= next_addr - 1; 165 | mod_count <= mod_count - 1; 166 | if (mod_count == 0) begin 167 | next_pe_state <= ZERO; 168 | end 169 | else begin 170 | if (input_dir[3] == 0) begin 171 | next_pe_state <= H; 172 | end 173 | else begin 174 | next_pe_state <= M; 175 | end 176 | end 177 | end 178 | end 179 | DONE: begin 180 | end 181 | endcase 182 | end 183 | end 184 | 185 | always @(*) 186 | begin 187 | next_state = state; 188 | case (state) 189 | WAIT: 190 | if (start) 191 | next_state = BLOCK1; 192 | BLOCK1: 193 | next_state = BLOCK2; 194 | BLOCK2: 195 | next_state = CALC; 196 | CALC: 197 | if ((next_pe_state == ZERO) || (next_H_offset == max_H_offset) || (next_V_offset == max_V_offset)) 198 | next_state = DONE; 199 | else 200 | next_state = BLOCK1; 201 | DONE: 202 | next_state = WAIT; 203 | endcase 204 | end 205 | 206 | endmodule 207 | 208 | -------------------------------------------------------------------------------- /RTL/GACT/DP_BRAM.v: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2018 Yatish Turakhia, Sneha D. Goenka, Gill Bejerano and William Dally 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | module DP_BRAM #( 26 | parameter ADDR_WIDTH = 4, 27 | parameter DATA_WIDTH = 8 28 | )( 29 | input clk, 30 | input [ADDR_WIDTH-1:0] raddr, 31 | input [ADDR_WIDTH-1:0] waddr, 32 | input wr_en, 33 | input [DATA_WIDTH-1:0] data_in, 34 | output reg [DATA_WIDTH-1:0] data_out); 35 | 36 | 37 | reg [DATA_WIDTH-1:0] mem [2**ADDR_WIDTH-1:0]; 38 | 39 | integer i; 40 | 41 | // initial begin 42 | // for ( i = 0; i < 2**ADDR_WIDTH; i = i + 1) begin 43 | // mem[i] <= 0; 44 | // end 45 | // end 46 | 47 | always @(posedge clk) begin 48 | if (wr_en == 1) 49 | mem[waddr] <= data_in; 50 | data_out <= mem[raddr]; 51 | end 52 | 53 | endmodule 54 | 55 | 56 | -------------------------------------------------------------------------------- /RTL/GACT/FIFOWithCount.v: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2018 Yatish Turakhia, Sneha D. Goenka, Gill Bejerano and William Dally 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | module FIFOWithCount #( 26 | parameter DATA_WIDTH = 8, 27 | parameter DEPTH_WIDTH = 3 28 | ) 29 | ( 30 | input clk, 31 | input rst, 32 | 33 | input wr_en, 34 | input rd_en, 35 | input [DATA_WIDTH-1:0] wr_data_in, 36 | 37 | output reg [DEPTH_WIDTH:0] count, 38 | output wire [DATA_WIDTH-1:0] rd_data_out, 39 | output wire full, 40 | output reg empty); 41 | 42 | reg [DEPTH_WIDTH:0] write_pointer; 43 | reg [DEPTH_WIDTH:0] read_pointer; 44 | 45 | assign empty_int = (write_pointer[DEPTH_WIDTH] == read_pointer[DEPTH_WIDTH]); 46 | assign full_or_empty = (write_pointer[DEPTH_WIDTH-1:0] == read_pointer[DEPTH_WIDTH-1:0]); 47 | 48 | assign full_wire = full_or_empty & !(empty_int); 49 | assign empty_wire = full_or_empty & (empty_int); 50 | 51 | assign full = full_wire; 52 | 53 | always @(posedge clk) begin 54 | if (rst) begin 55 | read_pointer <= 0; 56 | write_pointer <= 0; 57 | count <= 0; 58 | end 59 | 60 | else begin 61 | if (wr_en && (full_wire == 1'b0)) begin 62 | write_pointer <= write_pointer + 1; 63 | count <= count + 1; 64 | end 65 | 66 | if (rd_en && (empty_wire == 1'b0)) begin 67 | read_pointer <= read_pointer + 1; 68 | count <= count - 1; 69 | end 70 | empty <= empty_wire; 71 | end 72 | end 73 | 74 | DP_BRAM 75 | #( 76 | .ADDR_WIDTH(DEPTH_WIDTH), 77 | .DATA_WIDTH(DATA_WIDTH) 78 | ) 79 | fifo_dp_bram 80 | ( 81 | .clk(clk), 82 | .raddr(read_pointer[DEPTH_WIDTH-1:0]), 83 | .waddr(write_pointer[DEPTH_WIDTH-1:0]), 84 | .wr_en(wr_en), 85 | .data_out(rd_data_out), 86 | .data_in(wr_data_in) 87 | ); 88 | 89 | endmodule 90 | -------------------------------------------------------------------------------- /RTL/GACT/GACTTop.v: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2018 Yatish Turakhia, Sneha D. Goenka, Gill Bejerano and William Dally 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | module GACTTop #( 26 | parameter PE_WIDTH = 16, 27 | parameter BLOCK_WIDTH = 3, 28 | parameter MAX_TILE_SIZE = 512, 29 | parameter NUM_PE = 64, 30 | parameter REF_FILENAME = "", 31 | parameter QUERY_FILENAME = "", 32 | parameter NUM_DIR_BLOCK = 32, 33 | parameter DIR_BRAM_ADDR_WIDTH = 5, 34 | parameter REQUEST_ID_WIDTH = 16 35 | ) ( 36 | input wire clk, 37 | input wire rst, 38 | 39 | input wire [12*PE_WIDTH-1:0] in_params, 40 | input wire set_params, 41 | input wire [8*(2 ** BLOCK_WIDTH)-1:0] query_in, 42 | input wire [8*(2 ** BLOCK_WIDTH)-1:0] ref_in, 43 | 44 | input wire [$clog2(MAX_TILE_SIZE)-BLOCK_WIDTH-1:0] ref_addr_in, 45 | input wire [$clog2(MAX_TILE_SIZE)-BLOCK_WIDTH-1:0] query_addr_in, 46 | input wire ref_wr_en, 47 | input wire query_wr_en, 48 | 49 | input wire [$clog2(MAX_TILE_SIZE):0] max_tb_steps, 50 | input wire [$clog2(MAX_TILE_SIZE)-1:0] ref_len, 51 | input wire [$clog2(MAX_TILE_SIZE)-1:0] query_len, 52 | 53 | input wire [PE_WIDTH-1:0] score_threshold, 54 | input wire [7:0] align_fields, 55 | 56 | output wire ready, 57 | input wire start, 58 | output wire done, 59 | input wire clear_done, 60 | 61 | output reg [PE_WIDTH-1:0] tile_score, 62 | output reg [$clog2(MAX_TILE_SIZE)-1:0] ref_max_pos, 63 | output reg [$clog2(MAX_TILE_SIZE)-1:0] query_max_pos, 64 | output reg [2*$clog2(MAX_TILE_SIZE)-1:0] num_tb_steps, 65 | output reg [$clog2(MAX_TILE_SIZE)-1:0] num_ref_bases, 66 | output reg [$clog2(MAX_TILE_SIZE)-1:0] num_query_bases, 67 | 68 | input wire [DIR_BRAM_ADDR_WIDTH-1:0] dir_rd_addr, 69 | output reg [DIR_BRAM_ADDR_WIDTH-1:0] dir_total_count, 70 | output wire [2*NUM_DIR_BLOCK-1:0] dir_data_out, 71 | output wire dir_valid, 72 | output wire [1:0] dir, 73 | 74 | input wire [REQUEST_ID_WIDTH-1:0] req_id_in, 75 | output reg [REQUEST_ID_WIDTH-1:0] req_id_out 76 | ); 77 | 78 | parameter LOG_NUM_PE = $clog2(NUM_PE); 79 | parameter NUM_BLOCK = (2 ** BLOCK_WIDTH); 80 | 81 | wire [$clog2(MAX_TILE_SIZE)-BLOCK_WIDTH-1:0] ref_bram_addr; 82 | wire [$clog2(MAX_TILE_SIZE)-BLOCK_WIDTH-1:0] query_bram_addr; 83 | 84 | wire [$clog2(MAX_TILE_SIZE)-1:0] ref_bram_rd_addr; 85 | wire [$clog2(MAX_TILE_SIZE)-1:0] query_bram_rd_addr; 86 | 87 | reg [$clog2(MAX_TILE_SIZE)-1:0] reg_ref_bram_rd_addr; 88 | reg [$clog2(MAX_TILE_SIZE)-1:0] reg_query_bram_rd_addr; 89 | 90 | reg [$clog2(MAX_TILE_SIZE)-1:0] ref_length; 91 | reg [$clog2(MAX_TILE_SIZE)-1:0] query_length; 92 | 93 | wire [8*NUM_BLOCK-1:0] ref_bram_data_out; 94 | wire [8*NUM_BLOCK-1:0] query_bram_data_out; 95 | 96 | reg [PE_WIDTH-1:0] max_score_threshold; 97 | reg [$clog2(MAX_TILE_SIZE)-1:0] max_H_offset; 98 | reg [$clog2(MAX_TILE_SIZE)-1:0] max_V_offset; 99 | 100 | wire [$clog2(MAX_TILE_SIZE)-1:0] ref_max_score_pos; 101 | wire [$clog2(MAX_TILE_SIZE)-1:0] query_max_score_pos; 102 | 103 | wire [PE_WIDTH-1:0] max_score; 104 | wire [$clog2(MAX_TILE_SIZE)-1:0] H_offset; 105 | wire [$clog2(MAX_TILE_SIZE)-1:0] V_offset; 106 | 107 | wire [2*$clog2(MAX_TILE_SIZE)-1:0] array_num_tb_steps; 108 | 109 | reg [12*PE_WIDTH-1:0] reg_in_params; 110 | 111 | reg [DIR_BRAM_ADDR_WIDTH-1:0] dir_count; 112 | reg dir_wr_en; 113 | reg [2*NUM_DIR_BLOCK-1:0] dir_data_in; 114 | wire [DIR_BRAM_ADDR_WIDTH-1:0] dir_wr_addr; 115 | 116 | wire array_done; 117 | reg rst_array; 118 | 119 | reg [2:0] state; 120 | reg [2:0] next_state; 121 | 122 | localparam READY=1, ARRAY_START=2, ARRAY_PROCESSING=3, BLOCK=4, DONE=5; 123 | 124 | assign ref_bram_addr = (ref_wr_en) ? ref_addr_in - 1 : ref_bram_rd_addr[$clog2(MAX_TILE_SIZE)-1:BLOCK_WIDTH]; 125 | assign query_bram_addr = (query_wr_en) ? query_addr_in - 1 : query_bram_rd_addr[$clog2(MAX_TILE_SIZE)-1:BLOCK_WIDTH]; 126 | 127 | BRAM #( 128 | .ADDR_WIDTH($clog2(MAX_TILE_SIZE)-BLOCK_WIDTH), 129 | .DATA_WIDTH(8*NUM_BLOCK), 130 | .MEM_INIT_FILE(REF_FILENAME) 131 | ) ref_bram ( 132 | .clk(clk), 133 | .addr(ref_bram_addr), 134 | .write_en(ref_wr_en), 135 | .data_in(ref_in), 136 | .data_out(ref_bram_data_out) 137 | ); 138 | 139 | BRAM #( 140 | .ADDR_WIDTH($clog2(MAX_TILE_SIZE)-BLOCK_WIDTH), 141 | .DATA_WIDTH(8*NUM_BLOCK), 142 | .MEM_INIT_FILE(QUERY_FILENAME) 143 | ) query_bram ( 144 | .clk(clk), 145 | .addr(query_bram_addr), 146 | .write_en(query_wr_en), 147 | .data_in(query_in), 148 | .data_out(query_bram_data_out) 149 | ); 150 | 151 | DP_BRAM #( 152 | .DATA_WIDTH(2*NUM_DIR_BLOCK), 153 | .ADDR_WIDTH(DIR_BRAM_ADDR_WIDTH) 154 | ) dir_bram ( 155 | .clk(clk), 156 | 157 | .raddr (dir_rd_addr), 158 | .wr_en (dir_wr_en), 159 | .waddr (dir_wr_addr), 160 | 161 | .data_in (dir_data_in), 162 | .data_out (dir_data_out) 163 | ); 164 | 165 | reg [7:0] ref_array_in; 166 | reg [7:0] query_array_in; 167 | 168 | reg do_traceback_in; 169 | reg ref_complement; 170 | reg query_complement; 171 | reg ref_reverse; 172 | reg query_reverse; 173 | reg start_last; 174 | 175 | integer i, j; 176 | always @(*) begin 177 | ref_array_in = 0; 178 | for (i = 0; i < NUM_BLOCK; i=i+1) 179 | begin:m 180 | if (reg_ref_bram_rd_addr[BLOCK_WIDTH-1:0] == i) begin 181 | ref_array_in = ref_bram_data_out[8*i+:8]; 182 | end 183 | end 184 | end 185 | 186 | always @(*) begin 187 | query_array_in = 0; 188 | for (j = 0; j < NUM_BLOCK; j=j+1) 189 | begin:n 190 | if (reg_query_bram_rd_addr[BLOCK_WIDTH-1:0] == j) begin 191 | query_array_in = (query_bram_rd_addr <= query_length) ? query_bram_data_out[8*j+:8] : 0; 192 | end 193 | end 194 | end 195 | 196 | always@(posedge clk) begin 197 | reg_ref_bram_rd_addr <= ref_bram_rd_addr; 198 | reg_query_bram_rd_addr <= query_bram_rd_addr; 199 | end 200 | 201 | SmithWatermanArray # ( 202 | .NUM_PE(NUM_PE), 203 | .LOG_NUM_PE(LOG_NUM_PE), 204 | .REF_LEN_WIDTH($clog2(MAX_TILE_SIZE)), 205 | .QUERY_LEN_WIDTH($clog2(MAX_TILE_SIZE)), 206 | .REF_BLOCK_SIZE_WIDTH($clog2(MAX_TILE_SIZE)), 207 | .QUERY_BLOCK_SIZE_WIDTH($clog2(MAX_TILE_SIZE)), 208 | .PE_WIDTH(PE_WIDTH), 209 | .PARAM_ADDR_WIDTH($clog2(MAX_TILE_SIZE)) 210 | ) array ( 211 | .clk (clk), 212 | .rst (rst_array), 213 | .start (array_start), 214 | 215 | .reverse_ref_in(ref_reverse), 216 | .reverse_query_in(query_reverse), 217 | 218 | .complement_ref_in(ref_complement), 219 | .complement_query_in(query_complement), 220 | 221 | .in_param(reg_in_params), 222 | 223 | .do_traceback_in (do_traceback_in), 224 | .ref_length (ref_length), 225 | .query_length (query_length), 226 | 227 | .ref_bram_rd_start_addr(0), 228 | .ref_bram_rd_addr(ref_bram_rd_addr), 229 | .ref_bram_data_in (ref_array_in), 230 | 231 | .query_bram_rd_start_addr(0), 232 | .query_bram_rd_addr(query_bram_rd_addr), 233 | .query_bram_data_in (query_array_in), 234 | 235 | .max_score_threshold(max_score_threshold), 236 | .start_last(start_last), 237 | 238 | .max_score(max_score), 239 | .H_offset(H_offset), 240 | .max_H_offset(max_H_offset), 241 | .V_offset(V_offset), 242 | .max_V_offset(max_V_offset), 243 | 244 | .num_tb_steps(array_num_tb_steps), 245 | 246 | .ref_max_score_pos(ref_max_score_pos), 247 | .query_max_score_pos(query_max_score_pos), 248 | 249 | .dir(dir), 250 | .dir_valid(dir_valid), 251 | 252 | .done(array_done) 253 | ); 254 | 255 | 256 | assign done = (state == DONE); 257 | assign ready = (state == READY) && (~start); 258 | assign array_start = (state == ARRAY_START); 259 | assign dir_wr_addr = (dir_total_count - 1); 260 | 261 | always @(posedge clk) begin 262 | if (rst) begin 263 | dir_wr_en <= 0; 264 | rst_array <= 1; 265 | state <= READY; 266 | end 267 | else begin 268 | state <= next_state; 269 | if (state == READY) begin 270 | if (set_params) begin 271 | rst_array <= 0; 272 | reg_in_params <= in_params; 273 | end 274 | if (start) begin 275 | do_traceback_in <= align_fields[5]; 276 | ref_reverse <= align_fields[4]; 277 | ref_complement <= align_fields[3]; 278 | query_reverse <= align_fields[2]; 279 | query_complement <= align_fields[1]; 280 | start_last <= align_fields[0]; 281 | max_H_offset <= max_tb_steps; 282 | max_V_offset <= max_tb_steps; 283 | max_score_threshold <= score_threshold; 284 | ref_length <= ref_len; 285 | query_length <= query_len; 286 | req_id_out <= req_id_in; 287 | dir_total_count <= 0; 288 | dir_count <= 0; 289 | dir_wr_en <= 0; 290 | end 291 | end 292 | if (state == ARRAY_PROCESSING) begin 293 | if (dir_valid) begin 294 | // TODO 295 | if (dir_valid) begin 296 | if (dir_count == 0) begin 297 | dir_data_in <= dir; 298 | end 299 | else begin 300 | dir_data_in <= (dir_data_in << 2) + dir; 301 | end 302 | if (dir_count == NUM_DIR_BLOCK-1) begin 303 | dir_wr_en <= 1; 304 | dir_total_count <= dir_total_count + 1; 305 | dir_count <= dir_count + 1; 306 | dir_count <= 0; 307 | end 308 | else begin 309 | dir_wr_en <= 0; 310 | dir_count <= dir_count + 1; 311 | end 312 | end 313 | end 314 | else if (array_done) begin 315 | ref_max_pos <= ref_max_score_pos; 316 | query_max_pos <= query_max_score_pos; 317 | num_ref_bases <= H_offset; 318 | num_query_bases <= V_offset; 319 | num_tb_steps <= array_num_tb_steps; 320 | tile_score <= max_score; 321 | rst_array <= 1; 322 | if (dir_count > 0) begin 323 | dir_wr_en <= 1; 324 | dir_total_count <= dir_total_count + 1; 325 | dir_count <= dir_count + 1; 326 | end 327 | else begin 328 | dir_wr_en <= 0; 329 | end 330 | end 331 | else begin 332 | dir_wr_en <= 0; 333 | end 334 | end 335 | if (state == BLOCK) begin 336 | dir_wr_en <= 0; 337 | end 338 | if (state == DONE) begin 339 | rst_array <= 0; 340 | dir_wr_en <= 0; 341 | end 342 | end 343 | end 344 | 345 | always @(*) 346 | begin 347 | next_state = state; 348 | case (state) 349 | READY: begin 350 | if (start) begin 351 | next_state = ARRAY_START; 352 | end 353 | end 354 | ARRAY_START: begin 355 | next_state = ARRAY_PROCESSING; 356 | end 357 | ARRAY_PROCESSING: begin 358 | if (array_done) begin 359 | next_state = BLOCK; 360 | end 361 | end 362 | BLOCK: begin 363 | next_state = DONE; 364 | end 365 | DONE: begin 366 | if (clear_done) begin 367 | next_state = READY; 368 | end 369 | end 370 | endcase 371 | end 372 | 373 | endmodule 374 | 375 | -------------------------------------------------------------------------------- /RTL/GACT/Nt2Param.v: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2018 Yatish Turakhia, Sneha D. Goenka, Gill Bejerano and William Dally 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | //Converting nucleotide bases to the parameters from the W matrix, gap_open 26 | //penalty, gap_extend penalty 27 | // 28 | //W matrix is symmetric, hence we save the upper triangle 29 | //and, gap_open and the gap_extend penalties 30 | 31 | 32 | // | A | C | G | T 33 | // A | 12 | 11 | 10 | 9 34 | // C | 11 | 8 | 7 | 6 35 | // G | 10 | 7 | 5 | 4 36 | // T | 9 | 6 | 4 | 3 37 | // Gap_open - 2 38 | // Gap_extend - 1 39 | // numbers represent the element index of in-param 40 | module Nt2Param #( 41 | parameter PE_WIDTH=10 42 | ) 43 | ( 44 | input [3:0] nt, 45 | input [12*PE_WIDTH-1:0] in_param, 46 | output reg [7*PE_WIDTH-1:0] out_param); 47 | 48 | localparam A=1, C=2, G=3, T=4, N=0; 49 | 50 | always @(*) begin 51 | case ({nt}) 52 | A : out_param = {in_param[12*PE_WIDTH-1:8*PE_WIDTH], {(PE_WIDTH){1'b0}}, in_param[2*PE_WIDTH-1:0]}; 53 | C : out_param = {in_param[11*PE_WIDTH-1:10*PE_WIDTH], in_param[8*PE_WIDTH-1:5*PE_WIDTH], {(PE_WIDTH){1'b0}}, in_param[2*PE_WIDTH-1:0]}; 54 | G : out_param = {in_param[10*PE_WIDTH-1:9*PE_WIDTH], in_param[7*PE_WIDTH-1:6*PE_WIDTH], in_param[5*PE_WIDTH-1:3*PE_WIDTH], {(PE_WIDTH){1'b0}}, in_param[2*PE_WIDTH-1:0]}; 55 | T : out_param = {in_param[9*PE_WIDTH-1:8*PE_WIDTH], in_param[6*PE_WIDTH-1:5*PE_WIDTH], in_param[4*PE_WIDTH-1:2*PE_WIDTH], {(PE_WIDTH){1'b0}}, in_param[2*PE_WIDTH-1:0]}; 56 | default : out_param = {{(5*PE_WIDTH){1'b0}}, in_param[2*PE_WIDTH-1:0]}; 57 | endcase 58 | end 59 | 60 | endmodule 61 | -------------------------------------------------------------------------------- /RTL/GACT/README.md: -------------------------------------------------------------------------------- 1 | ## RTL Heirarchy 2 | GACTTop.v is the top module. tb_GACTTop.v is the testbench. 3 | 4 | ## Parameters in testbench 5 | * REF_FILENAME and QUERY_FILENAME consist of the sequences (A, T, C, G, N) in the hex format. 6 | * params consist of the score matrix, gap_open and gap_extend parameters. 7 | * ref_len and query_len are the lengths of the reference and the query sequences respectively. 8 | * score_threshold parameter can be set for filtering out tiles with scores below the threshold. 9 | * GACT can be run in various modes by using the 8 bit align_fields parameter. Its bits represent the following: 10 | * [7] - don't care 11 | * [6] - don't care 12 | * [5] - return direction pointers 13 | * [4] - reverse reference sequence 14 | * [3] - complement reference sequence 15 | * [2] - reverse query sequence 16 | * [1] - complement query sequence 17 | * [0] - start at the last cell instead of the maximum score position 18 | 19 | 20 | ## Running test simulation 21 | Running these tests requires the following 22 | * Python 23 | * Icarus Verilog 24 | * GTKWave 25 | 26 | 27 | This example runs GACT for 10 sets of test data in ./test_data/ . There are 10 reference and query sequences in ./test_data/ref_320.txt and ./test_data/query_320.txt. The 10 refernce and query sequences are sent as in input to GACT in the hex format (./test_data/ref.*.hex, ./test_data/query.*.hex). In order to run GACT simulation, run the following: 28 | ``` 29 | $ ./run_test.sh 30 | ``` 31 | 32 | Results are created in ./results/. 33 | The folder consists of VCD file which consists of the waveform dump. It can be viewed using gtkwave. 34 | 35 | ``` 36 | $ gtkwave *.vcd 37 | ``` 38 | 39 | The folder also consists of the *.out file which consists of the direction pointer output. It can be further processed to get the aligned sequences, maximum score and maximum score positions. Further processing can be done as follows: 40 | 41 | ``` 42 | $ python get_alignments.py ./test_data/ref_320.txt ./test_data/query_320.txt 10 43 | ``` 44 | -------------------------------------------------------------------------------- /RTL/GACT/SmithWatermanPE.v: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2018 Yatish Turakhia, Sneha D. Goenka, Albert Ng, Gill Bejerano and William Dally 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | // V <-> H 26 | // F <-> I 27 | // E <-> D 28 | // 29 | module SmithWatermanPE #( 30 | parameter WIDTH = 10, 31 | parameter REF_LEN_WIDTH = 10, 32 | parameter QUERY_LEN_WIDTH = 10, 33 | parameter LOG_NUM_PE = 2, 34 | parameter PE_ID = 0 35 | 36 | )( 37 | input clk, // System clock 38 | input rst, // System reset 39 | 40 | // Scoring parameters (from substitution matrix) (basically separate indices of the parameter 41 | // calculated in Nt2Param 42 | input [WIDTH-1:0] sub_A_in, 43 | input [WIDTH-1:0] sub_C_in, 44 | input [WIDTH-1:0] sub_G_in, 45 | input [WIDTH-1:0] sub_T_in, 46 | input [WIDTH-1:0] sub_N_in, 47 | input [WIDTH-1:0] gap_open_in, 48 | input [WIDTH-1:0] gap_extend_in, 49 | input set_param, 50 | 51 | input [WIDTH-1:0] V_in, // Score from previous PE 52 | input [WIDTH-1:0] M_in, // Match score from previous PE 53 | input [WIDTH-1:0] F_in, // Gap penalty of previous PE 54 | input [2:0] T_in, // Reference seq shift in 55 | input init_in, // Computation active shift in 56 | input [WIDTH-1:0] init_V, // V initialization value 57 | input [WIDTH-1:0] init_E, // E initialization value 58 | 59 | input [REF_LEN_WIDTH-1:0] max_ref_pos_in, 60 | input [REF_LEN_WIDTH-1:0] max_ref_mod_in, 61 | input [QUERY_LEN_WIDTH-1:0] max_query_mod_in, 62 | input [LOG_NUM_PE-1:0] max_query_pos_in, 63 | input [1:0] max_pe_state_in, 64 | input compute_max_in, 65 | input last, 66 | input last_in, 67 | 68 | output reg [REF_LEN_WIDTH-1:0] max_ref_pos_out, 69 | output reg [REF_LEN_WIDTH-1:0] max_ref_mod_out, 70 | output reg [LOG_NUM_PE-1:0] max_query_pos_out, 71 | output reg [QUERY_LEN_WIDTH-1:0] max_query_mod_out, 72 | output reg [1:0] max_pe_state_out, 73 | 74 | output reg compute_max_out, 75 | output reg last_out, 76 | output wire [WIDTH-1:0] V_out, // Score of this PE 77 | output wire [WIDTH-1:0] M_out, // Match score of this PE 78 | output wire [WIDTH-1:0] E_out, // Left gap penalty of this cell 79 | output wire [WIDTH-1:0] F_out, // Up Gap penalty of this cell 80 | output wire [2:0] T_out, // Reference seq shift out 81 | output wire init_out, // Computation active shift out 82 | output reg dir_valid, 83 | output wire [REF_LEN_WIDTH-1:0] dir_addr, 84 | output reg signed [3:0] dir 85 | ); 86 | 87 | localparam ZERO=0, MATCH=3, VER=1, HOR=2; 88 | 89 | reg [2:0] T; 90 | reg signed [WIDTH-1:0] V_diag; 91 | reg signed [WIDTH-1:0] V; 92 | reg signed [WIDTH-1:0] M; 93 | reg signed [WIDTH-1:0] E; 94 | reg signed [WIDTH-1:0] F; 95 | reg signed [WIDTH-1:0] max_V; 96 | 97 | reg store_S; 98 | reg init; 99 | reg reg_last; 100 | 101 | reg [REF_LEN_WIDTH-1:0] curr_ref_pos; 102 | reg [REF_LEN_WIDTH-1:0] curr_ref_mod; 103 | reg [QUERY_LEN_WIDTH-1:0] curr_query_mod; 104 | 105 | reg signed [WIDTH-1:0] sub_A; 106 | reg signed [WIDTH-1:0] sub_C; 107 | reg signed [WIDTH-1:0] sub_G; 108 | reg signed [WIDTH-1:0] sub_T; 109 | reg signed [WIDTH-1:0] sub_N; 110 | reg signed [WIDTH-1:0] gap_open; 111 | reg signed [WIDTH-1:0] gap_extend; 112 | 113 | reg signed [WIDTH-1:0] V_gap_open; 114 | reg signed [WIDTH-1:0] E_gap_extend; 115 | reg signed [WIDTH-1:0] upV_gap_open; 116 | reg signed [WIDTH-1:0] upF_gap_extend; 117 | reg signed [WIDTH-1:0] match_score; 118 | reg signed [WIDTH-1:0] new_E; 119 | reg signed [WIDTH-1:0] new_F; 120 | reg signed [WIDTH-1:0] new_V; 121 | reg [3:0] new_dir; 122 | 123 | reg signed [WIDTH-1:0] match_reward; 124 | 125 | reg [1:0] pe_state; 126 | reg [1:0] last_pe_state; 127 | 128 | assign V_out = V; 129 | assign M_out = M; 130 | assign E_out = E; 131 | assign F_out = F; 132 | assign T_out = T; 133 | assign init_out = init; 134 | assign store_S_out = store_S; 135 | assign dir_addr = curr_ref_pos-1; 136 | 137 | always @(*) begin 138 | case ({T_in})//reference sequence base pair for reward calculation (W(r_i,q_j)) to calc match_score 139 | 3'b000 : match_reward = sub_N; 140 | 3'b001 : match_reward = sub_A; 141 | 3'b010 : match_reward = sub_C; 142 | 3'b011 : match_reward = sub_G; 143 | 3'b100 : match_reward = sub_T; 144 | default : match_reward = 0; 145 | endcase 146 | end 147 | 148 | //Score calculation 149 | always @(*) begin 150 | //for I matrix 151 | V_gap_open = V + gap_open; 152 | E_gap_extend = E + gap_extend; 153 | //for D matrix 154 | upV_gap_open = V_in + gap_open; 155 | upF_gap_extend = F_in + gap_extend; 156 | 157 | //H(i-1,j-1)+W(r_i,q_j) 158 | match_score = V_diag + match_reward; 159 | 160 | //I(i,j) 161 | if ($signed(V_gap_open) > $signed(E_gap_extend)) begin 162 | new_E = V_gap_open; 163 | new_dir[3] = 1; 164 | end 165 | else begin 166 | new_E = E_gap_extend; 167 | new_dir[3] = 0; 168 | end 169 | 170 | //D(i,j) 171 | if ($signed(upV_gap_open) > $signed(upF_gap_extend)) begin 172 | new_F = upV_gap_open; 173 | new_dir[2] = 1; 174 | end 175 | else begin 176 | new_F = upF_gap_extend; 177 | new_dir[2] = 0; 178 | end 179 | 180 | //calculating max and final state 181 | if (0 >= $signed(new_E) && 0 >= $signed(new_F) && 0 >= $signed(match_score)) begin 182 | new_V = 0; 183 | pe_state = ZERO; 184 | new_dir[1:0] = 0; 185 | end 186 | else if ($signed(new_F) >= $signed(new_E) && $signed(new_F) >= $signed(match_score)) begin 187 | new_V = new_F; 188 | pe_state = VER; 189 | new_dir[1:0] = 1; 190 | end 191 | else if ($signed(new_E) >= $signed(match_score)) begin 192 | new_V = new_E; 193 | pe_state = HOR; 194 | new_dir[1:0] = 2; 195 | end 196 | else begin 197 | new_V = match_score; 198 | pe_state = MATCH; 199 | new_dir[1:0] = 3; 200 | end 201 | end 202 | //why pe_state and new_dir both? - same value 203 | 204 | 205 | always @(posedge clk) begin 206 | last_pe_state <= pe_state; 207 | if (rst) begin 208 | max_ref_pos_out <= 0; 209 | max_ref_mod_out <= 0; 210 | max_query_mod_out <= 0; 211 | max_pe_state_out <= 0; 212 | max_V <= 0; 213 | end 214 | else if ((init == 1'b1) && ((reg_last == 1'b1) || (V > max_V))) begin 215 | max_ref_pos_out <= curr_ref_pos - 1; 216 | max_ref_mod_out <= curr_ref_mod - 1; 217 | max_query_mod_out <= curr_query_mod - 1; 218 | max_pe_state_out <= last_pe_state; 219 | max_V <= V; 220 | end 221 | else if (compute_max_in) begin 222 | if (((max_V <= V_in) || (last_in == 1'b1)) && (reg_last == 1'b0)) begin 223 | max_ref_pos_out <= max_ref_pos_in; 224 | max_ref_mod_out <= max_ref_mod_in; 225 | max_query_mod_out <= max_query_mod_in; 226 | max_pe_state_out <= max_pe_state_in; 227 | end 228 | end 229 | end 230 | 231 | always @(posedge clk) begin 232 | //reset/initialize variable 233 | if (rst) begin 234 | T <= 0; 235 | V_diag <= 0; 236 | V <= 0; 237 | M <= 0; 238 | E <= (2'b11 << (WIDTH-2)); 239 | F <= 0; 240 | store_S <= 0; 241 | init <= 0; 242 | dir <= 0; 243 | dir_valid <= 0; 244 | curr_ref_pos <= 0; 245 | curr_ref_mod <= 0; 246 | curr_query_mod <= 0; 247 | max_query_pos_out <= PE_ID; 248 | compute_max_out <= 0; 249 | reg_last <= 0; 250 | 251 | //set the parameters 252 | end else if (set_param) begin 253 | sub_A <= sub_A_in; 254 | sub_C <= sub_C_in; 255 | sub_G <= sub_G_in; 256 | sub_T <= sub_T_in; 257 | sub_N <= sub_N_in; 258 | gap_open <= gap_open_in; 259 | gap_extend <= gap_extend_in; 260 | reg_last <= last; 261 | init <= 0; 262 | dir_valid <= 0; 263 | curr_ref_mod <= 0; 264 | curr_query_mod <= curr_query_mod + 1; 265 | 266 | //actual calculation 267 | end else begin 268 | init <= init_in; 269 | T <= T_in; 270 | V_diag <= V_in; 271 | compute_max_out <= compute_max_in; 272 | last_out <= (reg_last | last_in); 273 | 274 | if (init_in) begin 275 | E <= new_E; 276 | F <= new_F; 277 | V <= new_V; 278 | //M <= ($signed(match_score) >= 0) ? match_score : 0; 279 | dir <= new_dir; 280 | dir_valid <= 1; 281 | curr_ref_pos <= curr_ref_pos + 1; 282 | curr_ref_mod <= curr_ref_mod + 1; 283 | end else if (compute_max_in) begin 284 | if ((((max_V > V_in) || (reg_last == 1'b1))) && (last_in == 1'b0)) begin 285 | V <= max_V; 286 | max_query_pos_out <= PE_ID; 287 | end 288 | else begin 289 | max_query_pos_out <= max_query_pos_in; 290 | V <= V_in; 291 | end 292 | dir_valid <= 0; 293 | end else begin 294 | V <= init_V; 295 | E <= init_E; 296 | dir_valid <= 0; 297 | end 298 | end 299 | end 300 | 301 | endmodule 302 | 303 | -------------------------------------------------------------------------------- /RTL/GACT/get_alignments.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | args = sys.argv[1:] 4 | 5 | ref_file = args[0] 6 | query_file = args[1] 7 | num_tb_files = int(args[2]) 8 | 9 | f = open(ref_file, 'r') 10 | text = f.read() 11 | ref_seqs = text.splitlines() 12 | f.close() 13 | 14 | f = open(query_file, 'r') 15 | text = f.read() 16 | query_seqs = text.splitlines() 17 | f.close() 18 | 19 | for i in range(1,num_tb_files+1): 20 | tb_file = './results/test.' + str(i) + '.out' 21 | f = open(tb_file, 'r') 22 | text = f.read() 23 | tb_content = text.splitlines() 24 | f.close() 25 | 26 | l = len(tb_content) 27 | tb_pointers = tb_content[4:l-2] 28 | 29 | max_score = int(tb_content[l-2].replace(',','').split()[8]) 30 | max_ref_pos = int(tb_content[l-2].replace(',','').split()[2]) 31 | max_query_pos = int(tb_content[l-2].replace(',','').split()[5]) 32 | 33 | ref_pos = max_ref_pos 34 | query_pos = max_query_pos 35 | 36 | ref = ref_seqs[i-1] 37 | query = query_seqs[i-1] 38 | 39 | ref_aligned = '' 40 | query_aligned = '' 41 | 42 | for tb in tb_pointers: 43 | if tb == '3': 44 | ref_aligned = ref[ref_pos] + ref_aligned 45 | query_aligned = query[query_pos] + query_aligned 46 | ref_pos -= 1 47 | query_pos -= 1 48 | elif tb == '1': 49 | ref_aligned = '-' + ref_aligned 50 | query_aligned = query[query_pos] + query_aligned 51 | query_pos -= 1 52 | elif tb == '2': 53 | ref_aligned = ref[ref_pos] + ref_aligned 54 | query_aligned = '-' + query_aligned 55 | ref_pos -= 1 56 | 57 | print(ref_aligned) 58 | print(query_aligned) 59 | print('') 60 | 61 | -------------------------------------------------------------------------------- /RTL/GACT/mux_1OfN.v: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2018 Yatish Turakhia, Sneha D. Goenka, Gill Bejerano and William Dally 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | module mux_1OfN #( 26 | parameter NUM_PORTS_WIDTH = 2, 27 | parameter DATA_WIDTH = 32 28 | 29 | )( 30 | input clk, 31 | input [NUM_PORTS_WIDTH-1:0] select, 32 | input [(2 ** NUM_PORTS_WIDTH)*DATA_WIDTH-1:0] data_in, 33 | output reg [DATA_WIDTH-1:0] data_out 34 | ); 35 | 36 | localparam NUM_PORTS = 2**NUM_PORTS_WIDTH; 37 | 38 | always @(posedge clk) begin 39 | data_out <= data_in[(select+1)*DATA_WIDTH-1-:DATA_WIDTH]; 40 | end 41 | 42 | endmodule 43 | -------------------------------------------------------------------------------- /RTL/GACT/run_test.sh: -------------------------------------------------------------------------------- 1 | set -x 2 | curr_dir=$PWD 3 | mkdir -p results 4 | cd results/ 5 | for i in 1 2 3 4 5 6 7 8 9 10; 6 | do 7 | echo '' > test.${i}.out 8 | echo "sed -i -e 's/ref\.\(.*\)\.hex/ref\.${i}\.hex/g' ${curr_dir}/tb_GACTTop.v" | sh -e 9 | echo "sed -i -e 's/query\.\(.*\)\.hex/query\.${i}\.hex/g' ${curr_dir}/tb_GACTTop.v" | sh -e 10 | echo "sed -i -e 's/test\.\(.*\)\.vcd/test\.${i}\.vcd/g' ${curr_dir}/tb_GACTTop.v" | sh -e 11 | iverilog ${curr_dir}/tb_GACTTop.v ${curr_dir}/GACTTop.v ${curr_dir}/BRAM.v ${curr_dir}/FIFOWithCount.v ${curr_dir}/SmithWatermanArray.v ${curr_dir}/SmithWatermanPE.v ${curr_dir}/Ascii2Nt.v ${curr_dir}/BTLogic.v ${curr_dir}/DP_BRAM.v ${curr_dir}/Nt2Param.v ${curr_dir}/mux_1OfN.v 12 | ./a.out >> test.${i}.out 13 | done 14 | cd $curr_dir 15 | echo 'Results in folder '${curr_dir}'/results/' 16 | -------------------------------------------------------------------------------- /RTL/GACT/tb_GACTTop.v: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2018 Yatish Turakhia, Sneha D. Goenka, Gill Bejerano and William Dally 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | `timescale 1ns / 1ps 26 | 27 | module tb_GACTTop(); 28 | localparam test_cycles = 50000; 29 | parameter HalfClkPeriod = 5; 30 | parameter REF_FILENAME = "../test_data/ref.10.hex"; 31 | parameter QUERY_FILENAME = "../test_data/query.10.hex"; 32 | 33 | localparam ClkPeriod = 2*HalfClkPeriod; 34 | reg [31:0] cycle; 35 | 36 | reg clk; 37 | reg rst; 38 | wire done; 39 | 40 | wire [8:0] num_query_bases; 41 | wire [8:0] num_ref_bases; 42 | wire [17:0] num_tb_steps; 43 | wire [8:0] query_max_pos; 44 | wire ready; 45 | wire [8:0] ref_max_pos; 46 | wire [15:0] req_id_out; 47 | wire [9:0] tile_score; 48 | wire [1:0] dir; 49 | wire dir_valid; 50 | 51 | reg clear_done; 52 | reg [8:0] ref_len; 53 | reg [8:0] query_len; 54 | 55 | reg [9:0] max_tb_steps; 56 | 57 | reg [9:0] score_threshold; 58 | reg [119:0] in_params; 59 | 60 | reg [9:0] params [0:11]; 61 | reg [7:0] align_fields; 62 | reg [15:0] req_id_in; 63 | 64 | reg set_params; 65 | reg start; 66 | 67 | reg [63:0] ref_in; 68 | reg [63:0] query_in; 69 | reg ref_wr_en; 70 | reg query_wr_en; 71 | reg [5:0] ref_addr_in; 72 | reg [5:0] query_addr_in; 73 | 74 | // Generate Clock 75 | initial clk = 1; 76 | always #(HalfClkPeriod) clk = ~clk; 77 | 78 | GACTTop #( 79 | .PE_WIDTH(10), 80 | .BLOCK_WIDTH(3), 81 | .MAX_TILE_SIZE(512), 82 | .NUM_PE(4), 83 | .REF_FILENAME(REF_FILENAME), 84 | .QUERY_FILENAME(QUERY_FILENAME), 85 | .REQUEST_ID_WIDTH(16) 86 | ) dut ( 87 | .clk(clk), 88 | .rst(rst), 89 | .align_fields (align_fields), 90 | 91 | .clear_done (clear_done), 92 | .in_params (in_params), 93 | .max_tb_steps (max_tb_steps), 94 | .query_addr_in (query_addr_in), 95 | .query_in (query_in), 96 | .query_len (query_len), 97 | .query_wr_en (query_wr_en), 98 | .ref_addr_in (ref_addr_in), 99 | .ref_in (ref_in), 100 | .ref_len (ref_len), 101 | .ref_wr_en (ref_wr_en), 102 | .req_id_in (req_id_in), 103 | .score_threshold (score_threshold), 104 | .set_params (set_params), 105 | .start (start), 106 | 107 | .dir (dir), 108 | .dir_valid (dir_valid), 109 | 110 | .done (done), 111 | .num_query_bases (num_query_bases), 112 | .num_ref_bases (num_ref_bases), 113 | .num_tb_steps (num_tb_steps), 114 | .query_max_pos (query_max_pos), 115 | .ready (ready), 116 | .ref_max_pos (ref_max_pos), 117 | .req_id_out (req_id_out), 118 | .tile_score (tile_score) 119 | 120 | ); 121 | 122 | // Run simulation 123 | initial begin 124 | $dumpfile("test.10.vcd"); 125 | $dumpvars(0, dut); 126 | cycle = 0; 127 | start = 0; 128 | set_params = 0; 129 | 130 | score_threshold = 0; 131 | clear_done = 1; 132 | 133 | ref_len = 320; 134 | query_len = 320; 135 | ref_wr_en = 0; 136 | query_wr_en = 0; 137 | 138 | max_tb_steps = 400; 139 | 140 | align_fields = (1<<5); 141 | 142 | params[11] = 1; 143 | params[10] = -1; 144 | params[9] = -1; 145 | params[8] = -1; 146 | 147 | params[7] = 1; 148 | params[6] = -1; 149 | params[5] = -1; 150 | 151 | params[4] = 1; 152 | params[3] = -1; 153 | 154 | params[2] = 1; 155 | 156 | params[1] = -1; 157 | params[0] = -1; 158 | 159 | in_params = {params[11], params[10], params[9], params[8], params[7], params[6], params[5], params[4], params[3], params[2], params[1], params[0]}; 160 | $display("---- Performing Reset ----"); 161 | rst = 1; 162 | 163 | #(1*ClkPeriod); 164 | rst = 0; 165 | 166 | #(1*ClkPeriod); 167 | set_params = 1; 168 | 169 | #(1*ClkPeriod); 170 | set_params = 0; 171 | 172 | #(1*ClkPeriod); 173 | $display("---- Starting Simulation ----"); 174 | start = 1; 175 | 176 | #(1*ClkPeriod); 177 | start = 0; 178 | end 179 | 180 | always @ (posedge clk) begin 181 | cycle <= cycle + 1; 182 | if (cycle > test_cycles) begin 183 | $display("---- Done ----"); 184 | $finish(); 185 | end 186 | end 187 | 188 | always @ (posedge clk) begin 189 | if (dir_valid) begin 190 | $display("%d", dir); 191 | end 192 | if (done) begin 193 | $display("ref pos: %d, query pos: %d, max score", ref_max_pos, query_max_pos, tile_score); 194 | end 195 | end 196 | 197 | endmodule 198 | -------------------------------------------------------------------------------- /RTL/GACT/test_data/query.1.hex: -------------------------------------------------------------------------------- 1 | 0x4147544343434141 2 | 0x5441414747474747 3 | 0x4747544347415454 4 | 0x4141545447474147 5 | 0x5454414141434747 6 | 0x4343545441475447 7 | 0x4743474141474154 8 | 0x4754544743474141 9 | 0x4347414347474743 10 | 0x4347544347434141 11 | 0x5447474343545454 12 | 0x4143474741474347 13 | 0x4354545447474741 14 | 0x4754475454414743 15 | 0x4347474754414347 16 | 0x4147544141544347 17 | 0x4343544154545454 18 | 0x4141474747435454 19 | 0x5441414741544141 20 | 0x4741435454434743 21 | 0x4143414147474747 22 | 0x5447474754544747 23 | 0x4347414743414341 24 | 0x4147434754434354 25 | 0x4754434354475441 26 | 0x4347414747474754 27 | 0x4147415454414343 28 | 0x5441474741434343 29 | 0x4343414741434341 30 | 0x4141414141545447 31 | 0x4741414354435454 32 | 0x4747544743434141 33 | 0x4143414741434343 34 | 0x4741544747474141 35 | 0x5441414341435441 36 | 0x4354474141435443 37 | 0x5443544343414347 38 | 0x5443545447544141 39 | 0x4747414141414141 40 | 0 41 | 0 42 | 0 43 | 0 44 | 0 45 | 0 46 | 0 47 | 0 48 | 0 49 | 0 50 | 0 51 | 0 52 | 0 53 | 0 54 | 0 55 | 0 56 | 0 57 | 0 58 | 0 59 | 0 60 | 0 61 | 0 62 | 0 63 | 0 64 | 0 65 | -------------------------------------------------------------------------------- /RTL/GACT/test_data/query.10.hex: -------------------------------------------------------------------------------- 1 | 0x4754474354544154 2 | 0x4743434341474747 3 | 0x4154414754434347 4 | 0x4347434741544147 5 | 0x4354474741434143 6 | 0x4347434747474743 7 | 0x4154544743435454 8 | 0x4341474343544747 9 | 0x5454434743475443 10 | 0x4754474154544743 11 | 0x5441544354545441 12 | 0x4143414354414747 13 | 0x4741414154474143 14 | 0x4343434741475443 15 | 0x5441474141414147 16 | 0x4743474343414747 17 | 0x4743434154474141 18 | 0x5443415443414341 19 | 0x5454474347544747 20 | 0x4343435441474147 21 | 0x4741545454544147 22 | 0x4143474147434343 23 | 0x4147544343435443 24 | 0x4147474347474143 25 | 0x5447414347544141 26 | 0x4741544347544347 27 | 0x5441414354414143 28 | 0x4754414147434741 29 | 0x4347475447474343 30 | 0x5454414341475441 31 | 0x4343544743434147 32 | 0x4754435454414141 33 | 0x4147544354414343 34 | 0x4343544741544341 35 | 0x5443545454415441 36 | 0x4343414143414347 37 | 0x4347544147544343 38 | 0x4747415443414754 39 | 0x4747414743435447 40 | 0x4154434741544743 41 | 0 42 | 0 43 | 0 44 | 0 45 | 0 46 | 0 47 | 0 48 | 0 49 | 0 50 | 0 51 | 0 52 | 0 53 | 0 54 | 0 55 | 0 56 | 0 57 | 0 58 | 0 59 | 0 60 | 0 61 | 0 62 | 0 63 | 0 64 | 0 65 | -------------------------------------------------------------------------------- /RTL/GACT/test_data/query.2.hex: -------------------------------------------------------------------------------- 1 | 0x4147545447474343 2 | 0x5447474741474141 3 | 0x4741435447414754 4 | 0x4743414154544754 5 | 0x4741474747414741 6 | 0x5454434743434347 7 | 0x4741414754414143 8 | 0x4141474754545447 9 | 0x4147474741475447 10 | 0x4754414754475441 11 | 0x4341435441474747 12 | 0x4143474147475441 13 | 0x4147544147414143 14 | 0x4743414147544343 15 | 0x4341434141474341 16 | 0x5443544154545447 17 | 0x5443434747415443 18 | 0x4343435447434343 19 | 0x4343544141474147 20 | 0x4743414747544341 21 | 0x5441544743474354 22 | 0x4747474354434347 23 | 0x4747434754434154 24 | 0x5441414354414141 25 | 0x4747474341415441 26 | 0x4741474147415447 27 | 0x4354475447414747 28 | 0x4741435447434743 29 | 0x4354414154544354 30 | 0x4747545441475441 31 | 0x4141544154434754 32 | 0x5443434154544143 33 | 0x4154544754474154 34 | 0x4141414341415441 35 | 0x5441434354544141 36 | 0x4743545441474143 37 | 0x5454474154434347 38 | 0x4141434154475454 39 | 0x4743474747544747 40 | 0x4343415454434154 41 | 0 42 | 0 43 | 0 44 | 0 45 | 0 46 | 0 47 | 0 48 | 0 49 | 0 50 | 0 51 | 0 52 | 0 53 | 0 54 | 0 55 | 0 56 | 0 57 | 0 58 | 0 59 | 0 60 | 0 61 | 0 62 | 0 63 | 0 64 | 0 65 | -------------------------------------------------------------------------------- /RTL/GACT/test_data/query.3.hex: -------------------------------------------------------------------------------- 1 | 0x4354435447434354 2 | 0x4154414747544147 3 | 0x4141474343475454 4 | 0x4143434347474141 5 | 0x4354415447434154 6 | 0x5443435443474754 7 | 0x5441435454415443 8 | 0x4754434754414154 9 | 0x4354475447544143 10 | 0x4747544143474147 11 | 0x5443545443474741 12 | 0x4141474347434354 13 | 0x4143434747474754 14 | 0x5454414741474754 15 | 0x4743414143475447 16 | 0x4747475443414741 17 | 0x4341544347415447 18 | 0x4154434341414754 19 | 0x5454474143544147 20 | 0x4141545454545454 21 | 0x5441545454545443 22 | 0x4147544347434754 23 | 0x4741414743435441 24 | 0x4154474147475447 25 | 0x4741434341474347 26 | 0x5443434743434354 27 | 0x4141544347474147 28 | 0x4743434341414747 29 | 0x4147475447434143 30 | 0x4341544354434147 31 | 0x4354475441415443 32 | 0x5454545447544141 33 | 0x5447474743474147 34 | 0x4747414141414154 35 | 0x5441414147414743 36 | 0x4741414141545443 37 | 0x4143414141544343 38 | 0x4143414343544141 39 | 0x4143434141544754 40 | 0x4347545454544347 41 | 0 42 | 0 43 | 0 44 | 0 45 | 0 46 | 0 47 | 0 48 | 0 49 | 0 50 | 0 51 | 0 52 | 0 53 | 0 54 | 0 55 | 0 56 | 0 57 | 0 58 | 0 59 | 0 60 | 0 61 | 0 62 | 0 63 | 0 64 | 0 65 | -------------------------------------------------------------------------------- /RTL/GACT/test_data/query.4.hex: -------------------------------------------------------------------------------- 1 | 0x4747544354415443 2 | 0x4154544147544347 3 | 0x4347435454414143 4 | 0x5443435441545443 5 | 0x5441474343544141 6 | 0x4341544354474147 7 | 0x4741474754475454 8 | 0x4747544747474747 9 | 0x4743434354434741 10 | 0x5441544741434141 11 | 0x4747474143434741 12 | 0x4147544141474147 13 | 0x4143544341414141 14 | 0x4147474154414141 15 | 0x4143434747474154 16 | 0x4743434347414154 17 | 0x4141415454474743 18 | 0x4147414747414341 19 | 0x4747544141544741 20 | 0x4741544154545443 21 | 0x4354545447474743 22 | 0x4743434754434343 23 | 0x4343544343474754 24 | 0x5441434743474741 25 | 0x4747414354475441 26 | 0x4147414354544143 27 | 0x5443435454414343 28 | 0x4347434341475447 29 | 0x4141544754544147 30 | 0x4141414341474354 31 | 0x4741544747415447 32 | 0x4341414741414354 33 | 0x5441474154544341 34 | 0x5454544741414341 35 | 0x5443475441544747 36 | 0x4741435454414154 37 | 0x4741434741435441 38 | 0x4141474354545447 39 | 0x4143475454434343 40 | 0x4343434341474741 41 | 0 42 | 0 43 | 0 44 | 0 45 | 0 46 | 0 47 | 0 48 | 0 49 | 0 50 | 0 51 | 0 52 | 0 53 | 0 54 | 0 55 | 0 56 | 0 57 | 0 58 | 0 59 | 0 60 | 0 61 | 0 62 | 0 63 | 0 64 | 0 65 | -------------------------------------------------------------------------------- /RTL/GACT/test_data/query.5.hex: -------------------------------------------------------------------------------- 1 | 0x5441544347414747 2 | 0x4143434347434747 3 | 0x4147544741474347 4 | 0x5441414343545454 5 | 0x4754414143475441 6 | 0x4343544741544341 7 | 0x4741545454414141 8 | 0x5441414743545441 9 | 0x4154475441474341 10 | 0x4343434354434343 11 | 0x4741544354474354 12 | 0x4741434754414743 13 | 0x4341415447414347 14 | 0x4743434343545447 15 | 0x4747544141474341 16 | 0x4754414747414154 17 | 0x4354544143434343 18 | 0x4347414347544747 19 | 0x5441415454415441 20 | 0x4141474141474741 21 | 0x5447474143544341 22 | 0x5443434354544354 23 | 0x4147545443434141 24 | 0x5454435454544354 25 | 0x4141435443544147 26 | 0x4343414741414147 27 | 0x4147474341544143 28 | 0x4154544747415441 29 | 0x4741415441434154 30 | 0x5454544147434747 31 | 0x4747435447414343 32 | 0x4743544354434347 33 | 0x4743435441435447 34 | 0x4147434341434343 35 | 0x4747474141544143 36 | 0x5443544143434741 37 | 0x5454414754435441 38 | 0x5447474347434141 39 | 0x5441414154545454 40 | 0x4343545454414147 41 | 0 42 | 0 43 | 0 44 | 0 45 | 0 46 | 0 47 | 0 48 | 0 49 | 0 50 | 0 51 | 0 52 | 0 53 | 0 54 | 0 55 | 0 56 | 0 57 | 0 58 | 0 59 | 0 60 | 0 61 | 0 62 | 0 63 | 0 64 | 0 65 | -------------------------------------------------------------------------------- /RTL/GACT/test_data/query.6.hex: -------------------------------------------------------------------------------- 1 | 0x4341434147545441 2 | 0x4341414147414143 3 | 0x4343414754474154 4 | 0x4141544154474143 5 | 0x4341434754434747 6 | 0x4743434747414754 7 | 0x4354414147434743 8 | 0x4754544347434341 9 | 0x5447414743544754 10 | 0x4347474343434147 11 | 0x4143475441414343 12 | 0x5447474341415454 13 | 0x4747544341435441 14 | 0x4754415443434354 15 | 0x4741415447414141 16 | 0x4741545454434754 17 | 0x4147545441544347 18 | 0x4343414347544341 19 | 0x5447415443414341 20 | 0x4354545454414741 21 | 0x4141434141474741 22 | 0x4343434741435443 23 | 0x5443544354434154 24 | 0x4341414147475447 25 | 0x4347474154545454 26 | 0x4743414143474754 27 | 0x4147435443545447 28 | 0x4741414143434343 29 | 0x4747414754474347 30 | 0x4354545441414147 31 | 0x4343434147474347 32 | 0x4147415441415454 33 | 0x4747435441434141 34 | 0x4743474754414147 35 | 0x5454474754414147 36 | 0x4754434741434347 37 | 0x4141434747434341 38 | 0x4347434747415443 39 | 0x4341474143475443 40 | 0x4747435447474741 41 | 0 42 | 0 43 | 0 44 | 0 45 | 0 46 | 0 47 | 0 48 | 0 49 | 0 50 | 0 51 | 0 52 | 0 53 | 0 54 | 0 55 | 0 56 | 0 57 | 0 58 | 0 59 | 0 60 | 0 61 | 0 62 | 0 63 | 0 64 | 0 65 | -------------------------------------------------------------------------------- /RTL/GACT/test_data/query.7.hex: -------------------------------------------------------------------------------- 1 | 0x4343544743544141 2 | 0x4343415441415447 3 | 0x4343545443414143 4 | 0x4141415454544341 5 | 0x4347434143435454 6 | 0x4341474147474741 7 | 0x4343435454544341 8 | 0x4147414354544747 9 | 0x4741475454434743 10 | 0x4354474354474347 11 | 0x4343474141434741 12 | 0x4354414343414141 13 | 0x4347415447434143 14 | 0x4341434141545447 15 | 0x5441434141414347 16 | 0x4354544154544147 17 | 0x5441414347414754 18 | 0x4354415443434143 19 | 0x4347475441415454 20 | 0x4747545441474341 21 | 0x5454545454414354 22 | 0x5447414747415447 23 | 0x4141414143545443 24 | 0x4154434354544147 25 | 0x4747474747414343 26 | 0x4143545443435447 27 | 0x4147434141434754 28 | 0x4147434154544347 29 | 0x4743434354414141 30 | 0x4341474347474354 31 | 0x4747474347434743 32 | 0x4354415443475443 33 | 0x4347414141434747 34 | 0x4147434341544743 35 | 0x5441474154544141 36 | 0x5441414741544141 37 | 0x4147414343434343 38 | 0x4354544754475454 39 | 0x5454474141434154 40 | 0x5441544747434147 41 | 0 42 | 0 43 | 0 44 | 0 45 | 0 46 | 0 47 | 0 48 | 0 49 | 0 50 | 0 51 | 0 52 | 0 53 | 0 54 | 0 55 | 0 56 | 0 57 | 0 58 | 0 59 | 0 60 | 0 61 | 0 62 | 0 63 | 0 64 | 0 65 | -------------------------------------------------------------------------------- /RTL/GACT/test_data/query.8.hex: -------------------------------------------------------------------------------- 1 | 0x4141434747474143 2 | 0x4754414147545441 3 | 0x4147474343414143 4 | 0x5441474341435447 5 | 0x4754415441544343 6 | 0x5443414143434154 7 | 0x5447475447545443 8 | 0x5447434743544341 9 | 0x4747414347544741 10 | 0x4147414347545447 11 | 0x4147434341414147 12 | 0x4354414743544747 13 | 0x4341544341544741 14 | 0x5441544141414747 15 | 0x4343434754414741 16 | 0x4347434143544343 17 | 0x4347474747414154 18 | 0x5441544743545443 19 | 0x4347475441414754 20 | 0x4754474747544347 21 | 0x4754475454544741 22 | 0x4343474743434341 23 | 0x5443434741475443 24 | 0x4747474754434347 25 | 0x4147544347475441 26 | 0x4354414743414747 27 | 0x4341434747474747 28 | 0x4754434154545443 29 | 0x4147415443435441 30 | 0x5443475447545441 31 | 0x4343415443434341 32 | 0x4741544341414354 33 | 0x5443474741415447 34 | 0x5441435441544143 35 | 0x4743544143434143 36 | 0x4154434754434343 37 | 0x4743474741475454 38 | 0x4754475447414343 39 | 0x4341544747435443 40 | 0x5454544354434141 41 | 0 42 | 0 43 | 0 44 | 0 45 | 0 46 | 0 47 | 0 48 | 0 49 | 0 50 | 0 51 | 0 52 | 0 53 | 0 54 | 0 55 | 0 56 | 0 57 | 0 58 | 0 59 | 0 60 | 0 61 | 0 62 | 0 63 | 0 64 | 0 65 | -------------------------------------------------------------------------------- /RTL/GACT/test_data/query.9.hex: -------------------------------------------------------------------------------- 1 | 0x4354415447475454 2 | 0x5454434354435443 3 | 0x4747414143474754 4 | 0x4143415447414141 5 | 0x4343414354434141 6 | 0x4354474343544154 7 | 0x5454474354544147 8 | 0x5441434347434754 9 | 0x5441545447434743 10 | 0x5441414141545447 11 | 0x4741434143434754 12 | 0x4743434354434147 13 | 0x4347545443545443 14 | 0x5443474141415443 15 | 0x4347474141474741 16 | 0x4347415454434347 17 | 0x4747544154414741 18 | 0x4143544354544147 19 | 0x4147544743474747 20 | 0x4141474154414754 21 | 0x5447435443434354 22 | 0x4754474741544741 23 | 0x4341544741415441 24 | 0x4747544343475443 25 | 0x4154415443544341 26 | 0x5441545454415441 27 | 0x5447475443474747 28 | 0x5454474141415454 29 | 0x4343415454544743 30 | 0x4143434141434343 31 | 0x4154414147434343 32 | 0x4754434143434343 33 | 0x4154474354434347 34 | 0x4343414354414747 35 | 0x4747435454414143 36 | 0x4354544743474754 37 | 0x4343434343474354 38 | 0x4347434347544754 39 | 0x5443544147544147 40 | 0x4354434141474754 41 | 0 42 | 0 43 | 0 44 | 0 45 | 0 46 | 0 47 | 0 48 | 0 49 | 0 50 | 0 51 | 0 52 | 0 53 | 0 54 | 0 55 | 0 56 | 0 57 | 0 58 | 0 59 | 0 60 | 0 61 | 0 62 | 0 63 | 0 64 | 0 65 | -------------------------------------------------------------------------------- /RTL/GACT/test_data/query.hex: -------------------------------------------------------------------------------- 1 | 0x0000000000000041 2 | 0 3 | 0 4 | 0 5 | 0 6 | 0 7 | 0 8 | 0 9 | 0 10 | 0 11 | 0 12 | 0 13 | 0 14 | 0 15 | 0 16 | 0 17 | 0 18 | 0 19 | 0 20 | 0 21 | 0 22 | 0 23 | 0 24 | 0 25 | 0 26 | 0 27 | 0 28 | 0 29 | 0 30 | 0 31 | 0 32 | 0 33 | 0 34 | 0 35 | 0 36 | 0 37 | 0 38 | 0 39 | 0 40 | 0 41 | 0 42 | 0 43 | 0 44 | 0 45 | 0 46 | 0 47 | 0 48 | 0 49 | 0 50 | 0 51 | 0 52 | 0 53 | 0 54 | 0 55 | 0 56 | 0 57 | 0 58 | 0 59 | 0 60 | 0 61 | 0 62 | 0 63 | 0 64 | 0 65 | -------------------------------------------------------------------------------- /RTL/GACT/test_data/query_320.txt: -------------------------------------------------------------------------------- 1 | AACCCTGAGGGGGAATTTAGCTGGGAGGTTAAGGCAAATTGTGATTCCTAGAAGCGAAGCGTTGCGGGCAGCAACGCTGCTTTCCGGTGCGAGGCAAGGGTTTCCGATTGTGGCATGGGCGCTAATGATTTTATCCTTCGGGAAAATAGAATCGCTTCAGGGGGAACAGGTTGGGTACACGAGCTCCTGCGAATGTCCTGTGGGGAGCCCATTAGACCCAGGATACCAGACCGTTAAAAATTCTCAAGAACCGTGGCCCAGACAAAGGGTAGATCACAATCTCAAGTCGCACCTCTAATGTTCTAAAAAAGGCCCTGGGT 2 | CCGGTTGAAAGAGGGTTGAGTCAGTGTTAACGAGAGGGAGGCCCGCTTCAATGAAGGTTTGGAAGTGAGGGAATGTGATGGGGATCACATGGAGCACAAGATGACCTGAACGACGAACACGTTTATCTCTAGGCCTCCCGTCCCGAGAATCCACTGGACGTCGCGTATGCCTCGGGTACTGCGGAAATCAATATAACGGGGTAGAGAGGGAGTGTCCGCGTCAGTCTTAATCATGATTGGTGCTATAACATTACCTTAGTGTTAATAACAAAAATTCCATCAGATTCGGCCTAGTTTTGTACAAGGTGGGCGTACTTACC 3 | TCCGTCTCGATGGATATTGCCGAAAAGGCCCATACGTATCTGGCTCCTCTATTCATTAATGCTGCATGTGTCGAGCATGGAGGCTTCTTCCGCGAATGGGGCCATGGAGATTGTGCAACGAGACTGGGGTAGCTACTGAACCTAGATCAGTTTTTTTTAACTTTTTATTGCGCTGAATCCGAAGGTGGAGTAGCGACCAGTCCCGCCTGAGGCTAAGGAACCCGCACGTGGAGACTCTACCTAATGTCAATGTTTTGAGCGGGTTAAAAAGGCGAGAAATCTTAAAAGCCTAAACAAATCCACATGTAACCAGCTTTTGC 4 | CTATCTGGGCTGATTACAATTCGCCTTATCCTAATCCGATGAGTCTACTTGTGGAGGGGGGTGGAGCTCCCGAACAGTATAGCCAGGGGAGAATGAAAAACTCAAAATAGGATAGGGCCATAAGCCCGCGGTTAAAACAGGAGAAGTAATGGCTTTATAGCGGGTTTCCCCTGCCGTGGCCTCCAGGCGCATATGTCAGGCATTCAGACCATTCCTGTGACCGCGATTGTAATCGACAAAGTAGGTAGTCAAGAACACTTAGATACAAGTTTGGTATGCTTAATTCAGATCAGCAGGTTTCGAACCCTTGCAAGGACCCC 5 | GGAGCTATGGCGCCCAGCGAGTGATTTCCAATATGCAATGACTAGTCCAAATTTAGATTCGAATACGATGTACCCTCCCCTCGTCTAGCGATGCAGGCAGTAACGTTCCCCGACGAATGGTAAGGATGCCCCATTCGGTGCAGCATATTAATAGGAAGAAACTCAGGTTCTTCCCTAACCTTGATCTTTCTTGATCTCAAGAAAGACCCATACGGAATAGGTTATACATAAGGGCGATTTCCAGTCGGGCCTCTCGGTCATCCGCCCACCGACATAAGGGAGCCATCTATCTGATTAACGCGGTTTTTAAATGAATTTCC 6 | ATTGACACCAAGAAACTAGTGACCCAGTATAAGGCTGCACTGAGGCCGCGCGAATCACCGCTTGTGTCGAGTGACCCGGCCCAATGCATTAACGGTATCACTGGTCCCTATGAAAGTAAGTGCTTTAGGCTATTGAACTGCACCACACTAGTAGATTTTCAGGAACAACTCAGCCCTACTCTCTGTGGAAACTTTTAGGCTGGCAACGGTTCTCGACCCCAAAGGCGTGAGGGAAATTTCGCGGACCCTTAATAGAAACATCGGGAATGGCGGAATGGTTGCCAGCTGACCGGCAACTAGGCGCCTGCAGACAGGGTCGG 7 | AATCGTCCGTAATACCCAACTTCCACTTTAAATTCCACGCAGGGAGACACTTTCCCGGTTCAGACGCTTGAGGCGTCGTCAGCAAGCCAAACCATCCACGTAGCGTTAACACGCAAACATGATTATTCTGAGCAATCACCTATCTTAATGGCACGATTGGTCATTTTTGTAGGAGTCTTCAAAAGATTCCTACCAGGGGGGTCCTTCATGCAACGAGCTTACGAAAATCCCGTCGGCGACCGCGCGGGCTGCTATCGGCAAAGCCGTACCGAAATTAGATAATAGAATCCCCCAGATTGTGTTCTACAAGTTGACGGTAT 8 | CAGGGCAAATTGAATGCAACCGGAGTCACGATCCTATATGTACCAACTCTTGTGGTACTCGCGTAGTGCAGGGTTGCAGAGAAACCGAGGTCGATCAGTACTACGGAAATATAGATGCCCCCTCACGCTAAGGGGCCTTCGTATTGAATGGCGCTGGGTGAGTTTGTGACCCGGCCCTGAGCCTGCCTGGGGATGGCTGAGGACGATCGGGGGCACCTTTACTGATCCTAGAATTGTGCTACCCTACCTCAACTAGGTAAGGCTCATATCATCACCATCGCCCTGCTATTGAGGCGCCAGTGTGCTCGGTACAACTCTTT 9 | TTGGTATCCTCTCCTTTGGCAAGGAAAGTACAAACTCACCTATCCGTCGATTCGTTTGCGCCATCGCGTTATGTTAAAATTGCCACAGGACTCCCGCTTCTTGCCTAAAGCTAGGAAGGCGCCTTAGCAGATATGGGATTCTCAGGGCGTGATGATAGAATCCCTCGTAGTAGGTGATAAGTACCTGCCTGGACTCTATAATATTTATGGGCTGGTTTAAAGTTCGTTTACCCCCAACCACCCGAATACCCCACTGGCCTCGTAGGATCACCCAATTCGGTGGCGTTCTCGCCCCCTGTGCCGCGATGATCTTGGAACTC 10 | TATTCGTGGGGACCCGGCCTGATAGATAGCGCCACAGGTCCGGGGCGCTTCCGTTAGGTCCGACCTGCGCTTCGTTAGTGATTTCTATGGATCACACAGTAAAGCTGAGCCCGAAAAGATGGACCGCGAAGTACCGACACTACTGGTGCGTTGAGATCCCGATTTTAGCCCGAGCACTCCCTGACAGGCGGAAATGCAGTGCTGCTAGCAATCAATAGCGAATGCCGGTGGCATGACATTGACCGTCCAAATTCTGCCATCTGAACTAGTCCATATTTCTGCACAACCCCTGATGCTGACTAGGGTCCGAGGCGTAGCTA 11 | -------------------------------------------------------------------------------- /RTL/GACT/test_data/ref.1.hex: -------------------------------------------------------------------------------- 1 | 0x4147544343434141 2 | 0x5447544141474747 3 | 0x4747475443474154 4 | 0x4741415447474141 5 | 0x5454414141435447 6 | 0x4343545441475447 7 | 0x4743474141474154 8 | 0x4743475447474141 9 | 0x4143474143434747 10 | 0x4354434754434741 11 | 0x4347434754474743 12 | 0x4747414154434747 13 | 0x5454474743435447 14 | 0x4754414347474747 15 | 0x4147434743475447 16 | 0x5454545441475441 17 | 0x4743545443435441 18 | 0x5441474154414141 19 | 0x4741435454434743 20 | 0x4341474747474347 21 | 0x4747475454474741 22 | 0x4341474341434154 23 | 0x5441474354434354 24 | 0x4747544343435447 25 | 0x4347434147474747 26 | 0x4147415454414343 27 | 0x4341544747414343 28 | 0x5447434341474143 29 | 0x4354544141414141 30 | 0x5443414741414354 31 | 0x4147434143475447 32 | 0x4741544747414143 33 | 0x4743544143414354 34 | 0x4343544741414354 35 | 0x5447415454434341 36 | 0x4141545443545447 37 | 0x4343434747474141 38 | 0x4343414354474754 39 | 0x4147474154434343 40 | 0x4154544754414154 41 | 0 42 | 0 43 | 0 44 | 0 45 | 0 46 | 0 47 | 0 48 | 0 49 | 0 50 | 0 51 | 0 52 | 0 53 | 0 54 | 0 55 | 0 56 | 0 57 | 0 58 | 0 59 | 0 60 | 0 61 | 0 62 | 0 63 | 0 64 | 0 65 | -------------------------------------------------------------------------------- /RTL/GACT/test_data/ref.10.hex: -------------------------------------------------------------------------------- 1 | 0x4747475447544154 2 | 0x4754434347434341 3 | 0x4154414741544141 4 | 0x4341434743474347 5 | 0x4747434354474741 6 | 0x4354544347434747 7 | 0x4747415447544743 8 | 0x5443434147434354 9 | 0x4743545443474347 10 | 0x5454414754474154 11 | 0x4147475441544354 12 | 0x4741434143414354 13 | 0x5443474141414154 14 | 0x4147434343474147 15 | 0x4747544147414141 16 | 0x4343475443434341 17 | 0x4743434154414147 18 | 0x5447414143414341 19 | 0x5454474347544747 20 | 0x4143435441474147 21 | 0x4743474741545454 22 | 0x4343544341434741 23 | 0x4741434341475443 24 | 0x5441414147474347 25 | 0x4754435447414341 26 | 0x5441414347415443 27 | 0x4341474154414143 28 | 0x4743434754414147 29 | 0x4754414343474754 30 | 0x4343414754544141 31 | 0x4354544143414354 32 | 0x5443544143434754 33 | 0x5441544341414147 34 | 0x5454544154414343 35 | 0x4143414143475443 36 | 0x4147544343434341 37 | 0x5443414754434754 38 | 0x4743435447474741 39 | 0x4741544743474741 40 | 0x5441415441475443 41 | 0 42 | 0 43 | 0 44 | 0 45 | 0 46 | 0 47 | 0 48 | 0 49 | 0 50 | 0 51 | 0 52 | 0 53 | 0 54 | 0 55 | 0 56 | 0 57 | 0 58 | 0 59 | 0 60 | 0 61 | 0 62 | 0 63 | 0 64 | 0 65 | -------------------------------------------------------------------------------- /RTL/GACT/test_data/ref.2.hex: -------------------------------------------------------------------------------- 1 | 0x5447545447474343 2 | 0x5447474741474141 3 | 0x5447414347414754 4 | 0x4741474341415454 5 | 0x4343474741474741 6 | 0x4143544154434743 7 | 0x5454544741475441 8 | 0x4747474154474147 9 | 0x4147544347544141 10 | 0x5441544747474754 11 | 0x4147544754434143 12 | 0x4747415441434347 13 | 0x4754434341474754 14 | 0x4743414743434141 15 | 0x5441474341434141 16 | 0x4154435443544154 17 | 0x4743434354434347 18 | 0x4154414743434354 19 | 0x4754434143435441 20 | 0x4747435447434147 21 | 0x4354434347544154 22 | 0x4754434154474747 23 | 0x5441415441474743 24 | 0x4743415441544143 25 | 0x4341414154474747 26 | 0x4741474147474147 27 | 0x5447434743435447 28 | 0x4154544354474143 29 | 0x5441475441435441 30 | 0x4154415443474754 31 | 0x5454434341544143 32 | 0x5441415447544741 33 | 0x5454414141414341 34 | 0x4147414354415443 35 | 0x4143434747435454 36 | 0x4143415454545447 37 | 0x4747474754474741 38 | 0x4343544154434354 39 | 0x5454474141414341 40 | 0x4154414347414143 41 | 0 42 | 0 43 | 0 44 | 0 45 | 0 46 | 0 47 | 0 48 | 0 49 | 0 50 | 0 51 | 0 52 | 0 53 | 0 54 | 0 55 | 0 56 | 0 57 | 0 58 | 0 59 | 0 60 | 0 61 | 0 62 | 0 63 | 0 64 | 0 65 | -------------------------------------------------------------------------------- /RTL/GACT/test_data/ref.3.hex: -------------------------------------------------------------------------------- 1 | 0x5443435447434354 2 | 0x4741474754414743 3 | 0x4743434754544154 4 | 0x5443434747414141 5 | 0x5441544743415441 6 | 0x4343544347475443 7 | 0x4143545441544354 8 | 0x4347544347544154 9 | 0x4743544754545441 10 | 0x4747544154434741 11 | 0x5443545443474741 12 | 0x4147474743475443 13 | 0x5441434347474754 14 | 0x5454414741474147 15 | 0x4147434143475447 16 | 0x5447474754474147 17 | 0x4754434154434741 18 | 0x4341474154434341 19 | 0x4141545454544147 20 | 0x4754544154545443 21 | 0x4341475443475443 22 | 0x4347474141474343 23 | 0x4747475447414747 24 | 0x4743435447414341 25 | 0x5443474741475443 26 | 0x4743544147474141 27 | 0x4147475447434143 28 | 0x4341435443414747 29 | 0x4143544754415443 30 | 0x4147545454475441 31 | 0x4141415447474347 32 | 0x4147414743474741 33 | 0x5454434754414741 34 | 0x5443434741414141 35 | 0x4354414143414141 36 | 0x5447415441434143 37 | 0x5443474143434141 38 | 0x4141434754545454 39 | 0x5441435454434341 40 | 0x4141544743544154 41 | 0 42 | 0 43 | 0 44 | 0 45 | 0 46 | 0 47 | 0 48 | 0 49 | 0 50 | 0 51 | 0 52 | 0 53 | 0 54 | 0 55 | 0 56 | 0 57 | 0 58 | 0 59 | 0 60 | 0 61 | 0 62 | 0 63 | 0 64 | 0 65 | -------------------------------------------------------------------------------- /RTL/GACT/test_data/ref.4.hex: -------------------------------------------------------------------------------- 1 | 0x4747544354415443 2 | 0x4343415454414747 3 | 0x4754435454414141 4 | 0x4354544154544343 5 | 0x4147434354414154 6 | 0x4154435447414754 7 | 0x4741474754475443 8 | 0x4347414747544747 9 | 0x4143414147434754 10 | 0x4343474154415447 11 | 0x4147414747474741 12 | 0x4341414141475441 13 | 0x4741544141414354 14 | 0x4343474747414147 15 | 0x4343434741545441 16 | 0x4741434141545447 17 | 0x4154474141474147 18 | 0x4154545443474754 19 | 0x5454474747434754 20 | 0x4743434754434343 21 | 0x4343544343475447 22 | 0x4143474347474154 23 | 0x4741435447544154 24 | 0x4147414354414347 25 | 0x5443435454414343 26 | 0x4147434341475447 27 | 0x4354414154475454 28 | 0x4154474141434147 29 | 0x4741435447415447 30 | 0x4141544354414341 31 | 0x4754544741434154 32 | 0x4154544347544147 33 | 0x4147414354435441 34 | 0x4747414143474354 35 | 0x4341414743545454 36 | 0x4147474143475443 37 | 0x4741414743434343 38 | 0x4747545454544747 39 | 0x5447475454415443 40 | 0x4743474741414354 41 | 0 42 | 0 43 | 0 44 | 0 45 | 0 46 | 0 47 | 0 48 | 0 49 | 0 50 | 0 51 | 0 52 | 0 53 | 0 54 | 0 55 | 0 56 | 0 57 | 0 58 | 0 59 | 0 60 | 0 61 | 0 62 | 0 63 | 0 64 | 0 65 | -------------------------------------------------------------------------------- /RTL/GACT/test_data/ref.5.hex: -------------------------------------------------------------------------------- 1 | 0x4754414743474147 2 | 0x4747414343474347 3 | 0x5454414754474147 4 | 0x5443415441414354 5 | 0x4341475441414347 6 | 0x4141434347474154 7 | 0x5441474154545441 8 | 0x4743415441474354 9 | 0x4354434341475441 10 | 0x4143544743544743 11 | 0x4741434754474347 12 | 0x4141544147414347 13 | 0x4743434354544743 14 | 0x4747545447414341 15 | 0x4347544147474154 16 | 0x5447474354544143 17 | 0x4154414347414347 18 | 0x4747474154414154 19 | 0x5443414141474141 20 | 0x5443545447474143 21 | 0x4141544343435454 22 | 0x4354414754544343 23 | 0x4147544354545443 24 | 0x4741414147414354 25 | 0x4154474143434341 26 | 0x4747415441414743 27 | 0x5441434154415454 28 | 0x5441474347474141 29 | 0x4343544741434354 30 | 0x5443544354474747 31 | 0x4354414354474743 32 | 0x4743434143434347 33 | 0x4741544143434341 34 | 0x5441434347414747 35 | 0x5441474354415443 36 | 0x4743474341415454 37 | 0x4141415454545447 38 | 0x4354545441414754 39 | 0x4343434343475443 40 | 0x5447434141414347 41 | 0 42 | 0 43 | 0 44 | 0 45 | 0 46 | 0 47 | 0 48 | 0 49 | 0 50 | 0 51 | 0 52 | 0 53 | 0 54 | 0 55 | 0 56 | 0 57 | 0 58 | 0 59 | 0 60 | 0 61 | 0 62 | 0 63 | 0 64 | 0 65 | -------------------------------------------------------------------------------- /RTL/GACT/test_data/ref.6.hex: -------------------------------------------------------------------------------- 1 | 0x4143414754545441 2 | 0x4154474141434341 3 | 0x4341475447544341 4 | 0x4341415447414343 5 | 0x5443414347544347 6 | 0x4743434347474147 7 | 0x5441414743434743 8 | 0x5454544347434143 9 | 0x4741474354475447 10 | 0x4747434343414754 11 | 0x4143475441434343 12 | 0x4154474741415454 13 | 0x4354475443414341 14 | 0x4141475441544343 15 | 0x4754474141475447 16 | 0x4154434741545443 17 | 0x4143475441414754 18 | 0x4154434143414343 19 | 0x5441474141544741 20 | 0x4341474741435454 21 | 0x5447414354434141 22 | 0x5443434154434343 23 | 0x5443414754474343 24 | 0x4754474754415454 25 | 0x5454474341414347 26 | 0x4343434341435443 27 | 0x4754474347474141 28 | 0x5454414141474741 29 | 0x4341474347435443 30 | 0x4741544141544343 31 | 0x4743544143414141 32 | 0x4743475441414747 33 | 0x5454474754414147 34 | 0x5447434747414343 35 | 0x4143474343544147 36 | 0x4747474154544341 37 | 0x4347544343434743 38 | 0x5447474741434741 39 | 0x4154475443474743 40 | 0x5447474747544343 41 | 0 42 | 0 43 | 0 44 | 0 45 | 0 46 | 0 47 | 0 48 | 0 49 | 0 50 | 0 51 | 0 52 | 0 53 | 0 54 | 0 55 | 0 56 | 0 57 | 0 58 | 0 59 | 0 60 | 0 61 | 0 62 | 0 63 | 0 64 | 0 65 | -------------------------------------------------------------------------------- /RTL/GACT/test_data/ref.7.hex: -------------------------------------------------------------------------------- 1 | 0x4743544743544141 2 | 0x4141434154414154 3 | 0x5443414343545443 4 | 0x4141435441414154 5 | 0x4341474147414347 6 | 0x4743474354544341 7 | 0x4743414741435447 8 | 0x4743474147545443 9 | 0x4347414354474354 10 | 0x4141414343474141 11 | 0x4743414354414343 12 | 0x4154544743474154 13 | 0x4341414347434143 14 | 0x5441415454414741 15 | 0x4143474147544354 16 | 0x5443434143415441 17 | 0x4141415454435441 18 | 0x5441474341434754 19 | 0x5454544143544754 20 | 0x4354474147414754 21 | 0x4741544141435454 22 | 0x4343544343545441 23 | 0x4354474747474741 24 | 0x4347544143545443 25 | 0x5443474147414141 26 | 0x5441414141474341 27 | 0x4747435447434347 28 | 0x4743474347434347 29 | 0x4354415443474347 30 | 0x4347414141434747 31 | 0x4147434341544743 32 | 0x4141414741545441 33 | 0x4343544141544154 34 | 0x4754544147414343 35 | 0x4141434154435454 36 | 0x4754474743475447 37 | 0x5447415441475454 38 | 0x4354435454544347 39 | 0x4354474143545454 40 | 0x5447434141414354 41 | 0 42 | 0 43 | 0 44 | 0 45 | 0 46 | 0 47 | 0 48 | 0 49 | 0 50 | 0 51 | 0 52 | 0 53 | 0 54 | 0 55 | 0 56 | 0 57 | 0 58 | 0 59 | 0 60 | 0 61 | 0 62 | 0 63 | 0 64 | 0 65 | -------------------------------------------------------------------------------- /RTL/GACT/test_data/ref.8.hex: -------------------------------------------------------------------------------- 1 | 0x5441414747474143 2 | 0x4141434754414147 3 | 0x4143544741474743 4 | 0x4147544354414743 5 | 0x4341475447544154 6 | 0x5443544341414143 7 | 0x4354434154475447 8 | 0x4741414754474154 9 | 0x4741434754544747 10 | 0x5447474143434147 11 | 0x5447414354414743 12 | 0x4141474341544341 13 | 0x4754414741544154 14 | 0x4743414343434343 15 | 0x4347474147414143 16 | 0x5441544743545443 17 | 0x4347475441414741 18 | 0x4754544747544347 19 | 0x4147544754544741 20 | 0x4343474347474343 21 | 0x5443434147414754 22 | 0x4747474754434347 23 | 0x5441434754475441 24 | 0x5441474354474741 25 | 0x4341434747474743 26 | 0x4143475443415443 27 | 0x4341474154434354 28 | 0x5443475447545441 29 | 0x4154434343434141 30 | 0x5443414143544343 31 | 0x4347474154474741 32 | 0x4354414354414354 33 | 0x5441434143415441 34 | 0x4154434754434147 35 | 0x4747414747475454 36 | 0x4754475447414343 37 | 0x4341544747435443 38 | 0x5447435443414154 39 | 0x5447544747474754 40 | 0x4154434141474741 41 | 0 42 | 0 43 | 0 44 | 0 45 | 0 46 | 0 47 | 0 48 | 0 49 | 0 50 | 0 51 | 0 52 | 0 53 | 0 54 | 0 55 | 0 56 | 0 57 | 0 58 | 0 59 | 0 60 | 0 61 | 0 62 | 0 63 | 0 64 | 0 65 | -------------------------------------------------------------------------------- /RTL/GACT/test_data/ref.9.hex: -------------------------------------------------------------------------------- 1 | 0x5443434154474754 2 | 0x4147545443435443 3 | 0x4154474741414147 4 | 0x4143544341414143 5 | 0x4743435441544343 6 | 0x4743475441474354 7 | 0x4347434743545454 8 | 0x5447434743544143 9 | 0x5454414154544741 10 | 0x4147474143414354 11 | 0x5443474343435443 12 | 0x5443434754544354 13 | 0x4143544347414141 14 | 0x4343474747414147 15 | 0x4147414347415454 16 | 0x4147474754414754 17 | 0x4347474143544354 18 | 0x4154414754415447 19 | 0x4354434754414147 20 | 0x5447475447415447 21 | 0x4154474141544147 22 | 0x5443434754434341 23 | 0x5447435443414747 24 | 0x5454415441415441 25 | 0x5443474747544154 26 | 0x4141544154544747 27 | 0x4754545447435447 28 | 0x4143414343434341 29 | 0x4341544141474343 30 | 0x4754434143434343 31 | 0x4154474354434347 32 | 0x4343414354414747 33 | 0x4743545441414143 34 | 0x4354544343475447 35 | 0x4754434343474354 36 | 0x4147434743434754 37 | 0x5447544354414754 38 | 0x4741544341414747 39 | 0x5441434141434354 40 | 0x4154435441474143 41 | 0 42 | 0 43 | 0 44 | 0 45 | 0 46 | 0 47 | 0 48 | 0 49 | 0 50 | 0 51 | 0 52 | 0 53 | 0 54 | 0 55 | 0 56 | 0 57 | 0 58 | 0 59 | 0 60 | 0 61 | 0 62 | 0 63 | 0 64 | 0 65 | -------------------------------------------------------------------------------- /RTL/GACT/test_data/ref.hex: -------------------------------------------------------------------------------- 1 | 0x0000000000000041 2 | 0 3 | 0 4 | 0 5 | 0 6 | 0 7 | 0 8 | 0 9 | 0 10 | 0 11 | 0 12 | 0 13 | 0 14 | 0 15 | 0 16 | 0 17 | 0 18 | 0 19 | 0 20 | 0 21 | 0 22 | 0 23 | 0 24 | 0 25 | 0 26 | 0 27 | 0 28 | 0 29 | 0 30 | 0 31 | 0 32 | 0 33 | 0 34 | 0 35 | 0 36 | 0 37 | 0 38 | 0 39 | 0 40 | 0 41 | 0 42 | 0 43 | 0 44 | 0 45 | 0 46 | 0 47 | 0 48 | 0 49 | 0 50 | 0 51 | 0 52 | 0 53 | 0 54 | 0 55 | 0 56 | 0 57 | 0 58 | 0 59 | 0 60 | 0 61 | 0 62 | 0 63 | 0 64 | 0 65 | -------------------------------------------------------------------------------- /RTL/GACT/test_data/ref_320.txt: -------------------------------------------------------------------------------- 1 | AACCCTGAGGGAATGTTAGCTGGGAAGGTAAGGTCAAATTGTGATTCCTAGAAGCGAAGGTGCGGGCCAGCAAGCTGCTCCGGTGCGCGGCTAAGGGTCCGGTTGGGGCATGGTGCGCGAATGATTTTATCCTTCGAAATAGATCGCTTCAGGCGGGGACAGGTTGGGTACACGACTCCTCGATGTCCCTGGGGGGACGCCCATTAGACCAGGTACCAGACCGTAAAAATTCTCAAGACTGTGCACGACAAGGTAGTCACATCGTCAAGTCCACCTTAGTGTTCTTAAAAGGGCCCTGGTCACCCCCTAGGATAATGTTA 2 | CCGGTTGTAAGAGGGTTGAGCAGTTTAACGAGAGGAGGCCCGCTATCAATGAGTTTGAGTAGGGAATGCTGATGGGGTATCACTGTGAGCCATAGGTGGACCTGAACCGACGAACACGATTATCTCTAGCCTCCCGTCCCGATAATCCACTGGACGTCGGTATGCCTCGGGTACTGCGGATAATCATATACGGGGTAAACGAGGAGAGGTCCGCGTCAGTCTTAATCATGATTGGCTATACATACCTTAGTGTAATACAAAATTCTATCAGATTCGGCCAGTTTTACAAGGTGGGGTCCTATCCACAAAGTTCAAGCATA 3 | TCCGTCCTCGATGGAGTATTGCCGAAAGGCCTATACGTATCTGGCTCCTCTATTCATATGCTGCATTTGTCGAGCTATGGAGGCTTCTCTGCGGGATGGGCCATGAGAGATTGTGCACGAGAGTGGGTAGCTACTGACCTAGACGATTTTAACTTTATTGCTGCTGACCCGAAGGCGGAGTGGGACAGTCCGCTGAGGCTAAGGATCGCACGTGGAGGACTCACCTATGTCAATGTTTGAGCGGTAAAAGGCGAGAAGATGCTTAAAAGCCTAAACAATCCACATAGTAACCAGCTTTTTGCAAACCTTCATTATCGTAA 4 | CTATCTGGGGATTACCAAATTCTGCCTTATTCTAATCCGATGAGTCTACTGTGGAGGGTGGAGCTGCGAACAGTATAGCCAGGGGAGAATGAAAACTCAAATAGGAAGGGCCATTAGCCCGTTAACAGGAGAAGTATGGCTTTATGCGGGTTCCCTGCCGGTGCCTCCTAGGCGCATATGTCAGGCATCAGACCATTCCTGTGACCGATTGTAATCGACAAGTAGTAGTCAGACATCTAATACAGTTGGATGCTTAATCTCAGATCGCAAGGTTTCGAACCTGCAGGACCCCGAAGGGTTTTGGCTATTGGTTCAAGGCG 5 | GAGCGATGGCGCCAGGGAGTGATTTCAATACTGCAATGACTAGGCCAAATTTAGATTCGATACGATGACCTCCGTCGTCAGCGTGCAGGCAGATAACGTTCCCGACAGTTGGTAGGATGCCATTCGGTGCAGCATATAATAGGGAAGAAACTCAGGTTCTTTCCCTAACCTTGATCCTTTCTGATCAGAAAGACCCAGTACGAATAGGTTATACATAAGGCGATTCCAGTCCGGGTCTCTCGGTCATCGCCCACCGACCCATAGGGAGCCATCTATCGATTTAACGCGGTTTTAAATGAATTTCCTGCCCCCGCAAACGT 6 | ATTTGACAACCAAGTAACTGTGACCCAGTAACGCTGCACTGAGGCCCGCGCCGAATCACGCTTTGTGTCGAGTGACCCGGCCCATGCATTAAGGTAACACTGTCCCTATGAAGTGAAGTGCTTAGCTATGAATGCACCACACTAAGTAAGATTTCAGGACAACTCAGTCCCTACCTCCGTGACTTTATGGTGGCAACGTTCTCACCCCAAGGCGTGAGGAAATTCTCGCGACCCTAATAGAAACATCGGGAATGCGGAATGGTTCCAGGCGTGATCCGCAACTTAGGGCGCCCTGCAGCAGGGTCGGCTGTACCTGGGGT 7 | AATCGTCGTAATACAACTTCCACTTAAATCAAGCAGAGACACTTCGCGGTCAGACGCTTGAGCGTCGTCAGCAAGCCAAACCATCACGTAGCGTTACACGCAACAGATTAATTCTGAGCAATACACCTATCTTAAATGCACGATTGTCATTTTGAGAGTCTTCAATAGATTCCTCCAGGGGGTCCTTCATGCAAAGAGCTACGAAAATGCCGTCGGGCCGCGCGGCGCTATCGGCAAAGCCGTACCGAATTAGAAATATAATCCCCAGATTGTTCTACAAGTGCGGTGTTGATAGTGCTTTCTCTTTCAGTCTCAAACGT 8 | CAGGGAATGAATGCAACGGAGTCACGATCTGATATGTGACCAAACTCTGTGTACTCTAGTGAAGGGTTGCAGGACCAGGTCGATCAGTACTACGAATATAGATGCCCCCACGCAAGAGGCCTTCGTATAGAATGGCGCTGGTTGAGTTGTGACCGGCGCCTGAGACCTGCCTGGGGATGTGCATAGGTCGATCGGGGCACCTACTGCATCCTAGACATTGTGCTAACCCCTACCTCAACTAGGTAGGCTCATCATCATACACATGACTGCTATTGGGAGGCCAGTGTGCTCGGTACTAACTCGTTGGGGTGTAGGAACTA 9 | TGGTACCTCTCCTTGAGAAAGGTACAAACTCACCTATCCGTCGATGCGTTTCGCGCCATCGCGTAGTTAATTTCACAGGACTCCCGCTTCTTGCCTAAAGCTCAGAAGGGCCTTAGCAGATGATGGGATCTCAGGCGTATGATAGAATGCTCGTAGTGGTGATAAGTAACCTGCCTGGACTCGTATAATATTTATGGGCTGGTTATAAGTCGTTTGACCCCACACCGAATACCCCCACTGGCCTCGTAGGATCACCCAAATTCGGTGCCTTCTCGCCCTGTGCCGCGATGATCTGTGGAACTAGTCCAACATCAGATCTA 10 | TATGTGGGACCGCCTGAATAGATAGCGCGCACAGGTCCGGGGCGCTTCCGTGTAGGTCCGACCTGCGCTTCGTAGTGATTTCTATGGATCACACAGTAAAAGCTGAGCCCGAAAAGATGGACCCTGCCGAATACCGACACAAGTGGTGCGTTGAGATCCATTTAGGCGAGCACTCCCTGACCAGGCGGAAATACAGTCTGCTAGCAATCAATAGACGAATGCCGTGGCCATGAATTGACCTCACATTCTGCCATCTGAAACTATCCATATTTCTGCAACAACCCCTGATGCTGACTAGGGTCCGAGGCGTAGCTGATAAT 11 | -------------------------------------------------------------------------------- /RTL/GACT/test_data/test_align.txt: -------------------------------------------------------------------------------- 1 | AACCCTGAGGG--AATGTTAGCTGGGAAGGT-AAGGTCAAATTGTGATTCCTAGAAGCGAAG-GT-GCGGGCCAGCAA-GCTGCT--CCGGTGCGCGGCTAAGGGT--CCGGTTGGGGCATGGTGCGCGAATGATTTTATCCTTCG--AAA-TAGA-TCGCTTCAGGCGGGGACAGGTTGGGTACACGA-CTCCT-CGA-TGTCCCTGGGGGGACGCCCATTAGACC-AGG-TACCAGACCGT-AAAAATTCTCAAGA-CTGTG-CAC-GACAA-GG-TAG-TCACA-TCGTCAAGTC-CACCT-TAGTGTTCTTAAAAGGGCCCTGG 2 | AACCCTGAGGGGGAAT-TTAGCTGGGA-GGTTAAGG-CAAATTGTGATTCCTAGAAGCGAAGCGTTGCGGGC-AGCAACGCTGCTTTCCGGTGCGAGGC-AAGGGTTTCCGATTGTGGCATGG-GCGCTAATGATTTTATCCTTCGGGAAAATAGAATCGCTTCAGG-GGGAACAGGTTGGGTACACGAGCTCCTGCGAATGTCC-TGTGGGGA-GCCCATTAGACCCAGGATACCAGACCGTTAAAAATTCTCAAGAACCGTGGCCCAGACAAAGGGTAGATCACAATC-TCAAGTCGCACCTCTAATGTTCTAAAAAAGGCCCTGG 3 | Total score: 228 4 | CCGGTTGTAAGAGGGTTGAG-CAGT-TTAACGAGAGG-AGGCCCGCTATCAATGA-G-TTTG-A-GT-AGGGAATGCTGATGGGGTATCAC-TGTGAGC-CATAGGTGGACCTGAACCGACGAACACGATTATCTCTAG-CCTCCCGTCCCGATAATCCACTGGACGTCG-GTATGCCTCGGGTACTGCGGATAATCA-TATA-CGGGGTAAACGAGGAGAG-GTCCGCGTCAGTCTTAATCATGATTGG--CTATA-CAT-ACCTTAGTGT-AATA-CAAAA-TTCTATCAGATTCGGCC-AGTTTT--ACAAGGTGGG-GTCCTAT-CC 5 | CCGGTTGAAAGAGGGTTGAGTCAGTGTTAACGAGAGGGAGGCCCGCT-TCAATGAAGGTTTGGAAGTGAGGGAATG-TGATGGGG-ATCACATG-GAGCACA-AGATG-ACCTGAAC-GACGAACACGTTTATCTCTAGGCCTCCCGTCCCGAGAATCCACTGGACGTCGCGTATGCCTCGGGTACTGCGGA-AATCAATATAACGGGGTAGA-GAGG-GAGTGTCCGCGTCAGTCTTAATCATGATTGGTGCTATAACATTACCTTAGTGTTAATAACAAAAATTCCATCAGATTCGGCCTAGTTTTGTACAAGGTGGGCGTACT-TACC 6 | Total score: 241 7 | TCCGTCCTCGATGGAGTATTGCCGAAA-GGCCTATACGTATCTGGCTCCTCTATTCAT-A-TGCTGCATTTGTCGAGCTATGGAGGCTTCTCTGCGGGA-TGGG-CCATGAGAGATTGTGCA-CGAGAGTGGG-TAGCTACTGA-CCTAGA-C-GATTTT---AACTTT--ATTGCTGCTGAC-CCGAAGGCGGAGTGG-GAC-AGTCC-GC-TGAGGCTAAGGATC--GCACGTGGAGGACTC-ACCTA-TGTCAATGTTT-GAGCGG-T-AAAA-GGCGAGAAGATGCTTAAAAGCCTAAACAA-TCCACATAGTAACCAGCTTTTTGC 8 | TCCGTC-TCGATGGA-TATTGCCGAAAAGGCCCATACGTATCTGGCTCCTCTATTCATTAATGCTGCATGTGTCGAGC-ATGGAGGCTTCT-TCCGCGAATGGGGCCATG-GAGATTGTGCAACGAGACTGGGGTAGCTACTGAACCTAGATCAGTTTTTTTTAACTTTTTATTGC-GCTGAATCCGAAGGTGGAGTAGCGACCAGTCCCGCCTGAGGCTAAGGAACCCGCACGTGGAG-ACTCTACCTAATGTCAATGTTTTGAGCGGGTTAAAAAGGCGAGAA-AT-CTTAAAAGCCTAAACAAATCCACAT-GTAACCAGCTTTT-GC 9 | Total score: 231 10 | CTATCTGGG--GATTACCAAATTCTGCCTTATTCTAATCCGATGAGTCTACT-GTGGAGGG---TGGAGCTGC-GAACAGTATAGCCAGGGGAGAATGAAAA-CTCAAA-TAGGA-AGGGCCATTAGCCCG---TTAA--CAGGAGAAGTA-TGGCTTTAT-GCGGGTT-CCC-TGCCGGTG-CCTCCTAGGCGCATATGTCAGGCAT-CAGACCATTCCTGTGACCG--ATTGTAATCGACAA-GTAG-TAGTCA-GA-CATCT-A-ATACA-GTT-GG-ATGCTTAATCTCAGATC-GCAAGGTTTCGAACC-T-GCA-GGACCCC 11 | CTATCTGGGCTGATTAC-AA-TTC-GCCTTATCCTAATCCGATGAGTCTACTTGTGGAGGGGGGTGGAGCTCCCGAACAGTATAGCCAGGGGAGAATGAAAAACTCAAAATAGGATAGGGCCATAAGCCCGCGGTTAAAACAGGAGAAGTAATGGCTTTATAGCGGGTTTCCCCTGCCG-TGGCCTCC-AGGCGCATATGTCAGGCATTCAGACCATTCCTGTGACCGCGATTGTAATCGACAAAGTAGGTAGTCAAGAACA-CTTAGATACAAGTTTGGTATGCTTAAT-TCAGATCAGCA-GGTTTCGAACCCTTGCAAGGACCCC 12 | Total score: 234 13 | GAGCGATGGCGCC-AGGGAGTGATTTC-AATACTGCAATGACTAGGCCAAATTTAGATTCGA-TACGATG-ACC-TCCG-TCGTC-AGCG-TGCAGGCAGATAACGTTCCC-GACAGT-TGGTA-GGATGCC--ATTCGGTGCAGCATAT-AATAGGGAAGAAACTCAGGTTCTTTCCCTAACCTTGATCCTTTCT-GATC--A-GAAAGACCCAGTACG-AATAGGTTATACATAAGG-CGATT-CCAGTCCGGGTCTCTCGGTCATC-GCCCACCGACCCATA-GGGAGCCATCTATC-GATTTAACGCGGTTTT-AAATGAATTTCC 14 | GAGCTATGGCGCCCAGCGAGTGATTTCCAATA-TGCAATGACTAGTCCAAATTTAGATTCGAATACGATGTACCCTCCCCTCGTCTAGCGATGCAGGCAG-TAACGTTCCCCGAC-GAATGGTAAGGATGCCCCATTCGGTGCAGCATATTAATAGG-AAGAAACTCAGGTTCTT-CCCTAACCTTGATC-TTTCTTGATCTCAAGAAAGACCCA-TACGGAATAGGTTATACATAAGGGCGATTTCCAGTC-GGGCCTCTCGGTCATCCGCCCACCGAC--ATAAGGGAGCCATCTATCTGATT-AACGCGGTTTTTAAATGAATTTCC 15 | Total score: 246 16 | ATTTGACAACCAAGTAACT-GTGACCCAGTA-ACG-CTGCACTGAGGCCCGCGCCGAATCAC-GCTTTGTGTCGAGTGACCCGGCCCA-TGCATTAA-GGTAACACTG-TCCCTATGAA-GTGAAGTGCTT-AG-CTAT-GAA-TGCACCACACTAAGTAAGATTT-CAGGA-CAACTCAGTCCCTAC-CTCCGTG-A--CTTTAT-GG-TGGCAACG-TTCTC-ACCCCAA-GGCGTGAGG-AAATTCTCGCG-ACCCT-AATAGAAACATCGGGAATG-CGGAATGGTT-CCAGGCGTGATCCG-CAACTTAGGGCGCCCTGCAG-CAGGGTCGG 17 | ATT-GACA-CCAAGAAACTAGTGACCCAGTATAAGGCTGCACTGAGGCC-GCGC-GAATCACCGCTT-GTGTCGAGTGACCCGGCCCAATGCATTAACGGTATCACTGGTCCCTATGAAAGT-AAGTGCTTTAGGCTATTGAACTGCACCACACTA-GTA-GATTTTCAGGAACAACTCAG-CCCTACTCTCTGTGGAAACTTT-TAGGCTGGCAACGGTTCTCGACCCCAAAGGCGTGAGGGAAATT-TCGCGGACCCTTAATAGAAACATCGGGAATGGCGGAATGGTTGCCAG-C-TGA-CCGGCAACT-AGG-CGCC-TGCAGACAGGGTCGG 18 | Total score: 235 19 | AATCGTC-GTAATAC--AACTTCCACTT-AAAT-CAA-GCAG--AGACACTT-CGCGGT-CAGACGCTTGAG-CGTCGTCAGCAAGCCAAACCATC-ACGTAGCGTTA-CACGCAA-CA-GATTAATTCTGAGCAATACACCTATCTTAAATG-CACGATTG-TCATTTT-G-AG-AGTCTTCAATAGATTCCT-CCAGGGGG-TCCTTCATGCAAAGAGCT-ACGAAAATGCCGTCGG-G-CCGCGCGG-C-GCTATCGGCAAAGCCGTACCGAA-TTAGA-AATATAATCCCC-AGATTGT-T-CTACAAGT-G-CGGT 20 | AATCGTCCGTAATACCCAACTTCCACTTTAAATTCCACGCAGGGAGACACTTTCCCGGTTCAGACGCTTGAGGCGTCGTCAGCAAGCCAAACCATCCACGTAGCGTTAACACGCAAACATGATTA-TTCTGAGCAAT-CACCTATCTTAA-TGGCACGATTGGTCATTTTTGTAGGAGTCTTCAAAAGATTCCTACCAGGGGGGTCCTTCATGCAACGAGCTTACGAAAATCCCGTCGGCGACCGCGCGGGCTGCTATCGGCAAAGCCGTACCGAAATTAGATAATAGAATCCCCCAGATTGTGTTCTACAAGTTGACGGT 21 | Total score: 235 22 | CAGGG-AA-T-GAATGCAAC-GGAGTCACGATC-TGATATGTGACCAAACTCT-GTG-TACTC---TAGTGAAGGGTTGCAG-GA--CC-AGGTCGATCAGTACTACG-AA-TATAGATGCCCCC--ACGC-AAGAGGCCTTCGTATAGAATGGCGCTGGTTGAGTT-GTGACC-GGCGCCTGAGACCTGCCTGGGGATGTGCAT-AGGTCGATCGGGG-CACCT--ACTGCATCCTAGACATTGTGCTAACCCCTACCTCAACTAGGTA-GGCTCATCATCATACAC-AT-GAC-TGCTATTGGGAG-GCCAGTGTGCTCGGTACTAACTCGTT 23 | CAGGGCAAATTGAATGCAACCGGAGTCACGATCCT-ATATGT-ACCAA-CTCTTGTGGTACTCGCGTAGTGCAGGGTTGCAGAGAAACCGAGGTCGATCAGTACTACGGAAATATAGATGCCCCCTCACGCTAAGGGGCCTTCGTATTGAATGGCGCTGGGTGAGTTTGTGACCCGGC-CCTGAG-CCTGCCTGGGGATG-GC-TGAGGACGATCGGGGGCACCTTTACTG-ATCCTAGA-ATTGTGCTA-CCC-TACCTCAACTAGGTAAGGCTCAT-ATCAT-CACCATCGCCCTGCTATTGAG-GCGCCAGTGTGCTCGGTAC-AACTCTTT 24 | Total score: 229 25 | TGGTA-CCTCTCCTT-G--A-G-AAAGGTACAAACTCACCTATCCGTCGATGCGTTTCGCGCCATCGCGT-A-GTTAAT-TT-C-ACAGGACTCCCGCTTCTTGCCTAAAGCTCAG-AAGG-GCCTTAGCAGATGATGGGAT-CTCAGG-CGT-ATGATAGAATGC-TCGTAGT-GGTGATAAGTAACCTGCCTGGACTCGTATAATATTTATGGGCTGGTTATAA-GT-CGTTTGACCCC-A-C-ACC-GAATACCCCCACTGGCCTCGTAGGATCACCCAAATTCGGTGCC-TTCTCGCCC--TGTGCCGCGATGATCTGTGGAACT 26 | TGGTATCCTCTCCTTTGGCAAGGAAAG-TACAAACTCACCTATCCGTCGATTCGTTT-GCGCCATCGCGTTATGTTAAAATTGCCACAGGACTCCCGCTTCTTGCCTAAAGCT-AGGAAGGCGCCTTAGCAGAT-ATGGGATTCTCAGGGCGTGATGATAGAATCCCTCGTAGTAGGTGATAAGTA-CCTGCCTGGACTC-TATAATATTTATGGGCTGGTT-TAAAGTTCGTTT-ACCCCCAACCACCCGAATACCCC-ACTGGCCTCGTAGGATCACCCAA-TTCGGTGGCGTTCTCGCCCCCTGTGCCGCGATGATCT-TGGAACT 27 | Total score: 245 28 | TAT--GTGGG-ACC-G-CCTGAATAGATAGCGCGCACAGGTCCGGGGCGCTTCCGTGTAGGTCCGACCTGCGCTTCGT-AGTGATTTCTATGGATCACACAGTAAAAGCTGAGCCCGAAAAGATGGACCCTGCCGAA-TACCGACACAAGTGGTGCGTTGAGATCC--ATTT-AGGC-GAGCACTCCCTGACCAGGCGGAAATACAGT-CTGCTAGCAATCAATAGACGAATGCCG-TGGCCATGA-ATTGACC-TC-ACATTCTGCCATCTGAAACTA-TCCATATTTCTGCAACAACCCCTGATGCTGACTAGGGTCCGAGGCGTAGCT 29 | TATTCGTGGGGACCCGGCCTGA-TAGATAGCGC-CACAGGTCCGGGGCGCTTCCGT-TAGGTCCGACCTGCGCTTCGTTAGTGATTTCTATGGATCACACAGTAAA-GCTGAGCCCGAAAAGATGGACC--GC-GAAGTACCGACACTACTGGTGCGTTGAGATCCCGATTTTAGCCCGAGCACTCCCTGAC-AGGCGGAAATGCAGTGCTGCTAGCAATCAATAG-CGAATGCCGGTGGC-ATGACATTGACCGTCCAAATTCTGCCATCTGAA-CTAGTCCATATTTCTGCA-CAACCCCTGATGCTGACTAGGGTCCGAGGCGTAGCT 30 | Total score: 263 31 | -------------------------------------------------------------------------------- /software/.gitignore: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # This .gitignore file was automatically created by Microsoft(R) Visual Studio. 3 | ################################################################################ 4 | 5 | /.vs 6 | *.user 7 | /packages 8 | /x64 9 | /DarwinAvx/packages 10 | /DarwinAvx/x64 11 | *.vspx 12 | -------------------------------------------------------------------------------- /software/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required (VERSION 3.8) 2 | 3 | project (Darwin) 4 | 5 | #set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /bigobj") 6 | set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -std=c++11 -O4 -mbmi2 -msse4.2 -mavx2") 7 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -O4 -mbmi2 -msse4.2 -mavx2") 8 | 9 | find_package(ZLIB REQUIRED) 10 | find_package (Threads) 11 | 12 | # To find and use zlib 13 | find_path(ZLIB_INCLUDE_DIR zlib.h) 14 | include_directories(${ZLIB_INCLUDE_DIR}) 15 | 16 | # To find and use tbb 17 | include(${TBB_ROOT}/cmake/TBBBuild.cmake) 18 | 19 | tbb_build(TBB_ROOT ${TBB_ROOT} CONFIG_DIR TBB_DIR MAKE_ARGS tbb_cpf=1) 20 | 21 | find_package(TBB REQUIRED tbbmalloc tbbmalloc_proxy tbb_preview) 22 | 23 | add_executable(Darwin 24 | Darwin_apply.cpp 25 | Darwin_apply.h 26 | Darwin_reflection.h 27 | Darwin_types.cpp 28 | Darwin_types.h 29 | DRAM.cpp 30 | DRAM.h 31 | Index.cpp 32 | Index.h 33 | ntcoding.cpp 34 | ntcoding.h 35 | ConfigFile.cpp 36 | ConfigFile.h 37 | Chameleon.cpp 38 | Chameleon.h 39 | seed_pos_table.cpp 40 | seed_pos_table.h 41 | Processor.cpp 42 | Processor.h 43 | graph.h 44 | extender.cpp 45 | filter.cpp 46 | printer.cpp 47 | seeder.cpp 48 | sender.cpp 49 | main.cpp) 50 | 51 | target_link_libraries(Darwin PRIVATE ${TBB_IMPORTED_TARGETS}) 52 | target_link_libraries(Darwin PRIVATE ZLIB::ZLIB) 53 | target_link_libraries (Darwin PRIVATE ${CMAKE_THREAD_LIBS_INIT}) 54 | -------------------------------------------------------------------------------- /software/Chameleon.cpp: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Chameleon.cpp 4 | * 5 | * Copyright (C) 2002-2004 René Nyffenegger 6 | * 7 | * This source code is provided 'as-is', without any express or implied 8 | * warranty. In no event will the author be held liable for any 9 | * damages 10 | * arising from the use of this software. 11 | * 12 | * Permission is granted to anyone to use this software for 13 | * any purpose, 14 | * including commercial applications, and to alter it and 15 | * redistribute it 16 | * freely, subject to the following restrictions: 17 | * 18 | * 1. The origin of this source code must not be 19 | * misrepresented; you must not 20 | * claim that you wrote the original source 21 | * code. If you use this source code 22 | * in a product, an acknowledgment in the 23 | * product documentation would be 24 | * appreciated but is not required. 25 | * 26 | * 2. Altered source versions 27 | * must be plainly marked as 28 | * such, and must not be 29 | * misrepresented as being 30 | * the original source 31 | * code. 32 | * 33 | * 3. This notice may 34 | * not be removed or 35 | * altered from any 36 | * source distribution. 37 | * 38 | * René Nyffenegger 39 | * rene.nyffenegger@adp-gmbh.ch 40 | * */ 41 | 42 | #include 43 | #include 44 | #include 45 | 46 | #include "Chameleon.h" 47 | 48 | Chameleon::Chameleon(std::string const& value) { 49 | value_=value; 50 | } 51 | 52 | #include 53 | 54 | Chameleon::Chameleon(const char* c) { 55 | value_=c; 56 | } 57 | 58 | Chameleon::Chameleon(double d) { 59 | std::stringstream s; 60 | s< 45 | 46 | class Chameleon { 47 | public: 48 | Chameleon() {}; 49 | explicit Chameleon(const std::string&); 50 | explicit Chameleon(double); 51 | explicit Chameleon(const char*); 52 | 53 | Chameleon(const Chameleon&); 54 | Chameleon& operator=(Chameleon const&); 55 | 56 | Chameleon& operator=(double); 57 | Chameleon& operator=(std::string const&); 58 | 59 | public: 60 | operator std::string() const; 61 | operator double () const; 62 | private: 63 | std::string value_; 64 | }; 65 | 66 | #endif 67 | -------------------------------------------------------------------------------- /software/ConfigFile.cpp: -------------------------------------------------------------------------------- 1 | #include "ConfigFile.h" 2 | 3 | #include 4 | 5 | std::string trim(std::string const& source, char const* delims = " \t\r\n") { 6 | std::string result(source); 7 | std::string::size_type index = result.find_last_not_of(delims); 8 | if(index != std::string::npos) 9 | result.erase(++index); 10 | 11 | index = result.find_first_not_of(delims); 12 | if(index != std::string::npos) 13 | result.erase(0, index); 14 | else 15 | result.erase(); 16 | return result; 17 | } 18 | 19 | ConfigFile::ConfigFile(std::string const& configFile) { 20 | std::ifstream file(configFile.c_str()); 21 | 22 | std::string line; 23 | std::string name; 24 | std::string value; 25 | std::string inSection; 26 | int posEqual; 27 | while (std::getline(file,line)) { 28 | 29 | if (! line.length()) continue; 30 | 31 | if (line[0] == '#') continue; 32 | if (line[0] == ';') continue; 33 | 34 | if (line[0] == '[') { 35 | inSection=trim(line.substr(1,line.find(']')-1)); 36 | continue; 37 | } 38 | 39 | posEqual=line.find('='); 40 | name = trim(line.substr(0,posEqual)); 41 | value = trim(line.substr(posEqual+1)); 42 | 43 | content_[inSection+'/'+name]=Chameleon(value); 44 | } 45 | } 46 | 47 | Chameleon const& ConfigFile::Value(std::string const& section, std::string const& entry) const { 48 | 49 | std::map::const_iterator ci = content_.find(section + '/' + entry); 50 | 51 | if (ci == content_.end()) throw "does not exist"; 52 | 53 | return ci->second; 54 | } 55 | 56 | Chameleon const& ConfigFile::Value(std::string const& section, std::string const& entry, double value) { 57 | try { 58 | return Value(section, entry); 59 | } catch(const char *) { 60 | return content_.insert(std::make_pair(section+'/'+entry, Chameleon(value))).first->second; 61 | } 62 | } 63 | 64 | Chameleon const& ConfigFile::Value(std::string const& section, std::string const& entry, std::string const& value) { 65 | try { 66 | return Value(section, entry); 67 | } catch(const char *) { 68 | return content_.insert(std::make_pair(section+'/'+entry, Chameleon(value))).first->second; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /software/ConfigFile.h: -------------------------------------------------------------------------------- 1 | #ifndef __CONFIG_FILE_H__ 2 | #define __CONFIG_FILE_H__ 3 | 4 | #include 5 | #include 6 | 7 | #include "Chameleon.h" 8 | 9 | class ConfigFile { 10 | std::map content_; 11 | 12 | public: 13 | ConfigFile(std::string const& configFile); 14 | 15 | Chameleon const& Value(std::string const& section, std::string const& entry) const; 16 | 17 | Chameleon const& Value(std::string const& section, std::string const& entry, double value); 18 | Chameleon const& Value(std::string const& section, std::string const& entry, std::string const& value); 19 | }; 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /software/DRAM.cpp: -------------------------------------------------------------------------------- 1 | #include "DRAM.h" 2 | #include 3 | 4 | #include "tbb/scalable_allocator.h" 5 | #include "tbb/tbb.h" 6 | 7 | DRAM::DRAM() 8 | : size(4ull * 1024ull * 1024ull * 1024ull), 9 | referenceSize(0) 10 | { 11 | 12 | buffer = (char*)scalable_aligned_malloc(size, 64); 13 | } 14 | 15 | 16 | DRAM::~DRAM() 17 | { 18 | scalable_aligned_free(buffer); 19 | } 20 | -------------------------------------------------------------------------------- /software/DRAM.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #define WORD_SIZE 128 5 | 6 | class DRAM 7 | { 8 | public: 9 | char* buffer; 10 | std::size_t size; 11 | 12 | std::size_t referenceSize; 13 | std::size_t bufferPosition; 14 | public: 15 | DRAM(); 16 | ~DRAM(); 17 | }; 18 | 19 | -------------------------------------------------------------------------------- /software/Darwin.bond: -------------------------------------------------------------------------------- 1 | namespace Darwin 2 | 3 | enum Application 4 | { 5 | Hardware_Id = 0x685753, // SWh 6 | Software_Id = 0x735753, // SWs 7 | Version = 1 8 | } 9 | 10 | enum Function 11 | { 12 | InitializeScoringParameters = 1, 13 | InitializeDRAM = 2, 14 | WaitForWrites = 3, 15 | GACTMessageDRAM = 4 16 | } 17 | 18 | // TODO: Assign Magic codes 19 | enum Magic 20 | { 21 | InitializeScoringParameters = 1, 22 | InitializeDRAM = 2, 23 | WaitForWrites = 3, 24 | GACTMessageDRAM = 4 25 | } 26 | 27 | using Score = int32; 28 | using Addr = uint64; 29 | using TileSize = uint16; 30 | using MaxTBSteps = uint16; 31 | using TileScore = uint32; 32 | //using Sequence = blob; 33 | using Sequence = vector; 34 | using BatchSize = uint8; 35 | 36 | enum Status 37 | { 38 | OK = 0, 39 | InvalidData = 1 // validation rule(s) failed 40 | } 41 | 42 | struct AlignmentScoringParams 43 | { 44 | // Scoring matrix is symmetric 45 | 0: Score sub_AA = 1; 46 | 1: Score sub_AC = -1; 47 | 2: Score sub_AG = -1; 48 | 3: Score sub_AT = -1; 49 | 50 | 4: Score sub_CC = 1; 51 | 5: Score sub_CG = -1; 52 | 6: Score sub_CT = -1; 53 | 54 | 7: Score sub_GG = 1; 55 | 8: Score sub_GT = -1; 56 | 57 | 9: Score sub_TT = 1; 58 | 59 | 10: Score sub_N = 0; 60 | 61 | 11: Score gap_open = -1; 62 | 12: Score gap_extend = -1; 63 | 64 | 13: Score long_gap_open = -1; 65 | 14: Score long_gap_extend = -1; 66 | } 67 | 68 | struct AlignmentScoringParamsResponse 69 | { 70 | 0: Status status = OK; 71 | } 72 | 73 | struct InitializeDRAMMessage 74 | { 75 | 0: Addr start_addr; 76 | 1: uint16 num_bytes; 77 | 2: Sequence data; 78 | } 79 | 80 | struct InitializeDRAMMessageResponse 81 | { 82 | 0: Status status = OK; 83 | } 84 | 85 | struct WaitForWritesMessage 86 | { 87 | 0: int32 start = 1; 88 | } 89 | 90 | struct WaitForWritesResponse 91 | { 92 | 0: Status status = OK; 93 | } 94 | 95 | struct AlignmentInputFieldsDRAM 96 | { 97 | // 7-6: unused, 5: Do traceback, 4: Reverse ref, 3:Complement ref, 2: Reverse query, 1: Complement query, 0: Align from end 98 | 0: uint8 align_fields; 99 | 100 | 1: uint16 index; 101 | 102 | 2: Addr ref_bases_start_addr; 103 | 3: Addr query_bases_start_addr; 104 | 105 | 4: TileSize ref_size; 106 | 5: TileSize query_size; 107 | 108 | 6: MaxTBSteps max_tb_steps = 512; 109 | 110 | 7: TileScore score_threshold = 0; 111 | } 112 | 113 | struct AlignmentResult 114 | { 115 | 0: BatchSize index; 116 | 1: TileScore score; 117 | 118 | 2: TileSize ref_offset; 119 | 3: TileSize query_offset; 120 | 121 | 4: TileSize ref_max_pos; 122 | 5: TileSize query_max_pos; 123 | 124 | 6: TileSize total_TB_pointers; 125 | 126 | 7: vector TB_pointers; 127 | 128 | 8: Status status = OK; 129 | } 130 | 131 | struct BatchAlignmentInputFieldsDRAM 132 | { 133 | 0: uint8 do_traceback; 134 | 1: vector requests; 135 | } 136 | 137 | struct BatchAlignmentResultDRAM 138 | { 139 | // batch of results 140 | 0: vector results; 141 | // 1: Status status = OK; 142 | } 143 | 144 | -------------------------------------------------------------------------------- /software/Darwin.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.28010.2046 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Darwin", "Darwin.vcxproj", "{7003B7B2-7B3D-446B-A3C0-A3460D4F164F}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Release|x64 = Release|x64 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {7003B7B2-7B3D-446B-A3C0-A3460D4F164F}.Debug|x64.ActiveCfg = Debug|x64 15 | {7003B7B2-7B3D-446B-A3C0-A3460D4F164F}.Debug|x64.Build.0 = Debug|x64 16 | {7003B7B2-7B3D-446B-A3C0-A3460D4F164F}.Release|x64.ActiveCfg = Release|x64 17 | {7003B7B2-7B3D-446B-A3C0-A3460D4F164F}.Release|x64.Build.0 = Release|x64 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {3FEA54D1-A2E2-417E-8DEF-3371433A0BCF} 24 | EndGlobalSection 25 | GlobalSection(Performance) = preSolution 26 | HasPerformanceSessions = true 27 | EndGlobalSection 28 | EndGlobal 29 | -------------------------------------------------------------------------------- /software/Darwin.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | x64 7 | 8 | 9 | Release 10 | x64 11 | 12 | 13 | 14 | {7003B7B2-7B3D-446B-A3C0-A3460D4F164F} 15 | Win32Proj 16 | Darwin 17 | 10.0.17134.0 18 | 19 | 20 | 21 | Application 22 | true 23 | v141 24 | Unicode 25 | false 26 | 27 | 28 | Application 29 | false 30 | v141 31 | true 32 | Unicode 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | true 48 | ClCompile 49 | 50 | 51 | false 52 | ClCompile 53 | 54 | 55 | 56 | /bigobj %(AdditionalOptions) 57 | 58 | 59 | Level3 60 | Disabled 61 | _DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;BOOST_ALL_NO_LIB;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES;_ENABLE_ATOMIC_ALIGNMENT_FIX;%(PreprocessorDefinitions) 62 | true 63 | $(IntermediateOutputPath);%(AdditionalIncludeDirectories) 64 | 65 | 66 | Console 67 | true 68 | 69 | 70 | $(VcpkgRoot)tools\gbc.exe c++ --output-dir=$(IntermediateOutputPath) Darwin.bond 71 | Compiling Bond 72 | Darwin_apply.cpp;Darwin_types.cpp 73 | 74 | 75 | 76 | 77 | /bigobj %(AdditionalOptions) 78 | Level3 79 | 80 | 81 | MaxSpeed 82 | true 83 | true 84 | NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;BOOST_ALL_NO_LIB;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES;_ENABLE_ATOMIC_ALIGNMENT_FIX;%(PreprocessorDefinitions) 85 | true 86 | $(IntermediateOutputPath);%(AdditionalIncludeDirectories) 87 | 88 | 89 | Console 90 | true 91 | true 92 | true 93 | 94 | 95 | $(VcpkgRoot)tools\gbc.exe c++ --output-dir=$(IntermediateOutputPath) Darwin.bond 96 | Compiling Bond 97 | Darwin_apply.cpp;Darwin_types.cpp 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | -------------------------------------------------------------------------------- /software/Darwin.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | Source Files 19 | 20 | 21 | Source Files 22 | 23 | 24 | Source Files 25 | 26 | 27 | Source Files 28 | 29 | 30 | Source Files 31 | 32 | 33 | Source Files 34 | 35 | 36 | Source Files 37 | 38 | 39 | Source Files 40 | 41 | 42 | Source Files 43 | 44 | 45 | Source Files 46 | 47 | 48 | Source Files 49 | 50 | 51 | 52 | 53 | Header Files 54 | 55 | 56 | Header Files 57 | 58 | 59 | Header Files 60 | 61 | 62 | Header Files 63 | 64 | 65 | Header Files 66 | 67 | 68 | Header Files 69 | 70 | 71 | 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /software/Index.cpp: -------------------------------------------------------------------------------- 1 | #include "Index.h" 2 | 3 | #include "Processor.h" 4 | 5 | std::vector Darwin::Index::chr_id; 6 | std::vector Darwin::Index::chr_len; 7 | std::vector Darwin::Index::chr_len_unpadded; 8 | std::vector Darwin::Index::chr_coord; 9 | 10 | void Darwin::Index::init() 11 | { 12 | memset(g_DRAM->buffer, 'N', WORD_SIZE); 13 | 14 | g_DRAM->referenceSize += WORD_SIZE; 15 | 16 | chr_coord.push_back(g_DRAM->referenceSize); 17 | } 18 | 19 | bond::blob Darwin::Index::add_chr(std::string name, bond::blob seq) 20 | { 21 | chr_id.push_back(name); 22 | 23 | size_t seq_len = seq.size(); 24 | 25 | chr_len.push_back(seq_len); 26 | 27 | std::memcpy(g_DRAM->buffer + g_DRAM->referenceSize, seq.data(), seq_len); 28 | 29 | bond::blob ref(g_DRAM->buffer + g_DRAM->referenceSize, seq_len); 30 | 31 | size_t extra = seq_len % WORD_SIZE; 32 | if (extra != 0) 33 | { 34 | extra = WORD_SIZE - extra; 35 | memset(g_DRAM->buffer + g_DRAM->referenceSize + seq_len, 'N', extra); 36 | 37 | seq_len += extra; 38 | } 39 | 40 | g_DRAM->referenceSize += seq_len; 41 | 42 | chr_coord.push_back(g_DRAM->referenceSize); 43 | 44 | return ref; 45 | } 46 | -------------------------------------------------------------------------------- /software/Index.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | 6 | #include "bond/core/blob.h" 7 | 8 | namespace Darwin 9 | { 10 | namespace Index 11 | { 12 | extern std::vector chr_id; 13 | extern std::vector chr_coord; 14 | extern std::vector chr_len; 15 | extern std::vector chr_len_unpadded; 16 | 17 | void init(); 18 | bond::blob add_chr(std::string name, bond::blob seq); 19 | } 20 | } 21 | 22 | -------------------------------------------------------------------------------- /software/Processor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Darwin_reflection.h" 3 | 4 | #include "DRAM.h" 5 | #include "Index.h" 6 | #include 7 | #include "immintrin.h" 8 | 9 | #define INF (1 << 30) 10 | #define MAX_TILE_SIZE 512 11 | 12 | typedef int AlnOp; 13 | enum AlnOperands { ZERO_OP, INSERT_OP, DELETE_OP, LONG_INSERT_OP, LONG_DELETE_OP}; 14 | enum states { Z, I, D, M , L_Z, L_I, L_D}; 15 | 16 | /* for traceback */ 17 | #define TRACEBACK_T_MASK 8160 /* all bits set except the first five */ 18 | #define TRACEBACK_F_MASK 7807 /* all bits set except the F bits */ 19 | #define TRACEBACK_F_L_MASK 2047 /* all bits set except the F_L bits */ 20 | 21 | #define TRACEBACK_ZERO_T 0 22 | #define TRACEBACK_DEL_T 1 23 | #define TRACEBACK_INS_T 2 24 | #define TRACEBACK_DEL_L_T 4 25 | #define TRACEBACK_INS_L_T 8 26 | #define TRACEBACK_DIAG 16 27 | #define TRACEBACK_DIAG_DEL 32 28 | #define TRACEBACK_DEL 64 29 | #define TRACEBACK_DIAG_INS 128 30 | #define TRACEBACK_INS 256 31 | #define TRACEBACK_DIAG_DEL_L 512 32 | #define TRACEBACK_DEL_L 1024 33 | #define TRACEBACK_DIAG_INS_L 2048 34 | #define TRACEBACK_INS_L 4096 35 | 36 | typedef union __m256i_16 { 37 | __m256i m; 38 | int16_t v[16]; 39 | } __m256i_16_t; 40 | 41 | typedef struct result { 42 | int score; /* alignment score */ 43 | int end_query; /* end position of query sequence */ 44 | int end_ref; /* end position of reference sequence */ 45 | __m256i *trace; 46 | } result_t; 47 | 48 | using namespace Darwin; 49 | 50 | typedef size_t(*InitializeProcessor_ptr)(int t, int f, std::string s); 51 | typedef void(*InitializeScoringParameters_ptr)(size_t token, AlignmentScoringParams& request, AlignmentScoringParamsResponse& response); 52 | typedef void(*InitializeReferenceMemory_ptr)(size_t token, char* dram, InitializeDRAMMessage& request, InitializeDRAMMessageResponse& response); 53 | typedef void(*InitializeReadMemory_ptr)(size_t token, char* dram, InitializeDRAMMessage& request, InitializeDRAMMessageResponse& response); 54 | typedef void(*BatchAlignment_ptr)(size_t token, char* dram, BatchAlignmentInputFieldsDRAM& request, BatchAlignmentResultDRAM& result); 55 | typedef void(*BatchAlignmentSIMD_ptr)(size_t token, char* dram, BatchAlignmentInputFieldsDRAM& request, BatchAlignmentResultDRAM& result); 56 | 57 | extern DRAM *g_DRAM; 58 | 59 | extern InitializeScoringParameters_ptr g_InitializeScoringParameters; 60 | extern InitializeReferenceMemory_ptr g_InitializeReferenceMemory; 61 | extern InitializeReadMemory_ptr g_InitializeReadMemory; 62 | extern BatchAlignment_ptr g_BatchAlignment; 63 | extern BatchAlignmentSIMD_ptr g_BatchAlignmentSIMD; 64 | //extern BatchAlignmentTwoPiece_ptr g_BatchAlignmentTwoPiece; 65 | -------------------------------------------------------------------------------- /software/README.md: -------------------------------------------------------------------------------- 1 | ## Building 2 | 3 | Use the following steps for compiling on linux machine (tested on Ubuntu 16.04) 4 | 5 | * install bond package (https://github.com/Microsoft/bond) 6 | * generate bond headers using gbc (installed with bond library) 7 | ``` 8 | $ gbc cpp Darwin.bond 9 | ``` 10 | * clone tbb package (https://github.com/01org/tbb) 11 | ``` 12 | $ cd ${HOME}; git clone https://github.com/01org/tbb 13 | ``` 14 | * copy kseq.h from https://github.com/lh3/ksw2 15 | * build darwin using the following steps 16 | ``` 17 | $ cmake -DTBB_ROOT=${HOME}/tbb -DCMAKE_BUILD_TYPE=Release . 18 | $ make 19 | ``` 20 | * test reference-guided assembly using the sample data 21 | ``` 22 | $ ./Darwin data/sample_ref.fa data/sample_reads.fa 0 > out.maf 23 | ``` 24 | * test overlap stage for OLC assembly using the sample data (without the awk command below, the output also prints the actual alignments) 25 | ``` 26 | $ ./Darwin data/sample_reads.fa data/sample_reads.fa 1 | awk '{if (NF > 1) {print $0}}' > out.mhap 27 | ``` 28 | -------------------------------------------------------------------------------- /software/ReadMe.txt: -------------------------------------------------------------------------------- 1 | ======================================================================== 2 | CONSOLE APPLICATION : Darwin Project Overview 3 | ======================================================================== 4 | 5 | AppWizard has created this Darwin application for you. 6 | 7 | This file contains a summary of what you will find in each of the files that 8 | make up your Darwin application. 9 | 10 | 11 | Darwin.vcxproj 12 | This is the main project file for VC++ projects generated using an Application Wizard. 13 | It contains information about the version of Visual C++ that generated the file, and 14 | information about the platforms, configurations, and project features selected with the 15 | Application Wizard. 16 | 17 | Darwin.vcxproj.filters 18 | This is the filters file for VC++ projects generated using an Application Wizard. 19 | It contains information about the association between the files in your project 20 | and the filters. This association is used in the IDE to show grouping of files with 21 | similar extensions under a specific node (for e.g. ".cpp" files are associated with the 22 | "Source Files" filter). 23 | 24 | Darwin.cpp 25 | This is the main application source file. 26 | 27 | ///////////////////////////////////////////////////////////////////////////// 28 | Other standard files: 29 | 30 | StdAfx.h, StdAfx.cpp 31 | These files are used to build a precompiled header (PCH) file 32 | named Darwin.pch and a precompiled types file named StdAfx.obj. 33 | 34 | ///////////////////////////////////////////////////////////////////////////// 35 | Other notes: 36 | 37 | AppWizard uses "TODO:" comments to indicate parts of the source code you 38 | should add to or customize. 39 | 40 | ///////////////////////////////////////////////////////////////////////////// 41 | -------------------------------------------------------------------------------- /software/filter.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "graph.h" 3 | 4 | std::atomic filter_body::num_filter_tiles(0); 5 | std::atomic filter_body::num_extend_requests(0); 6 | std::atomic filter_body::num_slope_filtered(0); 7 | 8 | extender_input filter_body::operator()(filter_input input) 9 | { 10 | auto &payload = get<0>(input); 11 | 12 | auto &reads = get<0>(payload); 13 | 14 | auto &data = get<1>(payload); 15 | 16 | size_t token = get<1>(input); 17 | 18 | filter_data output; 19 | 20 | std::deque read_extend_locations; 21 | size_t word_size = WORD_SIZE; 22 | 23 | const size_t max_requests = cfg.first_tile_batch_size; 24 | 25 | // Forward reads 26 | auto& f_anchors = data.fwAnchors; 27 | 28 | for (size_t b = 0; b < f_anchors.size(); b += max_requests) 29 | { 30 | size_t first_hit = b; 31 | size_t last_hit = std::min(b + max_requests, f_anchors.size()); 32 | 33 | size_t num_requests = last_hit - first_hit; 34 | if (num_requests > 0) { 35 | 36 | BatchAlignmentInputFieldsDRAM request_batch_dram; 37 | BatchAlignmentResultDRAM result_batch_dram; 38 | request_batch_dram.requests.resize(num_requests); 39 | 40 | request_batch_dram.do_traceback = 0; //traceback; 41 | 42 | for (size_t c = first_hit, r = 0; c < last_hit; c++, r++) 43 | { 44 | uint32_t hit = (f_anchors[c].hit_offset >> 32); 45 | uint32_t offset = ((f_anchors[c].hit_offset << 32) >> 32); 46 | 47 | size_t chr_id = std::upper_bound(Index::chr_coord.cbegin(), Index::chr_coord.cend(), hit) - Index::chr_coord.cbegin() - 1; 48 | uint32_t chr_start = Index::chr_coord[chr_id]; 49 | uint32_t chr_end = chr_start + Index::chr_len[chr_id]; 50 | 51 | size_t read_num = std::upper_bound(data.fwAnchorBuckets.cbegin(), data.fwAnchorBuckets.cend(), c) - data.fwAnchorBuckets.cbegin() - 1; 52 | Read &read = reads[read_num]; 53 | const size_t read_len = read.seq.size(); 54 | char *read_char = (char *)read.seq.data(); 55 | 56 | uint32_t ref_tile_start = (hit + cfg.first_tile_size < chr_end) ? hit : ((chr_end > cfg.first_tile_size) ? chr_end - cfg.first_tile_size : 0); 57 | uint32_t query_tile_start = (offset + cfg.first_tile_size < read_len) ? offset : ((read_len > cfg.first_tile_size) ? read_len - cfg.first_tile_size : 0); 58 | uint32_t ref_tile_size = std::min(uint32_t(cfg.first_tile_size), (chr_end - chr_start)); 59 | uint32_t query_tile_size = std::min(size_t(cfg.first_tile_size), read_len); 60 | 61 | request_batch_dram.requests[r].index = c - b; 62 | request_batch_dram.requests[r].ref_size = ref_tile_size; 63 | request_batch_dram.requests[r].query_size = query_tile_size; 64 | 65 | request_batch_dram.requests[r].ref_bases_start_addr = ref_tile_start; 66 | request_batch_dram.requests[r].query_bases_start_addr = (read_char - g_DRAM->buffer) + query_tile_start; 67 | 68 | request_batch_dram.requests[r].max_tb_steps = 2 * cfg.first_tile_size; 69 | request_batch_dram.requests[r].score_threshold = 0; 70 | 71 | request_batch_dram.requests[r].align_fields = 0; 72 | } 73 | 74 | 75 | //fpga_writer_lock.lock_read(); 76 | 77 | g_BatchAlignmentSIMD(token, g_DRAM->buffer, request_batch_dram, result_batch_dram); 78 | 79 | //fpga_writer_lock.unlock(); 80 | 81 | 82 | num_filter_tiles += num_requests; 83 | 84 | 85 | for (size_t r = 0; r < num_requests; r++) { 86 | AlignmentResult result = result_batch_dram.results[r]; 87 | int index = b + result.index; 88 | 89 | if (result.score >= cfg.first_tile_score_threshold) { 90 | uint32_t hit = (f_anchors[index].hit_offset >> 32); 91 | uint32_t offset = ((f_anchors[index].hit_offset << 32) >> 32); 92 | 93 | size_t chr_id = std::upper_bound(Index::chr_coord.cbegin(), Index::chr_coord.cend(), hit) - Index::chr_coord.cbegin() - 1; 94 | uint32_t chr_start = Index::chr_coord[chr_id]; 95 | uint32_t chr_end = chr_start + Index::chr_len[chr_id]; 96 | 97 | size_t read_num = std::upper_bound(data.fwAnchorBuckets.cbegin(), data.fwAnchorBuckets.cend(), index) - data.fwAnchorBuckets.cbegin() - 1; 98 | Read &read = reads[read_num]; 99 | const size_t read_len = read.seq.size(); 100 | 101 | uint32_t ref_tile_start = (hit + cfg.first_tile_size < chr_end) ? hit : ((chr_end > cfg.first_tile_size) ? chr_end - cfg.first_tile_size : 0); 102 | uint32_t query_tile_start = (offset + cfg.first_tile_size < read_len) ? offset : ((read_len > cfg.first_tile_size) ? read_len - cfg.first_tile_size : 0); 103 | uint32_t query_tile_size = std::min(size_t(cfg.first_tile_size), read_len); 104 | 105 | uint32_t ovl = (offset + (chr_end - hit)); 106 | 107 | if (ovl > cfg.min_overlap / 2) { 108 | ExtendLocations loc; 109 | loc.read_num = read_num; 110 | loc.chr_id = chr_id; 111 | loc.score = result.score; 112 | loc.reference_pos = ref_tile_start + result.ref_max_pos; 113 | loc.query_pos = query_tile_start + result.query_max_pos; 114 | loc.left_hit_offsets.assign(f_anchors[index].left_chained_hits.begin(), f_anchors[index].left_chained_hits.end()); 115 | loc.right_hit_offsets.assign(f_anchors[index].right_chained_hits.begin(), f_anchors[index].right_chained_hits.end()); 116 | read_extend_locations.push_back(loc); 117 | } 118 | num_extend_requests += 1; 119 | } 120 | } 121 | } 122 | } 123 | 124 | slopeFilter(read_extend_locations, output.fwLocations); 125 | 126 | // Reverse-complement reads 127 | auto& rc_anchors = data.rcAnchors; 128 | 129 | read_extend_locations.clear(); 130 | 131 | for (size_t b = 0; b < rc_anchors.size(); b += max_requests) 132 | { 133 | size_t first_hit = b; 134 | size_t last_hit = std::min(b + max_requests, rc_anchors.size()); 135 | 136 | size_t num_requests = last_hit - first_hit; 137 | 138 | if (num_requests > 0) { 139 | BatchAlignmentInputFieldsDRAM request_batch_dram; 140 | BatchAlignmentResultDRAM result_batch_dram; 141 | request_batch_dram.requests.resize(num_requests); 142 | 143 | request_batch_dram.do_traceback = 0; //traceback; 144 | 145 | for (size_t c = first_hit, r = 0; c < last_hit; c++, r++) 146 | { 147 | uint32_t hit = (rc_anchors[c].hit_offset >> 32); 148 | uint32_t offset = ((rc_anchors[c].hit_offset << 32) >> 32); 149 | 150 | size_t chr_id = std::upper_bound(Index::chr_coord.cbegin(), Index::chr_coord.cend(), hit) - Index::chr_coord.cbegin() - 1; 151 | uint32_t chr_start = Index::chr_coord[chr_id]; 152 | uint32_t chr_end = chr_start + Index::chr_len[chr_id]; 153 | 154 | size_t read_num = std::upper_bound(data.rcAnchorBuckets.cbegin(), data.rcAnchorBuckets.cend(), c) - data.rcAnchorBuckets.cbegin() - 1; 155 | Read &read = reads[read_num]; 156 | const size_t read_len = read.seq.size(); 157 | char *read_char = (char *)read.seq.data(); 158 | 159 | uint32_t ref_tile_start = (hit + cfg.first_tile_size < chr_end) ? hit : ((chr_end > cfg.first_tile_size) ? chr_end - cfg.first_tile_size : 0); 160 | uint32_t query_tile_start = (offset + cfg.first_tile_size < read_len) ? offset : ((read_len > cfg.first_tile_size) ? read_len - cfg.first_tile_size : 0); 161 | uint32_t ref_tile_size = std::min(uint32_t(cfg.first_tile_size), (chr_end - chr_start)); 162 | uint32_t query_tile_size = std::min(size_t(cfg.first_tile_size), read_len); 163 | 164 | request_batch_dram.requests[r].index = c - b; 165 | request_batch_dram.requests[r].ref_size = ref_tile_size; 166 | request_batch_dram.requests[r].query_size = query_tile_size; 167 | 168 | request_batch_dram.requests[r].ref_bases_start_addr = ref_tile_start; 169 | request_batch_dram.requests[r].query_bases_start_addr = (read_char - g_DRAM->buffer) + read_len - (query_tile_start + query_tile_size); 170 | 171 | request_batch_dram.requests[r].max_tb_steps = 2 * cfg.first_tile_size; 172 | request_batch_dram.requests[r].score_threshold = 0; 173 | 174 | request_batch_dram.requests[r].align_fields = reverse_query + complement_query; 175 | } 176 | 177 | //fpga_writer_lock.lock_read(); 178 | 179 | g_BatchAlignmentSIMD(token, g_DRAM->buffer, request_batch_dram, result_batch_dram); 180 | 181 | //fpga_writer_lock.unlock(); 182 | 183 | num_filter_tiles += num_requests; 184 | 185 | for (int r = 0; r < num_requests; r++) { 186 | AlignmentResult result = result_batch_dram.results[r]; 187 | int index = b + result.index; 188 | 189 | if (result.score >= cfg.first_tile_score_threshold) { 190 | uint32_t hit = (rc_anchors[index].hit_offset >> 32); 191 | uint32_t offset = ((rc_anchors[index].hit_offset << 32) >> 32); 192 | 193 | size_t chr_id = std::upper_bound(Index::chr_coord.cbegin(), Index::chr_coord.cend(), hit) - Index::chr_coord.cbegin() - 1; 194 | uint32_t chr_start = Index::chr_coord[chr_id]; 195 | uint32_t chr_end = chr_start + Index::chr_len[chr_id]; 196 | 197 | size_t read_num = std::upper_bound(data.rcAnchorBuckets.cbegin(), data.rcAnchorBuckets.cend(), index) - data.rcAnchorBuckets.cbegin() - 1; 198 | Read &read = reads[read_num]; 199 | const size_t read_len = read.seq.size(); 200 | 201 | uint32_t ref_tile_start = (hit + cfg.first_tile_size < chr_end) ? hit : ((chr_end > cfg.first_tile_size) ? chr_end - cfg.first_tile_size : 0); 202 | uint32_t query_tile_start = (offset + cfg.first_tile_size < read_len) ? offset : ((read_len > cfg.first_tile_size) ? read_len - cfg.first_tile_size : 0); 203 | uint32_t query_tile_size = std::min(size_t(cfg.first_tile_size), read_len); 204 | 205 | uint32_t ovl = (offset + (chr_end - hit)); 206 | 207 | if (ovl > cfg.min_overlap / 2) { 208 | ExtendLocations loc; 209 | loc.read_num = read_num; 210 | loc.chr_id = chr_id; 211 | loc.score = result.score; 212 | loc.reference_pos = ref_tile_start + result.ref_max_pos; 213 | loc.query_pos = query_tile_start + result.query_max_pos; 214 | loc.left_hit_offsets.assign(rc_anchors[index].left_chained_hits.begin(), rc_anchors[index].left_chained_hits.end()); 215 | loc.right_hit_offsets.assign(rc_anchors[index].right_chained_hits.begin(), rc_anchors[index].right_chained_hits.end()); 216 | read_extend_locations.push_back(loc); 217 | } 218 | // rc_extend_locations.push(loc); 219 | num_extend_requests += 1; 220 | } 221 | } 222 | } 223 | } 224 | 225 | slopeFilter(read_extend_locations, output.rcLocations); 226 | 227 | return extender_input(extender_payload(reads, output), token); 228 | } 229 | 230 | void filter_body::slopeFilter(std::deque &read_extend_locations, std::vector &extend_locations) 231 | { 232 | extend_locations.clear(); 233 | if (!read_extend_locations.empty()) 234 | { 235 | std::sort(read_extend_locations.begin(), read_extend_locations.end(), 236 | [](const ExtendLocations &a, const ExtendLocations &b) { 237 | return ((a.read_num < b.read_num) || ((a.read_num == b.read_num) && (a.score > b.score)) || ((a.read_num == b.read_num) && (a.score == b.score) && (a.reference_pos < b.reference_pos)) || ((a.read_num == b.read_num) && (a.score == b.score) && (a.reference_pos == b.reference_pos) && (a.query_pos < b.query_pos))); 238 | }); 239 | 240 | for (auto l1 = read_extend_locations.begin(); l1 != read_extend_locations.end(); l1++) 241 | { 242 | if (l1->read_num == -1) 243 | continue; 244 | 245 | extend_locations.push_back(*l1); 246 | 247 | for (auto l2 = l1 + 1; l2 != read_extend_locations.end(); l2++) 248 | { 249 | if (l2->read_num == -1) 250 | continue; 251 | 252 | if (l2->read_num != l1->read_num) 253 | break; 254 | 255 | /*uint32_t rs1 = (l1->left_hit_offsets.front() >> 32); 256 | uint32_t qs1 = ((l1->left_hit_offsets.front() << 32) >> 32); 257 | uint32_t re1 = (l1->right_hit_offsets.front() >> 32); 258 | uint32_t qe1 = ((l1->right_hit_offsets.front() << 32) >> 32); 259 | uint32_t r2 = l2->reference_pos; 260 | uint32_t q2 = l2->query_pos;*/ 261 | 262 | 263 | 264 | 265 | /*if ((r2 >= rs1) && (r2 <= re1) && (q2 >= qs1) && (q2 <= qe1)) { 266 | l2->read_num = -1; 267 | num_slope_filtered += 1; 268 | } 269 | else {*/ 270 | float r1 = l1->reference_pos; 271 | float q1 = l1->query_pos; 272 | float r2 = l2->reference_pos; 273 | float q2 = l2->query_pos; 274 | float slope = std::abs((r1 - r2) / (q1 - q2) - 1); 275 | if (std::abs((r1 - r2) / (q1 - q2) - 1) <= cfg.slope_threshold) 276 | { 277 | l2->read_num = -1; 278 | num_slope_filtered += 1; 279 | } 280 | 281 | //} 282 | 283 | 284 | 285 | } 286 | } 287 | } 288 | } 289 | -------------------------------------------------------------------------------- /software/graph.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #define BOOST_LOCALE_NO_LIB 3 | #define NOMINMAX 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include "ntcoding.h" 12 | #include "seed_pos_table.h" 13 | #include "Processor.h" 14 | #include "DRAM.h" 15 | #include "Index.h" 16 | 17 | #define TB_MASK 3 18 | 19 | #define MAX_CHAR_TO_SEND 2048 20 | 21 | //#define traceback 0 22 | #define reverse_ref (1 << 4) 23 | #define complement_ref (1 << 3) 24 | #define reverse_query (1 << 2) 25 | #define complement_query (1 << 1) 26 | #define start_end 1 27 | 28 | struct Configuration { 29 | // GACT scoring 30 | int gact_sub_mat[11]; 31 | int gap_open; 32 | int gap_extend; 33 | int long_gap_open; 34 | int long_gap_extend; 35 | 36 | // D-SOFT parameters 37 | int seed_size; 38 | int minimizer_window; 39 | uint32_t bin_size; 40 | int dsoft_threshold; 41 | int num_seeds; 42 | int seed_occurence_multiple; 43 | int max_candidates; 44 | int num_nz_bins; 45 | int max_stride; 46 | int do_overlap; 47 | bool ignore_lower; 48 | 49 | // GACT first tile 50 | int first_tile_size; 51 | int first_tile_score_threshold; 52 | int first_tile_batch_size; 53 | 54 | int min_overlap; 55 | float slope_threshold; 56 | 57 | //GACT extend 58 | int tile_size; 59 | int tile_overlap; 60 | int batch_size; 61 | 62 | //Multi-threading 63 | int num_threads; 64 | 65 | //FPGA 66 | std::string processor_library; 67 | int num_fpgas; 68 | // std::string chip_ids; 69 | }; 70 | 71 | extern Configuration cfg; 72 | 73 | extern SeedPosTable *sa; 74 | 75 | void GenerateInitializeMemoryMessage(InitializeDRAMMessage& init_dram_message, const char* seq, uint32_t seq_addr, uint32_t dram_addr, int num_bytes); 76 | 77 | struct Read { 78 | std::string description; 79 | bond::blob seq; 80 | bond::blob rc_seq; 81 | }; 82 | 83 | struct ExtendLocations { 84 | int read_num; 85 | int chr_id; 86 | int score; 87 | uint32_t reference_pos; 88 | uint32_t query_pos; 89 | vector left_hit_offsets; 90 | vector right_hit_offsets; 91 | }; 92 | 93 | static inline bool CompareExtendLocations(ExtendLocations e1, ExtendLocations e2) { 94 | return e1.score > e2.score; 95 | } 96 | 97 | struct ExtendAlignments { 98 | int read_num; 99 | int chr_id; 100 | uint32_t curr_reference_offset; 101 | uint32_t curr_query_offset; 102 | uint32_t reference_start_offset; 103 | uint32_t query_start_offset; 104 | uint32_t reference_end_offset; 105 | uint32_t query_end_offset; 106 | uint32_t reference_start_addr; 107 | uint32_t query_start_addr; 108 | uint32_t reference_length; 109 | uint32_t query_length; 110 | int left_extension_done; 111 | int right_extension_done; 112 | bool used_large_tile; 113 | bool do_print; 114 | char strand; 115 | std::string aligned_reference_str; 116 | std::string aligned_query_str; 117 | int score; 118 | int chain_score; 119 | vector left_hit_offsets; 120 | vector right_hit_offsets; 121 | }; 122 | 123 | struct SamFields { 124 | std::string QNAME; 125 | uint16_t FLAG; 126 | std::string RNAME; 127 | size_t POS; 128 | uint8_t MAPQ; 129 | std::string CIGAR; 130 | std::string RNEXT; 131 | size_t PNEXT; 132 | int32_t TLEN; 133 | std::string SEQ; 134 | std::string QUAL; 135 | int32_t SCORE; 136 | int32_t CHAIN_SCORE; 137 | }; 138 | 139 | typedef std::vector reader_output; 140 | 141 | typedef tbb::flow::tuple seeder_input; 142 | 143 | struct seeder_data 144 | { 145 | std::vector fwAnchorBuckets; 146 | std::vector rcAnchorBuckets; 147 | 148 | std::vector fwAnchors; 149 | std::vector rcAnchors; 150 | }; 151 | 152 | typedef tbb::flow::tuple seeder_output; 153 | 154 | typedef tbb::flow::tuple filter_payload; 155 | typedef tbb::flow::tuple filter_input; 156 | 157 | struct filter_data 158 | { 159 | std::vector fwLocations; 160 | std::vector rcLocations; 161 | }; 162 | 163 | typedef tbb::flow::tuple extender_payload; 164 | typedef tbb::flow::tuple extender_input; 165 | 166 | struct extend_data 167 | { 168 | std::vector extend_alignments; 169 | }; 170 | typedef tbb::flow::tuple printer_payload; 171 | typedef tbb::flow::tuple printer_input; 172 | //typedef std::pair printer_input; 173 | //typedef std::pair printer_input; 174 | 175 | typedef tbb::flow::tuple extender_output; 176 | 177 | typedef tbb::flow::multifunction_node extender_node; 178 | 179 | struct printer_body 180 | { 181 | static std::atomic done_header; 182 | SamFields AlignmentToSam (Read r, ExtendAlignments e); 183 | void sam_printer(printer_input input); 184 | void mhap_printer(printer_input input); 185 | size_t operator()(printer_input input); 186 | }; 187 | 188 | //extern tbb::reader_writer_lock fpga_writer_lock; 189 | 190 | extern std::mutex io_lock; 191 | 192 | struct reference_sender_body 193 | { 194 | seeder_input operator()(seeder_input input); 195 | }; 196 | 197 | struct read_sender_body 198 | { 199 | seeder_input operator()(seeder_input input); 200 | }; 201 | 202 | 203 | struct seeder_body 204 | { 205 | filter_input operator()(seeder_input input); 206 | }; 207 | 208 | struct filter_body 209 | { 210 | static std::atomic num_filter_tiles; 211 | static std::atomic num_extend_requests; 212 | static std::atomic num_slope_filtered; 213 | 214 | extender_input operator()(filter_input input); 215 | void slopeFilter(std::deque &read_extend_locations, std::vector &extend_locations); 216 | }; 217 | 218 | struct extender_body 219 | { 220 | static std::atomic num_extend_tiles; 221 | static std::atomic num_active_tiles; 222 | static std::atomic num_large_tiles; 223 | 224 | // printer_input operator()(extender_input input, extender_node::output_ports_type &op); 225 | void operator()(extender_input input, extender_node::output_ports_type &op); 226 | ExtendAlignments makeForwardAlignment(std::vector &batch, std::vector::const_iterator &loc); 227 | ExtendAlignments makeBackwardAlignment(std::vector &batch, std::vector::const_iterator &loc); 228 | int AlignmentScore(std::string r, std::string q); 229 | }; 230 | -------------------------------------------------------------------------------- /software/ntcoding.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "ntcoding.h" 3 | #include 4 | 5 | #include "tbb/scalable_allocator.h" 6 | 7 | int shape_pos[32]; 8 | int shape_size; 9 | bool is_ignore_lower = false; 10 | 11 | uint32_t NtChar2Int(char nt) { 12 | if (!is_ignore_lower) { 13 | nt = toupper(nt); 14 | } 15 | switch (nt) { 16 | case 'A': return A_NT; 17 | case 'C': return C_NT; 18 | case 'G': return G_NT; 19 | case 'T': return T_NT; 20 | case 'N': return N_NT; 21 | default: return N_NT; 22 | } 23 | } 24 | 25 | void SetIgnoreLower() { 26 | is_ignore_lower = true; 27 | } 28 | 29 | uint32_t KmerToIndex(std::string kmer) { 30 | uint32_t index = 0; 31 | char nt; 32 | for (int i = 0; i < kmer.length(); i++) { 33 | nt = (kmer.at(i)); 34 | index = (index << 2) + NtChar2Int(nt); 35 | } 36 | return index; 37 | } 38 | 39 | void GenerateShapePos(std::string shape) { 40 | shape_size = 0; 41 | for (int i = 0; i < shape.length(); i++) { 42 | if (shape[i] == '1') { 43 | shape_pos[shape_size++] = i; 44 | } 45 | } 46 | } 47 | 48 | uint32_t GetKmerIndexAtPos(char* sequence, uint32_t pos) { 49 | uint32_t kmer = 0; 50 | for (int i = 0; i < shape_size; i++) { 51 | uint32_t nt = NtChar2Int(sequence[pos + shape_pos[i]]); 52 | if (nt != N_NT) { 53 | kmer = (kmer << 2) + nt; 54 | } 55 | else { 56 | kmer = (1 << 31); 57 | break; 58 | } 59 | } 60 | return kmer; 61 | } 62 | 63 | uint32_t GetKmerIndexAtPos(std::string sequence, uint32_t pos) { 64 | uint32_t kmer = 0; 65 | for (int i = 0; i < shape_size; i++) { 66 | uint32_t nt = NtChar2Int(sequence[pos + shape_pos[i]]); 67 | if (nt != N_NT) { 68 | kmer = (kmer << 2) + nt; 69 | } 70 | else { 71 | kmer = (1 << 31); 72 | break; 73 | } 74 | } 75 | return kmer; 76 | } 77 | 78 | 79 | static inline int NtToTwoBit(char nt) { 80 | switch (nt) { 81 | case 'a': 82 | case 'A': return 0; 83 | case 'c': 84 | case 'C': return 1; 85 | case 'g': 86 | case 'G': return 2; 87 | case 't': 88 | case 'T': return 3; 89 | default: return 0; 90 | } 91 | return 0; 92 | } 93 | 94 | uint32_t* SeqToTwoBit(char* seq, uint32_t seq_len) { 95 | uint32_t len_2bit = (seq_len + 15) / 16; 96 | uint32_t* s_2bit = (uint32_t*)scalable_calloc(len_2bit, sizeof(uint32_t)); 97 | 98 | char c; 99 | int idx, j_max; 100 | for (uint32_t i = 0; i < seq_len; i += 16) { 101 | j_max = FIND_MIN(16, seq_len - i); 102 | idx = i / 16; 103 | for (int j = 0; j < j_max; j++) { 104 | c = seq[i + j]; 105 | s_2bit[idx] += (NtToTwoBit(c) << 2 * j); 106 | } 107 | } 108 | return s_2bit; 109 | 110 | } 111 | 112 | 113 | void SeqToMinimizers( 114 | std::vector& minimizers, int64_t &miniCount, 115 | int kmer_size, int minimizer_window, 116 | char* seq_addr, std::size_t seq_len, std::size_t seq_offset) { 117 | uint32_t* window = (uint32_t*)scalable_calloc(minimizer_window, sizeof(uint32_t)); 118 | uint64_t last_m = 0; 119 | uint32_t last_p = 0; 120 | 121 | std::size_t rlen_2bit = 1 + ((seq_len + 15) / 16); 122 | uint32_t* r_2bit = SeqToTwoBit(seq_addr, seq_len); 123 | 124 | for (int p = 0; p < minimizer_window - 1; p++) { 125 | window[p] = hash32(GetSeedAtPos(r_2bit, p, kmer_size), kmer_size); 126 | } 127 | 128 | for (uint32_t p = minimizer_window - 1; p < seq_len - kmer_size - minimizer_window; p++) { 129 | window[p%minimizer_window] = hash32(GetSeedAtPos(r_2bit, p, kmer_size), kmer_size); 130 | uint64_t m = Min_Window(window, minimizer_window); 131 | if ((m != last_m) || (p - last_p >= minimizer_window)) 132 | { 133 | int64_t miniPos = ++miniCount; 134 | 135 | minimizers[miniPos] = (m << 32) + p + seq_offset; 136 | last_m = m; 137 | last_p = p; 138 | } 139 | } 140 | 141 | scalable_free(r_2bit); 142 | scalable_free(window); 143 | } 144 | 145 | std::pair TwoBitToMinimizers(uint32_t* s_2bit, uint32_t s_len, int k, int w) { 146 | uint32_t* window = (uint32_t*)calloc(w, sizeof(uint32_t)); 147 | uint64_t last_m = 0; 148 | uint32_t last_p = 0; 149 | uint64_t m; 150 | 151 | uint32_t N = 0; 152 | 153 | uint64_t* minimizers = (uint64_t*)calloc(s_len, sizeof(uint64_t)); 154 | for (int p = 0; p < w - 1; p++) { 155 | window[p] = hash32(GetSeedAtPos(s_2bit, p, k), k); 156 | } 157 | 158 | for (uint32_t p = w - 1; p < s_len - k - w; p++) { 159 | window[p%w] = hash32(GetSeedAtPos(s_2bit, p, k), k); 160 | m = Min_Window(window, w); 161 | if ((m != last_m) || (p - last_p >= w)) { 162 | minimizers[N++] = (m << 32) + p; 163 | last_m = m; 164 | last_p = p; 165 | } 166 | } 167 | 168 | uint64_t* new_minimizers = (uint64_t*)malloc(N * sizeof(uint64_t)); 169 | std::memcpy(new_minimizers, minimizers, N * sizeof(uint64_t)); 170 | delete[] minimizers; 171 | return std::pair (new_minimizers, N); 172 | } 173 | 174 | std::pair QTwoBitToMinimizers(uint32_t* s_2bit, uint32_t s_len, int k, int w) { 175 | uint32_t* window = (uint32_t*)calloc(w, sizeof(uint32_t)); 176 | uint64_t last_m = 0; 177 | uint32_t last_p = 0; 178 | uint64_t m; 179 | 180 | uint32_t N = 0; 181 | 182 | uint64_t* minimizers = (uint64_t*)scalable_calloc(s_len, sizeof(uint64_t)); 183 | for (int p = 0; p < w - 1; p++) { 184 | window[p] = hash32(GetSeedAtPos(s_2bit, p, k), k); 185 | } 186 | 187 | for (uint32_t p = w - 1; p < s_len - k; p++) { 188 | window[p%w] = hash32(GetSeedAtPos(s_2bit, p, k), k); 189 | m = Min_Window(window, w); 190 | if ((m != last_m) || (p - last_p >= w)) { 191 | minimizers[N++] = ((uint64_t)p << 32) + m; 192 | last_m = m; 193 | last_p = p; 194 | } 195 | } 196 | 197 | uint64_t* new_minimizers = (uint64_t*)scalable_malloc(N * sizeof(uint64_t)); 198 | std::memcpy(new_minimizers, minimizers, N * sizeof(uint64_t)); 199 | scalable_free(minimizers); 200 | return std::pair (new_minimizers, N); 201 | } 202 | 203 | -------------------------------------------------------------------------------- /software/ntcoding.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define A_NT 0 4 | #define C_NT 1 5 | #define G_NT 2 6 | #define T_NT 3 7 | #define N_NT 4 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #define FIND_MIN(x, y) (x < y) ? x : y 15 | #define FIND_MAX(x, y) (x > y) ? x : y 16 | 17 | 18 | using namespace std; 19 | 20 | void SetIgnoreLower(); 21 | uint32_t NtChar2Int (char nt); 22 | void GenerateShapePos(std::string shape); 23 | uint32_t KmerToIndex(std::string kmer); 24 | uint32_t GetKmerIndexAtPos(char* sequence, uint32_t pos); 25 | uint32_t GetKmerIndexAtPos(std::string sequence, uint32_t pos); 26 | static inline int NtToTwoBit (char nt); 27 | uint32_t* SeqToTwoBit (char* seq, uint32_t seq_len); 28 | std::pair TwoBitToMinimizers (uint32_t* s_2bit, uint32_t s_len, int k, int w); 29 | std::pair QTwoBitToMinimizers (uint32_t* s_2bit, uint32_t s_len, int k, int w); 30 | void SeqToMinimizers( 31 | std::vector& minimizers, int64_t &miniCount, 32 | int kmer_size, int minimizer_window, 33 | char* seq_addr, std::size_t seq_len, std::size_t seq_offset); 34 | 35 | inline uint32_t Min_Window(uint32_t* window, int size) { 36 | uint32_t min = (1ull << 31ull) - 1ull; 37 | for (int i = 0; i < size; i++) { 38 | if (min > window[i]) { 39 | min = window[i]; 40 | } 41 | } 42 | return min; 43 | } 44 | 45 | inline uint32_t GetSeedAtPos(uint32_t* s_2bit, uint32_t pos, int k) { 46 | int idx, shift; 47 | uint32_t m = (1 << 2 * k) - 1; 48 | uint32_t seed; 49 | idx = pos / 16; 50 | shift = pos % 16; 51 | uint64_t concat = (((uint64_t)s_2bit[idx + 1]) << 32) + s_2bit[idx]; 52 | seed = (concat >> 2 * shift) & m; 53 | return seed; 54 | } 55 | 56 | inline uint32_t hash32(uint32_t key, int k) 57 | { 58 | uint32_t m = (1 << 2 * k) - 1; 59 | key = (~key + (key << 21)) & m; 60 | key = key ^ (key >> 24); 61 | key = ((key + (key << 3)) + (key << 8)) & m; 62 | key = key ^ (key >> 14); 63 | key = ((key + (key << 2)) + (key << 4)) & m; 64 | key = key ^ (key >> 28); 65 | key = (key + (key << 31)) & m; 66 | return key; 67 | } 68 | -------------------------------------------------------------------------------- /software/params.cfg: -------------------------------------------------------------------------------- 1 | [GACT_scoring] 2 | sub_AA = 2 3 | sub_AC = -6 4 | sub_AG = -6 5 | sub_AT = -6 6 | sub_CC = 2 7 | sub_CG = -6 8 | sub_CT = -6 9 | sub_GG = 2 10 | sub_GT = -6 11 | sub_TT = 2 12 | sub_N = -1 13 | gap_open = -4 14 | gap_extend = -2 15 | long_gap_open = -25 16 | long_gap_extend = -1 17 | 18 | [DSOFT_params] 19 | seed_size = 14 20 | minimizer_window = 3 21 | bin_size = 64 22 | threshold = 26 23 | num_seeds = 1000 24 | seed_occurence_multiple = 40 25 | max_candidates = 1000 26 | ignore_lower = 0 27 | max_stride = 4 28 | 29 | [GACT_first_tile] 30 | first_tile_size = 128 31 | first_tile_score_threshold = 60 32 | first_tile_batch_size = 64 33 | slope_threshold = 0.05 34 | min_overlap = 1000 35 | 36 | [GACT_extend] 37 | tile_size = 384 38 | tile_overlap = 64 39 | batch_size = 2 40 | 41 | [Multithreading] 42 | num_threads = 48 43 | 44 | [FPGA] 45 | processor_library = DarwinFpga.dll 46 | num_fpgas = 4 47 | //chip_ids = 23645556578518026,23645556587822601,23645556457603852,23645556573340686 48 | 49 | -------------------------------------------------------------------------------- /software/printer.cpp: -------------------------------------------------------------------------------- 1 | #include "graph.h" 2 | #include 3 | std::mutex io_lock; 4 | 5 | std::atomic printer_body::done_header(0); 6 | 7 | void printer_body::sam_printer(printer_input input) { 8 | auto &payload = get<0>(input); 9 | 10 | auto &reads = get<0>(payload); 11 | 12 | auto &data = get<1>(payload); 13 | 14 | // 15 | Read read; 16 | 17 | auto& extend_alignments = data.extend_alignments; 18 | std::stable_sort(extend_alignments.begin(), extend_alignments.end(), 19 | [](const ExtendAlignments &e1, const ExtendAlignments &e2) { 20 | return ((e1.read_num < e2.read_num) || ((e1.read_num == e2.read_num) && (e1.score > e2.score))); 21 | }); 22 | 23 | for (auto e1 = extend_alignments.begin(); e1 != extend_alignments.end(); e1++) { 24 | if (!e1->do_print) { 25 | continue; 26 | } 27 | uint32_t s_1 = e1->query_start_offset; 28 | uint32_t e_1 = e1->query_end_offset; 29 | for (auto e2 = e1 + 1; e2 != extend_alignments.end(); e2++) { 30 | if (!e2->do_print) { 31 | continue; 32 | } 33 | if (e2->read_num != e1->read_num) { 34 | break; 35 | } 36 | uint32_t s_2 = e2->query_start_offset; 37 | uint32_t e_2 = e2->query_end_offset; 38 | uint32_t s = std::max(s_1, s_2); 39 | uint32_t e = std::min(e_1, e_2); 40 | uint32_t overlap = 0; 41 | if (e > s) { 42 | overlap = e-s; 43 | } 44 | if (2*overlap > (e_2-s_2)) { 45 | e2->do_print = false; 46 | } 47 | } 48 | } 49 | 50 | for (auto e: extend_alignments) { 51 | if (e.do_print) { 52 | Read read = reads[e.read_num]; 53 | // SAM Format 54 | SamFields sf = AlignmentToSam(read, e); 55 | 56 | io_lock.lock(); 57 | if (done_header == 0) { 58 | std::cout << "@HD\tVN:1.6\tSO:coordinate\n"; 59 | int num_chrom = Index::chr_id.size(); 60 | for (int c = 0; c < num_chrom; c++) { 61 | std::cout << "@SQ\tSN:" << Index::chr_id[c] << "\tLN:" << Index::chr_len_unpadded[c] << "\n"; 62 | } 63 | done_header = 1; 64 | } 65 | 66 | 67 | std::cout << sf.QNAME << "\t"; 68 | std::cout << sf.FLAG << "\t"; 69 | std::cout << sf.RNAME << "\t"; 70 | std::cout << sf.POS << "\t"; 71 | std::cout << (int)sf.MAPQ << "\t"; 72 | std::cout << sf.CIGAR << "\t"; 73 | std::cout << sf.RNEXT << "\t"; 74 | std::cout << sf.PNEXT << "\t"; 75 | std::cout << sf.TLEN << "\t"; 76 | std::cout << sf.SEQ << "\t"; 77 | std::cout << sf.QUAL << "\t"; 78 | std::cout << "AS:i:" << sf.SCORE << "\t"; 79 | std::cout << "ZS:i:" << sf.CHAIN_SCORE; 80 | std::cout << "\n"; 81 | 82 | //MAF format 83 | // int score = e.score; 84 | // uint32_t ref_start = 1 + e.reference_start_offset; 85 | // uint32_t query_start = 1 + e.query_start_offset; 86 | // uint32_t ref_align_len = ((e.reference_end_offset + 1) - e.reference_start_offset); 87 | // uint32_t query_align_len = ((e.query_end_offset + 1) - e.query_start_offset); 88 | // printf("a score=%d\n", score); 89 | // printf("s\t%s\t%lu\t%lu\t+\t%lu\t", Index::chr_id[e.chr_id].c_str(), ref_start, ref_align_len, Index::chr_len[e.chr_id]); 90 | // puts(e.aligned_reference_str.c_str()); 91 | // printf("s\t%s\t%lu\t%lu\t%c\t%lu\t", read.description.c_str(), query_start, query_align_len, e.strand, read.seq.size()); 92 | // puts(e.aligned_query_str.c_str()); 93 | // printf("\n"); 94 | 95 | io_lock.unlock(); 96 | } 97 | } 98 | } 99 | 100 | void printer_body::mhap_printer(printer_input input) { 101 | auto &payload = get<0>(input); 102 | 103 | auto &reads = get<0>(payload); 104 | 105 | auto &data = get<1>(payload); 106 | 107 | // 108 | Read read; 109 | 110 | auto& extend_alignments = data.extend_alignments; 111 | std::stable_sort(extend_alignments.begin(), extend_alignments.end(), 112 | [](const ExtendAlignments &e1, const ExtendAlignments &e2) { 113 | return ((e1.read_num < e2.read_num) || ((e1.read_num == e2.read_num) && (e1.chr_id < e2.chr_id)) || ((e1.read_num == e2.read_num) && (e1.chr_id == e2.chr_id) && (e1.score > e2.score))); 114 | }); 115 | 116 | for (auto e1 = extend_alignments.begin(); e1 != extend_alignments.end(); e1++) { 117 | 118 | uint32_t ref_end = 1 + e1->reference_end_offset; 119 | uint32_t query_end = 1 + e1->query_end_offset; 120 | uint32_t ref_len = e1->reference_length; 121 | uint32_t query_len = e1->query_length; 122 | if ((ref_end < (9*ref_len)/10) && (query_end < (9*query_len)/10)) { 123 | e1->do_print = false; 124 | } 125 | if (!e1->do_print) { 126 | continue; 127 | } 128 | uint32_t s_1 = e1->query_start_offset; 129 | uint32_t e_1 = e1->query_end_offset; 130 | for (auto e2 = e1 + 1; e2 != extend_alignments.end(); e2++) { 131 | if (!e2->do_print) { 132 | continue; 133 | } 134 | if (e2->read_num != e1->read_num) { 135 | break; 136 | } 137 | if (e1->chr_id != e2->chr_id) { 138 | break; 139 | } 140 | e2->do_print = false; 141 | } 142 | } 143 | 144 | for (auto e: extend_alignments) { 145 | if (e.do_print) { 146 | Read read = reads[e.read_num]; 147 | io_lock.lock(); 148 | 149 | int score = e.score; 150 | std::string r1_name = Index::chr_id[e.chr_id]; 151 | std::string r2_name = read.description; 152 | int r2_strand = (e.strand == '-') ? 1 : 0; 153 | uint32_t ref_start = 1 + e.reference_start_offset; 154 | uint32_t query_start = 1 + e.query_start_offset; 155 | uint32_t ref_end = 1 + e.reference_end_offset; 156 | uint32_t query_end = 1 + e.query_end_offset; 157 | uint32_t ref_align_len = ((e.reference_end_offset + 1) - e.reference_start_offset); 158 | uint32_t query_align_len = ((e.query_end_offset + 1) - e.query_start_offset); 159 | uint32_t ovl_len = 0, matches = 0; 160 | for (int i = 0; i < e.aligned_reference_str.length(); i++) { 161 | if (toupper(e.aligned_reference_str[i]) == toupper(e.aligned_query_str[i])) { 162 | matches +=1; 163 | } 164 | } 165 | ovl_len = (ref_align_len + query_align_len)/2; 166 | float error = (1.0*(ovl_len - matches))/ovl_len; 167 | 168 | if ((ovl_len >= cfg.min_overlap) && (r1_name != r2_name)){ 169 | printf ("%s %s %.3f %d %d %lu %lu %lu %d %lu %lu %lu\n", r1_name.c_str(), r2_name.c_str(), error, matches, 0, ref_start, ref_end, Index::chr_len_unpadded[e.chr_id], r2_strand, query_start, query_end, read.seq.size()); 170 | printf("%s\n", e.aligned_reference_str.c_str()); 171 | printf("%s\n", e.aligned_query_str.c_str()); 172 | printf ("%s %s %.3f %d %d %lu %lu %lu %d %lu %lu %lu\n", r2_name.c_str(), r1_name.c_str(), error, matches, r2_strand, query_start, query_end, read.seq.size(), 0, ref_start, ref_end, Index::chr_len_unpadded[e.chr_id]); 173 | printf("%s\n", e.aligned_query_str.c_str()); 174 | printf("%s\n", e.aligned_reference_str.c_str()); 175 | 176 | } 177 | io_lock.unlock(); 178 | } 179 | } 180 | } 181 | size_t printer_body::operator()(printer_input input) 182 | { 183 | size_t token = get<1>(input); 184 | if (cfg.do_overlap == 1) { 185 | mhap_printer(input); 186 | } 187 | else { 188 | sam_printer(input); 189 | } 190 | return token; 191 | }; 192 | 193 | 194 | SamFields printer_body::AlignmentToSam (Read read, ExtendAlignments e) { 195 | SamFields sf; 196 | 197 | sf.QNAME = std::string(read.description.c_str()); 198 | sf.FLAG = 0; 199 | if (e.strand == '-') { 200 | sf.FLAG += 16; 201 | char* read_char = (char*) read.rc_seq.data(); 202 | const size_t read_len = read.rc_seq.size(); 203 | sf.SEQ = std::string(read_char, read_len); 204 | } 205 | else { 206 | char* read_char = (char*) read.seq.data(); 207 | const size_t read_len = read.seq.size(); 208 | sf.SEQ = std::string(read_char, read_len); 209 | } 210 | 211 | sf.FLAG += 64; 212 | 213 | sf.RNAME = std::string(Index::chr_id[e.chr_id].c_str()); 214 | sf.POS = 1 + e.reference_start_offset; 215 | 216 | // UNUNSED. FOR LATER 217 | sf.MAPQ = 60; 218 | 219 | // ------------ CIGAR ------------- // 220 | std::vector cigar; 221 | cigar.clear(); 222 | 223 | char op = 'Z'; 224 | char prev_op = 'Z'; 225 | size_t num_op = 0; 226 | std::string num_op_str = ""; 227 | 228 | if (e.query_start_offset > 0) { 229 | num_op = e.query_start_offset; 230 | op = 'S'; 231 | num_op_str = std::to_string(num_op); 232 | for (int i = 0; i < num_op_str.length(); i++) { 233 | cigar.push_back(num_op_str[i]); 234 | } 235 | cigar.push_back(op); 236 | } 237 | 238 | assert(e.aligned_reference_str.length() == e.aligned_query_str.length()); 239 | num_op = 0; 240 | for (int i = 0; i < e.aligned_reference_str.length(); i++) { 241 | char r = e.aligned_reference_str[i]; 242 | char q = e.aligned_query_str[i]; 243 | if (r == '-') { 244 | op = 'I'; 245 | } 246 | else if (q == '-') { 247 | op = 'D'; 248 | } 249 | else { 250 | op = 'M'; 251 | } 252 | // else if (toupper(r) == toupper(q)) { 253 | // op = '='; 254 | // } 255 | // else { 256 | // op = 'X'; 257 | // } 258 | if (op == prev_op) { 259 | num_op++; 260 | } 261 | else { 262 | if (num_op > 0) { 263 | num_op_str = std::to_string(num_op); 264 | for (int i = 0; i < num_op_str.length(); i++) { 265 | cigar.push_back(num_op_str[i]); 266 | } 267 | cigar.push_back(prev_op); 268 | } 269 | num_op = 1; 270 | } 271 | prev_op = op; 272 | } 273 | 274 | if (num_op > 0) { 275 | num_op_str = std::to_string(num_op); 276 | for (int i = 0; i < num_op_str.length(); i++) { 277 | cigar.push_back(num_op_str[i]); 278 | } 279 | cigar.push_back(prev_op); 280 | } 281 | 282 | num_op = (e.query_length - e.query_end_offset - 1); 283 | if (num_op > 0) { 284 | op = 'S'; 285 | num_op_str = std::to_string(num_op); 286 | for (int i = 0; i < num_op_str.length(); i++) { 287 | cigar.push_back(num_op_str[i]); 288 | } 289 | cigar.push_back(op); 290 | } 291 | 292 | sf.CIGAR = (cigar.size() == 0) ? "*" : std::string(cigar.begin(), cigar.end()); 293 | 294 | 295 | // ------------ END CIGAR ------------- // 296 | 297 | sf.RNEXT = "*"; 298 | sf.PNEXT = 0; 299 | sf.TLEN = 0; 300 | sf.QUAL = "*"; 301 | sf.SCORE = e.score; 302 | //FOR LATER 303 | sf.CHAIN_SCORE = e.score; 304 | 305 | return sf; 306 | } 307 | 308 | -------------------------------------------------------------------------------- /software/seed_pos_table.cpp: -------------------------------------------------------------------------------- 1 | #define NOMINMAX 2 | #include 3 | #include 4 | 5 | #include "tbb/parallel_scan.h" 6 | #include "tbb/parallel_sort.h" 7 | #include "tbb/blocked_range.h" 8 | #include "tbb/scalable_allocator.h" 9 | 10 | #include "seed_pos_table.h" 11 | #include "Processor.h" 12 | 13 | SeedPosTable::SeedPosTable() { 14 | ref_size_ = 0; 15 | kmer_size_ = 0; 16 | minimizer_window_ = 0; 17 | max_stride_ = 1; 18 | shape_size_ = 0; 19 | num_bins_ = 0; 20 | avg_hits_ = 0; 21 | } 22 | 23 | int SeedPosTable::GetKmerSize() { 24 | return kmer_size_; 25 | } 26 | 27 | bool SeedPosTable::IsPresent(uint32_t index) { 28 | uint32_t start_index = seedBuckets[index]; 29 | uint32_t end_index = seedBuckets[index + 1]; 30 | return (end_index - start_index <= kmer_max_occurence_); 31 | } 32 | 33 | 34 | template 35 | inline __m256i _mm256_shift_left_si256(__m256i a) { 36 | __m256i c = _mm256_permute2x128_si256(a, a, 0x08); 37 | return _mm256_alignr_epi8(a, c, 16 - __N); 38 | } 39 | 40 | SeedPosTable::SeedPosTable(uint32_t ref_length, const int seed_size, const int minimizer_window, int max_stride, const uint32_t seed_occurence_multiple, const uint32_t bin_size, 41 | const tbb::concurrent_vector &minimizers, 42 | uint32_t* seedHistogram, const std::size_t histogramSize) { 43 | int kmer_size = seed_size; 44 | shape_size_ = seed_size; 45 | minimizer_window_ = minimizer_window; 46 | max_stride_ = max_stride; 47 | 48 | assert(kmer_size <= 15); 49 | assert(kmer_size > 3); 50 | kmer_size_ = kmer_size; 51 | bin_size_ = bin_size; 52 | log_bin_size_ = (uint32_t)(log2(bin_size_)); 53 | ref_size_ = ref_length; 54 | 55 | kmer_max_occurence_ = seed_occurence_multiple * (1 + ((ref_length) >> (2 * kmer_size))); 56 | 57 | uint32_t seedCount = 0; 58 | for (auto &miniList : minimizers) 59 | { 60 | seedCount += miniList.size(); 61 | } 62 | 63 | // Prefix Sum 64 | seedBuckets = (uint32_t*)scalable_aligned_malloc((histogramSize + 1) * sizeof(uint32_t), 32); 65 | 66 | __m256i _sum = _mm256_setzero_si256(); 67 | _mm256_storeu_si256((__m256i*)(seedBuckets), _sum); 68 | 69 | for (size_t bucketIndex = 0; bucketIndex < histogramSize; bucketIndex += 8) 70 | { 71 | __m256i _buckets = _mm256_load_si256((__m256i*)(seedHistogram + bucketIndex)); 72 | 73 | // Vector prefix sum 74 | _buckets = _mm256_add_epi32( 75 | _buckets, 76 | _mm256_shift_left_si256<4>( 77 | _buckets)); 78 | 79 | _buckets = _mm256_add_epi32( 80 | _buckets, 81 | _mm256_shift_left_si256<8>( 82 | _buckets)); 83 | 84 | _buckets = _mm256_add_epi32( 85 | _buckets, 86 | _mm256_permute2x128_si256( 87 | _buckets, 88 | _buckets, 89 | 0x08)); 90 | 91 | _buckets = _mm256_add_epi32( 92 | _buckets, 93 | _sum); 94 | 95 | _mm256_storeu_si256((__m256i*)(seedBuckets + bucketIndex + 1), _buckets); 96 | 97 | _sum = _mm256_permutevar8x32_epi32( 98 | _buckets, 99 | _mm256_setr_epi32(7, 7, 7, 7, 7, 7, 7, 7)); 100 | } 101 | 102 | /* 103 | uint32_t *seedBuckets2 = (uint32_t*)scalable_malloc((histogramSize + 1) * sizeof(uint32_t)); 104 | uint32_t sum = 0; 105 | for (size_t i = 0; i < histogramSize; i++) 106 | { 107 | seedBuckets2[i] = sum; 108 | sum += seedHistogram[i]; 109 | } 110 | seedBuckets2[histogramSize] = sum; 111 | 112 | for (size_t i = 0; i <= histogramSize; i++) 113 | { 114 | assert(seedBuckets[i] == seedBuckets2[i]); 115 | } 116 | */ 117 | 118 | avg_hits_ = 1 + (seedCount / (1 << 2 * kmer_size_)); 119 | 120 | assert(seedBuckets[histogramSize] == seedCount); 121 | 122 | // Bucket sort 123 | seedPositions = (uint32_t*)scalable_malloc(seedCount * sizeof(uint32_t)); 124 | 125 | // for (std::size_t chr = 0; chr < minimizers.size(); chr++) 126 | // { 127 | // auto miniList = minimizers[chr]; 128 | // 129 | // const uint32_t localCount = miniList.size(); 130 | // 131 | // for (uint32_t i = 0; i < localCount; i++) 132 | // { 133 | // uint64_t minimizer = miniList[i]; 134 | // 135 | // uint32_t pos = ((minimizer << 32) >> 32); 136 | // uint32_t seed = (minimizer >> 32); 137 | // 138 | // uint32_t posIndex = seedBuckets[seed] + (--seedHistogram[seed]); 139 | // seedPositions[posIndex] = pos; 140 | // } 141 | // } 142 | 143 | tbb::parallel_for(tbb::blocked_range(0, minimizers.size()), 144 | [&](const tbb::blocked_range &r) { 145 | for (std::size_t chr = r.begin(); chr < r.end(); chr++) 146 | { 147 | auto miniList = minimizers[chr]; 148 | 149 | const uint32_t localCount = miniList.size(); 150 | 151 | for (uint32_t i = 0; i < localCount; i++) 152 | { 153 | uint64_t minimizer = miniList[i]; 154 | 155 | uint32_t pos = ((minimizer << 32) >> 32); 156 | uint32_t seed = (minimizer >> 32); 157 | 158 | // uint32_t posIndex = seedBuckets[seed] + InterlockedDecrement(seedHistogram + seed); 159 | uint32_t posIndex = seedBuckets[seed] + (__sync_fetch_and_add(&seedHistogram[seed], -1)-1); 160 | seedPositions[posIndex] = pos; 161 | } 162 | } 163 | }); 164 | 165 | // sort buckets by position 166 | tbb::parallel_for(tbb::blocked_range(0, histogramSize), 167 | [&](const tbb::blocked_range &r) { 168 | for (std::size_t i = r.begin(); i < r.end(); i++) { 169 | if ((seedBuckets[i] < seedBuckets[i + 1]) && (seedBuckets[i + 1] - seedBuckets[i] <= kmer_max_occurence_)) 170 | { 171 | std::sort(seedPositions + seedBuckets[i], seedPositions + seedBuckets[i + 1]); 172 | } 173 | } 174 | }); 175 | 176 | /* 177 | // Histogram should be empty by now 178 | for (uint32_t i = 0; i < histogramSize; i++) { 179 | assert(seedHistogram[i] == 0); 180 | } 181 | 182 | uint64_t* miniArray = (uint64_t*)scalable_malloc(ref_length * sizeof(uint64_t)); 183 | 184 | // Compact the minimizers 185 | uint32_t curr = 0; 186 | 187 | for (auto &miniList : minimizers) 188 | { 189 | const uint32_t localCount = miniList.size(); 190 | 191 | for (uint32_t i = 0; i < localCount; i++) 192 | { 193 | miniArray[curr++] = miniList[i]; 194 | } 195 | } 196 | 197 | assert(curr == seedCount); 198 | 199 | // Compare with the slow sort method 200 | tbb::parallel_sort(miniArray, miniArray + seedCount); 201 | 202 | uint32_t *index_table_; 203 | uint32_t *pos_table_; 204 | 205 | index_table_size_ = ((uint32_t)1 << 2 * kmer_size) + 1; 206 | index_table_ = new uint32_t[index_table_size_]; 207 | 208 | pos_table_ = new uint32_t[seedCount]; 209 | 210 | uint32_t curr_index = 0; 211 | uint32_t seed, pos; 212 | 213 | for (uint32_t i = 0; i < seedCount; i++) { 214 | pos = ((miniArray[i] << 32) >> 32); 215 | seed = (miniArray[i] >> 32); 216 | pos_table_[i] = pos; 217 | if (seed > curr_index) { 218 | for (uint32_t s = curr_index; s < seed; s++) { 219 | index_table_[s] = i; 220 | } 221 | curr_index = seed; 222 | } 223 | } 224 | for (uint32_t i = curr_index; i < index_table_size_; i++) { 225 | index_table_[i] = seedCount; 226 | } 227 | 228 | for (uint32_t i = 0; i < histogramSize; i++) { 229 | assert(index_table_[i] == seedBuckets[i + 1]); 230 | } 231 | 232 | for (uint32_t i = 0; i < seedCount; i++) { 233 | assert(pos_table_[i] == seedPositions[i]); 234 | } 235 | 236 | delete[] index_table_; 237 | delete[] pos_table_; 238 | scalable_free(miniArray); 239 | */ 240 | } 241 | 242 | SeedPosTable::~SeedPosTable() { 243 | scalable_aligned_free(seedBuckets); 244 | scalable_free(seedPositions); 245 | } 246 | 247 | static inline int collinear_score(uint32_t h1, uint32_t o1, uint32_t h2, uint32_t o2) { 248 | return ((h1 <= h2) && (o1 <= o2)) ? 1 : -(1 << 24); 249 | } 250 | 251 | 252 | std::vector SeedPosTable::DSOFT(char* query, uint32_t query_length, int N, int threshold, size_t max_hits, size_t max_candidates, int overlap) 253 | { 254 | uint64_t k = kmer_size_; 255 | uint64_t w = minimizer_window_; 256 | 257 | uint64_t* minimizers = (uint64_t*)scalable_malloc(query_length * sizeof(uint64_t)); 258 | 259 | uint64_t min_count = 0; 260 | 261 | iterate_minimizers(query, query_length, k, w, 262 | [&](uint64_t p, uint32_t m) { 263 | minimizers[min_count] = (p << 32) + m; 264 | min_count++; 265 | }); 266 | 267 | //#ifdef _DEBUG 268 | // uint32_t qlen_2bit = (query_length + 15) / 16; 269 | // uint32_t* q_2bit = SeqToTwoBit(query, query_length); 270 | // 271 | // uint32_t* window = (uint32_t*)calloc(w, sizeof(uint32_t)); 272 | // uint64_t last_m = 0; 273 | // uint32_t last_p = 0; 274 | // 275 | // uint32_t num_min = 0; 276 | // 277 | // for (int p = 0; p < w - 1; p++) { 278 | // window[p] = hash32(GetSeedAtPos(q_2bit, p, k), k); 279 | // } 280 | // 281 | // for (uint32_t p = w - 1; p < 16 * qlen_2bit - k; p++) { 282 | // window[p%w] = hash32(GetSeedAtPos(q_2bit, p, k), k); 283 | // uint64_t m = Min_Window(window, w); 284 | // if ((m != last_m) || (p - last_p >= w)) { 285 | // assert(minimizers[num_min] == ((uint64_t)p << 32) + m); 286 | // num_min++; 287 | // last_m = m; 288 | // last_p = p; 289 | // } 290 | // } 291 | // 292 | // assert(num_min == min_count); 293 | // 294 | // free(window); 295 | //#endif 296 | 297 | uint32_t expected_hits = avg_hits_ * min_count; 298 | 299 | std::vector hits_array; 300 | hits_array.reserve(expected_hits); 301 | 302 | int num_seeds = 0; 303 | 304 | int stride = 1; //FIND_MAX(1, FIND_MIN(min_count/N, max_stride_)); 305 | 306 | for (int i = 0; i < min_count; i += stride) { 307 | 308 | uint32_t offset = (minimizers[i] >> 32); 309 | uint32_t index = ((minimizers[i] << 32) >> 32); 310 | 311 | uint32_t start_index = seedBuckets[index]; 312 | uint32_t end_index = seedBuckets[index + 1]; 313 | 314 | if (end_index - start_index <= kmer_max_occurence_) { 315 | num_seeds++; 316 | for (uint32_t j = start_index; j < end_index; j++) { 317 | uint32_t hit = seedPositions[j]; 318 | if (hit >= offset) { 319 | uint32_t bin = ((hit - offset) / bin_size_); 320 | uint64_t bin_offset = ((uint64_t)bin << 32) + offset; 321 | hits_array.push_back(Hits(bin_offset, hit)); 322 | } 323 | } 324 | } 325 | 326 | 327 | if (i > N) { 328 | if (overlap == 0) { 329 | stride = max_stride_; 330 | } 331 | else { 332 | break; 333 | } 334 | } 335 | } 336 | 337 | std::stable_sort(hits_array.begin(), hits_array.end(), CompareHits); 338 | 339 | 340 | int num_hits = 0; 341 | int num_candidates = 0; 342 | 343 | std::vector anchors; 344 | anchors.reserve(max_candidates); 345 | std::vector final_anchors; 346 | final_anchors.reserve(max_candidates); 347 | std::deque candidate_bins; 348 | anchors.reserve(max_candidates); 349 | 350 | num_hits = hits_array.size(); 351 | 352 | uint32_t last_bin = (1 << 31); 353 | uint32_t last_offset = 0; 354 | uint32_t curr_count = 0; 355 | 356 | for (int i = 0; i < num_hits; i++) { 357 | Hits next_hit = hits_array[i]; 358 | uint32_t offset = ((next_hit.bin_offset << 32) >> 32); 359 | uint32_t bin = (next_hit.bin_offset >> 32); 360 | uint32_t hit = next_hit.hit; 361 | if (bin == last_bin) { 362 | if (curr_count < threshold) { 363 | curr_count = ((offset - last_offset > kmer_size_) || (curr_count == 0)) ? curr_count + kmer_size_ : curr_count + (offset - last_offset); 364 | //curr_count += 1; 365 | if (curr_count >= threshold) { 366 | uint64_t anchor = ((uint64_t)hit << 32) + offset; 367 | anchors.push_back(Anchors(anchor)); 368 | candidate_bins.push_back(bin); 369 | if (num_candidates >= max_candidates) { 370 | break; 371 | } 372 | } 373 | } 374 | } 375 | else { 376 | last_bin = bin; 377 | curr_count = kmer_size_; 378 | if (curr_count >= threshold) { 379 | uint64_t anchor = ((uint64_t)hit << 32) + offset; 380 | anchors.push_back(Anchors(anchor)); 381 | candidate_bins.push_back(bin); 382 | if (num_candidates >= max_candidates) { 383 | break; 384 | } 385 | } 386 | //curr_count = 1; 387 | } 388 | last_offset = offset; 389 | } 390 | 391 | int chain_len = 0; 392 | int max_chain_len = 0; 393 | int curr_candidate = 0; 394 | uint32_t sv_num_bins = (overlap == 0) ? (1 << 12) / bin_size_ : 1; 395 | 396 | int start_idx = 0; 397 | 398 | // Each cadidate bin gets a set of hit offsets within a SV window 399 | for (int k = 0; k < anchors.size(); k++) { 400 | uint32_t curr_bin = candidate_bins[k]; 401 | bool start_assigned = false; 402 | anchors[k].num_chained_hits = 0; 403 | anchors[k].anchor_score = 0; 404 | 405 | for (int i = start_idx; i < num_hits; i++) { 406 | Hits next_hit = hits_array[i]; 407 | uint32_t bin = (next_hit.bin_offset >> 32); 408 | 409 | if ((bin + sv_num_bins >= curr_bin) && (bin < curr_bin + sv_num_bins)) { 410 | if (!start_assigned) { 411 | start_assigned = true; 412 | start_idx = i; 413 | } 414 | uint32_t offset = ((next_hit.bin_offset << 32) >> 32); 415 | uint32_t hit = next_hit.hit; 416 | 417 | uint64_t hit_offset = ((uint64_t)hit << 32) + offset; 418 | if (hit_offset <= anchors[k].hit_offset) { 419 | anchors[k].left_chained_hits.push_back(hit_offset); 420 | } 421 | if (hit_offset >= anchors[k].hit_offset) { 422 | anchors[k].right_chained_hits.push_back(hit_offset); 423 | } 424 | } 425 | else if ((bin >= curr_bin + sv_num_bins)) { 426 | break; 427 | } 428 | } 429 | 430 | assert(anchors[k].left_chained_hits.size() > 0); 431 | assert(anchors[k].right_chained_hits.size() > 0); 432 | std::sort(anchors[k].left_chained_hits.begin(), anchors[k].left_chained_hits.end()); 433 | std::sort(anchors[k].right_chained_hits.begin(), anchors[k].right_chained_hits.end()); 434 | 435 | // Left chain collinear 436 | int left_chain_size = anchors[k].left_chained_hits.size(); 437 | vector collinear_left_chained_hits; 438 | collinear_left_chained_hits.reserve(left_chain_size); 439 | 440 | uint64_t curr_hit_offset = anchors[k].left_chained_hits.back(); 441 | collinear_left_chained_hits.push_back(curr_hit_offset); 442 | 443 | for (int h = left_chain_size - 2; h >= 0; h--) { 444 | uint64_t hit_offset = anchors[k].left_chained_hits[h]; 445 | 446 | uint32_t h1 = (curr_hit_offset >> 32); 447 | uint32_t o1 = ((curr_hit_offset << 32) >> 32); 448 | uint32_t h2 = (hit_offset >> 32); 449 | uint32_t o2 = ((hit_offset << 32) >> 32); 450 | 451 | if ((h1 >= h2) && (o1 >= o2)) { 452 | //int match = FIND_MIN((h1 - h2), (o1 - o2)); 453 | int match = ((h1 - h2) > (o1 - o2)) ? (o1 - o2) : (h1 - h2); 454 | int gap = ((h1 - h2) > (o1 - o2)) ? ((h1 - h2) - (o1 - o2)) : ((o1 - o2) - (h1 - h2)); 455 | anchors[k].anchor_score += (match - gap / 10); 456 | collinear_left_chained_hits.push_back(hit_offset); 457 | curr_hit_offset = hit_offset; 458 | } 459 | } 460 | 461 | std::sort(collinear_left_chained_hits.begin(), collinear_left_chained_hits.end()); 462 | anchors[k].left_chained_hits.clear(); 463 | anchors[k].left_chained_hits.assign(collinear_left_chained_hits.begin(), collinear_left_chained_hits.end()); 464 | 465 | // Right chain collinear 466 | int right_chain_size = anchors[k].right_chained_hits.size(); 467 | vector collinear_right_chained_hits; 468 | collinear_right_chained_hits.reserve(right_chain_size); 469 | 470 | curr_hit_offset = anchors[k].right_chained_hits.front(); 471 | collinear_right_chained_hits.push_back(curr_hit_offset); 472 | for (int h = 1; h < right_chain_size; h++) { 473 | uint64_t hit_offset = anchors[k].right_chained_hits[h]; 474 | 475 | uint32_t h1 = (curr_hit_offset >> 32); 476 | uint32_t o1 = ((curr_hit_offset << 32) >> 32); 477 | uint32_t h2 = (hit_offset >> 32); 478 | uint32_t o2 = ((hit_offset << 32) >> 32); 479 | 480 | if ((h1 <= h2) && (o1 <= o2)) { 481 | int match = ((h2 - h1) > (o2 - o1)) ? (o2 - o1) : (h2 - h1); 482 | int gap = ((h2 - h1) > (o2 - o1)) ? ((h2 - h1) - (o2 - o1)) : ((o2 - o1) - (h2 - h1)); 483 | anchors[k].anchor_score += (match - gap / 10); 484 | collinear_right_chained_hits.push_back(hit_offset); 485 | curr_hit_offset = hit_offset; 486 | } 487 | } 488 | std::reverse(collinear_right_chained_hits.begin(), collinear_right_chained_hits.end()); 489 | anchors[k].right_chained_hits.clear(); 490 | anchors[k].right_chained_hits.assign(collinear_right_chained_hits.begin(), collinear_right_chained_hits.end()); 491 | 492 | 493 | chain_len = anchors[k].left_chained_hits.size() + anchors[k].right_chained_hits.size(); 494 | anchors[k].num_chained_hits = chain_len; 495 | if (chain_len > max_chain_len) { 496 | max_chain_len = chain_len; 497 | } 498 | } 499 | 500 | 501 | int num_secondary_chains = 0; 502 | 503 | // Discard anchors with overlapping range early 504 | if (!anchors.empty()) 505 | { 506 | std::sort(anchors.begin(), anchors.end(), 507 | [](const Anchors &a, const Anchors &b) { 508 | //return ((a.anchor_score > b.anchor_score) || ((a.anchor_score == b.anchor_score) && (a.hit_offset < b.hit_offset))); 509 | return ((a.num_chained_hits > b.num_chained_hits) || ((a.num_chained_hits == b.num_chained_hits) && (a.hit_offset < b.hit_offset))); 510 | }); 511 | 512 | for (auto a1 = anchors.begin(); a1 != anchors.end(); a1++) 513 | { 514 | uint32_t hs1 = (a1->left_chained_hits.front() >> 32); 515 | uint32_t he1 = (a1->right_chained_hits.front() >> 32); 516 | uint32_t s1 = ((a1->left_chained_hits.front() << 32) >> 32); 517 | uint32_t e1 = ((a1->right_chained_hits.front() << 32) >> 32); 518 | 519 | if (a1->num_chained_hits > 0) { 520 | num_secondary_chains++; 521 | } 522 | 523 | a1->num_chained_hits = a1->left_chained_hits.size() + a1->right_chained_hits.size(); 524 | 525 | final_anchors.push_back(*a1); 526 | 527 | if ((num_secondary_chains > 10) && (overlap == 0)) { 528 | // break; 529 | } 530 | 531 | // if (overlap == 0) { 532 | // for (auto a2 = a1 + 1; a2 != anchors.end(); a2++) 533 | // { 534 | // float r1 = (a1->hit_offset >> 32); 535 | // float q1 = ((a1->hit_offset << 32) >> 32); 536 | // float r2 = (a2->hit_offset >> 32); 537 | // float q2 = ((a2->hit_offset << 32) >> 32); 538 | // 539 | // float slope = std::abs((r1 - r2) / (q1 - q2) - 1); 540 | // if (std::abs((r1 - r2) / (q1 - q2) - 1) <= 0.15) 541 | // { 542 | // a2->num_chained_hits = -1; 543 | // } 544 | // } 545 | // } 546 | } 547 | 548 | } 549 | 550 | scalable_free(minimizers); 551 | 552 | return final_anchors; 553 | } 554 | 555 | -------------------------------------------------------------------------------- /software/seed_pos_table.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include "immintrin.h" 11 | 12 | #include "tbb/concurrent_vector.h" 13 | 14 | #include "ntcoding.h" 15 | 16 | using namespace std; 17 | 18 | #define nz_bins 25000000 19 | 20 | struct Hits { 21 | Hits(uint64_t a, uint32_t b) 22 | : bin_offset(a), 23 | hit(b) 24 | {}; 25 | 26 | uint64_t bin_offset; 27 | uint32_t hit; 28 | }; 29 | 30 | struct Anchors { 31 | Anchors(uint64_t a) 32 | : hit_offset(a) 33 | {}; 34 | 35 | uint64_t hit_offset; 36 | int num_chained_hits; 37 | int anchor_score; 38 | vector left_chained_hits; 39 | vector right_chained_hits; 40 | }; 41 | 42 | static inline bool CompareHits (Hits h1, Hits h2) { 43 | //return ((h1.bin_offset < h2.bin_offset) || ((h1.bin_offset == h2.bin_offset) && (h1.hit < h2.hit))); 44 | return ((h1.bin_offset < h2.bin_offset)); 45 | } 46 | 47 | typedef std::vector mini_list; 48 | 49 | #define _mm256_shuffle_epx32(a, b, imm) _mm256_castps_si256(_mm256_shuffle_ps(_mm256_castsi256_ps(a), _mm256_castsi256_ps(b), imm)) 50 | 51 | template 52 | inline __m256i _mm256_shift_left_si256(__m256i a, __m256i b) { 53 | __m256i c = _mm256_permute2x128_si256(a, b, 0x03); 54 | return _mm256_alignr_epi8(a, c, 16 - __N); 55 | } 56 | 57 | template 58 | inline __m256i _mm256_shift_right_si256(__m256i a, __m256i b) { 59 | __m256i c = _mm256_permute2x128_si256(a, b, 0x21); 60 | return _mm256_alignr_epi8(c, a, __N); 61 | } 62 | 63 | inline uint64_t _q_to_2_bit(const char* pQuery) 64 | { 65 | // Load 16 characters 66 | __m128i _q = _mm_loadu_si128((const __m128i*) pQuery); 67 | 68 | __m128i _q_2bit = _mm_shuffle_epi8( 69 | // 8 -> 2 bit conversion table, N character is mapped to zero 70 | _mm_set_epi8(0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 3, 1, 0, 0, 0), 71 | _mm_and_si128( 72 | _q, 73 | // 8 -> 2 bit conversion mask 74 | _mm_set1_epi8(0x0f))); 75 | 76 | // PEXT mask for compacting the sequence 77 | const uint64_t pext_mask_8_2 = 0x0303030303030303ull; 78 | 79 | uint64_t q_2bit = 80 | _pext_u64(_mm_extract_epi64(_q_2bit, 1), pext_mask_8_2) << 16 | 81 | _pext_u64(_mm_extract_epi64(_q_2bit, 0), pext_mask_8_2); 82 | 83 | return q_2bit; 84 | } 85 | 86 | inline __m256i _get_seeds(const __m256i _min_qword, const __m256i _kmer_mask) 87 | { 88 | // Vector of 8 minimizers 89 | __m256i _min_x_8 = _mm256_and_si256( 90 | _mm256_shuffle_epx32( 91 | _mm256_srlv_epi64( 92 | _min_qword, 93 | _mm256_set_epi64x( 94 | 10ull, 8ull, 2ull, 0ull)), 95 | _mm256_srlv_epi64( 96 | _min_qword, 97 | _mm256_set_epi64x( 98 | 14ull, 12ull, 6ull, 4ull)), 99 | 0x88), 100 | _kmer_mask); 101 | 102 | // hash32 103 | //key = (~key + (key << 21)) & m; 104 | _min_x_8 = _mm256_and_si256( 105 | _mm256_add_epi32( 106 | _mm256_xor_si256( 107 | _min_x_8, 108 | _mm256_set1_epi32(-1)), 109 | _mm256_slli_epi32( 110 | _min_x_8, 111 | 21)), 112 | _kmer_mask); 113 | 114 | //key = key ^ (key >> 24); 115 | _min_x_8 = _mm256_xor_si256( 116 | _min_x_8, 117 | _mm256_srli_epi32( 118 | _min_x_8, 119 | 24)); 120 | 121 | //key = ((key + (key << 3)) + (key << 8)) & m; 122 | _min_x_8 = _mm256_and_si256( 123 | _mm256_add_epi32( 124 | _min_x_8, 125 | _mm256_add_epi32( 126 | _mm256_slli_epi32( 127 | _min_x_8, 128 | 3), 129 | _mm256_slli_epi32( 130 | _min_x_8, 131 | 8))), 132 | _kmer_mask); 133 | 134 | //key = key ^ (key >> 14); 135 | _min_x_8 = _mm256_xor_si256( 136 | _min_x_8, 137 | _mm256_srli_epi32( 138 | _min_x_8, 139 | 14)); 140 | 141 | //key = ((key + (key << 2)) + (key << 4)) & m; 142 | _min_x_8 = _mm256_and_si256( 143 | _mm256_add_epi32( 144 | _min_x_8, 145 | _mm256_add_epi32( 146 | _mm256_slli_epi32( 147 | _min_x_8, 148 | 2), 149 | _mm256_slli_epi32( 150 | _min_x_8, 151 | 4))), 152 | _kmer_mask); 153 | 154 | //key = key ^ (key >> 28); 155 | _min_x_8 = _mm256_xor_si256( 156 | _min_x_8, 157 | _mm256_srli_epi32( 158 | _min_x_8, 159 | 28)); 160 | 161 | //key = (key + (key << 31)) & m; 162 | _min_x_8 = _mm256_and_si256( 163 | _mm256_add_epi32( 164 | _min_x_8, 165 | _mm256_slli_epi32( 166 | _min_x_8, 167 | 31)), 168 | _kmer_mask); 169 | 170 | return _min_x_8; 171 | } 172 | 173 | inline __m256i _sliding_minimum_5w(__m256i &_min_window, const __m256i _min_seeds) 174 | { 175 | static const __m256i _mm256_000f_epu32 = _mm256_set_epi32( 176 | 0, 0, 0, 0xffffffff, 177 | 0, 0, 0, 0xffffffff); 178 | 179 | // Suffix scan 180 | __m256i _min_suffix = _mm256_min_epu32( 181 | _min_seeds, 182 | _mm256_or_si256( 183 | _mm256_bsrli_epi128( 184 | _min_seeds, 185 | 4), 186 | _mm256_bslli_epi128( 187 | _mm256_000f_epu32, 188 | 12))); 189 | 190 | _min_suffix = _mm256_min_epu32( 191 | _min_suffix, 192 | _mm256_shuffle_epx32( 193 | _min_suffix, 194 | _mm256_000f_epu32, 195 | 0x0e)); 196 | 197 | // Prefix scan 198 | __m256i _min_prefix = _mm256_min_epu32( 199 | _mm256_or_si256( 200 | _mm256_bslli_epi128( 201 | _min_seeds, 202 | 4), 203 | _mm256_000f_epu32), 204 | _min_seeds); 205 | 206 | _min_prefix = _mm256_min_epu32( 207 | _mm256_shuffle_epx32( 208 | _mm256_000f_epu32, 209 | _min_prefix, 210 | 0x40), 211 | _min_prefix); 212 | 213 | // Sliding window minimum 214 | __m256i _min_result = _mm256_min_epu32( 215 | _mm256_permute2x128_si256( 216 | _min_window, 217 | _min_suffix, 218 | 0x21), 219 | _min_prefix); 220 | 221 | _min_window = _min_suffix; 222 | 223 | return _min_result; 224 | } 225 | 226 | inline __m256i _sliding_minimum_9w(__m256i &_min_window, const __m256i _min_seeds) 227 | { 228 | static const __m256i _mm256_ff_epu32 = _mm256_set1_epi32(0xffffffff); 229 | 230 | // Suffix scan 231 | __m256i _min_suffix = _mm256_min_epu32( 232 | _min_seeds, 233 | _mm256_shift_right_si256<4>( 234 | _min_seeds, 235 | _mm256_ff_epu32)); 236 | 237 | _min_suffix = _mm256_min_epu32( 238 | _min_suffix, 239 | _mm256_shift_right_si256<8>( 240 | _min_suffix, 241 | _mm256_ff_epu32)); 242 | 243 | _min_suffix = _mm256_min_epu32( 244 | _min_suffix, 245 | _mm256_permute2x128_si256( 246 | _min_suffix, 247 | _mm256_ff_epu32, 248 | 0x21)); 249 | 250 | // Prefix scan 251 | __m256i _min_prefix = _mm256_min_epu32( 252 | _min_seeds, 253 | _mm256_shift_left_si256<4>( 254 | _min_seeds, 255 | _mm256_ff_epu32)); 256 | 257 | _min_prefix = _mm256_min_epu32( 258 | _min_prefix, 259 | _mm256_shift_left_si256<8>( 260 | _min_prefix, 261 | _mm256_ff_epu32)); 262 | 263 | _min_prefix = _mm256_min_epu32( 264 | _min_prefix, 265 | _mm256_permute2x128_si256( 266 | _min_prefix, 267 | _mm256_ff_epu32, 268 | 0x03)); 269 | 270 | // Sliding window minimum 271 | __m256i _min_result = _mm256_min_epu32( 272 | _min_window, 273 | _min_prefix); 274 | 275 | _min_window = _min_suffix; 276 | 277 | return _min_result; 278 | } 279 | 280 | template 281 | void iterate_minimizers_qw(const char* query, const uint32_t query_length, uint64_t k, uint64_t w, Body body) 282 | { 283 | uint64_t kmer_mask = (1ull << (k << 1)) - 1ull; 284 | 285 | uint64_t last_m = 0, last_p = 0; 286 | 287 | uint32_t* pWindow = (uint32_t*)calloc(w, sizeof(uint32_t)); 288 | 289 | // Priming the vector loop 290 | uint64_t min_current = _q_to_2_bit(query); 291 | 292 | uint64_t min_next = _q_to_2_bit(query + 16); 293 | 294 | uint64_t min_qword = min_current | (min_next << 32); 295 | 296 | uint64_t p = 0; 297 | 298 | uint32_t qlen_centinel = (~0x0f & (query_length + 15)) - k; 299 | 300 | // Fill the window 301 | for (; p < w - 1; p++) { 302 | pWindow[p] = hash32(min_qword & kmer_mask, k); 303 | min_qword >>= 2; 304 | } 305 | 306 | // Finish the first batch 307 | for (/*p = w - 1*/; p < 16; p++) 308 | { 309 | pWindow[p%w] = hash32(min_qword & kmer_mask, k); 310 | min_qword >>= 2; 311 | uint32_t m = Min_Window(pWindow, w); 312 | if ((m != last_m) || (p - last_p >= w)) 313 | { 314 | body(p, m); 315 | last_m = m; 316 | last_p = p; 317 | } 318 | } 319 | 320 | min_current = min_next; 321 | 322 | // Main loop 323 | while (p < qlen_centinel) 324 | { 325 | min_next = _q_to_2_bit(query + p + 16); 326 | 327 | min_qword = min_current | (min_next << 32); 328 | 329 | __m256i _kmer_mask = _mm256_set1_epi32( 330 | (1 << (k << 1)) - 1); 331 | 332 | __m256i _min_qword = _mm256_set1_epi64x(min_qword); 333 | 334 | __m256i _min_seeds = _get_seeds(_min_qword, _kmer_mask); 335 | 336 | for (uint32_t i = 0; (i < 8) && (p < qlen_centinel); i++, p++) 337 | { 338 | __m128i _i = _mm_cvtsi32_si128(i); 339 | __m256i _val = _mm256_permutevar8x32_epi32(_min_seeds, _mm256_castsi128_si256(_i)); 340 | pWindow[p%w] = _mm_cvtsi128_si32(_mm256_castsi256_si128(_val)); 341 | 342 | uint32_t m = Min_Window(pWindow, w); 343 | if ((m != last_m) || (p - last_p >= w)) 344 | { 345 | body(p, m); 346 | last_m = m; 347 | last_p = p; 348 | } 349 | } 350 | 351 | _min_qword = _mm256_srli_epi64( 352 | _min_qword, 353 | 16); 354 | 355 | _min_seeds = _get_seeds(_min_qword, _kmer_mask); 356 | 357 | for (uint32_t i = 0; (i < 8) && (p < qlen_centinel); i++, p++) 358 | { 359 | __m128i _i = _mm_cvtsi32_si128(i); 360 | __m256i _val = _mm256_permutevar8x32_epi32(_min_seeds, _mm256_castsi128_si256(_i)); 361 | pWindow[p%w] = _mm_cvtsi128_si32(_mm256_castsi256_si128(_val)); 362 | 363 | uint32_t m = Min_Window(pWindow, w); 364 | if ((m != last_m) || (p - last_p >= w)) 365 | { 366 | body(p, m); 367 | last_m = m; 368 | last_p = p; 369 | } 370 | } 371 | 372 | min_current = min_next; 373 | } 374 | } 375 | 376 | // Special case with w set to 5 377 | template 378 | void iterate_minimizers_5w(const char* query, const uint32_t query_length, uint64_t k, Body body) 379 | { 380 | const int64_t w = 5ull; 381 | 382 | uint64_t last_m = 0, last_p = 0; 383 | 384 | // Priming the vector loop 385 | __m256i _kmer_mask = _mm256_set1_epi32( 386 | (1 << (k << 1)) - 1); 387 | 388 | uint64_t min_current = _q_to_2_bit(query); 389 | 390 | __m256i _min_window = _mm256_setzero_si256(); 391 | 392 | uint64_t qlen_centinel = (~0x0full & (query_length + 15ull)) - k; 393 | 394 | // Main loop 395 | for (uint64_t p = 0; p < qlen_centinel;) 396 | { 397 | uint64_t min_next = _q_to_2_bit(query + p + 16); 398 | 399 | uint64_t min_qword = min_current | (min_next << 32); 400 | 401 | __m256i _min_qword = _mm256_set1_epi64x(min_qword); 402 | 403 | __m256i _min_seeds = _get_seeds(_min_qword, _kmer_mask); 404 | 405 | __m256i _min_result = _sliding_minimum_5w(_min_window, _min_seeds); 406 | 407 | for (uint32_t i = 0; (i < 8) && (p < qlen_centinel); i++, p++) 408 | { 409 | __m128i _i = _mm_cvtsi32_si128(i); 410 | __m256i _val = _mm256_permutevar8x32_epi32(_min_result, _mm256_castsi128_si256(_i)); 411 | uint32_t m = _mm_cvtsi128_si32(_mm256_castsi256_si128(_val)); 412 | 413 | if ((m != last_m) || (p - last_p >= w)) 414 | { 415 | body(p, m); 416 | last_m = m; 417 | last_p = p; 418 | } 419 | } 420 | 421 | _min_qword = _mm256_srli_epi64( 422 | _min_qword, 423 | 16); 424 | 425 | _min_seeds = _get_seeds(_min_qword, _kmer_mask); 426 | 427 | _min_result = _sliding_minimum_5w(_min_window, _min_seeds); 428 | 429 | for (uint32_t i = 0; (i < 8) && (p < qlen_centinel); i++, p++) 430 | { 431 | __m128i _i = _mm_cvtsi32_si128(i); 432 | __m256i _val = _mm256_permutevar8x32_epi32(_min_result, _mm256_castsi128_si256(_i)); 433 | uint32_t m = _mm_cvtsi128_si32(_mm256_castsi256_si128(_val)); 434 | 435 | if ((m != last_m) || (p - last_p >= w)) 436 | { 437 | body(p, m); 438 | last_m = m; 439 | last_p = p; 440 | } 441 | } 442 | 443 | min_current = min_next; 444 | } 445 | } 446 | 447 | // Special case with w set to 9 448 | template 449 | void iterate_minimizers_9w(const char* query, const uint32_t query_length, uint64_t k, Body body) 450 | { 451 | const int64_t w = 9ull; 452 | 453 | uint64_t last_m = 0, last_p = 0; 454 | 455 | // Priming the vector loop 456 | __m256i _kmer_mask = _mm256_set1_epi32( 457 | (1 << (k << 1)) - 1); 458 | 459 | uint64_t min_current = _q_to_2_bit(query); 460 | 461 | __m256i _min_window = _mm256_setzero_si256(); 462 | 463 | uint64_t qlen_centinel = (~0x0full & (query_length + 15ull)) - k; 464 | 465 | // Main loop 466 | for (uint64_t p = 0; p < qlen_centinel;) 467 | { 468 | uint64_t min_next = _q_to_2_bit(query + p + 16); 469 | 470 | uint64_t min_qword = min_current | (min_next << 32); 471 | 472 | __m256i _min_qword = _mm256_set1_epi64x(min_qword); 473 | 474 | __m256i _min_seeds = _get_seeds(_min_qword, _kmer_mask); 475 | 476 | __m256i _min_result = _sliding_minimum_9w(_min_window, _min_seeds); 477 | 478 | for (uint32_t i = 0; (i < 8) && (p < qlen_centinel); i++, p++) 479 | { 480 | __m128i _i = _mm_cvtsi32_si128(i); 481 | __m256i _val = _mm256_permutevar8x32_epi32(_min_result, _mm256_castsi128_si256(_i)); 482 | uint32_t m = _mm_cvtsi128_si32(_mm256_castsi256_si128(_val)); 483 | 484 | if ((m != last_m) || (p - last_p >= w)) 485 | { 486 | body(p, m); 487 | last_m = m; 488 | last_p = p; 489 | } 490 | } 491 | 492 | _min_qword = _mm256_srli_epi64( 493 | _min_qword, 494 | 16); 495 | 496 | _min_seeds = _get_seeds(_min_qword, _kmer_mask); 497 | 498 | _min_result = _sliding_minimum_9w(_min_window, _min_seeds); 499 | 500 | for (uint32_t i = 0; (i < 8) && (p < qlen_centinel); i++, p++) 501 | { 502 | __m128i _i = _mm_cvtsi32_si128(i); 503 | __m256i _val = _mm256_permutevar8x32_epi32(_min_result, _mm256_castsi128_si256(_i)); 504 | uint32_t m = _mm_cvtsi128_si32(_mm256_castsi256_si128(_val)); 505 | 506 | if ((m != last_m) || (p - last_p >= w)) 507 | { 508 | body(p, m); 509 | last_m = m; 510 | last_p = p; 511 | } 512 | } 513 | 514 | min_current = min_next; 515 | } 516 | } 517 | 518 | template 519 | void iterate_minimizers(const char* query, const uint32_t query_length, uint64_t k, uint64_t w, Body body) 520 | { 521 | switch (w) 522 | { 523 | case 5: 524 | iterate_minimizers_5w(query, query_length, k, body); 525 | break; 526 | 527 | case 9: 528 | iterate_minimizers_9w(query, query_length, k, body); 529 | break; 530 | 531 | default: 532 | iterate_minimizers_qw(query, query_length, k, w, body); 533 | break; 534 | } 535 | } 536 | 537 | class SeedPosTable { 538 | private: 539 | uint32_t index_table_size_; 540 | uint32_t ref_size_; 541 | uint32_t bin_size_; 542 | uint32_t log_bin_size_; 543 | int kmer_size_; 544 | int minimizer_window_; 545 | int max_stride_; 546 | int shape_size_; 547 | uint32_t kmer_max_occurence_; 548 | 549 | uint32_t *seedBuckets; 550 | uint32_t *seedPositions; 551 | 552 | uint32_t num_bins_; 553 | 554 | uint32_t avg_hits_; 555 | 556 | 557 | public: 558 | SeedPosTable(); 559 | SeedPosTable(uint32_t ref_length, const int seed_size, const int minimizer_window, int max_stride, 560 | const uint32_t seed_occurence_multiple, const uint32_t bin_size, 561 | const tbb::concurrent_vector &minimizers, 562 | uint32_t* seedHistogram, const std::size_t histogramSize); 563 | //SeedPosTable(char* ref_str, uint32_t ref_length, int seed_size, int minimizer_window, uint32_t seed_occurence_multiple, uint32_t bin_size); 564 | ~SeedPosTable(); 565 | 566 | bool IsPresent(uint32_t index); 567 | int GetKmerSize(); 568 | std::vector DSOFT(char* query, uint32_t query_length, int N, int threshold, size_t max_hits, size_t max_candidates, int overlap); 569 | }; 570 | 571 | 572 | 573 | -------------------------------------------------------------------------------- /software/seeder.cpp: -------------------------------------------------------------------------------- 1 | #include "graph.h" 2 | 3 | #include "tbb/mutex.h" 4 | #include "tbb/parallel_for_each.h" 5 | 6 | filter_input seeder_body::operator()(seeder_input input) 7 | { 8 | reader_output &reads = get<0>(input); 9 | 10 | size_t token = get<1>(input); 11 | 12 | seeder_data output; 13 | 14 | output.fwAnchorBuckets.push_back(0ull); 15 | output.rcAnchorBuckets.push_back(0ull); 16 | 17 | tbb::mutex output_mutex; 18 | 19 | tbb::parallel_for_each( reads.cbegin(), reads.cend(), 20 | [&](const Read &read) 21 | { 22 | const size_t read_len = read.seq.size(); 23 | char *read_char = (char *)read.seq.data(); 24 | char *rev_read_char = (char *)read.rc_seq.data(); 25 | 26 | uint32_t kmer_max_occurence = cfg.seed_occurence_multiple * (1 + ((g_DRAM->referenceSize) >> (2 * cfg.seed_size))); 27 | size_t max_hits = kmer_max_occurence * cfg.num_seeds; 28 | 29 | // Forward reads 30 | auto fwAnchors = sa->DSOFT(read_char, read_len, cfg.num_seeds, cfg.dsoft_threshold, max_hits, cfg.max_candidates, cfg.do_overlap); 31 | 32 | output_mutex.lock(); 33 | output.fwAnchors.insert(output.fwAnchors.end(), fwAnchors.begin(), fwAnchors.end()); 34 | output.fwAnchorBuckets.push_back(output.fwAnchorBuckets.back() + fwAnchors.size()); 35 | output_mutex.unlock(); 36 | 37 | // Reverse-complement reads 38 | auto rcAnchors = sa->DSOFT(rev_read_char, read_len, cfg.num_seeds, cfg.dsoft_threshold, max_hits, cfg.max_candidates, cfg.do_overlap); 39 | 40 | output_mutex.lock(); 41 | output.rcAnchors.insert(output.rcAnchors.end(), rcAnchors.begin(), rcAnchors.end()); 42 | output.rcAnchorBuckets.push_back(output.rcAnchorBuckets.back() + rcAnchors.size()); 43 | output_mutex.unlock(); 44 | }); 45 | 46 | return filter_input(filter_payload(reads, output), token); 47 | } 48 | -------------------------------------------------------------------------------- /software/sender.cpp: -------------------------------------------------------------------------------- 1 | #include "graph.h" 2 | tbb::reader_writer_lock fpga_writer_lock; 3 | 4 | seeder_input reference_sender_body::operator()(seeder_input input) 5 | { 6 | auto &reads = get<0>(input); 7 | 8 | size_t token = get<1>(input); 9 | 10 | size_t word_size = WORD_SIZE; 11 | size_t max_char_to_send = MAX_CHAR_TO_SEND; 12 | 13 | size_t num_bytes_to_send = 0; 14 | 15 | //fpga_writer_lock.lock(); 16 | for (size_t i = 0; i < reads.size(); i++) 17 | { 18 | Read &read = reads[i]; 19 | 20 | const size_t read_len = read.seq.size(); 21 | char *read_char = (char *)read.seq.data(); 22 | 23 | size_t dram_start_addr = read_char - g_DRAM->buffer; 24 | 25 | // SEND READ 26 | for (size_t j = 0; j < read_len;) { 27 | num_bytes_to_send = std::min(max_char_to_send, read_len - j); 28 | if (num_bytes_to_send % word_size != 0) { 29 | num_bytes_to_send += word_size - (num_bytes_to_send % word_size); 30 | } 31 | 32 | assert(num_bytes_to_send % word_size == 0); 33 | 34 | InitializeDRAMMessage init_dram_message; 35 | GenerateInitializeMemoryMessage(init_dram_message, read_char, j, dram_start_addr, num_bytes_to_send); 36 | 37 | { 38 | InitializeDRAMMessageResponse init_dram_response; 39 | g_InitializeReferenceMemory(0, g_DRAM->buffer, init_dram_message, init_dram_response); 40 | } 41 | 42 | dram_start_addr += num_bytes_to_send; 43 | j += num_bytes_to_send; 44 | } 45 | } 46 | //fpga_writer_lock.unlock(); 47 | 48 | return input; 49 | } 50 | 51 | 52 | seeder_input read_sender_body::operator()(seeder_input input) 53 | { 54 | auto &reads = get<0>(input); 55 | 56 | size_t token = get<1>(input); 57 | 58 | size_t word_size = WORD_SIZE; 59 | size_t max_char_to_send = MAX_CHAR_TO_SEND; 60 | 61 | size_t num_bytes_to_send = 0; 62 | 63 | //fpga_writer_lock.lock(); 64 | for (size_t i = 0; i < reads.size(); i++) 65 | { 66 | Read &read = reads[i]; 67 | 68 | const size_t read_len = read.seq.size(); 69 | char *read_char = (char *)read.seq.data(); 70 | 71 | size_t dram_start_addr = read_char - g_DRAM->buffer; 72 | 73 | // SEND READ 74 | for (size_t j = 0; j < read_len;) { 75 | num_bytes_to_send = std::min(max_char_to_send, read_len - j); 76 | if (num_bytes_to_send % word_size != 0) { 77 | num_bytes_to_send += word_size - (num_bytes_to_send % word_size); 78 | } 79 | 80 | assert(num_bytes_to_send % word_size == 0); 81 | 82 | InitializeDRAMMessage init_dram_message; 83 | GenerateInitializeMemoryMessage(init_dram_message, read_char, j, dram_start_addr, num_bytes_to_send); 84 | 85 | { 86 | InitializeDRAMMessageResponse init_dram_response; 87 | g_InitializeReadMemory(0, g_DRAM->buffer, init_dram_message, init_dram_response); 88 | } 89 | 90 | dram_start_addr += num_bytes_to_send; 91 | j += num_bytes_to_send; 92 | } 93 | } 94 | //fpga_writer_lock.unlock(); 95 | 96 | return input; 97 | } 98 | --------------------------------------------------------------------------------