I'm new to Verilog. I was trying to write the next Finite State Machines (miley machine) in Verilog:https://i.stack.imgur.com/9rvCj.jpg One of the attached file (called FSM.v) is the program I built in Verilog. I tried some tests (The test program is provided. It's called "FSM_tester.v") but some of them fail. I think its because the always clock block.
You are assigning a value to 'out' in both always blocks. You can't do this. You need to remove it from the clocked always block into the other. In your case 'out' results in a combinational circuit. Giving it a value in the clocked block is wrong.You're also using blocking assignments in your clocked block. Although it makes no odds in your code, it is common practice to use the non-blocking assignment operator. There are perfectly good reasons to use the blocking operator. However, given you'er new to the language I suggest you stick to non-blocking assignments (in clocked always blocks only) until you're more fluent with the language. Have alook at "blocking and nonblocking in verilog (http://www.asic-world.com/tidbits/blocking.html)". Cheers, Alex
Hi Verilogoz,1.Did you Simulate?There is a mapping error in FSM_tester. 2.Clock should be given at right bock.(Sequential block not at combination block). 3.Mealy state machine output change when ever there is change in input or state. FSM.v
module FSM (clock,reset,in,out); input clock,reset,in; output out; wire clock,reset,in; reg out; reg present_state; reg next_state; localparam A=2'b00, B=2'b01, C=2'b10; always @(posedge clock ) begin case (present_state) A: if(in) begin next_state <= B; end else begin next_state <= A; end B: if(in) begin next_state <= A; end else begin next_state <= C; end C: if(in) begin next_state <= C; end else begin next_state <= B; end endcase end always @(present_state or in or posedge reset) begin if(reset) begin present_state = 2'b00; out = 1'b0; end else begin present_state=next_state; case (present_state) A: out = 1'b0; B: out = in; C: out = 1'b1; endcase end end endmoduleFSM_tester.v
module FSM_tester; reg clock, reset, in; wire out; FSM U0 ( .clock (clock), .reset (reset), .in (in), .out (out) ); initial begin clock = 1; reset = 1; in = 1; $display("Simulation..."); # 2; if (out !== 1'b0) $display("Failed1"); // Check reset reset = 0; # 2; if (out !== 1'b0) $display("Failed2"); # 2; if (out !== 1'b1) $display("Failed3"); # 2; if (out !== 1'b0) $display("Failed4"); # 2; if (out !== 1'b1) $display("Failed5"); # 2; if (out !== 1'b0) $display("Failed6"); $display("Done..."); end always begin # 1 clock = !clock; end always begin# 3 in=~in; end endmoduleBest Regards, Anand Raj Shankar (This message was posted on behalf of Intel Corporation)
Forgive me but the code you've posted, Anand, is still fundamentally wrong - in the same way the original code was. You cannot assign 'out' a value in two different always blocks, which you are still doing.There a several other aspects of the code you've posted that I also dislike - both 'next_state' and 'present_state' being update in the same always block, both assigned with non-blocking assignments. 'present_state' isn't going to update for two clock cycles. So, there's also a very good change 'out' takes the wrong value for the extra, unnecessary, clock cycle. Verilogoz, I much prefer the code you originally posted - save the minor mistake it had. I suggest you work with that as a basis for your solution. Cheers, Alex
For the SM you've put up, here's the Verilog Code..Since the outputs are on the States and not on the transitions, the state machine code will be like below.
module SM1 ( clock, reset, in1, out1 ); input clock; input reset; input in1; output out1; reg out1; reg current_state; reg next_state; parameter S0=0,S1=1,S2=2; always @(posedge clock or negedge reset) begin if (~reset) begin current_state <= S0; end else begin current_state <= next_state; end end always @(current_state or in1) begin out1 <= 1'b0; case (current_state) S0: begin if ((in1 == 1'b1)) next_state <= S1; else if ((in1 == 1'b0)) next_state <= S0; else next_state <= S0; out1 <= 1'b0; end S1: begin if ((in1 == 1'b0)) next_state <= S2; else if ((in1 == 1'b1)) next_state <= S0; else next_state <= S1; out1 <= in1; end S2: begin if ((in1 == 1'b0)) next_state <= S1; else if ((in1 == 1'b1)) next_state <= S2; else next_state <= S2; out1 <= 1'b1; end default: begin out1 <= 1'b0; end endcase end endmodule // SM1
You can also use the State Machine Editor that comes packaged with the Altera Quartus tool to draw your FSMs and have it generate the VHDL/Verilog code for you.File -> New -> State Machine File. Here you can specify the inputs, outputs, states and transitions. Once done, select the language you want to generate (VHDL/Verilog) and click Generate. This will add the FSM and generated code to your project.
Please refer to State machine templates provided with Quartus Prime.In your Verilog file do this. Right click > Insert Template > Navigate to Verilog HDL > Full Designs > State Machines > Select Mealy or Moore state machines and Insert code to your file. Once you have a template feel free to modify this are per your requirement. Hope this helps. Best Regards, arslanusman2003 (This message was posted on behalf of Intel Corporation)