搜索
bottom↓
楼主: skyxjh

开源Verilog HDL原创UART模块

  [复制链接]

出0入0汤圆

发表于 2013-6-18 09:15:20 | 显示全部楼层
跟着大神的脚步学习

出0入0汤圆

 楼主| 发表于 2013-6-18 12:42:01 | 显示全部楼层
wsfry 发表于 2013-6-17 20:20
能不能写一个这个串口通讯的测试文件啊?虽然实际用串口调试已经验证过了,但是仍然想看下仿真波形! ...

测试文件自己写吧,不要什么都向人家伸手。
先看Verilog HDL教程,只要你认真看一遍,写个简单的测试文件不难。
建议你看夏宇闻《Verilog_HDL_数字系统设计教程》

本帖子中包含更多资源

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

x

出0入0汤圆

发表于 2013-6-19 23:41:17 | 显示全部楼层
牛叉的人总是把平凡的东西做得不平凡~~~

出0入0汤圆

发表于 2013-6-19 23:57:21 | 显示全部楼层
markmarkmarkmarkmark

出0入0汤圆

 楼主| 发表于 2013-6-20 00:03:20 | 显示全部楼层
suxilong 发表于 2013-6-19 23:41
牛叉的人总是把平凡的东西做得不平凡~~~

过讲了,我也是FPGA初学者。

出0入0汤圆

发表于 2013-6-20 09:06:49 | 显示全部楼层
skyxjh 发表于 2013-6-20 00:03
过讲了,我也是FPGA初学者。

不是吧,这么谦虚,初学者就可以写出逻辑这么强的代码,过不了一个月就是顶尖高手。厉害!

出0入0汤圆

 楼主| 发表于 2013-6-20 12:52:02 | 显示全部楼层
wsfry 发表于 2013-6-20 09:06
不是吧,这么谦虚,初学者就可以写出逻辑这么强的代码,过不了一个月就是顶尖高手。厉害! ...

Verilog HDL与C语言是相通的,有C语言的基础,写出这样的代码不难。关键是要善于独立思考,将自己的想法用代码实现出来。

出0入0汤圆

发表于 2013-6-20 17:20:19 | 显示全部楼层
最近正好要看这个~学习之~~~~

出0入0汤圆

发表于 2013-6-20 17:34:20 | 显示全部楼层
好东西,谢谢分享

出0入0汤圆

发表于 2013-6-21 10:15:41 | 显示全部楼层
skyxjh 发表于 2013-6-9 13:45
再发一个fifo模块,可以用作UART接收处理。

请问FIFO模块中
reg [addrbits-1:0]rdaddr; //fifo读地址
reg [addrbits-1:0]wraddr; //fifo写地址
不是8个字节么,为什么地址可以达到1111,不是最大的都只有8么

出0入0汤圆

发表于 2013-6-21 11:27:09 | 显示全部楼层
多谢lz分享

出0入0汤圆

 楼主| 发表于 2013-6-21 12:35:17 | 显示全部楼层
wsfry 发表于 2013-6-21 10:15
请问FIFO模块中
reg [addrbits-1:0]rdaddr; //fifo读地址
reg [addrbits-1:0]wraddr; //fifo写地址

地址位宽是自己设的,是可变的,3位就是8个字节,4位就是16个字节。

出0入0汤圆

发表于 2013-6-21 13:58:20 | 显示全部楼层
好帖 学习了

出0入0汤圆

发表于 2013-6-21 14:30:53 | 显示全部楼层
高手,顶一个。

出0入0汤圆

发表于 2013-6-21 14:36:27 | 显示全部楼层
谢谢,学习!!!

出0入0汤圆

 楼主| 发表于 2013-6-22 21:47:50 | 显示全部楼层
再开源一个用状态机写的串口模块,适合高速串口应用,带16字节的发送和接收FIFO。

  1. module uart8n1(
  2.         input rst,
  3.         input clk,
  4.         input rxd,
  5.         output txd
  6.         );
  7.         parameter true = 1'b0, false = 1'b1;
  8.         wire [7:0] dat;
  9.         wire txen, rdrxd, txfull, txempty, rxfull, rxempty;
  10.         uart8n1_ctrl ctrl(
  11.                 .rst(rst),
  12.                 .clk(clk),
  13.                 .rxempty(rxempty),
  14.                 .txfull(txfull),
  15.                 .txen(txen),
  16.                 .rdrxd(rdrxd)
  17.                 );
  18.         uart8n1_rx rx(
  19.                 .rst(rst),
  20.                 .clk(clk),
  21.                 .rxd(rxd),
  22.                 .rxen(true),
  23.                 .divp(50_000_000/115_200), //fclk/baud
  24.                 .rdrxd(rdrxd),
  25.                 .dat(dat),
  26.                 .rxfull(rxfull),
  27.                 .rxempty(rxempty)
  28.                 );
  29.         uart8n1_tx tx(
  30.                 .rst(rst),
  31.                 .clk(clk),
  32.                 .dat(dat),
  33.                 .txen(txen),
  34.                 .divp(50_000_000/115_200),  //fclk/baud
  35.                 .txd(txd),
  36.                 .txfull(txfull),
  37.                 .txempty(txempty)
  38.                 );
  39. endmodule
复制代码

出0入0汤圆

 楼主| 发表于 2013-6-22 21:48:22 | 显示全部楼层

  1. module uart8n1_ctrl(
  2.         input rst,
  3.         input clk,
  4.         input rxempty,
  5.         input txfull,
  6.         output txen,
  7.         output rdrxd
  8.         );
  9.         parameter true = 1'b0, false = 1'b1;
  10.         reg txe = false, rdd = false;
  11.         assign txen = txe;
  12.         assign rdrxd = rdd;
  13.         reg [1:0]ctrstate = IDLE;
  14.         parameter IDLE = 2'd1, RDRXDAT = 2'd2, TXDAT = 2'd3;
  15.         always @(posedge clk or negedge rst) begin
  16.                 if(rst == 1'b0) begin
  17.                         rdd <= false;
  18.                         txe <= false;
  19.                         end
  20.                 else begin
  21.                         case(ctrstate)
  22.                                 IDLE: begin
  23.                                         rdd <= false;
  24.                                         txe <= false;
  25.                                         if(rxempty == false) begin
  26.                                                 if(txfull == false) begin
  27.                                                         ctrstate <= RDRXDAT;
  28.                                                         end
  29.                                                 end
  30.                                         end
  31.                                 RDRXDAT: begin
  32.                                         rdd <= true;
  33.                                         ctrstate <= TXDAT;
  34.                                         end
  35.                                 TXDAT: begin
  36.                                         txe <= true;
  37.                                         ctrstate <= IDLE;
  38.                                         end
  39.                         endcase
  40.                         end
  41.                 end
  42. endmodule
复制代码

出0入0汤圆

 楼主| 发表于 2013-6-22 21:48:45 | 显示全部楼层

  1. module uart8n1_tx(
  2.         input rst,
  3.         input clk,
  4.         input [7:0] dat,
  5.         input txen,
  6.         input [15:0] divp,
  7.         output reg txd,
  8.         output txfull,
  9.         output txempty
  10.         );
  11.         parameter true = 1'b0, false = 1'b1;
  12.         wire [7:0] txdat;
  13.         reg rdfifo = false;
  14.         fifo8x15 txfifo(
  15.                 .rst(rst),
  16.                 .clk(clk),
  17.                 .ien(txen),
  18.                 .oen(rdfifo),
  19.                 .idat(dat),
  20.                 .odat(txdat),
  21.                 .full(txfull),
  22.                 .empty(txempty)
  23.                 );
  24.         reg [15:0] divcnt = 16'b0;
  25.         reg [3:0] txstate = IDLE;
  26.         parameter IDLE = 4'h1, TXSTART = 4'h2, TXBIT0 = 4'h3, TXBIT1 = 4'h4, TXBIT2 = 4'h5, TXBIT3 = 4'h6,
  27.                   TXBIT4 = 4'h7, TXBIT5 = 4'h8, TXBIT6 = 4'h9, TXBIT7 = 4'hA, TXSTOP = 4'hB;
  28.         always @ (posedge clk or negedge rst) begin
  29.                 if(rst == 1'b0) begin
  30.                         txd <= 1'b1;
  31.                         rdfifo <= false;
  32.                         divcnt <= 16'b0;
  33.                         txstate <= IDLE;
  34.                         end
  35.                 else begin
  36.                         case(txstate)
  37.                                 IDLE: begin
  38.                                         txd <= 1'b1;
  39.                                         if(txempty == false) begin
  40.                                                 rdfifo <= true;
  41.                                                 divcnt <= 16'b0;
  42.                                                 txstate <= TXSTART;
  43.                                                 end
  44.                                         end
  45.                                 TXSTART: begin
  46.                                         txd <= 1'b0;
  47.                                         rdfifo <= false;
  48.                                         if(divcnt == divp) begin
  49.                                                 divcnt <= 16'b0;
  50.                                                 txstate <= TXBIT0;
  51.                                                 end
  52.                                         else begin
  53.                                                 divcnt <= divcnt + 1'b1;
  54.                                                 end
  55.                                         end
  56.                                 TXBIT0: begin
  57.                                         txd <= txdat[0];
  58.                                         if(divcnt == divp) begin
  59.                                                 divcnt <= 16'b0;
  60.                                                 txstate <= TXBIT1;
  61.                                                 end
  62.                                         else begin
  63.                                                 divcnt <= divcnt + 1'b1;
  64.                                                 end
  65.                                         end
  66.                                 TXBIT1: begin
  67.                                         txd <= txdat[1];
  68.                                         if(divcnt == divp) begin
  69.                                                 divcnt <= 16'b0;
  70.                                                 txstate <= TXBIT2;
  71.                                                 end
  72.                                         else begin
  73.                                                 divcnt <= divcnt + 1'b1;
  74.                                                 end
  75.                                         end
  76.                                 TXBIT2: begin
  77.                                         txd <= txdat[2];
  78.                                         if(divcnt == divp) begin
  79.                                                 divcnt <= 16'b0;
  80.                                                 txstate <= TXBIT3;
  81.                                                 end
  82.                                         else begin
  83.                                                 divcnt <= divcnt + 1'b1;
  84.                                                 end
  85.                                         end
  86.                                 TXBIT3: begin
  87.                                         txd <= txdat[3];
  88.                                         if(divcnt == divp) begin
  89.                                                 divcnt <= 16'b0;
  90.                                                 txstate <= TXBIT4;
  91.                                                 end
  92.                                         else begin
  93.                                                 divcnt <= divcnt + 1'b1;
  94.                                                 end
  95.                                         end
  96.                                 TXBIT4: begin
  97.                                         txd <= txdat[4];
  98.                                         if(divcnt == divp) begin
  99.                                                 divcnt <= 16'b0;
  100.                                                 txstate <= TXBIT5;
  101.                                                 end
  102.                                         else begin
  103.                                                 divcnt <= divcnt + 1'b1;
  104.                                                 end
  105.                                         end
  106.                                 TXBIT5: begin
  107.                                         txd <= txdat[5];
  108.                                         if(divcnt == divp) begin
  109.                                                 divcnt <= 16'b0;
  110.                                                 txstate <= TXBIT6;
  111.                                                 end
  112.                                         else begin
  113.                                                 divcnt <= divcnt + 1'b1;
  114.                                                 end
  115.                                         end
  116.                                 TXBIT6: begin
  117.                                         txd <= txdat[6];
  118.                                         if(divcnt == divp) begin
  119.                                                 divcnt <= 16'b0;
  120.                                                 txstate <= TXBIT7;
  121.                                                 end
  122.                                         else begin
  123.                                                 divcnt <= divcnt + 1'b1;
  124.                                                 end
  125.                                         end
  126.                                 TXBIT7: begin
  127.                                         txd <= txdat[7];
  128.                                         if(divcnt == divp) begin
  129.                                                 divcnt <= 16'b0;
  130.                                                 txstate <= TXSTOP;
  131.                                                 end
  132.                                         else begin
  133.                                                 divcnt <= divcnt + 1'b1;
  134.                                                 end
  135.                                         end
  136.                                 TXSTOP: begin
  137.                                         txd <= 1'b1;
  138.                                         rdfifo <= false;
  139.                                         if(divcnt == divp) begin
  140.                                                 divcnt <= 16'b0;
  141.                                                 txstate <= IDLE;
  142.                                                 end
  143.                                         else begin
  144.                                                 divcnt <= divcnt + 1'b1;
  145.                                                 end
  146.                                         end
  147.                         endcase
  148.                         end
  149.                 end
  150. endmodule
复制代码

出0入0汤圆

 楼主| 发表于 2013-6-22 21:49:03 | 显示全部楼层

  1. module uart8n1_rx(
  2.         input rst,
  3.         input clk,
  4.         input rxd,
  5.         input rxen,
  6.         input [15:0] divp,
  7.         input rdrxd,
  8.         output [7:0] dat,
  9.         output rxfull,
  10.         output rxempty
  11.         );
  12.         parameter true = 1'b0, false = 1'b1;
  13.         reg [7:0] rxdata;
  14.         wire [7:0] rxdat = rxdata;
  15.         reg dready;
  16.         wire ien = dready;
  17.         wire rxdlpo;
  18.         fifo8x15 rxfifo(
  19.                 .rst(rst),
  20.                 .clk(clk),
  21.                 .ien(ien),
  22.                 .oen(rdrxd),
  23.                 .idat(rxdat),
  24.                 .odat(dat),
  25.                 .full(rxfull),
  26.                 .empty(rxempty)
  27.                 );
  28.         lowpass lp(
  29.                 .clk(clk),
  30.                 .lin(rxd),
  31.                 .lout(rxdlpo)
  32.                 );
  33.         reg [15:0] divcnt = 16'b0;
  34.         reg [3:0] rxstate = IDLE;
  35.         parameter IDLE = 4'h1, RXSTART = 4'h2, RXBIT0 = 4'h3, RXBIT1 = 4'h4, RXBIT2 = 4'h5, RXBIT3 = 4'h6,
  36.                   RXBIT4 = 4'h7, RXBIT5 = 4'h8, RXBIT6 = 4'h9, RXBIT7 = 4'hA, RXSTOP = 4'hB;
  37.         always @ (posedge clk or negedge rst) begin
  38.                 if(rst == 1'b0) begin
  39.                         dready <= false;
  40.                         divcnt <= 16'b0;
  41.                         rxstate <= IDLE;
  42.                         end
  43.                 else begin
  44.                         case(rxstate)
  45.                                 IDLE: begin
  46.                                         dready <= false;
  47.                                         if(rxen == true && rxdlpo == 1'b0) begin
  48.                                                 divcnt <= 16'b0;
  49.                                                 rxstate <= RXSTART;
  50.                                                 end
  51.                                         end
  52.                                 RXSTART: begin
  53.                                         if(divcnt == divp[15:1]) begin
  54.                                                 divcnt <= 16'b0;
  55.                                                 if(rxdlpo == 1'b0) rxstate <= RXBIT0;
  56.                                                 else rxstate <= IDLE;
  57.                                                 end
  58.                                         else begin
  59.                                                 divcnt <= divcnt + 1'b1;
  60.                                                 end
  61.                                         end
  62.                                 RXBIT0: begin
  63.                                         if(divcnt == divp) begin
  64.                                                 rxdata[0] <= rxdlpo;
  65.                                                 divcnt <= 16'b0;
  66.                                                 rxstate <= RXBIT1;
  67.                                                 end
  68.                                         else begin
  69.                                                 divcnt <= divcnt + 1'b1;
  70.                                                 end
  71.                                         end
  72.                                 RXBIT1: begin
  73.                                         if(divcnt == divp) begin
  74.                                                 rxdata[1] <= rxdlpo;
  75.                                                 divcnt <= 16'b0;
  76.                                                 rxstate <= RXBIT2;
  77.                                                 end
  78.                                         else begin
  79.                                                 divcnt <= divcnt + 1'b1;
  80.                                                 end
  81.                                         end
  82.                                 RXBIT2: begin
  83.                                         if(divcnt == divp) begin
  84.                                                 rxdata[2] <= rxdlpo;
  85.                                                 divcnt <= 16'b0;
  86.                                                 rxstate <= RXBIT3;
  87.                                                 end
  88.                                         else begin
  89.                                                 divcnt <= divcnt + 1'b1;
  90.                                                 end
  91.                                         end
  92.                                 RXBIT3: begin
  93.                                         if(divcnt == divp) begin
  94.                                                 rxdata[3] <= rxdlpo;
  95.                                                 divcnt <= 16'b0;
  96.                                                 rxstate <= RXBIT4;
  97.                                                 end
  98.                                         else begin
  99.                                                 divcnt <= divcnt + 1'b1;
  100.                                                 end
  101.                                         end
  102.                                 RXBIT4: begin
  103.                                         if(divcnt == divp) begin
  104.                                                 rxdata[4] <= rxdlpo;
  105.                                                 divcnt <= 16'b0;
  106.                                                 rxstate <= RXBIT5;
  107.                                                 end
  108.                                         else begin
  109.                                                 divcnt <= divcnt + 1'b1;
  110.                                                 end
  111.                                         end
  112.                                 RXBIT5: begin
  113.                                         if(divcnt == divp) begin
  114.                                                 rxdata[5] <= rxdlpo;
  115.                                                 divcnt <= 16'b0;
  116.                                                 rxstate <= RXBIT6;
  117.                                                 end
  118.                                         else begin
  119.                                                 divcnt <= divcnt + 1'b1;
  120.                                                 end
  121.                                         end
  122.                                 RXBIT6: begin
  123.                                         if(divcnt == divp) begin
  124.                                                 rxdata[6] <= rxdlpo;
  125.                                                 divcnt <= 16'b0;
  126.                                                 rxstate <= RXBIT7;
  127.                                                 end
  128.                                         else begin
  129.                                                 divcnt <= divcnt + 1'b1;
  130.                                                 end
  131.                                         end
  132.                                 RXBIT7: begin
  133.                                         if(divcnt == divp) begin
  134.                                                 rxdata[7] <= rxdlpo;
  135.                                                 divcnt <= 16'b0;
  136.                                                 rxstate <= RXSTOP;
  137.                                                 end
  138.                                         else begin
  139.                                                 divcnt <= divcnt + 1'b1;
  140.                                                 end
  141.                                         end
  142.                                 RXSTOP: begin
  143.                                         if(divcnt == divp) begin
  144.                                                 divcnt <= 16'b0;
  145.                                                 rxstate <= IDLE;
  146.                                                 if(rxdlpo == 1'b1) begin
  147.                                                         dready <= true;
  148.                                                         end
  149.                                                 end
  150.                                         else begin
  151.                                                 divcnt <= divcnt + 1'b1;
  152.                                                 end
  153.                                         end
  154.                         endcase
  155.                         end
  156.                 end
  157. endmodule
复制代码

出0入0汤圆

 楼主| 发表于 2013-6-22 21:49:31 | 显示全部楼层

  1. module fifo8x15(
  2.         input rst,
  3.         input clk,
  4.         input ien,
  5.         input oen,
  6.         input [7:0] idat,
  7.         output [7:0] odat,
  8.         output full,
  9.         output empty
  10.         );
  11.         parameter true = 1'b0, false = 1'b1;
  12.         reg [7:0] mem [0:15];
  13.         reg [3:0] wraddr = {4{1'b0}};
  14.         reg [3:0] rdaddr = {4{1'b0}};
  15.         wire [3:0] datnum = wraddr - rdaddr;
  16.         assign empty = datnum == {4{1'b0}} ? true : false;
  17.         assign full  = datnum == {4{1'b1}} ? true : false;
  18.         reg [7:0] odatq;
  19.         assign odat = odatq;
  20.         reg ienbuf = 1'b0, oenbuf = 1'b0;
  21.         wire negedge_ien = ienbuf & ~ien;
  22.         wire negedge_oen = oenbuf & ~oen;
  23.         always @ (posedge clk or negedge rst) begin
  24.                 if(rst == 1'b0) begin //reset
  25.                         ienbuf <= 1'b0;
  26.                         oenbuf <= 1'b0;
  27.                         end
  28.                 else begin //buffer
  29.                         ienbuf <= ien;
  30.                         oenbuf <= oen;
  31.                         end
  32.                 end
  33.         always @ (posedge clk or negedge rst) begin
  34.                 if(rst == 1'b0) begin //reset
  35.                         wraddr <= {4{1'b0}};
  36.                         rdaddr <= {4{1'b0}};
  37.                         end
  38.                 else begin
  39.                         if(negedge_ien && full == false) begin //push
  40.                                 mem[wraddr] <= idat;
  41.                                 wraddr <= wraddr + 1'b1;
  42.                                 end
  43.                         if(negedge_oen && empty == false) begin //pop
  44.                                 odatq <= mem[rdaddr];
  45.                                 rdaddr <= rdaddr + 1'b1;
  46.                                 end
  47.                         end
  48.                 end
  49. endmodule
复制代码

出0入0汤圆

 楼主| 发表于 2013-6-22 21:49:46 | 显示全部楼层

  1. module lowpass(
  2.         input clk,
  3.         input lin,
  4.         output lout
  5.         );
  6.         reg [3:0] lpbuf;
  7.         always @ (posedge clk) begin lpbuf <= {lpbuf[2:0],lin}; end
  8.         wire lin1 = & lpbuf;
  9.         wire lin0 = | lpbuf;
  10.         assign lout = (lin1 == 1'b1) ? 1'b1 : (lin0 == 1'b0) ? 1'b0 : lout;
  11. endmodule
复制代码

出0入0汤圆

 楼主| 发表于 2013-6-22 21:51:10 | 显示全部楼层
用状态机写的代码,逻辑关系很清楚,就没有写注释。

出0入0汤圆

 楼主| 发表于 2013-6-22 22:01:00 | 显示全部楼层
为方便大家下载引用,打包工程代码如下,请不要用于商业用途,如用于出版或教程,请联系本人。

本帖子中包含更多资源

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

x

出0入0汤圆

 楼主| 发表于 2013-6-22 22:01:56 | 显示全部楼层

本帖子中包含更多资源

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

x

出0入0汤圆

 楼主| 发表于 2013-6-22 22:05:51 | 显示全部楼层

本帖子中包含更多资源

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

x

出0入0汤圆

发表于 2013-6-24 17:18:34 | 显示全部楼层
skyxjh 发表于 2013-6-22 21:49

大侠你好:
        编译之后我烧到开发板里面了,用电脑串口调试助手发送指令 返回的值是乱码,这是怎么回事呀,求解中!谢谢!

出0入0汤圆

发表于 2013-6-24 17:43:04 | 显示全部楼层
skyxjh 发表于 2013-6-22 22:01
为方便大家下载引用,打包工程代码如下,请不要用于商业用途,如用于出版或教程,请联系本人。

...

不好意思,我搞错了 ,没什么问题!我学习的第一个串口例子就是你这个,很经典,不像一些书上写的,冗余废话多,很感谢你分享这么好的代码!谢谢!

出0入0汤圆

 楼主| 发表于 2013-6-24 20:42:06 | 显示全部楼层
wsfry 发表于 2013-6-24 17:43
不好意思,我搞错了 ,没什么问题!我学习的第一个串口例子就是你这个,很经典,不像一些书上写的,冗余 ...

不用客气,大家共同学习,共同进步。

出0入0汤圆

发表于 2013-6-25 09:15:02 | 显示全部楼层
skyxjh 发表于 2013-6-24 20:42
不用客气,大家共同学习,共同进步。

大侠好请问:你这个为什么没有采集的时候不是在中间位置采集吗?.divp(20_000_000/115_200), //fclk/baud,
不是应该divp(20_000_000/115_200/2);我这样设置后 出现的是发送后 返回值乱码?请问这是怎么回事?

出0入0汤圆

 楼主| 发表于 2013-6-25 12:42:11 | 显示全部楼层
wsfry 发表于 2013-6-25 09:15
大侠好请问:你这个为什么没有采集的时候不是在中间位置采集吗?.divp(20_000_000/115_200), //fclk/baud ...

计时到一半的时刻检测起始位,然后计时器清零,后面就是间隔1位时采样数据,刚好在数据的中点。

出0入0汤圆

发表于 2013-6-25 14:37:55 | 显示全部楼层
skyxjh 发表于 2013-6-25 12:42
计时到一半的时刻检测起始位,然后计时器清零,后面就是间隔1位时采样数据,刚好在数据的中点。 ...

你写的程序好隐蔽呀,if(divcnt == divp[15:1]) begin   等价于if(divcnt == (divp[15:0]>>1'b1)) begin,相当于除了一个2,中间值采样!
找了半天才找到,这个程序比上次的那个要准确 ,上次的那个用串口调试助手自动发送,如果发送过快的话,偶尔会出现错误的代码,这次的这个就很准确,写法很经典,学习的很好的例子!黄金案例!

出0入0汤圆

 楼主| 发表于 2013-6-25 19:51:48 | 显示全部楼层
wsfry 发表于 2013-6-25 14:37
你写的程序好隐蔽呀,if(divcnt == divp[15:1]) begin   等价于if(divcnt == (divp[15:0]>>1'b1)) begin ...

第一个模块你是用的修改后的代码吗?不应该有出错的情况啊。

出0入0汤圆

 楼主| 发表于 2013-6-25 19:54:26 | 显示全部楼层
wsfry 发表于 2013-6-25 14:37
你写的程序好隐蔽呀,if(divcnt == divp[15:1]) begin   等价于if(divcnt == (divp[15:0]>>1'b1)) begin ...

这种是很常规的写法。

出0入0汤圆

 楼主| 发表于 2013-6-25 19:57:02 | 显示全部楼层
第一个模块运行时钟频率低,节能。后面的模块全速运行,响应速度快,适合高速串口通信。

出0入0汤圆

发表于 2013-6-25 21:47:51 | 显示全部楼层
mark                  

出0入0汤圆

发表于 2013-6-27 17:03:58 | 显示全部楼层
本帖最后由 wsfry 于 2013-6-27 17:16 编辑
skyxjh 发表于 2013-6-9 12:50
更正接收模块上电后丢失接收到的第1个字节数据的BUG。原因是检查结束位时实际该帧数据结束位的采样还没结束 ...


这样改了之后,仍然要丢失一个完整的字节,后面的数据才是对的!

本帖子中包含更多资源

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

x

出0入0汤圆

 楼主| 发表于 2013-6-28 00:15:46 | 显示全部楼层
wsfry 发表于 2013-6-27 17:03
这样改了之后,仍然要丢失一个完整的字节,后面的数据才是对的!

这个不是字节丢失,只有接收完一个字节,才能转发出去。如果不对字节检验,而是原始波形转发就没有意义了。

出0入0汤圆

 楼主| 发表于 2013-6-28 00:17:14 | 显示全部楼层
发送会比接收滞后一个字节时间。

出0入0汤圆

发表于 2013-6-28 14:34:50 | 显示全部楼层
本帖最后由 wsfry 于 2013-6-28 19:07 编辑

我没有用你的发送模块,想看下接收模块的并口数据
发现在高阻态之后,有个0的数据接收,能解释下?
这算不算错误,如果是怎么清除?

本帖子中包含更多资源

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

x

出0入0汤圆

 楼主| 发表于 2013-6-28 23:36:38 | 显示全部楼层
本帖最后由 skyxjh 于 2013-6-28 23:41 编辑
wsfry 发表于 2013-6-28 14:34
我没有用你的发送模块,想看下接收模块的并口数据
发现在高阻态之后,有个0的数据接收,能解释下?
这算不 ...


是你仿真输入波形产生的问题吧。

出0入0汤圆

发表于 2013-6-29 10:27:41 | 显示全部楼层
本帖最后由 wsfry 于 2013-6-29 15:12 编辑
skyxjh 发表于 2013-6-28 23:36
是你仿真输入波形产生的问题吧。




解决了,不是波形的问题,是我自己代码写的有问题,少了一个判断条件!
我想请教下,假如在传输数据中复位,比如一个8位的数据中间复位(没传完),是不是会出现错误了!

出0入0汤圆

 楼主| 发表于 2013-6-30 21:00:49 | 显示全部楼层
wsfry 发表于 2013-6-29 10:27
解决了,不是波形的问题,是我自己代码写的有问题,少了一个判断条件!
我想请教下,假如在传输数据中 ...

接收端会接收到一个错误的字节。

出0入0汤圆

发表于 2013-7-1 11:25:22 | 显示全部楼层
这个必须顶啊

出0入0汤圆

发表于 2013-7-1 16:32:59 | 显示全部楼层
skyxjh 发表于 2013-6-30 21:00
接收端会接收到一个错误的字节。

请问为什么都是8位的数据连接会出现这种问题,连接FIFO模块的时候!
第二张图假如我把顶层文件rxdout(rxdout)  txdin(rxdout)2个端口从txdin改为rxdout也出现了这种情况,请教下!

本帖子中包含更多资源

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

x

出0入0汤圆

 楼主| 发表于 2013-7-1 16:47:18 | 显示全部楼层
wsfry 发表于 2013-7-1 16:32
请问为什么都是8位的数据连接会出现这种问题,连接FIFO模块的时候!
第二张图假如我把顶层文件rxdout(rxd ...

没明白你说的是什么问题。

出0入0汤圆

 楼主| 发表于 2013-7-1 16:49:07 | 显示全部楼层
wsfry 发表于 2013-7-1 16:32
请问为什么都是8位的数据连接会出现这种问题,连接FIFO模块的时候!
第二张图假如我把顶层文件rxdout(rxd ...

是说显示7‘NC吗?是你的参数位宽设置成1位了吧。

出0入0汤圆

发表于 2013-7-1 16:53:55 | 显示全部楼层
本帖最后由 wsfry 于 2013-7-1 19:05 编辑
skyxjh 发表于 2013-7-1 16:49
是说显示7‘NC吗?是你的参数位宽设置成1位了吧。


肯定设置的是8位啊,你看RTL图都显示了位宽的!


假如我把顶层文件rxdout(rxdout)  txdin(rxdout)2个端口从txdin改为rxdout也出现了这种情况,请教下!
这是不是也反映了rxdout其实也没占满!

本帖子中包含更多资源

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

x

出0入0汤圆

 楼主| 发表于 2013-7-1 21:27:56 | 显示全部楼层
wsfry 发表于 2013-7-1 16:53
肯定设置的是8位啊,你看RTL图都显示了位宽的!

收发模块里设置的是8位,你顶层模块里没有设置成8位就会这样。

出0入0汤圆

发表于 2013-7-2 21:04:36 | 显示全部楼层
注释真全

出0入0汤圆

发表于 2013-7-11 15:46:30 | 显示全部楼层
很好!讨论和分析都很好!

出0入0汤圆

发表于 2013-7-18 13:38:21 | 显示全部楼层
  baudset #(.fsysclk(50_000_000),.baud(115_200)) baudset(.rst(rst),.sysclk(clk),.txclk(txclk),.rxclk(rxclk));

这个例化怎么理解?

出0入0汤圆

 楼主| 发表于 2013-7-20 22:29:20 | 显示全部楼层
afei8856 发表于 2013-7-18 13:38
baudset #(.fsysclk(50_000_000),.baud(115_200)) baudset(.rst(rst),.sysclk(clk),.txclk(txclk),.rxclk ...

#(.fsysclk(50_000_000),.baud(115_200))是设置模块内用到的参数,系统时钟和波特率。

出0入0汤圆

发表于 2013-7-21 10:00:58 | 显示全部楼层
谢谢分享~有空再好好看看

出0入0汤圆

发表于 2013-7-22 19:23:07 | 显示全部楼层
好贴必顶,嘿嘿,学习学习

出0入0汤圆

发表于 2013-7-24 13:57:53 | 显示全部楼层
我尝试修改过奇偶校验设置,发现只有才无奇偶校验时接收是正确的,在其他情况下出现数接收错误,不知道怎么个情况?

出0入0汤圆

 楼主| 发表于 2013-7-24 20:47:13 | 显示全部楼层
afei8856 发表于 2013-7-24 13:57
我尝试修改过奇偶校验设置,发现只有才无奇偶校验时接收是正确的,在其他情况下出现数接收错误,不知道怎么 ...

你是怎么设置的?怎么测试的?

出0入0汤圆

发表于 2013-7-24 22:01:27 | 显示全部楼层
有收获,顶一个

出0入0汤圆

发表于 2013-7-25 08:34:30 | 显示全部楼层
skyxjh 发表于 2013-6-6 19:37
你这种采样方式,如果信号的边沿很平缓的话,岂不是采样到全0的概率很大。 ...

你好:最近遇到一个问题百思不得其解,请教你一下:
      别人做好的一个工程,我自己在重新建立一个和别人一模一样的工程(是VHDL的工程,这个是以原理图的形式做的),但是两个工程编译出来的效果不一样,我用比较软件看了一下生成的.POF文件,发现两个文件的.POF文件不一样,请问这是怎么回事,
并且我的编译出来的警告都是一模一样的,请问是不是VHDL的建立工程有很多设置的地方?谢谢!

出0入0汤圆

 楼主| 发表于 2013-7-25 13:17:18 | 显示全部楼层
wsfry 发表于 2013-7-25 08:34
你好:最近遇到一个问题百思不得其解,请教你一下:
      别人做好的一个工程,我自己在重新建立一个和 ...

同一个工程,设置不一样,编译出来的结果不一样很正常。甚至同样的设置两次编译的结果都有可能不一样。

出0入0汤圆

发表于 2013-7-25 14:56:12 | 显示全部楼层
这个资料要收藏

出0入0汤圆

发表于 2013-8-13 16:12:20 | 显示全部楼层
。。。学习啦

出0入0汤圆

发表于 2013-8-15 15:43:24 | 显示全部楼层
太给力了

出0入8汤圆

发表于 2013-8-15 16:02:02 | 显示全部楼层
好东西,有时间拜读一下

出0入0汤圆

 楼主| 发表于 2013-9-20 13:15:32 | 显示全部楼层
好久没关注了,都加精华了,谢谢版主。

出0入0汤圆

发表于 2013-9-22 10:49:28 | 显示全部楼层
这个牛啊

出0入0汤圆

发表于 2013-9-22 11:35:30 | 显示全部楼层
LZ很认真,顶

出0入0汤圆

发表于 2013-9-22 19:22:24 | 显示全部楼层
学习了,谢谢楼主分享。

出0入0汤圆

发表于 2013-9-23 16:50:59 | 显示全部楼层
这个注释真的很给力

出0入0汤圆

发表于 2013-9-23 17:35:45 | 显示全部楼层
留下足迹,日后瞻仰学习。

出0入0汤圆

发表于 2013-9-23 17:52:08 | 显示全部楼层
mark下这么好的学习资料,感谢

出0入0汤圆

发表于 2013-10-9 16:40:24 | 显示全部楼层
学习了,很不错。

出0入0汤圆

发表于 2013-12-19 21:52:08 | 显示全部楼层
顶一个!               

出0入0汤圆

发表于 2013-12-19 22:54:44 | 显示全部楼层
好帖要顶

出0入0汤圆

发表于 2013-12-21 17:34:35 | 显示全部楼层
skyxjh 发表于 2013-6-15 19:40
FIFO及测试代码如下,请不要用于商用,如果用于出版或教程之类,请联系本人。
...

问一下,你发的第二套uart中的fifo是怎么插进去的?

出0入0汤圆

 楼主| 发表于 2013-12-21 20:56:50 | 显示全部楼层
orange-208 发表于 2013-12-21 17:34
问一下,你发的第二套uart中的fifo是怎么插进去的?
  1.         fifo8x15 txfifo(
  2.                 .rst(rst),
  3.                 .clk(clk),
  4.                 .ien(txen),
  5.                 .oen(rdfifo),
  6.                 .idat(dat),
  7.                 .odat(txdat),
  8.                 .full(txfull),
  9.                 .empty(txempty)
  10.                 );
复制代码
  1.         fifo8x15 rxfifo(
  2.                 .rst(rst),
  3.                 .clk(clk),
  4.                 .ien(ien),
  5.                 .oen(rdrxd),
  6.                 .idat(rxdat),
  7.                 .odat(dat),
  8.                 .full(rxfull),
  9.                 .empty(rxempty)
  10.                 );
复制代码

这两个FIFO实例化就是。

出0入0汤圆

发表于 2013-12-21 21:31:17 | 显示全部楼层
skyxjh 发表于 2013-12-21 20:56
这两个FIFO实例化就是。

这个是第三套uart的模块,第二套uart的fifo中,有iclk,oclk。

出0入0汤圆

 楼主| 发表于 2013-12-21 21:56:10 | 显示全部楼层
一样的用啊。

出0入0汤圆

发表于 2013-12-24 09:09:41 | 显示全部楼层
认认真真拜读完这组帖子,受益匪浅啊。这里远比混乱的现实世界美好。

出0入0汤圆

发表于 2013-12-29 08:34:05 | 显示全部楼层
你好,学习你的帖子,受益很多,现在有两个问题想向你请教,请不吝赐教,谢谢!
我用xlinx ISE,但是对于bandset.v综合始终不能通过;
主要在两个地方:
(1)function [N-1:0] fixv2; //位宽调整
        input [31:0]value;
        fixv2 = value;
endfunction
(2)function [5:0]wordsize; //计算位宽
        input [31:0]value;
        wordsize = 6'd1;         
                  while((32'b1 << (wordsize - 6'd1)) < value) wordsize = wordsize + 6'd1;                         
endfunction

出0入0汤圆

 楼主| 发表于 2013-12-29 14:24:34 | 显示全部楼层
22seu_08 发表于 2013-12-29 08:34
你好,学习你的帖子,受益很多,现在有两个问题想向你请教,请不吝赐教,谢谢!
我用xlinx ISE,但是对于ba ...

有什么提示?

出0入0汤圆

发表于 2013-12-30 08:59:41 | 显示全部楼层
对于(1),ISE报错:ERROR:HDLCompilers:26 - "baudset.v" line 29 expecting 'endfunction', found 'while'
                              ERROR:HDLCompilers:26 - "baudset.v" line 29 expecting 'endmodule', found '('
然后,我把wordsize = hi;给屏蔽,报错取消,但是(2)出错了:
ERROR:HDLCompilers:181 - "baudset.v" line 38 Illegal reference to parameter 'N' in parameter expression
ERROR:HDLCompilers:181 - "baudset.v" line 38 Illegal reference to parameter 'N' in parameter expression

谢谢

出0入0汤圆

 楼主| 发表于 2013-12-30 13:12:33 | 显示全部楼层
22seu_08 发表于 2013-12-30 08:59
对于(1),ISE报错:ERROR:HDLCompilers:26 - "baudset.v" line 29 expecting 'endfunction', found 'whil ...

应该是少了一个“)”,你好好检查一下。

出0入0汤圆

发表于 2013-12-30 14:36:08 | 显示全部楼层
mark,mark, 支持

出0入0汤圆

发表于 2013-12-30 19:37:20 | 显示全部楼层
while((32'b1 << (wordsize - 6'd1)) < value) wordsize = wordsize + 6'd1;   
你好!这句中的确没有少")",就是while() 语句;
请问,哪里出问题了,谢谢

出0入0汤圆

 楼主| 发表于 2013-12-30 19:49:55 | 显示全部楼层

我用QUARTUSII综合都是没问题的,不知道是不是ISE的问题。

出0入0汤圆

发表于 2013-12-30 19:58:29 | 显示全部楼层
支持                              

出0入0汤圆

发表于 2013-12-30 22:54:26 | 显示全部楼层
UART是简单的东西。opencore上有很多开源代码

出0入0汤圆

发表于 2013-12-31 20:31:35 | 显示全部楼层
谢谢楼主细心的注解,作为初学者很是受用。赞一个

出0入0汤圆

 楼主| 发表于 2014-1-1 20:24:35 | 显示全部楼层
sakulaka 发表于 2013-12-31 20:31
谢谢楼主细心的注解,作为初学者很是受用。赞一个

甭客气,写代码注释很重要,这样日后维护代码就方便了。

出0入0汤圆

发表于 2014-1-7 10:10:18 | 显示全部楼层
好好研读下~

出0入0汤圆

发表于 2014-1-8 11:24:00 | 显示全部楼层
支持,支持这种实用的适合初学者的!

出0入0汤圆

发表于 2014-1-10 08:04:11 | 显示全部楼层
楼主好牛!

出0入0汤圆

发表于 2014-1-10 09:05:06 | 显示全部楼层
mark

出0入0汤圆

发表于 2014-1-10 09:46:00 | 显示全部楼层
也来献丑传一个自认为比较方便的带波特率设置的发送程序,思维比较新颖

大概原理就是利用移位,这里是重点   parameter BAUD_INC = ((BAUD<<(BAUD_WIDTH-4))+(CLK>>5))/(CLK>>4),//定义波特率增长进位处理

大概推导过程为 比如我们使用2M的时钟,要产生115200的波特率那么有  2_000_000/115200≈1024/59   这个59怎么来的呢   就是这样凑出来的  然后就可以得到
INC=Baud<<Width/Clk


//`default_nettype none
`timescale 1ns/1ns


module USART_TXD
#
(
   parameter BAUD = 115200,      //定义波特率
   parameter TXD_BIT=10,         //数据宽度 1起始位 8数据位 1停止位
   parameter CLK = 100_000_000, // 定义时钟100MHz
   parameter BAUD_WIDTH = 16,    //定义宽度,保持16位就可以了
   parameter BAUD_INC = ((BAUD<<(BAUD_WIDTH-4))+(CLK>>5))/(CLK>>4),//定义波特率增长进位处理
   
   parameter STA_IDLE=1'b0,
   parameter STA_TXD=1'b1
)
(
   input i_usart_clk,   //输入时钟 100m
   input[7:0]i_txd_data,//输入数据   
   input i_txd_req,     //请求开始
      
   output o_txd_data,   //txd数据输出
   output o_txd_ack     //请求应答
)/*synthesis, probe_port,keep */;







reg[3:0]r_txd_cnt;   //发送位数计数器
reg r_state=STA_IDLE;//状态机   
reg[TXD_BIT-1:0]r_in_data;//1起始位 8数据位 1停止位,共10位
reg r_txd_ack;   
reg r_txd_data;
reg r_data_latch;

//波特率处理
reg [BAUD_WIDTH:0] r_baud=0;             //波特率产生寄存器
wire w_baud_tick=r_baud[BAUD_WIDTH];    //波特率时间到达标志
//波特率基准产生
always @(posedge i_usart_clk)
begin
   if(r_state)r_baud <= r_baud[BAUD_WIDTH-1:0]+BAUD_INC[BAUD_WIDTH:0];
   else r_baud[BAUD_WIDTH]<=1;//txd_req一产生就发送起始位,不需要等待w_baud_tick
end




//输入数据锁存
always@(posedge i_usart_clk)
begin
   if((r_state==STA_IDLE)&&(i_txd_req))
   begin
      r_in_data<={1'b1,i_txd_data,1'b0};
      r_data_latch<=1;
   end   
   else
      r_data_latch<=0;
end


//状态转换
always@(posedge i_usart_clk)
begin
   case(r_state)
      STA_IDLE:if((r_state==STA_IDLE)&&(i_txd_req))r_state<=STA_TXD;//状态转换
      STA_TXD:if(w_baud_tick&&(r_txd_cnt>=TXD_BIT))r_state<=STA_IDLE;
      default:r_state<=STA_IDLE;
   endcase
end

//输出处理
always@(posedge i_usart_clk)
begin
   if(r_state==STA_TXD)
   begin
      r_txd_ack<=1'b1;
      if(w_baud_tick)
      begin
         r_txd_cnt<=r_txd_cnt+1'b1;
         r_txd_data<=r_in_data[r_txd_cnt];
      end   
   end
   else
   begin
      r_txd_data<=1'b1;
      r_txd_cnt<=4'd0;
      r_txd_ack<=1'b0;
   end
end

assign o_txd_data=r_txd_data;
assign o_txd_ack=r_txd_ack|i_txd_req|r_data_latch;

endmodule

出0入0汤圆

发表于 2014-1-10 10:07:16 | 显示全部楼层
可以看得出来 楼主的经验非常丰富。乐于见到这样的讨论,作为初学者,可以从中学到很多东西。

出0入0汤圆

发表于 2014-1-10 11:51:57 | 显示全部楼层
好帖要顶

出0入0汤圆

发表于 2014-1-18 17:11:45 | 显示全部楼层
好贴,学习。。。。

出0入0汤圆

发表于 2014-1-18 23:02:22 | 显示全部楼层
楼主和网友的讨论让我明白了细节处理需要注意的地方,而不是代码本身,感谢诸位的辛苦付出,谢谢。

出0入0汤圆

 楼主| 发表于 2014-1-19 14:25:57 | 显示全部楼层
感谢大家对本贴的肯定,也希望大家多提宝贵意见。

出0入0汤圆

发表于 2014-1-19 17:11:42 | 显示全部楼层
相当给力啊。我自己写了个带FIFO的UART,刚看了下,要137个LE啊。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-4-19 18:19

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

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