【verilog】UART串口发送(FPGA)

2023-05-16

  • 简述
  • 核心代码
  • 仿真测试

简述

串口发送是以一定速率发送单bit数据,通常一组数据为10bit。空闲状态为高电平,起始位为0,中间以低位在前的方式发送8bit数据,终止位为1。
采用计数器 [cnt_baud] 对系统时钟进行计数,计满值即为预设的波特率值 [baud_num]
在这个计数过程中,每当计数值为1时,就产生一个标志值 [flag1]
采用计数器 [cnt_for_flag1] 对flag1进行计数11次,当计数值达到11时,同步清零。
所以cnt_for_flag1 = 11 只能维持1个系统时钟,并不能维持一个baud_num。
能维持一个baud_num的为计数值1~10。利用cnt_for_flag1作为多路器的选择端分别发送出10个bit的数据。
当cnt_for_flag1值为11时,代表一次发送完成,产生done信号。

核心代码

module ser_tx(data,en,clk,rst,tx,done);
    input [7:0] data;
    input en;
    input clk;
    input rst;

    output reg tx;
    output reg done;

    reg [15:0] baud_num = 16'd5207; //5207=9600、2603=19200、1301=38400、867=57600、433=115200

    /*将引脚 <input [7:0] data> 进行一级寄存 -> reg_data*/
    reg [7:0]reg_data;   
    always@(posedge clk or negedge rst) begin
        if(!rst)
            reg_data <= 8'b0;
        else if(en)begin 
            reg_data <= data;     
        end                  
        else
            reg_data <= data;
    end

    /*计数器:0~5207~0~5207....*/
    reg [15:0]cnt_baud;
    always@(posedge clk or negedge rst)
    begin
        if(!rst)
            cnt_baud <= 1'b0;
        else if(cnt_baud == baud_num)
            cnt_baud <= 1'b0;
        else
            cnt_baud <= cnt_baud + 1'b1;          
    end

    /*0~5207这个过程中,每当计数到1的时候就产生一个flag*/
    reg flag1;
    always@(posedge clk or negedge rst)
    begin
        if(!rst)
            flag1 <= 1'b0;
        else if(cnt_baud == 16'd1)
            flag1 <= 1'b1;
        else
            flag1 <= 1'b0;         
    end

    /*对flag1进行计数,计数11次,但11只能维持1个clk,并不能维持9600bps,然后就被清0*/
    reg [3:0] cnt_for_flag1;
    always@(posedge clk or negedge rst)
    begin
        if(!rst)
            cnt_for_flag1 <= 1'b0;
        else if(cnt_for_flag1 == 4'd11)
            cnt_for_flag1 <= 1'b0;    
        else if(flag1 == 1'd1)
            cnt_for_flag1 <= cnt_for_flag1 + 1'b1;
        else
            cnt_for_flag1 <= cnt_for_flag1;
    end


    /*依次发送起始位、数据位、终止位*/
    always@(posedge clk or negedge rst)
    begin
        if(!rst)
        tx <= 1'd1; //根据时序图,tx的闲时状态是高电平。
        else
            begin
                case (cnt_for_flag1)
                    4'd0: tx <= 1'd1;  //空闲状态
                
                    4'd1: tx <= 1'd0;  //起始位
                
                    4'd2: tx <= reg_data[0]; //低位在前
                    4'd3: tx <= reg_data[1]; 
                    4'd4: tx <= reg_data[2];    
                    4'd5: tx <= reg_data[3]; 
                    4'd6: tx <= reg_data[4]; 
                    4'd7: tx <= reg_data[5]; 
                    4'd8: tx <= reg_data[6]; 
                    4'd9: tx <= reg_data[7]; 

                    4'd10: tx <= 1'd1; //终止位
                    default:tx <= 1'd1;//空闲状态
                endcase               
            end
     end

    //每次计数器“cnt_for_flag1”值为11时,代表一次发送完成,产生done信号。
    always@(posedge clk or negedge rst) begin
        if(!rst)
            done <= 1'd0;
        else if(cnt_for_flag1 == 4'd11) //cnt_to_10计数到11自动清零
            done <= 1'd1;                 
        else
            done <= 1'd0;
    end

endmodule

仿真测试

发送8bit的 data1 = 8’b01001101 作为测试!

`timescale 1ns/1ns
module ser_tx_tb;

    reg [7:0] data1;
    reg en1;
    reg clk1;
    reg rst1;

    wire  tx1;
    wire  done1;

    
    ser_tx txer
                (
                .data(data1),
                .en(en1),
                .clk(clk1),
                .rst(rst1),
                .tx(tx1),
                .done(done1)
                );

    initial clk1 = 1'b1;
    always#10 clk1 = ~clk1;

    initial begin
    rst1 = 1'b0;    //未运行状态

    #400;
    rst1 = 1'b1;

    data1 = 8'b01001101;

    en1 = 1;
    #20;//一个时钟周期
    en1 = 0;

    #4000000;

     $stop;

    end
endmodule

在这里插入图片描述

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【verilog】UART串口发送(FPGA) 的相关文章

  • 使用forever和always语句

    以下两个代码都会生成一个时钟 我需要知道除了时钟生成之外 永远循环是否还有其他用途 我只在时钟一代中遇到过永远 如果只是为了这个目的 那岂不是毫无用处 initial begin clk 0 forever begin 5 clk clk
  • 使用 Verilator 和 VPI 读取寄存器数组

    所以我在我的verilog中定义了以下寄存器 reg 31 0 register mem 0 15 verilator public 我的目标是从我的 verilator c 代码中读取存储在其中的 16 个值中的每一个 我发现有关 VPI
  • 「HDLBits题解」Gates4

    本专栏的目的是分享可以通过HDLBits仿真的Verilog代码 以提供参考 各位可同时参考我的代码和官方题解代码 或许会有所收益 题目链接 Gates4 HDLBits module top module input 3 0 in out
  • VHDL 中的 BRAM_INIT

    我正在模拟基于处理器的设计 其中程序存储器内容保存在 BRAM 中 我正在使用 VHDL 推断 BRAM 实现程序存储器 我试图避免使用 CoreGen 因为我想保持设计的可移植性 最终该设计将进入 FPGA 我想看看是否有一种方法可以使用
  • 如何使用 Verilog 和 FPGA 计算一系列组合电路的传播延迟?

    我是 FPGA 和 HDL 的新手 但我正在尝试学习 但无法弄清楚这一点 如何通过多个级别的组合逻辑来计算或估计传播延迟 我可以仅凭经验确定这一点 还是可以在设计时弄清楚 在这种情况下 我使用 FPGA 来实现奇偶校验设置和检查电路 该电路
  • Verilog 中的“net”代表什么?

    我刚刚开始学习Verilog 据我了解 Verilog有net数据类型 什么是net代表 网络就是这样一种数据类型 您不使用它来存储值 它们代表物理连接 您可以将线路视为一种网络数据类型 你可以去网上看看更多here http www ee
  • 如何使用 don't cares 参数化 case 语句?

    我有一条称为输入的电线 我想检测前导的数量 我正在尝试创建一个模块 该模块使用下面的 case 语句根据前导零的数量更改输出数据 然而 输入的大小是可参数化的 如果 X 是固定值 4 我将创建一个 case 语句 case input 4
  • 通过 USB 模拟 UART

    有谁知道是否可以通过 USB 模拟 UART 简单串行发送和接收 这将如何实现 我在 Microchip 网站上找到了这个链接 但不是很容易找到 http www microchip com forums m522571 print asp
  • 向左旋转 verilog 大小写

    我的任务是用verilog编写一个16位ALU 当我做需要旋转操作数和进行2的补码加法和减法的部分时 我发现了困难 我知道如何用纸和铅笔解决这个问题 但我无法弄清楚如何在 Verilog 中做到这一点 例如 A表示为a15 a14 a13
  • FPGA大输入数据

    我正在尝试向 FPGA 发送 4 KB 字符串 最简单的方法是什么 是我正在使用的fpga的链接 我正在使用 Verilog 和 Quartus 您的问题的答案在很大程度上取决于将数据输入 FPGA 的内容 即使没有您需要遵守的特定协议 S
  • 为什么 Verilog 不被视为编程语言? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 教授在课堂上说学生不应该说他们学会了用Verilog 编程 他说 Verilog 之类的东西不是用来编程的 而是用来设计的 那么 Verilog
  • 标识符必须用端口模式声明:busy。 (Verilog)

    我有如下所示的 Verilog 代码 当我编译它时 我收到以下错误消息 并且代码的第一行突出显示 Error 标识符必须用端口模式声明 busy Code module main clk rst start busy ready cnt s
  • 如何从 Spartan 6 写入 Nexys 3 FPGA 板上的 Micron 外部蜂窝 RAM?

    我到处都查过了 数据表 Xilinx 网站 digilent 等等 但什么也没找到 我能够使用 Adept 工具来验证我的蜂窝 RAM 是否正常运行 但我找不到任何库存 VHDL 代码作为控制器来写入数据和从中读取数据 帮助 找到了此链接
  • Verilog 中的大括号是什么意思?

    我很难理解 Verilog 中的以下语法 input 15 0 a 16 bit input output 31 0 result 32 bit output assign result 16 a 15 a 15 0 我知道assign语句
  • VIM 高亮匹配开始/结束

    我正在尝试找到一个插件 它将突出显示与 Verilog 匹配的开始 结束语句 VIM 可以使用花括号 方括号 但不能使用它的开始 结束 我希望 VIM 突出显示正确的开始到正确的结束 在我看来 最好的选择是使用 matchit 该脚本是 v
  • 我怎样才能让我的verilog移位器更通用?

    这里我有一个移位器 但现在它最多只能工作 3 位 我一直在寻找 但不知道如何让它工作最多 8 位 module shifter a b out input 7 0 a b output 7 0 out wire 7 0 out1 out2
  • 系统 verilog 中没有类型的输入

    我在一个系统 verilog 代码的输入和输出的示例中遇到过module没有说明它们的类型 例如logic wire module mat to stream input 2 0 2 0 2 0 a b input newdata inpu
  • 具有内部赋值延迟的阻塞和非阻塞语句之间的区别

    以下 2 个 verilog 代码片段有什么区别 1 always in out 5 in AND 2 always in out lt 5 in 考虑到always块中不存在其他行 输出会有什么不同吗 问题参考幻灯片 16 参见 o5 和
  • Verilog 数组语法

    我是 Verilog 新手 并且遇到了很多麻烦 例如 我想要一个包含八个单元的数组 每个单元都是 8 位宽 以下不起作用 reg 7 0 transitionTable 0 7 assign transitionTable 0 10 仅仅做
  • 可以购买哪些 FPGA(现场可编程门阵列)在家中进行实验? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 什么是 FPGA 在哪里可以买到 它们要花多少钱 您需要什么样的系统来试验它们 如何对它们进行编程 如果这是正确的术语 您能否使用普通 M

随机推荐

  • MyMatrix(二维矩阵类)实现

    二维矩阵类 xff08 MyMatrix xff09 说明文档 一 MyMatrix 类的组成 1 1 私有成员 int row 二维矩阵行数 int col 二维矩阵列数 T data 二维矩阵数据 1 2 共有成员 1 2 1 构造与析
  • 基于CUDA和TCP通信的大数据双机加速计算(CUDA加速、内存优化、TCP多机协同)

    1 环境 技术简介 1 1 程序运行环境 1 server端计算机 操作系统 xff1a Ubuntu 18 04 5 LTS 运行环境 xff1a VSCode或Bash终端 2 client端计算机 操作系统 xff1a Ubuntu
  • RGB888转换为RGB565格式

    RGB888转换为RGB565格式 RGB888用unsigned int 32位字节存储 00000000R7 R6 R5 R4 R3 R2 R1 R0 G7 G6 G5 G4 G3 G2 G1 G0 B7 B6 B5 B4 B3 B2
  • Keil5界面配置

    配置一 xff1a 绿色 Specification for text selection and caret line selection fore 61 00FFFF selection back 61 004000 caret for
  • Linux内核调试环境(centos+gdb+qemu)

    一 写在前面 主要介绍qemu在Centos中的安装过程 xff0c 以及遇到的一些麻烦 网上教程好多都是在Ubuntu环境下的安装 xff0c 但是公司给的环境大都是Centos xff0c 没办法花了一天的时间 xff0c 磕磕绊绊弄好
  • Linux中修改系统启动项grub

    在修改grub时看到很多资料 xff0c 上来就是直接修改 etc default grub配置文件中的GRUB DEFAULT配置项 xff0c 但是有时候修改不成功 xff0c 本文简单说明一下修改的原理 注 xff1a 根据本人机器上
  • C语言调用cJSON库解析json

    一 源代码文件下载 自己使用时可以只需要其中的cJSON c和cJSON h文件就可以了 xff0c 只需要将cJSON和自己的main文件一起编译即可 下载地址 xff1a cJSONFiles zip 互联网文档类资源 CSDN下载 二
  • Java学习记录 (一)

    使用 BufferedReader 按行读入文档内容 InputStream input file span class token operator 61 span null span class token punctuation sp
  • cmake学习5:如何将自己的库作为第三方库给别人使用

    前言 自己在使用cmake进行编译工程的时候不太了解cmake的基本使用方法 有时候出现找不到第三方库的问题也不知如何排查 因此相对cmake有个稍微系统的认识 希望能用这个强大的工具来更好的为自己的工程服务 因此总结为了几篇博客 主要参考
  • C++头文件包含顺序

    Google C 43 43 编程风格指南 对于头文件的包含顺序是这样的 xff1a Names and Order of Includes link Use standard order for readability and to av
  • VLC Web插件踩坑记录

    VLC Web插件 问题描述 近期由于工作项目组人员变动 xff0c 来到新的项目组 xff0c Leader约谈前期也不安排过多任务 xff0c 但是有一个项目中现有的问题需要解决 项目中视频在线播放功能需要支持在线播放 avi媒体格式
  • cmake添加第三方库

    主要方法 将包含目录添加到构建中 span class token function include directories span span class token punctuation span D span class token
  • UART+DMA数据传输

    DMA的概念 DMA xff08 Direct Memory Access xff09 即直接内存访问 xff0c DMA传输方式无需CPU直接控制传输 xff0c 通过硬件为RAM I O设备开辟一条直接传输数据的通路 xff0c 能使C
  • asp.net core 3.1 应用部署到国产服务器 centos7 自动启动

    首先安装依赖 xff1a 注册 Microsoft 密钥 注册产品存储库 安装必需的依赖项 sudo rpm Uvh https packages microsoft com config centos 7 packages microso
  • Visual Studio2022 离线安装包下载

    首先去官网下载引导程序 xff1a https docs microsoft com en us visualstudio install create an offline installation of visual studio vi
  • MWC-电机、电池螺旋桨搭配

    原址 xff1a http blog sina com cn s blog 402c071e0102v2xv html 电池 电机 螺旋桨搭配 1 电机 1 电机KV值 xff1a 大KV配小桨 xff0c 小KV配大桨 KV值是每1V的电
  • linux系统发送http请求示例:

    http post示例 xff1a curl H 34 Content Type application json 34 X POST d 39 34 ChannelInfo 34 34 algoList 34 34 CarDetectio
  • 博途的多步过程控制, 寄存器寻址

    1 xff0c 实际生产中 xff0c 收到的开关信号往往是短信号 脉冲 2 Step 变化的逻辑和设备的逻辑分开 Step的变化逻辑在实际中往往是设备的反馈信号决定 xff0c 在此处用定时器信号代替 定时器的触发用Step的状态触发 x
  • 栈、堆、方法区存储的内容

    堆区 1 存储的全部是对象 xff0c 每个对象都包含一个与之对应的class的信息 class的目的是得到操作指令 2 jvm只有一个堆区 heap 被所有线程共享 xff0c 堆中不存放基本类型和对象引用 xff0c 只存放对象本身 栈
  • 【verilog】UART串口发送(FPGA)

    简述核心代码仿真测试 简述 串口发送是以一定速率发送单bit数据 xff0c 通常一组数据为10bit 空闲状态为高电平 xff0c 起始位为0 xff0c 中间以低位在前的方式发送8bit数据 xff0c 终止位为1 采用计数器 cnt