| ||
一次Trig写入一个byte 发出去一个byte,如果再增加一个fifo就好了
module UART_TX
#(
parameter BAUDRATE = 115200,
parameter FREQ_CLK = 50000000
)(
TX_DOUT,
TX_DONE,
TX_ACTIVE,
CLK,
RSTB,
TX_DIN,
TX_TRIG
);
output reg TX_DOUT;
output reg TX_DONE;
output reg TX_ACTIVE;
input wire CLK;
input wire RSTB;
input wire TX_TRIG;
input wire [7:0] TX_DIN;
reg [15:0] DIV_CNT;
reg [3:0] BIT_INDEX;
reg [7:0] TX_DATA_REG;
reg [2:0] TX_PST;
reg [2:0] TX_NST;
reg DIV_CNT_INC;
reg DIV_CNT_CLR;
reg BIT_INDEX_INC;
reg BIT_INDEX_CLR;
reg DATA_ONE;
reg DATA_ZERO;
reg TX_TRIG_1P;
reg TX_TRIG_2P;
reg TX_TRIG_3P;
reg TX_EN;
wire TX_TRIG_RISE;
wire TX_1bit;
parameter NCPB = FREQ_CLK/BAUDRATE; //NUMBER_CLK_PER_BIT
parameter TX_IDLE = 3'b000;
parameter TX_START = 3'b001;
parameter TX_DATA = 3'b010;
parameter TX_STOP = 3'b011;
parameter TX_FINISH = 3'b100;
always@(posedge CLK or negedge RSTB)begin
if(!RSTB)begin
TX_PST <= TX_IDLE;
TX_DONE <= 1'b0;
TX_ACTIVE <= 1'b0;
end else if(TX_TRIG_RISE)begin
TX_PST <= TX_IDLE;
TX_DONE <= 1'b0;
TX_ACTIVE <= 1'b0;
end else begin
TX_PST <= TX_NST;
TX_DONE <= (TX_NST == TX_FINISH);
TX_ACTIVE <= (|TX_PST[1:0]);
end
end
always@(posedge CLK or negedge RSTB)begin
if(!RSTB)begin
TX_DATA_REG <= 8'h00;
end else begin
TX_DATA_REG <= TX_DIN;
end
end
always@(posedge CLK or negedge RSTB)begin
if(!RSTB)begin
TX_DOUT <= 1'b0;
end else if(DATA_ONE) begin
TX_DOUT <= 1'b1;
end else if(DATA_ZERO) begin
TX_DOUT <= 1'b0;
end
end
always@(posedge CLK or negedge RSTB)begin
if(!RSTB)begin
DIV_CNT <= 16'h00;
end else if(DIV_CNT_INC) begin
DIV_CNT <= DIV_CNT + 1'b1;
end else if(DIV_CNT_CLR) begin
DIV_CNT <= 16'h00;
end
end
always@(posedge CLK or negedge RSTB)begin
if(!RSTB)begin
BIT_INDEX <= 4'h0;
end else if(BIT_INDEX_INC) begin
BIT_INDEX <= BIT_INDEX + 1'b1;
end else if(BIT_INDEX_CLR) begin
BIT_INDEX <= 16'h00;
end
end
always@(posedge CLK or negedge RSTB)begin
if(!RSTB)begin
{TX_TRIG_1P,TX_TRIG_2P,TX_TRIG_3P} <= 3'b0;
end else begin
{TX_TRIG_1P,TX_TRIG_2P,TX_TRIG_3P} <= {TX_TRIG,TX_TRIG_1P,TX_TRIG_2P};
end
end
assign TX_TRIG_RISE = TX_TRIG_2P & !TX_TRIG_3P;
always@(posedge CLK or negedge RSTB)begin
if(!RSTB)begin
TX_EN <= 1'b0;
end else if(TX_DONE) begin
TX_EN <= 1'b0;
end else if(TX_TRIG_RISE)begin
TX_EN <= 1'b1;
end
end
assign TX_1bit = DIV_CNT >= NCPB;
always@(*) begin
TX_NST = TX_PST;
DIV_CNT_INC = 1'b0;
DIV_CNT_CLR = 1'b0;
BIT_INDEX_INC = 1'b0;
BIT_INDEX_CLR = 1'b0;
DATA_ONE = 1'b0;
DATA_ZERO = 1'b0;
case(TX_PST)
TX_IDLE : begin
DATA_ONE = 1'b1;
if(TX_EN)
TX_NST = TX_START;
else
TX_NST = TX_IDLE;
end
TX_START : begin
DATA_ZERO = 1'b1;
if(DIV_CNT <= NCPB )begin
DIV_CNT_INC = 1'b1;
end else begin
DIV_CNT_CLR = 1'b1;
TX_NST = TX_DATA;
end
end
TX_DATA : begin
if(TX_DATA_REG[BIT_INDEX])
DATA_ONE = 1'b1;
else
DATA_ZERO = 1'b1;
if(DIV_CNT <= NCPB )begin
DIV_CNT_INC = 1'b1;
end else begin
DIV_CNT_CLR = 1'b1;
if(BIT_INDEX != 3'h7)begin
BIT_INDEX_INC = 1'b1;
end else begin
BIT_INDEX_CLR = 1'b1;
TX_NST = TX_STOP;
end
end
end
TX_STOP : begin
DATA_ONE = 1'b1;
if(DIV_CNT <= NCPB )begin
DIV_CNT_INC = 1'b1;
end else begin
DIV_CNT_CLR = 1'b1;
TX_NST = TX_FINISH;
end
end
TX_FINISH : begin
DATA_ONE = 1'b1;
DIV_CNT_CLR = 1'b1;
BIT_INDEX_CLR = 1'b1;
TX_NST = TX_IDLE;
end
default : TX_NST = TX_IDLE;
endcase
end
endmodulemodule UART_RX
#(
parameter BAUDRATE = 115200,
parameter FREQ_CLK = 50000000
)(
RX_DOUT,
RX_VALID,
RX_ACTIVE,
CLK,
RSTB,
RX_DIN,
RX_TRIG
);
output reg [7:0] RX_DOUT;
output reg RX_VALID;
output reg RX_ACTIVE;
input wire CLK;
input wire RSTB;
input wire RX_TRIG;
input wire RX_DIN;
reg [15:0] DIV_CNT;
reg [7:0] RX_DATA_REG;
reg [3:0] BIT_INDEX;
reg [2:0] RX_PST;
reg [2:0] RX_NST;
reg DIV_CNT_INC;
reg DIV_CNT_CLR;
reg BIT_INDEX_INC;
reg BIT_INDEX_CLR;
reg BIT_WRITE;
reg BIT_CLR;
reg RX_TRIG_1P;
reg RX_TRIG_2P;
reg RX_TRIG_3P;
reg RX_EN;
wire RX_TRIG_RISE;
reg RX_DIN_1P;
reg RX_DIN_2P;
parameter NCPB = FREQ_CLK/BAUDRATE; //NUMBER_CLK_PER_BIT
parameter RX_IDLE = 3'b000;
parameter RX_START = 3'b001;
parameter RX_DATA = 3'b010;
parameter RX_STOP = 3'b011;
parameter RX_DONE = 3'b100;
always@(posedge CLK or negedge RSTB)begin
if(!RSTB)begin
RX_PST <= RX_IDLE;
RX_VALID <= 1'b0;
RX_ACTIVE <= 1'b0;
end else begin
RX_PST <= RX_NST;
RX_VALID <= (RX_PST == RX_DONE);
RX_ACTIVE <= (|RX_PST[1:0]);
end
end
always@(posedge CLK or negedge RSTB)begin
if(!RSTB)begin
{RX_DIN_1P,RX_DIN_2P} <= 2'b0;
end else begin
{RX_DIN_1P,RX_DIN_2P} <= {RX_DIN,RX_DIN_1P};
end
end
always@(posedge CLK or negedge RSTB)begin
if(!RSTB)begin
RX_DATA_REG <= 8'h00;
end else if(BIT_WRITE) begin
RX_DATA_REG[BIT_INDEX] <= RX_DIN_2P;
end else if(BIT_CLR) begin
RX_DATA_REG <= 8'h00;
end
end
always@(posedge CLK or negedge RSTB)begin
if(!RSTB)begin
RX_DOUT <= 8'h00;
end else if(RX_VALID)begin
RX_DOUT <= RX_DATA_REG;
end
end
always@(posedge CLK or negedge RSTB)begin
if(!RSTB)begin
DIV_CNT <= 16'h00;
end else if(DIV_CNT_INC) begin
DIV_CNT <= DIV_CNT + 1'b1;
end else if(DIV_CNT_CLR) begin
DIV_CNT <= 16'h00;
end
end
always@(posedge CLK or negedge RSTB)begin
if(!RSTB)begin
BIT_INDEX <= 4'h0;
end else if(BIT_INDEX_INC) begin
BIT_INDEX <= BIT_INDEX + 1'b1;
end else if(BIT_INDEX_CLR) begin
BIT_INDEX <= 16'h00;
end
end
always@(posedge CLK or negedge RSTB)begin
if(!RSTB)begin
{RX_TRIG_1P,RX_TRIG_2P,RX_TRIG_3P} <= 3'b0;
end else begin
{RX_TRIG_1P,RX_TRIG_2P,RX_TRIG_3P} <= {RX_TRIG,RX_TRIG_1P,RX_TRIG_2P};
end
end
assign RX_TRIG_RISE = RX_TRIG_2P & !RX_TRIG_3P;
always@(posedge CLK or negedge RSTB)begin
if(!RSTB)begin
RX_EN <= 1'b0;
end else if(RX_VALID) begin
RX_EN <= 1'b0;
end else if(RX_TRIG_RISE)begin
RX_EN <= 1'b1;
end
end
always@(*) begin
RX_NST = RX_PST;
DIV_CNT_INC = 1'b0;
DIV_CNT_CLR = 1'b0;
BIT_INDEX_INC = 1'b0;
BIT_INDEX_CLR = 1'b0;
BIT_WRITE = 1'b0;
BIT_CLR = 1'b0;
case(RX_PST)
RX_IDLE : begin
if(RX_EN && !RX_DIN_2P)
RX_NST = RX_START;
else
RX_NST = RX_IDLE;
end
RX_START : begin
if(DIV_CNT < (NCPB/2 + 1'b1) )begin
DIV_CNT_INC = 1'b1;
end else begin
DIV_CNT_CLR = 1'b1;
if(!RX_DIN_2P)
RX_NST = RX_DATA;
else
RX_NST = RX_IDLE;
end
end
RX_DATA : begin
if(DIV_CNT < NCPB )begin
DIV_CNT_INC = 1'b1;
end else begin
DIV_CNT_CLR = 1'b1;
BIT_WRITE = 1'b1;
if(BIT_INDEX < 3'h7)begin
BIT_INDEX_INC = 1'b1;
end else begin
BIT_INDEX_CLR = 1'b1;
BIT_CLR = 1'b1;
RX_NST = RX_STOP;
end
end
end
RX_STOP : begin
if(DIV_CNT < NCPB )begin
DIV_CNT_INC = 1'b1;
end else begin
if(RX_DIN_2P)
RX_NST = RX_DONE;
else
RX_NST = RX_IDLE;
end
end
RX_DONE : begin
DIV_CNT_CLR = 1'b1;
BIT_INDEX_CLR = 1'b1;
RX_NST = RX_IDLE;
end
default : RX_NST = RX_IDLE;
endcase
end
endmodulemodule UART_TOP( TX_DOUT, TX_ACTIVE, TX_DONE, RX_VALID, RX_ACTIVE, CLK, RSTB, RX_DIN, TX_TRIG, RX_TRIG ); output TX_DOUT; output TX_ACTIVE; output TX_DONE; output RX_VALID; output RX_ACTIVE; input CLK; input RSTB; input RX_DIN; input TX_TRIG; input RX_TRIG; wire [7:0] RX_DOUT; UART_RX U_UART_RX( .RX_DOUT(RX_DOUT), .RX_VALID(RX_VALID), .RX_ACTIVE(RX_ACTIVE), .CLK(CLK), .RSTB(RSTB), .RX_DIN(RX_DIN), .RX_TRIG(RX_TRIG) ); UART_TX U_UART_TX( .TX_DOUT(TX_DOUT), .TX_DONE(TX_DONE), .TX_ACTIVE(TX_ACTIVE), .CLK(CLK), .RSTB(RSTB), .TX_DIN(RX_DOUT), .TX_TRIG(TX_TRIG) ); endmodule
/1