verilog-1 FPGA串口通信问题解析

</pre>这里是有问题的代码,(修改版在后面)<pre class="cpp" name="code">/**/
`timescale 1ns / 1ps

module uart_tx( clk,rst_n,
    rx,tx,
    com1,
    led4,
    rx_int
    );
  
input clk,rst_n;
input rx;
//input key;    //receive trigger key 
output[7:0] led4;
reg[7:0]    led4;
output tx;
reg    tx;

parameter bps96 = 13'd5207;
parameter bps962= 13'd2603;  
reg[12:0] cnt;

output   rx_int;     //led85
reg      rx_int;

//1-cnt adding
always@(posedge clk or negedge rst_n)
 if(!rst_n) cnt <= 13'd0;
 else if(cnt == bps96 || (bps_start) ) cnt <= 13'd0;
 else  cnt <= cnt + 13'd1;  //if(!bps_start) no eddect!!!!!                  

output com1;
reg    com1; 
always@(posedge clk or negedge rst_n)
    if(!rst_n) com1 <= 1'b0;
    else       com1 <= 1'b0;
//2-start bit detecting 
wire      bps_start;
reg  bps_s1,bps_s2,bps_s3,bps_s4;
always@(posedge clk or negedge rst_n)
 if(!rst_n) begin 
  bps_s1 <= 1'b1;
  bps_s2 <= 1'b1;
  bps_s3 <= 1'b1;
  bps_s4 <= 1'b1;
 end
 else begin 
  bps_s1 <= rx;
  bps_s2 <= bps_s1;
  bps_s3 <= bps_s2;
  bps_s4 <= bps_s3;
 end
assign bps_start = (!bps_s1) & ( !bps_s2) & (bps_s3) & (bps_s4);    
//detecring start bit flag!!!


//4-timing preparing !!!
reg[7:0]  rx_data;
reg[3:0] num;
always@ (posedge clk or negedge rst_n)
 if(!rst_n) begin 
  rx_int <= 1'b0;
  num <= 4'd0;
 end
 else if(bps_start) begin 
  rx_int <= 1'b1;
  num <= 4'd0; 
 end
 else if(cnt == bps962 && rx_int) begin  
  num <= num + 14'd1;
  case(num)  
   4'd0 : begin                   num <=4'd1; end 
   4'd1 : begin rx_data[0] <= rx; num <=4'd2; end 
   4'd2 : begin rx_data[1] <= rx; num <=4'd3; end 
   4'd3 : begin rx_data[2] <= rx; num <=4'd4; end 
   4'd4 : begin rx_data[3] <= rx; num <=4'd5; end 
   4'd5 : begin rx_data[4] <= rx; num <=4'd6; end 
   4'd6 : begin rx_data[5] <= rx; num <=4'd7; end 
   4'd7 : begin rx_data[6] <= rx; num <=4'd8; end 
   4'd8 : begin rx_data[7] <= rx; num <=4'd9; end 
   4'd9 : begin /*rx_int <= 1'b0;*/   num <=4'd10; end 
  default : begin  num <= 4'd0;  rx_int <= 1'b0; 
      led4 <= rx_data;  end
  endcase
  end  //ifcnt
 else ;//begin  led4 <= rx_data;  end
endmodule

问题待解决。等解决了再来更新吧。。。。。。

时隔两天,终于在不懈的努力下 找到了答案。。。

首先用modelsim仿真,发现了bps_start 变量实际上是一个检测下降沿的变量。如果佛送的数据中为8‘b10101010,那么会检测到5个下降沿,

也就是说每一个下降沿都作为了cnt归零的条件,那么检测到的数据只有可能是最后连续的几个0补上停止位和rx始终拉高之后的1;


如果发送数据为 8’b00000001,数据帧格式为: 0(起始位)1(lsb)0000000(msb)1(停止位)接收数据为 1(msb)1000000(lsb)

做表格如下

发送数据帧格式(起始+数据+停止位)接收帧格式(数据+停止位+rx=1)接收数据
8‘b0000000101000000010000001111000000
8‘b0000001000100000010000011111100000
8‘b0000010000010000010000111111110000
8‘b0000100000001000010001111111111000
8‘b0001000000000100010011111111111100
8‘b0010000000000010010111111111111110
8‘b0100000000000001011111111111111111
8‘b1000000000000000111000000000000001

经过仔细分析,得出的结论是:

1 将原来代码中的bps_start 名称改为neg_bps_start

2 重写新的过程快,对bps_start 赋值

3 bps_start = 0 , !bps_start = 0 时,将cnt《= 0,同步帧的时间

4 num和rx_int相互制约,分开到两个过程快中进行赋值

修改版代码如下:其中led4是检测输出变量之用,com1是位选择,数码管的led资源比较丰富,rx_int 之所以用来作为output,是用来测试是否进入接收中断的。

 
 
 
 
 
// goal  : to realize rs 

// data  : 2014-12-26

//finish : 2014-12-30  successfully receive data!

/**/
`timescale 1ns / 1ps

module uart_tx( clk,rst_n,
				rx,tx,
				com1,
				led4,
				rx_int
				);
  
input clk,rst_n;
input rx;
//input key;    //receive trigger key 
output[7:0] led4;
reg[7:0]    led4;
output tx;
reg    tx;

parameter bps96 = 13'd5207;
parameter bps962= 13'd2603;  
reg[12:0] cnt;

output   rx_int;     //led85
reg      rx_int;

output com1;
reg    com1; 
always@(posedge clk or negedge rst_n)
    if(!rst_n) com1 <= 1'b0;
    else       com1 <= 1'b0;
    
//start bit detecting 
wire      neg_bps_start;
reg  bps_s1,bps_s2,bps_s3,bps_s4;
always@(posedge clk or negedge rst_n)
 if(!rst_n) begin 
  bps_s1 <= 1'b1;
  bps_s2 <= 1'b1;
  bps_s3 <= 1'b1;
  bps_s4 <= 1'b1;
 end
 else begin 
  bps_s1 <= rx;
  bps_s2 <= bps_s1;
  bps_s3 <= bps_s2;
  bps_s4 <= bps_s3;
 end
assign neg_bps_start = (!bps_s1) & ( !bps_s2) & (bps_s3) & (bps_s4);    
//detecring start bit flag!!!

//cnt adding
always@(posedge clk or negedge rst_n)
 if(!rst_n) cnt <= 13'd0;
 else if(cnt == bps96 || (! bps_start) ) cnt <= 13'd0;
 else  cnt <= cnt + 13'd1;  //if(!bps_start) no eddect!!!!!                  
//rx_int  + bps_start 
reg  bps_start;
always@ (posedge clk or negedge rst_n)
	if(!rst_n) begin 
		rx_int <= 1'b0;
		bps_start <= 1'b0;
	end 
	else if(neg_bps_start) begin 
		rx_int <= 1'b1;
		bps_start <= 1'b1;
	end
	else if(num == 4'd11) begin 
		rx_int <= 1'b0;
		bps_start <= 1'b0;
	end

//4-timing preparing !!!
reg[7:0]  rx_data;
reg[3:0] num;
always@ (posedge clk or negedge rst_n)
	if(!rst_n) begin 
		num <= 4'd0;
	end
	else if( ! bps_start) begin 
		num <= 4'd0; 
	end
	else if(cnt == bps962 && rx_int) begin  
	num <= num + 4'd1;
	case(num)  
	//   4'd0 : begin                     end 
	   4'd1 : begin rx_data[0] <= rx;   end 
	   4'd2 : begin rx_data[1] <= rx;   end 
	   4'd3 : begin rx_data[2] <= rx;   end 
	   4'd4 : begin rx_data[3] <= rx;   end 
	   4'd5 : begin rx_data[4] <= rx;   end 
	   4'd6 : begin rx_data[5] <= rx;   end 
	   4'd7 : begin rx_data[6] <= rx;   end 
	   4'd8 : begin rx_data[7] <= rx;   end 
	  default : begin  if(num == 4'd12) num <= 4'd0;   
		  led4 <= rx_data;  end
	  endcase 
  end  //ifcnt
  else ;//begin  led4 <= rx_data;  end

endmodule




 

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Verilog串口通信IP,是一种可以在FPGA或ASIC中实现的硬件模块,用于实现串口通信功能。Verilog是一种硬件描述语言,可以用来描述数字逻辑电路的行为和结构。串口通信是一种通过串行传输数据的通信方式,通过串口可以实现设备之间的数据收发。 Verilog串口通信IP可以实现串口通信协议,如UART(Universal Asynchronous Receiver/Transmitter)协议。UART协议定义了数据的帧格式、波特率等通信参数。串口通信IP可以实现UART接口的收发操作,包括数据的传输、发送和接收的时序控制。 在实现串口通信IP时,通常需要实现以下功能模块: 1. 发送数据模块:负责将要发送的数据从并行格式转换为串行格式,按照UART协议的要求进行数据传输。 2. 接收数据模块:负责将从串口接收到的串行数据转换为并行数据格式,按照UART协议的要求解析和处理接收到的数据。 3. 控制模块:负责产生串口通信的时序控制信号,包括波特率的控制和数据的帧间、帧起始、帧结束标志的生成。 4. 缓存模块:为发送和接收数据提供缓存功能,以保证数据的稳定传输。 实现Verilog串口通信IP需要了解串口通信协议的内部细节,以及使用Verilog语言描述硬件逻辑的能力。同时,需要了解FPGA或ASIC的资源和时序约束,以保证串口通信IP在硬件中的正确运行。 通过实现Verilog串口通信IP,可以方便地在FPGA或ASIC中集成串口通信功能,实现设备之间的数据收发。它在很多应用中都有广泛的用途,例如嵌入式系统、通信系统、工控系统等。 ### 回答2: Verilog 串口通信 IP 是一种可以在 FPGA(可编程逻辑器件)上实现的串口通信接口。串口通信主要用于将数据从一个设备传输到另一个设备。 Verilog 串口通信 IP 可以通过实现各个串行通信协议(如UART、SPI、I2C等)来实现串口通信功能。该 IP 可以被添加到 FPGA 设计中,与其他模块(比如处理器、存储器等)连接,并通过串行通信协议与外部设备进行数据交换。 实现 Verilog 串口通信 IP 需要以下步骤: 1. 确定所需的串口通信协议。比如,如果需要实现 UART 协议,则需要编写相应的 Verilog 代码来处理 UART 的数据格式、波特率设置等。 2. 编写接收和发送模块。接收模块(RX 模块)负责从外部设备接收数据,发送模块(TX 模块)负责向外部设备发送数据。这些模块需要根据选择的串口协议进行编写。 3. 实现数据缓冲和控制逻辑。为了处理来自外部设备的数据,需要添加一个数据缓冲区。同时,需要添加控制逻辑来处理串口通信的时序和数据流控制。 4. 进行仿真和验证。在设计完成后,需要进行仿真和验证来确保 Verilog 串口通信 IP 正确地实现了所需的功能。可以使用一些仿真工具(如 ModelSim)来进行测试,并对设计进行修正。 5. 将 Verilog 串口通信 IP 添加到 FPGA 设计中。完成验证后,将 Verilog 代码综合到 FPGA 设计中,并进行布局和布线操作,以实现在 FPGA 上的实际应用。 通过实现 Verilog 串口通信 IP,可以在 FPGA 上实现灵活且可定制的串口通信接口,使其适应各种应用需求。这样的串口通信 IP 可以应用于各种领域,比如通信、嵌入式系统和自动化等。 ### 回答3: Verilog 串口通信IP(Intellectual Property)是一种用于设计数字电路中实现串行通信功能的硬件IP核。它基于Verilog硬件描述语言,可用于在数字电路中实现串口通信功能。 串口通信是一种通过串行数据传输进行通信的方式,常用于各种设备之间的数据传输。Verilog 串口通信IP核可以用于设计各种数字电路的串行通信接口,例如嵌入式系统、芯片和电路板等。 Verilog 串口通信IP核的设计过程通常包括以下几个步骤: 1. 定义串口通信协议:确定通信协议的格式、波特率、数据位数、校验位等参数,以确保传输的准确性和可靠性。 2. 设计发送和接收模块:设计发送模块和接收模块,发送模块将并行数据转换为串行数据发送,接收模块将串行数据转换为并行数据接收。 3. 编写Verilog代码:使用Verilog硬件描述语言编写发送和接收模块的代码,实现所定义的串口通信协议。 4. 进行仿真和验证:使用仿真工具对Verilog代码进行验证,确保发送和接收模块的功能能够正常工作。 5. 实现与集成:将Verilog代码转换为适当的硬件语言,并将串口通信IP核集成到目标数字电路中。 Verilog 串口通信IP核可以提供高速、可靠的串行通信功能,有助于简化数字电路的设计过程,并提高系统的可扩展性和可维护性。它广泛应用于各种领域,例如通信设备、工业自动化、嵌入式系统等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值