用fpga 实现图形算法的硬件加速设计 有源码,能直接用:武术最高境界--万源归宗,其实单片机,dsp ,cpu,都是有限状态机的特例,就数字电路来讲,只是其中的一部分,由此而来,统称的 类mcu,cpu等都有其特定的长处与短处,软件的东西可以硬件做,硬件的东西可以软件模拟,南拳北腿,内外兼修,方能登堂入室, 心中有招,刀剑棍棒皆可用,无论单片机,FPGA或是ARM DSP.
下面是Bresenham画线算法 分别用C语言和verilog 分别实现,这是我做的LCD控制器里硬件加速的一个模块,其它如画圆,字符,填充等可以以此类推
Bresenham画线算法 C程序如下:
int BresenhamLine ( int x1 , int y1 , int x2 , int y2 , int c)
{
int dx , dy ;
int tx , ty ;
int inc1 , inc2 ;
int d , iTag ;
int x , y ;
putpixel ( x1 , y1 , c ) ;
if ( x1 == x2 && y1 == y2 )
return 1 ;
iTag = 0 ;
dx = abs ( x2 - x1 );
dy = abs ( y2 - y1 );
if ( dx < dy )
{
iTag = 1 ;
Swap ( & x1 , & y1 );
Swap ( & x2 , & y2 );
Swap ( & dx , & dy );
}
tx = ( x2 - x1 ) > 0 ? 1 : -1 ;
ty = ( y2 - y1 ) > 0 ? 1 : -1 ;
x = x1 ;
y = y1 ;
inc1 = 2 * dy ;
inc2 = 2 * ( dy - dx );
d = inc1 - dx ;
while ( x != x2 )
{
if ( d < 0 )
 d += inc1 ;
else
{
 y += ty ;
 d += inc2 ;
}
if ( iTag )
 putpixel ( y , x , c ) ;
else
 putpixel ( x , y , c ) ;
x += tx ;
}
return 0;
}
Swap ( int * a , int * b )
{
int tmp ;
tmp = * a ;
* a = * b ;
* b = tmp ;
}
FPGA实现如下verilog HDL :
module line
(
  input[31 :0] page_address,
input  clk_i,
input  rstn_i,
input  load_i,
  input  ack_i,
input signed[15:0] sx,
input signed[15:0] sy,
input signed[15:0] ex,
input signed[15:0] ey,
input[23:0] f_color_i,
  input[23:0] b_color_i,
input[7 :0] data_i,
 
  output[23 :0] data_o,
  output[23 :0] addr_o,
  output  pset_start_o,
  output reg  line_over_o
);
reg[23: 0]addr;
reg[7 :0] rdata_i;
reg signed [15:0] x;
reg signed [15:0] y;
reg signed [15:0] xsign;
reg signed [15:0] ysign;
reg signed [16:0] delta_x;
reg signed [16:0] delta_y;
reg [16:0] rdelta_x;
reg [16:0] rdelta_y;
reg signed [16:0] i;
reg signed [16:0] e;
regchange;
reg [3:0]state;
reg pset_load;
wireover_o;
// Declare states
parameter S0 = 0, S1 = 1, S2 = 2, S3 = 3,S4 = 4, S5 = 5,S6 =6, S7=7,S40 = 8;
// Determine the next state synchronously, based on the
// current state and the input
always @ (posedge clk_i or negedge rstn_i) begin
if (! rstn_i)
 begin
 line_over_o <= 1'b0;
 rdata_i <= 8'd0;
 addr  <= 24'd0;
   xsign <= 16'd0;
   ysign <= 16'd0;
   delta_x <= 17'd0;
   delta_y <= 17'd0;
    i  <= 17'd0;
    e  <= 17'd0;
    
    pset_load <= 1'b0;
 state <= S0;
 end
else
 case (state)
  S0:
   if(load_i)
 begin
   line_over_o <= 1'b1;
  
  x   <= sx;
  y   <= sy;
  delta_x <= ex - sx;
  delta_y <= ey - sy;
  state <= S1;
 end
   else
  begin
  line_over_o <= 1'b0;
  state <= S0;
 end
  S1:
   begin
  if(delta_x < 0 ) begin rdelta_x <= (~ delta_x )+ 1'b1; xsign<= -1; end
  else     begin rdelta_x <=delta_x ;    xsign <= 1;end
  if(delta_y < 0 ) begin rdelta_y <= (~ delta_y )+ 1'b1; ysign <= -1; end
  else     begin rdelta_y <=delta_y ;    ysign <= 1;end
  
  state <= S2;
  
   end
  S2:
 begin
     if(rdelta_x < rdelta_y)
       begin
  delta_x <= rdelta_y;
  delta_y <= rdelta_x;
  change<= 1'b1;
  end
 else
   begin
  delta_x <= rdelta_x;
  delta_y <= rdelta_y;
  change<= 1'b0;
   end      
 state <= S3;
 end
  S3:
 begin
  e  <= ( delta_y * 2 ) - delta_x;
  i  <= 17'd1;
   rdata_i<= data_i;
  state  <= S4;
 end
  S4:
 begin
  addr  <=( ( y * 1024 ) + x ) + page_address[23 :0];
  pset_load <= 1'b1;
  state <= S40;
 end
  S40:
 begin
  if(over_o == 1'b1 )
   begin
   pset_load <= 1'b0;
   state <= S5; 
   end
   else
   state <= S40; 
 end
  S5:
 begin
   if( e >= 0 )
   begin
  if(change == 1'b1) x <= x + xsign;
  else     y <= y + ysign;
  e <= e + ( delta_x * 2);
  state <= S5;
   end 
  else
  state <= S6;
 end
 
  S6:
 begin
  if( change == 1'b1) y <= y + ysign;
  else      x <= x + xsign;
   e <= e + ( delta_y * 2);
  state <= S7;
 end
 
  S7:
 begin
  if(i < delta_x )
   begin
   i <= i + 1'b1;
   state <= S4;
   end
  else
   begin
   line_over_o <= 1'b0;
   state <= S0;
   end
 end
 
 endcase
end
endmodule