概述
主要记录自己在利用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里面的wrfull和rdempty信号,并不是延迟一个时钟出来的,而是延迟两个;
(2)fifo里面的wrusedw或者rdusedw,要等它反映过来,貌似是延迟4个时钟。而且这两个信号是可以用最高位来看fifo是否满半来做一些其它的操作的。
(3)Fifo的aclr是高有效而产生复位
暂时就想到这么多,先写这么多,其实实现起来也很简单,主要写这个主要是为了以后多阅读英文文献,先从fifo user guide来入手研究一下容易点。
最后
以上就是悲凉宝贝为你收集整理的verilog实现串口的全部内容,希望文章能够帮你解决verilog实现串口所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复