天天看點

【verilog】淺複習狀态機(FSM)狀态機代碼寫法案例一(簡單可樂機)代碼以及輸出案例二(可以找零的可樂機)

狀态機代碼寫法

一段式

在一段狀态機中,使用時序邏輯既描述狀态的轉移又描述輸入輸出。

二段式

分兩段狀态機,在第一段狀态機中描述狀态的轉移,在第二段中描述輸入輸出。

三段式

分三段。第一段中采用時序邏輯描述狀态的轉移,第二段中采用組合邏輯,判斷轉移條件,描述轉移規律,第三段狀态機中描述狀态輸出,可使用組合邏輯或者時序邏輯。

案例一(簡單可樂機)

【verilog】淺複習狀态機(FSM)狀态機代碼寫法案例一(簡單可樂機)代碼以及輸出案例二(可以找零的可樂機)

代碼以及輸出

//cola.v
module cola(
//輸入信号 時鐘信号 複位信号 投币
input wire clk,
input wire rst_n,
input wire money,

//輸出信号
output reg cola
);
//定義狀态參數 使用獨熱碼編碼
parameter IDLE = 3'b000;
parameter ONE = 3'b010;
parameter TWO = 3'b100;
//獨熱碼 每個狀态下編碼隻有一位是高電平 其他都是低電平 幾個狀态用幾位編碼
reg[2:0] state;
always @(posedge clk or negedge rst_n)
if(rst_n == 1'b0)//rst==1 複位信号有效
state <= IDLE;
else case(state)
	IDLE:if(money == 1'b1)
	state <= ONE;
	else
	state <= IDLE;
	ONE: if(money == 1'b1)
	state <= TWO;
	else
	state <= ONE;
	TWO:if(money == 1'b1)
	state <= IDLE;
	else
	state <= TWO;
	default:state <= IDLE;
endcase

always @ (posedge clk or negedge rst_n)//begin
if(rst_n == 1'b0)
cola <= 1'b0;
else if((state == TWO)&&(money == 1'b1))
cola <= 1'b1;
else
cola <= 1'b0;
//end
endmodule
           
//cola_tb.v
`timescale 1ns/1ns
module cola_tb();
reg clk;
reg rst_n;
reg money;
wire cola;
//初始化系統時鐘,全局複位
initial begin
	clk = 1'b1;
	rst_n <= 1'b0;//複位有效
	#20
	rst_n <= 1'b1;//複位無效
end
//clk模拟時鐘系統 每10ns電平翻轉一次 周期為20ns 頻率為 50mhz
always #10 clk = ~clk;
//産生輸入随機數 模拟投币一進制的情況
always @ (posedge clk or negedge rst_n)
if(rst_n == 1'b0)
money <= 1'b0;
else
money <= {$random}%2;//取模求餘數 産生随機數 0、1
wire[2:0] state = cola0.state;
initial 
begin
	$timeformat(-9,0,"ns",6);
	$monitor("@time %t: money=%b state=%b cola=%b",$time,money,state,cola);
end
//開始執行個體化
cola cola0(
.clk(clk),
.rst_n(rst_n),
.money(money),
.cola(cola)
);
endmodule
/*run
# @time    0ns: money=0 state=000 cola=0
# @time   40ns: money=1 state=000 cola=0
# @time   60ns: money=1 state=010 cola=0
# @time   80ns: money=1 state=100 cola=0
run
# @time  100ns: money=1 state=000 cola=1
# @time  120ns: money=1 state=010 cola=0
# @time  140ns: money=1 state=100 cola=0
# @time  160ns: money=0 state=000 cola=1
# @time  180ns: money=1 state=000 cola=0
run
# @time  200ns: money=1 state=010 cola=0
# @time  220ns: money=0 state=100 cola=0
# @time  240ns: money=1 state=100 cola=0
# @time  260ns: money=1 state=000 cola=1
# @time  280ns: money=0 state=010 cola=0
add wave  \
sim:/cola_tb/clk \
sim:/cola_tb/rst_n \
sim:/cola_tb/money \
sim:/cola_tb/cola \
sim:/cola_tb/state
run
# @time  300ns: money=1 state=010 cola=0
# @time  320ns: money=0 state=100 cola=0
# @time  340ns: money=1 state=100 cola=0
# @time  360ns: money=0 state=000 cola=1
# @time  380ns: money=1 state=000 cola=0
run
# @time  400ns: money=1 state=010 cola=0
# @time  420ns: money=0 state=100 cola=0
# @time  440ns: money=1 state=100 cola=0
# @time  460ns: money=0 state=000 cola=1
# @time  480ns: money=0 state=000 cola=0
run
# @time  520ns: money=1 state=000 cola=0
# @time  540ns: money=0 state=010 cola=0
# @time  560ns: money=1 state=010 cola=0
# @time  580ns: money=1 state=100 cola=0
run
# @time  600ns: money=1 state=000 cola=1
# @time  620ns: money=1 state=010 cola=0
# @time  640ns: money=0 state=100 cola=0

*/


           

仿真

【verilog】淺複習狀态機(FSM)狀态機代碼寫法案例一(簡單可樂機)代碼以及輸出案例二(可以找零的可樂機)

案例二(可以找零的可樂機)

簡單分析一下它的狀态:

一聽可樂是2.5元

輸入:0.5、1

輸出:不出可樂不找零、不出可樂找零 、出可樂不找零、出可樂找零

狀态:不投币(00)、投0.5元(01)、投1元(10)

不出可樂不找零(00)、出可樂找零(01)、出可樂不找零(10)

代碼:

//cola2.v
module cola2(
input wire rst,
input wire clk,
input wire pi_money_half,
input wire pi_money_one,
output reg po_money, //找零
output reg po_cola//出可樂
);
//五種狀态使用獨熱碼
parameter IDLE = 5'b00001;
parameter HALF = 5'b00010;
parameter ONE = 5'b00100;
parameter ONE_HALF= 5'b01000;
parameter TWO = 5'b10000;

reg [4:0]state;
wire [1:0] pi_money;
assign  pi_money = {pi_money_one,pi_money_half};//00 01 10 
//第一段狀态機,描述目前狀态state如何根據輸入跳轉到下一個狀态
always @ (posedge clk or posedge rst)begin
if(rst == 1'b1)begin
	state <= IDLE;
end
else begin
case(state)
	IDLE:begin 
		if(pi_money == 2'b01)begin//pi_one = 0 pi_half= 1 輸入0.5	
		  state <= HALF;
	end
	else if(pi_money == 2'b10)begin
		state <= ONE;
	end
	else begin
		state <= IDLE;
	end
end
HALF:begin
	if(pi_money == 2'b01) begin
		state <= ONE;
	end
	else if(pi_money == 2'b10)begin
		state <= ONE_HALF;
	end
	else begin
		state <= HALF;
	end
end
ONE:begin
	if(pi_money == 2'b01)begin
		state <= ONE_HALF;
	end
	else if(pi_money == 2'b10)begin
		state <= TWO;
	end
	else begin
		state <= ONE;
	end
end
ONE_HALF:begin
	if(pi_money == 2'b01)begin
		state <= TWO;
	end
	if(pi_money == 2'b10)begin
		state <= IDLE;
	end
	else begin
		state <= ONE_HALF;
	end
end
TWO:begin
	if(pi_money == 2'b01)begin
 state <= IDLE;
end
else if(pi_money == 2'b10)begin
	state <= IDLE;
end
else begin
	state <= TWO;
end
end
default://begin
	state <= IDLE;
//end
endcase
end
end
//第二段狀态機 描述目前狀态state和輸入pi_money如何影響po_cola的輸出
always @ (posedge clk or posedge rst)begin
	if(rst == 1'b1)begin
		po_cola <= 1'b0;
	end
	else if((state == TWO&&pi_money == 2'b01)||(state == TWO&&pi_money == 2'b10)||(state == ONE_HALF&&pi_money == 2'b10))begin
		po_cola <= 1'b1;
	end
	else begin
		po_cola <= 1'b0;
	end
end
//第二段狀态機 描述目前狀态state和輸入pi_money如何影響po_money輸出
always @ (posedge clk or posedge rst)begin
	if(rst == 1'b1)begin
		po_money <= 1'b0;
	end
	else if((state == TWO)&&(pi_money == 2'b10))begin
		po_money <= 1'b1;
	end
	else begin
	po_money <= 1'b0;
end
end
endmodule
           

tb

//cola2_tb.v
`timescale 1ns/1ns
module cola2_tb();
reg clk;
reg rst;
reg pi_money_one;
reg pi_money_half;
reg random_data;//随機數

wire po_money;
wire po_cola;

//初始化系統時鐘、全局複位
initial begin
	clk = 1'b1;
	rst <= 1'b1;
	#20 //延時20ns
	rst <= 1'b0;
end
//clk:模拟系統時鐘,每10ns電平翻轉一次,周期為20ns,頻率50mhz
always #10 clk = ~clk;
//radom_data:産生随機數 0 1
always @(posedge clk or posedge rst)begin
	if(rst == 1'b1)begin
		random_data <= 1'b0;
	end
	else begin
		random_data <= {$random}%2;
	end
end
//pi_money_one:模拟投入一進制的情況
always @(posedge clk or posedge rst)begin
	if(rst == 1'b1)begin
		pi_money_one <= 1'b0;
	end
	else begin
		pi_money_one <=random_data;
	end
end
//pi_money_half:模拟投入五毛的情況
always @(posedge clk or posedge rst)begin
	if(rst == 1'b1)begin
		pi_money_half <= 1'b0;
	end
	else begin
		pi_money_half <= ~random_data;//不可以同時投入五毛和一進制
	end
end
//将rtl子產品中的内部信号引入到testbench子產品中觀察
wire [4:0] state = cola2_0.state;
wire [1:0] pi_money = cola2_0.pi_money;

initial begin
	$timeformat(-9,0,"ns",6);
	$monitor("@time %t :pi_money_one=%b pi_money_half=%b pi_money=%b state=%b po_cola=%b po_money=%b",$time,pi_money_one,pi_money_half,pi_money,state,po_cola,po_money);
end
//例化
cola2 cola2_0(
.clk(clk),
.rst(rst),
.pi_money_one(pi_money_one),
.pi_money_half(pi_money_half),
.po_cola(po_cola),
.po_money(po_money)
);
endmodule
/*run
# @time    0ns :pi_money_one=0 pi_money_half=0 pi_money=00 state=00001 po_cola=0 po_money=0
# @time   40ns :pi_money_one=0 pi_money_half=1 pi_money=01 state=00001 po_cola=0 po_money=0
# @time   60ns :pi_money_one=1 pi_money_half=0 pi_money=10 state=00010 po_cola=0 po_money=0
# @time   80ns :pi_money_one=1 pi_money_half=0 pi_money=10 state=01000 po_cola=0 po_money=0
run
# @time  100ns :pi_money_one=1 pi_money_half=0 pi_money=10 state=00001 po_cola=1 po_money=0
# @time  120ns :pi_money_one=1 pi_money_half=0 pi_money=10 state=00100 po_cola=0 po_money=0
# @time  140ns :pi_money_one=1 pi_money_half=0 pi_money=10 state=10000 po_cola=0 po_money=0
# @time  160ns :pi_money_one=1 pi_money_half=0 pi_money=10 state=00001 po_cola=1 po_money=1
# @time  180ns :pi_money_one=0 pi_money_half=1 pi_money=01 state=00100 po_cola=0 po_money=0
run
# @time  200ns :pi_money_one=1 pi_money_half=0 pi_money=10 state=01000 po_cola=0 po_money=0
# @time  220ns :pi_money_one=1 pi_money_half=0 pi_money=10 state=00001 po_cola=1 po_money=0
# @time  240ns :pi_money_one=0 pi_money_half=1 pi_money=01 state=00100 po_cola=0 po_money=0
# @time  260ns :pi_money_one=1 pi_money_half=0 pi_money=10 state=01000 po_cola=0 po_money=0
# @time  280ns :pi_money_one=1 pi_money_half=0 pi_money=10 state=00001 po_cola=1 po_money=0
run
# @time  300ns :pi_money_one=0 pi_money_half=1 pi_money=01 state=00100 po_cola=0 po_money=0
# @time  320ns :pi_money_one=1 pi_money_half=0 pi_money=10 state=01000 po_cola=0 po_money=0
# @time  340ns :pi_money_one=0 pi_money_half=1 pi_money=01 state=00001 po_cola=1 po_money=0
# @time  360ns :pi_money_one=1 pi_money_half=0 pi_money=10 state=00010 po_cola=0 po_money=0
# @time  380ns :pi_money_one=0 pi_money_half=1 pi_money=01 state=01000 po_cola=0 po_money=0
run
# @time  400ns :pi_money_one=1 pi_money_half=0 pi_money=10 state=01000 po_cola=0 po_money=0
# @time  420ns :pi_money_one=1 pi_money_half=0 pi_money=10 state=00001 po_cola=1 po_money=0
# @time  440ns :pi_money_one=0 pi_money_half=1 pi_money=01 state=00100 po_cola=0 po_money=0
# @time  460ns :pi_money_one=1 pi_money_half=0 pi_money=10 state=01000 po_cola=0 po_money=0
# @time  480ns :pi_money_one=0 pi_money_half=1 pi_money=01 state=00001 po_cola=1 po_money=0
run
# @time  500ns :pi_money_one=0 pi_money_half=1 pi_money=01 state=00010 po_cola=0 po_money=0
# @time  520ns :pi_money_one=0 pi_money_half=1 pi_money=01 state=00100 po_cola=0 po_money=0
# @time  540ns :pi_money_one=1 pi_money_half=0 pi_money=10 state=01000 po_cola=0 po_money=0
# @time  560ns :pi_money_one=0 pi_money_half=1 pi_money=01 state=00001 po_cola=1 po_money=0
# @time  580ns :pi_money_one=1 pi_money_half=0 pi_money=10 state=00010 po_cola=0 po_money=0
run
# @time  600ns :pi_money_one=1 pi_money_half=0 pi_money=10 state=01000 po_cola=0 po_money=0
# @time  620ns :pi_money_one=1 pi_money_half=0 pi_money=10 state=00001 po_cola=1 po_money=0
# @time  640ns :pi_money_one=1 pi_money_half=0 pi_money=10 state=00100 po_cola=0 po_money=0
# @time  660ns :pi_money_one=0 pi_money_half=1 pi_money=01 state=10000 po_cola=0 po_money=0
# @time  680ns :pi_money_one=0 pi_money_half=1 pi_money=01 state=00001 po_cola=1 po_money=0
run
# @time  700ns :pi_money_one=0 pi_money_half=1 pi_money=01 state=00010 po_cola=0 po_money=0
# @time  720ns :pi_money_one=0 pi_money_half=1 pi_money=01 state=00100 po_cola=0 po_money=0
# @time  740ns :pi_money_one=1 pi_money_half=0 pi_money=10 state=01000 po_cola=0 po_money=0
# @time  760ns :pi_money_one=0 pi_money_half=1 pi_money=01 state=00001 po_cola=1 po_money=0
# @time  780ns :pi_money_one=1 pi_money_half=0 pi_money=10 state=00010 po_cola=0 po_money=0
run
# @time  800ns :pi_money_one=1 pi_money_half=0 pi_money=10 state=01000 po_cola=0 po_money=0
# @time  820ns :pi_money_one=1 pi_money_half=0 pi_money=10 state=00001 po_cola=1 po_money=0
# @time  840ns :pi_money_one=1 pi_money_half=0 pi_money=10 state=00100 po_cola=0 po_money=0
# @time  860ns :pi_money_one=1 pi_money_half=0 pi_money=10 state=10000 po_cola=0 po_money=0
# @time  880ns :pi_money_one=0 pi_money_half=1 pi_money=01 state=00001 po_cola=1 po_money=1
run
# @time  900ns :pi_money_one=0 pi_money_half=1 pi_money=01 state=00010 po_cola=0 po_money=0
# @time  920ns :pi_money_one=1 pi_money_half=0 pi_money=10 state=00100 po_cola=0 po_money=0
# @time  940ns :pi_money_one=1 pi_money_half=0 pi_money=10 state=10000 po_cola=0 po_money=0
# @time  960ns :pi_money_one=1 pi_money_half=0 pi_money=10 state=00001 po_cola=1 po_money=1
# @time  980ns :pi_money_one=0 pi_money_half=1 pi_money=01 state=00100 po_cola=0 po_money=0
*/
           

仿真

【verilog】淺複習狀态機(FSM)狀态機代碼寫法案例一(簡單可樂機)代碼以及輸出案例二(可以找零的可樂機)

困了,累了,懶,一天寫一個都沒有。。。。