</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‘b00000001 | 0100000001 | 00000011 | 11000000 |
8‘b00000010 | 0010000001 | 00000111 | 11100000 |
8‘b00000100 | 0001000001 | 00001111 | 11110000 |
8‘b00001000 | 0000100001 | 00011111 | 11111000 |
8‘b00010000 | 0000010001 | 00111111 | 11111100 |
8‘b00100000 | 0000001001 | 01111111 | 11111110 |
8‘b01000000 | 0000000101 | 11111111 | 11111111 |
8‘b10000000 | 0000000011 | 10000000 | 00000001 |
经过仔细分析,得出的结论是:
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