整个工程结构:
module UART
(
input CLK,
input RST,
input RX,
output TX
);
wire [7:0] wDATA;
wire wReset;
wire wRxEmpty,wTxEmpty;
RESET_MODULE Rest
(
.CLK_I(CLK),
.RST_I(RST),
.RST_O(wReset)
);
UART_TRANSMIT_MODULE UartTransmit
(
.wClock(CLK), //输入时钟,所有操作由该时钟进行同步
.wReset(wReset), //复位
.wEnable(1'B1), //使能
.wTxWE(wRxEmpty),
.wTxEmpty(wTxEmpty),
.wTxData(wDATA),
.wTX(TX)
);
UART_RECEIVE_MODULE UartReceive
(
.wClock(CLK), //输入时钟,所有操作由该时钟进行同步
.wReset(wReset), //复位
.wEnable(1'B1), //使能
.wRxRE(wTxEmpty),
.wRxEmpty(wRxEmpty),
.wRxData(wDATA),
.wRX(RX)
);
endmodule
复位模块:
//复位信号处理,异步复位同步化
module RESET_MODULE
#(
parameter pClockCount=4 //检测周期数
)
(
input CLK_I,
input RST_I,
output RST_O
);
reg [pClockCount-1:0] rReset;
//采样到pClockCount个周期的低电平则认为为有效复位
assign RST_O=|rReset;
always @(posedge CLK_I) rReset<={rReset[pClockCount-2:0],RST_I};
endmodule
时钟分频模块:
/*
时钟分频模块
InClockValue:输入时钟频率
Width :计数位宽
K :分频系数
K=F0*2^N/Fc Fo:输出频率,Fc:模块频率,N计数位宽
*/
module CLOCK_DIVISION_MODULE
#(
parameter pWidth=32 //计数位宽
)
//.......................................................................................................................
(
input wClock, //输入时钟
input wReset, //复位
input wEnable, //使能
input wPOL, //极性
input [pWidth-1:0] wPK, //系数
output wOutClock, //分频输出
output wPosedge, //上升沿
output wNegedge //下降沿
);
//.......................................................................................................................
reg [pWidth-1:0] rCount;
reg [1:0] rOutClock;
assign wPosedge=~rOutClock[1]&rOutClock[0];
assign wNegedge=rOutClock[1]&~rOutClock[0];
assign wOutClock=rOutClock[1];
//.......................................................................................................................
always @ (posedge wClock or negedge wReset)
if(!wReset) begin
rCount <={pWidth{1'B0}};
rOutClock <={2{wPOL}};
end
else if(!wEnable)begin
rCount <={pWidth{1'B0}};
rOutClock <={2{wPOL}};
end
else begin
rCount<=rCount+wPK;
if(rCount[pWidth-1]) rOutClock<={rOutClock[0],~wPOL};
else rOutClock<={rOutClock[0],wPOL};
end
//.......................................................................................................................
endmodule
UART发送模块
module UART_TRANSMIT_MODULE
(
input wClock,
input wReset,
input wEnable,
output wBusy,
input wTxClear,
input wTxWE,
output wTxFull,
output wTxEmpty,
input [7:0] wTxData,
output wTX
);
//UART发送时钟控制
reg rTxClockEnable;
wire wTxClock;
wire wPosedge,wNegedge;
CLOCK_DIVISION_MODULE TxClock
(
.wClock(wClock),
.wReset(wReset),
.wPOL(1'B0),
.wPK(9895605),
.wEnable(rTxClockEnable),
.wOutClock(wTxClock),
.wPosedge(wPosedge),
.wNegedge(wNegedge)
);
reg rTxRE;
wire [7:0] wTxDataOut;
FAST_FIFO_MODULE FIFO_TX
(
.wClock(wClock),
.wReset(wReset),
.wClear(wTxClear),
.wWE(wTxWE),
.wRE(rTxRE),
.wFull(wTxFull),
.wEmtpy(wTxEmpty),
.wDataIn(wTxData),
.wDataOut(wTxDataOut)
);
reg rTX;
reg rBusy;
reg [8:0] rTxData;
reg [3:0] rBitCount;
assign wBusy=rBusy;
assign wTX=rTX;
always @(posedge wClock or negedge wReset)
if(!wReset) begin
rTX<=1'B1;
rBusy<=1'B0;
rTxRE<=1'B0;
rTxClockEnable<=1'B0;
end
else if(wEnable) begin
if(rTxRE) rTxRE<=1'B0;
if(!wTxEmpty & !rBusy) begin
rBusy<=1'B1;
rTxClockEnable<=1'B1;
rTxRE<=1'B1;
rBitCount<=4'H0;
{rTX,rTxData[8:0]}<={1'B0,wTxDataOut,1'B1};
end
//下降沿
if(wNegedge) begin
rBitCount<=rBitCount+1'B1;
if(rBitCount==3'H9) begin
if(!wTxEmpty) begin
rBusy<=1'B1;
rTxRE<=1'B1;
{rTX,rTxData[8:0]}<={1'B0,wTxDataOut,1'B1};
end
else begin
rBusy<=1'B0;
rTxClockEnable<=1'B0;
end
end
else {rTX,rTxData[8:1]}<=rTxData;
end
end
endmodule
UART接受模块
module UART_RECEIVE_MODULE
(
input wClock, //输入时钟,所有操作由该时钟进行同步
input wReset, //复位
input wEnable, //使能
input wRxRE,
input wRxClear,
output wRxFull,
output wRxEmpty,
output [7:0] wRxData,
output wRX
);
//......................................................................................................................
wire wPosedge,wNegedge;
wire wRxClock; //Receive clock
CLOCK_DIVISION_MODULE RxClock
(
.wClock(wClock),
.wReset(wReset),
.wPOL(1'B0),
.wPK(158329674),
.wEnable(wEnable),
.wOutClock(wRxClock),
.wPosedge(wPosedge),
.wNegedge(wNegedge)
);
reg rRxWE;
reg [7:0] rRxData;
FAST_FIFO_MODULE SPI_FIFO_RX
(
.wClock(wClock),
.wReset(wReset),
.wClear(wRxClear),
.wWE(rRxWE),
.wRE(wRxRE),
.wFull(wRxFull),
.wEmtpy(wRxEmpty),
.wDataIn(rRxData),
.wDataOut(wRxData)
);
reg rStart;
reg [7:0] rSampleBitCount; //采样计数
reg [15:0] rSignalSample; //16倍采样数据
assign BitResut=((rSignalSample[9:7]==3'B111)||(rSignalSample[9:7]==3'B101)||(rSignalSample[9:7]==3'B011)||(rSignalSample[9:7]==3'B110));
always @(posedge wClock or negedge wReset)
if(!wReset) begin
rSignalSample<=16'HFFFF;
rStart<=1'B0;
rRxWE<=1'B0;
end
else if(wEnable) begin
if(rRxWE) rRxWE<=1'B0;
if(wPosedge) begin
rSignalSample <={rSignalSample[14:0],wRX};
if({rStart,rSignalSample[12:9],rSignalSample[7],rSignalSample[5],rSignalSample[3:0]}==11'B01110000000)begin
rSampleBitCount<=8'H0A;
rStart<=1'B1;
end
if(rStart) begin
rSampleBitCount<=rSampleBitCount+1'B1;
if(rSampleBitCount[3:0]==4'HF) case(rSampleBitCount[7:4])
4'H0:if(BitResut) rStart<=1'B0;
4'H1,4'H2,4'H3,4'H4,4'H5,4'H6,4'H7,4'H8:rRxData<={BitResut,rRxData[7:1]};
4'H9: begin
rStart<=1'B0;
rRxWE<=1'B1;
end
default;
endcase
end
end
end
endmodule