VHDL串口程序

合集下载

基于VHDL语言的同步串口设计

基于VHDL语言的同步串口设计

F GA T ec c iSt n eu nes l i scmpee nQur sI. h nefc i ut ycn g r g te P , h i ut migsq ec i a o i o l di at I T eit aec ci b o f ui r ’i mu t n t u r r i n h
1 NP l NM DI N
O T U P OU M T
D OU T T V 2AC 0 F L 3 0 I 1 S S L C K
M92 0 50 0
作者简 介;徐 奎 ( 8 一 ) 男,研 究 1 1 , 9 方向:数 字通信 。朱晓明 ( 9 l ) 1 6 一 ,男, 高工。研 究方向:数字通信 。
2 T V 2 A 0 0芯片工作原理 L 3 0 11
由图 1 可知, L 3 0 I 1 进行 串行通信时使 T V 2A C 0
用4 个管脚 :D N、D U 、F 、S L . I 和 I O T S C K 。D N
用两路模拟输入信号 中的一路进行模数转换 ,通过
D U O T传至 F G 同样通过 D 接受 F G P A; N I P A传来 的数据 ,进行数模转换以后 ,由模拟输出端输 出。
V L I K C
图 1 硬件连接 示意图
维普资讯
基 于 VD 语 言的同步 串口设计 HL
3 L30 l1 TV2AC0时序分析
T V 2A C 0 L 30 I 1 有两种工作模式 : 首通信、 次通 信 。其时序 图如图 2 所示 ,在首通信期间可以通过 在最低位发送逻辑 1 来请求次通信 , 可以利用次通 信对 T V 2A C 0的寄存器进行写或者读操作 , L 30 I 1 来初始化 T V 2 A C 0 L 30 I 1 和监测 T V 2A C 0的工 L 30 I 1

基于FPGA Verilog RS232串口回环测试例程,附源程序仿真源码及测试图片

基于FPGA Verilog RS232串口回环测试例程,附源程序仿真源码及测试图片

FPGA Verilog RS232串口回环测试基于FPGA Verilog RS232串口回环测试例程,支持多byte数据传输,附源程序仿真源码及测试图片。

测试基于SSCOM/友善之臂上位机软件测试,测试结果如下图一图二所示。

图一SSCOM图二图三连续发送仿真截图图四连续接收仿真截图后附verilog源程序代码及testbech仿真例程,注释欠。

重点:多byte回环测试要点,上位机串口多位数据连续发送停止位和起始位之间无间隔,回环程序在接收和发送都需要具备在停止位后能立马跳转到下一个起始位的能力。

重点关注cnt_bit的处理方式。

附录1 顶层例化uart_txd uart_txd(.clk_50m(sys_clk_50m),.reset_n(sys_rst_n),.tx_data(rx_data),.baud_set(3'd4),.send_en(rx_done),.send_done(),.send_busy(send_busy),.uart_tx(uart_tx));uart_rxd uart_rxd(.clk_50m(sys_clk_50m),.reset_n(sys_rst_n),.rx_data(rx_data),.baud_set(3'd4),.rx_done(rx_done),.rx_busy(rx_busy),.uart_rx(uart_rx));附录2 串口发送源程序`timescale1ns/1ps///////////////////////////////////////////////////////////////////// /////////////// Company:// Engineer://// Create Date: 2020/06/21 09:45:23// Design Name:// Module Name: uart_txd// Project Name:// Target Devices:// Tool Versions:// Description://// Dependencies:// Revision:// Revision 0.01 - File Created// Additional Comments://///////////////////////////////////////////////////////////////////// /////////////module uart_txd(clk_50m,reset_n,tx_data,baud_set,send_en,send_done,send_busy,uart_tx);input clk_50m;input reset_n;input[7:0] tx_data;input[2:0] baud_set;input send_en;output reg send_done;output reg send_busy;output reg uart_tx;reg[12:0] cnt;reg[12:0] baud_rate_cnt_max;reg[3:0] cnt_bit;reg[7:0] tx_data_r;localparam baud_rate_9600 =13'd5207;localparam baud_rate_19200 =13'd2603;localparam baud_rate_38400 =13'd1301;localparam baud_rate_57600 =13'd867;localparam baud_rate_115200 =13'd433;always@(posedge clk_50m or negedge reset_n)if(!reset_n)baud_rate_cnt_max <= baud_rate_115200;elsecase(baud_set)3'd0:baud_rate_cnt_max = baud_rate_9600;3'd1:baud_rate_cnt_max = baud_rate_19200;3'd2:baud_rate_cnt_max = baud_rate_38400;3'd3:baud_rate_cnt_max = baud_rate_57600;3'd4:baud_rate_cnt_max = baud_rate_115200;default:baud_rate_cnt_max = baud_rate_115200;endcasealways@(posedge clk_50m or negedge reset_n)if(!reset_n)tx_data_r <=8'd0;else if(send_en)tx_data_r <= tx_data;elsetx_data_r <= tx_data_r;always@(posedge clk_50m or negedge reset_n)if(!reset_n)send_busy <=1'b0;else if(send_en)send_busy <=1'b1;else if(cnt == baud_rate_cnt_max)beginif(cnt_bit ==4'd10)send_busy <=1'b0;elsesend_busy <= send_busy;endelsesend_busy <= send_busy;always@(posedge clk_50m or negedge reset_n)if(!reset_n)send_done <=1'b0;else if(cnt == baud_rate_cnt_max)beginif(cnt_bit ==4'd10)send_done <=1'b1;elsesend_done <=1'b0;endelsesend_done <=1'b0;always@(posedge clk_50m or negedge reset_n)if(!reset_n)cnt <=13'd0;else if(send_busy)beginif(cnt == baud_rate_cnt_max)cnt <=13'd0;elsecnt <= cnt +1'b1;endelsecnt <= cnt;/****************************************always@(posedge clk_50m or negedge reset_n)if(!reset_n)cnt_bit <= 4'd0;else if(send_en) //send_en needs to be 1 clock high pulse cnt_bit <= 4'd1;else if(cnt == baud_rate_cnt_max)beginif(cnt_bit == 4'd10)cnt_bit <= 4'd0;elsecnt_bit <= cnt_bit + 1'b1;endelsecnt_bit <= cnt_bit;******************************************/always@(posedge clk_50m or negedge reset_n)if(!reset_n)cnt_bit <=4'd0;else if(send_busy &&(cnt_bit ==4'd11))cnt_bit <=4'd1;else if(cnt ==1)cnt_bit <= cnt_bit +1'b1;elsecnt_bit <= cnt_bit;always@(posedge clk_50m or negedge reset_n)if(!reset_n)beginuart_tx <=1'b1;endelsecase(cnt_bit)4'd0:;4'd1: uart_tx <=1'b0;//start4'd2: uart_tx <= tx_data_r[0];//bit 04'd3: uart_tx <= tx_data_r[1];4'd4: uart_tx <= tx_data_r[2];4'd5: uart_tx <= tx_data_r[3];4'd6: uart_tx <= tx_data_r[4];4'd7: uart_tx <= tx_data_r[5];4'd8: uart_tx <= tx_data_r[6];4'd9: uart_tx <= tx_data_r[7];//bit 84'd10: uart_tx <=1'b1;//stopdefault:;endcaseendmodule附录3 串口发送testbench`timescale1ns/1ps///////////////////////////////////////////////////////////////////// /////////////// Company:// Engineer://// Create Date: 2020/06/21 11:38:04// Design Name:// Module Name: uart_txd_tb// Project Name:// Target Devices:// Tool Versions:// Description://// Dependencies://// Revision:// Revision 0.01 - File Created// Additional Comments://///////////////////////////////////////////////////////////////////// /////////////module uart_txd_tb();reg clk_50m;reg reset_n;reg[7:0] tx_data;reg[2:0] baud_set;reg send_en;wire send_done;wire send_busy;wire uart_tx;parameter CLK_PERIOD =20;initial clk_50m =0;always#(CLK_PERIOD /2) clk_50m =~clk_50m;initial begintx_data =8'h55;baud_set =4;reset_n =0;send_en =0;#(CLK_PERIOD *100);reset_n =1;# CLK_PERIOD;send_en =1;#(CLK_PERIOD );send_en =0;#(CLK_PERIOD *4340);send_en =1;#(CLK_PERIOD );send_en =0;#(CLK_PERIOD *4340);#(CLK_PERIOD *100);$stop;enduart_txd uart_txd(.clk_50m(clk_50m),.reset_n(reset_n),.tx_data(tx_data),.baud_set(baud_set),.send_en(send_en),.send_done(send_done),.send_busy(send_busy),.uart_tx(uart_tx));endmodule附录4 串口接收源程序`timescale1ns/1ps///////////////////////////////////////////////////////////////////// /////////////// Company:// Engineer://// Create Date: 2020/06/21 15:30:30// Design Name:// Module Name: uart_rxd// Project Name:// Target Devices:// Tool Versions:// Description://// Dependencies://// Revision:// Revision 0.01 - File Created// Additional Comments://///////////////////////////////////////////////////////////////////// /////////////module uart_rxd(clk_50m,reset_n,rx_data,baud_set,rx_done,rx_busy,uart_rx);input clk_50m;input reset_n;output reg[7:0] rx_data;input[2:0] baud_set;output reg rx_done;output reg rx_busy;input uart_rx;reg[12:0] cnt;reg[12:0] baud_rate_cnt_max;reg[3:0] cnt_bit;reg uart_rx_r1;reg uart_rx_r2;wire nedge;localparam baud_rate_9600 =13'd5207;localparam baud_rate_19200 =13'd2603;localparam baud_rate_38400 =13'd1301;localparam baud_rate_57600 =13'd867;localparam baud_rate_115200 =13'd433;always@(posedge clk_50m or negedge reset_n)if(!reset_n)baud_rate_cnt_max <= baud_rate_115200;elsecase(baud_set)3'd0:baud_rate_cnt_max = baud_rate_9600;3'd1:baud_rate_cnt_max = baud_rate_19200;3'd2:baud_rate_cnt_max = baud_rate_38400;3'd3:baud_rate_cnt_max = baud_rate_57600;3'd4:baud_rate_cnt_max = baud_rate_115200;default:baud_rate_cnt_max = baud_rate_115200;endcasealways@(posedge clk_50m or negedge reset_n)if(!reset_n)beginuart_rx_r1 <=8'd0;uart_rx_r2 <=8'd0;endelse beginuart_rx_r1 <= uart_rx;uart_rx_r2 <= uart_rx_r1;endassign nedge = uart_rx_r2 &(!uart_rx_r1);always@(posedge clk_50m or negedge reset_n) if(!reset_n)rx_busy <=1'b0;else if(nedge)rx_busy <=1'b1;else if(cnt == baud_rate_cnt_max)begin if(cnt_bit ==4'd10)rx_busy <=1'b0;elserx_busy <= rx_busy;endelserx_busy <= rx_busy;always@(posedge clk_50m or negedge reset_n) if(!reset_n)rx_done <=1'b0;else if(cnt == baud_rate_cnt_max)begin if(cnt_bit ==4'd10)rx_done <=1'b1;elserx_done <=1'b0;endelserx_done <=1'b0;always@(posedge clk_50m or negedge reset_n) if(!reset_n)cnt <=13'd0;else if(rx_busy)beginif(cnt == baud_rate_cnt_max)cnt <=13'd0;elsecnt <= cnt +1'b1;endelsecnt <= cnt;always@(posedge clk_50m or negedge reset_n) if(!reset_n)cnt_bit <=4'd1;else if(cnt == baud_rate_cnt_max )begin if(cnt_bit ==4'd10)cnt_bit <=4'd1;elsecnt_bit <= cnt_bit +1'b1;endelsecnt_bit <= cnt_bit;always@(posedge clk_50m or negedge reset_n)if(!reset_n)beginrx_data <=8'd0;endelse if(cnt == baud_rate_cnt_max /2)case(cnt_bit)4'd1:;//start4'd2: rx_data[0]<= uart_rx_r2;//bit 04'd3: rx_data[1]<= uart_rx_r2;4'd4: rx_data[2]<= uart_rx_r2;4'd5: rx_data[3]<= uart_rx_r2;4'd6: rx_data[4]<= uart_rx_r2;4'd7: rx_data[5]<= uart_rx_r2;4'd8: rx_data[6]<= uart_rx_r2;4'd9: rx_data[7]<= uart_rx_r2;//bit 74'd10:;//stopdefault:;endcaseelserx_data <= rx_data;endmodule附录5串口接收testbench`timescale1ns/1ps///////////////////////////////////////////////////////////////////// /////////////// Company:// Engineer://// Create Date: 2020/06/21 19:44:29// Design Name:// Module Name: uart_rxd_tb// Project Name:// Target Devices:// Tool Versions:// Description://// Dependencies://// Revision:// Revision 0.01 - File Created// Additional Comments://///////////////////////////////////////////////////////////////////// /////////////module uart_rxd_tb();reg clk_50m;reg reset_n;wire[7:0] rx_data;wire rx_done;wire rx_busy;reg uart_rx;parameter CLK_PERIOD =20;initial clk_50m =0;always#(CLK_PERIOD /2) clk_50m =~clk_50m;initial beginreset_n =0;uart_rx =1;//idle#(CLK_PERIOD *100);reset_n =1;# CLK_PERIOD;uart_rx =0;//start#(CLK_PERIOD *434);uart_rx =1;//bit0#(CLK_PERIOD *434);uart_rx =0;//bit1#(CLK_PERIOD *434);uart_rx =1;//bit2#(CLK_PERIOD *434);uart_rx =0;//bit3#(CLK_PERIOD *434);uart_rx =1;//bit4#(CLK_PERIOD *434);uart_rx =0;//bit5#(CLK_PERIOD *434);uart_rx =1;//bit6#(CLK_PERIOD *434);uart_rx =0;//bit7#(CLK_PERIOD *434);uart_rx =1;//stop#(CLK_PERIOD *434);uart_rx =1;//idle#(CLK_PERIOD *434);#(CLK_PERIOD *434);#(CLK_PERIOD *434);uart_rx =0;//start #(CLK_PERIOD *434);uart_rx =0;//bit0#(CLK_PERIOD *434);uart_rx =1;//bit1#(CLK_PERIOD *434);uart_rx =0;//bit2#(CLK_PERIOD *434);uart_rx =1;//bit3#(CLK_PERIOD *434);uart_rx =0;//bit4#(CLK_PERIOD *434);uart_rx =1;//bit5#(CLK_PERIOD *434);uart_rx =0;//bit6#(CLK_PERIOD *434);uart_rx =1;//bit7#(CLK_PERIOD *434);uart_rx =1;//stop#(CLK_PERIOD *434);uart_rx =1;//idle#(CLK_PERIOD *434);#(CLK_PERIOD *434);#(CLK_PERIOD *434);$stop;enduart_rxd uart_rxd(.clk_50m(clk_50m),.reset_n(reset_n),.rx_data(rx_data),.baud_set(3'd4),.rx_done(rx_done),.rx_busy(rx_busy),.uart_rx(uart_rx));endmodule。

VHDL串口通信

VHDL串口通信

4 .UART 模块设计UART 异步通信串口协议的VHDL实现包括3个基本模块:时钟分频、接收模块和发送模块,下面逐一介绍其实现方法。

4.2.1 时钟分频模块由于UART是异步传输,没有传输同步时钟。

为了能保证数据传输的正确性,UART采用16倍数据波特率的时钟进行采样。

每个数据有16个时钟采样,取中间的采样值,以保证采样不会滑码或误码。

一般UART一帧的数据位数为8,这样即使每个数据有一个时钟的误差,接收端也能正确地采样到数据。

这里采用常用的数据波特率为9600bps,则所需时钟的频率为16*9600。

系统时钟为50MHz,则分频系数为50000000/(16*9600) =325.52,取整为325。

分频器实现相对简单,这里对其设计流程图不做详细介绍。

只是将设计过程和结果简述如下:首先用VHDL语言进行设计输入,并生成模块文件如图4.3所示,其中clk 为50M系统时钟输入,clkout为325分频后时钟输出。

图4.3 分频模块然后建立波形文件,对以上模块进行时序仿真,仿真结果如图4.4所示,方正结果说明,分频输出实现了对输入的325分频,分频模块设计正确。

图4.4 分频模块仿真结果4.2.2 UART发送模块发送过程:空闲状态,线路处于高电平;当受到发送数据指令后,拉低线路一个数据位的时间T,接着数据按地位到高位依次发送,数据发送完毕后,接着发送停止位(停止位为高电平),一帧数据发送结束。

(1)模块流程图根据以上发送过程,发送模块算法示意图设计如图4.5所示。

图4.5 UART发送数据算法示意图(2)生成模块文件新建一原理图文件,将VHDL 源文件生成对应的模块文件如图4.6所示,其中clk为时钟输入,datain为需要发送的数据输入,wrsig为发送命令输入,idle 为忙闲信号输出,tx为串行数据输出端。

图4.6 UART发送模块(3)波形仿真要对发送模块进行时序仿真必须设计一测试模块,即在每一个clk来时产生一个八位的数据。

用vhdl语言在cpld上实现串行通信

用vhdl语言在cpld上实现串行通信

用vhdl语言在cpld上实现串行通信一、概述串行通信是现代通信领域中最为常见的一种通信方式。

通过串行通信,现代社会中的各种设备可以以最高效的方式进行数据传输,实现快速、准确的信息交换。

而vhdl语言则是数字电路设计领域中最为常用的一种描述语言,因为vhdl 语言可以描述数字电路的不同行为,对于数字电路的模拟和仿真非常方便。

在本文中,我们将介绍如何使用vhdl语言在cpld 上实现串行通信。

二、串行通信的基本原理串行通信是指在数据传输过程中,数据位是按照顺序一个一个相继传输的。

串行通信的传输速率相对较慢,但是传输距离远,主要是通过数据信号占用两个或者三个核心线来完成的。

串行通信的数据信号一般由三个部分构成:开始位、数据位和停止位。

开始位一般用于启动数据传输,而停止位则用于结束数据传输。

三、vhdl语言概述VHDL(VHSIC Hardware Description Language)是美国国防工业联合会(VHSIC)在80年代末期为了解决数字电路设计中的复杂性而开发的一种硬件描述语言,是一种基于文本的语言。

VHDL语言主要用来描述数字逻辑和数字电路。

VHDL语言本身就是一种结构化的、层次化的语言,可以很好地体现出数字电路的层次关系。

四、使用vhdl语言在cpld上实现串行通信的步骤1、确定串行通信的传输速率和数据格式。

在确定串行通信的传输速率和数据格式之前,需要确定串行通信的基本参数,包括其传输速率、在接收端进行判定数据是否有效的时间程度、以及在发送端和接收端之间互相传输数据的位数。

这些参数对于后续的设计极为重要。

2、编写串行通信的vhdl模块。

在vhdl模块中,需要包括发送和接收两个部分,分别对应于硬件接口中的发送和接收部分。

发送部分主要是将数据按照规定的格式进行串行传输,而接收部分则主要是将串行传输的数据再转换为并行数据。

3、完成vhdl模块的仿真测试。

在完成vhdl模块的设计之后,需要进行仿真测试,以验证vhdl模块的正确性和稳定性。

vhdl语言100例程序

vhdl语言100例程序

vhdl语言100例程序以下是100个关于VHDL语言的程序示例:1. 用VHDL编写一个计数器模块2. 用VHDL编写一个SR-Latch模块3. 用VHDL编写一个JK-Flip Flop模块4. 用VHDL编写一个D-Flip Flop模块5. 用VHDL编写一个T-Flip Flop模块6. 用VHDL编写一个复位计数器模块7. 用VHDL编写一个移位寄存器模块8. 用VHDL编写一个状态机模块9. 用VHDL编写一个MUX模块10. 用VHDL编写一个DeMUX模块11. 用VHDL编写一个加法器模块12. 用VHDL编写一个减法器模块13. 用VHDL编写一个乘法器模块14. 用VHDL编写一个除法器模块15. 用VHDL编写一个比较器模块16. 用VHDL编写一个位逻辑模块17. 用VHDL编写一个字逻辑模块18. 用VHDL编写一个数据选择器模块19. 用VHDL编写一个FIFO队列模块20. 用VHDL编写一个LIFO栈模块21. 用VHDL编写一个流水线模块22. 用VHDL编写一个中断控制器模块23. 用VHDL编写一个时钟分频器模块24. 用VHDL编写一个IO控制器模块25. 用VHDL编写一个SPI通信控制器模块26. 用VHDL编写一个I2C通信控制器模块27. 用VHDL编写一个UART通信控制器模块28. 用VHDL编写一个哈希函数模块29. 用VHDL编写一个随机数产生器模块30. 用VHDL编写一个CRC校验器模块31. 用VHDL编写一个AES加密算法模块32. 用VHDL编写一个DES加密算法模块33. 用VHDL编写一个SHA加密算法模块34. 用VHDL编写一个MD5加密算法模块35. 用VHDL编写一个RSA加密算法模块36. 用VHDL编写一个卷积滤波器模块37. 用VHDL编写一个峰值检测器模块38. 用VHDL编写一个平滑滤波器模块39. 用VHDL编写一个中值滤波器模块40. 用VHDL编写一个微处理器模块41. 用VHDL编写一个信号发生器模块42. 用VHDL编写一个信号采集器模块43. 用VHDL编写一个频率计算器模块44. 用VHDL编写一个相位计算器模块45. 用VHDL编写一个时序分析器模块46. 用VHDL编写一个正弦波产生器模块47. 用VHDL编写一个余弦波产生器模块48. 用VHDL编写一个数字滤波器模块49. 用VHDL编写一个数字信号处理器模块50. 用VHDL编写一个数字识别模块51. 用VHDL编写一个自动售货机模块52. 用VHDL编写一个二进制加法器模块53. 用VHDL编写一个二进制减法器模块54. 用VHDL编写一个二进制乘法器模块55. 用VHDL编写一个二进制除法器模块56. 用VHDL编写一个自然对数模块57. 用VHDL编写一个指数函数模块58. 用VHDL编写一个三角函数模块59. 用VHDL编写一个高斯滤波器模块60. 用VHDL编写一个激光传感器模块61. 用VHDL编写一个超声波传感器模块62. 用VHDL编写一个光电传感器模块63. 用VHDL编写一个温度传感器模块64. 用VHDL编写一个气压传感器模块65. 用VHDL编写一个陀螺仪模块67. 用VHDL编写一个电流传感器模块68. 用VHDL编写一个电容传感器模块69. 用VHDL编写一个磁场传感器模块70. 用VHDL编写一个通信电缆模块71. 用VHDL编写一个电源控制器模块72. 用VHDL编写一个电机控制器模块73. 用VHDL编写一个汽车控制器模块74. 用VHDL编写一个飞机控制器模块75. 用VHDL编写一个摄像头模块76. 用VHDL编写一个音频控制器模块77. 用VHDL编写一个扬声器控制器模块78. 用VHDL编写一个拨号器模块79. 用VHDL编写一个振动控制器模块80. 用VHDL编写一个压力控制器模块81. 用VHDL编写一个过滤器模块82. 用VHDL编写一个微波发射模块84. 用VHDL编写一个智能电表模块85. 用VHDL编写一个闹钟模块86. 用VHDL编写一个计时器模块87. 用VHDL编写一个时间戳模块88. 用VHDL编写一个脉冲宽度模块89. 用VHDL编写一个电路仿真模块90. 用VHDL编写一个电路控制模块91. 用VHDL编写一个电路测试模块92. 用VHDL编写一个电路优化模块93. 用VHDL编写一个电路布局模块94. 用VHDL编写一个电路验证模块95. 用VHDL编写一个数字信号发生器模块96. 用VHDL编写一个数字信号反演器模块97. 用VHDL编写一个数字信号滤波器模块98. 用VHDL编写一个数字信号加速器模块99. 用VHDL编写一个数字信号降噪器模块100. 用VHDL编写一个数字信号解调器模块VHDL语言是一种硬件描述语言,它用于描述数字电路和系统。

串并转换VHDL

串并转换VHDL
reg_en <= '1';
ready <= '1';
data_valid <= '0';
shift_start <= '0';
next_state <= shift;
when shift =>
reg_en <= '1';
ready : out std_logic; --low active,ready to recieve data
q : out std_logic
);
end p2s;
architecture Behavioral of p2s is
signal reg : std_logic_vector(7 downto 0);
-- Description: This module is designed to implement parallel to serial conversion
--------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity p2s is
port(
reset : in std_logic;
begin
counter: process(reset,clk,shift_start)

第2章 VHDL语言基础

第2章 VHDL语言基础

End 实体名;
端口名
端口模式
数据类型
(2)ENTITY
端口模式(MODE)有以下几种类型: IN ;OUT;INOUT ;BUFFER 端口模式可用下图说明:(黑框代表一个设计或模块)
IN
OUT
BUFFER
INOUT
二输入与门电路设计范例
Library std; Use std.standard.all;
(4)CONFIGURATION定义区
定义格式: Configuration 配置名 of 实体名 is for 选用的结构体名 end for; end configuration 配置名 ;
二输入与门电路设计范例
a c
b电Leabharlann 真值表abc
0
0
0
1
0
0
0
1
0
1
1
1
二输入与门电路设计范例
Architecture Na of and2 is
‘1’; 符号<=为信号直接赋值符。
End Na;
--结构体Na
Architecture Nb of and2 is
Begin
c <= a and b;
--and 为逻辑与操作
End Nb; --结构体Nb
Library ieee; Use ieee.std_logic_1164.all;
Entity half_adder is Port( x,y : in std_logic;sum,carry : out hlf_adder); End half_adder;
(4)CONFIGURATION定义区
一个完整VHDL电路设计必须有一个实体 和对应的结构体,即实体和结构体对构成一个 完整的VHDL设计。

VHDL实验报告(1)

VHDL实验报告(1)

VHDL 实验报告******班级:电子0701学号:************实验一组合逻辑电路设计一实验目的:1. 熟悉mux+pluxII软件,可以进行新文件的编辑和文件的修改。

2. 掌握门电路VHDL语言程序设计方法。

3. 掌握选择器VHDL语言程序设计方法。

4. 掌握加法器VHDL语言程序设计方法。

5. 熟悉VHDL编程的基本方法。

二实验设备:1.计算机2.Max+PlusII软件三实验原理及内容:1 二输入与门(1)实验原理二输入与门是我们数字电路中的一个基础逻辑门电路,是最基本的逻辑门电路之一,也是最简单的逻辑门之一。

它能实现两个输入端的相与,一般有三个端口。

二输入与门的表达式是:Y=ab二输入与门的逻辑符号如图(1)所示,真值表如表(1)所示。

图(1)与门逻辑符号表(1)与门真值表(2)实验内容a.在mux+pluxII文本编辑环境下,打开新文本,编写两输入与门VHDL语言源程序,程序设计如下:LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;ENTITY and2 ISPORT(a,b: IN STD_LOGIC;Y: OUT STD_LOGIC);END and2;ARCHITECTURE behave OF and2 ISBEGINY <= a and b;END behave;b.对源程序进行编译,按照提示进行修改,直至编译通过。

c.对编译程序进行仿真,分析并记录仿真波形,其仿真波形图如图(2)所示。

图(2)二输入与门仿真图d.在自己的目录下保存相应的源文件、波形文件。

2 四选一选择器(1)实验原理四选一选择器如图(3)所示,真值表如表(2)所示。

图(3)mux4管脚图表(2)mux4真值表(2)实验内容a.在mux+plusII文本编辑环境下,打开新文件,编辑四选一VHDL源程序文件,其程序设计如下:LIBRARY IEEEUSE IEEE.STD_LOGIC_1164.ALL;ENTITY mux4 ISPORT(A: IN STD_LOGIC_VECTOR (1 DOWNTO 0);D0,D1,D2,D3:IN STD_LOGIC;G:IN STD_LOGIC;Y: OUT STD_LOGIC);END mux4;ARCHITECTURE dataflow OF mux4 ISBEGINPROCESS (A,D0,D1,D2,D3,G)BEGINIF (G ='0') THENIF (A="00")THEN Y <= D0;ELSIF(A="01")THEN Y <= D1;ELSIF(A="10")THEN Y <= D2;ELSE Y <= D3;END IF;ELSE Y <='0';END IF;END PROCESS;END dataflow;b.对源程序进行编译,按照提示进行修改,直到编译通过。

VHDL并串转换

VHDL并串转换

VHDL并串转换并串转换⼀、电路功能:本电路能实现FPGA与单⽚机的部分接⼝功能,使单⽚机与FPGA 能进⾏简单通信的功能,即单⽚机通过ale、wr、P0、P2管脚与FPGA 相连接,通过这⼏个控制引脚,指导FPGA进⾏并串转换。

同时,在FPGA上⾃带有clr与clk,实现对系统的清零复位,保证串⾏输出有条进⾏。

⼆、电路设计思路:(1)单⽚机是⼀个拥有多扩展模块的芯⽚,所以,⾸先我们要设计地址总线。

本题中设地址为FAH,当ale来⼀个上升沿时,我们要锁存当前P0⼝的地址,然后再将此地址与FAH⽐较。

若⽐较结果相等,则写有效(把wr赋给FPGA的内部信号wr_en)否则写⽆效(把1赋给wr_en),其中wr_en为0有效。

(2)设计数据总线当选择该芯⽚时,若单⽚机发⼀个写有效来,则将P2和P0⼝的数据读⼊FPGA内部数据锁存器.当数据读⼊后,同时,内部应该产⽣⼀个读⼊完成型号a,以便通知FPGA进⾏并串转换。

(3)并串转换当a有效时,开始进⾏并串转换,并输出串⼝按时钟clk将数据⼀个⼀个输出,当并串转换结束后,应当产⽣⼀个结束控制标志(本电路中将ld反馈回电路做结束标志),使a⽆效,停⽌停⽌并串转换。

三、电路原理框图如下:四、具体程序与原理图:(1)地址锁存器library ieee;use ieee.std_logic_1164.all;entity latch_add isport ( ale,clr:in std_logic;P0:in std_logic_vector(7 downto 0);add:out std_logic_vector(7 downto 0));end latch_add;architecture art of latch_add isbeginprocess(clr,ale)beginif(clr='1') thenadd<="00000000";elsif(ale'event and ale='1') then --锁存地址add<=P0;end if;end process;end art;(2)⽐较器library ieee;use ieee.std_logic_1164.all;entity en isport( wr,clr:in std_logic;add:in std_logic_vector(7 downto 0);wr_en:out std_logic);end en;architecture art of en isbeginprocess(add,wr,clr)beginif (clr='1') thenwr_en<='1';elsif(add="11111010") thenwr_en<=wr; --写允许elsewr_en<='1'; --写禁⽌end if;end process;end art;(3)数据锁存library ieee;use ieee.std_logic_1164.all;entity latch_data isport( wr_en,b,clr:in std_logic;P1,P2:in std_logic_vector(7 downto 0);datain:out std_logic_vector(15 downto 0);a:out std_logic); --a是允许并串转换end latch_data;architecture art of latch_data isbeginprocess(wr_en,clr)beginif(clr='1') thena<='0';elsif(wr_en'event and wr_en='0') then --数据读⼊FPGA datain<=P2&P1; a<='1'; --a为1,开始并串转换end if; if(b='1') then --将ld接⼊b端⼝,为并串结束标志a<='0'; --a为0,结束并串转换end if;end process;end art;(4)并串转换library ieee;use ieee.std_logic_1164.all;entity bing_chuan isport( a,clk,clr: in std_logic;datain1:in std_logic_vector(15 downto 0);ld,s_clk,s_data: out std_logic);end bing_chuan;architecture art of bing_chuan issignal b:std_logic; -- b为产⽣输出同步时钟s_clk的控制信号begin process(a,clk)variable I: integer;beginif(clr='1') thenI:=16;ld<='0';elsif( clk'event and clk='1') thenb<=a;if(a='1') thenif(I=0) thenI:=16; ld<='1';s_data<='0';b<='0';elses_data<=datain1(I-1);I:=I-1;end if;else ld<='0';end if;end if;end process ;s_clk<=clk when b='1' else --b为1,产⽣输出同步时钟'0';end art;五、并串转换原理图:仿真结果:六、结果分析仿真如上图,我们可以看出,当ale来上升沿时,FPGA读⼊P0⼝的地址11111010,此地址与设置地址FAH相同,所以写有效(wr_en<=wr)。

CRC16校验码移位算法及VHDL实现4页word文档

CRC16校验码移位算法及VHDL实现4页word文档

CRC16校验码移位算法及VHDL实现在数据传输过程中,由于信道干扰,往往使得发送和接收的数据不一致。

为了降低误码率,保证传输数据的可靠性,通常会改进信道的传输质量或在传输的数据中加入校验信息。

在各种校验方法中,循环冗余校验CRC (CyclicRedundancy Check)是一种最常用的方法。

CRC校验技术是一种十分有效的数据传输错误检测技术,由于其编码和解码过程简单,检错和纠错能力强,广泛应用于通信领域用于实现差错控制。

串行通信普遍应用于工业通信控制领域,如何提高数据的传输可靠性尤为重要,现有的串口在数据传输过程中加入CRC校验可提高数据传输的可靠性。

普通串行口不自带CRC校验功能,大多数应用中都是通过软件编程计算CRC码后再附加在数据末尾传输的,由于软件执行耗费时间长,影响数据的传输速度。

现场可编程门阵列FPGA (Field-Programmable Gate Array)在数字系统设计中已被广泛使用。

用硬件描述语言(VHDL)实现CRC校验码的计算,然后下载到FPGA芯片中,硬件实现CRC校验,与软件实现相比,对数据的传输速度影响较小。

本文介绍一种CRC16校验码串行产生的方法,并给出了其VHDL实现及仿真分析。

1 CRC校验原理在发送方要发送的K位数据码后,以一定的规则产生一个r位用于校验的监督码,附加在原数据后面,构成的信息码为n=k+r位,因此,这种编码又叫(n,k)码。

接收方根据通信双方约定的规则进行校验,确定数据是否出错。

这个规则即“生成多项式”。

K位数据码表示为M(x),选择合适的CRC生成多项式G(x),G(x)的最高次幂为r。

把M(x)左移r位,即M(x)*xr对G(x)做不借位除法(即异或运算),所得余数为CRC校验码,即:其中R(x)为CRC校验码。

发送方以上述原理生成校验码附加在数据末尾发送出去,接收方接收到的数据也对同样的G(x)做除法,如果余数为0,则认为数据传送无误,否则按出错处理。

模拟串口的三种方法及C语言

模拟串口的三种方法及C语言

模拟串口的三种方法及C语言模拟串口是软件中模拟实现串口通信的一种方法,它是在电脑上通过软件模拟两个串口之间的传输,用来测试、调试串口相关的应用程序。

本文将介绍三种常见的模拟串口的方法,并提供C语言代码示例。

1.使用虚拟串口软件虚拟串口软件是一种用于模拟串口通信的应用程序。

它创建了虚拟的串口设备,使其在电脑上模拟出真实的串口通信环境。

通过虚拟串口软件,可以实现串口的模拟收发数据,可以连接到串口测试工具、串口调试工具或者自己编写的串口通信程序上。

以下是一个使用虚拟串口软件模拟串口通信的C语言代码示例:```c#include <stdio.h>#include <windows.h>int mai//打开虚拟串口//检测串口是否成功打开printf("Error in opening serial port\n");return 1;}//进行串口通信操作,如发送、接收数据//关闭串口return 0;```在这个示例中,我们使用了Windows操作系统的函数`CreateFile`来打开一个虚拟串口,这里的串口名称是"COM1"。

然后可以调用相关函数进行串口通信操作,最后用`CloseHandle`函数关闭串口。

2.使用串口驱动模拟在一些情况下,可以通过修改电脑的串口驱动程序来模拟串口通信。

这种方法需要更深入的了解操作系统的底层机制,并进行驱动程序的开发和修改。

通过修改串口驱动程序,可以模拟出一个虚拟的串口设备,通过这个设备进行串口通信。

以下是一个简单的C语言代码示例,用于修改串口驱动程序来模拟串口通信:```c#include <stdio.h>#include <fcntl.h>#include <unistd.h>int maiint fd;//打开串口设备fd = open("/dev/ttyS0", O_RDWR);//检测串口是否成功打开if (fd < 0)printf("Error in opening serial port\n");return 1;}//进行串口通信操作,如发送、接收数据//关闭串口设备close(fd);return 0;```在这个示例中,我们使用了Linux操作系统的函数`open`来打开一个串口设备,这里的设备名称是"/dev/ttyS0"。

VHDL编写IIC程序

VHDL编写IIC程序

如题所示,本文是使用VHDL语言编写的IIC 总线的24C02的读写例程,程序加了中文注释便于想我一样的初学者理解,写使用的写一个字节,读使用的随机读,具体参考24c02的手册library IEEE;use IEEE.std_logic_1164.all;use ;use ;entity iic_com isport(clk: in STD_LOGIC;rst_n: in STD_LOGIC;sw1_en: in STD_LOGIC; --读使能sw2_en: in STD_LOGIC; --写使能scl: out STD_LOGIC;sda: inout STD_LOGIC;dis_data: out STD_LOGIC_VECTOR (7 downto 0));end entity iic_com;architecture iic_communication of iic_com issignal sw_state: STD_LOGIC;signal cnt_delay: STD_LOGIC_VECTOR (8 downto 0);signal scl_pos: STD_LOGIC;signal scl_hig: STD_LOGIC;signal scl_neg: STD_LOGIC;signal scl_low: STD_LOGIC;signal db_r: STD_LOGIC_VECTOR (7 downto 0);signal read_data: STD_LOGIC_VECTOR (7 downto 0);signal sda_r: STD_LOGIC;signal sda_in: STD_LOGIC;signal sda_link: STD_LOGIC;signal num: STD_LOGIC_VECTOR (3 downto 0);constant DEVICE_READ: STD_LOGIC_VECTOR (7 downto 0) := "10100001";--器件地址读constant DEVICE_WRITE: STD_LOGIC_VECTOR (7 downto 0) := "10100000";--器件地址写constant WRITE_DATA: STD_LOGIC_VECTOR (7 downto 0) := "11000011"; --写入的数据constant BYTE_ADDR: STD_LOGIC_VECTOR (7 downto 0) := "00000011";--写入的地址type state is (IDLE,START1,ADD1,ACK1,ADD2,ACK2,START2,ADD3,ACK3,DATA,ACK4,STOP1,STOP2);signal cstate: state;signal temp_sw1,temp_sw2:Std_LOGIC;begin----------------------process(clk,rst_n)beginif (rst_n = '0') thensw_state <= '0';elsif (clk'event AND clk = '1') thenif(sw1_en = '1') thensw_state <= '0';elsif (sw2_en = '1') thensw_state <= '1';end if;end if;end process;----------------------process(clk,rst_n)beginif (rst_n = '0') thencnt_delay <= '0' & x"00";elsif (clk'event AND clk = '1') thenif(cnt_delay = 10#499#) then --相当于500分频,得到100K时钟cnt_delay <= '0' & x"00";elsecnt_delay <= cnt_delay+'1';end if;end if;end process;scl_pos <= '1' when (cnt_delay = 10#499#) else'0'; --IIC时钟上升沿scl_hig <= '1' when (cnt_delay = 10#124#) else'0'; --IIC时钟高电平scl_neg <= '1' when (cnt_delay = 10#249#) else'0'; --IIC时钟下降沿scl_low <= '1' when (cnt_delay = 10#374#) else'0'; --IIC时钟低电平process(clk,rst_n)beginif (rst_n = '0') thenscl <= '0';elsif (clk'event AND clk = '1') thenif(scl_pos = '1') thenscl <= '1';elsif(scl_neg = '1') thenscl <= '0';end if;end if;end process;----------------------process(clk,rst_n)beginif (rst_n = '0') thencstate <= IDLE;sda_r <= '1';sda_link <= '0';num <= x"0";read_data <= x"00";elsif (clk'event AND clk = '1') thencase cstate iswhen IDLE =>sda_link <= '1';sda_r <= '1';if (sw1_en/=temp_sw1)or(sw2_en/=temp_sw2) then --当sw1_en 和sw2_en 变化一次,只读或写一次,防止屡次读写temp_sw1<=sw1_en;temp_sw2<=sw2_en;if ((sw1_en = '1') OR (sw2_en = '1')) thendb_r <= DEVICE_WRITE;cstate <= START1;elsecstate <= IDLE;end if;elsecstate <= IDLE;end if;when START1 =>if (scl_hig = '1') then --起始位sda_link <= '1';--数据线由sda_r控制sda_r <= '0';cstate <= ADD1;num <= x"0";elsecstate <= START1;end if;when ADD1 => --器件地址&'0'if (scl_low = '1') thenif (num = x"8") thennum <= x"0";sda_r <= '1';sda_link <= '0';--数据线设为高阻态,允许输入cstate <= ACK1;elsecstate <= ADD1;num <= num+'1';case num iswhen x"0" => sda_r <= db_r(7);when x"1" => sda_r <= db_r(6);when x"2" => sda_r <= db_r(5);when x"3" => sda_r <= db_r(4);when x"4" => sda_r <= db_r(3);when x"5" => sda_r <= db_r(2);when x"6" => sda_r <= db_r(1);when x"7" => sda_r <= db_r(0);when others => NULL;end case;end if;elsecstate <= ADD1;end if;when ACK1 => --应答if (scl_neg = '1') thencstate <= ADD2;db_r <= BYTE_ADDR;elsecstate <= ACK1;end if;when ADD2 => --要写入数据或读取数据的地址if (scl_low = '1') thenif (num = x"8") thennum <= x"0";sda_r <= '1';sda_link <= '0';--数据线设为高阻态,允许输入cstate <= ACK2;elsesda_link <= '1';--数据线由sda_r控制num <= num+'1';cstate <= ADD2;case num iswhen x"0" => sda_r <= db_r(7);when x"1" => sda_r <= db_r(6);when x"2" => sda_r <= db_r(5);when x"3" => sda_r <= db_r(4);when x"4" => sda_r <= db_r(3);when x"5" => sda_r <= db_r(2);when x"7" => sda_r <= db_r(0);when others => NULL;end case;end if;elsecstate <= ADD2;end if;when ACK2 => --应答if (scl_neg = '1') thenif (sw_state = '0') then --如果写入数据cstate <= DATA;db_r <= WRITE_DATA;elsif (sw_state = '1') then --如果读取数据db_r <= DEVICE_READ;cstate <= START2;end if;elsecstate <= ACK2;end if;when START2 => --起始位if (scl_low = '1') thensda_link <= '1';sda_r <= '1';cstate <= START2;elsif (scl_hig = '1') thensda_r <= '0';cstate <= ADD3;elsecstate <= START2;end if;when ADD3 => --器件地址&'1' if (scl_low ='1') thenif (num = x"8") thennum <= x"0";sda_r <= '1';sda_link <= '0';cstate <= ACK3;l11<='0';elsenum <= num+'1';cstate <= ADD3;case num iswhen x"0" => sda_r <= db_r(7);when x"2" => sda_r <= db_r(5);when x"3" => sda_r <= db_r(4);when x"4" => sda_r <= db_r(3);when x"5" => sda_r <= db_r(2);when x"6" => sda_r <= db_r(1);when x"7" => sda_r <= db_r(0);when others => NULL;end case;end if;elsecstate <= ADD3;end if;when ACK3 => --应答if (scl_neg = '1') thencstate <= DATA;sda_link <= '0';elsecstate <= ACK3;end if;when DATA =>if (sw_state = '1') then --如果是读数据if (num <= x"7") thencstate <= DATA;if (scl_hig = '1') thennum <= num+'1';case num iswhen x"0" => read_data(7) <= sda_in;when x"1" => read_data(6) <= sda_in;when x"2" => read_data(5) <= sda_in;when x"3" => read_data(4) <= sda_in;when x"4" => read_data(3) <= sda_in;when x"5" => read_data(2) <= sda_in;when x"6" => read_data(1) <= sda_in;when x"7" => read_data(0) <= sda_in;when others => NULL;end case;end if;elsif ((scl_low = '1') AND (num = x"8")) thennum <= x"0";cstate <= ACK4;elsecstate <= DATA;end if;elsif (sw_state = '0') then --如果是写数据sda_link <= '1';if (num <= x"7") thencstate <= DATA;if (scl_low = '1') thensda_link <= '1';num <= num+'1';case num iswhen x"0" => sda_r <= db_r(7);when x"1" => sda_r <= db_r(6);when x"2" => sda_r <= db_r(5);when x"3" => sda_r <= db_r(4);when x"4" => sda_r <= db_r(3);when x"5" => sda_r <= db_r(2);when x"6" => sda_r <= db_r(1);when x"7" => sda_r <= db_r(0);when others => NULL;end case;end if;elsif ((scl_Low = '1') AND (num = x"8")) thennum <= x"0";sda_r <= '1';sda_link <= '0';cstate <= ACK4;elsecstate <= DATA;end if;end if;when ACK4 => --应答if (scl_neg = '1') thencstate <= STOP1;elsecstate <= ACK4;end if;when STOP1 => --停止位if(scl_low = '1') thensda_link <= '1';sda_r <= '0';cstate <= STOP1;elsif (scl_hig = '1') thensda_r <= '1';cstate <= STOP2;elsecstate <= STOP1;end if;when STOP2 =>if (scl_low = '1') thensda_r <= '1';elsecstate <= IDLE;end if;when others => cstate <= IDLE;end case;end if;end process;process (sda, sda_link)beginif(sda_link = '1') thensda <= sda_r;elsesda <= 'Z';end if;end process;sda_in <= sda;--sda_in <= 'z';--sda <= sda_r when (sda_link = '1') else-- "z";dis_data <= read_data;end architecture iic_communication;。

c语言怎么写串口通信编程

c语言怎么写串口通信编程

c语言怎么写串口通信编程串口通信是一种广泛应用于嵌入式系统和电子设备之间的通信方式。

无论是嵌入式开发还是电子设备控制,串口通信都是常见的需求。

在C语言中,实现串口通信需要通过操作串口的硬件寄存器和使用相应的通信协议来实现数据的发送和接收。

本文将一步一步介绍如何使用C语言编写串口通信程序。

第一步:打开串口要开始串口通信,首先需要打开串口。

在C语言中,可以使用文件操作函数来打开串口设备。

通常,串口设备被命名为/dev/ttyS0,/dev/ttyS1等,具体名称取决于系统。

下面是一个打开串口设备的示例代码:cinclude <stdio.h>include <fcntl.h>include <termios.h>int open_serial_port(const char *port) {int fd = open(port, O_RDWR O_NOCTTYO_NDELAY);if (fd == -1) {perror("open_serial_port");return -1;}设置串口属性struct termios options;tcgetattr(fd, &options);cfmakeraw(&options);cfsetspeed(&options, B9600);tcsetattr(fd, TCSANOW, &options);return fd;}int main() {const char *port = "/dev/ttyS0";int fd = open_serial_port(port);if (fd == -1) {打开串口失败,处理错误return -1;}串口已打开,可以进行数据的读写操作return 0;}在上面的代码中,open_serial_port函数用于打开指定的串口设备并进行一些必要的设置。

VHDL并串转换

VHDL并串转换

Yibin University物理与电子 工程学院题 目:基于FPGA 的51单片机总线接口 专 业: 电子信息科学与技术 姓 名: 戢 红 伟 学 号: 130303035 年 级: 2013 级 班 级: 三 班 指导老师: 李 庆 时 间: 2015 年 6 月 23 日一、 电路功能与要求1、本电路能实现FPGA 与单片机的部分接口功能,使单片机与FPGA 能进行简单通信的功能,即单片机通过‘ALE ’、‘WR ’、‘P0’、‘P2’管脚与FPGA 相连接,通过这几个控制引脚,控制FPGA 进行并串转换。

同时,在FPGA 上自带有‘REST ’与‘CLK ’,实现对系统的清零复位,保证串行输出有序进行。

P2 P0 ALEWR复位CLK P2 P0 ALEWRCL RESTS_DATA数据输出同步时钟S_CLK LD串口数据输出数据发送结束2、时序3、具体功能单片机是一个拥有多扩展模块的芯片三种总线,分别是地址总线、数据总线、控制总线。

本题中当‘ALE’来一个高电平‘1’时,判断地址总线‘P2&P0’的值是否为“7FF0H”,若不为“7FF0H”,则继续等待下一个ALE高电平的到来。

若为“7FF0H”,则判断‘WR’是否为高电平‘1’,则继续等待‘WR’高电平的到来。

若为高电平,则将数据总线‘P0’数据送入FPGA内部进行“并—串”转换。

二、设计思路需要用到的引脚名:输入:ALE:地址锁存信号WR:数据写信号P2:高八位地址输入口P0:低八位地址/数据分时复用输入口REST:复位输出:S_DATA:串行数据输出口S_CLK:串行数据输出LD:转换完成信号内部传输/通信控制:DATA:锁存器数据(输出)与数据转换数据(输入)端口BUSY:数据转换器忙碌信号START:开始转换信号1、数据锁存器首先判断‘ALE’是否为高电平‘1’,若不为高电平则继续等待,若为高电平则判断地址‘P2&P0’是等于“7FF0H”,若等于,则继续等待ALE下一个高电平‘1’的到来。

《VHDL语言及应用》Quartus II 软件使用与 VHDL 基础程序设计实验

《VHDL语言及应用》Quartus II 软件使用与 VHDL 基础程序设计实验

《VHDL语言及应用》Quartus II 软件使用与 VHDL 基础程序设计实验一、实验目的:(1)掌握 Quartus II 开发软件的基本使用,包括新建工程,代码编写与添加,工程编译与综合,建立波形仿真等步骤;(2)通过与门电路(AndGate)功能的编写,掌握 VHDL 程序的基本设计结构。

二、实验设备及软件:电脑,Quartus II 软件四、实验过程1.新建工程打开软件,File--New--New Quartus II Projec然后点击OK, 新建工程的第一个界面直接点击 Next, 界面第一行要在FPGA工程文件夹路径后再加上单独工程的名字,界面第二,第三行分别与工程目录名设定相同,因此都写AndGate。

选择实验需要的器件型号。

2.新建与添加代码文件对.vhd文件先进行编辑,编辑之后才可进行保存,点击左上方保存按钮,将代码文件保存至工程目录中,文件名为 AndGate。

第1行,第2行:库、程序包的调用说明。

第4行:ENTITY实体名IS。

第6行,第7行:输入的端口类型,输出的端口类型。

第12行:将信号赋值给对应的输出端口。

3.工程编译编译完成,通过下方的 Message窗口可以确认编译是否成功,如有错误,从Message信息提示判断代码何处出现错误,在编译完成后,点击左侧编译窗口中的RTL Viewer 可以查看代码综合生成的电路,此时编译窗口中还有一布EDA Netlist Writer没有自动完成,如果要进行功能波形仿真,则此时要再双击EDA Netlist Writer完成。

4.波形仿真点击左上角的 File—New--Vector Waveform File点击OK,出现波形文件界面后,点击左上方保存按钮,将其保存至工程目录中,默认命名与工程名相同,都为AndGate。

在波形文件界面左侧的Name拦中右键,选择Insert-->Insert Node or Bus,在弹出的界面中,点击Node Finder。

VHDL的串口程序

VHDL的串口程序

管脚意义clk:时钟(50M)ce:使能:高电平使能系统工作we:写操作信号:高电平有效re:正在接收标识位:高电平代表串口正在接收数据dat_in:数据输入口:写数据时的数据入口dat_out:数据输出口:接收数据的输出口rx:串口接收端:分配管脚,连线到另外一个板的tx端tx:串口输出端:分配管脚,连线到另外一个板的rx端finish:完成标志:高电平表示当前发送/接收操作已完成,进入待机状态写操作指南:1、把要发送的数据输入dat_in(dat_in的位数是8bit,串口一次传送8bit);2、查看当前finish的状态(1为等待状态,可以进行写操作);3、拉高we,进入写操作,测试finish会拉低;4、保持we两个时钟后,拉低we(不拉低,会一直写),等待finish变高电平;5、finish变高电平,写操作完成;读操作指南:1、拉低we,等待接收信号re的置位(或finish的下降沿),标志读操作;2、等待finish变成高电平;3、当finish变成高电平时,即上升沿出现时,dat_out为接收到的8bit数据;需要分配管脚的端口:rx,tx 和clk(板上的clk就ok)附加程序library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;entity USART isport(clk,ce:in std_logic;we:in std_logic;--'1'sendre:out std_logic;--receivingdat_in:in std_logic_vector(7 downto 0);dat_out:buffer std_logic_vector(7 downto 0);rx:in std_logic;tx:out std_logic;finish:buffer std_logic);end USART;architecture behave of USART istype state is (s0,s1,s2,s3);type modetype is (waiting,send,receive); signal pre_s,nx_s:state:=s0;signal clock,clk_out:std_logic;signal start,timed:std_logic;signal start2,timed2:std_logic;signal mode:modetype;signal en:std_logic:='0';signal dat:std_logic_vector(8 downto 0); signal dat_o:std_logic_vector(8 downto 0); signal t,s:std_logic;begindat_out<=dat_o(8 downto 1);s<=dat_o(0);tx<=not clk_out when mode=receive else t when mode=send else'0' ;cdiv:process(clk,en)--1usvariable cnt:integer range 0 to 25;beginif(en='0')thenclk_out<='1';cnt:=0;elsif(clk'event and clk='1')thencnt:=cnt+1;if(cnt=25)thencnt:=0;clk_out<=not clk_out;end if;end if;end process cdiv;--com:process(clock)--begin--if(clock'event and clock='1')then--pre_s<=nx_s;--end if;--end process com;con:process(clk,ce)beginif(ce='0')thennx_s<= s0;elsif(clk'event and clk='1')thencase nx_s iswhen s0=> --waitfinish<='1';mode<=waiting;start<='0';start2<='0';en<='0';if(rx='1')thenfinish<='0';mode<=receive;start<='1';en<='1';nx_s<=s1;--receiveelsif(we='1')thenfinish<='0';mode<=send;start2<='1';en<='0';nx_s<=s2;--sendelsestart<='0';start2<='0';mode<=waiting;finish<='1';en<='0';nx_s<=s0;--waitend if;when s1=> --receivestart<='1';re<='1';finish<='0';mode<=receive;en<='1';if(timed='1')thenstart<='0';finish<='1';mode<=waiting;re<='0';en<='0';nx_s<=s0;elsestart<='1';finish<='0';mode<=receive;re<='1';en<='1';nx_s<=s1;end if;when s2=> --sendstart2<='1';finish<='0';en<='0';mode<=send;if(timed2='1')thenstart2<='0';finish<='1';en<='0';mode<=waiting;nx_s<=s3;elsestart<='1';finish<='0';en<='0';mode<=send;nx_s<=s2;end if;when s3=>if(rx='0')thennx_s<=s0;elsenx_s<=s3;end if;when others=>nx_s<=s0;end case;end if;end process con;rec:process(clk_out,start) --receive variable count:integer range 0 to 9; beginif(start='0')thencount:=0;timed<='0';elsif(clk_out'event and clk_out='1')thendat_o<=dat_o(7 downto 0)& rx;count:=count+1;if(count=9)thencount:=0;timed<='1';end if;end if;end process rec;sen:process(rx,start2,dat_in) --send variable count:integer range 0 to 10; beginif(start2='0')thencount:=0;timed2<='0';t<='1';dat<=dat_in&'0';elsif(rx'event and rx='1')thent<=dat(8);dat<=dat(7 downto 0)& '0';count:=count+1;if(count=9)thencount:=0;timed2<='1';end if;end if;end process sen;end behave;。

基于VHDL的串行同步通信电路设计

基于VHDL的串行同步通信电路设计

r c i i gcr ut n i es q e c i lto e ev n ic i a d t e u n esmu ain. m
Ke wo d : y r s VHDL; n h o o sc mm u i a i n Ti e s q e e smu a i n Sy c r n u o n c t ; m e u nc i l to o
Abt c:T e crut ein f sr ls n ho o s o sat h i i r c d s o ei y c rn u c mmu iain ae o VHD n ld s e in f eil g a nc t b sd n o L icu e d sg o sr a
发 送 电路及 时序 仿真 的设 计 ,后 者 则 由波特 率 发生 器和 采 样 时钟 的设 计 、接 收 电路 的设 计及 时序仿 真 组 戍 关键 词 :V HDL 同步 通信 ; 时序仿 真 ;
中图分 类号 :T 3 30 P 9 .3 文献 标 识码 :A
Cic i De i n o e i l y c r n u mm u i a i n Ba e n VHDL r u t sg fS ra n h o o sCo S n c t s do o

致 。位 同步 是 实现 收 发 双 方 的码 元 同 步 , 由数 据
从抽象到具体级别硬件 的工业标准语言 ,它支持硬 件 的设计 、验证 、综 合和 测试 ,以及硬件 设计数据 的交 换 、维 护 、修 改和 硬 件 的 实 现 。具 有 捕述 能 力 强 、生 命 周 期 长 、支 持 大 规 模 设 计 的分 解 和 已有 设
O. . t ma i n I Au o t o 2 0 , o . 5 No 2 0 6 V 12 , .

频率计VHDL程序与仿真

频率计VHDL程序与仿真

数字频率计VHDL程序与仿真一、功能:频率计。

具有4位显示,能自动根据7位十进制计数旳成果,自动选择有效数据旳高4位进行动态显示。

小数点表达是千位,即KHz。

二、源程序及各模块和重要语句旳功能libraryieee;use ieee.std_logic_1164.all;useieee.std_logic_unsigned.all;entity plj isport(start:instd_logic;--复位信号clk :in std_logic; --系统时钟clk1:in std_logic; --被测信号yy1:out std_logic_vector(7 downto 0);--八段码w1 :out std_logic_vector(3 downto 0));--数码管位选信号endplj;architecturebehavofPLj issignalb1,b2,b3,b4,b5,b6,b7:std_logic_vector(3 downto0);--十进制计数器signalbcd:std_logic_vector(3 downto0); --BCD码寄存器signal q:integer range 0to 49999999;--秒分频系数signal qq : integer range0 to499999; --动态扫描分频系数signal en,bclk:std_logic; --使能信号,有效被测信号signal sss:std_logic_vector(3downto 0); --小数点signal bcd0,bcd1,bcd2,bcd3 :std_logic_vector(3 downto0);--寄存7位十位计数器中有效旳高4位数据beginsecond:process(clk) --此进程产生一种持续时间为一秒旳旳闸门信号beginif start='1' then q<=0;elsif clk'event and clk='1' thenif q<49999999 then q<=q+1;else q<=49999999;end if;end if;ifq<49999999 and start='0' then en<='1';else en<='0';end if;end process;and2:process(en,clk1) --此进程得到7位十进制计数器旳计数脉冲beginbclk<=clk1 anden;endprocess;com:process(start,bclk) --此进程完毕对被测信号计脉冲数beginifstart='1' then--复位b1<="0000";b2<="0000";b3<="0000";b4<="0000";b5<="0000";b6<="0000";b7<="0000";elsif bclk'event andbclk='1' thenifb1="1001"then b1<="0000"; --此IF语句完毕个位十进制计数ifb2="1001"then b2<="0000"; --此IF语句完毕百位十进制计数if b3="1001" thenb3<="0000"; --此IF语句完毕千位十进制计数ifb4="1001" then b4<="0000";--此IF语句完毕万位十进制计数if b5="1001" THENb5<="0000"; --此IF语句完毕十万位十进制计数if b6="1001" thenb6<="0000"; --此IF语句完毕百万位十进制计数if b7="1001" then b7<="0000"; --此IF语句完毕千万位十进制计数elseb7<=b7+1;endif;else b6<=b6+1;end if;else b5<=b5+1;endif;else b4<=b4+1;end if;else b3<=b3+1;end if;elseb2<=b2+1;endif;else b1<=b1+1;end if;endif;end process;process(clk) --此进程把7位十进制计数器有效旳高4位数据送入bcd0~3;并得到小数点信息beginif rising_edge(clk)thenif en='0' thenif b7>"0000" then bcd3<=b7;bcd2<=b 6; bcd1<=b5;bcd0<=b4; sss<="1110";elsif b6>"0000" thenbcd3<=b6; bcd2<=b5;bcd1<=b4;bcd0<=b3; sss<="1101";elsifb5>"0000"thenbcd3<=b5;bcd2<=b4; bcd1<=b3;bcd0<=b2;sss<="1011";ﻩelse bcd3<=b4; bcd2<=b3; bcd1<=b2; bcd0<=b1; sss<="1111";end if;end if;end if;end process;weixuan:process(clk) --此进程完毕数据旳动态显示beginif clk'event and clk='1' thenif qq< 99999 then qq<=qq+1;bcd<=bcd3; w1<="0111";ﻩif sss="0111" thenyy1(0)<='0';ﻩelseyy1(0)<='1';ﻩﻩend if;elsif qq<199999 then qq<=qq+1;bcd<=bcd2; w1<="1011";ﻩif sss="1011" then yy1(0)<='0';ﻩelseyy1(0)<='1';ﻩend if;elsifqq<299999then qq<=qq+1;bcd<=bcd1; w1<="1101";ﻩif sss="1101"then yy1(0)<='0';ﻩelse yy1(0)<='1';end if;elsif qq<399999 thenqq<=qq+1;bcd<=b cd0; w1<="1110";ifsss="1110" thenyy1(0)<='0';else yy1(0)<='1';end if;else qq<=0;end if;end if;end process;m0:process(bcd) --译码begincasebcd iswhen"0000"=>yy1(7 downto1)<="0000001";when "0001"=>yy1(7 downto1)<="1001111";when"0010"=>yy1(7 downto1)<="0010010";when "0011"=>yy1(7 downto 1)<="0000110";when "0100"=>yy1(7 downto 1)<="1001100";when "0101"=>yy1(7downto1)<="0100100";when "0110"=>yy1(7 downto 1)<="1100000";when "0111"=>yy1(7 downto1)<="0001111";when"1000"=>yy1(7downto 1)<="0000000";when "1001"=>yy1(7 downto 1)<="0001100";when others=>yy1(7 downto1)<="1111111";end case;endprocess;end behav;三、程序仿真图注:仿真中秒分频为50000,动态显示旳分频系数也相应调小。

VHDL详细语法教程

VHDL详细语法教程

VHDL详细语法教程VHDL(Very High Speed Integrated Circuit HardwareDescription Language)是一种硬件描述语言,用于对数字电路进行描述、建模和仿真。

它是一种用于描述数字系统结构和行为的语言,广泛用于FPGA(Field Programmable Gate Array)和ASIC(ApplicationSpecific Integrated Circuit)设计中。

VHDL语言具有丰富的语法结构,可以描述数字系统的结构和行为,并可以进行仿真和综合。

下面是VHDL语言的详细语法教程:1. 实体声明(Entity Declaration):VHDL代码的第一部分是实体声明,用于定义设计的接口和名称。

实体声明是设计的顶级结构,它包含输入输出端口的定义。

语法格式如下:```vhdlentity entity_name isportport_name : in/out type;port_name : in/out type;...end entity_name;```其中,entity_name为实体名称,port_name为端口名称,type为端口类型,in表示输入端口,out表示输出端口。

2. 结构体声明(Architecture declaration):在实体声明后,需要定义该实体的结构和行为。

这一部分被称为结构体声明。

语法格式如下:```vhdlarchitecture architecture_name of entity_name issignal signal_name : type;...begin...end architecture_name;```3. 信号声明(Signal declaration):信号用于在VHDL代码中传输数据。

通过信号声明,可以定义存储或传输数据的变量。

信号声明需要在结构体声明的前面进行。

语法格式如下:```vhdlsignal signal_name : type;```其中,signal_name为信号名称,type为信号类型。

VHDL串口程序

VHDL串口程序
rx_data: in std_logic_vector(7 downto 0); --接收数据寄存器,保存直至下一个数据来到
rx_int: in std_logic --接收数据中断信号,接收数据期间时钟为高电平,传送给串口发送
bps_start:out std_logic; --接收到数据后,波特率时钟启动置位
rx_data: out std_logic_vector(7 downto 0); --接收数据寄存器,保存直至下一个数据来到
rx_int: out std_logic --接收数据中断信号,接收数据期间时钟为高电平,传送给串口发送
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity uart_rx is
port(clk : in std_logic; --系统时钟
rst_n=>rst_n, --复位信号
rs232_tx=>rs232_tx, --RS232发送数据信号
clk_bps=>clk_bps_2, --此时clk_bps的高电平为发送数据的采样点
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity uart is
port(clk : in std_logic; --系统时钟
rst_n: in std_logic; --复位信号
clk_bps=>clk_bps_2,
bps_start=>bps_start_2
);
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

要做FPGA的串口通信毕业设计,一点思路都没有.谁做过这个题目啊!谁有这个题目的论文发我邮箱,最好是一套的开题报告英文翻译什么的都有.有点是点!本问题满意50分.问题补充:邮箱baiguihu2008@提问者:wetsky2008 - 一级最佳答案检举你应该是想实现单片机与FPGA的串口通信。

以下内容可能会对你有所帮助:根据RS232 异步串行通信来的帧格式,在FPGA发送模块中采用的每一帧格式为:1位开始位+8位数据位+1位奇校验位+1位停止位,波特率为2400。

本系统设计的是将一个16位的数据封装成高位帧和低位帧两个帧进行发送,先发送低位帧,再发送高位帧,在传输数据时,加上文件头和数据长度,文件头用555555来表示,只有单片机收到555555时,才将下面传输的数据长度和数据位进行接收,并进行奇校验位的检验,正确就对收到的数据进行存储处理功能,数据长度可以根据需要任意改变。

由设置的波特率可以算出分频系数,具体算法为分频系数X=CLK/(BOUND*2)。

可由此式算出所需的任意波特率。

下面是实现上述功能的VHDL源程序。

Library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_arith.all;use ieee.std_logic_unsigned.all;entity atel2_bin isport( txclk: in std_logic; --2400Hz的波特率时钟reset: in std_logic; --复位信号din: in std_logic_vector(15 downto 0); --发送的数据start: in std_logic; --允许传输信号sout: out std_logic --串行输出端口);end atel2_bin;architecture behav of atel2_bin issignal thr,len: std_logic_vector(15 downto 0);signal txcnt_r: std_logic_vector(2 downto 0);signal sout1: std_logic;signal cou: integer:=0;signal oddb:std_logic;type sis(start1,start2,shift1,shift2,odd1,odd2,stop 1,stop2);signal state:s:=start1;beginprocess(txclk)beginif rising_edge(txclk) thenif cou<3 then thr<=0000000001010101; --发送的文件头elsif cou=3 thenthr<=0000000000000010; --发送的文件长度elsif (cou>3 and state=stop2) thenthr<=din;--发送的数据end if;end if;end process;process(reset,txclk)variable tsr,tsr1,oddb1,oddb2: std_logic_vector(7 downto 0); beginif reset=1 thentxcnt_r<=(others=>0);sout1<=1;state<=start1;cou<=0;elsif txclk event and txclk=1 then case state iswhen start1=>if start=1 thenif cou=3 thenlen<=thr;end if;tsr:=thr(7 downto 0);oddb1:=thr(7 downto 0);sout1<=0; --起始位txcnt_r<=(others=>0);state<=shift1;elsestate<=start1;end if;when shift1=>oddb<=oddb1(7) xor oddb1(6) xor oddb1(5) xor oddb1(4) xor oddb1(3) xor oddb1(2) xor oddb1(1) xor oddb1(0);sout1<=tsr(0); --数据位tsr(6 downto 0):=tsr(7 downto 1);tsr(7):=0;txcnt_r<=txcnt_r+1;if (txcnt_r=7) thenstate<=odd1;cou<=cou+1;end if;when odd1=> --奇校验位if oddb=1 thensout1<=0;state<=stop1;elsesout1<=1;state<=stop1;end if;when stop1=>sout1<=1; --停止位if cou<4 thenstate<=start1;elsestate<=start2;end if;when start2=>tsr1:=thr(15 downto 8);oddb2:=thr(15 downto 8);sout1<=0; --起始位txcnt_r<=(others=>0);state<=shift2;when shift2=>oddb<=oddb2(7) xor oddb2(6) xor oddb2(5) xor oddb2(4) xor oddb2(3) xor oddb2(2) xor oddb2(1) xor oddb2(0);sout1<=tsr1(0);--数据位tsr1(6 downto 0):=tsr1(7 downto 1);tsr1(7):=0;txcnt_r<=txcnt_r+1;if (txcnt_r=7) thenstate<=odd2;end if;when odd2=> --奇校验位if oddb=1 thensout1<=0;state<=stop2;elsesout1<=1;state<=stop2;end if;when stop2=>sout1<=1; --停止位if len=0000000000000000 then state<=stop2;elsestate<=start1;len<=len-1;end if;end case;end if;end process;sout<=sout1;end behav;剩下的波形仿真就自己搞定。

希望这些内容对你有所帮助!!相关内容已发到你邮箱Library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_arith.all;use ieee.std_logic_unsigned.all;entity atel2_bin isport( txclk: in std_logic; --2400Hz的波特率时钟reset: in std_logic; --复位信号din: in std_logic_vector(15 downto 0); --发送的数据start: in std_logic; --允许传输信号sout: out std_logic --串行输出端口);end atel2_bin;architecture behav of atel2_bin issignal thr,len: std_logic_vector(15 downto 0);signal txcnt_r: std_logic_vector(2 downto 0);signal sout1: std_logic;signal cou: integer:=0;signal oddb:std_logic;type s is(start1,start2,shift1,shift2,odd1,odd2,stop1,stop2);signal state:s:=start1;beginprocess(txclk)beginif rising_edge(txclk) thenif cou<3 then thr<=0000000001010101; --发送的文件头elsif cou=3 thenthr<=0000000000000010; --发送的文件长度elsif (cou>3 and state=stop2) then thr<=din;--发送的数据end if;end if;end process;process(reset,txclk)variable tsr,tsr1,oddb1,oddb2: std_logic_vector(7 downto 0); beginif reset=1 thentxcnt_r<=(others=>0);sout1<=1;state<=start1;cou<=0;elsif txclk event and txclk=1 thencase state iswhen start1=>if start=1 thenif cou=3 thenlen<=thr;end if;tsr:=thr(7 downto 0);oddb1:=thr(7 downto 0);sout1<=0; --起始位txcnt_r<=(others=>0);state<=shift1;elsestate<=start1;end if;when shift1=>oddb<=oddb1(7) xor oddb1(6) xor oddb1(5) xor oddb1(4) xor oddb1(3) xoroddb1(2) xor oddb1(1) xor oddb1(0);sout1<=tsr(0); --数据位tsr(6 downto 0):=tsr(7 downto 1);tsr(7):=0;txcnt_r<=txcnt_r+1;if (txcnt_r=7) thenstate<=odd1;cou<=cou+1;end if;when odd1=> --奇校验位if oddb=1 thensout1<=0;state<=stop1;elsesout1<=1;state<=stop1;end if;when stop1=>sout1<=1; --停止位if cou<4 thenstate<=start1;elsestate<=start2;end if;when start2=>tsr1:=thr(15 downto 8);oddb2:=thr(15 downto 8);sout1<=0; --起始位txcnt_r<=(others=>0);state<=shift2;when shift2=>oddb<=oddb2(7) xor oddb2(6) xor oddb2(5) xor oddb2(4) xor oddb2(3) xoroddb2(2) xor oddb2(1) xor oddb2(0);sout1<=tsr1(0);--数据位tsr1(6 downto 0):=tsr1(7 downto 1);tsr1(7):=0;txcnt_r<=txcnt_r+1;if (txcnt_r=7) thenstate<=odd2;end if;when odd2=> --奇校验位if oddb=1 thensout1<=0;state<=stop2;elsesout1<=1;state<=stop2;end if;when stop2=>sout1<=1; --停止位if len=0000000000000000 thenstate<=stop2;elsestate<=start1;len<=len-1;end if;end case;end if;end process;sout<=sout1;end behav;。

相关文档
最新文档