1,mealy狀態機與moore狀態機的特征區別?
可以從圖中較為明顯的發現:mealy狀態機的輸出是不僅跟當前狀態有關,還跟輸入信號有關。
moore狀態機的輸出只跟當前狀態有關。
因此mealy狀態機的輸出容易受到輸入中的毛刺影響,且moore狀態機相比mealy狀態機在輸出時,多等待一個時鍾周期。
狀態機又可分為二段式和三段式,因此狀態機類型可分為mealy二段,mealy三段,moore二段,moore三段。
2,個人理解中,狀態機最重要的部分是:狀態的轉換-即always組合邏輯部分。通過判斷不同狀態個數,設置合理的寄存器bit位,可避免出現資源的浪費。又當需要對狀態進行精簡時,可使用mealy狀態機。
3,序列檢測器--1100101
moore二段式寫法,狀態轉移圖如下(線還是丑了一些,勉強看吧)
主程序:
module sequence_fsm (
clk,rst,d_in,d_out
);
input clk;
input rst;
input d_in;
output d_out;
reg d_out;
parameter s0 = 3'b000;
parameter s1 = 3'b001;
parameter s2 = 3'b010;
parameter s3 = 3'b011;
parameter s4 = 3'b100;
parameter s5 = 3'b101;
parameter s6 = 3'b110;
parameter s7 = 3'b111;
reg [3:0]state,nextstate;
always @(posedge clk or negedge rst) begin
if(!rst) begin
state <= s0;
end
else begin
state <= nextstate;
end
end
always @(state or d_in) begin
d_out = 1'b0;
nextstate = 3'bxxx;
case(state)
s0: begin
d_out = 1'b0;
if(d_in == 1'b0) begin
nextstate = s0;
end
else begin
nextstate = s1;
end
end
s1: begin
d_out = 1'b0;
if(d_in == 1'b0) begin
nextstate = s0;
end
else begin
nextstate = s2;
end
end
s2: begin
d_out = 1'b0;
if(d_in == 1'b0) begin
nextstate = s3;
end
else begin
nextstate = s2;
end
end
s3: begin
d_out = 1'b0;
if (d_in == 1'b0) begin
nextstate = s4;
end
else begin
nextstate = s1;
end
end
s4: begin
d_out = 1'b0;
if (d_in == 1'b0) begin
nextstate = s0;
end
else begin
nextstate = s5;
end
end
s5: begin
d_out = 1'b0;
if (d_in == 1'b0) begin
nextstate = s6;
end
else begin
nextstate = s2;
end
end
s6: begin
d_out = 1'b0;
if (d_in == 1'b0) begin
nextstate = s0;
end
else begin
nextstate = s7;
end
end
s7: begin
d_out = 1'b1;
if (d_in == 1'b0) begin
nextstate = s0;
end
else begin
nextstate = s2;
end
end
default: begin
d_out = 1'b0;
nextstate = s0;
end
endcase
end
endmodule
tb程序:
`timescale 1ns/1ps
module sequence_fsm_tb;
reg clk;
reg rst;
reg d_in;
wire d_out;
sequence_fsm u1(
.clk(clk),
.rst(rst),
.d_in(d_in),
.d_out(d_out)
);
initial begin
clk = 1'b1;
rst = 1'b0;
#10;
rst = 1'b1;
end
always #5 clk = ~clk;
initial begin
#10 d_in = 0;
$display("display:simulation time is : %t",$time,"the value is :%b",d_in);
#10 d_in = 0;
$display("display:simulation time is : %t",$time,"the value is :%b",d_in);
#10 d_in = 1;
$display("display:simulation time is : %t",$time,"the value is :%b",d_in);
#10 d_in = 1;
$display("display:simulation time is : %t",$time,"the value is :%b",d_in);
#10 d_in = 0;
$display("display:simulation time is : %t",$time,"the value is :%b",d_in);
#10 d_in = 0;
$display("display:simulation time is : %t",$time,"the value is :%b",d_in);
#10 d_in = 1;
$display("display:simulation time is : %t",$time,"the value is :%b",d_in);
#10 d_in = 0;
$display("display:simulation time is : %t",$time,"the value is :%b",d_in);
#10 d_in = 1;
$display("display:simulation time is : %t",$time,"the value is :%b",d_in);
#10 d_in = 1;
$display("display:simulation time is : %t",$time,"the value is :%b",d_in);
#10 d_in = 0;
$display("display:simulation time is : %t",$time,"the value is :%b",d_in);
#10 d_in = 0;
$display("display:simulation time is : %t",$time,"the value is :%b",d_in);
#10 d_in = 1;
$display("display:simulation time is : %t",$time,"the value is :%b",d_in);
#10 d_in = 0;
$display("display:simulation time is : %t",$time,"the value is :%b",d_in);
#10 d_in = 1;
$display("display:simulation time is : %t",$time,"the value is :%b",d_in);
#10 d_in = 0;
$display("display:simulation time is : %t",$time,"the value is :%b",d_in);
#10 d_in = 0;
$display("display:simulation time is : %t",$time,"the value is :%b",d_in);//前面的賦值驗證正確性,后面采用隨機賦值
forever #10 begin
d_in = {$random}%2;
$display("display:simulation time is : %t",$time,"the value is :%b",d_in);
end
end
endmodule
局部放大:
由仿真結果可以看出;moore的輸出要晚一個時鍾。
總結:forever只能用於仿真和測試程序,不能進行可綜合設計,且一般用在initial過程塊中,如果在forever語句中沒有加延時語句,則forever將在0延時后無限循環。
$random%b:如果忽略b的值,則會返回一個隨機的32位有符號數,如果考慮b的值,則會返回[1-b,b-1]這個區間內的等概率有符號隨機數。
{$random}%b:因為{ }返回的是無符號數,所以可以通過位拼接符將返回的有符號數轉變為無符號數。當b>0時,返回的無符號隨機數的范圍[0,b-1].