// interpolation.v
`include "config.v" `define STATE_WIDTH 4
//插值运算
module interpolation(iclk, //系统时钟
irst, //复位信号
ix, //图片像素的X坐标,是一个定点数,
//高`DECIMAL_X_POSTION_WIDTH-1:`DECIMAL_PRECISION_POSTION位为整数部分
//低`DECIMAL_PRECISION_POSTION-1:0位为小数部分
iy, //图片像素的Y坐标,是一个定点数,
//高`DECIMAL_Y_POSTION_WIDTH-1:`DECIMAL_PRECISION_POSTION位为整数部分
//低`DECIMAL_PRECISION_POSTION-1:0位为小数部分
isrc_first_addr, //存储图像数据缓冲区的首地址
isrc_dat, //存储图像数据缓冲区的数据线
osrc_addr, //存储图像数据缓冲区的地址线
osrc_rd, //存储图像数据缓冲区的读命令
isrc_busy, //存储图像数据缓冲区的读数据是否有效标志
odir_dat, //经过计算得到的插值数据
obusy //输出的插值数据是否有效
);//idir_first_addr,,odir_addr,odir_wr
//,v_cur_state);
input iclk,irst; input [`DECIMAL_X_POSTION_WIDTH-1:0] ix; input [`DECIMAL_Y_POSTION_WIDTH-1:0] iy; input [`RAM_ADDR_WIDTH-1:0] isrc_first_addr;//,idir_first_addr;
input [`IMG_COLOR_WIDTH-1:0] isrc_dat; input isrc_busy; output [`RAM_ADDR_WIDTH-1:0] osrc_addr;//,odir_addr;
output osrc_rd; output [`IMG_COLOR_WIDTH-1:0] odir_dat; //output odir_wr;
output obusy;
//output [`STATE_WIDTH-1:0] v_cur_state;
reg [`RAM_ADDR_WIDTH-1:0] osrc_addr,odir_addr; reg [`IMG_COLOR_WIDTH-1:0] odir_dat;//,dat_buf;
reg [1:0] dir_dat_ex;
reg [`STATE_WIDTH-1:0] cur_state,nest_state,willdo; reg osrc_rd,is_bound,obusy;//,odir_wr
parameter st_begin=`STATE_WIDTH'd0,st_check_bound=`STATE_WIDTH'd1,st_loading_data=`STATE_WIDTH'd2, st_loaded_data=`STATE_WIDTH'd3,st_idle=`STATE_WIDTH'd4,st_output_result=`STATE_WIDTH'd5, st_load_x0_y0=`STATE_WIDTH'd6,st_load_x1_y0=`STATE_WIDTH'd7,st_load_x1_y1=`STATE_WIDTH'd8, st_load_x0_y1=`STATE_WIDTH'd9,st_output_result2=`STATE_WIDTH'd10;
//assign v_cur_state=cur_state; always @(posedge iclk or negedge irst) begin if(!irst) begin cur_state<=st_begin; end else begin cur_state<=nest_state; end end
always @(cur_state or isrc_busy or is_bound) begin case(cur_state) st_begin: nest_state=st_load_x0_y0; st_load_x0_y0: begin nest_state=st_loading_data; willdo=st_check_bound; end st_load_x1_y0: begin nest_state=st_loading_data; willdo=st_load_x1_y1; end st_load_x1_y1: begin nest_state=st_loading_data; willdo=st_load_x0_y1; end st_load_x0_y1: begin nest_state=st_loading_data; willdo=st_output_result2; end st_check_bound: begin if(is_bound) nest_state=st_output_result; else begin nest_state=st_load_x1_y0; end end st_loading_data: if(isrc_busy==1'b0)nest_state=st_loaded_data; st_loaded_data: nest_state=willdo; st_output_result: nest_state=st_idle; st_output_result2: nest_state=st_idle; default:; endcase end
always @(posedge iclk or negedge irst) begin if(!irst) begin obusy<=1'b1; is_bound<=0; dir_dat_ex<=0; odir_dat<=0; end else case(nest_state) st_load_x0_y0: begin osrc_addr<=isrc_first_addr +(iy[`DECIMAL_Y_POSTION_WIDTH-1:`DECIMAL_PRECISION_POSTION] *`IMG_WIDTH +ix[`DECIMAL_X_POSTION_WIDTH-1:`DECIMAL_PRECISION_POSTION] )<<2;// *`IMG_DATA_WASTE_BYTES;IMG_DATA_WASTE_BYTES=4 end st_load_x1_y0: begin osrc_addr<=osrc_addr+`IMG_DATA_WASTE_BYTES; end st_load_x1_y1: begin osrc_addr<=osrc_addr+`IMG_WIDTH*`IMG_DATA_WASTE_BYTES; end st_load_x0_y1: begin osrc_addr<=osrc_addr-`IMG_DATA_WASTE_BYTES; end st_check_bound: begin if(ix[`DECIMAL_PRECISION_POSTION-1:0]==0 &&(iy[`DECIMAL_PRECISION_POSTION-1:0]==0) &&(ix[`DECIMAL_X_POSTION_WIDTH-1:`DECIMAL_PRECISION_POSTION]==0 || iy[`DECIMAL_Y_POSTION_WIDTH-1:`DECIMAL_PRECISION_POSTION]==0 || ix[`DECIMAL_X_POSTION_WIDTH-1:`DECIMAL_PRECISION_POSTION]==(`IMG_WIDTH-1) || iy[`DECIMAL_Y_POSTION_WIDTH-1:`DECIMAL_PRECISION_POSTION]==(`IMG_HEIGHT-1) ) ) is_bound<=1'b1; end st_loading_data: osrc_rd<=1'b1; st_loaded_data: begin {dir_dat_ex,odir_dat}<=isrc_dat+{dir_dat_ex,odir_dat}; osrc_rd<=1'b0; end st_output_result: begin obusy<=1'b0; end st_output_result2: begin obusy<=1'b0; odir_dat<={dir_dat_ex,odir_dat[`IMG_COLOR_WIDTH-1:2]}; end default:;//st_idle,do nothing
endcase end
endmodule
`undef STATE_WIDTH
|