//------------------------------------------
//clk_bps sync bps generater
reg clk_bps_r0,clk_bps_r1,clk_bps_r2;
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
clk_bps_r0 <= 0;
clk_bps_r1 <= 0;
clk_bps_r2 <= 0;
end
else
begin
if(bps_cnt1 < 32'h7FFF_FFFF)
clk_bps_r0 <= 0;
else
clk_bps_r0 <= 1;
clk_bps_r1 <= clk_bps_r0;
clk_bps_r2 <= clk_bps_r1;
end
end
assign clk_bps = ~clk_bps_r2 & clk_bps_r1;
//------------------------------------------
//clk_smp sync receive bps generator
reg clk_smp_r0,clk_smp_r1,clk_smp_r2;
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
clk_smp_r0 <= 0;
clk_smp_r1 <= 0;
clk_smp_r2 <= 0;
end
else
begin
if(bps_cnt2 < 32'h7FFF_FFFF)
clk_smp_r0 <= 0;
else
clk_smp_r0 <= 1;
clk_smp_r1 <= clk_smp_r0;
clk_smp_r2 <= clk_smp_r1;
end
end
assign clk_smp = ~clk_smp_r2 & clk_smp_r1;
endmodule
/**************************************************************
* File Name : uart_receiver.v
* Author : Crazy Bingo
* Version : Quartus II 9.1
* CreateDate : 2011/01/31
* Description : rxd data Receiver
**************************************************************/
module uart_receiver
(
input clk,
input clk_smp, //clk_smp=16*clk_bps
input rst_n,
input rxd,
output rxd_flag, //the flag of receive over
output reg [7:0] rxd_data
);
//---------------------------------
//sync the data: rxd_sync
reg rxd_sync_r0,rxd_sync_r1;
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
rxd_sync_r0 <= 1;
rxd_sync_r1 <= 1;
end
else if(clk_smp == 1)
begin
rxd_sync_r0 <= rxd;
rxd_sync_r1 <= rxd_sync_r0;
end
end
wire rxd_sync = rxd_sync_r1;
//---------------------------------
//sample data from pc to cpu
parameter R_IDLE = 1'b0; //>=7 clk_smp : receive flag
parameter R_SAMPLE = 1'b1; //sample data programmer
reg rxd_state;
reg [3:0] smp_cnt; //sample cycle counter
reg [2:0] rxd_cnt; //the lenth of data
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
smp_cnt <= 0;
rxd_cnt <= 0;
rxd_data <= 0;
rxd_state <= R_IDLE;
end
else if(clk_smp == 1)
begin
case(rxd_state)
R_IDLE:
begin
rxd_cnt <= 0;
if(rxd_sync == 1'b0)
begin
smp_cnt <= smp_cnt + 1'b1;
if(smp_cnt == 4'd7) //8 clk_smp enable
rxd_state <= R_SAMPLE;
end
else
smp_cnt <= 0;
end
R_SAMPLE:
begin
smp_cnt <= smp_cnt +1'b1;
if(smp_cnt == 4'd7)
begin
rxd_cnt <= rxd_cnt +1'b1;
if(rxd_cnt == 4'd7)
rxd_state <= R_IDLE;
case(rxd_cnt)
3'd0: rxd_data[0] <= rxd_sync;
3'd1: rxd_data[1] <= rxd_sync;
3'd2: rxd_data[2] <= rxd_sync;
3'd3: rxd_data[3] <= rxd_sync;
3'd4: rxd_data[4] <= rxd_sync;
3'd5: rxd_data[5] <= rxd_sync;
3'd6: rxd_data[6] <= rxd_sync;
3'd7: rxd_data[7] <= rxd_sync;
endcase
end
end
endcase
end
end
wire rxd_flag_r = (rxd_cnt == 4'd7) ? 1'b1 : 1'b0;
//---------------------------------
//the signal flag of rxd receive over
reg rxd_flag_r0,rxd_flag_r1;
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
rxd_flag_r0 <= 0;
rxd_flag_r1 <= 0;
end
else
begin
rxd_flag_r0 <= rxd_flag_r;
rxd_flag_r1 <= rxd_flag_r0;
end
end
assign rxd_flag = ~rxd_flag_r1 & rxd_flag_r0;
endmodule
/**************************************************************
* File Name : uart_transfer.v
* Author : Crazy Bingo
* Version : Quartus II 9.1 SP2
* CreateDate : 2011/01/31
* Description : txd data Transfer
**************************************************************/
module uart_transfer
(
input clk,
input clk_bps,
input rst_n,
input txd_en, //txd data mark
input [7:0] txd_data,
output txd_flag, //txd data over mark
output reg txd
);
//-------------------------------------
//transfer data from cpu to pc
parameter T_IDLE = 1'b0; //test the flag to transfer data
parameter T_SEND = 1'b1; //uart transfer data
reg txd_state;
reg [3:0] txd_cnt; //txd data counter
reg txd_flag_r;
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
txd_state <= T_IDLE;
txd_flag_r <= 0;
txd <= 1'b1;
end
else
begin
case(txd_state)
T_IDLE:
begin
txd <= 1;
txd_flag_r <= 0;
if(txd_en == 1)
txd_state <= T_SEND;
else
txd_state <= T_IDLE;
end
T_SEND:
begin
if(clk_bps == 1)
begin
if(txd_cnt < 4'd9)
txd_cnt <= txd_cnt + 1'b1;
else
begin
txd_cnt <= 0;
txd_state <= T_IDLE;
txd_flag_r <= 1;
end
case(txd_cnt)
4'd0: txd <= 0;
4'd1: txd <= txd_data[0];
4'd2: txd <= txd_data[1];
4'd3: txd <= txd_data[2];
4'd4: txd <= txd_data[3];
4'd5: txd <= txd_data[4];
4'd6: txd <= txd_data[5];
4'd7: txd <= txd_data[6];
4'd8: txd <= txd_data[7];
4'd9: txd <= 1;
endcase
end
end
endcase
end
end
//-------------------------------------
//Capture the falling of data transfer over
reg txd_flag_r0,txd_flag_r1;
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
txd_flag_r0 <= 0;
txd_flag_r1 <= 0;
end
else
begin
txd_flag_r0 <= txd_flag_r;
txd_flag_r1 <= txd_flag_r0;
end
end
assign txd_flag = txd_flag_r1 & ~txd_flag_r0;