基于Verilog HDL数字电位器ADN2850的串口控制

合集下载

verilog 逻辑函数 串口发送

verilog 逻辑函数 串口发送

verilog 逻辑函数串口发送摘要:1.Verilog 逻辑函数概述2.串口发送原理3.Verilog 实现串口发送的逻辑函数4.应用实例正文:【1.Verilog 逻辑函数概述】Verilog 是一种硬件描述语言,主要用于数字电路和模拟混合信号电路的描述。

它的语法简洁,易于理解和使用。

在数字电路设计中,逻辑函数是基本的构建模块,通过组合这些模块可以实现复杂的数字电路。

【2.串口发送原理】串口(Serial Port)是一种计算机硬件接口,可以通过串行通信传输数据。

发送数据时,数据被逐个比特按顺序传送,这样可以减少线路的传输次数,提高通信效率。

在电子设备中,如单片机、FPGA 等,通常会使用串口进行数据通信。

【3.Verilog 实现串口发送的逻辑函数】要实现串口发送功能,首先需要设计一个状态机,控制数据的发送过程。

下面是一个简单的Verilog 代码示例,实现一个8 位串口发送器:```verilogmodule serial_port_sender(input wire clk, // 时钟信号input wire rst_n, // 低电平复位信号input wire start, // 开始发送信号input wire [7:0] data, // 发送数据output wire busy // 忙碌信号);// 定义状态机typedef enum logic [1:0] {IDLE, SENDING} state_t; state_t current_state, next_state;always_ff @(posedge clk or negedge rst_n) begin if (!rst_n) begincurrent_state <= IDLE;end else begincurrent_state <= next_state;endendalways_comb begincase (current_state)IDLE: beginif (start &&!busy) beginnext_state = SENDING;endendSENDING: beginif (data == 8"b0000_0001) begin // 发送结束标志next_state = IDLE;end else begin// 发送数据busy = 1;next_state = SENDING;endendendcaseendendmodule```【4.应用实例】上述代码实现了一个简单的8 位串口发送器。

verilog 串口时钟相位控制字-概述说明以及解释

verilog 串口时钟相位控制字-概述说明以及解释

verilog 串口时钟相位控制字-概述说明以及解释1.引言1.1 概述概述部分的内容可以包括对verilog 串口时钟相位控制字的简要介绍和重要性的提及。

可以参考以下内容进行编写:在现代通信领域中,串口通信起到了至关重要的作用。

而在串口通信中,时钟相位控制字是一个非常关键的概念。

verilog 串口时钟相位控制字是指通过调节时钟信号的相位来进行数据传输的一种技术。

时钟相位控制字的作用在于确保在数据传输过程中,接收方能够正确地识别发送方发送的数据。

通过调整时钟信号的相位,可以使得接收方在正确的时间点对数据进行采样,从而减少数据传输过程中可能会出现的误差。

时钟相位控制字的设计和调整对于串口通信的稳定性和可靠性具有非常重要的意义。

合理地设置时钟相位控制字可以提高数据传输的成功率,并减少传输过程中可能出现的错误。

因此,了解verilog 串口时钟相位控制字的原理和作用对于串口通信的设计和实现是至关重要的。

在本篇文章中,将详细介绍verilog 串口时钟相位控制字的原理和作用,希望能够为读者提供一个全面的了解,并为未来的研究和应用提供有益的参考。

1.2文章结构1.2 文章结构本文将围绕Verilog串口时钟相位控制字展开讨论,主要分为以下几个部分:第一部分是引言,包括概述、文章结构和目的。

在概述部分,将介绍串口通信的基本原理和应用领域。

文章结构部分将简要介绍本文的章节安排和内容要点。

目的部分将说明本文的研究目的和意义。

第二部分是正文,主要包括串口通信原理和时钟相位控制字的作用。

在串口通信原理部分,将介绍串口通信的基本原理,包括数据传输的方式、波特率的定义和选择。

时钟相位控制字的作用部分将详细探讨时钟相位控制字在串口通信中的作用及其实现原理。

第三部分是结论,主要总结本文的主要内容和研究成果。

在总结部分,将回顾本文的研究目的和主要内容,并对所得出的结论进行归纳和概括。

对未来研究的展望部分将提出一些关于Verilog串口时钟相位控制字相关研究的展望和建议,以促进相关领域的进一步研究和发展。

基于FPGA的多串口控制器的设计与实现

基于FPGA的多串口控制器的设计与实现

基于FPGA的多串口控制器的设计与实现作者:胥飞燕郑华荣周宦银胡洁微曹剑锋来源:《物联网技术》2017年第10期摘要:针对工程应用中经常需要使用一个控制终端与多个设备通信的问题,文中设计了基于FPGA的多串口控制器。

该控制器实现了一对四的多串口通信功能,为控制器中的每个串口都分配了一个FIFO,用以缓存收到的数据,并为每个设备的串口设置了优先级,在工作中控制器优先响应优先级别高的串口请求。

文中详述了各功能模块的设计思路和方法,且各功能模块都通过了ISim仿真,验证了本设计的正确性。

关键词:FPGA;串口;逻辑控制;ISim仿真中图分类号:TP39;TN957 文献标识码:A 文章编号:2095-1302(2017)10-00-020 引言海上浮动的专用监测系统除搭载专用探头外,还有温度传感器、GPS定位系统、北斗定位系统等设备。

这些设备都需要与控制终端进行串口通信,以便响应控制终端的命令及回传监测数据,但在控制终端上为每个设备都分配一个串口是不合理的,因此为了提高系统的集成度,降低硬件成本,有必要设计一种一对多的串口通信控制器。

1 多串口控制器的结构多串口控制器的结构原理如图1所示。

其由逻辑控制模块和5个UARTFIFO模块构成,前者用于控制主串口(UARTFIFO_C)与其余4个从串口(UARTFIFO_i)模块的逻辑联接,UARTFIFO模块用于控制终端、搭载设备的数据收发。

2 UARTFIFO模块设计UARTFIFO模块主要由UART串口模块和FIFO模块构成,如图2所示。

UART串口模块包括波特率发生单元、发送单元和接收单元,FIFO模块具有16 B的先入先出缓存单元[1]。

表1所列为UARTFIFO模块的引脚功能表。

作为主从式通信系统,主串口需要处理4个从串口发送过来的数据,而这种情况下容易出现主串口正发送某个从串口数据时,另一个从串口也请求响应。

为了不影响后续数据的发送,同时避免数据丢失,需要为每个UART的接收模块配置一个FIFO用于缓存UART接收模块接收到的数据[2]。

串口通讯设计之Verilog实现

串口通讯设计之Verilog实现

串口通讯设计之Verilog 实现FPGA串口模块是将由RS-485发送过来的数据进行处理,提取出8位有效数据,并按异步串口通讯的格式要求输出到MAX3223的12脚。

FPGA选用Xilinx公司的Spartan II系列xc2s50。

此部分为该设计的主体。

如上所述,输入数据的传输速率为700k波特率。

为了使FPGA能够正确地对输入数据进行采样,提高分辨率能力和抗干扰能力,采样时钟必须选用比波特率更高的时钟,理论上至少是波特率时钟的2倍。

1串口通信基本特点随着多微机系统的应用和微机网络的发展,通信功能越来越显得重要。

串行通信是在一根传输线上一位一位地传送信息.这根线既作数据线又作联络线。

串行通信作为一种主要的通信方式,由于所用的传输线少,并且可以借助现存的电话网进行信息传送,因此特别适合于远距离传送。

在串行传输中,通信双方都按通信协议进行,所谓通信协议是指通信双方的一种约定。

约定对数据格式、同步方式、传送速度、传送步骤、纠错方式以及控制字符定义等问题做岀统一规定,通信双方必须共同遵守。

异步起止式的祯信息格式为:每祯信息由四部分组成:a. 1位起始位。

b. 5~8位数据位。

传送顺序是低位在前,高位在后.依次传送。

c. 一位校验位,也可以没有。

d. 最后是1位或是2位停止位。

FPGA(Field Pmgrammable Gate Array) 现场可编程门阵列在数字电路的设计中已经被广泛使用。

这种设计方式可以将以前需要多块集成芯片的电路设计到一块大模块可编程逻辑器件中,大大减少了电路板的尺寸,增强了系统的可靠性和设计的灵活性。

本文详细介绍了已在实际项目中应用的基于FPGA的串口通讯设计。

本设计分为硬件电路设计和软件设计两部分,最后用仿真验证了程序设计的正确性。

2系统的硬件设计本方案的异步串行通信的硬件接口电路图如图1所示,主要由四部分组成:RS-485数据发送模块、FPGA串口模块、MAX3223和DB9。

Verilog之串口(UART)通信

Verilog之串口(UART)通信

Verilog之串口(UART)通信0:起始位,低电平;1~8:数据位;9:校验位,高电平;10:停止位,高电平。

波特率“9600bps”表示每秒可以传输9600位。

波特率定时计数器由时钟频率除以波特率。

采集1~8位,忽略0、9、10位。

发送“0、8位数据、1、1”串口传输数据,从最低位开始,到最高位结束。

串口发送:module tx_bps_module(CLK, RSTn,Count_Sig,BPS_CLK);input CLK;input RSTn;input Count_Sig;output BPS_CLK;/***************************/reg [12:0]Count_BPS;always @ ( posedge CLK or negedge RSTn )if( !RSTn )Count_BPS <= 13'd0;else if( Count_BPS == 13'd5207 )Count_BPS <= 13'd0;else if( Count_Sig )Count_BPS <= Count_BPS + 1'b1;elseCount_BPS <= 13'd0;/********************************/assign BPS_CLK = ( Count_BPS == 13'd2604 ) ? 1'b1 : 1'b0; /*********************************/endmodulemodule tx_control_module(CLK, RSTn,TX_En_Sig, TX_Data, BPS_CLK,TX_Done_Sig, TX_Pin_Out);input CLK;input RSTn;input TX_En_Sig;input [7:0]TX_Data;input BPS_CLK;output TX_Done_Sig;output TX_Pin_Out;/********************************************************/reg [3:0]i;reg rTX;reg isDone;always @ ( posedge CLK or negedge RSTn )if( !RSTn )begini <= 4'd0;rTX <= 1'b1;isDone <= 1'b0;endelse if( TX_En_Sig )case ( i )4'd0 :if( BPS_CLK ) begin i <= i + 1'b1; rTX <= 1'b0; end4'd1, 4'd2, 4'd3, 4'd4, 4'd5, 4'd6, 4'd7, 4'd8 :if( BPS_CLK ) begin i <= i + 1'b1; rTX <= TX_Data[ i - 1 ]; end4'd9 :if( BPS_CLK ) begin i <= i + 1'b1; rTX <= 1'b1; end4'd10 :if( BPS_CLK ) begin i <= i + 1'b1; rTX <= 1'b1; end4'd11 :if( BPS_CLK ) begin i <= i + 1'b1; isDone <= 1'b1; end4'd12 :begin i <= 4'd0; isDone <= 1'b0; endendcase/********************************************************/assign TX_Pin_Out = rTX;assign TX_Done_Sig = isDone;/*********************************************************/ endmodulemodule tx_module(CLK, RSTn,TX_Data, TX_En_Sig,TX_Done_Sig, TX_Pin_Out);input CLK;input RSTn;input [7:0]TX_Data;input TX_En_Sig;output TX_Done_Sig;output TX_Pin_Out;/********************************/wire BPS_CLK;tx_bps_module U1(.CLK( CLK ),.RSTn( RSTn ),.Count_Sig( TX_En_Sig ), // input - from U2 .BPS_CLK( BPS_CLK ) // output - to U2 );/*********************************/tx_control_module U2(.CLK( CLK ),.RSTn( RSTn ),.TX_En_Sig( TX_En_Sig ), // input - from top.TX_Data( TX_Data ), // input - from top.BPS_CLK( BPS_CLK ), // input - from U2.TX_Done_Sig( TX_Done_Sig ), // output - to top .TX_Pin_Out( TX_Pin_Out ) // output - to top );/***********************************/endmodule串口接受module detect_module(CLK, RSTn,RX_Pin_In,H2L_Sig);input CLK;input RSTn;input RX_Pin_In;output H2L_Sig;/******************************/reg H2L_F1;reg H2L_F2;always @ ( posedge CLK or negedge RSTn )if( !RSTn )beginH2L_F1 <= 1'b1;H2L_F2 <= 1'b1;endelsebeginH2L_F1 <= RX_Pin_In;H2L_F2 <= H2L_F1;end/***************************************/ assign H2L_Sig = H2L_F2 & !H2L_F1;/***************************************/ endmodulemodule rx_control_module(CLK, RSTn,H2L_Sig, RX_Pin_In, BPS_CLK, RX_En_Sig,Count_Sig, RX_Data, RX_Done_Sig);input CLK;input RSTn;input H2L_Sig;input RX_En_Sig;input RX_Pin_In;input BPS_CLK;output Count_Sig;output [7:0]RX_Data;output RX_Done_Sig;/********************************************************/reg [3:0]i;reg [7:0]rData;reg isCount;reg isDone;always @ ( posedge CLK or negedge RSTn )if( !RSTn )begini <= 4'd0;rData <= 8'd0;isCount <= 1'b0;isDone <= 1'b0;endelse if( RX_En_Sig )case ( i )4'd0 :if( H2L_Sig ) begin i <= i + 1'b1; isCount <= 1'b1; end /*进入第0位,同时驱动bps_module开始计数。

基于VerilogHDL语言的串口设计说明

基于VerilogHDL语言的串口设计说明

基于Verilog HDL语言的串口设计串口Verilog HDL代码://串口moduletrans(clk,rst,en,TxD_data,Wsec,RxD,TxD,TxD_busy,rcven,RxD_data);//时钟50MHzinput clk,rst,en; //en时发送数据使能input [7:0]TxD_data; //发送数据输入input [2:0]Wsec; //波特率调节0-2400;1-4800;2-9600;3-14400;4-19200;5-38400;6-115200;7-128000input RxD; //接收数据输入端output TxD,TxD_busy,rcven;//发送,发送忙,接收结束标志输出output [7:0]RxD_data;//接收数据输出wire Baud1,Baud8;reg [7:0]addwire;//RAM地址连线reg [7:0]data;wire[7:0]AD_t;//读取RAM数据的地址用于发送wire[7:0]AD_r;//接收的数据存储在RAM中的地址wire [7:0]datawire;//数据连线//发送例化trans_ttt1(.clk_t(clk),.rst_t(rst),.en_t(en),.BTI_t(Baud1),.recen(recen),.TxD_data_t(datawire),.TxD_t(TxD),.addro_t(AD_t),.TxD_busy_t(TxD_ busy));//波特生成例化BaudGtt2(.clk_b(clk),.rst_b(rst),.BTO_b(Baud1),.BTO_R(Baud8),.Wsec_b(Wsec) );//接收例化trans_r tt3(.clk_r(clk),.rst_r(rst),.BTI_r(Baud8),.RxD_r(RxD),.RxD_data_r(RxD_data),.wren_r(wren_r),.addro_r(AD_r),.RxD_end(RxD _end));//LPM_RAM例化RAM0tt4(.address(addwire),.clock(~clk),.data(data),.wren(wren_r),.q(dataw ire));always (posedge clk or negedge rst)if(~rst)addwire <= 8'b00000000;else if(RxD_end)beginaddwire <=AD_r ;data<=RxD_data;endelse addwire<=AD_t;endmodule//发送模块moduletrans_t(clk_t,rst_t,en_t,BTI_t,TxD_data_t,TxD_t,recen,TxD_busy_t,addr o_t,recen );input clk_t,rst_t,en_t,BTI_t;input [7:0]TxD_data_t;output TxD_t;output TxD_busy_t;output recen;output [7:0]addro_t;reg TxD_t;reg [7:0]TxD_dataReg;//寄存器reg [7:0]addro_t;//reg [3:0]state;reg recen;wire TxD_busy_t;assign BaudTick = BTI_t;//波特输出// 发送启动wire TxD_ready = (state==0); // TxD_ready = 1assign TxD_busy_t = ~TxD_ready;// 加载发送数据always (posedge clk_t or negedge rst_t)if(~rst_t)TxD_dataReg <= 8'b00000000;else if(TxD_ready && en_t)TxD_dataReg <= TxD_data_t;// 状态机发送always (posedge clk_t or negedge rst_t)if(~rst_t)beginstate <= 4'b0000; // 复位时发送1TxD_t <= 1'b1;endelsecase(state)4'b0000: if(en_t ) beginstate <= 4'b0100; // 检测发送开始end4'b0100: if(BaudTick && en_t) beginstate <= 4'b1000; // 发送起始位0TxD_t <= 1'b0;end4'b1000: if(BaudTick && en_t) beginstate <= 4'b1001; // bit 0if(en_t) TxD_t <= TxD_dataReg[0];else TxD_t <= 1'b0;end4'b1001: if(BaudTick && en_t) beginstate <= 4'b1010; // bit 1if(en_t) TxD_t <= TxD_dataReg[1];else TxD_t <= 1'b0;end4'b1010: if(BaudTick && en_t) beginstate <= 4'b1011; // bit 2if(en_t) TxD_t <= TxD_dataReg[2];else TxD_t <= 1'b0;end4'b1011: if(BaudTick && en_t) beginstate <= 4'b1100; // bit 3if(en_t) TxD_t <= TxD_dataReg[3];else TxD_t <= 1'b0;end4'b1100: if(BaudTick && en_t) beginstate <= 4'b1101; // bit 4if(en_t) TxD_t <= TxD_dataReg[4];else TxD_t <= 1'b0;end4'b1101: if(BaudTick && en_t) beginstate <= 4'b1110; // bit 5if(en_t) TxD_t <= TxD_dataReg[5];else TxD_t <= 1'b0;end4'b1110: if(BaudTick && en_t) beginstate <= 4'b1111; // bit 6if(en_t) TxD_t <= TxD_dataReg[6];else TxD_t <= 1'b0;end4'b1111: if(BaudTick && en_t) beginstate <= 4'b0010; // bit 7if(en_t) TxD_t <= TxD_dataReg[7];else TxD_t <= 1'b0;end4'b0010: if(BaudTick && en_t) beginstate <= 4'b0011; // stop1TxD_t <= 1'b1;end4'b0011: if(BaudTick) beginstate <= 4'b0000; // stop2TxD_t <= 1'b1;enddefault: if(BaudTick) beginstate <= 4'b0000;TxD_t <= 1'b1;endendcasealways (posedge clk_t or negedge rst_t)if(~rst_t)begin recen<=0;endelse if(~TxD_ready)recen<=1;else recen<=0;//地址计数器ddressalways (posedge clk_t or negedge rst_t)if(~rst_t)addro_t <= 8'b00000000;else if(TxD_ready && en_t)addro_t <=addro_t +1;endmodule//波特生成模块module BaudG(clk_b,rst_b,BTO_b,BTO_R,Wsec_b);input clk_b,rst_b;input [2:0]Wsec_b;output BTO_b,BTO_R;reg FT,FT8;reg [16:0]BGA;reg [16:0]BGA1;wire BTO_b = FT; //发送波特wire BTO_R = FT8;//接收模块波特=发送*16always (posedge clk_b or negedge rst_b )if(~rst_b)begin BGA <= 0;BGA1 <= 0;endelsecase(Wsec_b)0:beginif(BGA1>1302)begin FT8=1'b1; BGA1<=0; end // 接收波特=2400*16else begin FT8=1'b0; BGA1 <= BGA1+ 1;endif(BGA>62500)begin FT=1'b1;FT8=1'b1; BGA1<=0; BGA<=0; end // 发送波特=2400else begin FT=1'b0; BGA <= BGA+ 3; endend1: begin if(BGA1>651)begin FT8=1'b1; BGA1<=0; end // 接收波特=4800*16else begin FT8=1'b0; BGA1 <= BGA1+ 1;endif(BGA>62500)begin FT=1'b1; FT8=1'b1; BGA1<=0;BGA<=0; end // 发送波特=4800else begin FT=1'b0; BGA <= BGA+ 6; endend2: begin if(BGA1>651)begin FT8=1'b1; BGA1<=0; end // 接收波特=9600*16else begin FT8=1'b0; BGA1<= BGA1+ 2; endif(BGA>15625)begin FT=1'b1;FT8=1'b1; BGA1<=0; BGA<=0; end // 发送波特=9600else begin FT=1'b0; BGA <= BGA+ 3; endend3: begin if(BGA1>217)begin FT8=1'b1; BGA1<=0; end // 接收波特=14400*16else begin FT8=1'b0; BGA1 <= BGA1+ 1;endif(BGA>17361)begin FT=1'b1;FT8=1'b1; BGA1<=0; BGA<=0; end // 发送波特=14400else begin FT=1'b0; BGA <= BGA+ 5; endend4: begin if(BGA1>651)begin FT8=1'b1; BGA1<=0; end //接收波特=19200*16else begin FT8=1'b0; BGA1 <= BGA1+ 4;endif(BGA>15625)begin FT=1'b1; FT8=1'b1; BGA1<=0;BGA<=0; end // 发送波特=19200else begin FT=1'b0; BGA <= BGA+ 6;endend5: begin if(BGA1>244)begin FT8=1'b1; BGA1<=0; end // 接收波特=38400*16else begin FT8=1'b0; BGA1 <= BGA1+ 3;endif(BGA>15625)begin FT=1'b1;FT8=1'b1; BGA1<=0; BGA<=0; end // 发送波特=38400else begin FT=1'b0; BGA <= BGA+ 12;endend6: begin if(BGA1>217)begin FT8=1'b1; BGA1<=0; end // 接收波特=115200*16else begin FT8=1'b0; BGA1 <= BGA1+ 8;endif(BGA>434) begin FT=1'b1;FT8=1'b1; BGA1<=0; BGA<=0; end // 发送波特=115200else begin FT=1'b0; BGA <= BGA+ 1;endend7: begin if(BGA1>122)begin FT8=1'b1; BGA1<=0; end // 接收波特=128000*16else begin FT8=1'b0; BGA1 <= BGA1+ 5;endif(BGA>3125) begin FT=1'b1; BGA<=0;FT8=1'b1; BGA1<=0; end // 发送波特=128000else begin FT=1'b0; BGA <= BGA+ 8;endenddefault:begin BGA<=0;FT=1'b0;endendcaseendmodule//接收模块moduletrans_r(clk_r,rst_r,BTI_r,RxD_r,RxD_data_r,wren_r,addro_r,RxD_end);input clk_r,rst_r,RxD_r,BTI_r;output [7:0]RxD_data_r;output wren_r,RxD_end;output [7:0]addro_r;reg [3:0]bit_spacing;//两Bit间隔16reg RxD_end; //接收数据有效标志reg RxD_delay; //中间参量reg RxD_en; //接收使能reg [7:0]RxD_data_r; //接收数据输出reg [7:0]RxD_cach; //接收数据缓存reg [3:0]state;reg [7:0]addro_r; //地址reg wren_r;assign Baud8Tick = BTI_r;//接收波特always (posedge clk_r or negedge rst_r)if(~rst_r)bit_spacing<=0;elsecase(state)0: bit_spacing<=0;default:if(Baud8Tick)bit_spacing<=bit_spacing+1;endcasewire next_bit=(bit_spacing==5);//两bit间隔16波特always (posedge clk_r)if(Baud8Tick)beginRxD_delay<=RxD_r;RxD_en<=(Baud8Tick & RxD_delay & (~RxD_r));//检测接收信号是否有下降沿end//状态机接收always(posedge clk_r or negedge rst_r)if(~rst_r)state <= 4'b0000;else if(Baud8Tick)case(state)4'b0000: if(RxD_en) state <= 4'b0001; // 有下降沿开始接收4'b0001: if(next_bit) state <= 4'b1000; // bit 04'b1000: if(next_bit) state <= 4'b1001; // bit 14'b1001: if(next_bit) state <= 4'b1010; // bit 24'b1010: if(next_bit) state <= 4'b1011; // bit 34'b1011: if(next_bit) state <= 4'b1100; // bit 44'b1100: if(next_bit) state <= 4'b1101; // bit 54'b1101: if(next_bit) state <= 4'b1110; // bit 64'b1110: if(next_bit) state <= 4'b1111; // bit 74'b1111: if(next_bit) state <= 4'b0010; // 停止位4'b0010: if(next_bit) state <= 4'b0000;default: state <= 4'b0000;endcase// 移位寄存器接收always (posedge clk_r or negedge rst_r)if(~rst_r)RxD_cach <= 8'b00000000;else if(Baud8Tick && next_bit && state[3])RxD_cach <= {RxD_r, RxD_cach[7:1]};//停止位与接收结束标志位有效时将数据输出always (posedge clk_r or negedge rst_r)if(~rst_r)RxD_data_r <= 8'b00000000;else if(RxD_end && RxD_r)RxD_data_r <= RxD_cach;// 产生接收结束标志位always (posedge clk_r or negedge rst_r)if(~rst_r)begin RxD_end<=0;endelsebegin RxD_end<=(Baud8Tick && next_bit && state==4'b0010 && RxD_r);endalways (posedge clk_r or negedge rst_r)if(~rst_r)begin wren_r<=0;endelse if(RxD_end)wren_r<=1;else wren_r<=0;//地址计数器ddressalways (posedge clk_r or negedge rst_r)if(~rst_r)addro_r <= 8'b11111111;else if(RxD_end)addro_r <=addro_r +1;endmodule为了测试收发是否正常,写的Test Bench`timescale 1ns/1nsmodule trsb;reg clk,rst,en;reg [7:0]TxD_data;reg [2:0]Wsec;wire TxD,TxD_busy,rcven;wire [7:0]RxD_data;trans trsb(.clk(clk),.rst(rst),.en(en),.TxD(TxD),.Wsec(Wsec),.TxD_busy(TxD_busy),.TxD_data(TxD_data),.rcven(rcven),.RxD_data(RxD_data),.RxD(TxD));initial beginen = 0;TxD_data = 0;rst = 1;#1 Wsec=2;#54 rst=0;#70 rst=1;#10 TxD_data = 8'b11011001;#10 en = 1'b1;#1250000 en = 1'b1;endinitial begin#3790000 TxD_data = 8'b01011010; #10 en = 1'b1;#2750000 en = 1'b0;#1290000 TxD_data = 8'b101001010; #10 en = 1'b1;#2750000 en = 1'b0;endinitial beginclk = 1;while (1)#10 clk = ~clk;endendmoduleFPGA实现串行接口 RS232(1)2008-12-17 11:38串行接口(RS-232)串行接口是连接FPGA和PC机的一种简单方式。

串口通讯设计之Verilog实现

串口通讯设计之Verilog实现

串口通讯设计之V e r i l o g实现Company Document number:WUUT-WUUY-WBBGB-BWYTT-1982GT串口通讯设计之V e r i l o g实现FPGA串口模块是将由RS-485发送过来的数据进行处理,提取出8位有效数据,并按异步串口通讯的格式要求输出到MAX3223的12脚。

FPGA选用Xilinx公司的SpartanII系列xc2s50。

此部分为该设计的主体。

如上所述,输入数据的传输速率为700k波特率。

为了使FPGA能够正确地对输入数据进行采样,提高分辨率能力和抗干扰能力,采样时钟必须选用比波特率更高的时钟,理论上至少是波特率时钟的2倍。

1 串口通信基本特点随着多微机系统的应用和微机网络的发展,通信功能越来越显得重要。

串行通信是在一根传输线上一位一位地传送信息.这根线既作数据线又作联络线。

串行通信作为一种主要的通信方式,由于所用的传输线少,并且可以借助现存的电话网进行信息传送,因此特别适合于远距离传送。

在串行传输中,通信双方都按通信协议进行,所谓通信协议是指通信双方的一种约定。

约定对数据格式、同步方式、传送速度、传送步骤、纠错方式以及控制字符定义等问题做出统一规定,通信双方必须共同遵守。

异步起止式的祯信息格式为:每祯信息由四部分组成:位起始位。

~8位数据位。

传送顺序是低位在前,高位在后.依次传送。

c.一位校验位,也可以没有。

d.最后是1位或是2位停止位。

FPGA(Field Pmgrammable Gate Array)现场可编程门阵列在数字电路的设计中已经被广泛使用。

这种设计方式可以将以前需要多块集成芯片的电路设计到一块大模块可编程逻辑器件中,大大减少了电路板的尺寸,增强了系统的可靠性和设计的灵活性。

本文详细介绍了已在实际项目中应用的基于FPGA的串口通讯设计。

本设计分为硬件电路设计和软件设计两部分,最后用仿真验证了程序设计的正确性。

2 系统的硬件设计本方案的异步串行通信的硬件接口电路图如图1所示,主要由四部分组成:RS-485数据发送模块、FPGA 串口模块、MAX3223和DB9。

基于Verilog HDL的串行ADC控制电路设计与总结报告

基于Verilog HDL的串行ADC控制电路设计与总结报告

基于Verilog HDL的串行ADC控制电路设计与总结报告题目名称:报告人: __学院:专业:班级:学号:制作日期: __目录摘要 (1)第一章串行ADC控制控制电路的功能介绍及Verilog HDL简介 (3)1.1串行ADC控制控制电路的功能 (3)1.2Verilog HDL简介 (4)第二章组成模块简介 (5)2.1组成模块 (6)(1)、状态机 (6)(2)、锁相环 (8)(3)、累计器 (10)(4)、多路选择器 (12)第三章模拟仿真 (13)总结结论 (14)参考文献 (15)基于Verilog HDL的串行ADC控制电路设计摘要Verilog HDL的串行ADC控制电路设计,是使用高速10位逐次逼近式模数转换器( ADC)芯片TLV1572,用Verilog HDL编程语言编写状态机按一定周期采样转换模拟信号。

在Quartus2软件上完成顶层电路设计、状态机、锁相环、累加器、译码器、多路选择器等编程和封装。

各个模块完成不同的任务,合在一起就构成了Verilog HDL 的串行ADC控制电路设计,软件模拟直接在Quartus2上进行。

在此程序中关键是用于状态机,其中状态机的优势有以下几点:(1)、高效的顺序控制模型,状态机克服了纯硬件数字系统顺序方式控制不灵活的缺点。

状态dat0是对1572的初始化、状态dat1是打开1572的片选信等,一直到采集数据输出数据。

(2)容易利用现成的EDA工具进行优化设计。

由于状态机的构件简单,其中用宏模块PLL将20MHz的时钟进行分频得到想要的时钟周期。

(3)性能稳定。

状态机容易构成性能良好的同步时序逻辑模块。

(4)高速性能。

状态机载高速通信和高速控制方面,有着巨大的优势。

第二章串行ADC控制控制电路的功能介绍及Verilog HDL简介1.1串行ADC控制控制电路的功能在我们的信息时代日益更新的生活,A\D、D\A转换时刻进行着,而这些功能的实现,均以多半是以MCU或MPU的控制芯片实现的,但CPU的不稳定和低时钟严重影响着转换的效率,因此,研究状态机控制转换芯片有着现实意义。

基于Verilog HDL数字频率计的设计

基于Verilog HDL数字频率计的设计

EDA设计课程论文题目基于Verilog HDL数字频率计的设计学院通信学院专业班级学生姓名大彬哥指导教师大陆会2013年5月17日EDA设计基础实验论文摘要频率是常用的物理量, 在实际测量过程中总是尽可能地把被测参量转换成频率参量进行测量。

例如工程中用振弦式方法测量力、时间测量、速度控制等, 都可转化为频率测量。

随着科学技术与计算机应用的不断发展, 以单片机作为核心的测量控制系统层出不穷。

在被测信号中, 较多的是模拟和数字开关信号, 此外还经常遇到以频率为参数的测量信号, 例如流量、转速、晶体压力传感器以及经过参变量一频率转换后的信号等等。

因此, 频率测量是电子测量技术中最基本的测量之一。

电子计数器测频有两种方式:一是直接测频法,即在一定闸门时间内测量被测信号的脉冲个数;二是间接测频法,如周期测频法。

直接测频法适用于高频信号的频率测量,间接测频法适用于低频信号的频率测量。

本文运用现代电子设计工具, 采用V er ilogHDL语言在CPLD器件上实现了简易数字频率计的设计。

在10Hz ~ 100MHz 频率测量范围内, 该频率计能根据输入被测频率信号, 自动调整测试量程进行测试并给出测试结果的BCD 码及七段LED 译码显示。

具有体积小、可靠性高、功耗低的特点。

关键词:数字频率计 Verilog_HDL 分频计数IEDA设计基础实验论文AbstractFrequency is a common physical quantities, in actual measurement process is always possible, the measured parameters are converted into the frequency parameter measurement. For example, engineering with vibrating method for measuring force, measurement of time, velocity control, can all be converted into frequency measurement. With the development of science and technology and the continuous development of computer applications, to single-chip microcomputer as the core control system for measuring the emerge in an endless stream. In the measured signal, more is analog and digital switch signal, in addition also frequently encountered with a frequency parameter measurement signal, such as flow rate, rotational speed, crystal pressure sensor and the variable frequency converted signal and so on. Therefore, the frequency measurement is the electronic measurement technology in the most fundamental measurement of.Electronic counter frequency measurement in two ways : one is the direct frequency measurement Law, or within a certain time gates of measured signal pulse number; two is the indirect frequency measurement Law, such as cycle frequency measurement method. Direct frequency measurement Law is applicable to the high frequency signal frequency measurement, indirect frequency measurement Law is applicable to low-frequency signals in the frequency measurement. The use of modern electronic design tool, using V Er ilogHDL language in CPLD device achieves simple digital frequency meter design. In the10Hz100MHz frequency measurement range, the frequency meter according to input the measured frequency signal, automatic adjustment and test range tested and the test results are given in the BCD code and the seven LED decoding display. Has the advantages of small volume, high reliability, low power consumption.Keywords: digital frequency meter Verilog_HDL frequency countingIIEDA设计基础实验论文目录摘要 (I)ABSTRACT (II)第1章绪论 (1)1.1数字频率计概况 (1)1.2本文研究内容 (1)1.3目的与意义 (2)第2章系统设计方案 (3)2.1数字频率计总体设计方案 (3)2.1.1 放大整形 (3)2.1.2 SW1、SW2、SW3按键 (3)2.1.3 标准时钟 (3)2.1.4 LED显示模块 (3)2.2系统的参数 (4)2.2.1 频率测量 (4)2.2.2 频率测量方法 (4)2.2.3 功能及技术指标 (4)第3章数字频率计的基本原理 (6)3.1计数模块COUNTER (6)3.2门控模块GATE_CONTROL (6)3.3分频模块FDIV (7)3.4寄存器模块FLIP_LATCH (7)3.5多路选择模块DATA_MUX (8)3.6动态位选模块DISPSELECT (9)3.7BCD译码模块DISPDECODER (11)第4章数字频率计软件设计 (15)4.1软件实现功能综述 (15)4.2多路选择模块DATA_MUX的设计 (15)4.2.1 多路选择模块data_mux的接口电路 (15)4.2.2 多路选择模块data_mux程序设计 (16)4.3动态位选模块DISPSELECT的设计 (17)4.3.1 动态位选模块dispselec的接口电路 (17)4.3.2 动态位选模块dispselec的程序设计 (17)IIIEDA设计基础实验论文4.4BCD译码模块DISPDECODER的设计 (18)4.4.1 BCD译码模块dispdecoder的接口电路 (18)4.4.2 BCD译码模块dispdecoder的程序设计 (19)第5章数字频率计系统的仿真分析 (23)5.1系统原理图 (23)5.2多路选择模块DATA_MUX的仿真分析 (24)5.3动态位选模块DISPSELEC的仿真分析 (25)5.4BCD译码模块DISPDECODER的仿真分析 (25)5.5软硬件调试 (26)结论 (28)参考文献 (29)IVEDA设计基础实验论文第1章绪论1.1数字频率计概况频率是常用的物理量, 在实际测量过程中总是尽可能地把被测参量转换成频率参量进行测量。

基于Verilog_HDL的信号处理板卡中双向端口的设计

基于Verilog_HDL的信号处理板卡中双向端口的设计

*基金项目: 四川省科技公关 编号: 05G0071201 http: //www.cicma g.com
2008 ·6· ( 总第 109 期) 71
应用
CIC 中国集成电路
China lnte gra te d Circult
向端口的设计介绍很少, 本文给出 FPGA 中双向端 口的设计原理和方法, 以及仿真和初始化双向端口 的方法, 同时 选用 Xilinx Virtex- 4 芯 片 进 行 实 际 应 用。
2 信号处理板卡的系统构成 及数据存储芯片
通过片上外设总线进行访问。TMS320C6713 片外设 备( 存储器或 I/O) 通 过外部存储器接口( EMIF) 进 行访问, 分成 4 个存储空间, 每个存储空间可独立进 行 配 置 , 并 提 供 了 32- bit 位 宽 的 外 部 存 储 器 接 口 (EMIF), 总 共 可 寻 址 512MB 的 存 储 器 空 间, 可 无 缝 挂接各种常见的同步异步存储器。本设计中挂接了 一个 SDRAM 和一个 Flash。
2. 2 DSP 芯片介绍
TMS320C6713 片上外设被映射到存储空间中,
3 双向端口的设计 和 Ver i l ogHDL 程序设计
72 ( 总第 109 期) 2008 ·6·
http: //www.cicma g.com
CIC 中国集成电路 China lnte gra te d Circult
http: //www.cicma g.com
2008 ·6· ( 总第 109 期) 73
应用
CIC 中国集成电路
China lnte gra te d Circult
endmodule
3. 3 双向端口的仿真结果

fpga控制数字电位器使用方法

fpga控制数字电位器使用方法

fpga控制数字电位器使用方法下载提示:该文档是本店铺精心编制而成的,希望大家下载后,能够帮助大家解决实际问题。

文档下载后可定制修改,请根据实际需要进行调整和使用,谢谢!本店铺为大家提供各种类型的实用资料,如教育随笔、日记赏析、句子摘抄、古诗大全、经典美文、话题作文、工作总结、词语解析、文案摘录、其他资料等等,想了解不同资料格式和写法,敬请关注!Download tips: This document is carefully compiled by this editor. I hope that after you download it, it can help you solve practical problems. The document can be customized and modified after downloading, please adjust and use it according to actual needs, thank you! In addition, this shop provides you with various types of practical materials, such as educational essays, diary appreciation, sentence excerpts, ancient poems, classic articles, topic composition, work summary, word parsing, copy excerpts, other materials and so on, want to know different data formats and writing methods, please pay attention!FPGA控制数字电位器使用方法一、概述在现代电子领域中,FPGA(现场可编程门阵列)已经成为一种常见的可编程器件,用于实现数字逻辑控制和信号处理。

串口接收端verilog代码分析

串口接收端verilog代码分析

串⼝接收端verilog代码分析串⼝接收端verilog代码分析`timescale 1ns / 1ps//////////////////////////////////////////////////////////////////////////////////// Company:// Engineer: chensimin//// Create Date: 2018/05/23 16:14:30// Design Name:// Module Name: uart_rx// Project Name:// Target Devices:// Tool Versions:// Description://// Dependencies://// Revision:// Revision 0.01 - File Created// Additional Comments:////////////////////////////////////////////////////////////////////////////////////module uart_rx(input wire clk,input wire rxd,output reg [7:0]data_i,output wire receive_ack);reg [7:0] data_i = 0;localparam IDLE = 0,RECEIVE = 1,RECEIVE_END = 2;reg [3:0]cur_st = 0;reg [3:0]nxt_st = 0;always @(posedge clk)begincur_st <= nxt_st;endalways @(*)beginnxt_st = cur_st;case(cur_st)IDLE:beginif(!rxd) //当从接收端⼝上进来的数据开始为0时,即启动接收nxt_st = RECEIVE;endRECEIVE:beginif(count == 7)nxt_st = RECEIVE_END;endRECEIVE_END:beginnxt_st = IDLE;enddefault:beginnxt_st = IDLE;endendcaseendreg [4:0]count = 0;always @(posedge clk)beginif(cur_st == RECEIVE)count <= count + 1;else if(cur_st == IDLE || cur_st == RECEIVE_END)count <= 0;end//当前状态为接收状态时,rxd 信号线上的数据存储在data_i的最⾼位//同时data_i 的数据总体右移⼀位always @(posedge clk)beginif(cur_st == RECEIVE)begindata_i[6:0] <= data_i[7:1];data_i[7] <= rxd; // rxd 传过来什么数据, data_i上⽴马显⽰什么数据,因为是从端⼝采集到的数据endendassign receive_ack = (cur_st == RECEIVE_END) ? 1: 0;endmodule/*add_force {/uart_rx/clk} -radix hex {1 0ns} {0 50000ps} -repeat_every 100000psadd_force {/uart_rx/rxd} -radix hex {1 0ns} {0 300ns} {1 400ns} {0 500ns} {1 600ns} {0 700ns} {1 800ns} {0 900ns} {1 1000ns} */仿真结果:注意: 分析寄存器的更新⼀定要结合时钟沿,然后寄存器在时钟沿前后的变化状态。

基于VerilogHDL语言的串口设计说明

基于VerilogHDL语言的串口设计说明

基于Verilog HDL语言的串口设计串口Verilog HDL代码://串口module trans(clk,rst,en,TxD_data,Wsec,RxD,TxD,TxD_busy,rcven,RxD_data);//时钟50MHzinput clk,rst,en; //en时发送数据使能input [7:0]TxD_data; //发送数据输入input [2:0]Wsec; //波特率调节0-2400;1-4800;2-9600;3-14400;4-19200;5-38400;6-115200;7-128000input RxD; //接收数据输入端output TxD,TxD_busy,rcven;//发送,发送忙,接收结束标志输出output [7:0]RxD_data;//接收数据输出wire Baud1,Baud8;reg [7:0]addwire;//RAM地址连线reg [7:0]data;wire[7:0]AD_t;//读取RAM数据的地址用于发送wire[7:0]AD_r;//接收的数据存储在RAM中的地址wire [7:0]datawire;//数据连线//发送例化trans_t tt1(.clk_t(clk),.rst_t(rst),.en_t(en),.BTI_t(Baud1),.recen(recen),.TxD_data_t(datawire),.TxD_t(TxD),.addro_t(AD_t),.TxD_busy_t(TxD_busy));//波特生成例化BaudG tt2(.clk_b(clk),.rst_b(rst),.BTO_b(Baud1),.BTO_R(Baud8),.Wsec_b(Wsec));//接收例化trans_r tt3(.clk_r(clk),.rst_r(rst),.BTI_r(Baud8),.RxD_r(RxD),.RxD_data_r(RxD_data),.wren_r(wren_r),.addro_r(AD_r),.RxD_end(RxD_end));//LPM_RAM例化RAM0tt4(.address(addwire),.clock(~clk),.data(data),.wren(wren_r),.q(datawire));always (posedge clk or negedge rst)if(~rst)addwire <= 8'b00000000;else if(RxD_end)beginaddwire <=AD_r ;data<=RxD_data;endelse addwire<=AD_t;endmodule//发送模块moduletrans_t(clk_t,rst_t,en_t,BTI_t,TxD_data_t,TxD_t,recen,TxD_busy_t,addro_t,recen );input clk_t,rst_t,en_t,BTI_t;input [7:0]TxD_data_t;output TxD_t;output TxD_busy_t;output recen;output [7:0]addro_t;reg TxD_t;reg [7:0]TxD_dataReg;//寄存器reg [7:0]addro_t;//reg [3:0]state;reg recen;wire TxD_busy_t;assign BaudTick = BTI_t;//波特输出// 发送启动wire TxD_ready = (state==0); // TxD_ready = 1assign TxD_busy_t = ~TxD_ready;// 加载发送数据always (posedge clk_t or negedge rst_t)if(~rst_t)TxD_dataReg <= 8'b00000000;else if(TxD_ready && en_t)TxD_dataReg <= TxD_data_t;// 状态机发送always (posedge clk_t or negedge rst_t)if(~rst_t)beginstate <= 4'b0000; // 复位时发送1TxD_t <= 1'b1;endelsecase(state)4'b0000: if(en_t ) beginstate <= 4'b0100; // 检测发送开始end4'b0100: if(BaudTick && en_t) beginstate <= 4'b1000; // 发送起始位0end4'b1000: if(BaudTick && en_t) beginstate <= 4'b1001; // bit 0if(en_t) TxD_t <= TxD_dataReg[0];else TxD_t <= 1'b0;end4'b1001: if(BaudTick && en_t) beginstate <= 4'b1010; // bit 1if(en_t) TxD_t <= TxD_dataReg[1];else TxD_t <= 1'b0;end4'b1010: if(BaudTick && en_t) beginstate <= 4'b1011; // bit 2if(en_t) TxD_t <= TxD_dataReg[2];else TxD_t <= 1'b0;end4'b1011: if(BaudTick && en_t) beginstate <= 4'b1100; // bit 3if(en_t) TxD_t <= TxD_dataReg[3];else TxD_t <= 1'b0;end4'b1100: if(BaudTick && en_t) beginstate <= 4'b1101; // bit 4if(en_t) TxD_t <= TxD_dataReg[4];else TxD_t <= 1'b0;end4'b1101: if(BaudTick && en_t) beginstate <= 4'b1110; // bit 5if(en_t) TxD_t <= TxD_dataReg[5];else TxD_t <= 1'b0;end4'b1110: if(BaudTick && en_t) beginstate <= 4'b1111; // bit 6if(en_t) TxD_t <= TxD_dataReg[6];else TxD_t <= 1'b0;end4'b1111: if(BaudTick && en_t) beginstate <= 4'b0010; // bit 7if(en_t) TxD_t <= TxD_dataReg[7];else TxD_t <= 1'b0;end4'b0010: if(BaudTick && en_t) beginstate <= 4'b0011; // stop1end4'b0011: if(BaudTick) beginstate <= 4'b0000; // stop2TxD_t <= 1'b1;enddefault: if(BaudTick) beginstate <= 4'b0000;TxD_t <= 1'b1;endendcasealways (posedge clk_t or negedge rst_t)if(~rst_t)begin recen<=0;endelse if(~TxD_ready)recen<=1;else recen<=0;//地址计数器ddressalways (posedge clk_t or negedge rst_t)if(~rst_t)addro_t <= 8'b00000000;else if(TxD_ready && en_t)addro_t <=addro_t +1;endmodule//波特生成模块module BaudG(clk_b,rst_b,BTO_b,BTO_R,Wsec_b);input clk_b,rst_b;input [2:0]Wsec_b;output BTO_b,BTO_R;reg FT,FT8;reg [16:0]BGA;reg [16:0]BGA1;wire BTO_b = FT; //发送波特wire BTO_R = FT8;//接收模块波特=发送*16always (posedge clk_b or negedge rst_b )if(~rst_b)begin BGA <= 0;BGA1 <= 0;endelsecase(Wsec_b)0:begin接收波特=2400*16else begin FT8=1'b0; BGA1 <= BGA1+ 1; endif(BGA>62500)begin FT=1'b1;FT8=1'b1; BGA1<=0; BGA<=0; end // 发送波特=2400else begin FT=1'b0; BGA <= BGA+ 3; endend1: begin if(BGA1>651)begin FT8=1'b1; BGA1<=0; end //接收波特=4800*16else begin FT8=1'b0; BGA1 <= BGA1+ 1; endif(BGA>62500)begin FT=1'b1; FT8=1'b1; BGA1<=0;BGA<=0; end // 发送波特=4800else begin FT=1'b0; BGA <= BGA+ 6; endend2: begin if(BGA1>651)begin FT8=1'b1; BGA1<=0; end // 接收波特=9600*16else begin FT8=1'b0; BGA1<= BGA1+ 2; endif(BGA>15625)begin FT=1'b1;FT8=1'b1; BGA1<=0; BGA<=0; end // 发送波特=9600else begin FT=1'b0; BGA <= BGA+ 3; endend3: begin if(BGA1>217)begin FT8=1'b1; BGA1<=0; end // 接收波特=14400*16else begin FT8=1'b0; BGA1 <= BGA1+ 1;endif(BGA>17361)begin FT=1'b1;FT8=1'b1; BGA1<=0; BGA<=0; end // 发送波特=14400else begin FT=1'b0; BGA <= BGA+ 5; endend4: begin if(BGA1>651)begin FT8=1'b1; BGA1<=0; end // 接收波特=19200*16else begin FT8=1'b0; BGA1 <= BGA1+ 4;endif(BGA>15625)begin FT=1'b1; FT8=1'b1; BGA1<=0;BGA<=0; end // 发送波特=19200else begin FT=1'b0; BGA <= BGA+ 6;endend5: begin if(BGA1>244)begin FT8=1'b1; BGA1<=0; end // 接收波特=38400*16else begin FT8=1'b0; BGA1 <= BGA1+ 3;endBGA<=0; end // 发送波特=38400else begin FT=1'b0; BGA <= BGA+ 12;endend6: begin if(BGA1>217)begin FT8=1'b1; BGA1<=0; end // 接收波特=115200*16else begin FT8=1'b0; BGA1 <= BGA1+ 8;endif(BGA>434) begin FT=1'b1;FT8=1'b1; BGA1<=0; BGA<=0; end // 发送波特=115200else begin FT=1'b0; BGA <= BGA+ 1;endend7: begin if(BGA1>122)begin FT8=1'b1; BGA1<=0; end // 接收波特=128000*16else begin FT8=1'b0; BGA1 <= BGA1+ 5;endif(BGA>3125) begin FT=1'b1; BGA<=0;FT8=1'b1; BGA1<=0; end // 发送波特=128000else begin FT=1'b0; BGA <= BGA+ 8;endenddefault:begin BGA<=0;FT=1'b0;endendcaseendmodule//接收模块module trans_r(clk_r,rst_r,BTI_r,RxD_r,RxD_data_r,wren_r,addro_r,RxD_end);input clk_r,rst_r,RxD_r,BTI_r;output [7:0]RxD_data_r;output wren_r,RxD_end;output [7:0]addro_r;reg [3:0]bit_spacing;//两Bit间隔16reg RxD_end; //接收数据有效标志reg RxD_delay; //中间参量reg RxD_en; //接收使能reg [7:0]RxD_data_r; //接收数据输出reg [7:0]RxD_cach; //接收数据缓存reg [3:0]state;reg [7:0]addro_r; //地址reg wren_r;assign Baud8Tick = BTI_r;//接收波特always (posedge clk_r or negedge rst_r)if(~rst_r)bit_spacing<=0;elsecase(state)0: bit_spacing<=0;default:if(Baud8Tick)bit_spacing<=bit_spacing+1;endcasewire next_bit=(bit_spacing==5);//两bit间隔16波特always (posedge clk_r)if(Baud8Tick)beginRxD_delay<=RxD_r;RxD_en<=(Baud8Tick & RxD_delay & (~RxD_r));//检测接收信号是否有下降沿end//状态机接收always(posedge clk_r or negedge rst_r)if(~rst_r)state <= 4'b0000;else if(Baud8Tick)case(state)4'b0000: if(RxD_en) state <= 4'b0001; // 有下降沿开始接收4'b0001: if(next_bit) state <= 4'b1000; // bit 04'b1000: if(next_bit) state <= 4'b1001; // bit 14'b1001: if(next_bit) state <= 4'b1010; // bit 24'b1010: if(next_bit) state <= 4'b1011; // bit 34'b1011: if(next_bit) state <= 4'b1100; // bit 44'b1100: if(next_bit) state <= 4'b1101; // bit 54'b1101: if(next_bit) state <= 4'b1110; // bit 64'b1110: if(next_bit) state <= 4'b1111; // bit 74'b1111: if(next_bit) state <= 4'b0010; // 停止位4'b0010: if(next_bit) state <= 4'b0000;default: state <= 4'b0000;endcase// 移位寄存器接收always (posedge clk_r or negedge rst_r)if(~rst_r)RxD_cach <= 8'b00000000;else if(Baud8Tick && next_bit && state[3])RxD_cach <= {RxD_r, RxD_cach[7:1]};//停止位与接收结束标志位有效时将数据输出always (posedge clk_r or negedge rst_r)if(~rst_r)RxD_data_r <= 8'b00000000;else if(RxD_end && RxD_r)RxD_data_r <= RxD_cach;// 产生接收结束标志位always (posedge clk_r or negedge rst_r)if(~rst_r)begin RxD_end<=0;endelsebegin RxD_end<=(Baud8Tick && next_bit && state==4'b0010 && RxD_r);endalways (posedge clk_r or negedge rst_r)if(~rst_r)begin wren_r<=0;endelse if(RxD_end)wren_r<=1;else wren_r<=0;//地址计数器ddressalways (posedge clk_r or negedge rst_r)if(~rst_r)addro_r <= 8'b11111111;else if(RxD_end)addro_r <=addro_r +1;endmodule为了测试收发是否正常,写的Test Bench`timescale 1ns/1nsmodule trsb;reg clk,rst,en;reg [7:0]TxD_data;reg [2:0]Wsec;wire TxD,TxD_busy,rcven;wire [7:0]RxD_data;trans trsb(.clk(clk),.rst(rst),.en(en),.TxD(TxD),.Wsec(Wsec),.TxD_busy(TxD_busy),.TxD_data(TxD_data),.rcven(rcven),.RxD_data(RxD_data),.RxD(TxD));initial beginen = 0;TxD_data = 0;rst = 1;#1 Wsec=2;#54 rst=0;#70 rst=1;#10 TxD_data = 8'b11011001;#10 en = 1'b1;#1250000 en = 1'b1;endinitial begin#3790000 TxD_data = 8'b01011010; #10 en = 1'b1;#2750000 en = 1'b0;#1290000 TxD_data = 8'b101001010; #10 en = 1'b1;#2750000 en = 1'b0;endinitial beginclk = 1;while (1)#10 clk = ~clk;endendmoduleFPGA实现串行接口RS232(1)2008-12-17 11:38串行接口(RS-232)串行接口是连接FPGA和PC机的一种简单方式。

基于Verilog-HDL数字频率计设计与实现

基于Verilog-HDL数字频率计设计与实现

河南工程学院《EDA》课程设计系别电气信息工程系专业电子科学与技术班级0941班组员基于Verilog HDL数字频率计设计与实现摘要:在电子技术中,频率是最基本的参数之一,并且与许多电参量的测量方案、测量结果都有十分密切的关系,因此频率的测量就显得更为重要。

测量频率的方法有多种,其中电子计数器测量频率具有精度高、使用方便、测量迅速,以及便于实现测量过程自动化等优点,是频率测量的重要手段之一。

电子计数器测频有两种方式:一是直接测频法,即在一定闸门时间内测量被测信号的脉冲个数;二是间接测频法,如周期测频法。

直接测频法适用于高频信号的频率测量,间接测频法适用于低频信号的频率测量。

本文阐述了用Verilog HDL语言设计了一个简单的数字频率计的过程关键词:周期;EDA;Verilog HDL;数字频率计;波形仿真目录1 引言......................................................... - 3 -1.1 数字频率计概述.......................................... - 4 -1.2 频率测量的思想和方法.................................... - 4 -2 Verilog HDL简介............................................. - 6 -2.1 Verilog HDL的简介....................................... - 6 -2.2方案比较 (10)3 数字频率计设计原理以及实现................................... - 7 -4 总结......................................................... - 38 - 参考文献....................................................... - 39 -1 引言在电子测量领域中,频率测量的精确度是最高的,可达10—10E-13数量级。

基于HDL的多接口控制设计

基于HDL的多接口控制设计

基于HDL的多接口控制设计赵杰【摘要】为解决传统接口控制方式不灵活、后期扩展性差的问题.利用EP2C5T144C8N芯片实现VGA接口控制和AD-TLC549、DA-TLC5615转换控制,采用自顶向下的设计方法,利用Verilog HDL硬件描述语言进行硬件编程,选择Quartus II作为开发平台,实现了A/D、D/A和VGA接口的同时控制,具有开发周期短、灵活性强、通用性好、易于扩展等优点.【期刊名称】《商洛学院学报》【年(卷),期】2017(031)006【总页数】4页(P21-24)【关键词】接口控制;硬件描述语言;自顶向下【作者】赵杰【作者单位】商洛学院电子信息与电气工程学院,陕西商洛 726000【正文语种】中文【中图分类】TP333随着技术的发展,多种接口协议现已广泛用于各大领域,从航空航天、国防军事到民用通信、多媒体技术等都涉及到接口的应用[1-2]。

常见的有A/D、D/A、SPI、IIC、CAN、VGA、PCI等。

一般的实现方式以专用接口芯片或单片机、DSP控制实现为主[3-8]。

专用芯片需要为各接口协议专门配置,会增加系统成本。

单片机在很多简单控制上可以处理,但是计算速度和性能很有限[9]。

例如使用单片机进行A/D、D/A转换,进行一个采样周期中必须完成的很多操作步骤才能实现。

由于单片机指令的指令周期长,因此对于速度稍高的器件就无法控制[10],DSP等器件处理能力相对较强。

单片机、DSP等若要实现多种接口同时控制难度较大,而且后期扩展接口不方便。

本文利用FPGA允许重复擦写、在线配置灵活的特性[11-12],对常见的A/D、D/A和VGA三种接口实现同时控制。

利用主流硬件描述语言Verilog HDL描述接口控制功能,顶层设计采用原理图方式来实现,而且系统允许后期扩展接口。

1 A/D接口控制功能及实现本文以控制TLC549芯片为例。

TLC549是8位A/D转换器,采用开关电容逐次逼近的方式实现模数转换。

基于Verilog HDL数字电位器ADN2850的串口控制

基于Verilog HDL数字电位器ADN2850的串口控制

基于Verilog HDL数字电位器ADN2850的串口控制
陈厚来;吴志明;罗凤武
【期刊名称】《现代电子技术》
【年(卷),期】2009(32)8
【摘要】数字电位器由于可调精度高,更稳定,定位更准确,操作更方便,数据可长期保存和随时刷新等优点,在某些场合具有模拟电位器不可比拟的优势.论述对数字电位器ADN2850的一种方便的控制方法,通过计算机上的串口直接对ADN2850进行写入和控制.该方法简洁、高效,明显提高了调试效率.给出用Verilog HDL实现该方法的关键程序,该程序已经通过前仿真和板级调试,达到了预期的效果.
【总页数】3页(P122-124)
【作者】陈厚来;吴志明;罗凤武
【作者单位】电子科技大学,电子薄膜与集成器件国家重点实验室,四川,成
都,610054;电子科技大学,电子薄膜与集成器件国家重点实验室,四川,成都,610054;电子科技大学,电子薄膜与集成器件国家重点实验室,四川,成都,610054
【正文语种】中文
【中图分类】TP368.1
【相关文献】
1.基于Verilog HDL数字式竞赛抢答器的制作 [J], 程琼
2.基于Verilog HDL的FIR数字滤波器的优化设计与仿真 [J], 李玉学;白忠臣;秦水介
3.基于Verilog HDL的FPGA数字系统设计优化 [J], 李桂林;苗长新
4.基于Verilog HDL的简易数字频率计设计 [J], 杨晓岚
5.基于Verilog HDL的数字竞赛抢答器 [J], 孙阔;王颖
因版权原因,仅展示原文概要,查看原文内容请购买。

FPGA模拟串口自收发-Verilog

FPGA模拟串口自收发-Verilog

实现功能,FPGA里实现从PC串口接收数据,接着把接收到的数据发回去。

波特率可选9600bps,可调 1bit起始位,8bit数据,1bit停止位,无校验位。

参考《VHDL硬件描述语言与和数字逻辑电路设计》模块介绍如下一、串口数据接收模块:特别注意一个数据位占4个clk_bps_4时钟周期。

串口数据接收控制当数据接收端rxd出现起始位低电平,启动接收控制计数器rx_cnt,置位为8’b0111_00(28),即rx_cnt[5:2]== 4’b0111(7),rx_cnt[1:0] == 2'b00(0);一个计数周期开始,伴随clk_bps_4, rx_cnt加1(每一个数据位加4)串口接收数据移位控制(关键采样点的选取)每当rx_cnt[1:0] == 2'b01,为了保证在rxd一位数据靠近中间位置采样;每4个clk_bps_4, rx_cnt[5:2]加1当rx_cnt[5:2] == 8,9,10….15,完成8位的数据采样,串并变换置位标志位rxdF数据接收标志rxd出现起始位低电平, rxdF置1,表示数据接收开始;当rx_cnt计数到8’b1111_11(63),数据接收完成, rxdF置0置位标志位rdFULL;//接收锁存器满标志空闲时rdFULL置0,当数据接收完成,数据锁存到do_latch,同时 rdFULL置1,向上层模块表示数据以准备OK,可以来读取;rd置0,表示上层模块开始读取数据,rdFULL置0,表示数据已读走二、串口数据发送模块:数据发送依赖于wr(低电平有效)空闲时wr置1,数据发送时wr产生低电平脉冲,wr上升沿将数据锁存到din_latch; 串口数据发送控制:wr由0跳变为1后,启动发送控制计数器tx_cnt,置位为8’b0111_00(28),即t x_cnt[5:2]== 4’b0111(7), tx_cnt[1:0] == 2'b00(0);一个计数周期开始,伴随clk_bps_4, tx_cnt加1(每一个数据位加4)串口发送数据移位控制每4个clk_bps_4, tx_cnt[5:2]加1当tx_cnt[5:2] ==7,8,9,10….15,完成一位起始位,8位的数据位发送,随后txd置1(停止位),完成并串转换置位标志位txdF,tdEMPTY //发送完成标志当写数据到发送寄存器din_latch时,txdF,tdEMPTY置0;当tx_cnt计数到8’b1111_11(63),数据发送完成,txdF,tdEMPTY置1;三、串口数据自收发控制模块当rdFULL == 1&& tdEMPTY == 1(rdFULL == 1表示数据准备OK,tdEMPTY == 1表示上次发送已完成) ,rd,wr产生低脉冲,rd置0,数据读取到DATA,wr置0使能发送数据控制,低脉冲将DATA锁存到din_latch四、波特率发生模块:针对9600bps,生成4倍于波特率38.4KHz的时钟信号,用于采样代码如下:串口数据自收发控制模块module UART(clk, rst_n, rxd, txd, LED1 );input clk; //时钟周期50MHzinput rst_n; //低电平复位input rxd; //串口引脚输入<--接收<--PCoutput txd; //串口引脚输出-->发送-->PCoutput reg LED1;//lED测试用/****************************************/wire tdEMPTY;//发送寄存器空标志reg wr;//发送使能信号reg [7:0]DATA;wire clk_bps_4;//4倍于波特率时钟信号reg[1:0] wr_cnt;//wr低电平计数reg rd;//读接收锁存器信号wire[7:0] do_latch;//接收数据锁存wire rdFULL;//接收锁存器满标志reg[1:0] rd_cnt;//rd低电平计数/*当rdFULL == 1&& tdEMPTY == 1(rdFULL == 1表示接收锁锁存器数据准备OK,tdEMPTY == 1表示上次发送已完成),rd,wr产生低脉冲,rd置0,do_latch数据读取到DATA,wr置0用于使能发送数据控制,低脉冲将DATA锁存到din_latch*/always(posedge clk_bps_4 or negedge rst_n)beginif(!rst_n)beginrd <= 1;wr <= 1;wr_cnt <= 0;rd_cnt <= 0;endelsebeginif(rdFULL == 1)beginrd <= 0;wr <= 0;wr_cnt <= 0;rd_cnt <= 0;DATA <= do_latch;endif(rd == 0)//产生rd低电平 2个clk_bps_4周期beginrd_cnt <= rd_cnt + 1;if(rd_cnt == 3)rd <= 1;endif(wr == 0)//产生wr低电平 2个clk_bps_4周期beginwr_cnt <= wr_cnt + 3;if(wr_cnt == 1)wr <= 1;endendend/*发送*/Uart_TX tx( .rst_n(rst_n),.clk_bps_4(clk_bps_4),.wr(wr),.tdEMPTY(tdEMPTY),.DATA(DATA),.txd(txd));//output to tx_m/*接收*/Uart_RX rx( .rst_n(rst_n),.clk_bps_4(clk_bps_4),.rd(rd),.rdFULL(rdFULL),.do_latch(do_latch),.rxd(rxd));/*针对9600bps,生成38.4KHz的时钟信号,用于接收数据采样与数据发送*/Baudrate baud(.clk(clk),.rst_n(rst_n),.clk_bps_4(clk_bps_4));Endmodule串口数据接收模块:module Uart_RX(rst_n, clk_bps_4, rd, rdFULL, do_latch, rxd);input rst_n; //低电平复位input clk_bps_4; //4倍于波特率时钟信号即一个数据位占4个时钟周期input rd;//接收使能,低电平有效output reg[7:0] do_latch;//接收数据锁存output reg rdFULL;//接收锁存器满标志input rxd;//串口引脚输入reg[7:0] data_r = 8'bx; //接收数据寄存器reg[5:0] rx_cnt;reg rxdF;//数据接收标志,RX模块部信号/*当数据接收端rxd出现起始位低电平,启动接收控制计数器rx_cnt,置位为8’b0111_00(28),即rx_cnt[5:2]== 4’b0111(7),rx_cnt[1:0] == 2'b00(0);一个计数周期开始,伴随clk_bps_4, rx_cnt加1(每一个数据位加4)*/always(posedge clk_bps_4 or negedge rst_n)if(!rst_n)begin rx_cnt <= 0; endelse if(rx_cnt <= 27 && rxd == 0)begin rx_cnt <= 28; endelse if(rx_cnt <= 27 && rxd == 1)//串口无数据时,rx_cnt保持0begin rx_cnt <= 0; endelsebegin rx_cnt <= rx_cnt + 1;endend/*空闲时rdFULL置0,当数据接收完成,数据锁存到do_latch,同时 rdFULL置1,向上层模块表示数据以准备OK,可以来读取;rd置0,表示上层模块开始读取数据,rdFULL置0,表示数据已读走*/always(posedge clk_bps_4 or negedge rst_n)//置位标志位 rdFULLbeginif(!rst_n)begin rdFULL <= 0; endelse if(rd == 0)begin rdFULL <= 0; endelse if(rxdF == 1 && rx_cnt == 63)begindo_latch <= data_r;//数据锁存rdFULL <= 1;//锁存器数据准备OKendend/*rxd出现起始位低电平, rxdF置1,表示数据接收开始;当rx_cnt计数到8’b1111_11(63),数据接收完成, rxdF置0*/always(posedge clk_bps_4 or negedge rst_n)//置位标志位 rxdFbeginif(!rst_n)begin rxdF <= 0; endelse if(rxd == 0)//拉低表示有数据来begin rxdF <= 1;endelse if(rxdF == 1 && rx_cnt == 63)begin rxdF <= 0;endend/*每当rx_cnt[1:0] == 2'b01,为了保证在rxd一位数据靠近中间位置采样;每4个clk_bps_4, rx_cnt[5:2]加1当rx_cnt[5:2] == 8,9,10…15,完成8位的数据采样,串并变换*/always(posedge clk_bps_4)//数据接收beginif( rx_cnt[1:0] == 2'b01 )case(rx_cnt[5:2])//4'd7:rxd==0;起始位4'd8:data_r[0] <= rxd;// 低第1位4'd9:data_r[1] <= rxd;// 第2位4'd10:data_r[2] <= rxd;// 第3位4'd11:data_r[3] <= rxd;// 第4位4'd12:data_r[4] <= rxd;// 第5位4'd13:data_r[5] <= rxd;// 第6位4'd14:data_r[6] <= rxd;// 第7位4'd15:data_r[7] <= rxd;//高第8位endcaseendmodule串口数据发送模块:module Uart_TX(rst_n, clk_bps_4,wr,tdEMPTY, DATA, txd);input rst_n; //低电平复位input clk_bps_4; //4倍于波特率时钟信号input [7:0]DATA;input wr;//发送使能信号output reg tdEMPTY;//发送寄存器空标志对外输出output txd;//串口引脚输出reg txdF;//发送完成标志模块部信号reg txd_r; //发送寄存器reg[7:0] din_latch;//发送数据锁存reg[5:0] tx_cnt;//发送计数器/*空闲时wr置1,数据发送时wr产生低电平脉冲,wr上升沿将数据锁存到din_latch;*/ always(posedge wr)begin//din_latch <= 8'hAB;din_latch <= DATA;end/*wr由0跳变为1后,启动发送控制计数器tx_cnt,置位为8’b0111_00(28),即tx_cnt[5:2]== 4’b0111(7), tx_cnt[1:0] == 2'b00(0);一个计数周期开始,伴随clk_bps_4, tx_cnt加1(每一个数据位加4)*/always(posedge clk_bps_4 or negedge rst_n)beginif(!rst_n)begin tx_cnt <= 0; endelse if(tx_cnt <= 27)beginif(tdEMPTY == 0 && wr == 1)begin tx_cnt <= 28;endelse begin tx_cnt <= 0; endendelsebegin tx_cnt <= tx_cnt + 1;endend/*当写数据到发送寄存器din_latch时,txdF,tdEMPTY置0;当tx_cnt计数到8’b1111_11(63),数据发送完成,txdF,tdEMPTY置1;*/always(posedge clk_bps_4 or negedge rst_n)beginif(!rst_n)begintxdF <= 1;tdEMPTY <= 1;endelse if(wr == 0)begintxdF <= 0;tdEMPTY <= 0;endelse if(txdF == 0 && tx_cnt == 63)begintxdF <= 1;tdEMPTY <= 1;endend/*每4个clk_bps_4, tx_cnt[5:2]加1当tx_cnt[5:2] ==7,8,9,10…15,完成一位起始位,8位的数据位发送,随后txd置1(停止位),完成并串转换*/ always(posedge clk_bps_4 or negedge rst_n)if(!rst_n)begintxd_r <= 1;endelsebegincase(tx_cnt[5:2])4'd7:txd_r <= 1'b0; //起始位04'd8:txd_r <= din_latch[0]; //低第1位4'd9:txd_r <= din_latch[1]; // 第2位4'd10:txd_r <= din_latch[2];// 第3位4'd11:txd_r <= din_latch[3];// 第4位4'd12:txd_r <= din_latch[4];// 第5位4'd13:txd_r <= din_latch[5];// 第6位4'd14:txd_r <= din_latch[6];// 第7位4'd15:txd_r <= din_latch[7];//高第8位default:txd_r <= 1;endcaseendassign txd = txd_r;endmodule波特率发生模块:/*针对9600bps,生成4倍于波特率38.4KHz的时钟信号,用于采样*/ module Baudrate(clk, rst_n,clk_bps_4);input clk; //时钟周期50MHzinput rst_n; //低电平复位output clk_bps_4; //38.4KHz时钟信号 9600*4reg clk_bps_4;reg [12:0] bps_cnt; //波特率产生时计数parameter N=1302;//分频系数 9600bpsalways(posedge clk or negedge rst_n)beginif(!rst_n) begin clk_bps_4 <= 0; bps_cnt <= 0;endelsebeginif(bps_cnt == N/2 - 1)begin clk_bps_4 <= ~clk_bps_4; bps_cnt <= 0;endelsebegin bps_cnt <= bps_cnt + 1;endendendendmoduleModelsim仿真波形图:rxd端输入数据01010101,txd发送01010101连接PC 串口助手。

X458Verilog参考例程-实战训练7 FPGA与PC串口自收发通信

X458Verilog参考例程-实战训练7 FPGA与PC串口自收发通信

实战训练7 FPGA与PC串口自收发通信
串口通信其实简单实用,这里我就不多说(如果有朋友还对串口通信的协议不是很了解,建议到google输入“串口通信协议”补补)。

我们的实验要实现的功能如题,就是FPGA里实现从PC接收数据,然后把接收到的数据发回去。

使用的是串口UART协议进行收发数据。

上位机用的是串口调试助手。

在FPGA设计中,FPGA端发送数据的波特率是可选的,有以下几种:9600bp s,19200bps,38400bps,57600bps,115200bps等,这部分在模块speed_select 里,可以根据需要进行设置。

发送的数据帧格式为:1bit起始位(从高电平到低电平保持一个bit周期),8bit数据,1bit停止位,无校验位。

以下的代码有比较详细的注释,经过下载验证!此外可参考同目录下的myuartverilog里的工程,打开编译后下载到开发板即可观看实验效果。

具体的实现过程有待大家慢慢消化verilog代码。

(下载本工程代码后,打开串口调试助手,设置好波特率和FPGA中的一致,无校验位,8个数据位,1个停止位,然后在发送的字符/数据后的空白栏内输入2位16进制数据,点击手动发送即可看到上方的数据接收区内返回了刚才发送过来的数据)。

注:在FPGA核心板上做此实验时,请注意不要直接将FPGA管脚接到高于5V电平的信号线上,如需跟电脑连接,请中间加上电平转换芯片。

基于FPGA与PC串口自收发通信-Verilog

基于FPGA与PC串口自收发通信-Verilog

FPGA与PC串口自收发通信实现的功能如题,就是FPGA里实现从PC接收数据,然后把接收到的数据发回去。

使用的是串口UART协议进行收发数据。

上位机用的是通用的串口调试助手。

发送数据的波特率可选9600bps,19200bps,38400bps,57600bps,115200bps等,是可调的。

发送格式为:1bit起始位,8bit数据,1bit停止位,无校验位。

以下的代码有比较详细的注释,经过下载验证,存在误码率(<5%),仅供学习!代码如下:(顶层模块):module my_uart_top(clk,rst_n,rs232_rx,rs232_tx);input clk;// 50MHz主时钟input rst_n;//低电平复位信号input rs232_rx;// RS232接收数据信号output rs232_tx;//RS232发送数据信号wire bps_start;//接收到数据后,波特率时钟启动信号置位wire clk_bps;// clk_bps的高电平为接收或者发送数据位的中间采样点wire[7:0] rx_data;//接收数据寄存器,保存直至下一个数据来到wire rx_int;//接收数据中断信号,接收到数据期间始终为高电平//----------------------------------------------------speed_selectspeed_select(.clk(clk),//波特率选择模块,接收和发送模块复用,不支持全双工通信.rst_n(rst_n),.bps_start(bps_start),.clk_bps(clk_bps));my_uart_rxmy_uart_rx(.clk(clk),//接收数据模块.rst_n(rst_n),.rs232_rx(rs232_rx),.clk_bps(clk_bps),.bps_start(bps_start),.rx_data(rx_data),.rx_int(rx_int));my_uart_txmy_uart_tx(.clk(clk),//发送数据模块.rst_n(rst_n),.clk_bps(clk_bps),.rx_data(rx_data),.rx_int(rx_int),.rs232_tx(rs232_tx),.bps_start(bps_start));endmodulemodule speed_select(clk,rst_n,bps_start,clk_bps);input clk;// 50MHz主时钟input rst_n;//低电平复位信号input bps_start;//接收到数据后,波特率时钟启动信号置位output clk_bps;// clk_bps的高电平为接收或者发送数据位的中间采样点parameterbps9600= 5207,//波特率为9600bpsbps19200= 2603,//波特率为19200bpsbps38400= 1301,//波特率为38400bpsbps57600= 867,//波特率为57600bpsbps115200= 433;//波特率为115200bpsparameterbps9600_2= 2603,bps19200_2= 1301,bps38400_2= 650,bps57600_2= 433,bps115200_2 = 216;reg[12:0] bps_para;//分频计数最大值reg[12:0] bps_para_2;//分频计数的一半reg[12:0] cnt;//分频计数reg clk_bps_r;//波特率时钟寄存器//----------------------------------------------------------reg[2:0] uart_ctrl;// uart波特率选择寄存器//----------------------------------------------------------always @ (posedge clk or negedge rst_n) beginif(!rst_n) beginuart_ctrl <= 3'd0;//默认波特率为9600bpsendelse begincase (uart_ctrl)//波特率设置3'd0:beginbps_para <= bps9600;bps_para_2 <= bps9600_2;end3'd1:beginbps_para <= bps19200;bps_para_2 <= bps19200_2;end3'd2:beginbps_para <= bps38400;bps_para_2 <= bps38400_2;end3'd3:beginbps_para <= bps57600;bps_para_2 <= bps57600_2;end3'd4:beginbps_para <= bps115200;bps_para_2 <= bps115200_2;enddefault: ;endcaseendendalways @ (posedge clk or negedge rst_n)if(!rst_n) cnt <= 13'd0;else if(cnt<bps_para && bps_start) cnt <= cnt+1'b1;//波特率时钟计数启动else cnt <= 13'd0;always @ (posedge clk or negedge rst_n)if(!rst_n) clk_bps_r <= 1'b0;else if(cnt==bps_para_2 && bps_start) clk_bps_r <= 1'b1;// clk_bps_r高电平为接收或者发送数据位的中间采样点else clk_bps_r <= 1'b0;assign clk_bps = clk_bps_r;endmodulemodulemy_uart_rx(clk,rst_n,rs232_rx,clk_bps,bps_start,rx_data,rx_int);input clk;// 50MHz主时钟input rst_n;//低电平复位信号input rs232_rx;// RS232接收数据信号input clk_bps;// clk_bps的高电平为接收或者发送数据位的中间采样点output bps_start;//接收到数据后,波特率时钟启动信号置位output[7:0] rx_data;//接收数据寄存器,保存直至下一个数据来到output rx_int;//接收数据中断信号,接收到数据期间始终为高电平//----------------------------------------------------------------reg rs232_rx0,rs232_rx1,rs232_rx2;//接收数据寄存器,滤波用wire neg_rs232_rx;//表示数据线接收到下降沿always @ (posedge clk or negedge rst_n) beginif(!rst_n) beginrs232_rx0 <= 1'b1;rs232_rx1 <= 1'b1;rs232_rx2 <= 1'b1;endelse beginrs232_rx0 <= rs232_rx;rs232_rx1 <= rs232_rx0;rs232_rx2 <= rs232_rx1;endendassign neg_rs232_rx = rs232_rx2 & ~rs232_rx1;//接收到下降沿后neg_rs232_rx置高一个时钟周期//----------------------------------------------------------------reg bps_start_r;reg[3:0]num;//移位次数reg rx_int;//接收数据中断信号,接收到数据期间始终为高电平always @ (posedge clk or negedge rst_n) beginif(!rst_n) beginbps_start_r <= 1'bz;rx_int <= 1'b0;endelse if(neg_rs232_rx) beginbps_start_r <= 1'b1;//启动接收数据rx_int <= 1'b1;//接收数据中断信号使能endelse if(num==4'd12) beginbps_start_r <= 1'bz;//数据接收完毕rx_int <= 1'b0;//接收数据中断信号关闭endendassign bps_start = bps_start_r;//----------------------------------------------------------------reg[7:0] rx_data_r;//接收数据寄存器,保存直至下一个数据来到//----------------------------------------------------------------reg[7:0]rx_temp_data;//但前接收数据寄存器reg rx_data_shift;//数据移位标志always @ (posedge clk or negedge rst_n) beginif(!rst_n) beginrx_data_shift <= 1'b0;rx_temp_data <= 8'd0;num <= 4'd0;rx_data_r <= 8'd0;endelse 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数据)endelse 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'd12) beginnum <= 4'd0;//接收到STOP位后结束,num清零rx_data_r <= rx_temp_data;//把数据锁存到数据寄存器rx_data中endendendendassign rx_data = rx_data_r;endmodulemodulemy_uart_tx(clk,rst_n,clk_bps,rx_data,rx_int,rs232_tx,bps_start);input clk;// 50MHz主时钟input rst_n;//低电平复位信号input clk_bps;// clk_bps的高电平为接收或者发送数据位的中间采样点input[7:0] rx_data;//接收数据寄存器input rx_int;//接收数据中断信号,接收到数据期间始终为高电平,在次利用它的下降沿来启动发送数据output rs232_tx;// RS232发送数据信号output bps_start;//接收或者要发送数据,波特率时钟启动信号置位//---------------------------------------------------------reg rx_int0,rx_int1,rx_int2;//rx_int信号寄存器,捕捉下降沿滤波用wire neg_rx_int;// rx_int下降沿标志位always @ (posedge clk or negedge rst_n) beginif(!rst_n) beginrx_int0 <= 1'b0;rx_int1 <= 1'b0;rx_int2 <= 1'b0;endelse beginrx_int0 <= rx_int;rx_int1 <= rx_int0;rx_int2 <= rx_int1;endendassign neg_rx_int =~rx_int1 & rx_int2;//捕捉到下降沿后,neg_rx_int拉地保持一个主时钟周期//---------------------------------------------------------reg[7:0] tx_data;//待发送数据的寄存器//---------------------------------------------------------reg bps_start_r;reg tx_en;//发送数据使能信号,高有效reg[3:0] num;always @ (posedge clk or negedge rst_n) beginif(!rst_n) beginbps_start_r <= 1'bz;tx_en <= 1'b0;tx_data <= 8'd0;endelse if(neg_rx_int) begin//接收数据完毕,准备把接收到的数据发回去bps_start_r <= 1'b1;tx_data <= rx_data;//把接收到的数据存入发送数据寄存器tx_en <= 1'b1;//进入发送数据状态中endelse if(num==4'd11) begin//数据发送完成,复位bps_start_r <= 1'bz;tx_en <= 1'b0;endendassign bps_start = bps_start_r;//---------------------------------------------------------reg rs232_tx_r;always @ (posedge clk or negedge rst_n) beginif(!rst_n) beginnum <= 4'd0;rs232_tx_r <= 1'b1;endelse if(tx_en) beginif(clk_bps)beginnum <= num+1'b1;case (num)4'd0:rs232_tx_r <= 1'b0;//发送起始位4'd1:rs232_tx_r <= tx_data[0];//发送bit04'd2:rs232_tx_r <= tx_data[1];//发送bit14'd3: rs232_tx_r <= tx_data[2];//发送bit24'd4: rs232_tx_r <= tx_data[3];//发送bit34'd5: rs232_tx_r <= tx_data[4];//发送bit44'd6: rs232_tx_r <= tx_data[5];//发送bit54'd7:rs232_tx_r <= tx_data[6];//发送bit64'd8: rs232_tx_r <= tx_data[7];//发送bit74'd9: rs232_tx_r <= 1'b0;//发送结束位default: rs232_tx_r <= 1'b1; endcaseendelse if(num==4'd11) num <= 4'd0; //复位endendassign rs232_tx = rs232_tx_r; endmodule。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

龙源期刊网
基于VerilogHDL数字电位器ADN2850的串口控制
作者:陈厚来吴志明罗凤武
来源:《现代电子技术》2009年第08期
摘要:数字电位器由于可调精度高,更稳定,定位更准确,操作更方便,数据可长期保存和随时刷新等优点,在某些场合具有模拟电位器不可比拟的优势。

论述对数字电位器
ADN2850的一种方便的控制方法,通过计算机上的串口直接对ADN2850进行写入和控制。

该方法简洁、高效,明显提高了调试效率。

给出用Verilog HDL实现该方法的关键程序。

该程序已经通过前仿真和板级调试,达到了预期的效果。

关键词:数字电位器;SPI;ADN2850串口;Verilog HDL。

相关文档
最新文档