zxl570426546 发表于 2014-10-27 16:50:09

verilig 编写的串口程序问题

大家好,小弟用verilog编写了一个串口的程序,功能是将串口助手发来的数据再发回给串口助手,功能很简单的一个程序,但是可能由于时序比较粗糙,运行之后出现了两个问题,就是上电之后会直接给串口助手发一个00,这之后发给板子的第一个数据再发回串口助手之后就不是原来那个数了,而这之后的再发送和接收的数据就正常了下面是小弟的代码   请大家帮忙指正   谢谢!

module my_uart(
        clk,//48M
        reset_n,
        rx_in,
        tx_out,
);

input clk;
input reset_n;
input rx_in;

output tx_out;

wire bsp_rx_clk;
uart_bsp_rx U1(
        .clk(clk),
        .reset_n(reset_n),
        .bsp_rx_en(bsp_rx_en),                      //input - from U2
        .bsp_rx_clk(bsp_rx_clk)                        //output - to U2
);

wire bsp_rx_en;
wire rx_done;
wire rx_data;
uart_rx U2(
        .clk(clk),
        .reset_n(reset_n),
        .bsp_rx_en(bsp_rx_en),                        //output - to U1
        .bsp_rx_clk(bsp_rx_clk),                //input - from U1
        .rx_in(rx_in),                        //input - from top
        .rx_done(rx_done),                        //output - to U5
        .rx_data(rx_data)                        //output - to U5
);

wire bsp_tx_clk;
uart_bsp_tx U3(
        .clk(clk),
        .reset_n(reset_n),
        .bsp_tx_en(bsp_tx_en),                     //input - from U4
        .bsp_tx_clk(bsp_tx_clk)                       //output - to U4
);

wire bsp_tx_en;
wire tx_en;
wire tx_done;
wire tx_out;
wire tx_data;
uart_tx U4(
        .clk(clk),
        .reset_n(reset_n),
        .bsp_tx_en(bsp_tx_en),                                //output - to U3
        .bsp_tx_clk(bsp_tx_clk),                        //input - from U3
        .tx_en(tx_en),                                //input - from U5
        .tx_data(tx_data),                                //input - from U5
        .tx_done(tx_done),                                //output - to U5               
        .tx_out(tx_out)                                //output - to top
);

uart_control U5(
        .clk(clk),
        .reset_n(reset_n),
        .rx_data(rx_data),                                //input - from U2
        .rx_done(rx_done),                                //input - from U2
        .tx_done(tx_done),                                //input - from U4
        .tx_en(tx_en),                                //output - to U4
        .tx_data(tx_data),                                //output - to U4
);
       
endmodule

********************************************************************************************************************************
module uart_bsp_rx(
        clk,
        reset_n,
        bsp_rx_en,
        bsp_rx_clk
);

input clk;
input reset_n;
input bsp_rx_en;
output bsp_rx_clk;

reg cnt;

parameter bsp_9600=13'd4999;
parameter bsp_9600_2=13'd2499;

always @ (posedge clk or negedge reset_n)
begin
        if(!reset_n)
                cnt<=13'd0;
        else if(cnt==bsp_9600)
                cnt<=13'd0;
        else if(bsp_rx_en)
                cnt<=cnt+13'd1;
        else
                cnt<=13'd0;
end

assign bsp_rx_clk=(cnt==bsp_9600_2)?1'b1:1'b0;

endmodule

**************************************************************************************************************
module uart_bsp_tx(
        clk,
        reset_n,
        bsp_tx_en,
        bsp_tx_clk
);

input clk;
input reset_n;
input bsp_tx_en;
output bsp_tx_clk;

reg cnt;

parameter bsp_9600=13'd4999;
parameter bsp_9600_2=13'd2499;

always @ (posedge clk or negedge reset_n)
begin
        if(!reset_n)
                cnt<=13'd0;
        else if(cnt==bsp_9600)
                cnt<=13'd0;
        else if(bsp_tx_en)
                cnt<=cnt+13'd1;
        else
                cnt<=13'd0;
end

assign bsp_tx_clk=(cnt==bsp_9600_2)?1'b1:1'b0;

endmodule

*******************************************************************************************************************************************************
module uart_rx(
        clk,
        reset_n,
        rx_in,
        bsp_rx_clk,
        bsp_rx_en,
        rx_data,
        rx_done
);

input clk;
input reset_n;
input rx_in;
input bsp_rx_clk;
output bsp_rx_en;
output rx_data;
output rx_done;

reg h2l_low;
reg h2l_low_r;
reg rx_done;
reg rx_en;
reg rx_num;
reg bsp_rx_en;
reg rdata;
reg rx_data;
reg cnt;

wire h2l;

always @ (posedge clk or negedge reset_n)
begin
        if(!reset_n)
        begin
                h2l_low<='d1;
                h2l_low_r<='d1;
        end
        else
        begin
                h2l_low<=rx_in;
                h2l_low_r<=h2l_low;
        end
end
       
assign h2l=h2l_low_r&(!h2l_low);

always @ (posedge clk or negedge reset_n)
begin
        if(!reset_n)
          cnt<=16'd0;
        else if(cnt==16'd47499)
                  cnt<=16'd0;
                else if(bsp_rx_en=='d1)
                  cnt<=cnt+1'd1;
end

always @ (posedge clk or negedge reset_n)//计数10个bsp周期 之后关闭bsp使能
begin
        if(!reset_n)
                bsp_rx_en<='d0;
        else if(h2l&(rx_num=='d0))
                bsp_rx_en<='d1;
        else if(cnt==16'd47499)
                bsp_rx_en<='d0;
end

always @ (posedge clk or negedge reset_n)
begin
        if(!reset_n)
                rx_done<='d0;
        else if(cnt>='d47499)
                rx_done<='d1;
        else
                rx_done<='d0;
end

always @ (posedge clk or negedge reset_n)
begin
        if(!reset_n)
                rx_en<='d0;
        else if(rx_done)
                begin
                        rx_en<='d0;
                        rx_data<=rdata;
                end
        else       
                rx_en<='d1;
end
          
always @ (posedge clk or negedge reset_n)
begin
if(!reset_n)
    rx_num<=4'd0;
        else if(rx_en)
        begin
          if(bsp_rx_clk)
          begin
                  case(rx_num)
                       4'd0:begin rdata<=8'd0;rx_num<=rx_num+4'd1; end
                       4'd1:begin rdata<=rx_in;rx_num<=rx_num+4'd1; end
                       4'd2:begin rdata<=rx_in;rx_num<=rx_num+4'd1; end
                       4'd3:begin rdata<=rx_in;rx_num<=rx_num+4'd1; end
                       4'd4:begin rdata<=rx_in;rx_num<=rx_num+4'd1; end
                       4'd5:begin rdata<=rx_in;rx_num<=rx_num+4'd1; end
                       4'd6:begin rdata<=rx_in;rx_num<=rx_num+4'd1; end
                       4'd7:begin rdata<=rx_in;rx_num<=rx_num+4'd1; end
                       4'd8:begin rdata<=rx_in;rx_num<=rx_num+4'd1; end
                       4'd9:rx_num<=4'd0;
                endcase
                end
        end
end

endmodule

*********************************************************************************************************************************************
module uart_tx(
        clk,
        reset_n,
        bsp_tx_clk,
        tx_en,
        bsp_tx_en,
        tx_data,
        tx_out,
        tx_done
);

input clk;
input reset_n;
input tx_en;
input bsp_tx_clk;
output bsp_tx_en;
input tx_data;
output tx_out;
output tx_done;

reg tx_done;
reg tx_num;
reg tx_out;
reg cnt;


always @ (posedge clk or negedge reset_n)//计数10个bsp周期 之后关闭bsp使能
begin
        if(!reset_n)
          cnt<=16'd0;
        else if(cnt==16'd47499)
          cnt<=16'd0;
        else if(bsp_tx_en=='d1)
          cnt<=cnt+1'd1;
end

always @ (posedge clk or negedge reset_n)
begin
        if(!reset_n)
                tx_done<='d0;
        else if(cnt>='d47499)
                tx_done<='d1;
        else
                tx_done<='d0;
end
          
always @ (posedge clk or negedge reset_n)
begin
if(!reset_n)
    tx_num<=4'd0;
        else if(tx_en)
        begin
          if(bsp_tx_clk)
          begin
                  case(tx_num)
                       4'd0:begin tx_out<='d0;tx_num<=tx_num+4'd1; end
                       4'd1:begin tx_out<=tx_data;tx_num<=tx_num+4'd1; end
                       4'd2:begin tx_out<=tx_data;tx_num<=tx_num+4'd1; end
                       4'd3:begin tx_out<=tx_data;tx_num<=tx_num+4'd1; end
                       4'd4:begin tx_out<=tx_data;tx_num<=tx_num+4'd1; end
                       4'd5:begin tx_out<=tx_data;tx_num<=tx_num+4'd1; end
                       4'd6:begin tx_out<=tx_data;tx_num<=tx_num+4'd1; end
                       4'd7:begin tx_out<=tx_data;tx_num<=tx_num+4'd1; end
                       4'd8:begin tx_out<=tx_data;tx_num<=tx_num+4'd1; end
                       4'd9:begin tx_out<='d1;tx_num<=4'd0; end
                        endcase
                end
        end
end

assign bsp_tx_en=tx_en?1'd1:1'd0;

endmodule

**********************************************************************************************************************************************************
module uart_control(
        clk,
        reset_n,
        rx_data,
        rx_done,
       
        tx_done,
        tx_en,
        tx_data,
);

input clk;
input reset_n;
input rx_data;
input rx_done;
input tx_done;
output tx_en;
output tx_data;

reg tx_en;
reg tx_data;


always @ (posedge clk or negedge reset_n)
begin
        if(!reset_n)
                tx_en<='d0;
        else if(rx_done)
                tx_en<='d1;
        else if(tx_done)
                tx_en='d0;
end

always @ (posedge clk or negedge reset_n)
begin
        if(!reset_n)
                tx_data<=8'd0;
        else if(tx_en=='d1)
                tx_data<=rx_data;
end

endmodule

wuqt 发表于 2014-10-28 10:29:29

建议用ModelSim仿一下就很容易找出问题了。

zxl570426546 发表于 2014-10-28 21:25:08

wuqt 发表于 2014-10-28 10:29
建议用ModelSim仿一下就很容易找出问题了。

仿真了。。   不仿真谁能保证一次成功。。

7802848 发表于 2014-10-29 12:30:54

仿真解决问题 别无他法

jm2011 发表于 2014-10-29 18:19:30

是不是reset的问题,板子发生的第一个00是在复位前还是复位后发的?

caizhihe11 发表于 2014-10-29 20:21:26

串口芯片上电的时候就会发00 呀

zxl570426546 发表于 2014-10-30 09:56:58

jm2011 发表于 2014-10-29 18:19
是不是reset的问题,板子发生的第一个00是在复位前还是复位后发的?

应该是在复位后。。是不是上电之后不稳定   我的电平检测那里写的不太好

zxl570426546 发表于 2014-10-30 09:57:44

caizhihe11 发表于 2014-10-29 20:21
串口芯片上电的时候就会发00 呀

那需要在程序中屏蔽这个00   是这样吗

caizhihe11 发表于 2014-11-1 17:59:40

zxl570426546 发表于 2014-10-30 09:57
那需要在程序中屏蔽这个00   是这样吗

不需要啊,你串口收数里肯定有校验吧,帧头对齐之类的设定吧,直接就忽视了呗
页: [1]
查看完整版本: verilig 编写的串口程序问题