1. 摘要
基于前文推导的正余弦数值,即可进行旋转公式的计算。图像旋转的本质是实现坐标变换,核心在于两个基本公式。以下按照实际编写思路记录关键设计点。
2. 图像旋转代码设计思路
2.1 旋转后的图像尺寸
图像旋转后像素位置发生变化,虽然总面积不变,但显示范围需扩大以容纳旋转后的对角线长度。通过勾股定理计算原始图像对角线,作为旋转后图像的最大显示范围。
reg [12:0] row_size ;
reg [12:0] col_size ;
assign Pixel_X = row_size ;
assign Pixel_Y = col_size ;
wire [31:0] cosout_abs = (cosout[31]) ? -cosout : cosout;
wire [31:0] sinout_abs = (sinout[31]) ? -sinout : sinout;
always @(posedge clk_i, negedge rstn_i) begin
if (!rstn_i) begin
row_size <= 'd0 ;
col_size <= 'd0 ;
end else begin
// h --> row
// w --> col
row_size <= (ROW*cosout_abs + COL*sinout_abs) >>14 ;
col_size <= (COL*cosout_abs + ROW*sinout_abs) >>14 ;
end
end
2.2 旋转后图像的有效位置
有效区域可自由设定,通常以屏幕中心为基准。假设使用标准 LCD 接口,需根据行场同步信号计算数据请求窗口。以屏幕中点为旋转中心,结合流水线延迟调整偏移量,确保时序对齐。
//parameter define localparam H_SYNC = 11'd41 , //行同步
H_BACK = 11'd2 , //行时序后沿
H_LEFT = 11'd0 , //行时序左边框
H_VALID = 11'd480 , //行有效数据
H_RIGHT = 11'd0 , //行时序右边框
H_FRONT = 11'd2 , //行时序前沿
H_TOTAL = 11'd525 ; //行扫描周期
localparam V_SYNC = 11'd10 , //场同步
V_BACK = 11'd2 , //场时序后沿
V_TOP = 11'd0 , //场时序左边框
V_VALID = 11'd272 , //场有效数据
V_BOTTOM = 11'd0 , //场时序右边框
V_FRONT = 11'd2 , //场时序前沿
V_TOTAL = 11'd286 ; //场扫描周期
//cnt_h:行扫描计数器
//cnt_v:场扫描计数器
//data_req:数据请求信号
wire data_req = (((cnt_h >= (((H_VALID - Pixel_X)>>1) + H_SYNC + H_BACK - 'd5)) && (cnt_h < (((H_VALID - Pixel_X)>>1) + Pixel_X + H_SYNC + H_BACK - 'd5))) &&((cnt_v >= ((V_VALID - Pixel_Y)>>1) + V_SYNC + V_BACK - 'd5) && ((cnt_v < (((V_VALID - Pixel_Y)>>1) + Pixel_Y + V_SYNC + V_BACK - 'd5)))));
2.3 第一级流水线
在图像有效信号期间进行行场计数,这是基础操作。同时生成旋转使能信号和结束标志。
always @(posedge clk_i, negedge rstn_i) begin
if (!rstn_i) r_rotate_valid <= 1'b0 ;
else r_rotate_valid <= data_req ;
end
always @(posedge clk_i, negedge rstn_i) begin
if (!rstn_i) r_rotate_end <= 'd0 ;
else if (r_rotate_valid && (vcnt == row_abs - 1) && (hcnt == col_abs - 2)) r_rotate_end <= 'd1 ;
else r_rotate_end <= 'd0 ;
end
always @(posedge clk_i, negedge rstn_i) begin
if (!rstn_i) hcnt <= 'd0 ;
else if (r_rotate_valid && (r_rotate_end || (hcnt == col_abs - 1))) hcnt <= 'd0 ;
else if (r_rotate_valid) hcnt <= hcnt + 'd1 ;
end
always @(posedge clk_i, negedge rstn_i) begin
if (!rstn_i) vcnt <= 'd0 ;
else if (r_rotate_valid && r_rotate_end) vcnt <= 'd0 ;
else if (r_rotate_valid && (hcnt == col_abs - 1)) vcnt <= vcnt + 'd1 ;
end
2.4 第二级流水
开始计算图像旋转公式。以中心点为起始坐标 (0,0),覆盖四个象限。组合公式并右移 14 位处理定点数精度。

