//串口发送模块
`timescale 1ns/10ps
module uart_tx(
clk,
res,
data_in,
en_data_in,
TX,
rdy
);
input clk;
input res;
input[7:0] data_in;//zhun befasongde shuju
input en_data_in;//fasongshinneg
output TX;
output rdy;//kogxianbiaozhi 0bioashikongxian
reg[3:0] state;//zhuzhuangtaijijicunqi
reg[9:0] send_buf;//fasong jicunqi
reg[12:0] con;//jisuan botelvzhouqi
reg[9:0] send_flag;//panduanyouyijieshu
reg rdy;
assign TX=send_buf[0];
always@(posedge clk or negedge res)
if(~res) begin
state<=0;send_buf<=1;con<=0;
send_flag<=10'b10_0000_0000;
rdy<=0;
end
else begin
case(state)
//dengdaishinnegxinhao
0:begin if(en_data_in)begin
send_buf<={1'b1,data_in,1'b0};
send_flag<=10'b10_0000_0000;
rdy<=1;
state<=1;
end
end
//chuankoufasong jicunqiyouyi
1:begin
if(con==5000-1)begin
con<=0;
end
else begin
con<=con+1;
end
if(con==5000-1)begin
send_buf[8:0]<=send_buf[9:1];
send_flag[8:0]<=send_flag[9:1];
end
if(send_flag[0]==1)begin
rdy<=0;
state<=0;
end
end
endcase
end
endmodule
module uart_tx_tb;
reg clk,res,en_data_in;
reg[7:0]data_in;
wire TX,rdy;
uart_tx uart_tx( //tongminglihua
clk,
res,
data_in,
en_data_in,
TX,
rdy
);
initial begin
clk<=0;res<=0;data_in<=8'h0a;en_data_in<=0;
#17 res<=1;
#30 en_data_in<=1;
#10 en_data_in<=0;
#1000 $stop;
end
always #5 clk=~clk;
endmodule
// 串口数据接收
`timescale 1ns/10ps
module UART_RX(
clk,
res,
RX,
data_out,
en_data_out
);
input clk,res,RX;
output[7:0] data_out;
output en_data_out;
reg[7:0] state;//zhuzhuangtaiji
reg[12:0] con;//jisuanbits kuandu
reg[3:0] con_bits;//jisuan bitsshu
reg RX_delay;
reg[7:0] data_out;
reg en_data_out;
always@(posedge clk or negedge res)
if(~res) begin
state<=0;
con<=0;
con_bits<=0;
RX_delay<=0;
data_out<=0;
en_data_out<=0;
end
else begin
RX_delay<=RX;
case(state)
0:begin if(con==4999)con<=0;else con<=con+1;//kongxian
if(con==0) begin
if(RX) con_bits<=con_bits+1;
else con_bits<=0;end
if(con_bits==12) state<=1;
end
//deng qi shi wei
1: begin
en_data_out<=0;
if(~RX&RX_delay) state<=2;
end
//shou zuidi wei
2:if(con==7500-1)begin
con<=0;
data_out[0]<=RX;
state<=3;
end
else con<=con+1;
3:if(con==4999)begin
con<=0;
data_out[1]<=RX;
state<=4;
end
else con<=con+1;
4:if(con==4999)begin
con<=0;
data_out[2]<=RX;
state<=5;
end
else con<=con+1;
5:if(con==4999)begin
con<=0;
data_out[3]<=RX;
state<=6;
end
else con<=con+1;
6:if(con==4999)begin
con<=0;
data_out[4]<=RX;
state<=7;
end
else con<=con+1;
7:if(con==4999)begin
con<=0;
data_out[5]<=RX;
state<=8;
end
else con<=con+1;
8:if(con==4999)begin
con<=0;
data_out[6]<=RX;
state<=9;
end
else con<=con+1;
9:if(con==4999)begin
con<=0;
data_out[7]<=RX;
state<=10;
end
else con<=con+1;
10:begin
en_data_out<=1;
state<=1;
end
default:begin
state<=0;
con<=0;
con_bits<=0;
en_data_out<=0;
end
endcase
end
endmodule
//test
module UART_RX_tb;
reg clk,res ;
wire RX;
wire[7:0] data_out;
wire en_data_out;
reg[25:0] RX_send;//chuankou fasongshuju
assign RX=RX_send[0];
reg[12:0] con;
UART_RX UART_RX(
.clk(clk),
.res(res),
.RX(RX),
.data_out(data_out),
.en_data_out(en_data_out)
);
initial begin
clk<=0;res<=0;RX_send<={1'b1,8'haa,1'b0,16'hffff};
con<=0;
#17 res<=1;
#4000000 $stop;
end
always #5 clk<=~clk;
always@(posedge clk) begin
if(con==4999)con<=0;else con<=con+1;
if(con==0)begin RX_send[24:0]<=RX_send[25:1];
RX_send[25]<= RX_send[0];end
end
endmodule
中心处理:
//指令处理器
module cmd_pro(
clk,
res,
din_pro,
en_din_pro,
dout_pro,
en_dout_pro,
rdy
);
input clk;
input res;
input[7:0] din_pro;//zhilin heshujushuruduankou
input en_din_pro;//zhilingshineng
output[7:0] dout_pro;//zhilingzhixingjioeguo
output en_dout_pro;//chuankou fasong kongxian 0biaoshikongxian
output rdy;
parameter add_ad=8'h0a;
parameter sub_ad=8'h0b;
parameter and_ad=8'h0c;
parameter or_ad=8'h0d;
reg[2:0] state ;//zhuangtaiji
reg[7:0] cmd_reg,A_reg,B_reg;//cunfangzhilin
reg[7:0] dout_pro;
reg en_dout_pro;
always@(posedge clk or negedge res)
if(~res)begin
state<=0;A_reg<=0;B_reg<=0; dout_pro<=0;en_dout_pro<=0;
end
else begin
case(state)
//dengzhilin
0: begin
en_dout_pro<=0;
if(en_din_pro) begin
cmd_reg<= din_pro;
state<=1;
end
end
//shou A
1: begin
if(en_din_pro) begin
A_reg<= din_pro;
state<=2;
end
end
//shouB
2: begin
if(en_din_pro) begin
B_reg<= din_pro;
state<=3;
end
end
//指令译码和执行
3: begin
state<=4;
case(cmd_reg)
add_ad: begin dout_pro<=A_reg+B_reg;end
sub_ad: begin dout_pro<=A_reg-B_reg;end
and_ad: begin dout_pro<=A_reg&B_reg;end
or_ad: begin dout_pro<=A_reg|B_reg;end
endcase
end
//发送指令执行结果
4:begin
if(~rdy)
en_dout_pro<=1;
state<=0;
end
default:begin state<=0;
en_dout_pro<=0; end
endcase
end
endmodule
顶层设计例化:
`timescale 1ns/10ps
module UART_top(
clk,
res,
RX,
TX);
input clk;
input res;
input RX;
output TX;
wire[7:0] din_pro;
wire en_din_pro;
wire[7:0] dout_pro;
wire en_dout_pro;
wire rdy;
UART_RX UART_RX(
.clk(clk),
.res(res),
.RX(RX),
.data_out(din_pro),
.en_data_out(en_din_pro)
);
uart_tx uart_tx(
.clk(clk),
.res(res),
.data_in(dout_pro),
.en_data_in(en_dout_pro),
.TX(TX),
.rdy(rdy)
);
cmd_pro cmd_pro(
.clk(clk),
.res(res),
.din_pro(din_pro),
.en_din_pro(en_din_pro),
.dout_pro(dout_pro),
.en_dout_pro(en_dout_pro),
.rdy(rdy)
);
endmodule
module UART_top_tb;
reg clk,res;
wire RX;
wire TX;
reg[45:0] RX_send;//chuankou fasongshuju
assign RX=RX_send[0];
reg[12:0] con;
UART_top UART_top(
clk,
res,
RX,
TX);
initial begin
clk<=0;res<=0;
RX_send<={1'b1,8'h09,1'b0,1'b1,8'h06,1'b0,1'b1,8'h0a,1'b0,16'hffff};
con<=0;
#17 res<=1;
#4000000 $stop;
end
always #5 clk<=~clk;
always@(posedge clk) begin
if(con==4999)con<=0;else con<=con+1;
if(con==0)begin RX_send[44:0]<=RX_send[45:1];
RX_send[45]<= RX_send[0];end
end
endmodule