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)? 1'd0  : 1'd1 ; //0: 递增方向
 49   assign y_dir= (ys_in<ye_in)? 1'd0  : 1'd1 ; //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) ? 1'd0:1'd1 ; //0:右手坐标系   1:左手坐标系
 58   
 59   
 60 reg signed [9:0] x_cnt ;        // 坐标计数 有符号运算
 61 //**********************************************************
 62 always @ (posedge clock )
 63     if(!reset)
 64             begin 
 65                     x_cnt     <= 10'd0 ; 
 66                     fini_flag <= 1'd0 ; 
 67             end 
 68     else if(cha_flag)  //旋转,将X与Y 颠倒过来
 69             begin 
 70                     if(in_en) 
 71                             begin 
 72                                     x_cnt     <= {1'b0,ys_in} ;
 73                                     fini_flag <= 1'd0 ;
 74                             end 
 75                     else if (x_cnt==ye_in) // 运算完毕
 76                                     fini_flag <= 1'd1 ; 
 77                     else             x_cnt <= x_cnt + {{9{y_dir}},1'd1};
 78             end 
 79     else   
 80             begin 
 81                     if(in_en) 
 82                             begin 
 83                                     x_cnt     <= xs_in ;
 84                                     fini_flag <= 1'd0 ;
 85                             end 
 86                     else if (x_cnt==xe_in) // 运算完毕
 87                                     fini_flag <= 1'd1 ; 
 88                     else             x_cnt <= x_cnt + {{9{x_dir}},1'd1};
 89             end 
 90 
 91 
 92 //算法的具体实现部分
 93 always @(posedge clock )
 94     if(!reset)
 95             begin 
 96                     y_ou    <= 9'd0 ;
 97                     x_ou    <= 10'd0 ; 
 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}},1'd1}; 
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}},1'd1}; 
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     begin
35             clock = 1'd0 ; reset =1'd0 ; in_en = 1'd0 ; 
36             xs_in = 10'd0 ; xe_in = 10'd0 ; 
37             ys_in = 9'd0  ; ye_in = 9'd0 ; 
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 或者修改意见

原文地址:https://www.cnblogs.com/sepeng/p/4045601.html