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
建议用ModelSim仿一下就很容易找出问题了。 wuqt 发表于 2014-10-28 10:29
建议用ModelSim仿一下就很容易找出问题了。
仿真了。。 不仿真谁能保证一次成功。。 仿真解决问题 别无他法 是不是reset的问题,板子发生的第一个00是在复位前还是复位后发的? 串口芯片上电的时候就会发00 呀 jm2011 发表于 2014-10-29 18:19
是不是reset的问题,板子发生的第一个00是在复位前还是复位后发的?
应该是在复位后。。是不是上电之后不稳定 我的电平检测那里写的不太好 caizhihe11 发表于 2014-10-29 20:21
串口芯片上电的时候就会发00 呀
那需要在程序中屏蔽这个00 是这样吗 zxl570426546 发表于 2014-10-30 09:57
那需要在程序中屏蔽这个00 是这样吗
不需要啊,你串口收数里肯定有校验吧,帧头对齐之类的设定吧,直接就忽视了呗
页:
[1]