OpenCores
URL https://opencores.org/ocsvn/seqalign/seqalign/trunk

Subversion Repositories seqalign

[/] [seqalign/] [trunk/] [sw_pe_affine.v] - Rev 2

Compare with Previous | Blame | View Log

module sw_pe_affine(clk,
             i_rst,
				 o_rst,
             i_data,
             i_preload,
             i_left_m,
				 i_left_i,
             i_high,
             i_vld,
             i_local,
             o_right_m,
				 o_right_i,
				 o_high,
             o_vld,
             o_data,
             start);
 
localparam
    SCORE_WIDTH = 11,
    N_A = 2'b00,        //nucleotide "A"
    N_G = 2'b01,        //nucleotide "G"
    N_T = 2'b10,        //nucleotide "T"
    N_C = 2'b11,        //nucleotide "C"
    INS_START = 3,            //insertion penalty
    INS_CONT  = 1,
    DEL_START = 3,            //deletion penalty
    DEL_CONT  = 1,
    TB_UP = 2'b00,      //"UP" traceback pointer
    TB_DIAG = 2'b01,    //"DIAG" traceback pointer
    TB_LEFT = 2'b10,    //"LEFT" traceback pointer
	 GOPEN = 12,
	 GEXT = 4;
 
input  wire clk;
input  wire i_rst;
output reg  o_rst;
input  wire [1:0] i_data;               //sequence being streamed in
input  wire [1:0] i_preload;            //fixed character assigned to this node
input  wire [SCORE_WIDTH-1:0] i_left_m;             //connection to left neighbor cell for M matrix
input  wire [SCORE_WIDTH-1:0] i_left_i;				//connection to left neighbor cell for I matrix
input  wire i_vld;                              //valid data coming from neighbor
input  wire i_local;			//=1 if local alignment, =0 if global alignment
input  wire start;                               //designate that you're on the left edge of the array
input  wire [SCORE_WIDTH-1:0] i_high;		//input of highest score from neighbor
output reg [SCORE_WIDTH-1:0] o_right_m;            //output of score from t-1 for M matrix
output reg [SCORE_WIDTH-1:0] o_right_i;				//output of score for t-1 for I matrix
output reg [SCORE_WIDTH-1:0] o_high;		//output of currently highest score
 
output reg  o_vld;                              //tells neighbor data is valid
output reg [1:0] o_data;
 
 
 
parameter LENGTH=48;
parameter LOGLENGTH = 6;
 
reg [1:0] state;        //just state counter
 
reg [SCORE_WIDTH-1:0] l_diag_score_m;
reg [SCORE_WIDTH-1:0] l_diag_score_i;
 
wire [SCORE_WIDTH-1:0] right_m_nxt;
wire [SCORE_WIDTH-1:0] right_i_nxt;
wire [SCORE_WIDTH-1:0] left_open;
wire [SCORE_WIDTH-1:0] left_ext;
wire [SCORE_WIDTH-1:0] up_open;
wire [SCORE_WIDTH-1:0] up_ext;
wire [SCORE_WIDTH-1:0] left_max;
wire [SCORE_WIDTH-1:0] up_max;
wire [SCORE_WIDTH-1:0] rightmax;
wire [SCORE_WIDTH-1:0] start_left;
 
reg [SCORE_WIDTH-1:0] match;
wire [SCORE_WIDTH-1:0] max_score_a;
wire [SCORE_WIDTH-1:0] max_score_b;
wire [SCORE_WIDTH-1:0] left_score;
wire [SCORE_WIDTH-1:0] up_score;
wire [SCORE_WIDTH-1:0] diag_score;
wire [SCORE_WIDTH-1:0] neutral_score;
 
wire [SCORE_WIDTH-1:0] left_score_b;
 
 
//compute new score options
 
assign neutral_score = 11'b10000000000;
 
assign start_left = (state==2'b01) ? (l_diag_score_m - GOPEN) : (l_diag_score_m - GEXT);
 
assign left_open = i_left_m  - GOPEN;
assign left_ext  = i_left_i  - GEXT;
assign up_open   = o_right_m - GOPEN;
assign up_ext    = o_right_i - GEXT;
assign left_max  = start ? start_left : ((left_open > left_ext) ? left_open : left_ext);
assign up_max    = (up_open   > up_ext)   ? up_open   : up_ext;
 
assign right_m_nxt = match + ((l_diag_score_m > l_diag_score_i) ? l_diag_score_m : l_diag_score_i);	//next m score
assign right_i_nxt = (left_max > up_max) ? left_max : up_max;
 
 
 
 
always@(posedge clk)
	o_rst <= i_rst;
 
always@*
    case({i_data[1:0],i_preload[1:0]})
//this is the match-score lookup table: +5 for a match, -4 for a mismatch
        {N_A,N_A}:match = 11'b101;	//+5
        {N_A,N_G}:match = 11'h7fc;	//-4
        {N_A,N_T}:match = 11'h7fc;
        {N_A,N_C}:match = 11'h7fc;
        {N_G,N_A}:match = 11'h7fc;
        {N_G,N_G}:match = 11'b101;
        {N_G,N_T}:match = 11'h7fc;
        {N_G,N_C}:match = 11'h7fc;
        {N_T,N_A}:match = 11'h7fc;
        {N_T,N_G}:match = 11'h7fc;
        {N_T,N_T}:match = 11'b101;
        {N_T,N_C}:match = 11'h7fc;
        {N_C,N_A}:match = 11'h7fc;
        {N_C,N_G}:match = 11'h7fc;
        {N_C,N_T}:match = 11'h7fc;
        {N_C,N_C}:match = 11'b101;
    endcase
 
//just propagate the valid signal
always@(posedge clk)
    if (i_rst==1'b1)
        o_vld <= 1'b0;
    else
        o_vld <= i_vld;           
 
 
//This continuously calculates the highest score to pass through the block
assign rightmax = (right_m_nxt > right_i_nxt) ? right_m_nxt : right_i_nxt;
 
 
always@(posedge clk)
begin
	if (i_rst==1'b1)
		o_high <= neutral_score;		//reset to "0"
	else if (i_vld==1'b1)
		o_high <= (o_high > rightmax) ? ( (o_high > i_high) ? o_high : i_high) : ((rightmax > i_high) ? rightmax : i_high);
end
 
 
always@(posedge clk) begin
       if (i_rst==1'b1) begin
								//This is where we initialize the matrix
                        o_right_m <= i_local ? neutral_score : (i_left_m - (start ? GOPEN : GEXT));	//init m matrix
                        o_right_i <= i_local ? neutral_score : (i_left_i - (start ? GOPEN : GEXT));	//init i matrix
			o_data[1:0] <= 2'b00;
                        l_diag_score_m <= start ? neutral_score : (i_local ? neutral_score : i_left_m);
			l_diag_score_i <= start ? neutral_score : (i_local ? neutral_score : i_left_i);
                      end
       else if (i_vld==1'b1) begin
                           o_data[1:0] <= i_data[1:0];
                           o_right_m <= (i_local ? ((right_m_nxt > neutral_score) ? right_m_nxt : neutral_score) : right_m_nxt);
			   o_right_i <= (i_local ? ((right_i_nxt > neutral_score) ? right_i_nxt : neutral_score) : right_i_nxt);
			   l_diag_score_m <= start ?  (i_local ? neutral_score : (l_diag_score_m - GEXT)) : i_left_m ;
			   l_diag_score_i <= start ?  (i_local ? neutral_score : (l_diag_score_i - GEXT)) : i_left_i ;									
                        end
                     end
 
always@(posedge clk) begin
    if (i_rst)
        state <= 2'b00;
    else begin
       case(state[1:0])
			 2'b00:state[1:0] <= 2'b01;										//reset state
          2'b01:if (i_vld==1'b1)        state[1:0] <= 2'b10;     //INIT state
          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
          2'b11:if (i_rst)              state[1:0] <= 2'b00;     //END state
       endcase
        end
    end
endmodule 
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.