• 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 或者修改意见

  • 相关阅读:
    调用控制台程序函数 RunProcess
    url传递中文的解决方案(备忘)
    Microsoft.SharePoint.SPException 安全性验证无效——错误解决
    Windows SharePoint Services 虚拟服务器没被配置为与 ASP.NET 2.0.50727.42 一起使用解决办法
    automation服务器不能创建对象
    InfoPath窗体事件列表说明和示例使用
    ORA01113:文件n需要介质恢复 (转载)
    DevExpress 第三方控件汉化的全部代码和使用方法 (转载)
    爱的感觉(转载)
    关于Oracle 01122,01110,01207的错误和解决(转载)
  • 原文地址:https://www.cnblogs.com/sepeng/p/4045601.html
Copyright © 2020-2023  润新知