搜索
bottom↓
回复: 4

fpga4fun uart 代码仿真 求解

[复制链接]

出0入0汤圆

发表于 2013-12-10 22:32:00 | 显示全部楼层 |阅读模式
fpga4fun 是一个很不错的关于FPGA 的外国网站 里面提供了很多实例,不过最近好像登录不上了!

其中有一个关于 uart 的实例很经典,当中关于波特率的一段尤其经典,可以不是很懂。

所以今天想仿真一下 ,看看这段经典代码的是如何实现的.....可惜捣鼓了很久都没仿出波形来,求各为大牛帮帮忙看看什么原因~~~~


这是fpga4fun uart 接收 的代码
  1. // RS-232 RX module
  2. // (c) fpga4fun.com KNJN LLC - 2003, 2004, 2005, 2006

  3. module async_receiver(clk, RxD, RxD_data_ready, RxD_data, RxD_endofpacket, RxD_idle);
  4. input clk, RxD;
  5. output RxD_data_ready;  // onc clock pulse when RxD_data is valid
  6. output [7:0] RxD_data;

  7. parameter ClkFrequency = 50000000; // 25MHz
  8. parameter Baud = 9600;

  9. // We also detect if a gap occurs in the received stream of characters
  10. // That can be useful if multiple characters are sent in burst
  11. //  so that multiple characters can be treated as a "packet"
  12. output RxD_endofpacket;  // one clock pulse, when no more data is received (RxD_idle is going high)
  13. output RxD_idle;  // no data is being received

  14. // Baud generator (we use 8 times oversampling)
  15. parameter Baud8 = Baud*8;
  16. parameter Baud8GeneratorAccWidth = 16;
  17. wire [Baud8GeneratorAccWidth:0] Baud8GeneratorInc = ((Baud8<<(Baud8GeneratorAccWidth-7))+(ClkFrequency>>8))/(ClkFrequency>>7);
  18. reg [Baud8GeneratorAccWidth:0] Baud8GeneratorAcc;
  19. always @(posedge clk) Baud8GeneratorAcc <= Baud8GeneratorAcc[Baud8GeneratorAccWidth-1:0] + Baud8GeneratorInc;
  20. wire Baud8Tick = Baud8GeneratorAcc[Baud8GeneratorAccWidth];

  21. ////////////////////////////
  22. reg [1:0] RxD_sync_inv;
  23. always @(posedge clk) if(Baud8Tick) RxD_sync_inv <= {RxD_sync_inv[0], ~RxD};
  24. // we invert RxD, so that the idle becomes "0", to prevent a phantom character to be received at startup

  25. reg [1:0] RxD_cnt_inv;
  26. reg RxD_bit_inv;

  27. always @(posedge clk)
  28. if(Baud8Tick)
  29. begin
  30.         if( RxD_sync_inv[1] && RxD_cnt_inv!=2'b11) RxD_cnt_inv <= RxD_cnt_inv + 2'h1;
  31.         else
  32.         if(~RxD_sync_inv[1] && RxD_cnt_inv!=2'b00) RxD_cnt_inv <= RxD_cnt_inv - 2'h1;

  33.         if(RxD_cnt_inv==2'b00) RxD_bit_inv <= 1'b0;
  34.         else
  35.         if(RxD_cnt_inv==2'b11) RxD_bit_inv <= 1'b1;
  36. end

  37. reg [3:0] state;
  38. reg [3:0] bit_spacing;

  39. // "next_bit" controls when the data sampling occurs
  40. // depending on how noisy the RxD is, different values might work better
  41. // with a clean connection, values from 8 to 11 work
  42. wire next_bit = (bit_spacing==4'd10);

  43. always @(posedge clk)
  44. if(state==0)
  45.         bit_spacing <= 4'b0000;
  46. else
  47. if(Baud8Tick)
  48.         bit_spacing <= {bit_spacing[2:0] + 4'b0001} | {bit_spacing[3], 3'b000};

  49. always @(posedge clk)
  50. if(Baud8Tick)
  51. case(state)
  52.         4'b0000: if(RxD_bit_inv) state <= 4'b1000;  // start bit found?
  53.         4'b1000: if(next_bit) state <= 4'b1001;  // bit 0
  54.         4'b1001: if(next_bit) state <= 4'b1010;  // bit 1
  55.         4'b1010: if(next_bit) state <= 4'b1011;  // bit 2
  56.         4'b1011: if(next_bit) state <= 4'b1100;  // bit 3
  57.         4'b1100: if(next_bit) state <= 4'b1101;  // bit 4
  58.         4'b1101: if(next_bit) state <= 4'b1110;  // bit 5
  59.         4'b1110: if(next_bit) state <= 4'b1111;  // bit 6
  60.         4'b1111: if(next_bit) state <= 4'b0001;  // bit 7
  61.         4'b0001: if(next_bit) state <= 4'b0000;  // stop bit
  62.         default: state <= 4'b0000;
  63. endcase

  64. reg [7:0] RxD_data;
  65. always @(posedge clk)
  66. if(Baud8Tick && next_bit && state[3]) RxD_data <= {~RxD_bit_inv, RxD_data[7:1]};

  67. reg RxD_data_ready, RxD_data_error;
  68. always @(posedge clk)
  69. begin
  70.         RxD_data_ready <= (Baud8Tick && next_bit && state==4'b0001 && ~RxD_bit_inv);  // ready only if the stop bit is received
  71.         RxD_data_error <= (Baud8Tick && next_bit && state==4'b0001 &&  RxD_bit_inv);  // error if the stop bit is not received
  72. end

  73. reg [4:0] gap_count;
  74. always @(posedge clk) if (state!=0) gap_count<=5'h00; else if(Baud8Tick & ~gap_count[4]) gap_count <= gap_count + 5'h01;
  75. assign RxD_idle = gap_count[4];
  76. reg RxD_endofpacket; always @(posedge clk) RxD_endofpacket <= Baud8Tick & (gap_count==5'h0F);

  77. endmodule
复制代码

这是我写的仿真代码
  1. `timescale 1ns / 1ps
  2. module async_receiver_tb  ;

  3.   wire  RxD_endofpacket   ;
  4.   reg    RxD   ;
  5.   reg    clk   ;
  6.   wire   RxD_idle   ;
  7.   wire  [7:0]  RxD_data   ;
  8.   wire  RxD_data_ready;
  9.   async_receiver   
  10.    DUT  (
  11.        .RxD_endofpacket (RxD_endofpacket ) ,
  12.       .RxD (RxD ) ,
  13.       .clk (clk ) ,
  14.       .RxD_idle (RxD_idle ) ,
  15.       .RxD_data (RxD_data ) ,
  16.       .RxD_data_ready (RxD_data_ready ) );

  17. parameter CLOCK_20NS = 20;
  18. initial begin
  19. clk = 1'b0;
  20. forever
  21. # (CLOCK_20NS/2) clk = ~clk; // 20ns CLOCK
  22. end

  23. parameter BPS_9600 = 104140,
  24. SEND_DATA = 8'b1000_0011;

  25. integer i;
  26. initial begin
  27. RxD = 1'b1; //RESET rs232_rx
  28. # BPS_9600 RxD = 1'b0; // transmit START bit
  29. for (i=0;i<8;i=i+1) //transmit DATA byte
  30. # BPS_9600 RxD = SEND_DATA[i];
  31. # BPS_9600 RxD = 1'b0; // transmit STOP bit
  32. # BPS_9600 RxD = 1'b1; // bus IDLE
  33. end
  34. endmodule
复制代码

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

 楼主| 发表于 2013-12-10 22:33:33 | 显示全部楼层
运行仿真后总是没办法 出现波形~~~~

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

 楼主| 发表于 2013-12-11 21:08:46 | 显示全部楼层
只要修改   reg [Baud8GeneratorAccWidth:0] Baud8GeneratorAcc; 对它赋个初始值就OK了。


但是仿真出来的结果还是有点奇怪, baudtick  居然是两个clk    想不明白~~~~

出0入0汤圆

发表于 2014-1-9 13:01:53 | 显示全部楼层
同求解释

出0入0汤圆

 楼主| 发表于 2014-3-10 21:34:14 | 显示全部楼层

这个好久没去研究了,后来重新写了个testbench 又OK了!
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-24 03:29

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表