在通常的modelsim波形仿真中,状态机的显示为16进制,如 3‘h1。如下图所示str_cur为状态跳变信号。
为了更加直观的以文本形式显示状态机的跳变,如自己定义的IDLE等,我们可以使用
代码语言:javascript复制virtual type
virtual function
状态机源文件:
代码语言:javascript复制//vending-machine
// 2 yuan for a bottle of drink
// only 2 coins supported: 5 jiao and 1 yuan
// finish the function of selling and changing
module vending_machine
(
input clk ,
input rstn ,
input [1:0] coin , //01 for 0.5 jiao, 10 for 1 yuan
output [1:0] change ,
output sell //output the drink
);
//machine state decode
parameter IDLE = 3'd0 ;
parameter GET05 = 3'd1 ;
parameter GET10 = 3'd2 ;
parameter GET15 = 3'd3 ;
//machine variable
reg [2:0] st_cur ;
//(1) using one state-variable do describe
reg [1:0] change_r ;
reg sell_r ;
always @(posedge clk or negedge rstn) begin
if (!rstn) begin
st_cur <= 'b0 ;
change_r <= 2'b0 ;
sell_r <= 1'b0 ;
end
else begin
case(st_cur)
IDLE: begin
change_r <= 2'b0 ;
sell_r <= 1'b0 ;
case (coin)
2'b01: st_cur <= GET05 ;
2'b10: st_cur <= GET10 ;
endcase
end
GET05: begin
case (coin)
2'b01: st_cur <= GET10 ;
2'b10: st_cur <= GET15 ;
endcase
end
GET10:
case (coin)
2'b01: begin
st_cur <= GET15 ;
end
2'b10: begin
st_cur <= IDLE ;
sell_r <= 1'b1 ;
end
endcase
GET15:
case (coin)
2'b01: begin
st_cur <= IDLE ;
sell_r <= 1'b1 ;
end
2'b10: begin
st_cur <= IDLE ;
change_r <= 2'b1 ;
sell_r <= 1'b1 ;
end
endcase
default: begin
st_cur <= IDLE ;
end
endcase // case (st_cur)
end // else: !if(!rstn)
end
assign sell = sell_r ;
assign change = change_r ;
endmodule
仿真顶层文件:
代码语言:javascript复制`timescale 1ns/1ps
module tb_vending_machine;
reg clk;
reg rstn ;
reg [1:0] coin ;
wire [1:0] change ;
wire sell ;
//clock generating
parameter CYCLE_200MHz = 10 ; //
always begin
clk = 0 ; #(CYCLE_200MHz/2) ;
clk = 1 ; #(CYCLE_200MHz/2) ;
end
//motivation generating
reg [9:0] buy_oper ; //store state of the buy operation
initial begin
buy_oper = 'h0 ;
coin = 2'h0 ;
rstn = 1'b0 ;
#8 rstn = 1'b1 ;
@(negedge clk) ;
//case(1) 0.5 -> 0.5 -> 0.5 -> 0.5
#16 ;
buy_oper = 10'b00_0101_0101 ;
repeat(5) begin
@(negedge clk) ;
coin = buy_oper[1:0] ;
buy_oper = buy_oper >> 2 ;
end
//case(2) 1 -> 0.5 -> 1, taking change
#16 ;
buy_oper = 10'b00_0010_0110 ;
repeat(5) begin
@(negedge clk) ;
coin = buy_oper[1:0] ;
buy_oper = buy_oper >> 2 ;
end
//case(3) 0.5 -> 1 -> 0.5
#16 ;
buy_oper = 10'b00_0001_1001 ;
repeat(5) begin
@(negedge clk) ;
coin = buy_oper[1:0] ;
buy_oper = buy_oper >> 2 ;
end
//case(4) 0.5 -> 0.5 -> 0.5 -> 1, taking change
#16 ;
buy_oper = 10'b00_1001_0101 ;
repeat(5) begin
@(negedge clk) ;
coin = buy_oper[1:0] ;
buy_oper = buy_oper >> 2 ;
end
end
vending_machine u_mealy
(
.clk (clk),
.rstn (rstn),
.coin (coin),
.change (change),
.sell (sell));
//simulation finish
always begin
#100;
if ($time >= 10000) $finish ;
end
endmodule // test
仿真脚本sim.do文件:
代码语言:javascript复制
#Build a new library
vlib work
#Switch to the emulation source file directory
vlog acc "tb_vending_machine.v"
vlog acc "vending_machine.v"
#Start simulation
vsim -voptargs= acc work.tb_vending_machine
#Add all the signals on the top layer
add wave *
#do wave.do
virtual type { {0x00 IDLE} {0x01 GET05} {0x02 GET10} {0x03 GET15}} FSM_TYPE
virtual function {(FSM_TYPE)/tb_vending_machine/u_mealy/st_cur} state1
add wave u_mealy/st_cur
add wave -color pink /tb_vending_machine/u_mealy/state1
view structure
view signals
run -all
仿真结果如下
状态机二进制被文本所替代。