data/full_repos/permissive/214176324/simulation/video_scaler.v
1: b'%Warning-WIDTH: data/full_repos/permissive/214176324/simulation/video_scaler.v:157: Operator ASSIGNDLY expects 36 bits on the Assign RHS, but Assign RHS\'s VARREF \'leftOffset\' generates 25 bits.\n                                                                                  : ... In instance video_scaler\n    xScaleAmount <= leftOffset;\n                 ^~\n                ... Use "/* verilator lint_off WIDTH */" and lint_on around source to disable this message.\n%Warning-WIDTH: data/full_repos/permissive/214176324/simulation/video_scaler.v:158: Operator ASSIGNDLY expects 36 bits on the Assign RHS, but Assign RHS\'s REPLICATE generates 25 bits.\n                                                                                  : ... In instance video_scaler\n    yScaleAmount <= {{INPUT_Y_RES_WIDTH{1\'b0}}, topFracOffset};\n                 ^~\n%Warning-WIDTH: data/full_repos/permissive/214176324/simulation/video_scaler.v:217: Operator ASSIGNDLY expects 36 bits on the Assign RHS, but Assign RHS\'s VARREF \'leftOffset\' generates 25 bits.\n                                                                                  : ... In instance video_scaler\n      xScaleAmount <= leftOffset;        \n                   ^~\n%Warning-WIDTH: data/full_repos/permissive/214176324/simulation/video_scaler.v:269: Operator ASSIGNDLY expects 8 bits on the Assign RHS, but Assign RHS\'s CONST \'1\'h0\' generates 1 bits.\n                                                                                  : ... In instance video_scaler\n  state_vaild_cnt <= 1\'d0;\n                  ^~\n%Warning-WIDTH: data/full_repos/permissive/214176324/simulation/video_scaler.v:276: Operator ASSIGNDLY expects 8 bits on the Assign RHS, but Assign RHS\'s CONST \'1\'h0\' generates 1 bits.\n                                                                                  : ... In instance video_scaler\n   state_vaild_cnt <= 1\'d0;\n                   ^~\n%Warning-WIDTH: data/full_repos/permissive/214176324/simulation/video_scaler.v:308: Operator EQ expects 18 bits on the RHS, but RHS\'s VARREF \'outputYRes\' generates 11 bits.\n                                                                                  : ... In instance video_scaler\n  scaler_done <= (outputLine_dump == outputYRes) && (outputColumn[10:0] == outputXRes);\n                                  ^~\n%Error: data/full_repos/permissive/214176324/simulation/video_scaler.v:406: Cannot find file containing module: \'BiCubic\'\nBiCubic BiCubic_inst(\n^~~~~~~\n        ... Looked in:\n             data/full_repos/permissive/214176324/simulation,data/full_repos/permissive/214176324/BiCubic\n             data/full_repos/permissive/214176324/simulation,data/full_repos/permissive/214176324/BiCubic.v\n             data/full_repos/permissive/214176324/simulation,data/full_repos/permissive/214176324/BiCubic.sv\n             BiCubic\n             BiCubic.v\n             BiCubic.sv\n             obj_dir/BiCubic\n             obj_dir/BiCubic.v\n             obj_dir/BiCubic.sv\n%Error: data/full_repos/permissive/214176324/simulation/video_scaler.v:425: Cannot find file containing module: \'coefficient\'\ncoefficient #(\n^~~~~~~~~~~\n%Warning-WIDTH: data/full_repos/permissive/214176324/simulation/video_scaler.v:640: Operator ADD expects 20 bits on the LHS, but LHS\'s SEL generates 17 bits.\n                                                                                  : ... In instance video_scaler\n      (product00[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel])+\n                                                                                             ^\n%Warning-WIDTH: data/full_repos/permissive/214176324/simulation/video_scaler.v:640: Operator ADD expects 20 bits on the RHS, but RHS\'s SEL generates 17 bits.\n                                                                                  : ... In instance video_scaler\n      (product00[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel])+\n                                                                                             ^\n%Warning-WIDTH: data/full_repos/permissive/214176324/simulation/video_scaler.v:641: Operator ADD expects 20 bits on the RHS, but RHS\'s SEL generates 17 bits.\n                                                                                  : ... In instance video_scaler\n      (product03[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel])+\n                                                                                             ^\n%Warning-WIDTH: data/full_repos/permissive/214176324/simulation/video_scaler.v:642: Operator ADD expects 20 bits on the RHS, but RHS\'s SEL generates 17 bits.\n                                                                                  : ... In instance video_scaler\n      (product11[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel])+\n                                                                                             ^\n%Warning-WIDTH: data/full_repos/permissive/214176324/simulation/video_scaler.v:646: Operator ADD expects 20 bits on the LHS, but LHS\'s SEL generates 17 bits.\n                                                                                  : ... In instance video_scaler\n      (product21[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel])+\n                                                                                             ^\n%Warning-WIDTH: data/full_repos/permissive/214176324/simulation/video_scaler.v:646: Operator ADD expects 20 bits on the RHS, but RHS\'s SEL generates 17 bits.\n                                                                                  : ... In instance video_scaler\n      (product21[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel])+\n                                                                                             ^\n%Warning-WIDTH: data/full_repos/permissive/214176324/simulation/video_scaler.v:647: Operator ADD expects 20 bits on the RHS, but RHS\'s SEL generates 17 bits.\n                                                                                  : ... In instance video_scaler\n      (product22[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel])+\n                                                                                             ^\n%Warning-WIDTH: data/full_repos/permissive/214176324/simulation/video_scaler.v:648: Operator ADD expects 20 bits on the RHS, but RHS\'s SEL generates 17 bits.\n                                                                                  : ... In instance video_scaler\n      (product30[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel])+\n                                                                                             ^\n%Warning-WIDTH: data/full_repos/permissive/214176324/simulation/video_scaler.v:652: Operator ADD expects 20 bits on the LHS, but LHS\'s SEL generates 17 bits.\n                                                                                  : ... In instance video_scaler\n      (product01[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel])+\n                                                                                             ^\n%Warning-WIDTH: data/full_repos/permissive/214176324/simulation/video_scaler.v:652: Operator ADD expects 20 bits on the RHS, but RHS\'s SEL generates 17 bits.\n                                                                                  : ... In instance video_scaler\n      (product01[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel])+\n                                                                                             ^\n%Warning-WIDTH: data/full_repos/permissive/214176324/simulation/video_scaler.v:653: Operator ADD expects 20 bits on the RHS, but RHS\'s SEL generates 17 bits.\n                                                                                  : ... In instance video_scaler\n      (product02[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel])+\n                                                                                             ^\n%Warning-WIDTH: data/full_repos/permissive/214176324/simulation/video_scaler.v:654: Operator ADD expects 20 bits on the RHS, but RHS\'s SEL generates 17 bits.\n                                                                                  : ... In instance video_scaler\n      (product10[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel])+\n                                                                                             ^\n%Warning-WIDTH: data/full_repos/permissive/214176324/simulation/video_scaler.v:658: Operator ADD expects 20 bits on the LHS, but LHS\'s SEL generates 17 bits.\n                                                                                  : ... In instance video_scaler\n      (product20[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel])+\n                                                                                             ^\n%Warning-WIDTH: data/full_repos/permissive/214176324/simulation/video_scaler.v:658: Operator ADD expects 20 bits on the RHS, but RHS\'s SEL generates 17 bits.\n                                                                                  : ... In instance video_scaler\n      (product20[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel])+\n                                                                                             ^\n%Warning-WIDTH: data/full_repos/permissive/214176324/simulation/video_scaler.v:659: Operator ADD expects 20 bits on the RHS, but RHS\'s SEL generates 17 bits.\n                                                                                  : ... In instance video_scaler\n      (product23[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel])+\n                                                                                             ^\n%Warning-WIDTH: data/full_repos/permissive/214176324/simulation/video_scaler.v:660: Operator ADD expects 20 bits on the RHS, but RHS\'s SEL generates 17 bits.\n                                                                                  : ... In instance video_scaler\n      (product31[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel])+\n                                                                                             ^\n%Warning-WIDTH: data/full_repos/permissive/214176324/simulation/video_scaler.v:675: Operator ASSIGNDLY expects 9 bits on the Assign RHS, but Assign RHS\'s AND generates 21 bits.\n                                                                                  : ... In instance video_scaler\n     dOut_shift[ COEFF_WIDTH*(channel+1)-1 : COEFF_WIDTH*channel ] <= (dOut_sum[ (DATA_WIDTH+COEFF_WIDTH+4)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH+4)*channel ] >> 8) & ({ {(DATA_WIDTH+4){1\'b0}}, {COEFF_WIDTH{1\'b1}} });\n                                                                   ^~\n%Warning-WIDTH: data/full_repos/permissive/214176324/simulation/video_scaler.v:718: Operator ASSIGNDLY expects 11 bits on the Assign RHS, but Assign RHS\'s AND generates 29 bits.\n                                                                                  : ... In instance video_scaler\n   writeNextValidLine <= ((writeOutputLine*yScale + {{(OUTPUT_Y_RES_WIDTH + SCALE_INT_BITS){1\'b0}}, topFracOffset}) >> SCALE_FRAC_BITS) & {{SCALE_BITS{1\'b0}}, {OUTPUT_Y_RES_WIDTH{1\'b1}}};\n                      ^~\n%Warning-WIDTH: data/full_repos/permissive/214176324/simulation/video_scaler.v:935: Operator ADD expects 32 or 18 bits on the LHS, but LHS\'s VARREF \'outputYRes\' generates 11 bits.\n                                                                                  : ... In instance video_scaler\n  else if(outputLine_dump == outputYRes+1) begin\n                                       ^\n%Warning-WIDTH: data/full_repos/permissive/214176324/simulation/video_scaler.v:939: Operator EQ expects 18 bits on the RHS, but RHS\'s VARREF \'outputYRes\' generates 11 bits.\n                                                                                  : ... In instance video_scaler\n else if(outputLine_dump == outputYRes) begin\n                         ^~\n%Error: data/full_repos/permissive/214176324/simulation/video_scaler.v:987: Cannot find file containing module: \'cash_ram_rw\'\ncash_ram_rw #(\n^~~~~~~~~~~\n%Error: Exiting due to 3 error(s), 26 warning(s)\n'
module video_scaler (

input wire							  clk,
input wire							  rst,
input wire							  start,
                                      

input wire [24-1:0]  dIn,
input wire							  dInValid,
input wire							  dout_Enable,
                                      

output wire							  din_Enable,

output reg [24-1:0]  dOut,
output reg							  dOutValid,
output reg                            scaler_done,
                                      

input wire [11-1:0]	  inputXRes,
input wire [11-1:0]	  inputYRes,
input wire [11-1:0]	  outputXRes,
input wire [11-1:0]	  outputYRes,
input wire [18-1:0]			  xScale,
input wire [18-1:0]			  yScale,


input wire [8-1:0]	  inputDiscardCnt,

														
input wire [25-1:0]              leftOffset,


														
input wire [14-1:0]	  topFracOffset

);
localparam	DATA_WIDTH =			8;
localparam	CHANNELS =				3;
localparam 	DISCARD_CNT_WIDTH =		8;
localparam	INPUT_X_RES_WIDTH =		11;
localparam	INPUT_Y_RES_WIDTH =		11;
localparam	OUTPUT_X_RES_WIDTH =	11;
localparam	OUTPUT_Y_RES_WIDTH =	11;
localparam	FRACTION_BITS =			8;

localparam	SCALE_INT_BITS =		4;



localparam	SCALE_FRAC_BITS =		14;
localparam	BUFFER_SIZE =			8;
localparam	COEFF_WIDTH =			FRACTION_BITS + 1;
localparam	SCALE_BITS =			SCALE_INT_BITS + SCALE_FRAC_BITS;
localparam  Q_WIDTH = OUTPUT_X_RES_WIDTH + SCALE_FRAC_BITS;

localparam	BUFFER_SIZE_WIDTH =		((BUFFER_SIZE+1) <= 2) ? 1 :
									((BUFFER_SIZE+1) <= 4) ? 2 :
									((BUFFER_SIZE+1) <= 8) ? 3 :
									((BUFFER_SIZE+1) <= 16) ? 4 :
									((BUFFER_SIZE+1) <= 32) ? 5 :
									((BUFFER_SIZE+1) <= 64) ? 6 : 7;

reg [COEFF_WIDTH*CHANNELS-1:0]                 dOut_shift;
reg [(DATA_WIDTH+COEFF_WIDTH+4)*CHANNELS-1:0]  dOut_sum;
reg [(DATA_WIDTH+COEFF_WIDTH+4)*CHANNELS-1:0]  dOut_add;
reg [(DATA_WIDTH+COEFF_WIDTH+4)*CHANNELS-1:0]  dOut_sub;
reg [(DATA_WIDTH+COEFF_WIDTH+3)*CHANNELS-1:0]  dOut_add_0;
reg [(DATA_WIDTH+COEFF_WIDTH+3)*CHANNELS-1:0]  dOut_add_1;
reg [(DATA_WIDTH+COEFF_WIDTH+3)*CHANNELS-1:0]  dOut_sub_0;
reg [(DATA_WIDTH+COEFF_WIDTH+3)*CHANNELS-1:0]  dOut_sub_1;

reg	advanceRead1,advanceRead2,advanceRead3,advanceRead4;

wire [DATA_WIDTH*CHANNELS-1:0]	readData00;
wire [DATA_WIDTH*CHANNELS-1:0]	readData01;
wire [DATA_WIDTH*CHANNELS-1:0]	readData02;
wire [DATA_WIDTH*CHANNELS-1:0]	readData03;
wire [DATA_WIDTH*CHANNELS-1:0]	readData10;
wire [DATA_WIDTH*CHANNELS-1:0]	readData11;
wire [DATA_WIDTH*CHANNELS-1:0]	readData12;
wire [DATA_WIDTH*CHANNELS-1:0]	readData13;
wire [DATA_WIDTH*CHANNELS-1:0]	readData20;
wire [DATA_WIDTH*CHANNELS-1:0]	readData21;
wire [DATA_WIDTH*CHANNELS-1:0]	readData22;
wire [DATA_WIDTH*CHANNELS-1:0]	readData23;
wire [DATA_WIDTH*CHANNELS-1:0]	readData30;
wire [DATA_WIDTH*CHANNELS-1:0]	readData31;
wire [DATA_WIDTH*CHANNELS-1:0]	readData32;
wire [DATA_WIDTH*CHANNELS-1:0]	readData33;

reg [INPUT_X_RES_WIDTH-1:0]	    readAddress;

reg 							readyForRead;
(* keep = "true" *)reg [SCALE_BITS-1:0]	        outputLine;
(* keep = "true" *)reg [SCALE_BITS-1:0]	        outputLine_dump;
reg [SCALE_BITS-1:0]		    outputColumn;
reg [SCALE_BITS-1:0]		    outputColumn_reg;
reg [2*SCALE_BITS-1:0]          xScaleAmount;
reg [2*SCALE_BITS-1:0]          yScaleAmount;
reg [2*SCALE_BITS-1:0]          yScaleAmountNext;
wire [BUFFER_SIZE_WIDTH-1:0] 	fillCount;
reg                 			lineSwitchOutputDisable;
reg								dOutValidInt;

reg [COEFF_WIDTH-1:0]			xBlend;
reg [COEFF_WIDTH-1:0]			yBlend;

wire [INPUT_X_RES_WIDTH-1:0]	xPixLow = xScaleAmount[INPUT_X_RES_WIDTH-1+SCALE_FRAC_BITS:SCALE_FRAC_BITS];

wire 							allDataWritten;
reg 							readState;
reg                             state_m_comb;

reg [INPUT_Y_RES_WIDTH-1:0]	yPixLow;
always @ (posedge clk)
begin
	yPixLow <= yScaleAmount[INPUT_Y_RES_WIDTH-1+SCALE_FRAC_BITS:SCALE_FRAC_BITS];
end

reg [INPUT_Y_RES_WIDTH-1:0]	yPixLowNext;
always @ (posedge clk)
begin
	yPixLowNext <= yScaleAmountNext[INPUT_Y_RES_WIDTH-1+SCALE_FRAC_BITS:SCALE_FRAC_BITS];
end


localparam RS_START = 0;
localparam RS_READ_LINE = 1;



always @ (posedge clk or posedge rst or posedge start)
begin
	if(rst | start)
	begin
		outputLine_dump <= 0;
		outputLine <= 0;
		outputColumn <= 0;
		outputColumn_reg <= 1;
		xScaleAmount <= 0;
		yScaleAmount <= 0;
		readState <= RS_START;
		dOutValidInt <= 0;
		lineSwitchOutputDisable <= 0;
		advanceRead1 <= 0;
		advanceRead2 <= 0;
		advanceRead3 <= 0;
		advanceRead4 <= 0;
	end
	else
	begin
		case (readState)  
			RS_START:
			begin

				xScaleAmount <= leftOffset;
				yScaleAmount <= {{INPUT_Y_RES_WIDTH{1'b0}}, topFracOffset};
				if(readyForRead)
				begin
					readState <= RS_READ_LINE;
					dOutValidInt <= 1;
				end
			end

			RS_READ_LINE:
			begin

				if(dout_Enable && dOutValidInt)
				begin
					if(outputColumn[10:0] == outputXRes)
					begin


						if(yPixLowNext == (yPixLow + 1))
						begin


							advanceRead1 <= 1;



							if(fillCount < 5)		
								dOutValidInt <= 0;
						end


						if(yPixLowNext == (yPixLow + 2))
						begin
							advanceRead2 <= 1;



							if(fillCount < 6)
								dOutValidInt <= 0;
						end					
						if(yPixLowNext == (yPixLow + 3))
						begin
							advanceRead3 <= 1;



							if(fillCount < 7)
								dOutValidInt <= 0;
						end
						if(yPixLowNext > (yPixLow + 3))
						begin
							advanceRead4 <= 1;



							if(fillCount < 8)
								dOutValidInt <= 0;
						end
						outputColumn <= 0;
						outputColumn_reg <= 1;
						xScaleAmount <= leftOffset;
						outputLine <= outputLine + 1;
						outputLine_dump <= outputLine_dump + 1;
						yScaleAmount <= yScaleAmountNext;
						lineSwitchOutputDisable <= 1;
					end
					else
					begin
						if(lineSwitchOutputDisable == 0)
						begin
							outputColumn <= outputColumn + 1;
							outputColumn_reg <= outputColumn_reg + 1;
							xScaleAmount <= outputColumn_reg * xScale;
						end
						advanceRead1 <= 0;
						advanceRead2 <= 0;
						advanceRead3 <= 0;
						advanceRead4 <= 0;
						lineSwitchOutputDisable <= 0;
					end
				end
				else
				begin
					advanceRead1 <= 0;
					advanceRead2 <= 0;
					advanceRead3 <= 0;
					advanceRead4 <= 0;
					lineSwitchOutputDisable <= 0;
				end
				



				if(fillCount >= 4 && dOutValidInt == 0 || allDataWritten)
				begin
					if( state_m_comb )
					begin
						dOutValidInt <= 1;
						lineSwitchOutputDisable <= 0;
					end
				end
			end
		endcase
	end
end

reg  [7:0] state_vaild_cnt;


always@(posedge clk)
begin
	if(rst | start) begin
		state_vaild_cnt <= 1'd0;
		state_m_comb <= 1'd1;
	end
	else if(state_vaild_cnt > 0) begin
		state_vaild_cnt <= state_vaild_cnt + 1;
		if(state_vaild_cnt == 8'd30) begin
			state_m_comb <= 1'd1;
			state_vaild_cnt <= 1'd0;
		end
	end
	else if(outputColumn[10:0] == outputXRes) begin
		state_m_comb <= 1'd0;
		state_vaild_cnt <= state_vaild_cnt + 1;
	end
end

reg [SCALE_BITS-1:0] outputLine_reg;

always@(posedge clk or posedge rst)
begin
	if(rst) begin
		yScaleAmountNext <= 0;
		outputLine_reg <= 0;
	end
	else begin
		outputLine_reg <= outputLine + 1;
		yScaleAmountNext <= outputLine_reg * yScale;
	end
end


always @(posedge clk or posedge rst)
begin
	if(rst)
	begin
		scaler_done <= 0;
	end
	else
	begin
		scaler_done <= (outputLine_dump == outputYRes) && (outputColumn[10:0] == outputXRes);
	end
end


always@(posedge clk or posedge rst)
begin
	if(rst) begin
		readAddress <= 0;
	end
	else begin
		readAddress <= xPixLow;
	end
end

reg [26:0] dOutValid_reg;

always @(posedge clk or posedge rst or posedge start)
begin
	if(rst | start)
	begin
		dOutValid_reg <= 0;
		dOutValid <= 0;
	end
	else
	begin


		dOutValid_reg <= {dOutValid_reg[25:0],(dout_Enable && dOutValidInt && !lineSwitchOutputDisable)};
		dOutValid <= dOutValid_reg[26];
	end
end

always @(posedge clk or posedge rst)
begin
	if(rst)
	begin
		xBlend <= 0;
		yBlend <= 0;
	end
	else begin

		xBlend <= {1'b0, xScaleAmount[SCALE_FRAC_BITS-1:SCALE_FRAC_BITS-FRACTION_BITS]};
		yBlend <= {1'b0, yScaleAmount[SCALE_FRAC_BITS-1:SCALE_FRAC_BITS-FRACTION_BITS]};
	end
end

wire [COEFF_WIDTH-1:0]	coeff00_0;
wire [COEFF_WIDTH-1:0]	coeff01_0;
wire [COEFF_WIDTH-1:0]	coeff02_0;
wire [COEFF_WIDTH-1:0]	coeff03_0;
wire [COEFF_WIDTH-1:0]	coeff10_0;
wire [COEFF_WIDTH-1:0]	coeff11_0;
wire [COEFF_WIDTH-1:0]	coeff12_0;
wire [COEFF_WIDTH-1:0]	coeff13_0;
wire [COEFF_WIDTH-1:0]	coeff20_0;
wire [COEFF_WIDTH-1:0]	coeff21_0;
wire [COEFF_WIDTH-1:0]	coeff22_0;
wire [COEFF_WIDTH-1:0]	coeff23_0;
wire [COEFF_WIDTH-1:0]	coeff30_0;
wire [COEFF_WIDTH-1:0]	coeff31_0;
wire [COEFF_WIDTH-1:0]	coeff32_0;
wire [COEFF_WIDTH-1:0]	coeff33_0;

reg [COEFF_WIDTH-1:0]	coeff00_1;
reg [COEFF_WIDTH-1:0]	coeff01_1;
reg [COEFF_WIDTH-1:0]	coeff02_1;
reg [COEFF_WIDTH-1:0]	coeff03_1;
reg [COEFF_WIDTH-1:0]	coeff10_1;
reg [COEFF_WIDTH-1:0]	coeff11_1;
reg [COEFF_WIDTH-1:0]	coeff12_1;
reg [COEFF_WIDTH-1:0]	coeff13_1;
reg [COEFF_WIDTH-1:0]	coeff20_1;
reg [COEFF_WIDTH-1:0]	coeff21_1;
reg [COEFF_WIDTH-1:0]	coeff22_1;
reg [COEFF_WIDTH-1:0]	coeff23_1;
reg [COEFF_WIDTH-1:0]	coeff30_1;
reg [COEFF_WIDTH-1:0]	coeff31_1;
reg [COEFF_WIDTH-1:0]	coeff32_1;
reg [COEFF_WIDTH-1:0]	coeff33_1;

wire [COEFF_WIDTH-1:0]	bi_y0;
wire [COEFF_WIDTH-1:0]	bi_y1;
wire [COEFF_WIDTH-1:0]	bi_y2;
wire [COEFF_WIDTH-1:0]	bi_y3;
wire [COEFF_WIDTH-1:0]	bi_x0;
wire [COEFF_WIDTH-1:0]	bi_x1;
wire [COEFF_WIDTH-1:0]	bi_x2;
wire [COEFF_WIDTH-1:0]	bi_x3;


wire [COEFF_WIDTH-1:0]	coeffOne  = {1'b1, {(COEFF_WIDTH-1){1'b0}}};

wire [COEFF_WIDTH-1:0]	coeffHalf = {2'b01, {(COEFF_WIDTH-2){1'b0}}};

wire [COEFF_WIDTH-1:0]  bi_a      = {2'b01, {(COEFF_WIDTH-2){1'b0}}};


BiCubic BiCubic_inst(
	.clk        (clk),
	.rst_n      (!rst | !start),
	.coeffHalf  (coeffHalf),
	.coeffOne   (coeffOne),
	.yBlend     (yBlend),
	.bi_a       (bi_a),
	.xBlend     (xBlend),
	.bi_y0      (bi_y0),
	.bi_y1      (bi_y1),
	.bi_y2      (bi_y2),
	.bi_y3      (bi_y3),
	.bi_x0      (bi_x0),
	.bi_x1      (bi_x1),
	.bi_x2      (bi_x2),
	.bi_x3      (bi_x3)
);


coefficient #(
	.FRACTION_BITS  (FRACTION_BITS),
	.COEFF_WIDTH    (COEFF_WIDTH)
)coefficient_inst(
	.clk        (clk),
	.rst_n      (!rst | !start),
	.coeffHalf  (coeffHalf),
	.bi_y0      (bi_y0),
	.bi_y1      (bi_y1),
	.bi_y2      (bi_y2),
	.bi_y3      (bi_y3),
	.bi_x0      (bi_x0),
	.bi_x1      (bi_x1),
	.bi_x2      (bi_x2),
	.bi_x3      (bi_x3),
	.coeff00    (coeff00_0),
	.coeff01    (coeff01_0),
	.coeff02    (coeff02_0),
	.coeff03    (coeff03_0),
	.coeff10    (coeff10_0),
	.coeff11    (coeff11_0),
	.coeff12    (coeff12_0),
	.coeff13    (coeff13_0),
	.coeff20    (coeff20_0),
	.coeff21    (coeff21_0),
	.coeff22    (coeff22_0),
	.coeff23    (coeff23_0),
	.coeff30    (coeff30_0),
	.coeff31    (coeff31_0),
	.coeff32    (coeff32_0),
	.coeff33    (coeff33_0)
);

reg [COEFF_WIDTH-1:0]	coeff00_reg0;
reg [COEFF_WIDTH-1:0]	coeff01_reg0;
reg [COEFF_WIDTH-1:0]	coeff02_reg0;
reg [COEFF_WIDTH-1:0]	coeff03_reg0;
reg [COEFF_WIDTH-1:0]	coeff10_reg0;
reg [COEFF_WIDTH-1:0]	coeff11_reg0;
reg [COEFF_WIDTH-1:0]	coeff12_reg0;
reg [COEFF_WIDTH-1:0]	coeff13_reg0;
reg [COEFF_WIDTH-1:0]	coeff20_reg0;
reg [COEFF_WIDTH-1:0]	coeff21_reg0;
reg [COEFF_WIDTH-1:0]	coeff22_reg0;
reg [COEFF_WIDTH-1:0]	coeff23_reg0;
reg [COEFF_WIDTH-1:0]	coeff30_reg0;
reg [COEFF_WIDTH-1:0]	coeff31_reg0;
reg [COEFF_WIDTH-1:0]	coeff32_reg0;
reg [COEFF_WIDTH-1:0]	coeff33_reg0;

reg [COEFF_WIDTH-1:0]	coeff00_reg1;
reg [COEFF_WIDTH-1:0]	coeff01_reg1;
reg [COEFF_WIDTH-1:0]	coeff02_reg1;
reg [COEFF_WIDTH-1:0]	coeff03_reg1;
reg [COEFF_WIDTH-1:0]	coeff10_reg1;
reg [COEFF_WIDTH-1:0]	coeff11_reg1;
reg [COEFF_WIDTH-1:0]	coeff12_reg1;
reg [COEFF_WIDTH-1:0]	coeff13_reg1;
reg [COEFF_WIDTH-1:0]	coeff20_reg1;
reg [COEFF_WIDTH-1:0]	coeff21_reg1;
reg [COEFF_WIDTH-1:0]	coeff22_reg1;
reg [COEFF_WIDTH-1:0]	coeff23_reg1;
reg [COEFF_WIDTH-1:0]	coeff30_reg1;
reg [COEFF_WIDTH-1:0]	coeff31_reg1;
reg [COEFF_WIDTH-1:0]	coeff32_reg1;
reg [COEFF_WIDTH-1:0]	coeff33_reg1;


always@(posedge clk)
begin
	coeff00_reg0 <= coeff00_0;
	coeff01_reg0 <= coeff01_0;
	coeff02_reg0 <= coeff02_0;
	coeff03_reg0 <= coeff03_0;
	coeff10_reg0 <= coeff10_0;
	coeff11_reg0 <= coeff11_0;
	coeff12_reg0 <= coeff12_0;
	coeff13_reg0 <= coeff13_0;
	coeff20_reg0 <= coeff20_0;
	coeff21_reg0 <= coeff21_0;
	coeff22_reg0 <= coeff22_0;
	coeff23_reg0 <= coeff23_0;
	coeff30_reg0 <= coeff30_0;
	coeff31_reg0 <= coeff31_0;
	coeff32_reg0 <= coeff32_0;
	coeff33_reg0 <= coeff33_0;
	
	coeff00_reg1 <= coeff00_reg0;
	coeff01_reg1 <= coeff01_reg0;
	coeff02_reg1 <= coeff02_reg0;
	coeff03_reg1 <= coeff03_reg0;
	coeff10_reg1 <= coeff10_reg0;
	coeff11_reg1 <= coeff11_reg0;
	coeff12_reg1 <= coeff12_reg0;
	coeff13_reg1 <= coeff13_reg0;
	coeff20_reg1 <= coeff20_reg0;
	coeff21_reg1 <= coeff21_reg0;
	coeff22_reg1 <= coeff22_reg0;
	coeff23_reg1 <= coeff23_reg0;
	coeff30_reg1 <= coeff30_reg0;
	coeff31_reg1 <= coeff31_reg0;
	coeff32_reg1 <= coeff32_reg0;
	coeff33_reg1 <= coeff33_reg0;
end

reg [COEFF_WIDTH-1:0]	coeff00;
reg [COEFF_WIDTH-1:0]	coeff01;
reg [COEFF_WIDTH-1:0]	coeff02;
reg [COEFF_WIDTH-1:0]	coeff03;
reg [COEFF_WIDTH-1:0]	coeff10;
reg [COEFF_WIDTH-1:0]	coeff11;
reg [COEFF_WIDTH-1:0]	coeff12;
reg [COEFF_WIDTH-1:0]	coeff13;
reg [COEFF_WIDTH-1:0]	coeff20;
reg [COEFF_WIDTH-1:0]	coeff21;
reg [COEFF_WIDTH-1:0]	coeff22;
reg [COEFF_WIDTH-1:0]	coeff23;
reg [COEFF_WIDTH-1:0]	coeff30;
reg [COEFF_WIDTH-1:0]	coeff31;
reg [COEFF_WIDTH-1:0]	coeff32;
reg [COEFF_WIDTH-1:0]	coeff33;

always@(posedge clk)
begin
	coeff00 <= coeff00_reg1;
	coeff01 <= coeff01_reg1;
	coeff02 <= coeff02_reg1;
	coeff03 <= coeff03_reg1;
	coeff10 <= coeff10_reg1;
	coeff11 <= coeff11_reg1;
	coeff12 <= coeff12_reg1;
	coeff13 <= coeff13_reg1;
	coeff20 <= coeff20_reg1;
	coeff21 <= coeff21_reg1;
	coeff22 <= coeff22_reg1;
	coeff23 <= coeff23_reg1;
	coeff30 <= coeff30_reg1;
	coeff31 <= coeff31_reg1;
	coeff32 <= coeff32_reg1;
	coeff33 <= coeff33_reg1;
end


reg [(DATA_WIDTH+COEFF_WIDTH)*CHANNELS-1:0]	product00, product01, product02, product03,product10, product11, product12, product13,product20, product21, product22, product23,product30, product31, product32, product33;
generate
genvar channel;
	for(channel = 0; channel < CHANNELS; channel = channel + 1)
		begin : blend_mult_generate
			always @(posedge clk or posedge rst)
			begin
				if(rst)
				begin

					product00[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel] <= 0;
					product01[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel] <= 0;
					product02[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel] <= 0;
					product03[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel] <= 0;
					product10[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel] <= 0;
					product11[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel] <= 0;
					product12[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel] <= 0;
					product13[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel] <= 0;
					product20[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel] <= 0;
					product21[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel] <= 0;
					product22[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel] <= 0;
					product23[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel] <= 0;
					product30[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel] <= 0;
					product31[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel] <= 0;
					product32[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel] <= 0;
					product33[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel] <= 0;
					dOut_add_0[ (DATA_WIDTH+COEFF_WIDTH+3)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH+3)*channel ] <= 0;
					dOut_add_1[ (DATA_WIDTH+COEFF_WIDTH+3)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH+3)*channel ] <= 0;
					dOut_sub_0[ (DATA_WIDTH+COEFF_WIDTH+3)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH+3)*channel ] <= 0;
					dOut_sub_1[ (DATA_WIDTH+COEFF_WIDTH+3)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH+3)*channel ] <= 0;
					dOut_add[ (DATA_WIDTH+COEFF_WIDTH+4)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH+4)*channel ] <= 0;
					dOut_sub[ (DATA_WIDTH+COEFF_WIDTH+4)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH+4)*channel ] <= 0;				
					dOut_sum[ (DATA_WIDTH+COEFF_WIDTH+4)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH+4)*channel ] <= 0;
					dOut_shift[ COEFF_WIDTH*(channel+1)-1 : COEFF_WIDTH*channel ] <= 0;
					dOut[ DATA_WIDTH*(channel+1)-1 : DATA_WIDTH*channel]<= 0;
					
				end
				else
				begin




					product00[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel] <= readData00[ DATA_WIDTH*(channel+1)-1 : DATA_WIDTH*channel ] * coeff00;
					product01[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel] <= readData01[ DATA_WIDTH*(channel+1)-1 : DATA_WIDTH*channel ] * coeff01;
					product02[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel] <= readData02[ DATA_WIDTH*(channel+1)-1 : DATA_WIDTH*channel ] * coeff02;
					product03[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel] <= readData03[ DATA_WIDTH*(channel+1)-1 : DATA_WIDTH*channel ] * coeff03;
					product10[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel] <= readData10[ DATA_WIDTH*(channel+1)-1 : DATA_WIDTH*channel ] * coeff10;
					product11[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel] <= readData11[ DATA_WIDTH*(channel+1)-1 : DATA_WIDTH*channel ] * coeff11;
					product12[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel] <= readData12[ DATA_WIDTH*(channel+1)-1 : DATA_WIDTH*channel ] * coeff12;
					product13[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel] <= readData13[ DATA_WIDTH*(channel+1)-1 : DATA_WIDTH*channel ] * coeff13;
					product20[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel] <= readData20[ DATA_WIDTH*(channel+1)-1 : DATA_WIDTH*channel ] * coeff20;
					product21[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel] <= readData21[ DATA_WIDTH*(channel+1)-1 : DATA_WIDTH*channel ] * coeff21;
					product22[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel] <= readData22[ DATA_WIDTH*(channel+1)-1 : DATA_WIDTH*channel ] * coeff22;
					product23[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel] <= readData23[ DATA_WIDTH*(channel+1)-1 : DATA_WIDTH*channel ] * coeff23;
					product30[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel] <= readData30[ DATA_WIDTH*(channel+1)-1 : DATA_WIDTH*channel ] * coeff30;
					product31[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel] <= readData31[ DATA_WIDTH*(channel+1)-1 : DATA_WIDTH*channel ] * coeff31;
					product32[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel] <= readData32[ DATA_WIDTH*(channel+1)-1 : DATA_WIDTH*channel ] * coeff32;
					product33[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel] <= readData33[ DATA_WIDTH*(channel+1)-1 : DATA_WIDTH*channel ] * coeff33;
					
					dOut_add_0[ (DATA_WIDTH+COEFF_WIDTH+3)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH+3)*channel ] <=
						(product00[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel])+
						(product03[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel])+
						(product11[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel])+
						(product12[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel]);
						
					dOut_add_1[ (DATA_WIDTH+COEFF_WIDTH+3)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH+3)*channel ] <=
						(product21[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel])+
						(product22[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel])+
						(product30[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel])+
						(product33[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel]);
						
					dOut_sub_0[ (DATA_WIDTH+COEFF_WIDTH+3)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH+3)*channel ] <=
						(product01[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel])+
						(product02[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel])+
						(product10[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel])+
						(product13[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel]);
						
					dOut_sub_1[ (DATA_WIDTH+COEFF_WIDTH+3)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH+3)*channel ] <=
						(product20[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel])+
						(product23[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel])+
						(product31[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel])+
						(product32[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel]);
					

					dOut_add[ (DATA_WIDTH+COEFF_WIDTH+4)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH+4)*channel ] <=
						  dOut_add_0[ (DATA_WIDTH+COEFF_WIDTH+3)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH+3)*channel ] + dOut_add_1[ (DATA_WIDTH+COEFF_WIDTH+3)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH+3)*channel ];
							

					dOut_sub[ (DATA_WIDTH+COEFF_WIDTH+4)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH+4)*channel ] <=
						  dOut_sub_0[ (DATA_WIDTH+COEFF_WIDTH+3)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH+3)*channel ] + dOut_sub_1[ (DATA_WIDTH+COEFF_WIDTH+3)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH+3)*channel ];
					

					dOut_sum[ (DATA_WIDTH+COEFF_WIDTH+4)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH+4)*channel ] <= (dOut_add[ (DATA_WIDTH+COEFF_WIDTH+4)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH+4)*channel ] >= dOut_sub[ (DATA_WIDTH+COEFF_WIDTH+4)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH+4)*channel ]) ? dOut_add[ (DATA_WIDTH+COEFF_WIDTH+4)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH+4)*channel ] - dOut_sub[ (DATA_WIDTH+COEFF_WIDTH+4)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH+4)*channel ] : dOut_sub[ (DATA_WIDTH+COEFF_WIDTH+4)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH+4)*channel ] - dOut_add[ (DATA_WIDTH+COEFF_WIDTH+4)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH+4)*channel ];
					

					dOut_shift[ COEFF_WIDTH*(channel+1)-1 : COEFF_WIDTH*channel ] <= (dOut_sum[ (DATA_WIDTH+COEFF_WIDTH+4)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH+4)*channel ] >> 8) & ({ {(DATA_WIDTH+4){1'b0}}, {COEFF_WIDTH{1'b1}} });
					

					dOut[ DATA_WIDTH*(channel+1)-1 : DATA_WIDTH*channel]<= (dOut_shift[ COEFF_WIDTH*(channel+1)-1 : COEFF_WIDTH*channel] > 9'd255)? 8'd255 : dOut_shift[ COEFF_WIDTH*(channel+1)-2 : COEFF_WIDTH*channel];
				end
			end
		end
endgenerate


/;

			writeNextValidLine <= ((writeOutputLine*yScale + {{(OUTPUT_Y_RES_WIDTH + SCALE_INT_BITS){1'b0}}, topFracOffset}) >> SCALE_FRAC_BITS) & {{SCALE_BITS{1'b0}}, {OUTPUT_Y_RES_WIDTH{1'b1}}};
		end
		else
		begin
			getNextPlusOne <= 1;
		end
	end
end

reg			discardInput;
reg [DISCARD_CNT_WIDTH-1:0] discardCountReg;

reg [1:0]	writeState;

(* keep = "true" *)  reg [INPUT_X_RES_WIDTH-1:0] writeColCount;
(* keep = "true" *)  reg [INPUT_X_RES_WIDTH-1:0] writeColCount_dump;
reg			enableNextDin;
reg			forceRead;




localparam	WS_START = 0;
localparam	WS_DISCARD = 1;
localparam	WS_READ = 2;
localparam	WS_DONE = 3;


always @ (posedge clk)
begin
	if(rst)
	begin
		writeState <= WS_START;
		enableNextDin <= 0;
		discardInput <= 0;
		readyForRead <= 0;
		writeRowCount <= 0;
		writeColCount <= 0;
		writeColCount_dump <= 0;
		discardCountReg <= 0;
		forceRead <= 0;
	end
	else
	begin
		case (writeState)
		
			WS_START:
			begin
				discardCountReg <= inputDiscardCnt;
				if(inputDiscardCnt > 0)
				begin
					discardInput <= 1;
					enableNextDin <= 1;
					writeState <= WS_DISCARD;
				end
				else
				begin
					discardInput <= 0;
					enableNextDin <= 1;
					writeState <= WS_READ;
				end
				discardInput <= (inputDiscardCnt > 0) ? 1'b1 : 1'b0;
			end
			
			WS_DISCARD:
			begin
				if(dInValid)
				begin
					discardCountReg <= discardCountReg - 1;
					if((discardCountReg - 1) == 0)
					begin
						discardInput <= 0;
						writeState <= WS_READ;
					end
				end
			end
			
			WS_READ:
			begin


				if(dInValid & din_Enable)
				begin

					if(writeColCount == inputXRes)
					begin
						if((writeNextValidLine == writeRowCount + 1) ||
						    (writeNextValidLine == writeRowCount + 2) ||
							(writeNextPlusOne == writeRowCount + 1) ||
							(writeNextPlusTwo == writeRowCount + 2))
						begin 
							discardInput <= 0;
						end
						else
						begin
							discardInput <= 1;
						end
						

						if(writeRowCount[2])
							readyForRead <= 1;
						
						if(writeRowCount == inputYRes)
						begin
							writeState <= WS_DONE;
							enableNextDin <= 0;
							forceRead <= 1;
						end
						
						writeColCount <= 0;
						writeColCount_dump <= 0;
						writeRowCount <= writeRowCount + 1;
					end
					else if(fillCount == BUFFER_SIZE) begin
						writeColCount <= 0;
						writeColCount_dump <= 0;
					end
					else
					begin
						writeColCount <= writeColCount + 1;
						writeColCount_dump <= writeColCount_dump + 1;
					end
				end
			end
			
			WS_DONE:
			begin

			end
			
		endcase
	end
end




reg nextDin_Reg;
always@(posedge clk)
begin
	if(rst | start) begin
		nextDin_Reg <= 0;
	end
	else if((fillCount < BUFFER_SIZE) & enableNextDin) begin
		nextDin_Reg <= 1;
	end
	else begin
		nextDin_Reg <= 0;
	end
end

assign din_Enable = (fillCount < BUFFER_SIZE) & enableNextDin;



reg advanceWrite;
reg advanceWrite_delay;
always@(posedge clk)
begin
	if(rst | start) begin
		advanceWrite <= 0;
		advanceWrite_delay <= 0;
	end
	else if((writeColCount == inputXRes - 3) & (discardInput == 0) & dInValid & din_Enable) begin
		advanceWrite <= 1;
	end
	else if((writeColCount == inputXRes) & (discardInput == 0) & dInValid & din_Enable) begin
		advanceWrite_delay <= 1;
	end
	else begin
		advanceWrite <= 0;
		advanceWrite_delay <= 0;
	end
end
assign allDataWritten = (writeState == WS_DONE);

reg [5:0] First_Outputline_cnt;
reg First_Outputline;

always@(posedge clk or posedge rst)
begin
	if(rst) begin
		First_Outputline_cnt <= 0;
	end
	else if(outputLine_dump == 0) begin
		First_Outputline_cnt <= 0;
	end
	else begin
		First_Outputline_cnt <= First_Outputline_cnt + 1;
	end
end

always@(posedge clk or posedge rst)
begin
	if(rst) begin
		First_Outputline <= 0;
	end
	else if(outputLine_dump == 0) begin
		First_Outputline <= 0;
	end
	else if(First_Outputline_cnt == 6'd17) begin
		First_Outputline <= 1;
	end
end

reg Last_Outputline;
reg [5:0] Last_Outputline_cnt;

always@(posedge clk or posedge rst)
begin
	if(rst) begin
		Last_Outputline_cnt <= 0;
	end
	else if(Last_Outputline) begin
		if(Last_Outputline_cnt == 6'd31) begin
			Last_Outputline_cnt <= 0;
		end
		else if(outputLine_dump == outputYRes+1) begin
			Last_Outputline_cnt <= Last_Outputline_cnt + 1;
		end
	end
	else if(outputLine_dump == outputYRes) begin
		Last_Outputline_cnt <= Last_Outputline_cnt + 1;
	end
end

always@(posedge clk or posedge rst)
begin
	if(rst) begin
		Last_Outputline <= 0;
	end
	else if(Last_Outputline) begin
		if(Last_Outputline_cnt == 6'd31) begin
			Last_Outputline <= 0;
		end
	end
	else if(Last_Outputline_cnt == 6'd15) begin
		Last_Outputline <= 1;
	end
end

reg writeEnable_reg_0,writeEnable_reg_1;
reg [INPUT_X_RES_WIDTH-1:0] writeColCount_reg;
reg forceRead_reg;
reg forceRead_dump;
reg advanceWrite_reg0,advanceWrite_reg1;
reg	[13:0] advanceRead1_ram,advanceRead2_ram,advanceRead3_ram,advanceRead4_ram;
reg [DATA_WIDTH*CHANNELS-1:0]  dIn_reg_0,dIn_reg_1;
reg Last_Outputline_reg,First_Outputline_reg;

always@(posedge clk)
begin
	dIn_reg_0 <= dIn;
	dIn_reg_1 <= dIn_reg_0;
	writeEnable_reg_0 <= dInValid & din_Enable & enableNextDin & ~discardInput;
	writeEnable_reg_1 <= writeEnable_reg_0;
	writeColCount_reg <= writeColCount_dump;
	forceRead_reg <= forceRead;
	advanceWrite_reg0 <= advanceWrite;
	advanceWrite_reg1 <= advanceWrite_reg0;
	advanceRead1_ram <= {advanceRead1_ram[12:0],advanceRead1};
	advanceRead2_ram <= {advanceRead2_ram[12:0],advanceRead2};
	advanceRead3_ram <= {advanceRead3_ram[12:0],advanceRead3};
	advanceRead4_ram <= {advanceRead4_ram[12:0],advanceRead4};
	Last_Outputline_reg <= Last_Outputline;
	First_Outputline_reg <= First_Outputline;
end


cash_ram_rw #(
	.DATA_WIDTH( DATA_WIDTH*CHANNELS ),
	.ADDRESS_WIDTH( INPUT_X_RES_WIDTH ),
	.BUFFER_SIZE( BUFFER_SIZE )
) cash_ram_rw_inst (
	.clk( clk ),
	.rst( rst | start ),
	.advanceRead1( advanceRead1_ram[13] ),
	.advanceRead2( advanceRead2_ram[13] ),
	.advanceRead3( advanceRead3_ram[13] ),
	.advanceRead4( advanceRead4_ram[13] ),
	.readAddress( readAddress ),
	.forceRead( forceRead_reg ),

	.inputXRes(inputXRes),
	.advanceWrite( advanceWrite_reg1 ),
	.advanceWrite_delay (advanceWrite_delay),
	.writeData( dIn_reg_1 ),
	.writeAddress( writeColCount_reg ),
	.writeEnable( writeEnable_reg_1 ),
	.fillCount( fillCount ),
	.First_Outputline(First_Outputline_reg),
	.Last_Outputline(Last_Outputline_reg),
	.allDataWritten(allDataWritten),
	.readData00 (readData00),
	.readData01 (readData01),
	.readData02 (readData02),
	.readData03 (readData03),
	.readData10 (readData10),
	.readData11 (readData11),
	.readData12 (readData12),
	.readData13 (readData13),
	.readData20 (readData20),
	.readData21 (readData21),
	.readData22 (readData22),
	.readData23 (readData23),
	.readData30 (readData30),
	.readData31 (readData31),
	.readData32 (readData32),
	.readData33 (readData33)
);

endmodule
module video_scaler (

input wire							  clk,
input wire							  rst,
input wire							  start,
                                      

input wire [24-1:0]  dIn,
input wire							  dInValid,
input wire							  dout_Enable,
                                      

output wire							  din_Enable,

output reg [24-1:0]  dOut,
output reg							  dOutValid,
output reg                            scaler_done,
                                      

input wire [11-1:0]	  inputXRes,
input wire [11-1:0]	  inputYRes,
input wire [11-1:0]	  outputXRes,
input wire [11-1:0]	  outputYRes,
input wire [18-1:0]			  xScale,
input wire [18-1:0]			  yScale,


input wire [8-1:0]	  inputDiscardCnt,

														
input wire [25-1:0]              leftOffset,


														
input wire [14-1:0]	  topFracOffset

);

localparam	DATA_WIDTH =			8;
localparam	CHANNELS =				3;
localparam 	DISCARD_CNT_WIDTH =		8;
localparam	INPUT_X_RES_WIDTH =		11;
localparam	INPUT_Y_RES_WIDTH =		11;
localparam	OUTPUT_X_RES_WIDTH =	11;
localparam	OUTPUT_Y_RES_WIDTH =	11;
localparam	FRACTION_BITS =			8;

localparam	SCALE_INT_BITS =		4;



localparam	SCALE_FRAC_BITS =		14;
localparam	BUFFER_SIZE =			8;
localparam	COEFF_WIDTH =			FRACTION_BITS + 1;
localparam	SCALE_BITS =			SCALE_INT_BITS + SCALE_FRAC_BITS;
localparam  Q_WIDTH = OUTPUT_X_RES_WIDTH + SCALE_FRAC_BITS;

localparam	BUFFER_SIZE_WIDTH =		((BUFFER_SIZE+1) <= 2) ? 1 :
									((BUFFER_SIZE+1) <= 4) ? 2 :
									((BUFFER_SIZE+1) <= 8) ? 3 :
									((BUFFER_SIZE+1) <= 16) ? 4 :
									((BUFFER_SIZE+1) <= 32) ? 5 :
									((BUFFER_SIZE+1) <= 64) ? 6 : 7;

reg [COEFF_WIDTH*CHANNELS-1:0]                 dOut_shift;
reg [(DATA_WIDTH+COEFF_WIDTH+4)*CHANNELS-1:0]  dOut_sum;
reg [(DATA_WIDTH+COEFF_WIDTH+4)*CHANNELS-1:0]  dOut_add;
reg [(DATA_WIDTH+COEFF_WIDTH+4)*CHANNELS-1:0]  dOut_sub;
reg [(DATA_WIDTH+COEFF_WIDTH+3)*CHANNELS-1:0]  dOut_add_0;
reg [(DATA_WIDTH+COEFF_WIDTH+3)*CHANNELS-1:0]  dOut_add_1;
reg [(DATA_WIDTH+COEFF_WIDTH+3)*CHANNELS-1:0]  dOut_sub_0;
reg [(DATA_WIDTH+COEFF_WIDTH+3)*CHANNELS-1:0]  dOut_sub_1;

reg	advanceRead1,advanceRead2,advanceRead3,advanceRead4;

wire [DATA_WIDTH*CHANNELS-1:0]	readData00;
wire [DATA_WIDTH*CHANNELS-1:0]	readData01;
wire [DATA_WIDTH*CHANNELS-1:0]	readData02;
wire [DATA_WIDTH*CHANNELS-1:0]	readData03;
wire [DATA_WIDTH*CHANNELS-1:0]	readData10;
wire [DATA_WIDTH*CHANNELS-1:0]	readData11;
wire [DATA_WIDTH*CHANNELS-1:0]	readData12;
wire [DATA_WIDTH*CHANNELS-1:0]	readData13;
wire [DATA_WIDTH*CHANNELS-1:0]	readData20;
wire [DATA_WIDTH*CHANNELS-1:0]	readData21;
wire [DATA_WIDTH*CHANNELS-1:0]	readData22;
wire [DATA_WIDTH*CHANNELS-1:0]	readData23;
wire [DATA_WIDTH*CHANNELS-1:0]	readData30;
wire [DATA_WIDTH*CHANNELS-1:0]	readData31;
wire [DATA_WIDTH*CHANNELS-1:0]	readData32;
wire [DATA_WIDTH*CHANNELS-1:0]	readData33;

reg [INPUT_X_RES_WIDTH-1:0]	    readAddress;

reg 							readyForRead;
(* keep = "true" *)reg [SCALE_BITS-1:0]	        outputLine;
(* keep = "true" *)reg [SCALE_BITS-1:0]	        outputLine_dump;
reg [SCALE_BITS-1:0]		    outputColumn;
reg [SCALE_BITS-1:0]		    outputColumn_reg;
reg [2*SCALE_BITS-1:0]          xScaleAmount;
reg [2*SCALE_BITS-1:0]          yScaleAmount;
reg [2*SCALE_BITS-1:0]          yScaleAmountNext;
wire [BUFFER_SIZE_WIDTH-1:0] 	fillCount;
reg                 			lineSwitchOutputDisable;
reg								dOutValidInt;

reg [COEFF_WIDTH-1:0]			xBlend;
reg [COEFF_WIDTH-1:0]			yBlend;

wire [INPUT_X_RES_WIDTH-1:0]	xPixLow = xScaleAmount[INPUT_X_RES_WIDTH-1+SCALE_FRAC_BITS:SCALE_FRAC_BITS];

wire 							allDataWritten;
reg 							readState;
reg                             state_m_comb;

reg [INPUT_Y_RES_WIDTH-1:0]	yPixLow;
always @ (posedge clk)
begin
	yPixLow <= yScaleAmount[INPUT_Y_RES_WIDTH-1+SCALE_FRAC_BITS:SCALE_FRAC_BITS];
end

reg [INPUT_Y_RES_WIDTH-1:0]	yPixLowNext;
always @ (posedge clk)
begin
	yPixLowNext <= yScaleAmountNext[INPUT_Y_RES_WIDTH-1+SCALE_FRAC_BITS:SCALE_FRAC_BITS];
end


localparam RS_START = 0;
localparam RS_READ_LINE = 1;



always @ (posedge clk or posedge rst or posedge start)
begin
	if(rst | start)
	begin
		outputLine_dump <= 0;
		outputLine <= 0;
		outputColumn <= 0;
		outputColumn_reg <= 1;
		xScaleAmount <= 0;
		yScaleAmount <= 0;
		readState <= RS_START;
		dOutValidInt <= 0;
		lineSwitchOutputDisable <= 0;
		advanceRead1 <= 0;
		advanceRead2 <= 0;
		advanceRead3 <= 0;
		advanceRead4 <= 0;
	end
	else
	begin
		case (readState)  
			RS_START:
			begin

				xScaleAmount <= leftOffset;
				yScaleAmount <= {{INPUT_Y_RES_WIDTH{1'b0}}, topFracOffset};
				if(readyForRead)
				begin
					readState <= RS_READ_LINE;
					dOutValidInt <= 1;
				end
			end

			RS_READ_LINE:
			begin

				if(dout_Enable && dOutValidInt)
				begin
					if(outputColumn[10:0] == outputXRes)
					begin


						if(yPixLowNext == (yPixLow + 1))
						begin


							advanceRead1 <= 1;



							if(fillCount < 5)		
								dOutValidInt <= 0;
						end


						if(yPixLowNext == (yPixLow + 2))
						begin
							advanceRead2 <= 1;



							if(fillCount < 6)
								dOutValidInt <= 0;
						end					
						if(yPixLowNext == (yPixLow + 3))
						begin
							advanceRead3 <= 1;



							if(fillCount < 7)
								dOutValidInt <= 0;
						end
						if(yPixLowNext > (yPixLow + 3))
						begin
							advanceRead4 <= 1;



							if(fillCount < 8)
								dOutValidInt <= 0;
						end
						outputColumn <= 0;
						outputColumn_reg <= 1;
						xScaleAmount <= leftOffset;
						outputLine <= outputLine + 1;
						outputLine_dump <= outputLine_dump + 1;
						yScaleAmount <= yScaleAmountNext;
						lineSwitchOutputDisable <= 1;
					end
					else
					begin
						if(lineSwitchOutputDisable == 0)
						begin
							outputColumn <= outputColumn + 1;
							outputColumn_reg <= outputColumn_reg + 1;
							xScaleAmount <= outputColumn_reg * xScale;
						end
						advanceRead1 <= 0;
						advanceRead2 <= 0;
						advanceRead3 <= 0;
						advanceRead4 <= 0;
						lineSwitchOutputDisable <= 0;
					end
				end
				else
				begin
					advanceRead1 <= 0;
					advanceRead2 <= 0;
					advanceRead3 <= 0;
					advanceRead4 <= 0;
					lineSwitchOutputDisable <= 0;
				end
				



				if(fillCount >= 4 && dOutValidInt == 0 || allDataWritten)
				begin
					if( state_m_comb )
					begin
						dOutValidInt <= 1;
						lineSwitchOutputDisable <= 0;
					end
				end
			end
		endcase
	end
end

reg  [7:0] state_vaild_cnt;


always@(posedge clk)
begin
	if(rst | start) begin
		state_vaild_cnt <= 1'd0;
		state_m_comb <= 1'd1;
	end
	else if(state_vaild_cnt > 0) begin
		state_vaild_cnt <= state_vaild_cnt + 1;
		if(state_vaild_cnt == 8'd30) begin
			state_m_comb <= 1'd1;
			state_vaild_cnt <= 1'd0;
		end
	end
	else if(outputColumn[10:0] == outputXRes) begin
		state_m_comb <= 1'd0;
		state_vaild_cnt <= state_vaild_cnt + 1;
	end
end

reg [SCALE_BITS-1:0] outputLine_reg;

always@(posedge clk or posedge rst)
begin
	if(rst) begin
		yScaleAmountNext <= 0;
		outputLine_reg <= 0;
	end
	else begin
		outputLine_reg <= outputLine + 1;
		yScaleAmountNext <= outputLine_reg * yScale;
	end
end


always @(posedge clk or posedge rst)
begin
	if(rst)
	begin
		scaler_done <= 0;
	end
	else
	begin
		scaler_done <= (outputLine_dump == outputYRes) && (outputColumn[10:0] == outputXRes);
	end
end


always@(posedge clk or posedge rst)
begin
	if(rst) begin
		readAddress <= 0;
	end
	else begin
		readAddress <= xPixLow;
	end
end

reg [26:0] dOutValid_reg;

always @(posedge clk or posedge rst or posedge start)
begin
	if(rst | start)
	begin
		dOutValid_reg <= 0;
		dOutValid <= 0;
	end
	else
	begin


		dOutValid_reg <= {dOutValid_reg[25:0],(dout_Enable && dOutValidInt && !lineSwitchOutputDisable)};
		dOutValid <= dOutValid_reg[26];
	end
end

always @(posedge clk or posedge rst)
begin
	if(rst)
	begin
		xBlend <= 0;
		yBlend <= 0;
	end
	else begin

		xBlend <= {1'b0, xScaleAmount[SCALE_FRAC_BITS-1:SCALE_FRAC_BITS-FRACTION_BITS]};
		yBlend <= {1'b0, yScaleAmount[SCALE_FRAC_BITS-1:SCALE_FRAC_BITS-FRACTION_BITS]};
	end
end

wire [COEFF_WIDTH-1:0]	coeff00_0;
wire [COEFF_WIDTH-1:0]	coeff01_0;
wire [COEFF_WIDTH-1:0]	coeff02_0;
wire [COEFF_WIDTH-1:0]	coeff03_0;
wire [COEFF_WIDTH-1:0]	coeff10_0;
wire [COEFF_WIDTH-1:0]	coeff11_0;
wire [COEFF_WIDTH-1:0]	coeff12_0;
wire [COEFF_WIDTH-1:0]	coeff13_0;
wire [COEFF_WIDTH-1:0]	coeff20_0;
wire [COEFF_WIDTH-1:0]	coeff21_0;
wire [COEFF_WIDTH-1:0]	coeff22_0;
wire [COEFF_WIDTH-1:0]	coeff23_0;
wire [COEFF_WIDTH-1:0]	coeff30_0;
wire [COEFF_WIDTH-1:0]	coeff31_0;
wire [COEFF_WIDTH-1:0]	coeff32_0;
wire [COEFF_WIDTH-1:0]	coeff33_0;

reg [COEFF_WIDTH-1:0]	coeff00_1;
reg [COEFF_WIDTH-1:0]	coeff01_1;
reg [COEFF_WIDTH-1:0]	coeff02_1;
reg [COEFF_WIDTH-1:0]	coeff03_1;
reg [COEFF_WIDTH-1:0]	coeff10_1;
reg [COEFF_WIDTH-1:0]	coeff11_1;
reg [COEFF_WIDTH-1:0]	coeff12_1;
reg [COEFF_WIDTH-1:0]	coeff13_1;
reg [COEFF_WIDTH-1:0]	coeff20_1;
reg [COEFF_WIDTH-1:0]	coeff21_1;
reg [COEFF_WIDTH-1:0]	coeff22_1;
reg [COEFF_WIDTH-1:0]	coeff23_1;
reg [COEFF_WIDTH-1:0]	coeff30_1;
reg [COEFF_WIDTH-1:0]	coeff31_1;
reg [COEFF_WIDTH-1:0]	coeff32_1;
reg [COEFF_WIDTH-1:0]	coeff33_1;

wire [COEFF_WIDTH-1:0]	bi_y0;
wire [COEFF_WIDTH-1:0]	bi_y1;
wire [COEFF_WIDTH-1:0]	bi_y2;
wire [COEFF_WIDTH-1:0]	bi_y3;
wire [COEFF_WIDTH-1:0]	bi_x0;
wire [COEFF_WIDTH-1:0]	bi_x1;
wire [COEFF_WIDTH-1:0]	bi_x2;
wire [COEFF_WIDTH-1:0]	bi_x3;


wire [COEFF_WIDTH-1:0]	coeffOne  = {1'b1, {(COEFF_WIDTH-1){1'b0}}};

wire [COEFF_WIDTH-1:0]	coeffHalf = {2'b01, {(COEFF_WIDTH-2){1'b0}}};

wire [COEFF_WIDTH-1:0]  bi_a      = {2'b01, {(COEFF_WIDTH-2){1'b0}}};


BiCubic BiCubic_inst(
	.clk        (clk),
	.rst_n      (!rst | !start),
	.coeffHalf  (coeffHalf),
	.coeffOne   (coeffOne),
	.yBlend     (yBlend),
	.bi_a       (bi_a),
	.xBlend     (xBlend),
	.bi_y0      (bi_y0),
	.bi_y1      (bi_y1),
	.bi_y2      (bi_y2),
	.bi_y3      (bi_y3),
	.bi_x0      (bi_x0),
	.bi_x1      (bi_x1),
	.bi_x2      (bi_x2),
	.bi_x3      (bi_x3)
);


coefficient #(
	.FRACTION_BITS  (FRACTION_BITS),
	.COEFF_WIDTH    (COEFF_WIDTH)
)coefficient_inst(
	.clk        (clk),
	.rst_n      (!rst | !start),
	.coeffHalf  (coeffHalf),
	.bi_y0      (bi_y0),
	.bi_y1      (bi_y1),
	.bi_y2      (bi_y2),
	.bi_y3      (bi_y3),
	.bi_x0      (bi_x0),
	.bi_x1      (bi_x1),
	.bi_x2      (bi_x2),
	.bi_x3      (bi_x3),
	.coeff00    (coeff00_0),
	.coeff01    (coeff01_0),
	.coeff02    (coeff02_0),
	.coeff03    (coeff03_0),
	.coeff10    (coeff10_0),
	.coeff11    (coeff11_0),
	.coeff12    (coeff12_0),
	.coeff13    (coeff13_0),
	.coeff20    (coeff20_0),
	.coeff21    (coeff21_0),
	.coeff22    (coeff22_0),
	.coeff23    (coeff23_0),
	.coeff30    (coeff30_0),
	.coeff31    (coeff31_0),
	.coeff32    (coeff32_0),
	.coeff33    (coeff33_0)
);

reg [COEFF_WIDTH-1:0]	coeff00_reg0;
reg [COEFF_WIDTH-1:0]	coeff01_reg0;
reg [COEFF_WIDTH-1:0]	coeff02_reg0;
reg [COEFF_WIDTH-1:0]	coeff03_reg0;
reg [COEFF_WIDTH-1:0]	coeff10_reg0;
reg [COEFF_WIDTH-1:0]	coeff11_reg0;
reg [COEFF_WIDTH-1:0]	coeff12_reg0;
reg [COEFF_WIDTH-1:0]	coeff13_reg0;
reg [COEFF_WIDTH-1:0]	coeff20_reg0;
reg [COEFF_WIDTH-1:0]	coeff21_reg0;
reg [COEFF_WIDTH-1:0]	coeff22_reg0;
reg [COEFF_WIDTH-1:0]	coeff23_reg0;
reg [COEFF_WIDTH-1:0]	coeff30_reg0;
reg [COEFF_WIDTH-1:0]	coeff31_reg0;
reg [COEFF_WIDTH-1:0]	coeff32_reg0;
reg [COEFF_WIDTH-1:0]	coeff33_reg0;

reg [COEFF_WIDTH-1:0]	coeff00_reg1;
reg [COEFF_WIDTH-1:0]	coeff01_reg1;
reg [COEFF_WIDTH-1:0]	coeff02_reg1;
reg [COEFF_WIDTH-1:0]	coeff03_reg1;
reg [COEFF_WIDTH-1:0]	coeff10_reg1;
reg [COEFF_WIDTH-1:0]	coeff11_reg1;
reg [COEFF_WIDTH-1:0]	coeff12_reg1;
reg [COEFF_WIDTH-1:0]	coeff13_reg1;
reg [COEFF_WIDTH-1:0]	coeff20_reg1;
reg [COEFF_WIDTH-1:0]	coeff21_reg1;
reg [COEFF_WIDTH-1:0]	coeff22_reg1;
reg [COEFF_WIDTH-1:0]	coeff23_reg1;
reg [COEFF_WIDTH-1:0]	coeff30_reg1;
reg [COEFF_WIDTH-1:0]	coeff31_reg1;
reg [COEFF_WIDTH-1:0]	coeff32_reg1;
reg [COEFF_WIDTH-1:0]	coeff33_reg1;


always@(posedge clk)
begin
	coeff00_reg0 <= coeff00_0;
	coeff01_reg0 <= coeff01_0;
	coeff02_reg0 <= coeff02_0;
	coeff03_reg0 <= coeff03_0;
	coeff10_reg0 <= coeff10_0;
	coeff11_reg0 <= coeff11_0;
	coeff12_reg0 <= coeff12_0;
	coeff13_reg0 <= coeff13_0;
	coeff20_reg0 <= coeff20_0;
	coeff21_reg0 <= coeff21_0;
	coeff22_reg0 <= coeff22_0;
	coeff23_reg0 <= coeff23_0;
	coeff30_reg0 <= coeff30_0;
	coeff31_reg0 <= coeff31_0;
	coeff32_reg0 <= coeff32_0;
	coeff33_reg0 <= coeff33_0;
	
	coeff00_reg1 <= coeff00_reg0;
	coeff01_reg1 <= coeff01_reg0;
	coeff02_reg1 <= coeff02_reg0;
	coeff03_reg1 <= coeff03_reg0;
	coeff10_reg1 <= coeff10_reg0;
	coeff11_reg1 <= coeff11_reg0;
	coeff12_reg1 <= coeff12_reg0;
	coeff13_reg1 <= coeff13_reg0;
	coeff20_reg1 <= coeff20_reg0;
	coeff21_reg1 <= coeff21_reg0;
	coeff22_reg1 <= coeff22_reg0;
	coeff23_reg1 <= coeff23_reg0;
	coeff30_reg1 <= coeff30_reg0;
	coeff31_reg1 <= coeff31_reg0;
	coeff32_reg1 <= coeff32_reg0;
	coeff33_reg1 <= coeff33_reg0;
end

reg [COEFF_WIDTH-1:0]	coeff00;
reg [COEFF_WIDTH-1:0]	coeff01;
reg [COEFF_WIDTH-1:0]	coeff02;
reg [COEFF_WIDTH-1:0]	coeff03;
reg [COEFF_WIDTH-1:0]	coeff10;
reg [COEFF_WIDTH-1:0]	coeff11;
reg [COEFF_WIDTH-1:0]	coeff12;
reg [COEFF_WIDTH-1:0]	coeff13;
reg [COEFF_WIDTH-1:0]	coeff20;
reg [COEFF_WIDTH-1:0]	coeff21;
reg [COEFF_WIDTH-1:0]	coeff22;
reg [COEFF_WIDTH-1:0]	coeff23;
reg [COEFF_WIDTH-1:0]	coeff30;
reg [COEFF_WIDTH-1:0]	coeff31;
reg [COEFF_WIDTH-1:0]	coeff32;
reg [COEFF_WIDTH-1:0]	coeff33;

always@(posedge clk)
begin
	coeff00 <= coeff00_reg1;
	coeff01 <= coeff01_reg1;
	coeff02 <= coeff02_reg1;
	coeff03 <= coeff03_reg1;
	coeff10 <= coeff10_reg1;
	coeff11 <= coeff11_reg1;
	coeff12 <= coeff12_reg1;
	coeff13 <= coeff13_reg1;
	coeff20 <= coeff20_reg1;
	coeff21 <= coeff21_reg1;
	coeff22 <= coeff22_reg1;
	coeff23 <= coeff23_reg1;
	coeff30 <= coeff30_reg1;
	coeff31 <= coeff31_reg1;
	coeff32 <= coeff32_reg1;
	coeff33 <= coeff33_reg1;
end


reg [(DATA_WIDTH+COEFF_WIDTH)*CHANNELS-1:0]	product00, product01, product02, product03,product10, product11, product12, product13,product20, product21, product22, product23,product30, product31, product32, product33;
generate
genvar channel;
	for(channel = 0; channel < CHANNELS; channel = channel + 1)
		begin : blend_mult_generate
			always @(posedge clk or posedge rst)
			begin
				if(rst)
				begin

					product00[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel] <= 0;
					product01[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel] <= 0;
					product02[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel] <= 0;
					product03[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel] <= 0;
					product10[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel] <= 0;
					product11[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel] <= 0;
					product12[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel] <= 0;
					product13[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel] <= 0;
					product20[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel] <= 0;
					product21[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel] <= 0;
					product22[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel] <= 0;
					product23[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel] <= 0;
					product30[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel] <= 0;
					product31[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel] <= 0;
					product32[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel] <= 0;
					product33[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel] <= 0;
					dOut_add_0[ (DATA_WIDTH+COEFF_WIDTH+3)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH+3)*channel ] <= 0;
					dOut_add_1[ (DATA_WIDTH+COEFF_WIDTH+3)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH+3)*channel ] <= 0;
					dOut_sub_0[ (DATA_WIDTH+COEFF_WIDTH+3)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH+3)*channel ] <= 0;
					dOut_sub_1[ (DATA_WIDTH+COEFF_WIDTH+3)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH+3)*channel ] <= 0;
					dOut_add[ (DATA_WIDTH+COEFF_WIDTH+4)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH+4)*channel ] <= 0;
					dOut_sub[ (DATA_WIDTH+COEFF_WIDTH+4)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH+4)*channel ] <= 0;				
					dOut_sum[ (DATA_WIDTH+COEFF_WIDTH+4)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH+4)*channel ] <= 0;
					dOut_shift[ COEFF_WIDTH*(channel+1)-1 : COEFF_WIDTH*channel ] <= 0;
					dOut[ DATA_WIDTH*(channel+1)-1 : DATA_WIDTH*channel]<= 0;
					
				end
				else
				begin




					product00[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel] <= readData00[ DATA_WIDTH*(channel+1)-1 : DATA_WIDTH*channel ] * coeff00;
					product01[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel] <= readData01[ DATA_WIDTH*(channel+1)-1 : DATA_WIDTH*channel ] * coeff01;
					product02[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel] <= readData02[ DATA_WIDTH*(channel+1)-1 : DATA_WIDTH*channel ] * coeff02;
					product03[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel] <= readData03[ DATA_WIDTH*(channel+1)-1 : DATA_WIDTH*channel ] * coeff03;
					product10[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel] <= readData10[ DATA_WIDTH*(channel+1)-1 : DATA_WIDTH*channel ] * coeff10;
					product11[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel] <= readData11[ DATA_WIDTH*(channel+1)-1 : DATA_WIDTH*channel ] * coeff11;
					product12[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel] <= readData12[ DATA_WIDTH*(channel+1)-1 : DATA_WIDTH*channel ] * coeff12;
					product13[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel] <= readData13[ DATA_WIDTH*(channel+1)-1 : DATA_WIDTH*channel ] * coeff13;
					product20[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel] <= readData20[ DATA_WIDTH*(channel+1)-1 : DATA_WIDTH*channel ] * coeff20;
					product21[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel] <= readData21[ DATA_WIDTH*(channel+1)-1 : DATA_WIDTH*channel ] * coeff21;
					product22[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel] <= readData22[ DATA_WIDTH*(channel+1)-1 : DATA_WIDTH*channel ] * coeff22;
					product23[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel] <= readData23[ DATA_WIDTH*(channel+1)-1 : DATA_WIDTH*channel ] * coeff23;
					product30[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel] <= readData30[ DATA_WIDTH*(channel+1)-1 : DATA_WIDTH*channel ] * coeff30;
					product31[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel] <= readData31[ DATA_WIDTH*(channel+1)-1 : DATA_WIDTH*channel ] * coeff31;
					product32[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel] <= readData32[ DATA_WIDTH*(channel+1)-1 : DATA_WIDTH*channel ] * coeff32;
					product33[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel] <= readData33[ DATA_WIDTH*(channel+1)-1 : DATA_WIDTH*channel ] * coeff33;
					
					dOut_add_0[ (DATA_WIDTH+COEFF_WIDTH+3)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH+3)*channel ] <=
						(product00[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel])+
						(product03[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel])+
						(product11[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel])+
						(product12[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel]);
						
					dOut_add_1[ (DATA_WIDTH+COEFF_WIDTH+3)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH+3)*channel ] <=
						(product21[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel])+
						(product22[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel])+
						(product30[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel])+
						(product33[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel]);
						
					dOut_sub_0[ (DATA_WIDTH+COEFF_WIDTH+3)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH+3)*channel ] <=
						(product01[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel])+
						(product02[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel])+
						(product10[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel])+
						(product13[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel]);
						
					dOut_sub_1[ (DATA_WIDTH+COEFF_WIDTH+3)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH+3)*channel ] <=
						(product20[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel])+
						(product23[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel])+
						(product31[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel])+
						(product32[ (DATA_WIDTH+COEFF_WIDTH)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH)*channel]);
					

					dOut_add[ (DATA_WIDTH+COEFF_WIDTH+4)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH+4)*channel ] <=
						  dOut_add_0[ (DATA_WIDTH+COEFF_WIDTH+3)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH+3)*channel ] + dOut_add_1[ (DATA_WIDTH+COEFF_WIDTH+3)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH+3)*channel ];
							

					dOut_sub[ (DATA_WIDTH+COEFF_WIDTH+4)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH+4)*channel ] <=
						  dOut_sub_0[ (DATA_WIDTH+COEFF_WIDTH+3)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH+3)*channel ] + dOut_sub_1[ (DATA_WIDTH+COEFF_WIDTH+3)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH+3)*channel ];
					

					dOut_sum[ (DATA_WIDTH+COEFF_WIDTH+4)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH+4)*channel ] <= (dOut_add[ (DATA_WIDTH+COEFF_WIDTH+4)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH+4)*channel ] >= dOut_sub[ (DATA_WIDTH+COEFF_WIDTH+4)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH+4)*channel ]) ? dOut_add[ (DATA_WIDTH+COEFF_WIDTH+4)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH+4)*channel ] - dOut_sub[ (DATA_WIDTH+COEFF_WIDTH+4)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH+4)*channel ] : dOut_sub[ (DATA_WIDTH+COEFF_WIDTH+4)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH+4)*channel ] - dOut_add[ (DATA_WIDTH+COEFF_WIDTH+4)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH+4)*channel ];
					

					dOut_shift[ COEFF_WIDTH*(channel+1)-1 : COEFF_WIDTH*channel ] <= (dOut_sum[ (DATA_WIDTH+COEFF_WIDTH+4)*(channel+1)-1 : (DATA_WIDTH+COEFF_WIDTH+4)*channel ] >> 8) & ({ {(DATA_WIDTH+4){1'b0}}, {COEFF_WIDTH{1'b1}} });
					

					dOut[ DATA_WIDTH*(channel+1)-1 : DATA_WIDTH*channel]<= (dOut_shift[ COEFF_WIDTH*(channel+1)-1 : COEFF_WIDTH*channel] > 9'd255)? 8'd255 : dOut_shift[ COEFF_WIDTH*(channel+1)-2 : COEFF_WIDTH*channel];
				end
			end
		end
endgenerate


/;

			writeNextValidLine <= ((writeOutputLine*yScale + {{(OUTPUT_Y_RES_WIDTH + SCALE_INT_BITS){1'b0}}, topFracOffset}) >> SCALE_FRAC_BITS) & {{SCALE_BITS{1'b0}}, {OUTPUT_Y_RES_WIDTH{1'b1}}};
		end
		else
		begin
			getNextPlusOne <= 1;
		end
	end
end

reg			discardInput;
reg [DISCARD_CNT_WIDTH-1:0] discardCountReg;

reg [1:0]	writeState;

(* keep = "true" *)  reg [INPUT_X_RES_WIDTH-1:0] writeColCount;
(* keep = "true" *)  reg [INPUT_X_RES_WIDTH-1:0] writeColCount_dump;
reg			enableNextDin;
reg			forceRead;




localparam	WS_START = 0;
localparam	WS_DISCARD = 1;
localparam	WS_READ = 2;
localparam	WS_DONE = 3;


always @ (posedge clk)
begin
	if(rst)
	begin
		writeState <= WS_START;
		enableNextDin <= 0;
		discardInput <= 0;
		readyForRead <= 0;
		writeRowCount <= 0;
		writeColCount <= 0;
		writeColCount_dump <= 0;
		discardCountReg <= 0;
		forceRead <= 0;
	end
	else
	begin
		case (writeState)
		
			WS_START:
			begin
				discardCountReg <= inputDiscardCnt;
				if(inputDiscardCnt > 0)
				begin
					discardInput <= 1;
					enableNextDin <= 1;
					writeState <= WS_DISCARD;
				end
				else
				begin
					discardInput <= 0;
					enableNextDin <= 1;
					writeState <= WS_READ;
				end
				discardInput <= (inputDiscardCnt > 0) ? 1'b1 : 1'b0;
			end
			
			WS_DISCARD:
			begin
				if(dInValid)
				begin
					discardCountReg <= discardCountReg - 1;
					if((discardCountReg - 1) == 0)
					begin
						discardInput <= 0;
						writeState <= WS_READ;
					end
				end
			end
			
			WS_READ:
			begin


				if(dInValid & din_Enable)
				begin

					if(writeColCount == inputXRes)
					begin
						if((writeNextValidLine == writeRowCount + 1) ||
						    (writeNextValidLine == writeRowCount + 2) ||
							(writeNextPlusOne == writeRowCount + 1) ||
							(writeNextPlusTwo == writeRowCount + 2))
						begin 
							discardInput <= 0;
						end
						else
						begin
							discardInput <= 1;
						end
						

						if(writeRowCount[2])
							readyForRead <= 1;
						
						if(writeRowCount == inputYRes)
						begin
							writeState <= WS_DONE;
							enableNextDin <= 0;
							forceRead <= 1;
						end
						
						writeColCount <= 0;
						writeColCount_dump <= 0;
						writeRowCount <= writeRowCount + 1;
					end
					else if(fillCount == BUFFER_SIZE) begin
						writeColCount <= 0;
						writeColCount_dump <= 0;
					end
					else
					begin
						writeColCount <= writeColCount + 1;
						writeColCount_dump <= writeColCount_dump + 1;
					end
				end
			end
			
			WS_DONE:
			begin

			end
			
		endcase
	end
end




reg nextDin_Reg;
always@(posedge clk)
begin
	if(rst | start) begin
		nextDin_Reg <= 0;
	end
	else if((fillCount < BUFFER_SIZE) & enableNextDin) begin
		nextDin_Reg <= 1;
	end
	else begin
		nextDin_Reg <= 0;
	end
end

assign din_Enable = (fillCount < BUFFER_SIZE) & enableNextDin;



reg advanceWrite;
reg advanceWrite_delay;
always@(posedge clk)
begin
	if(rst | start) begin
		advanceWrite <= 0;
		advanceWrite_delay <= 0;
	end
	else if((writeColCount == inputXRes - 3) & (discardInput == 0) & dInValid & din_Enable) begin
		advanceWrite <= 1;
	end
	else if((writeColCount == inputXRes) & (discardInput == 0) & dInValid & din_Enable) begin
		advanceWrite_delay <= 1;
	end
	else begin
		advanceWrite <= 0;
		advanceWrite_delay <= 0;
	end
end
assign allDataWritten = (writeState == WS_DONE);

reg [5:0] First_Outputline_cnt;
reg First_Outputline;

always@(posedge clk or posedge rst)
begin
	if(rst) begin
		First_Outputline_cnt <= 0;
	end
	else if(outputLine_dump == 0) begin
		First_Outputline_cnt <= 0;
	end
	else begin
		First_Outputline_cnt <= First_Outputline_cnt + 1;
	end
end

always@(posedge clk or posedge rst)
begin
	if(rst) begin
		First_Outputline <= 0;
	end
	else if(outputLine_dump == 0) begin
		First_Outputline <= 0;
	end
	else if(First_Outputline_cnt == 6'd17) begin
		First_Outputline <= 1;
	end
end

reg Last_Outputline;
reg [5:0] Last_Outputline_cnt;

always@(posedge clk or posedge rst)
begin
	if(rst) begin
		Last_Outputline_cnt <= 0;
	end
	else if(Last_Outputline) begin
		if(Last_Outputline_cnt == 6'd31) begin
			Last_Outputline_cnt <= 0;
		end
		else if(outputLine_dump == outputYRes+1) begin
			Last_Outputline_cnt <= Last_Outputline_cnt + 1;
		end
	end
	else if(outputLine_dump == outputYRes) begin
		Last_Outputline_cnt <= Last_Outputline_cnt + 1;
	end
end

always@(posedge clk or posedge rst)
begin
	if(rst) begin
		Last_Outputline <= 0;
	end
	else if(Last_Outputline) begin
		if(Last_Outputline_cnt == 6'd31) begin
			Last_Outputline <= 0;
		end
	end
	else if(Last_Outputline_cnt == 6'd15) begin
		Last_Outputline <= 1;
	end
end

reg writeEnable_reg_0,writeEnable_reg_1;
reg [INPUT_X_RES_WIDTH-1:0] writeColCount_reg;
reg forceRead_reg;
reg forceRead_dump;
reg advanceWrite_reg0,advanceWrite_reg1;
reg	[13:0] advanceRead1_ram,advanceRead2_ram,advanceRead3_ram,advanceRead4_ram;
reg [DATA_WIDTH*CHANNELS-1:0]  dIn_reg_0,dIn_reg_1;
reg Last_Outputline_reg,First_Outputline_reg;

always@(posedge clk)
begin
	dIn_reg_0 <= dIn;
	dIn_reg_1 <= dIn_reg_0;
	writeEnable_reg_0 <= dInValid & din_Enable & enableNextDin & ~discardInput;
	writeEnable_reg_1 <= writeEnable_reg_0;
	writeColCount_reg <= writeColCount_dump;
	forceRead_reg <= forceRead;
	advanceWrite_reg0 <= advanceWrite;
	advanceWrite_reg1 <= advanceWrite_reg0;
	advanceRead1_ram <= {advanceRead1_ram[12:0],advanceRead1};
	advanceRead2_ram <= {advanceRead2_ram[12:0],advanceRead2};
	advanceRead3_ram <= {advanceRead3_ram[12:0],advanceRead3};
	advanceRead4_ram <= {advanceRead4_ram[12:0],advanceRead4};
	Last_Outputline_reg <= Last_Outputline;
	First_Outputline_reg <= First_Outputline;
end


cash_ram_rw #(
	.DATA_WIDTH( DATA_WIDTH*CHANNELS ),
	.ADDRESS_WIDTH( INPUT_X_RES_WIDTH ),
	.BUFFER_SIZE( BUFFER_SIZE )
) cash_ram_rw_inst (
	.clk( clk ),
	.rst( rst | start ),
	.advanceRead1( advanceRead1_ram[13] ),
	.advanceRead2( advanceRead2_ram[13] ),
	.advanceRead3( advanceRead3_ram[13] ),
	.advanceRead4( advanceRead4_ram[13] ),
	.readAddress( readAddress ),
	.forceRead( forceRead_reg ),

	.inputXRes(inputXRes),
	.advanceWrite( advanceWrite_reg1 ),
	.advanceWrite_delay (advanceWrite_delay),
	.writeData( dIn_reg_1 ),
	.writeAddress( writeColCount_reg ),
	.writeEnable( writeEnable_reg_1 ),
	.fillCount( fillCount ),
	.First_Outputline(First_Outputline_reg),
	.Last_Outputline(Last_Outputline_reg),
	.allDataWritten(allDataWritten),
	.readData00 (readData00),
	.readData01 (readData01),
	.readData02 (readData02),
	.readData03 (readData03),
	.readData10 (readData10),
	.readData11 (readData11),
	.readData12 (readData12),
	.readData13 (readData13),
	.readData20 (readData20),
	.readData21 (readData21),
	.readData22 (readData22),
	.readData23 (readData23),
	.readData30 (readData30),
	.readData31 (readData31),
	.readData32 (readData32),
	.readData33 (readData33)
);

endmodule