我是靠谱客的博主 悲凉宝贝,最近开发中收集的这篇文章主要介绍verilog实现串口,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

主要记录自己在利用verilog实现串口的时候一些简单的介绍和遇到问题和思考。备忘

 

1、串口传输格式,可以百度,有很多也很简单。串口分为两部分,一个收,一个发。所以在verilog实现时可以把这两部分分开。也就是两个fifo配套收和发的.v文件,可以实现一个串口。一般人实现串口的都是这么想的吧。下面是文件的层级结构:


2、当然是coding了。写串口的代码。主要贴一下收和发的状态机(用一段来实现的):

(1)这是收的部分:

case(state_rxd)

state_rxd_idle :  //0

begin

finished_rxd <= 1'b0;

rxd_error <= 1'b0;

if((!rxd_write_full) && ({port_rxd_d3,port_rxd_d2,port_rxd_d1}==3'b100))

begin

state_rxd <= state_rxd_head;

time_rxd <= 1'd0;

end

else

state_rxd <= state_rxd_idle;

end

state_rxd_head : //1

begin

if((time_rxd == rxd_half_band_rate) && ({port_rxd_d3,port_rxd_d2,port_rxd_d1}==3'b000))

begin

time_rxd <= 15'd0;

state_rxd <= state_rxd_rxd;

data_rxd_d1 <= 8'd0;

end

else if((time_rxd == rxd_half_band_rate) && ({port_rxd_d3,port_rxd_d2,port_rxd_d1}!=3'b000))

begin

time_rxd <= 15'd0;

state_rxd <= state_rxd_idle;

end

else

time_rxd <= time_rxd + 1;

end

state_rxd_rxd : //2

begin

if((time_rxd == rxd_band_rate))

begin

time_rxd <= 15'd0;

if(count_rxd_bit == 3'd7)

begin

count_rxd_bit <= 3'd0;

state_rxd <= state_rxd_tail;

data_rxd_d1 <= {port_rxd_d1,data_rxd_d1[7:1]};

end

else

begin

count_rxd_bit <= count_rxd_bit + 1;

data_rxd_d1 <= {port_rxd_d1,data_rxd_d1[7:1]};

end

end

else

begin

time_rxd <= time_rxd + 1;

end

end

state_rxd_tail : //3

begin

if((time_rxd == rxd_band_rate) && ({port_rxd_d3,port_rxd_d2,port_rxd_d1}==3'b111))

begin

rxd_error <= 1'd0;

finished_rxd <= 1'b1;

state_rxd <= state_rxd_idle;

end

else if((time_rxd == rxd_band_rate) && ({port_rxd_d3,port_rxd_d2,port_rxd_d1}!=3'b111))

begin

rxd_error <= 1'd1;

finished_rxd <= 1'b0;

state_rxd <= state_rxd_idle;

end

else

begin

finished_rxd <= 1'b0;

rxd_error <= 1'b0;

time_rxd <= time_rxd + 1;

end

end

default : state_rxd <= state_rxd_idle;

Endcase

 

(2)这是发的部分:

case(state_txd)

state_txd_idle :  //0

begin

time_txd <= 15'd0;

finished_send <= 1'b0;

if(load_data_tag_d1 == 1'b1)

begin

state_txd <= state_txd_head;

data_txd_reg1 <= data_txd_reg;

end

else

state_txd <= state_txd;

end

state_txd_head : //1

begin

port_txd_reg <= 1'b0;

if(time_txd == txd_band_rate)

begin

time_txd <= 15'd0;

state_txd <= state_txd_txd;

end

else

time_txd <= time_txd + 1;

end

state_txd_txd : //2

begin

port_txd_reg <= data_txd_reg1[0];

if(time_txd == txd_band_rate)

begin

time_txd <= 15'd0;

if(count_bit_send == 3'd7)

begin

count_bit_send <= 3'd0;

state_txd <= state_txd_tail;

end

else

begin

count_bit_send <= count_bit_send + 1;

data_txd_reg1 <= {1'b0,data_txd_reg1[7:1]};

end

end

else

time_txd <= time_txd + 1;

end

state_txd_tail : //3

begin

port_txd_reg <= 1'b1;

if(time_txd == txd_band_rate)

begin

state_txd <= state_txd_idle;

finished_send <= 1'b1;

end

else

begin

finished_send <= 1'b0;

time_txd <= time_txd + 1;

end

end

default:

begin

port_txd_reg <= 1'b1;

finished_send <= 1'b0;

time_txd <= 15'd0;

data_txd_reg1 <= 8'd0;

end

Endcase

 

3、测试串口:

测试方法主要是通过自己把fifo写成回路来测试,相当于上位机发数据给fpga,然后fpga自己把数据通过串口传给上位机,对比传入和传出的数据是否一样来验证。这样测试对于一般串口的应用是应该够了。



4,调试过程中遇到问题:

 

(1)fifo里面的wrfullrdempty信号,并不是延迟一个时钟出来的,而是延迟两个;

(2)fifo里面的wrusedw或者rdusedw,要等它反映过来,貌似是延迟4个时钟。而且这两个信号是可以用最高位来看fifo是否满半来做一些其它的操作的。

(3)Fifoaclr是高有效而产生复位

暂时就想到这么多,先写这么多,其实实现起来也很简单,主要写这个主要是为了以后多阅读英文文献,先从fifo user guide来入手研究一下容易点。 




最后

以上就是悲凉宝贝为你收集整理的verilog实现串口的全部内容,希望文章能够帮你解决verilog实现串口所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(49)

评论列表共有 0 条评论

立即
投稿
返回
顶部