搜索
bottom↓
回复: 20

开源原创verilog四通道接收一通道转发UART模块

[复制链接]

出0入0汤圆

发表于 2013-7-3 19:23:07 | 显示全部楼层 |阅读模式
开源原创verilog四通道接收一通道转发UART模块。
该模块实现4通道接收,1通道转发,4字节为1帧。
设置发送通道波特率为接收通道的4倍就可以保证不丢失数据。
如果接收通道的数据不是连续的,间隔时间内能保证转发完4帧数据,这样发送通道波特率可以与接收通道相同。
每通道包括8字节FIFO,转发某一通道数据帧时不影响数据的接收。

出0入0汤圆

 楼主| 发表于 2013-7-3 19:24:27 | 显示全部楼层

  1. module uart8n1(
  2.         input rst,
  3.         input clk,
  4.         input [3:0]rxd,
  5.         output txd
  6.         );
  7.         parameter true = 1'b0, false = 1'b1;
  8.         wire txen, txfull, txempty, txhfull;
  9.         wire [7:0] dat;
  10.         wire [3:0] rdrxd;
  11.         wire [3:0] rxfull;
  12.         wire [3:0] rxempty;
  13.         wire [3:0] rxhfull;
  14.         uart8n1_ctrl ctrl(
  15.                 .rst(rst),
  16.                 .clk(clk),
  17.                 .rxhfull(rxhfull),
  18.                 .txhfull(txhfull),
  19.                 .txen(txen),
  20.                 .rdrxd(rdrxd)
  21.                 );
  22.         uart8n1_rx rx1(
  23.                 .rst(rst),
  24.                 .clk(clk),
  25.                 .rxd(rxd[0]),
  26.                 .rxen(true),
  27.                 .divp(50_000_000/115_200), //fclk/baud
  28.                 .rdrxd(rdrxd[0]),
  29.                 .dat(dat),
  30.                 .rxfull(rxfull[0]),
  31.                 .rxempty(rxempty[0]),
  32.                 .rxhfull(rxhfull[0])
  33.                 );
  34.         uart8n1_rx rx2(
  35.                 .rst(rst),
  36.                 .clk(clk),
  37.                 .rxd(rxd[1]),
  38.                 .rxen(true),
  39.                 .divp(50_000_000/115_200), //fclk/baud
  40.                 .rdrxd(rdrxd[1]),
  41.                 .dat(dat),
  42.                 .rxfull(rxfull[1]),
  43.                 .rxempty(rxempty[1]),
  44.                 .rxhfull(rxhfull[1])
  45.                 );
  46.         uart8n1_rx rx3(
  47.                 .rst(rst),
  48.                 .clk(clk),
  49.                 .rxd(rxd[2]),
  50.                 .rxen(true),
  51.                 .divp(50_000_000/115_200), //fclk/baud
  52.                 .rdrxd(rdrxd[2]),
  53.                 .dat(dat),
  54.                 .rxfull(rxfull[2]),
  55.                 .rxempty(rxempty[2]),
  56.                 .rxhfull(rxhfull[2])
  57.                 );
  58.         uart8n1_rx rx4(
  59.                 .rst(rst),
  60.                 .clk(clk),
  61.                 .rxd(rxd[3]),
  62.                 .rxen(true),
  63.                 .divp(50_000_000/115_200), //fclk/baud
  64.                 .rdrxd(rdrxd[3]),
  65.                 .dat(dat),
  66.                 .rxfull(rxfull[3]),
  67.                 .rxempty(rxempty[3]),
  68.                 .rxhfull(rxhfull[3])
  69.                 );
  70.         uart8n1_tx tx(
  71.                 .rst(rst),
  72.                 .clk(clk),
  73.                 .dat(dat),
  74.                 .txen(txen),
  75.                 .divp(50_000_000/115_200),  //fclk/baud
  76.                 .txd(txd),
  77.                 .txfull(txfull),
  78.                 .txempty(txempty),
  79.                 .txhfull(txhfull)
  80.                 );
  81. endmodule
复制代码

出0入0汤圆

 楼主| 发表于 2013-7-3 19:24:55 | 显示全部楼层

  1. module uart8n1_ctrl(
  2.         input rst,
  3.         input clk,
  4.         input [3:0] rxhfull,
  5.         input txhfull,
  6.         output txen,
  7.         output [3:0] rdrxd
  8.         );
  9.         parameter true = 1'b0, false = 1'b1;
  10.         reg txe = false;
  11.         assign txen = txe;
  12.         reg [3:0]rdd = 4'hf;
  13.         assign rdrxd = rdd;
  14.         reg [2:0]ctrstate = IDLE;
  15.         parameter IDLE = 3'h0, RD0 = 3'h1, RD1 = 3'h2, RD2 = 3'h3, RD3 = 3'h4;
  16.         reg [1:0]statetrans1 = 2'b0;
  17.         parameter RDRXFIFO = 2'd0, WRTXFIFO = 2'd1, BYTECNT = 2'd2;
  18.         reg [1:0]bytecnt = 2'b0;
  19.         task trans4bytes;
  20.                 input [1:0]chl;
  21.                 case(statetrans1)
  22.                         RDRXFIFO: begin
  23.                                 rdd[chl] <= true;
  24.                                 statetrans1 <= 2'd1;
  25.                                 end
  26.                         WRTXFIFO: begin
  27.                                 txe <= true;
  28.                                 statetrans1 <= 2'd2;
  29.                                 end
  30.                         BYTECNT: begin
  31.                                 txe <= false;
  32.                                 rdd[chl] <= false;
  33.                                 if(bytecnt == 2'd3) begin
  34.                                         ctrstate <= IDLE;
  35.                                         end
  36.                                 else begin
  37.                                         bytecnt <= bytecnt + 1'b1;
  38.                                         statetrans1 <= RDRXFIFO;
  39.                                         end
  40.                                 end
  41.                 endcase
  42.         endtask
  43.         always @(posedge clk or negedge rst) begin
  44.                 if(rst == true) begin
  45.                         rdd <= {4{false}};
  46.                         txe <= false;
  47.                         ctrstate <= IDLE;
  48.                         end
  49.                 else begin
  50.                         case(ctrstate)
  51.                                 IDLE: begin
  52.                                         rdd <= {4{false}};
  53.                                         txe <= false;
  54.                                         bytecnt <= 2'd0;
  55.                                         statetrans1 <= RDRXFIFO;
  56.                                         if(rxhfull[0] == true) begin ctrstate <= RD0; end
  57.                                         else if(rxhfull[1] == true) begin ctrstate <= RD1; end
  58.                                         else if(rxhfull[2] == true) begin ctrstate <= RD2; end
  59.                                         else if(rxhfull[3] == true) begin ctrstate <= RD3; end
  60.                                         else begin ctrstate <= IDLE; end
  61.                                         end
  62.                                 RD0: begin trans4bytes(0); end
  63.                                 RD1: begin trans4bytes(1); end
  64.                                 RD2: begin trans4bytes(2); end
  65.                                 RD3: begin trans4bytes(3); end
  66.                         endcase
  67.                         end
  68.                 end
  69. endmodule
复制代码

出0入0汤圆

 楼主| 发表于 2013-7-3 19:25:23 | 显示全部楼层

  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.         output rxhfull
  12.         );
  13.         parameter true = 1'b0, false = 1'b1;
  14.         reg [7:0] rxdata = 8'b0;
  15.         wire [7:0] rxdat = rxdata;
  16.         reg dready = false;
  17.         wire ien = dready;
  18.         wire rxdlpo;
  19.         reg [15:0] divcnt = 16'b0;
  20.         reg [2:0] bitcnt = 3'b0;
  21.         reg [1:0] rxstate = IDLE;
  22.         parameter IDLE = 2'h0, RXSTART = 2'h1, RXDATBITS = 2'h2, RXSTOP = 2'h3;
  23.         fifo8x8 rxfifo(
  24.                 .rst(rst),
  25.                 .ien(ien),
  26.                 .oen(rdrxd),
  27.                 .idat(rxdat),
  28.                 .odat(dat),
  29.                 .full(rxfull),
  30.                 .empty(rxempty),
  31.                 .hfull(rxhfull)
  32.                 );
  33.         lowpass lp(
  34.                 .clk(clk),
  35.                 .lin(rxd),
  36.                 .lout(rxdlpo)
  37.                 );
  38.         always @ (posedge clk or negedge rst) begin
  39.                 if(rst == 1'b0) begin
  40.                         dready <= false;
  41.                         divcnt <= 16'b0;
  42.                         rxstate <= IDLE;
  43.                         end
  44.                 else begin
  45.                         case(rxstate)
  46.                                 IDLE: begin
  47.                                         dready <= false;
  48.                                         if(rxen == true && rxdlpo == 1'b0) begin
  49.                                                 divcnt <= 16'b0;
  50.                                                 rxstate <= RXSTART;
  51.                                                 end
  52.                                         end
  53.                                 RXSTART: begin
  54.                                         if(divcnt == divp[15:1]) begin
  55.                                                 divcnt <= 16'b0;
  56.                                                 if(rxdlpo == 1'b0) begin
  57.                                                         bitcnt <= 3'b0;
  58.                                                         rxstate <= RXDATBITS;
  59.                                                         end
  60.                                                 else begin
  61.                                                         rxstate <= IDLE;
  62.                                                         end
  63.                                                 end
  64.                                         else begin
  65.                                                 divcnt <= divcnt + 1'b1;
  66.                                                 end
  67.                                         end
  68.                                 RXDATBITS: begin
  69.                                         if(divcnt == divp) begin
  70.                                         //        rxdata <= {rxdlpo,rxdata[7:1]}; //Lsb first
  71.                                                 rxdata <= {rxdata[6:0],rxdlpo}; //Msb first
  72.                                                 divcnt <= 16'b0;
  73.                                                 if(bitcnt == 3'h7) begin
  74.                                                         bitcnt <= 3'b0;
  75.                                                         rxstate <= RXSTOP;
  76.                                                         end
  77.                                                 else begin
  78.                                                         bitcnt <= bitcnt + 1'b1;
  79.                                                         end
  80.                                                 end
  81.                                         else begin
  82.                                                 divcnt <= divcnt + 1'b1;
  83.                                                 end
  84.                                         end
  85.                                 RXSTOP: begin
  86.                                         if(divcnt == divp) begin
  87.                                                 divcnt <= 16'b0;
  88.                                                 rxstate <= IDLE;
  89.                                                 if(rxdlpo == 1'b1) begin
  90.                                                         dready <= true;
  91.                                                         end
  92.                                                 end
  93.                                         else begin
  94.                                                 divcnt <= divcnt + 1'b1;
  95.                                                 end
  96.                                         end
  97.                         endcase
  98.                         end
  99.                 end
  100. endmodule
复制代码

出0入0汤圆

 楼主| 发表于 2013-7-3 19:25:40 | 显示全部楼层

  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.         output txhfull
  11.         );
  12.         parameter true = 1'b0, false = 1'b1;
  13.         wire [7:0] txdat;
  14.         reg rdfifo = false;
  15.         wire oen = rdfifo;
  16.         reg [15:0] divcnt = 16'b0;
  17.         reg [2:0] bitcnt = 3'b0;
  18.         reg [1:0] txstate = IDLE;
  19.         parameter IDLE = 2'h0, TXSTART = 2'h1, TXDATBITS = 2'h2, TXSTOP = 2'h3;
  20.         fifo8x8 txfifo(
  21.                 .rst(rst),
  22.                 .ien(txen),
  23.                 .oen(oen),
  24.                 .idat(dat),
  25.                 .odat(txdat),
  26.                 .full(txfull),
  27.                 .empty(txempty),
  28.                 .hfull(txhfull)
  29.                 );
  30.         always @ (posedge clk or negedge rst) begin
  31.                 if(rst == 1'b0) begin
  32.                         txd <= 1'b1;
  33.                         rdfifo <= false;
  34.                         txstate <= IDLE;
  35.                         end
  36.                 else begin
  37.                         case(txstate)
  38.                                 IDLE: begin
  39.                                         txd <= 1'b1;
  40.                                         if(txempty == false) begin
  41.                                                 divcnt <= 16'b0;
  42.                                                 txstate <= TXSTART;
  43.                                                 end
  44.                                         end
  45.                                 TXSTART: begin
  46.                                         txd <= 1'b0;
  47.                                         rdfifo <= true;
  48.                                         if(divcnt == divp) begin
  49.                                                 divcnt <= 16'b0;
  50.                                                 bitcnt <= 3'b0;
  51.                                                 txstate <= TXDATBITS;
  52.                                                 end
  53.                                         else begin
  54.                                                 divcnt <= divcnt + 1'b1;
  55.                                                 end
  56.                                         end
  57.                                 TXDATBITS: begin
  58.                                 //        txd <= txdat[bitcnt]; //Lsb first
  59.                                         txd <= txdat[3'h7 - bitcnt]; //Msb first
  60.                                         if(divcnt == divp) begin
  61.                                                 divcnt <= 16'b0;
  62.                                                 if(bitcnt == 3'd7) begin
  63.                                                         bitcnt <= 3'b0;
  64.                                                         txstate <= TXSTOP;
  65.                                                         end
  66.                                                 else begin
  67.                                                         bitcnt <= bitcnt + 1'b1;
  68.                                                         end
  69.                                                 end
  70.                                         else begin
  71.                                                 divcnt <= divcnt + 1'b1;
  72.                                                 end
  73.                                         end
  74.                                 TXSTOP: begin
  75.                                         txd <= 1'b1;
  76.                                         rdfifo <= false;
  77.                                         if(divcnt == divp) begin
  78.                                                 divcnt <= 16'b0;
  79.                                                 txstate <= IDLE;
  80.                                                 end
  81.                                         else begin
  82.                                                 divcnt <= divcnt + 1'b1;
  83.                                                 end
  84.                                         end
  85.                         endcase
  86.                         end
  87.                 end
  88. endmodule
复制代码

出0入0汤圆

 楼主| 发表于 2013-7-3 19:26:02 | 显示全部楼层

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

出0入0汤圆

 楼主| 发表于 2013-7-3 19:26:17 | 显示全部楼层

  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-7-3 19:32:31 | 显示全部楼层
为方便大家下载引用,打包工程代码如下,请勿用于商业用途,用于教程或出版请联系本人。

本帖子中包含更多资源

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

x

出0入0汤圆

 楼主| 发表于 2013-7-3 21:05:54 | 显示全部楼层
发送通道的FIFO可以省了,直接对接对应接收通道的FIFO就可以,可以节省不少资源。

出0入0汤圆

 楼主| 发表于 2013-7-3 21:08:05 | 显示全部楼层
只要资源足够,可以扩展到N通道,代码扩展很方便。

出0入0汤圆

 楼主| 发表于 2013-7-3 21:12:05 | 显示全部楼层
4RX、1TX加调度代码只占用700多个LE。

出0入0汤圆

发表于 2013-7-3 22:26:40 | 显示全部楼层
非常不错的思路,值得学习一下

出0入0汤圆

发表于 2013-7-4 07:58:22 | 显示全部楼层
感谢skyxjh 。

出0入0汤圆

发表于 2013-7-4 09:51:12 | 显示全部楼层
顶起,向skyxjh学习。

出0入0汤圆

发表于 2013-7-5 16:53:25 | 显示全部楼层
学习!!!!!!!!!!

出0入0汤圆

发表于 2013-7-18 10:52:16 | 显示全部楼层
参考学习一下设计思路

出0入0汤圆

发表于 2015-3-1 15:06:56 | 显示全部楼层
4收1发用在什么地方?

出0入0汤圆

发表于 2015-3-1 15:24:52 | 显示全部楼层
这个可以用在哪些方面

出10入12汤圆

发表于 2018-11-9 20:52:37 | 显示全部楼层
采样倍数是多少?

出10入12汤圆

发表于 2018-11-16 13:48:37 | 显示全部楼层
丢包吗????????

出0入0汤圆

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

本版积分规则

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

GMT+8, 2024-4-29 13:51

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

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