rxd.rar
(2.18 KB, 下载次数: 26)
2013-10-22 22:46 上传
点击文件名下载附件
串口接收
这是我写的串口接收部分的代码。在工程中,实例化5个串口,如果用XST综合,其中4个串口可以正常的工作,但有一个串口,发送部分没有问题,在接收中,运行一段时间后,就再也收不到数,作了一些实验可以判断该原因出在,接收的状态机中,一直处于IDLE中中,判断不到起始位,无法向下运行。
如果用synplify综合,5个串口均可以正常工作,不存在上述问题。
显然是两种综合工具综合出的电路存在差异。现在想问问诸位,针对这个代码,在XST下,应该如何编写约束,使其综合出来的电路可以正常工作。
接收状态机
**********************************************/
always @(posedge clk_i or negedge resetn_i)
begin
if(!resetn_i)
begin
rx_state <= IDLE;
clr_divisor_cnt <= 1'b0;
overframe <= 1'b0;
data_rxd <= 8'h0;
parity_value <= 1'b0;
rx_data_rdy <= 1'b0;
end
else
begin
clr_divisor_cnt <= 1'b0;
case(rx_state)
IDLE:
begin
parity_value <= 1'b0;
overframe <= 1'b0;
rx_data_rdy <= 1'b0;
if(baud_tick_i == 1'b1)
begin
if(rx_data_i == 1'b0)
begin
clr_divisor_cnt <= 1'b1;
rx_state <= RX_START;
end
else
begin
clr_divisor_cnt <= 1'b0;
rx_state <= IDLE;
end
end
else
begin
clr_divisor_cnt <= 1'b0;
rx_state <= IDLE;
end
end
RX_START:
begin
if(rx_baud_tick == 1'b1)
begin
if(rx_data_i == 1'b1)
begin
rx_state <= RX_OVF;
end
else
begin
rx_state <= RX_BIT0_WAITE;
end
end
else
begin
rx_state <= RX_START;
end
end
RX_BIT0_WAITE:
begin
if(rx_baud_tick == 1'b1)
begin
rx_state <= RX_BIT0;
end
else
begin
rx_state <= RX_BIT0_WAITE;
end
end
RX_BIT0:
begin
if(rx_baud_tick == 1'b1)
begin
data_rxd[0] <= rx_data_i;
parity_value <= parity_value ^ rx_data_i;
rx_state <= RX_BIT1_WAITE;
end
else
begin
rx_state <= RX_BIT0;
end
end
RX_BIT1_WAITE:
begin
if(rx_baud_tick == 1'b1)
begin
rx_state <= RX_BIT1;
end
else
begin
rx_state <= RX_BIT1_WAITE;
end
end
RX_BIT1:
begin
if(rx_baud_tick == 1'b1)
begin
data_rxd[1] <= rx_data_i;
parity_value <= parity_value ^ rx_data_i;
rx_state <= RX_BIT2_WAITE;
end
else
begin
rx_state <= RX_BIT1;
end
end
RX_BIT2_WAITE:
begin
if(rx_baud_tick == 1'b1)
begin
rx_state <= RX_BIT2;
end
else
begin
rx_state <= RX_BIT2_WAITE;
end
end
RX_BIT2:
begin
if(rx_baud_tick == 1'b1)
begin
data_rxd[2] <= rx_data_i;
parity_value <= parity_value ^ rx_data_i;
rx_state <= RX_BIT3_WAITE;
end
else
begin
rx_state <= RX_BIT2;
end
end
RX_BIT3_WAITE:
begin
if(rx_baud_tick == 1'b1)
begin
rx_state <= RX_BIT3;
end
else
begin
rx_state <= RX_BIT3_WAITE;
end
end
RX_BIT3:
begin
if(rx_baud_tick == 1'b1)
begin
data_rxd[3] <= rx_data_i;
parity_value <= parity_value ^ rx_data_i;
rx_state <= RX_BIT4_WAITE;
end
else
begin
rx_state <= RX_BIT3;
end
end
RX_BIT4_WAITE:
begin
if(rx_baud_tick == 1'b1)
begin
rx_state <= RX_BIT4;
end
else
begin
rx_state <= RX_BIT4_WAITE;
end
end
RX_BIT4:
begin
if(rx_baud_tick == 1'b1)
begin
data_rxd[4] <= rx_data_i;
parity_value <= parity_value ^ rx_data_i;
if((frame_bits_i == 2'b00) && (parity_en_i == 1'b0)) //5bit, 无效验位
begin
rx_state <= RX_STOP1_WAITE;
end
else if((frame_bits_i == 2'b00) && (parity_en_i == 1'b1)) //5bit,有效验位
begin
rx_state <= RX_PARITY_WAITE;
end
else
begin
rx_state <= RX_BIT5_WAITE;
end
end
else
begin
rx_state <= RX_BIT4;
end
end
RX_BIT5_WAITE:
begin
if(rx_baud_tick == 1'b1)
begin
rx_state <= RX_BIT5;
end
else
begin
rx_state <= RX_BIT5_WAITE;
end
end
RX_BIT5:
begin
if(rx_baud_tick == 1'b1)
begin
data_rxd[5] <= rx_data_i;
parity_value <= parity_value ^ rx_data_i;
if((frame_bits_i == 2'b01) && (parity_en_i == 1'b0)) //6bit, 无效验位
begin
rx_state <= RX_STOP1_WAITE;
end
else if((frame_bits_i == 2'b01) && (parity_en_i == 1'b1))//6bit,有效验位
begin
rx_state <= RX_PARITY_WAITE;
end
else
begin
rx_state <= RX_BIT6_WAITE;
end
end
else
begin
rx_state <= RX_BIT5;
end
end
RX_BIT6_WAITE:
begin
if(rx_baud_tick == 1'b1)
begin
rx_state <= RX_BIT6;
end
else
begin
rx_state <= RX_BIT6_WAITE;
end
end
RX_BIT6:
begin
if(rx_baud_tick == 1'b1)
begin
data_rxd[6] <= rx_data_i;
parity_value <= parity_value ^ rx_data_i;
if((frame_bits_i == 2'b10) && (parity_en_i == 1'b0)) //7bit, 无效验位
begin
rx_state <= RX_STOP1_WAITE;
end
else if((frame_bits_i == 2'b10) && (parity_en_i == 1'b1))//7bit,有效验位
begin
rx_state <= RX_PARITY_WAITE;
end
else
begin
rx_state <= RX_BIT7_WAITE;
end
end
else
begin
rx_state <= RX_BIT6;
end
end
RX_BIT7_WAITE:
begin
if(rx_baud_tick == 1'b1)
begin
rx_state <= RX_BIT7;
end
else
begin
rx_state <= RX_BIT7_WAITE;
end
end
RX_BIT7:
begin
if(rx_baud_tick == 1'b1)
begin
data_rxd[7] <= rx_data_i;
parity_value <= parity_value ^ rx_data_i;
rx_state <= RX_BIT7_WAITE;
if(parity_en_i == 1'b1) //8bit, 有效验位
begin
rx_state <= RX_PARITY_WAITE;
end
else //8bit, 无效验位
begin
rx_state <= RX_STOP1_WAITE;
end
end
else
begin
rx_state <= RX_BIT7;
end
end
RX_PARITY_WAITE:
begin
if(rx_baud_tick == 1'b1)
begin
rx_state <= RX_PARITY;
end
else
begin
rx_state <= RX_PARITY_WAITE;
end
end
RX_PARITY:
begin
if(rx_baud_tick == 1'b1)
begin
if(parity_type_i == 1'b1) //奇校验
begin
parity_value <= ((~parity_value) != rx_data_i);
end
else //偶校验
begin
parity_value <= (parity_value != rx_data_i);
end
rx_state <= RX_STOP1_WAITE;
end
else
begin
rx_state <= RX_PARITY;
end
end
RX_STOP1_WAITE:
begin
rx_data_rdy <= 1'b1;
if(rx_baud_tick == 1'b1)
begin
rx_state <= RX_STOP1;
end
else
begin
rx_state <= RX_STOP1_WAITE;
end
end
RX_STOP1:
begin
if(rx_baud_tick == 1'b1)
begin
if(stop_bits_i == 1'b1)
begin
rx_state <= RX_STOP2_WAITE;
end
else
begin
rx_state <= IDLE;
end
end
else
begin
rx_state <= RX_STOP1;
end
end
RX_STOP2_WAITE:
begin
if(rx_baud_tick == 1'b1)
begin
rx_state <= RX_STOP2;
end
else
begin
rx_state <= RX_STOP2_WAITE;
end
end
RX_STOP2:
begin
if(rx_baud_tick == 1'b1)
begin
rx_state <= IDLE;
end
else
begin
rx_state <= RX_STOP2;
end
end
RX_OVF:
begin
overframe <= 1'b1;
rx_state <= IDLE;
end
default:
begin
rx_state <= IDLE;
end
endcase
end
end
/****************************************************
读取工作状态后,清除帧、校验错误、空满标志位
****************************************************/
always @(posedge clk_i or negedge resetn_i)
begin
if(!resetn_i)
begin
parity_err_o <= 1'b0;
overframe_err_o <= 1'b0;
rx_rdy_o <= 1'b0;
end
else if(read_status_i)
begin
parity_err_o <= 1'b0;
overframe_err_o <= 1'b0;
rx_rdy_o <= 1'b0;
end
else
begin
parity_err_o <= parity_err_o | ((!parity_value_d2) && (parity_value_d1));
overframe_err_o <= overframe_err_o | ((!overframe_d1) && (overframe));
rx_rdy_o <= rx_rdy_o | ((!rx_data_rdy_d1) && (rx_data_rdy));
end
end
/******************************************
送出接收到的数据
*******************************************/
always @(posedge clk_i or negedge resetn_i)
begin
if(!resetn_i)
begin
data_o <= 8'h0;
end
else if(rx_data_rdy)
begin
case(frame_bits_i)
2'b00:
begin
data_o <= {3'b0,data_rxd[4:0]};
end
2'b01:
begin
data_o <= {2'b0,data_rxd[5:0]};
end
2'b10:
begin
data_o <= {1'b0,data_rxd[6:0]};
end
2'b11:
begin
data_o <= data_rxd;
end
endcase
end
end
/*****************************************
延时,用于边沿检测
******************************************/
always @(posedge clk_i or negedge resetn_i)
begin
if(!resetn_i)
begin
rx_data_rdy_d1 <= 1'b0;
overframe_d1 <= 1'b0;
end
else
begin
rx_data_rdy_d1 <= rx_data_rdy;
overframe_d1 <= overframe;
end
end
always @(posedge clk_i or negedge resetn_i)
begin
if(!resetn_i)
begin
parity_value_d1 <= 1'b0;
parity_value_d2 <= 1'b0;
end
else if(rx_state == RX_STOP1_WAITE)
begin
parity_value_d1 <= parity_value;
parity_value_d2 <= parity_value_d1;
end
else
begin
parity_value_d1 <= 1'b0;
parity_value_d2 <= 1'b0;
end
end
endmodule
一周热门 更多>