2017-10-21 40 views
0

我想學習使用EDA遊樂場的Verilog。我試圖通過結合下一個狀態和輸出邏輯來重寫Moore Machine:http://www.edaplayground.com/x/B非常簡單的FSM的怪異行爲

這裏是我做了什麼:

/* 
* Finite state machine.Moore Machine 
* If input 'a' is asserted, the state machine 
* moves IDLE->STATE_1->FINAL and remains in FINAL. 
* If 'a' is not asserted, FSM returns to idle. 
* Output 'out1' asserts when state machine is in 
* STATE_1. 'out2' asserts when state machine is in 
* FINAL state. 
*/ 
module fsm(clk, reset, a, out1, out2); 
    input clk; 
    input a; 
    input reset; 
    output out1, out2; 
    // State encodings 
    parameter [2:0] 
    IDLE = 3'b001, 
    STATE_1 = 3'b010, 
    FINAL = 3'b100; 
    reg [2:0] /* synopsys enum states */ current_state, next_state; 
// synopsys state_vector current_state 
reg out1, out2; 
    /*------- Sequential Logic ----*/ 
[email protected](posedge clk or negedge reset) 
    if (!reset) current_state <= IDLE; 
    else current_state <= next_state; 
/* next state logic and output logic – combined so as to share state decode logic */ 
    always @(posedge clk or negedge reset) 
    begin 
     out1 = 0; out2 = 0; 
     case (current_state) 
     IDLE: 
      begin 
      if (a) 
       begin out1= 1; out2=0; next_state <= STATE_1; end 
      else 
       begin out1= 0; out2=0;next_state <= IDLE;  end 
      end 
     STATE_1: 
      begin 
      if (a) 
       begin out1= 0; out2=1;next_state <= FINAL; end 
      else 
       begin out1= 0; out2=0;next_state <= IDLE; end 
      end 
     FINAL: 
      begin 
      if (a) 
      begin out1= 0; out2=1;next_state <= FINAL; end 
      else 
       begin out1= 0; out2=0;next_state <= IDLE;end 
      end 
     default: 
      begin out1= 0; out2=0; next_state <= IDLE;end 
     endcase 
    end 

endmodule 

但是,結果是不正確的,我得到

# KERNEL: ASDB file was created in location /home/runner/dataset.asdb 
run -all; 
# KERNEL: Initial a: 0,out1: x, out2: x 
# KERNEL: IDLE a: 0 ,out1: 0, out2: 0 
# KERNEL: STATE_1 a: 1 ,out1: 1, out2: 0 
# KERNEL: FINAL a: 1 ,out1: 1, out2: 0 
# KERNEL: FINAL a: 1,out1: 1, out2: 0 
# KERNEL: IDLE a: 0 ,out1: 0, out2: 0 
# KERNEL: Simulation has finished. There are no more test vectors to simulate. 
exit 

但是,預期的結果應該是:

run -all; 
# KERNEL: Initial a: 0,out1: x, out2: x 
# KERNEL: IDLE a: 0 ,out1: 0, out2: 0 
# KERNEL: STATE_1 a: 1 ,out1: 1, out2: 0 
# KERNEL: FINAL a: 1 ,out1: 0, out2: 1 
# KERNEL: FINAL a: 1,out1: 0, out2: 1 
# KERNEL: IDLE a: 0 ,out1: 0, out2: 0 
# KERNEL: Simulation has finished. There are no more test vectors to simulate. 

請問我做錯了什麼?

下面是測試夾具:

// Testbench 
module test; 

    reg clk, reset, a; 
    wire out1, out2; 

    // Instantiate device under test 
    fsm FSM(.clk(clk),.reset(reset), 
      .a(a), 
      .out1(out1), 
      .out2(out2)); 

    initial begin 
    // Dump waves 
    $dumpfile("dump.vcd"); 
    $dumpvars(1, test); 

    clk = 0; 
    reset = 1; 
    a = 0; 
    $display("Initial a: %0h,out1: %0h, out2: %0h", 
     a,out1, out2); 

    toggle_clk; 
    $display("IDLE a: %0h ,out1: %0h, out2: %0h", 
    a, out1, out2); 

    a = 1; 
    toggle_clk; 
    $display("STATE_1 a: %0h ,out1: %0h, out2: %0h", 
     a,out1, out2); 

    toggle_clk; 
    $display("FINAL a: %0h ,out1: %0h, out2: %0h", 
     a,out1, out2); 

    toggle_clk; 
    $display("FINAL a: %0h,out1: %0h, out2: %0h", 
     a,out1, out2); 

    a = 0; 
    toggle_clk; 
    $display("IDLE a: %0h ,out1: %0h, out2: %0h", 
     a,out1, out2); 
    end 

    task toggle_clk; 
    begin 
     #10 clk = ~clk; 
     #10 clk = ~clk; 
    end 
    endtask 

endmodule 

非常感謝你提前,

CS

+1

提示:'next_state'應該是一個組合邏輯,在'always @ *'中賦值並且阻塞('=')賦值。 – Greg

+0

非常感謝格雷格非常有用的提示。喲絕對正確。我不得不在靈敏度列表中添加一個。 – chikitin

回答

0

我試圖用Verilog 95實現米利機,但是,我sesetivity名單不完整。非常感謝格雷格的幫助。

/* 
* Finite state machine.Moore Machine 
* If input 'a' is asserted, the state machine 
* moves IDLE->STATE_1->FINAL and remains in FINAL. 
* If 'a' is not asserted, FSM returns to idle. 
* Output 'out1' asserts when state machine is in 
* STATE_1. 'out2' asserts when state machine is in 
* FINAL state. 
*/ 
module fsm(clk, reset, a, out1, out2); 
    input clk; 
    input a; 
    input reset; 
    output out1, out2; 
    // State encodings 
    parameter [2:0] 
    IDLE = 3'b001, 
    STATE_1 = 3'b010, 
    FINAL = 3'b100; 
    reg [2:0] /* synopsys enum states */ current_state, next_state; 
// synopsys state_vector current_state 
reg out1, out2; 
    /*------- Sequential Logic ----*/ 
[email protected](posedge clk or negedge reset) 
    if (!reset) current_state <= IDLE; 
    else current_state <= next_state; 
/* next state logic and output logic – combined so as to share state decode logic */ 
    always @(posedge clk or negedge reset or a) 
    begin 
     out1 = 0; out2 = 0; 
     case (current_state) 
     IDLE: 
      begin 
      if (a) 
       begin out1= 1; out2=0; next_state = STATE_1; end 
      else 
       begin out1= 0; out2=0;next_state = IDLE;  end 
      end 
     STATE_1: 
      begin 
      if (a) 
       begin out1= 0; out2=1;next_state = FINAL; end 
      else 
       begin out1= 0; out2=0;next_state = IDLE; end 
      end 
     FINAL: 
      begin 
      if (a) 
      begin out1= 0; out2=1;next_state = FINAL; end 
      else 
       begin out1= 0; out2=0;next_state = IDLE;end 
      end 
     default: 
      begin out1= 0; out2=0; next_state = IDLE;end 
     endcase 
    end 

endmodule 
+1

這仍然是錯誤的敏感列表。組合邏輯不應該對時鐘或任何「posedge」/「negedge」信號敏感。對於Verilog-95,它應該是'always @(current_state或a)'。對於Verilog-2001及更高版本,請使用'always @ *'或同義詞'always @(*)'。 – Greg

+0

你是對的。再一次非常感謝你。我將在下一次努力中考慮這一點。 – chikitin