zoukankan      html  css  js  c++  java
  • 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)? 1'd0  : 1'd1 ;
     43   assign y_dir= (ys_in<ye_in)? 1'd0  : 1'd1 ;
     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     <= 10'd0 ; 
     58                     fini_flag <= 1'd0 ; 
     59             end 
     60     else if(in_en) //数据装载                        
     61             begin 
     62                     x_cnt     <= xs_in ; 
     63                     fini_flag <= 1'd0 ; 
     64             end 
     65     else if (x_cnt==xe_in) // 运算完毕
     66             begin 
     67                     //x_cnt     <= 10'd0 ; 
     68                     fini_flag <= 1'd1 ; 
     69             end 
     70     else                 //运算进行中
     71             begin 
     72                     x_cnt <= x_cnt + {{9{x_dir}},1'd1};
     73                     fini_flag <= 1'd0 ; 
     74             end 
     75 
     76 
     77 always @(posedge clock )
     78     if(!reset)
     79             begin 
     80                     y_ou    <= 9'd0 ;
     81                     x_ou    <= 10'd0 ; 
     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}},1'd1}; 
     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     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             
    65             $stop ; 
    66                 
    67     end 
    68 
    69 endmodule 
  • 相关阅读:
    Linux-C基础知识学习:C语言作业-将5个学生成绩保存在一个数组中,单独实现一个计算平均成绩的average函数, 在main函数中获取该函数返回的平均值,并打印。
    Linux-C基础知识学习:C语言作业-输入两个数,将两个数交换,按升序输出。
    C语言学习:结构体(笔记)--未完待续
    C语言学习:结构体(笔记)
    PHP之函数
    PHP之流程控制
    PHP之常量和变量
    PHP之数据类型
    PHP之标记风格和注释
    VMware虚拟机中各类文件作用详解
  • 原文地址:https://www.cnblogs.com/sepeng/p/4045593.html
Copyright © 2011-2022 走看看