10 - 状态机代码设计与仿真
串口指令处理器
代码:
cmd_pro.v
//2021.11.24 lyw
//Instruction processor
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; //Command and data input port
input en_din_pro; //Input enable
input rdy; //Serial port sends idle flag,0 means free
output[7:0] dout_pro; //Instruction execution result
output en_dout_pro; //output enable
reg [2:0] state;// main state machine
reg [7:0] cmd_reg,A_reg,B_reg;//save 3 bytes
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 res) begin
if(~res)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://receive cmd
begin
en_dout_pro<=0;
if (en_din_pro) begin
cmd_reg<=din_pro;
state<=1;
end
end
1://receive A
begin
if (en_din_pro) begin
A_reg<=din_pro;
state<=2;
end
end
2://receive B
begin
if (en_din_pro) begin
B_reg<=din_pro;
state<=3;
end
end
3://Instruction decoding and execution
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://send result
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
//2021.11.24 lyw
//Instruction processor
`timescale 1ns/10ps
module UART_top (
clk,
res,
TX,
RX
);
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;
//receiver
UART_RXer UART_RXer (
.clk(clk),
.res(res),
.RX(RX),
.data_out(din_pro),
.en_data_out(en_din_pro)
);
//sender
UART_TXer UART_TXer (
.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
//-----testbench of UART_top-----
module UART_top_tb;
reg clk,res;
wire RX;
wire TX;
reg [45:0] RX_send;
assign RX=RX_send[0];
reg [12:0] con;
UART_top UART_top (
clk,
res,
TX,
RX
);
initial begin
clk<=0;res<=0;con<=0;
RX_send<={1'b1,8'h09,1'b0,1'b1,8'h06,1'b0,1'b1,8'h0a,1'b0,16'hffff};
#17 res<=1;
#4000000 $stop;
end
always #5 clk=~clk;
always @(posedge clk or negedge res) begin
if (~res) begin
end
if(con==5000-1) begin
con<=0;
end
else begin
con<=con+1;
end
if (con==0) begin
RX_send[24:0]<=RX_send[25:1];
RX_send[25]<=RX_send[0];
end
end
endmodule
关键:
从顶层来看,中间变量,不管输入输出,都是连接关系,因此类型是 wire。
但如果是在 testbench 里,会考虑输入在动,定义成 reg 的问题。
top 里面不能同名例化。
仿真波形:
RX:1’b1,8’h09,1’b0,1’b1,8’h06,1’b0,1’b1,8’h0a,1’b0,16’hffff
TX:6+9=15 即 0f