zywhsy 发表于 2011-6-26 10:37:57

用verilog写UART时遇到的问题

模仿写的UART,但只在发送一个字母或数字时正常,传输一串字母却乱码?为什么?

module uart2(clk,rst_n,rs_232_rx,rs_232_tx);

input clk;
input rst_n;
input rs_232_rx;

output rs_232_tx;

wire clk_bps_tx,clk_bps_rx;
wire bps_start_tx,bps_start_rx;
wire rx_int;
wire rx_data;

speed_select   speed_rx(
                                                        .clk(clk),
                                                        .rst_n(rst_n),
                                                        .bps_start(bps_start_rx),
                                                        .clk_bps(clk_bps_rx)
                                                  );
                                                  
uart_rx          uart_rx(
                                                        .clk(clk),
                                                        .rst_n(rst_n),
                                                        .clk_bps(clk_bps_rx),
                                                        .rs232_rx(rs_232_rx),
                                                        .bps_start(bps_start_rx),
                                                        .rx_data(rx_data),
                                                        .rx_int(rx_int)
                                                );

//---------------------------------------------------------
speed_select   speed_tx(
                                                        .clk(clk),
                                                        .rst_n(rst_n),
                                                        .bps_start(bps_start_tx),
                                                        .clk_bps(clk_bps_tx)

                                               );
                                               
uart_tx          uart_tx(
                                                        .clk(clk),
                                                        .rst_n(rst_n),
                                                        .clk_bps(clk_bps_tx),
                                                        .rx_int(rx_int),
                                                        .rx_data(rx_data),
                                                        .bps_start(bps_start_tx),
                                                        .rs232_tx(rs_232_tx)
                                                );
endmodule
//-------------------------------------------------------------------------------




module speed_select(bps_start,clk,rst_n,clk_bps);
input clk;         //系统时钟50M
input bps_start;   //波特率开始信号
input rst_n;       //异步复位

output clk_bps;    //

parameter   BPS_PARA = 5207;
parameter   BPS_PARA_2 = 2603;

reg cnt;
reg clk_bps_r;


always @ (posedge clk or negedge rst_n)
begin
                if(!rst_n)
                        cnt <= 13'd0;
                else if (cnt == BPS_PARA || !bps_start)
                        cnt <= 13'd0;
                else
                        cnt <= cnt + 1'd1;
end

always @ (posedge clk or negedge rst_n)
begin
                if(!rst_n)
                        clk_bps_r <= 1'd0;
                else if(cnt == BPS_PARA_2)
                        clk_bps_r <= 1'd1;
                else
                        clk_bps_r <= 1'd0;
end

assign clk_bps = clk_bps_r;

endmodule
//-------------------------------------------------------------



module uart_rx(clk,clk_bps,rs232_rx,rst_n,bps_start,rx_int,rx_data);

input clk;
input clk_bps;
input rs232_rx;
input rst_n;

output bps_start;
output rx_int;
output rx_data;


reg rs232_rx0,rs232_rx1,rs232_rx2,rs232_rx3;
wire neg_rs232_rx;
always @ (posedge clk or negedge rst_n)
begin
                if(!rst_n)
                begin
                        rs232_rx0 <= 1'd0;
                        rs232_rx1 <= 1'd0;
                        rs232_rx2 <= 1'd0;
                        rs232_rx3 <= 1'd0;
                end
                else
                begin
                        rs232_rx0 <= rs232_rx;
                        rs232_rx1 <= rs232_rx0;
                        rs232_rx2 <= rs232_rx1;
                        rs232_rx3 <= rs232_rx2;
                end
end
assign neg_rs232_rx = rs232_rx3 && rs232_rx2 && ~rs232_rx1 && ~rs232_rx0;

reg bps_start_r;
reg rx_int;
reg num;

always @ (posedge clk or negedge rst_n)
begin
                if(!rst_n)
                begin
                        bps_start_r <= 1'd0;//bps_start_r <= 1'dz;
                        rx_int <= 1'd0;
                end
                else if(neg_rs232_rx)
                begin
                        bps_start_r <= 1'd1;
                        rx_int <= 1'd1;               
                end
                else if(num == 4'd12)
                begin
                        bps_start_r <= 1'd0;
                        rx_int <= 1'd0;                       
                end
end
assign bps_start = bps_start_r;

reg rx_data_r;
reg rx_temp_data;
always @ (posedge clk or negedge rst_n)
begin
                if(!rst_n)
                begin
                        rx_data_r <= 8'd0;
                        rx_temp_data <= 8'd0;
                        num <= 4'd0;
                end
                else if(rx_int)
                                if(clk_bps)
                                begin
                                        num <= num + 4'd1;
                                        case (num)
                                                4'd1 : rx_temp_data <= rs232_rx;
                                                4'd2 : rx_temp_data <= rs232_rx;
                                                4'd3 : rx_temp_data <= rs232_rx;
                                                4'd4 : rx_temp_data <= rs232_rx;
                                                4'd5 : rx_temp_data <= rs232_rx;
                                                4'd6 : rx_temp_data <= rs232_rx;
                                                4'd7 : rx_temp_data <= rs232_rx;
                                                4'd8 : rx_temp_data <= rs232_rx;
                                                default : ;
                                        endcase
                                end
                                else if(num == 4'd12)
                                begin
                                        num <= 4'd0;
                                        rx_data_r <= rx_temp_data;
                                end
end
assign rx_data = rx_data_r;

endmodule
//-----------------------------------------------------------------------
module uart_tx(clk,rst_n,clk_bps,rx_int,rx_data,bps_start,rs232_tx);
input clk;
input rst_n;
input clk_bps;
input rx_int;
input rx_data;

output bps_start;
output rs232_tx;

reg rx_int0,rx_int1,rx_int2,rx_int3;
wire neg_rx_int;

always @ (posedge clk or negedge rst_n)
begin
                if(!rst_n)
                begin
                        rx_int0 <= 1'd0;
                        rx_int1 <= 1'd0;
                        rx_int2 <= 1'd0;
                        rx_int3 <= 1'd0;
                end
                else
                begin
                        rx_int0 <= rx_int;
                        rx_int1 <= rx_int0;
                        rx_int2 <= rx_int1;
                        rx_int3 <= rx_int2;
                end
end

assign neg_rx_int = rx_int3 && rx_int2 && ~rx_int1 && ~rx_int0;


reg tx_data;
reg bps_start_r;
reg num;
reg tx_en;   

always @ (posedge clk or negedge rst_n)
begin
                if(!rst_n)
                begin
                        bps_start_r <= 1'd0;
                        tx_en <= 1'd0;
                        tx_data <= 8'd0;
                end
                else if (neg_rx_int)
                begin
                        bps_start_r <= 1'd1;
                        tx_en <= 1'd1;
                        tx_data <= rx_data;
                end
                else if(num == 4'd11)//else if(num == 4'd12)
                begin
                        bps_start_r <= 1'd0;
                        tx_en <= 1'd0;
                        tx_data <= 8'd0;
                end
end

assign bps_start = bps_start_r;

reg rs232_tx_r;

always @ (posedge clk or negedge rst_n)
begin
                if(!rst_n)
                begin
                        rs232_tx_r <= 1'd0;
                        num <= 4'd0;
                end
                else if(tx_en)
                begin
                        if(clk_bps)
                        begin
                                num <= num + 4'd1;
                                case (num)
                                        4'd0 : rs232_tx_r <= 1'd0;
                                        4'd1 : rs232_tx_r <= tx_data;
                                        4'd2 : rs232_tx_r <= tx_data;
                                        4'd3 : rs232_tx_r <= tx_data;
                                        4'd4 : rs232_tx_r <= tx_data;
                                        4'd5 : rs232_tx_r <= tx_data;
                                        4'd6 : rs232_tx_r <= tx_data;
                                        4'd7 : rs232_tx_r <= tx_data;
                                        4'd8 : rs232_tx_r <= tx_data;
                                        4'd9 : rs232_tx_r <= 1'd1;
                                        default : ;//rs232_tx_r <= 1'd1;
                                endcase
                        end
                        else if(num == 4'd11) // else if(num == 4'd12)
                        begin
                                num <= 4'd0;
                        end
                end
end

assign rs232_tx = rs232_tx_r;

endmodule

zywhsy 发表于 2011-6-26 17:59:07

到底错在哪里了,实在找不出来!!!!
页: [1]
查看完整版本: 用verilog写UART时遇到的问题