UART通讯模块设计Verilog代码vivado仿真

名称:UART通讯模块设计Verilog代码vivado仿真(文末获取)

软件:vivado

语言:Verilog

代码功能:

具体要求如下:

1.分组进行设计实践,每组10~11人,组内人员自行分工开发任务:模块开发与testbench仿真验证。

2.技术参数要求:

用户收发数据位宽:8bit;

用户时钟:100MHz

数据发送缓存:不小于4KByte;

附加功能:串行波特率可配;是否添加校验位可配

3.通讯控制模块对外接口约定如下:

module uart_intf#

(

    parameter   BaudRate        =   868                         ,   //波特率:时钟/波特率,如:100Mhz,115200bps,100_000000/115200 = 868

    parameter   CheckMode       =   0                           ,   //奇偶校验:0-无,1-奇校验(ODD),2-偶校验(EVEN),3-高校验,4-低校验

    parameter   BitNum          =   8                           )   //数据位宽度

(

    input   wire    [00:00]     uart_refclk                     ,

    input   wire    [00:00]     uart_refrst                     ,

    input   wire    [00:00]     uart_txdata_en                  ,

    input  wire  [BitNum - 1:00]     uart_txdata                     ,

    output  wire    [00:00]     uart_rxdata_en                  ,

    output wire  [BitNum - 1:00]     uart_rxdata                     ,

    input   wire    [00:00]     uart_rx_sig                     ,

    output  wire    [00:00]     uart_tx_sig                     );

1. 工程文件

2. 程序文件

3. 程序编译

4. RTL图

5. Testbench

6. 仿真图

整体仿真图

将发送接收回环,依次发送0x24,0x3a,0x19,接收到的也为0x24,0x3a,0x19。故发送接收正确。

波特率控制模块

FIFO模块

串口发送模块

接收串口模块

部分代码展示:

module my_uart_rx(clk,rst_n,rs232_rx,clk_bps,rx_data,rx_en);
input clk;// 100MHz主时钟
input rst_n;//低电平复位信号
input rs232_rx;// RS232接收数据信号
input clk_bps;// clk_bps的高电平为接收或者发送数据位的中间采样点
output[7:0] rx_data;//接收数据寄存器,保存直至下一个数据来到 
output rx_en;//接收数据有效
//----------------------------------------------------------------
reg rs232_rx0,rs232_rx1,rs232_rx2;//接收数据寄存器,滤波用
wire neg_rs232_rx;//表示数据线接收到下降沿
always @ (posedge clk or negedge rst_n) begin
if(!rst_n) begin
rs232_rx0 <= 1'b1;
rs232_rx1 <= 1'b1;
rs232_rx2 <= 1'b1;
end
else begin
rs232_rx0 <= rs232_rx;
rs232_rx1 <= rs232_rx0;
rs232_rx2 <= rs232_rx1;
end
end
assign neg_rs232_rx = rs232_rx2 & ~rs232_rx1;//接收到下降沿后neg_rs232_rx置高一个时钟周期
//----------------------------------------------------------------
reg[3:0]num;//移位次数
reg rx_int;//接收数据中断信号,接收到数据期间始终为高电平
always @ (posedge clk or negedge rst_n) begin
if(!rst_n) begin
rx_int <= 1'b0;
end
else if(neg_rs232_rx) begin
rx_int <= 1'b1;//接收数据中断信号使能
end
else if(num==4'd11) begin
rx_int <= 1'b0;//接收数据中断信号关闭
end
end 
//----------------------------------------------------------------
reg[7:0] rx_data_r;//接收数据寄存器,保存直至下一个数据来到
//----------------------------------------------------------------
reg[7:0]rx_temp_data;//但前接收数据寄存器
reg rx_data_shift;//数据移位标志
always @ (posedge clk or negedge rst_n) begin
if(!rst_n) begin
rx_data_shift <= 1'b0;
rx_temp_data <= 8'd0;
num <= 4'd0;
rx_data_r <= 8'd0;
end
else if(rx_int) begin//接收数据处理
if(clk_bps) begin//读取并保存数据,接收数据为一个起始位,8bit数据,一个结束位
rx_data_shift <= 1'b1;
num <= num+1'b1;
if(num<=4'd8) rx_temp_data[7] <= rs232_rx;//锁存9bit(1bit起始位,8bit数据)
end
else if(rx_data_shift) begin//数据移位处理
rx_data_shift <= 1'b0;
if(num<=4'd8) rx_temp_data <= rx_temp_data >> 1'b1;//移位8次,第1bit起始位移除,剩下8bit正好时接收数据
else if(num==4'd11) begin
num <= 4'd0;//接收到STOP位后结束,num清零
rx_data_r <= rx_temp_data;//把数据锁存到数据寄存器rx_data中
end
end
   end
end
reg rx_int_buf=0;
always @ (posedge clk ) begin
rx_int_buf<=rx_int;
end
assign rx_en= rx_int_buf & (~rx_int);//rx_int下降沿
assign rx_data = rx_data_r;//数据
endmodule
源代码

 扫描文章末尾的公众号二维码

  • 16
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的 Verilog 实现 UART 控制模块代码示例: ```verilog module uart( input clk, // 时钟信号 input reset, // 复位信号 input rx, // 接收端口 output reg tx // 发送端口 ); parameter BAUD_RATE = 9600; // 波特率 parameter COUNT_MAX = $ceil($log10($timeunit * $timescale * BAUD_RATE)); // 计数器最大值 reg [7:0] data; // 数据寄存器 reg [3:0] count; // 计数器 reg [3:0] bit_count; // 位计数器 reg start_bit; // 起始位标志 reg stop_bit; // 停止位标志 always @ (posedge clk) begin if (reset) begin data <= 8'b0; count <= 4'd0; bit_count <= 4'd0; start_bit <= 0; stop_bit <= 1; tx <= 1; end else begin // 发送模式 if (count > 0) begin if (bit_count == 4'd0) begin // 起始位 tx <= 0; start_bit <= 1; end else if (bit_count == 4'd9) begin // 停止位 tx <= 1; stop_bit <= 1; count <= count - 1; end else begin // 数据位 tx <= data[bit_count - 1]; end bit_count <= bit_count + 1; // 接收模式 end else begin if (start_bit && !rx) begin // 起始位 bit_count <= 4'd1; start_bit <= 0; stop_bit <= 0; end else if (!start_bit && bit_count < 4'd9) begin // 数据位 data[bit_count - 1] <= rx; bit_count <= bit_count + 1; end else if (!start_bit && bit_count == 4'd9) begin // 停止位 stop_bit <= 1; count <= COUNT_MAX; bit_count <= 4'd0; end end end end // 发送数据 task send; input [7:0] value; begin data <= value; count <= COUNT_MAX; end endtask endmodule ``` 在这个模块中,我们实现了一个简单的串口发送和接收控制器,可以根据需要进行调整和扩展。 由于 Verilog 是硬件描述语言,无法直接运行,因此需要使用仿真工具来验证代码的正确性。常见的仿真工具有 ModelSim、Xilinx ISE、Vivado 等,其中 ModelSim 是比较常用的仿真工具。 以下是一个简单的 UART 仿真测试代码示例,用于测试发送和接收功能: ```verilog module uart_tb; reg clk; reg reset; reg rx; wire tx; uart dut(.clk(clk), .reset(reset), .rx(rx), .tx(tx)); initial begin clk <= 0; reset <= 1; rx <= 1; #1 reset <= 0; #1 rx <= 0; // 发送测试 dut.send(8'h41); // 发送字符 A #100 dut.send(8'h42); // 发送字符 B // 接收测试 #200 rx <= 1; #300 rx <= 0; #400 rx <= 1; #500 rx <= 1; #600 rx <= 0; #700 rx <= 1; #800 $finish; end always #5 clk <= ~clk; endmodule ``` 该测试代码通过使用 `uart` 模块的 `send` 任务向串口发送字符 A 和 B,并通过改变 `rx` 输入端口的值来模拟接收字符。可以根据需要进行调整和扩展。 完整的代码可以在以下网页地址中找到: https://github.com/AspenLuoQiyuan/Verilog-UART-Control-Module

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值