module Uart_tr( Sys_clk, //全局时钟 Sys_reset,//全局复位 //Tx_Clk, //发送模块接收波特率 Rc_Date, //输入,接收并行8位数据 Tx_Start,//输入,传输开始使能 Tx_out, //输出,数据输出 Tx_busy, //输出,传输忙标志 Tx_ready,//准备好标志 Tx_Clk //波特率时钟 ); input Sys_clk,Sys_reset; input [7:0] Rc_Date; input Tx_Start; output Tx_out; output Tx_busy; output Tx_ready; output Tx_Clk; reg Tx_out_r; //reg Tx_out; //reg Tx_busy; reg [3:0] state; reg [7:0] Rc_Dater; parameter idle=4'b0000; parameter startbite=4'b1001; //开始位 parameter bite0=4'b0001; //bite0 parameter bite1=4'b0010; //bite1 parameter bite2=4'b0011; //bite2 parameter bite3=4'b0100; //bite3 parameter bite4=4'b0101; //bite4 parameter bite5=4'b0110; //bite5 parameter bite6=4'b0111; //bite6 parameter bite7=4'b1000; //bite7 parameter stopbite1=4'b1010;//停止位1 parameter stopbite2=4'b1011;//停止位2 wire Tx_ready=(state==idle); //状态空闲时准备好 assign Tx_busy=~Tx_ready; //空闲时Tx_busy=0 //波特率产生1 parameter ClkFrequency = 25000000; // 时钟频率-25 MHz parameter Baud = 115200; // 串口波特率-115200 parameter BaudGeneratorAccWidth = 16; reg [BaudGeneratorAccWidth:0] BaudGeneratorAcc; wire [BaudGeneratorAccWidth:0] BaudGeneratorInc =((Baud<<(BaudGeneratorAccWidth-4))+(ClkFrequency>>5))/(ClkFrequency>>4); wire Tx_Clk = BaudGeneratorAcc[BaudGeneratorAccWidth]; always @(posedge Sys_clk or negedge Sys_reset) if(~Sys_reset) BaudGeneratorAcc <= 0; else if(Tx_busy) //关键的一句使Tx_Clk与Rc_Dater同步 BaudGeneratorAcc <= BaudGeneratorAcc[BaudGeneratorAccWidth-1:0] + BaudGeneratorInc; // 接收缓存的处理 always@(posedge Sys_clk or negedge Sys_reset) if(!Sys_reset) Rc_Dater=8'b00000000; else if(Tx_Start&Tx_ready) Rc_Dater=Rc_Date; //主程序 always@(posedge Sys_clk or negedge Sys_reset) begin if(!Sys_reset)begin Tx_out_r=1'b1; state=idle; //注意state要初始化 // Tx_Start=0; end // else if(Tx_Start) begin //注意错误,Tx_start只是一个开始信号,如总线从1变到零的下降沿 // case(state) // idle:state<=bite0 else begin case(state[3:0]) idle:if(Tx_Start) state<=startbite; startbite:if(Tx_Clk) begin state<=bite0; Tx_out_r=1'b0;end bite0:if(Tx_Clk) begin state<=bite1; Tx_out_r=Rc_Dater[0];end bite1:if(Tx_Clk) begin state<=bite2; Tx_out_r=Rc_Dater[1];end bite2:if(Tx_Clk) begin state<=bite3; Tx_out_r=Rc_Dater[2];end bite3:if(Tx_Clk) begin state<=bite4; Tx_out_r=Rc_Dater[3];end bite4:if(Tx_Clk) begin state<=bite5; Tx_out_r=Rc_Dater[4];end bite5:if(Tx_Clk) begin state<=bite6; Tx_out_r=Rc_Dater[5];end bite6:if(Tx_Clk) begin state<=bite7; Tx_out_r=Rc_Dater[6];end bite7:if(Tx_Clk) begin state<=stopbite1; Tx_out_r=Rc_Dater[7];end stopbite1:if(Tx_Clk) begin state<=stopbite2; Tx_out_r=1'b1;end stopbite2:if(Tx_Clk) begin state<=idle; Tx_out_r=1'b1;end default:if(Tx_Clk) state<=idle; endcase end end assign Tx_out=Tx_out_r;//注意不要忘了assign endmodule txtbench: module Uart_tr_vlg_tst(); reg [7:0] Rc_Date; reg Sys_clk; reg Sys_reset; reg Tx_Start; // wires wire Tx_busy; wire Tx_out; wire Tx_ready; reg [7:0] Rc_dater; Uart_tr i1 ( .Rc_Date(Rc_Date), .Sys_clk(Sys_clk), .Sys_reset(Sys_reset), .Tx_Start(Tx_Start), .Tx_busy(Tx_busy), .Tx_out(Tx_out), .Tx_ready(Tx_ready), .Tx_Clk(Tx_Clk) ); parameter SysClkCycle=40; initial begin Sys_clk=0; Sys_reset=0; Tx_Start=1; Rc_Date=8'b0; #(SysClkCycle*2) Sys_reset=1; #(SysClkCycle*2) Tx_Start=0; #(SysClkCycle*2) Tx_Start=1; # (SysClkCycle*900000) $stop; end always begin #(SysClkCycle/2) Sys_clk<=~Sys_clk; end always@(posedge Tx_ready) Rc_Date<=Rc_Date+1; endmodule |
|
来自: ruguoyouyuan > 《待分类1》