| ||
verilog;toolbar:false">一次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 endmodule
module 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 endmodule
module 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