- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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, SeanLink Copied
9 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
yup, you're right. I'm a bit old-fashioned ;-)
But you must admit, this works too.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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

Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page