首页 > 代码库 > bresenham算法的FPGA的实现1

bresenham算法的FPGA的实现1

接着上一篇的 计算实现给出屏幕上任意两个点,求出这两个点之间直线上的所有的点。http://www.cnblogs.com/sepeng/p/4042464.html 这种直接算法的确是被鄙视了

强大的度娘告诉我们还有专用的算法叫bresenham算法。调用我大脑中所有的数学知识残留借用网上资料,费尽了吃奶的力气才把这个算法推导了一遍,高手们不要笑话

            

            

后来觉得这个时候讨论的是 0<k<1.那么把pi换一换就是 -1<k<0.仿真后发现自己又脑残了一次,对算法知之甚少,组合了好几次都没有组合成功,最后不得不把-1<k<0的算法拿出来讨论

        

这次才知道-1<k<0的时候 pi,xi 长啥样子,我的大脑还是猜不出来的,老老实实的推导算法吧。

算法推导出来了,这下好了就开始写FPGA的实现了

  1 /*  2 date:2014/10/22  3 version : QuartusII + de1-soc cyclone V   4 designer : pengxiaoen   5 funtion :  实现bresenham 算法在象限对直线的计算   6             |k| <1 任意方向都满足  7 */  8   9 module bresenham ( 10             clock , 11             reset , 12             xs_in ,        //输入的X 点的起始坐标 13             ys_in ,        // 输入的Y 点的起始坐标  14             xe_in ,        //输入X点的终止坐标 15             ye_in ,        //输入Y 点的终止坐标 16             in_en ,        //当前输入信号有效标志    1:有效    0:无效 17              18             x_ou,         //输出的X 点的坐标  19             y_ou,         // 输出的Y 点的坐标   20             fini_flag     //计算完成标志位 21             ); 22   input         clock ,reset  ;  23   input         in_en ;  24   input [9:0]     xs_in  ,xe_in ; 25   input [8:0]     ys_in  ,ye_in ;  26    27   output reg [9:0]    x_ou ;  28   output reg [8:0]    y_ou ;  29   output reg        fini_flag ;  30  31   wire          [15:0] dx  ;     // X方向上的变化量 32   wire          [15:0] dy  ;     //Y方向上的变化量  33   reg  signed     [15:0] pi ; 34   wire                   x_dir ;  35   wire                 y_dir ;  36     37   wire       [9:0] Xmin ;  38   wire       [9:0] Xmax ;  39   wire       [8:0] Ymin ;  40   wire       [8:0] Ymax ;  41 // 42   assign x_dir= (xs_in<xe_in)? 1d0  : 1d1 ; 43   assign y_dir= (ys_in<ye_in)? 1d0  : 1d1 ; 44   assign Xmin = (xs_in<xe_in)? xs_in : xe_in ; 45   assign Xmax = (xs_in<xe_in)? xe_in : xs_in ; 46   assign Ymin = (ys_in<ye_in)? ys_in : ye_in ; 47   assign Ymax = (ys_in<ye_in)? ye_in : ys_in ;   48  49   assign dx = Xmax-Xmin;  //得出X方向上的差值 50   assign dy = Ymax-Ymin;  //得出Y方向上的差值 51    52 reg signed [9:0] x_cnt ;        // X 坐标计数 有符号运算 53 //********************************************************** 54 always @ (posedge clock ) 55     if(!reset) 56             begin  57                     x_cnt     <= 10d0 ;  58                     fini_flag <= 1d0 ;  59             end  60     else if(in_en) //数据装载                         61             begin  62                     x_cnt     <= xs_in ;  63                     fini_flag <= 1d0 ;  64             end  65     else if (x_cnt==xe_in) // 运算完毕 66             begin  67                     //x_cnt     <= 10‘d0 ;  68                     fini_flag <= 1d1 ;  69             end  70     else                 //运算进行中 71             begin  72                     x_cnt <= x_cnt + {{9{x_dir}},1d1}; 73                     fini_flag <= 1d0 ;  74             end  75  76  77 always @(posedge clock ) 78     if(!reset) 79             begin  80                     y_ou    <= 9d0 ; 81                     x_ou    <= 10d0 ;  82             end  83     else if ((!fini_flag) && (!in_en)) //运算标志正在运算,并且装载数据完成 84             begin  85                     if(pi[15])  86                             begin  87                                     pi        <= pi+(dy<<1) ;  88                                     x_ou    <= x_cnt ; 89                             end  90                     else  91                             begin  92                                     pi        <= pi + (dy<<1) - (dx<<1) ; 93                                     y_ou    <= y_ou + {{8{y_dir}},1d1};  94                                     x_ou    <= x_cnt ; 95                             end  96             end  97     else  98             begin  99                     pi        <=  (dy<<1)-dx ; 100                     y_ou    <=  ys_in ; 101                     x_ou    <=  xs_in ;102             end 103 104 endmodule 


附上测试代码

 1 `timescale 1ns/1ps 2  3  4 module bresenham_tb ; 5  6 reg clock ,reset ;  7 reg in_en ; 8 reg [9:0] xs_in ,xe_in ; 9 reg [8:0] ys_in ,ye_in ; 10 11 wire [9:0] x_ou ; 12 wire [8:0] y_ou ; 13 wire       fini_flag ;14 15 16 bresenham U1_bresenham(17             .clock (clock),18             .reset (reset),19             .xs_in (xs_in),        20             .ys_in (ys_in),         21             .xe_in (xe_in),        22             .ye_in (ye_in),        23             .in_en (in_en),       24             25             .x_ou (x_ou),        26             .y_ou (y_ou),        27             .fini_flag (fini_flag)    28             );29 30 31 always  #10 clock = ~clock ; 32 33 initial 34     begin35             clock = 1d0 ; reset =1d0 ; in_en = 1d0 ; 36             xs_in = 10d0 ; xe_in = 10d0 ; 37             ys_in = 9d0  ; ye_in = 9d0 ; 38                 39             #40 reset = 1 ; 40                 in_en = 1 ; 41                 xs_in = 100 ; xe_in = 200 ; 42                 ys_in = 100 ; ye_in = 150 ; 43             #80 in_en = 0 ; 44             #3000 ;   //  k = 1/2 验证 正方向45             46                 in_en = 1 ; 47                 xs_in = 200 ; xe_in =  100; 48                 ys_in = 150 ; ye_in =  100; 49             #80 in_en = 0 ; 50             #3000 ;   //  k = 1/2 验证 反方向51 52             in_en = 1 ; 53             xs_in = 100 ; xe_in= 200 ; 54             ys_in = 100 ; ye_in= 50 ; 55             #80 in_en = 0 ;   //  k = -1/2 验证 正方向56             #3000  57             58             in_en = 1 ; 59             xs_in = 200 ; xe_in=  100; 60             ys_in = 50 ;  ye_in=  100 ; 61             #80 in_en = 0 ;   //  k = -1/2 验证 反方向62             #3000  63             64             65             $stop ; 66                 67     end 68 69 endmodule 

 

bresenham算法的FPGA的实现1