Programmable Devices
CPLDs, FPGAs, SoC FPGAs, Configuration, and Transceivers
21323 Discussions

Looking for state machine in verilog

Altera_Forum
Honored Contributor II
1,863 Views

Hello there, 

 

 

I'm running into the problem that I don't know how to do this. I want to write state machine to run 2 conditions on my project. When I turn on machine, I want it runs 1st condition for sometimes ns, then kick in the 2nd condition to take over. 

 

 

Thanks, 

Sean
0 Kudos
9 Replies
Altera_Forum
Honored Contributor II
828 Views

You can achieve this by creating two processes (I don't know how this is called in verilog, I'm more into VHDL). 

The first process sets a pre-initialized signal from "State1" to "State2" if it gets a special signal from the second process. 

In the second process you put an if-statement like: 

State-Signal = State1 Switch-Signal = 0 Process1: if (Switch-Signal = 1) { Set State-Signal to "State2" } Process2: if (State-Signal = State1) then { Your code for State1 if (time is up) { Switch-Signal = 1 } } else { Your code for State2 }  

 

this is a very raw example, how it is done normally. You can also use a switch-case-statement instead. 

You can also check if the time is up in process1 and then set state2 there.
0 Kudos
Altera_Forum
Honored Contributor II
828 Views

 

--- Quote Start ---  

You can achieve this by creating two processes (I don't know how this is called in verilog, I'm more into VHDL). 

The first process sets a pre-initialized signal from "State1" to "State2" if it gets a special signal from the second process. 

In the second process you put an if-statement like: 

 

--- Quote End ---  

 

 

I really dont know what you're on about (your post does not make a lot of sense). A lot of old text books teams the two process method, but the apparent prefered method now is a single process. 

 

to the OP: there are plenty of examples out there - did you try google yet?
0 Kudos
Altera_Forum
Honored Contributor II
828 Views

yup, you're right. I'm a bit old-fashioned ;-)  

But you must admit, this works too.
0 Kudos
Altera_Forum
Honored Contributor II
828 Views

 

--- Quote Start ---  

yup, you're right. I'm a bit old-fashioned ;-)  

But you must admit, this works too. 

--- Quote End ---  

 

 

Yes it does, and Im sure its how many started, but you can easily fall into the latch trap. 

As I understand the 2 process state machine is a throwback to very old compilers that could only cope with registers and logic in separate processes. But this hasnt been the case for a long time. 

 

For anyone starting, I would always recommend a single process (it reads better in my mind too - more like software!) 

 

To the OP - AFAIK, the same problems can also happen in verilog. So get googling.
0 Kudos
Altera_Forum
Honored Contributor II
828 Views

 

--- Quote Start ---  

Yes it does, and Im sure its how many started, but you can easily fall into the latch trap. 

As I understand the 2 process state machine is a throwback to very old compilers that could only cope with registers and logic in separate processes. But this hasnt been the case for a long time. 

 

For anyone starting, I would always recommend a single process (it reads better in my mind too - more like software!) 

 

To the OP - AFAIK, the same problems can also happen in verilog. So get googling. 

--- Quote End ---  

 

 

 

Thank you folks.  

Could you point me to the sample? So I want to know the idea how this works. 

 

Best, 

Sean
0 Kudos
Altera_Forum
Honored Contributor II
828 Views

Ok. I can explain more detail about how to solve. 

 

When I turn on machine at very first time, I want to output pwms out with fix duty cycle and runs over period time, then I want to switch to real pwm (calculate from loop feedback). My co-worker thinks to use Mux 2 to 1 with timer (counter).  

 

Hope you guys have some good news.
0 Kudos
Altera_Forum
Honored Contributor II
828 Views

 

--- Quote Start ---  

I. A lot of old text books teams the two process method, but the apparent prefered method now is a single process. 

 

--- Quote End ---  

 

 

--- Quote Start ---  

Yes it does, and Im sure its how many started, but you can easily fall into the latch trap. 

As I understand the 2 process state machine is a throwback to very old compilers that could only cope with registers and logic in separate processes. But this hasnt been the case for a long time. 

 

For anyone starting, I would always recommend a single process (it reads better in my mind too - more like software!) 

 

To the OP - AFAIK, the same problems can also happen in verilog. So get googling. 

--- Quote End ---  

 

 

One-process state machines may seem to be the preferred method and will handle a lot of tasks but not all. Often you need combinatorial (non-registered) outputs and then the two-process is a lot easier to write and maintain than the 'one-process' where you have to anyway add that second process where you have to repeat most of the work to fabricate these combinatorial outputs. Most of my modules are ST-components for use in Qsys, and to handle the backpressure graciously you need combinatorial outputs. So Steffen, don't apologize. Two-process state machines are fine and certainly not out of fashion! 

 

Regards, 

 

Josy
0 Kudos
Altera_Forum
Honored Contributor II
828 Views

Does your logic state machine is working?  

 

I have my code here and hope you could find error in my code... 

 

 

 

 

localparam State1 = 0; 

localparam State2 = 1; 

 

reg [31:0] rCntr; 

reg [15:0] rTmCntr1, rTmCntr2; 

reg wPwm, StateSignal, SwitchSignal; 

 

initial begin 

rTmCntr1 = 0; 

rTmCntr2 = 0; 

rCntr = 2000000; 

wPwm = 0; 

StateSignal = State1; 

SwitchSignal = 0; 

end 

 

always @(posedge c0) begin 

if (SwitchSignal == 1)  

StateSignal = State2; 

end 

 

always @(posedge c0) begin 

if (StateSignal == State1) begin 

// code for State1 

if (Enable == 1'b1) begin 

rTmCntr1 <= rTmCntr1 + 1'b1; 

if (rTmCntr1 < 2500)  

wPwm <= 1; 

else if (rTmCntr1 > 2500)  

wPwm <= 0; 

 

if (rTmCntr1 == 5000)  

rTmCntr1 <= 1'b0; 

end 

 

if (rCntr > 0) 

rCntr <= rCntr - 1'b1; 

else if (rCntr == 10) 

SwitchSignal = 1; 

end 

else begin 

// code for State2 

if (Enable == 1'b1) begin 

rTmCntr2 <= rTmCntr2 + 1'b1; 

if (rTmCntr2 < 1250)  

wPwm <= 1; 

else if (rTmCntr2 > 5000)  

wPwm <= 0; 

 

if (rTmCntr2 == 5000)  

rTmCntr2 <= 1'b0; 

end 

end 

end  

 

 

 

Thanks, 

Sean
0 Kudos
Altera_Forum
Honored Contributor II
828 Views

As I said, i'm mor into VHDL than Verilog. 

Please use CODE-Tags if you want to write Code in your Post. It makes debugging easier. 

 

What is your Error-Message? 

 

I think you have forgotten to close some of your if statements. This is how I read your code: 

 

localparam State1 = 0; localparam State2 = 1; reg rCntr; reg rTmCntr1, rTmCntr2; reg wPwm, StateSignal, SwitchSignal; initial begin rTmCntr1 = 0; rTmCntr2 = 0; rCntr = 2000000; wPwm = 0; StateSignal = State1; SwitchSignal = 0; end always @(posedge c0) begin if (SwitchSignal == 1) StateSignal = State2; end always @(posedge c0) begin if (StateSignal == State1) begin // code for State1 if (Enable == 1'b1) begin rTmCntr1 <= rTmCntr1 + 1'b1; if (rTmCntr1 < 2500) wPwm <= 1; else if (rTmCntr1 > 2500) wPwm <= 0; if (rTmCntr1 == 5000) rTmCntr1 <= 1'b0; end if (rCntr > 0) rCntr <= rCntr - 1'b1; else if (rCntr == 10) SwitchSignal = 1; end else begin // code for State2 if (Enable == 1'b1) begin rTmCntr2 <= rTmCntr2 + 1'b1; if (rTmCntr2 < 1250) wPwm <= 1; else if (rTmCntr2 > 5000) wPwm <= 0; if (rTmCntr2 == 5000) rTmCntr2 <= 1'b0; end end end 

 

And this is how I think it should work (better): 

 

localparam State1 = 0; localparam State2 = 1; reg rCntr; reg rTmCntr1, rTmCntr2; reg wPwm, StateSignal, SwitchSignal; initial begin rTmCntr1 = 0; rTmCntr2 = 0; rCntr = 2000000; wPwm = 0; StateSignal = State1; SwitchSignal = 0; end always @(posedge c0) begin if (SwitchSignal == 1) StateSignal = State2; end always @(posedge c0) begin if (StateSignal == State1) begin // code for State1 if (Enable == 1'b1) begin rTmCntr1 <= rTmCntr1 + 1'b1; if (rTmCntr1 < 2500) wPwm <= 1; else if (rTmCntr1 > 2500) wPwm <= 0; if (rTmCntr1 == 5000) rTmCntr1 <= 1'b0; end if (rCntr > 0) rCntr <= rCntr - 1'b1; else if (rCntr == 10) SwitchSignal = 1; end end end else begin // code for State2 if (Enable == 1'b1) begin rTmCntr2 <= rTmCntr2 + 1'b1; if (rTmCntr2 < 1250) wPwm <= 1; else if (rTmCntr2 > 5000) wPwm <= 0; if (rTmCntr2 == 5000) rTmCntr2 <= 1'b0; end end end
0 Kudos
Reply