1 |
2 |
fentonc |
module sw_pe_affine(clk,
|
2 |
|
|
i_rst,
|
3 |
|
|
o_rst,
|
4 |
|
|
i_data,
|
5 |
|
|
i_preload,
|
6 |
|
|
i_left_m,
|
7 |
|
|
i_left_i,
|
8 |
|
|
i_high,
|
9 |
|
|
i_vld,
|
10 |
|
|
i_local,
|
11 |
|
|
o_right_m,
|
12 |
|
|
o_right_i,
|
13 |
|
|
o_high,
|
14 |
|
|
o_vld,
|
15 |
|
|
o_data,
|
16 |
|
|
start);
|
17 |
|
|
|
18 |
|
|
localparam
|
19 |
|
|
SCORE_WIDTH = 11,
|
20 |
|
|
N_A = 2'b00, //nucleotide "A"
|
21 |
|
|
N_G = 2'b01, //nucleotide "G"
|
22 |
|
|
N_T = 2'b10, //nucleotide "T"
|
23 |
|
|
N_C = 2'b11, //nucleotide "C"
|
24 |
|
|
INS_START = 3, //insertion penalty
|
25 |
|
|
INS_CONT = 1,
|
26 |
|
|
DEL_START = 3, //deletion penalty
|
27 |
|
|
DEL_CONT = 1,
|
28 |
|
|
TB_UP = 2'b00, //"UP" traceback pointer
|
29 |
|
|
TB_DIAG = 2'b01, //"DIAG" traceback pointer
|
30 |
|
|
TB_LEFT = 2'b10, //"LEFT" traceback pointer
|
31 |
|
|
GOPEN = 12,
|
32 |
|
|
GEXT = 4;
|
33 |
|
|
|
34 |
|
|
input wire clk;
|
35 |
|
|
input wire i_rst;
|
36 |
|
|
output reg o_rst;
|
37 |
|
|
input wire [1:0] i_data; //sequence being streamed in
|
38 |
|
|
input wire [1:0] i_preload; //fixed character assigned to this node
|
39 |
|
|
input wire [SCORE_WIDTH-1:0] i_left_m; //connection to left neighbor cell for M matrix
|
40 |
|
|
input wire [SCORE_WIDTH-1:0] i_left_i; //connection to left neighbor cell for I matrix
|
41 |
|
|
input wire i_vld; //valid data coming from neighbor
|
42 |
|
|
input wire i_local; //=1 if local alignment, =0 if global alignment
|
43 |
|
|
input wire start; //designate that you're on the left edge of the array
|
44 |
|
|
input wire [SCORE_WIDTH-1:0] i_high; //input of highest score from neighbor
|
45 |
|
|
output reg [SCORE_WIDTH-1:0] o_right_m; //output of score from t-1 for M matrix
|
46 |
|
|
output reg [SCORE_WIDTH-1:0] o_right_i; //output of score for t-1 for I matrix
|
47 |
|
|
output reg [SCORE_WIDTH-1:0] o_high; //output of currently highest score
|
48 |
|
|
|
49 |
|
|
output reg o_vld; //tells neighbor data is valid
|
50 |
|
|
output reg [1:0] o_data;
|
51 |
|
|
|
52 |
|
|
|
53 |
|
|
|
54 |
|
|
parameter LENGTH=48;
|
55 |
|
|
parameter LOGLENGTH = 6;
|
56 |
|
|
|
57 |
|
|
reg [1:0] state; //just state counter
|
58 |
|
|
|
59 |
|
|
reg [SCORE_WIDTH-1:0] l_diag_score_m;
|
60 |
|
|
reg [SCORE_WIDTH-1:0] l_diag_score_i;
|
61 |
|
|
|
62 |
|
|
wire [SCORE_WIDTH-1:0] right_m_nxt;
|
63 |
|
|
wire [SCORE_WIDTH-1:0] right_i_nxt;
|
64 |
|
|
wire [SCORE_WIDTH-1:0] left_open;
|
65 |
|
|
wire [SCORE_WIDTH-1:0] left_ext;
|
66 |
|
|
wire [SCORE_WIDTH-1:0] up_open;
|
67 |
|
|
wire [SCORE_WIDTH-1:0] up_ext;
|
68 |
|
|
wire [SCORE_WIDTH-1:0] left_max;
|
69 |
|
|
wire [SCORE_WIDTH-1:0] up_max;
|
70 |
|
|
wire [SCORE_WIDTH-1:0] rightmax;
|
71 |
|
|
wire [SCORE_WIDTH-1:0] start_left;
|
72 |
|
|
|
73 |
|
|
reg [SCORE_WIDTH-1:0] match;
|
74 |
|
|
wire [SCORE_WIDTH-1:0] max_score_a;
|
75 |
|
|
wire [SCORE_WIDTH-1:0] max_score_b;
|
76 |
|
|
wire [SCORE_WIDTH-1:0] left_score;
|
77 |
|
|
wire [SCORE_WIDTH-1:0] up_score;
|
78 |
|
|
wire [SCORE_WIDTH-1:0] diag_score;
|
79 |
|
|
wire [SCORE_WIDTH-1:0] neutral_score;
|
80 |
|
|
|
81 |
|
|
wire [SCORE_WIDTH-1:0] left_score_b;
|
82 |
|
|
|
83 |
|
|
|
84 |
|
|
//compute new score options
|
85 |
|
|
|
86 |
|
|
assign neutral_score = 11'b10000000000;
|
87 |
|
|
|
88 |
|
|
assign start_left = (state==2'b01) ? (l_diag_score_m - GOPEN) : (l_diag_score_m - GEXT);
|
89 |
|
|
|
90 |
|
|
assign left_open = i_left_m - GOPEN;
|
91 |
|
|
assign left_ext = i_left_i - GEXT;
|
92 |
|
|
assign up_open = o_right_m - GOPEN;
|
93 |
|
|
assign up_ext = o_right_i - GEXT;
|
94 |
|
|
assign left_max = start ? start_left : ((left_open > left_ext) ? left_open : left_ext);
|
95 |
|
|
assign up_max = (up_open > up_ext) ? up_open : up_ext;
|
96 |
|
|
|
97 |
|
|
assign right_m_nxt = match + ((l_diag_score_m > l_diag_score_i) ? l_diag_score_m : l_diag_score_i); //next m score
|
98 |
|
|
assign right_i_nxt = (left_max > up_max) ? left_max : up_max;
|
99 |
|
|
|
100 |
|
|
|
101 |
|
|
|
102 |
|
|
|
103 |
|
|
always@(posedge clk)
|
104 |
|
|
o_rst <= i_rst;
|
105 |
|
|
|
106 |
|
|
always@*
|
107 |
|
|
case({i_data[1:0],i_preload[1:0]})
|
108 |
|
|
//this is the match-score lookup table: +5 for a match, -4 for a mismatch
|
109 |
|
|
{N_A,N_A}:match = 11'b101; //+5
|
110 |
|
|
{N_A,N_G}:match = 11'h7fc; //-4
|
111 |
|
|
{N_A,N_T}:match = 11'h7fc;
|
112 |
|
|
{N_A,N_C}:match = 11'h7fc;
|
113 |
|
|
{N_G,N_A}:match = 11'h7fc;
|
114 |
|
|
{N_G,N_G}:match = 11'b101;
|
115 |
|
|
{N_G,N_T}:match = 11'h7fc;
|
116 |
|
|
{N_G,N_C}:match = 11'h7fc;
|
117 |
|
|
{N_T,N_A}:match = 11'h7fc;
|
118 |
|
|
{N_T,N_G}:match = 11'h7fc;
|
119 |
|
|
{N_T,N_T}:match = 11'b101;
|
120 |
|
|
{N_T,N_C}:match = 11'h7fc;
|
121 |
|
|
{N_C,N_A}:match = 11'h7fc;
|
122 |
|
|
{N_C,N_G}:match = 11'h7fc;
|
123 |
|
|
{N_C,N_T}:match = 11'h7fc;
|
124 |
|
|
{N_C,N_C}:match = 11'b101;
|
125 |
|
|
endcase
|
126 |
|
|
|
127 |
|
|
//just propagate the valid signal
|
128 |
|
|
always@(posedge clk)
|
129 |
|
|
if (i_rst==1'b1)
|
130 |
|
|
o_vld <= 1'b0;
|
131 |
|
|
else
|
132 |
|
|
o_vld <= i_vld;
|
133 |
|
|
|
134 |
|
|
|
135 |
|
|
//This continuously calculates the highest score to pass through the block
|
136 |
|
|
assign rightmax = (right_m_nxt > right_i_nxt) ? right_m_nxt : right_i_nxt;
|
137 |
|
|
|
138 |
|
|
|
139 |
|
|
always@(posedge clk)
|
140 |
|
|
begin
|
141 |
|
|
if (i_rst==1'b1)
|
142 |
|
|
o_high <= neutral_score; //reset to "0"
|
143 |
|
|
else if (i_vld==1'b1)
|
144 |
|
|
o_high <= (o_high > rightmax) ? ( (o_high > i_high) ? o_high : i_high) : ((rightmax > i_high) ? rightmax : i_high);
|
145 |
|
|
end
|
146 |
|
|
|
147 |
|
|
|
148 |
|
|
always@(posedge clk) begin
|
149 |
|
|
if (i_rst==1'b1) begin
|
150 |
|
|
//This is where we initialize the matrix
|
151 |
|
|
o_right_m <= i_local ? neutral_score : (i_left_m - (start ? GOPEN : GEXT)); //init m matrix
|
152 |
|
|
o_right_i <= i_local ? neutral_score : (i_left_i - (start ? GOPEN : GEXT)); //init i matrix
|
153 |
|
|
o_data[1:0] <= 2'b00;
|
154 |
|
|
l_diag_score_m <= start ? neutral_score : (i_local ? neutral_score : i_left_m);
|
155 |
|
|
l_diag_score_i <= start ? neutral_score : (i_local ? neutral_score : i_left_i);
|
156 |
|
|
end
|
157 |
|
|
else if (i_vld==1'b1) begin
|
158 |
|
|
o_data[1:0] <= i_data[1:0];
|
159 |
|
|
o_right_m <= (i_local ? ((right_m_nxt > neutral_score) ? right_m_nxt : neutral_score) : right_m_nxt);
|
160 |
|
|
o_right_i <= (i_local ? ((right_i_nxt > neutral_score) ? right_i_nxt : neutral_score) : right_i_nxt);
|
161 |
|
|
l_diag_score_m <= start ? (i_local ? neutral_score : (l_diag_score_m - GEXT)) : i_left_m ;
|
162 |
|
|
l_diag_score_i <= start ? (i_local ? neutral_score : (l_diag_score_i - GEXT)) : i_left_i ;
|
163 |
|
|
end
|
164 |
|
|
end
|
165 |
|
|
|
166 |
|
|
always@(posedge clk) begin
|
167 |
|
|
if (i_rst)
|
168 |
|
|
state <= 2'b00;
|
169 |
|
|
else begin
|
170 |
|
|
case(state[1:0])
|
171 |
|
|
2'b00:state[1:0] <= 2'b01; //reset state
|
172 |
|
|
2'b01:if (i_vld==1'b1) state[1:0] <= 2'b10; //INIT state
|
173 |
|
|
2'b10:if (i_vld==1'b0) state[1:0] <= 2'b01; //SCORE state - i_vld must be held high from the start of the query sequence to the end of it
|
174 |
|
|
2'b11:if (i_rst) state[1:0] <= 2'b00; //END state
|
175 |
|
|
endcase
|
176 |
|
|
end
|
177 |
|
|
end
|
178 |
|
|
endmodule
|