您的位置:首页 > 其它

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

2014-12-28 22:44 316 查看
</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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: