Chinaunix首页 | 论坛 | 博客
  • 博客访问: 336196
  • 博文数量: 47
  • 博客积分: 834
  • 博客等级: 军士长
  • 技术积分: 695
  • 用 户 组: 普通用户
  • 注册时间: 2011-12-07 09:38
文章分类
文章存档

2018年(1)

2015年(1)

2014年(2)

2013年(2)

2012年(23)

2011年(18)

分类: Verilog

2014-05-07 08:53:46

[plain] view plaincopy
  1. module hs0038_irq(clk_100k, rstn, irq, data, rd_suc)/*synthesis noprune*/;  
  2.     input clk_100k;     //T=0.01ms  
  3.     input rstn;  
  4.     input irq;        
  5.     output [31:0] data; //16位地址码,16位操作码  
  6.     output rd_suc;      //成功标志,维持0.01ms的高电平  
  7.       
  8.     parameter T9ms=10'd899;  
  9.     parameter T4ms5=10'd449;  
  10.     parameter Tms84=7'd83;      //0.84ms  
  11.     parameter error=8'd19;      //0.2ms  
  12.   
  13.     reg [1:0] irq_tmp;  
  14.     wire irq_up;  
  15.     wire irq_down;  
  16.       
  17.     //捕捉红外信号的上下沿  
  18.     always @(negedge clk_100k or negedge rstn)  
  19.     begin  
  20.         if (!rstn)  
  21.         begin  
  22.             irq_tmp <= 2'd0;  
  23.         end  
  24.         else  
  25.         begin  
  26.             irq_tmp[0] <= irq;  
  27.             irq_tmp[1] <= irq_tmp[0];  
  28.         end  
  29.     end  
  30.   
  31.     assign irq_up = ~irq_tmp[1] & irq_tmp[0];   //上升沿为1  
  32.     assign irq_down = irq_tmp[1] & ~irq_tmp[0]; //下降沿为1  
  33.   
  34.   
  35. /**********************************************************/  
  36.     reg irq_suc;  
  37.     reg [31:0] irq_buf;//提取出的32位数据,地址码,其反码,操作码,其反码  
  38.     reg [9:0] irq_cnt;  
  39.     reg [3:0] step; //状态机,解析红外的处理状态  
  40.     reg [7:0] i;    //引导码后的数据位计数  
  41.       
  42.     //上下沿的计数  
  43.     always @(negedge clk_100k or negedge rstn)  
  44.     begin  
  45.         if (!rstn)  
  46.         begin  
  47.             irq_cnt <= 10'd0;  
  48.             step <= 4'd0;  
  49.             irq_buf <= 32'd0;  
  50.             i <= 8'd0;  
  51.             irq_suc <= 1'b0;  
  52.         end  
  53.         else  
  54.         begin  
  55.             case (step)  
  56.                 4'd0 :  //开始等待捕捉引导码的上升沿  
  57.                     begin     
  58.                         if (irq_up) //第一次上升沿,过滤掉第一个上升沿  
  59.                         begin  
  60.                             step <= step + 1'd1;  
  61.                             irq_cnt <= 10'd0;  
  62.                         end  
  63.                     end  
  64.                           
  65.                 4'd1 :      //引导码上升沿后开始计数  
  66.                     begin  
  67.                         irq_cnt <= irq_cnt + 1'd1;  
  68.                         if (irq_down)   //下降沿截止计数  
  69.                             step <= step + 4'd1;  
  70.                     end  
  71.   
  72.                 4'd2 :      //判断引导码的高电平合法性  
  73.                     begin  
  74.                         if (irq_cnt <= (T9ms+error) && irq_cnt >= (T9ms-error))//引导码的9ms高电平  
  75.                         begin  
  76.                             step <= step + 4'd1;  
  77.                             irq_cnt <= 10'd0;  
  78.                         end  
  79.                         else  
  80.                             step <= 4'd0;  
  81.                     end  
  82.   
  83.                 4'd3 :      //引导码的下降沿开始计数至上升沿  
  84.                     begin  
  85.                         irq_cnt <= irq_cnt + 1'd1;  
  86.                         if (irq_up)  
  87.                             step <= step + 4'd1;  
  88.                     end  
  89.   
  90.                 4'd4 :      //判断引导码的低电平4.5ms  
  91.                     begin  
  92.                         if (irq_cnt <= (T4ms5+error) && irq_cnt >= (T4ms5-error))//引导码确认完成  
  93.                         begin  
  94.                             step <= step + 4'd1;  
  95.                             i <= 8'd0;  
  96.                         end  
  97.                         else  
  98.                             step <= 4'd0;  
  99.                     end  
  100.   
  101.                 4'd5 :      //引导码正确后开始提取数据  
  102.                     begin  
  103.                         if (irq_down)  
  104.                         begin  
  105.                             step <= step + 4'd1;  
  106.                             irq_cnt <= 10'd0;  
  107.                         end  
  108.                     end  
  109.   
  110.                 4'd6 :      //提取每个下降沿后0.84ms时的IRQ状态,为高是表示数据0,为低时表示数据1  
  111.                     begin  
  112.                         irq_cnt <= irq_cnt + 1'd1;  
  113.                         if (irq_cnt == Tms84)   //捕捉数据部分每个下降沿后0.84ms的值  
  114.                         begin  
  115.                             irq_buf[i] <= ~irq;  
  116.                             i <= i + 8'd1;  
  117.                             if (i==8'd31)   //所有数据提取完  
  118.                                 step <= step + 4'd1;  
  119.                             else            //捕捉下个位的下降沿  
  120.                                 step <= 4'd5;  
  121.                         end  
  122.                     end  
  123.   
  124.                 4'd7 :      //提取完数据发送成功标志  
  125.                     begin  
  126.                         step <= step + 4'd1;  
  127.                         irq_suc <= 1'b1;  
  128.                     end  
  129.   
  130.                 4'd8 :  
  131.                     begin  
  132.                         irq_suc <= 1'b0;  
  133.                         step <= 4'd0;  
  134.                     end  
  135.   
  136.                 default : ;  
  137.             endcase  
  138.         end  
  139.     end  
  140.   
  141.     assign rd_suc = irq_suc;  
  142.     assign data = irq_buf;  
  143.       
  144. endmodule  
  145.   
  146.     有必要说明一下,module后面的注释语句/*synthesis noprune*/是避免综合时候系统优化掉一些变量,导致在仿真里面看不到现象。  
[plain] view plaincopy
  1. 我自己调试的时候因为红外信号进来的没有取反,所以引导码是9ms低电平,4.5ms高电平,自己没注意导致调试费了一些时间.....需要在上层把红外信号取反之后送进来,这样就能正常工作了,注释很详细,不多解释了...  
[plain] view plaincopy
  1. 以后我会抽时间把自己调试的小功能程序分享出来,留作备用以及纪念。
阅读(3019) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~