一、模块框图及基本思路
tx_module:串口发送的核心模块,详细介绍请参照前面的“基于Verilog的串口发送实验”
fifo2tx_module:当fifo不为空时,读取fifo中的数据并使能发送
tx_fifo:深度为1024,8位宽度fifo
tx_interface:前面几个模块的组合
tx_interface_control:不断向tx_fifo中写入递增的8位数据(8’d0-8’hff)
tx_interface_top:顶层模块
二、软件部分
tx_bps_module:
1 module tx_bps_module #(parameter Baud=9600)( 2 CLK,RSTn, 3 Count_Sig, 4 BPS_CLK 5 ); 6 input CLK; 7 input RSTn; 8 input Count_Sig; 9 output BPS_CLK; 10 11 /***************************/ 12 localparam Baud_Div=50_000_000/Baud-1; 13 localparam Baud_Div2=Baud_Div/2; 14 15 reg[15:0] Count_BPS; 16 /*************************/ 17 always @(posedge CLK or negedge RSTn) 18 begin 19 if(!RSTn) 20 Count_BPS<=16'd0; 21 else if(Count_BPS==Baud_Div) 22 Count_BPS<=16'd0; 23 else if(Count_Sig) 24 Count_BPS<=Count_BPS+1; 25 else Count_BPS<=16'd0; 26 end 27 /************************/ 28 assign BPS_CLK=(Count_BPS==Baud_Div2)?1'b1:1'b0; 29 endmodule
tx_control_module:
1 module tx_control_module( 2 CLK,RSTn, 3 TX_En_Sig,TX_Data,BPS_CLK, 4 TX_Done_Sig,TX_Pin_Out 5 ); 6 input CLK,RSTn; 7 input TX_En_Sig,BPS_CLK; 8 input [7:0]TX_Data; 9 output TX_Done_Sig,TX_Pin_Out; 10 /***************************************/ 11 reg rTX; 12 reg isDone; 13 reg[3:0] i; 14 always @(posedge CLK or negedge RSTn) 15 begin 16 if(!RSTn) 17 begin 18 rTX<=1'b1; 19 isDone<=1'b0; 20 i<=4'd0; 21 end 22 else if(TX_En_Sig) 23 begin 24 case(i) 25 4'd0:if(BPS_CLK) begin rTX<=0;i<=i+1'b1; end 26 4'd1,4'd2,4'd3,4'd4,4'd5,4'd6,4'd7,4'd8: 27 if(BPS_CLK) begin rTX<=TX_Data[i-1];i<=i+1'b1; end 28 4'd9:if(BPS_CLK) begin rTX<=1;i<=i+1'b1; end 29 4'd10:if(BPS_CLK) begin rTX<=1;i<=i+1'b1; end 30 4'd11:if(BPS_CLK) begin isDone<=1;i<=i+1'b1; end 31 4'd12: begin isDone<=0;i<=1'b0; end 32 endcase 33 end 34 end 35 /***************************************/ 36 assign TX_Pin_Out=rTX; 37 assign TX_Done_Sig=isDone; 38 endmodule
tx_module:
module tx_module( CLK,RSTn, TX_En_Sig,TX_Data,TX_Pin_Out,TX_Done_Sig ); input CLK; input RSTn; input TX_En_Sig; input [7:0] TX_Data; output TX_Pin_Out; output TX_Done_Sig; wire BPS_CLK; tx_bps_module U0(.CLK(CLK),.RSTn(RSTn),.Count_Sig(TX_En_Sig),.BPS_CLK(BPS_CLK)); tx_control_module U1(.CLK(CLK),.RSTn(RSTn),.TX_En_Sig(TX_En_Sig), .BPS_CLK(BPS_CLK),.TX_Data(TX_Data),.TX_Done_Sig(TX_Done_Sig), .TX_Pin_Out(TX_Pin_Out)); endmodule
fifo2tx_module:
1 module fifo2tx_module( 2 input CLK, 3 input RSTn, 4 //fifo接口 5 input Empty_Sig, 6 input [7:0] FIFO_Read_Data, 7 output Read_Req_Sig, 8 //tx_module接口 9 input TX_Done_Sig, 10 output [7:0]TX_Data, 11 output TX_En_Sig 12 ); 13 14 /*************************************************/ 15 reg isRead; 16 reg isTX; 17 reg [1:0]i; 18 always @(posedge CLK or negedge RSTn) 19 if(!RSTn) 20 begin 21 i<=2'd0; 22 isRead<=1'b0; 23 isTX<=1'b0; 24 end 25 else 26 case(i) 27 2'd0:if(!Empty_Sig) begin isRead<=1'b1;i<=i+1'b1; end 28 2'd1:begin isRead<=1'b0;i<=1+1'b1; end 29 2'd2:if(TX_Done_Sig) begin isTX<=1'b0;i<=2'd0; end 30 else isTX<=1'b1; 31 endcase 32 /************************************************/ 33 assign Read_Req_Sig=isRead; 34 assign TX_En_Sig=isTX; 35 assign TX_Data=FIFO_Read_Data; 36 37 endmodule
tx_interface:
1 module tx_interface( 2 input CLK, 3 input RSTn, 4 //FIFO写入接口 5 input Write_Req_Sig, 6 input [7:0]FIFO_Write_Data, 7 output Full_Sig, 8 9 output TX_Pin_Out 10 ); 11 12 wire Empty_Sig; 13 wire Read_Req_Sig; 14 wire [7:0] FIFO_Read_Data; 15 16 wire TX_En_Sig; 17 wire TX_Done_Sig; 18 wire [7:0]TX_Data; 19 20 tx_fifo U0 ( 21 .clk(CLK), // input clk 22 .rst(!RSTn), // input rst 23 .din(FIFO_Write_Data), // input [7 : 0] din 24 .wr_en(Write_Req_Sig), // input wr_en 25 .rd_en(Read_Req_Sig), // input rd_en 26 .dout(FIFO_Read_Data), // output [7 : 0] dout 27 .full(Full_Sig), // output full 28 .empty(Empty_Sig) // output empty 29 ); 30 31 fifo2tx_module U1 ( 32 .CLK(CLK), 33 .RSTn(RSTn), 34 .Empty_Sig(Empty_Sig), 35 .FIFO_Read_Data(FIFO_Read_Data), 36 .Read_Req_Sig(Read_Req_Sig), 37 .TX_Done_Sig(TX_Done_Sig), 38 .TX_Data(TX_Data), 39 .TX_En_Sig(TX_En_Sig) 40 ); 41 42 43 tx_module U2 ( 44 .CLK(CLK), 45 .RSTn(RSTn), 46 .TX_En_Sig(TX_En_Sig), 47 .TX_Data(TX_Data), 48 .TX_Pin_Out(TX_Pin_Out), 49 .TX_Done_Sig(TX_Done_Sig) 50 ); 51 52 53 54 55 endmodule
tx_interface_control:
1 module tx_interface_control( 2 input CLK, 3 input RSTn, 4 output Write_Req_Sig, 5 output [7:0]FIFO_Write_Data, 6 input Full_Sig 7 ); 8 9 /*****************FIFO写入部分********************/ 10 reg [1:0] i; 11 reg Write_Req_Sig_r; 12 reg [7:0]FIFO_Write_Data_r; 13 14 always @(posedge CLK or negedge RSTn) 15 if(!RSTn) 16 begin 17 FIFO_Write_Data_r<=8'd0; 18 i<=2'd0; 19 Write_Req_Sig_r<=1'b0; 20 end 21 else if(!Full_Sig) 22 case(i) 23 2'd0:begin FIFO_Write_Data_r<=FIFO_Write_Data_r+1'b1;i<=i+1'b1;Write_Req_Sig_r<=1'b1;end 24 2'd1:begin i<=2'd0;Write_Req_Sig_r<=1'b0;end 25 endcase 26 assign Write_Req_Sig=Write_Req_Sig_r; 27 assign FIFO_Write_Data=FIFO_Write_Data_r; 28 29 endmodule
tx_interface_top:
1 module tx_interface_top( 2 input CLK, 3 input RSTn, 4 output TX_Pin_Out 5 ); 6 7 wire Write_Req_Sig; 8 wire [7:0]FIFO_Write_Data; 9 wire Full_Sig; 10 11 tx_interface_control U0 ( 12 .CLK(CLK), 13 .RSTn(RSTn), 14 .Write_Req_Sig(Write_Req_Sig), 15 .FIFO_Write_Data(FIFO_Write_Data), 16 .Full_Sig(Full_Sig) 17 ); 18 tx_interface U1 ( 19 .CLK(CLK), 20 .RSTn(RSTn), 21 .Write_Req_Sig(Write_Req_Sig), 22 .FIFO_Write_Data(FIFO_Write_Data), 23 .Full_Sig(Full_Sig), 24 .TX_Pin_Out(TX_Pin_Out) 25 ); 26 27 28 29 endmodule
三、硬件部分
黑金SPARTAN开发板
1 NET "CLK" LOC = T8; 2 NET "RSTn" LOC = L3; 3 NET "TX_Pin_Out" LOC = D12;