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

bresenham算法的FPGA的实现2

 

 

  在上一篇里http://www.cnblogs.com/sepeng/p/4045593.html 《bresenham算法的FPGA的实现1》已经做了一个整体框架的布局,但是那个程序只是支持|k|<1.要想全屏支持,就还需要对这个程序做修改,觉得自己的修改方式很繁琐,期望大家的指点,有高质量的code出现。算法的原理部分在上一篇中已经给出

  1 /*  2 date:2014/10/23  3 version : QuartusII + de1-soc cyclone V   4 designer : pengxiaoen   5 funtion :  实现bresenham 算法在象限对直线的计算   6 说明:(1) in_en 至少是2个clock才能保证前面模块数据装载的成功  7   8   9  10  11              12 */ 13  14 module bresenham ( 15             clock , 16             reset , 17             xs_in ,        //输入的X 点的起始坐标 18             ys_in ,        // 输入的Y 点的起始坐标  19             xe_in ,        //输入X点的终止坐标 20             ye_in ,        //输入Y 点的终止坐标 21             in_en ,        //当前输入信号有效标志    1:有效    0:无效 22              23             x_ou,         //输出的X 点的坐标  24             y_ou,         // 输出的Y 点的坐标   25             fini_flag     //计算完成标志位 26             ); 27   input         clock ,reset  ;  28   input         in_en ;  29   input [9:0]     xs_in  ,xe_in ; 30   input [8:0]     ys_in  ,ye_in ;  31    32   output reg [9:0]    x_ou ;  33   output reg [8:0]    y_ou ;  34   output reg        fini_flag ;  35  36   wire          [15:0] dx  ;     // X方向上的变化量 37   wire          [15:0] dy  ;     //Y方向上的变化量  38   reg  signed     [15:0] pi ;      //算法pi 39  40   wire       [9:0] Xmin ;  41   wire       [9:0] Xmax ;  42   wire       [8:0] Ymin ;  43   wire       [8:0] Ymax ;  44   wire              x_dir ;  //X走向标志 45   wire            y_dir ;   //Y走向标志 46   wire            cha_flag ; //coordinate change flag    47 // 48   assign x_dir= (xs_in<xe_in)? 1d0  : 1d1 ; //0: 递增方向 49   assign y_dir= (ys_in<ye_in)? 1d0  : 1d1 ; //1: 递减方向 50   assign Xmin = (xs_in<xe_in)? xs_in : xe_in ; 51   assign Xmax = (xs_in<xe_in)? xe_in : xs_in ; 52   assign Ymin = (ys_in<ye_in)? ys_in : ye_in ; 53   assign Ymax = (ys_in<ye_in)? ye_in : ys_in ;   54  55   assign dx = Xmax-Xmin;  //得出X方向上的差值 56   assign dy = Ymax-Ymin;  //得出Y方向上的差值 57   assign cha_flag = (dx>dy) ? 1d0:1d1 ; //0:右手坐标系   1:左手坐标系 58    59    60 reg signed [9:0] x_cnt ;        // 坐标计数 有符号运算 61 //********************************************************** 62 always @ (posedge clock ) 63     if(!reset) 64             begin  65                     x_cnt     <= 10d0 ;  66                     fini_flag <= 1d0 ;  67             end  68     else if(cha_flag)  //旋转,将X与Y 颠倒过来 69             begin  70                     if(in_en)  71                             begin  72                                     x_cnt     <= {1b0,ys_in} ; 73                                     fini_flag <= 1d0 ; 74                             end  75                     else if (x_cnt==ye_in) // 运算完毕 76                                     fini_flag <= 1d1 ;  77                     else             x_cnt <= x_cnt + {{9{y_dir}},1d1}; 78             end  79     else    80             begin  81                     if(in_en)  82                             begin  83                                     x_cnt     <= xs_in ; 84                                     fini_flag <= 1d0 ; 85                             end  86                     else if (x_cnt==xe_in) // 运算完毕 87                                     fini_flag <= 1d1 ;  88                     else             x_cnt <= x_cnt + {{9{x_dir}},1d1}; 89             end  90  91  92 //算法的具体实现部分 93 always @(posedge clock ) 94     if(!reset) 95             begin  96                     y_ou    <= 9d0 ; 97                     x_ou    <= 10d0 ;  98             end  99     else if ((!fini_flag) && (!in_en)) //运算标志正在运算,并且装载数据完成100             begin 101                     if(pi[15]) 102                             begin 103                                     if(cha_flag) //坐标旋转,X,Y 颠倒104                                             begin 105                                                     pi        <= pi+(dx<<1) ; 106                                                     y_ou    <= x_cnt[8:0] ;107                                             end 108                                     else 109                                             begin 110                                                     pi        <= pi+(dy<<1) ; 111                                                     x_ou    <= x_cnt ;112                                             end 113 114                             end 115                     else 116                             begin 117                                     if(cha_flag)  //坐标旋转,X,Y 颠倒118                                             begin 119                                                     pi        <= pi + (dx<<1) - (dy<<1) ;120                                                     x_ou    <= x_ou + {{8{x_dir}},1d1}; 121                                                     y_ou    <= x_cnt[8:0] ;122                                             end 123                                     else 124                                             begin 125                                                     pi        <= pi + (dy<<1) - (dx<<1) ;126                                                     y_ou    <= y_ou + {{8{y_dir}},1d1}; 127                                                     x_ou    <= x_cnt ;128                                             end 129 130                             end 131             end 132     else 133             begin 134                     if(cha_flag)  pi<= (dx<<1)-dy ;  //坐标旋转,X,Y 颠倒135                     else          pi<= (dy<<1)-dx ; 136                     y_ou    <=  ys_in ; 137                     x_ou    <=  xs_in ;138             end 139 140 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             in_en = 1 ; 65             xs_in = 100 ; xe_in= 150 ; 66             ys_in = 100 ; ye_in= 200 ; 67             #80 in_en = 0 ;   //  k = 2 验证 68             #3000  69             70             in_en = 1 ; 71             xs_in = 100 ; xe_in= 150 ; 72             ys_in = 200 ; ye_in= 100 ; 73             #80 in_en = 0 ;   //  k = -2 验证74             #3000  75             $stop ; 76                 77     end 78 79 endmodule 

欢迎大家提出bug 或者修改意见

 

bresenham算法的FPGA的实现2