差别
这里会显示出您选择的修订版和当前版本之间的差别。
两侧同时换到之前的修订记录 前一修订版 | |||
book_excise_serial_if [2021/08/20 15:18] zili |
book_excise_serial_if [2021/08/20 15:22] (当前版本) zili |
||
---|---|---|---|
行 130: | 行 130: | ||
reg new_data_in; | reg new_data_in; | ||
always @ ( posedge sample_clk or negedge rst ) begin : start_trigger | always @ ( posedge sample_clk or negedge rst ) begin : start_trigger | ||
- | if( !rst ) begin | + | if( !rst ) begin |
- | new_data_in <= 0; | + | new_data_in <= 0; |
- | end | + | end |
else begin | else begin | ||
- | new_data_in <= 0; //确保new_data_in为一个sample_clk周期。 | + | new_data_in <= 0; //确保new_data_in为一个sample_clk周期。 |
- | //当recv_state在空闲状态,且serial_2_delay为0时, | + | //当recv_state在空闲状态,且serial_2_delay为0时, |
- | //置new_data_in为高。 | + | //置new_data_in为高。 |
- | if( Recv_state == idle && ! serial_2_delay ) begin | + | if( Recv_state == idle && ! serial_2_delay ) begin |
- | new_data_in <= 1; | + | new_data_in <= 1; |
- | end | + | end |
- | end | + | end |
end | end | ||
行 156: | 行 156: | ||
<code verilog> | <code verilog> | ||
- | reg Recv_state; | + | reg Recv_state; |
- | reg [3:0] Recv_counter; | + | reg [3:0] Recv_counter; |
- | always @ ( posedge sample_clk or negedge rst ) begin: data_rx | + | always @ ( posedge sample_clk or negedge rst ) begin: data_rx |
- | if( !rst ) begin | + | if( !rst ) begin |
- | RCV_shftreg <= 8'hff; | + | RCV_shftreg <= 8'hff; |
- | Recv_state <= 0; | + | Recv_state <= 0; |
- | Recv_counter <= 0; | + | Recv_counter <= 0; |
- | Data_rdy <= 0; | + | Data_rdy <= 0; |
- | get_bit_en <= 0; | + | get_bit_en <= 0; |
- | Data_out <= 0; | + | Data_out <= 0; |
- | end | + | end |
- | else begin | + | else begin |
- | Data_rdy <= 0; | + | Data_rdy <= 0; |
- | get_bit_en <= 0; //使得使能脉冲为一个sample周期。 | + | get_bit_en <= 0; //使得使能脉冲为一个sample周期。 |
- | if( error_in ) begin //如果bit_tx接收数据发现错误,则进入ilde状态。 | + | if( error_in ) begin //如果bit_tx接收数据发现错误,则进入ilde状态。 |
- | RCV_shftreg <= 8'hff; | + | RCV_shftreg <= 8'hff; |
- | Recv_state <= 0; //idle。 | + | Recv_state <= 0; //idle。 |
- | Recv_counter <= 0; | + | Recv_counter <= 0; |
- | Data_rdy <= 0; | + | Data_rdy <= 0; |
+ | end | ||
+ | else begin | ||
+ | case(Recv_state) | ||
+ | 3'd0: begin //idle | ||
+ | if( new_data_in ) begin //有新数据到来,进入starting状态。 | ||
+ | get_bit_en <= 1; //通知bit_rx接收数据。 | ||
+ | Recv_state <= 1; //starting。 | ||
+ | end | ||
end | end | ||
- | else begin | + | 3'd1: begin //starting。 |
- | case(Recv_state) | + | if( bit_in_en ) begin //如果有数据接收完毕。 |
- | 3'd0: begin //idle | + | if( Recv_counter == 4'd9 ) begin //如果接收数据完毕。 |
- | if( new_data_in ) begin //有新数据到来,进入starting状态。 | + | //如果停止位为1,则将接收到的数据RCV_shftreg |
- | get_bit_en <= 1; //通知bit_rx接收数据。 | + | //赋给Data_out,并置使能信号Data_rdy。 |
- | Recv_state <= 1; //starting。 | + | if( bit_in ) begin |
- | end | + | Data_out <= RCV_shftreg; |
+ | Data_rdy <= 1; | ||
+ | End | ||
+ | //回到idle状态。 | ||
+ | RCV_shftreg <= 8'hff; | ||
+ | Recv_state <= 0; | ||
+ | Recv_counter <= 0; | ||
end | end | ||
- | 3'd1: begin //starting。 | + | else begin |
- | if( bit_in_en ) begin //如果有数据接收完毕。 | + | //将接收到的比特赋给RCV_shitreg的最高位,然后 |
- | if( Recv_counter == 4'd9 ) begin //如果接收数据完毕。 | + | //通知bit_tx接收下一比特数据。 |
- | //如果停止位为1,则将接收到的数据RCV_shftreg | + | RCV_shftreg <= {bit_in, RCV_shftreg[Datasize-1:1]}; |
- | //赋给Data_out,并置使能信号Data_rdy。 | + | Recv_counter <= Recv_counter + 1; |
- | if( bit_in ) begin | + | get_bit_en <= 1; |
- | Data_out <= RCV_shftreg; | + | |
- | Data_rdy <= 1; | + | |
- | End | + | |
- | //回到idle状态。 | + | |
- | RCV_shftreg <= 8'hff; | + | |
- | Recv_state <= 0; | + | |
- | Recv_counter <= 0; | + | |
- | end | + | |
- | else begin | + | |
- | //将接收到的比特赋给RCV_shitreg的最高位,然后 | + | |
- | //通知bit_tx接收下一比特数据。 | + | |
- | RCV_shftreg <= {bit_in, RCV_shftreg[Datasize-1:1]}; | + | |
- | Recv_counter <= Recv_counter + 1; | + | |
- | get_bit_en <= 1; | + | |
- | end | + | |
- | end | + | |
end | end | ||
- | endcase | + | end |
end | end | ||
- | end | + | endcase |
- | end | + | end |
+ | end | ||
+ | end | ||
</code> | </code> | ||
行 226: | 行 225: | ||
<code verilog> | <code verilog> | ||
- | reg bit_in_old,bit_in, bit_in_en; | + | reg bit_in_old,bit_in, bit_in_en; |
- | reg [3:0] checkcounter; | + | reg [3:0] checkcounter; |
- | reg bit_Rx_state, get_bit_en, error_in; | + | reg bit_Rx_state, get_bit_en, error_in; |
- | always @ ( posedge sample_clk or negedge rst ) begin : bit_Rx | + | always @ ( posedge sample_clk or negedge rst ) begin : bit_Rx |
- | if( !rst ) begin | + | if( !rst ) begin |
- | bit_Rx_state <= waiting; | + | bit_Rx_state <= waiting; |
- | bit_in_old <= 0; | + | bit_in_old <= 0; |
- | bit_in <= 0; //接收到的1比特数据。 | + | bit_in <= 0; //接收到的1比特数据。 |
- | checkcounter <= 0; //表示对数据确认次数,4次接收的数据全一致则认为数据正确。 | + | checkcounter <= 0; //表示对数据确认次数,4次接收的数据全一致则认为数据正确。 |
- | error_in <= 0; //指示数据接收错误。 | + | error_in <= 0; //指示数据接收错误。 |
- | bit_in_en <= 0; //1比特数据接收完成。 | + | bit_in_en <= 0; //1比特数据接收完成。 |
- | end | + | end |
- | else begin | + | else begin |
- | error_in <= 0; | + | error_in <= 0; |
- | bit_in_en <= 0; | + | bit_in_en <= 0; |
- | + | ||
- | case( bit_Rx_state ) | + | case( bit_Rx_state ) |
- | waiting: begin | + | waiting: begin |
- | //如果data_rx模块通知接收数据,则进入confirming状态。 | + | //如果data_rx模块通知接收数据,则进入confirming状态。 |
- | if( get_bit_en ) begin | + | if( get_bit_en ) begin |
- | bit_Rx_state <= confirming; | + | bit_Rx_state <= confirming; |
- | bit_in_old <= serial_3_delay; | + | bit_in_old <= serial_3_delay; |
- | checkcounter <= 1; | + | checkcounter <= 1; |
- | end | + | |
end | end | ||
- | confirming: begin | + | end |
- | //如果在4次以内接收的数据有不一致的地方则认为数据接收错误,返回waiting | + | confirming: begin |
+ | //如果在4次以内接收的数据有不一致的地方则认为数据接收错误,返回waiting | ||
//状态并将error_in置位。 | //状态并将error_in置位。 | ||
- | if( checkcounter <= 4'd4 && bit_in_old != serial_3_delay ) begin | + | if( checkcounter <= 4'd4 && bit_in_old != serial_3_delay ) begin |
+ | bit_Rx_state <= waiting; | ||
+ | bit_in_old <= 0; | ||
+ | checkcounter <= 1; | ||
+ | error_in <= 1; | ||
+ | end | ||
+ | else begin | ||
+ | //当checkcounter计数到6时,输出数据给data_rx。 | ||
+ | if( checkcounter == 4'd6 ) begin | ||
+ | checkcounter <= 0; | ||
+ | bit_in_en <= 1; | ||
bit_Rx_state <= waiting; | bit_Rx_state <= waiting; | ||
bit_in_old <= 0; | bit_in_old <= 0; | ||
- | checkcounter <= 1; | + | end |
- | error_in <= 1; | + | |
- | end | + | |
else begin | else begin | ||
- | //当checkcounter计数到6时,输出数据给data_rx。 | + | //如果4次数据确认都正确,则将收到数据赋给bit_in。 |
- | if( checkcounter == 4'd6 ) begin | + | if( checkcounter == 4'd4 ) begin |
- | checkcounter <= 0; | + | bit_in <= bit_in_old; |
- | bit_in_en <= 1; | + | end |
- | bit_Rx_state <= waiting; | + | checkcounter <= checkcounter + 1; |
- | bit_in_old <= 0; | + | |
- | end | + | |
- | else begin | + | |
- | //如果4次数据确认都正确,则将收到数据赋给bit_in。 | + | |
- | if( checkcounter == 4'd4 ) begin | + | |
- | bit_in <= bit_in_old; | + | |
- | end | + | |
- | checkcounter <= checkcounter + 1; | + | |
- | end | + | |
end | end | ||
end | end | ||
- | endcase | + | end |
- | end | + | endcase |
+ | end | ||
end | end | ||
行 287: | 行 286: | ||
<code verilog> | <code verilog> | ||
- | input clk; //时钟信号,50MHz。 | + | input clk; //时钟信号,50MHz。 |
- | input rst; //异步复位信号。 | + | input rst; //异步复位信号。 |
input clk_tx; //9.6KHz的时钟脉冲信号。 | input clk_tx; //9.6KHz的时钟脉冲信号。 | ||
input [7:0] data_in; //要发送的数据。 | input [7:0] data_in; //要发送的数据。 | ||
行 309: | 行 308: | ||
<code verilog> | <code verilog> | ||
- | reg [1:0] TX_state; | + | reg [1:0] TX_state; |
- | reg [7:0] data_sent; | + | reg [7:0] data_sent; |
- | always @ ( posedge clk or negedge rst ) begin | + | always @ ( posedge clk or negedge rst ) begin |
- | if( !rst ) begin | + | if( !rst ) begin |
+ | TX_state <= idle; | ||
+ | serial_out <= 1; | ||
+ | data_sent <= 0; //要发送的数据。 | ||
+ | bitnumber <= 0; | ||
+ | end | ||
+ | else begin | ||
+ | case(TX_state ) | ||
+ | idle: begin | ||
+ | if( data_en ) begin //将data_en时,进入starting状态。 | ||
+ | TX_state <= starting; | ||
+ | data_sent <= data_in; | ||
+ | end | ||
+ | end | ||
+ | starting: begin | ||
+ | if( clk_Tx ) begin //clk_tx为9.6KHz时钟,有clk_tx触发发送。 | ||
+ | serial_out <= 0; //发送起始位0。 | ||
+ | TX_state <= sending_data; //进入sending_data状态。 | ||
+ | bitnumber <= 0; //发送比特计数0。 | ||
+ | end | ||
+ | end | ||
+ | sending_data : begin | ||
+ | if( clk_Tx ) begin | ||
+ | serial_out <= data_sent[0]; //发送1比特数据。 | ||
+ | //data_sent右移一位,下一发送比特赋给data_sent[0]。 | ||
+ | data_sent <= {1'b1, data_sent[7:1]}; | ||
+ | bitnumber <= bitnumber + 1; | ||
+ | //当8比特发送完成后,进入stopping状态。 | ||
+ | if( bitnumber == 4'd7 ) begin | ||
+ | TX_state <= stopping; | ||
+ | end | ||
+ | end | ||
+ | end | ||
+ | stopping : begin | ||
+ | //在stopping状态,发送停止位,进入idle状态。 | ||
+ | if( clk_Tx) begin | ||
TX_state <= idle; | TX_state <= idle; | ||
serial_out <= 1; | serial_out <= 1; | ||
- | data_sent <= 0; //要发送的数据。 | + | data_sent <= 0; |
bitnumber <= 0; | bitnumber <= 0; | ||
end | end | ||
- | else begin | + | end |
- | case(TX_state ) | + | endcase |
- | idle: begin | + | end |
- | if( data_en ) begin //将data_en时,进入starting状态。 | + | end |
- | TX_state <= starting; | + | |
- | data_sent <= data_in; | + | |
- | end | + | |
- | end | + | |
- | starting: begin | + | |
- | if( clk_Tx ) begin //clk_tx为9.6KHz时钟,有clk_tx触发发送。 | + | |
- | serial_out <= 0; //发送起始位0。 | + | |
- | TX_state <= sending_data; //进入sending_data状态。 | + | |
- | bitnumber <= 0; //发送比特计数0。 | + | |
- | end | + | |
- | end | + | |
- | sending_data : begin | + | |
- | if( clk_Tx ) begin | + | |
- | serial_out <= data_sent[0]; //发送1比特数据。 | + | |
- | //data_sent右移一位,下一发送比特赋给data_sent[0]。 | + | |
- | data_sent <= {1'b1, data_sent[7:1]}; | + | |
- | bitnumber <= bitnumber + 1; | + | |
- | //当8比特发送完成后,进入stopping状态。 | + | |
- | if( bitnumber == 4'd7 ) begin | + | |
- | TX_state <= stopping; | + | |
- | end | + | |
- | end | + | |
- | end | + | |
- | stopping : begin | + | |
- | //在stopping状态,发送停止位,进入idle状态。 | + | |
- | if( clk_Tx) begin | + | |
- | TX_state <= idle; | + | |
- | serial_out <= 1; | + | |
- | data_sent <= 0; | + | |
- | bitnumber <= 0; | + | |
- | end | + | |
- | end | + | |
- | endcase | + | |
- | end | + | |
- | end | + | |
</code> | </code> |