EP10和EP11分别实现了串口接收和串口发送,现在要把他们从小模块综合起来成为一个大模块。
创建cmd_pro.v,代码如下:
cpp
//2025.9.23
//串口指令处理器
module cmd_pro(
clk,
rst,
din_pro,
en_din_pro,
dout_pro,
en_dout_pro,
rdy
);
input clk;
input rst;
input[7:0] din_pro;//指令和数据输入端口
input en_din_pro;//输入使能
output[7:0] dout_pro;//指令执行结果
output en_dout_pro;//指令输出使能
output rdy;//串口发送模块看空闲标志
reg[2:0] state;//主状态机寄存器
reg[7:0] cmd_reg,A_reg,B_reg;//存放指令、A、B
reg[7:0] dout_pro;
reg en_dout_pro;
parameter add_ab=8'h0a;
parameter sub_ab=8'h0b;
parameter and_ab=8'h0c;
parameter or_ab =8'h0d;
always@(posedge clk or negedge rst) begin
if(~rst) begin
state<=0;cmd_reg<=0;A_reg<=0;B_reg<=0;dout_pro<=0;en_dout_pro<=0;
end
else begin
case(state)
0://
begin
en_dout_pro<=0;
if(en_din_pro) begin
cmd_reg<=din_pro;
state<=1;
end
end
1://收A
begin
if(en_din_pro) begin
A_reg<=din_pro;
state<=2;
end
end
2://收B
begin
if(en_din_pro) begin
B_reg<=din_pro;
state<=3;
end
end
3://指令译码和执行
begin
state<=4;
case(cmd_reg)
add_ab: begin dout_pro<=A_reg+B_reg; end
sub_ab: begin dout_pro<=A_reg-B_reg; end
and_ab: begin dout_pro<=A_reg&B_reg; end
or_ab: begin dout_pro<=A_reg|B_reg; end
endcase
end
4://发送指令执行结果
begin
if(~rdy) begin
en_dout_pro<=1;
state<=0;
end
end
default://
begin
state<=0;
en_dout_pro<=0;
end
endcase
end
end
endmodule
接下来创建UART_top.v,代码如下:
cpp
//2025.9.23
//串口指令处理器
`timescale 1ns/10ps
module UART_top(
clk,
rst,
RX,
TX
);
input clk;
input rst;
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_RXer UART_RXer(
.clk(clk),
.rst(rst),
.RX(RX),
.data_out(din_pro),
.en_data_out(en_din_pro)
);
UART_TXer UART_TXer(
.clk(clk),
.rst(rst),
.data_in(dout_pro),
.en_data_in(en_dout_pro),
.TX(TX),
.rdy(rdy)
);
cmd_pro cmd_pro(
.clk(clk),
.rst(rst),
.din_pro(din_pro),
.en_din_pro(en_din_pro),
.dout_pro(dout_pro),
.en_dout_pro(en_dout_pro),
.rdy(rdy)
);
endmodule
//-----testbench of UART_TOP----
module UART_top_tb;
reg clk,rst;
wire RX;
wire TX;
reg[45:0] RX_send;//里面装有串口字节发送数据
assign RX=RX_send[0];//链接RX
reg[12:0] con;
UART_top UART_top(
clk,
rst,
RX,
TX
);
initial begin
clk<=0;rst<=0;
RX_send<={1'b1,8'h49,1'b0,1'b1,8'h06,1'b0,1'b1,8'h0a,1'b0,16'hffff};con<=0;
#17 rst<=1;
#400000 $stop;
end
always #5 clk<=~clk;
always@(posedge clk) begin
if(con==5000-1) begin
con<=0;
end
else begin
con<=con+1;
end
if(con==0) begin
RX_send[44:0] = RX_send[45:1];
RX_send[45] = RX_send[0];
end
end
endmodule
对UART_top的测试向量的波形图仿真,验证通过:


Verilog零基础入门 本套课程的学习都是根据李老师的课程讲座进行补充的,代码都发在专栏中了,供大家查阅,希望大家都能成为FPGA糕手😋