comp_engineer
Newbie level 5
- Joined
- Mar 23, 2013
- Messages
- 10
- Helped
- 0
- Reputation
- 0
- Reaction score
- 0
- Trophy points
- 1,281
- Activity points
- 1,385
A rising‐edge detector is a circuit that generates a one clock‐cycle pulse every time the input signal din changes from 0 to 1.
The detector also receives the clock signal CLK and a reset signal RESET and generates the output signal pe.
Use zero as the reset state.
`define zero 1'b0
`define one 1'b1
module MooreFSM(clk, reset, din, pe);
input clk, reset, din;
output reg pe;
reg out;
reg state;
reg next_state;
always@(posedge clk) begin
if(reset) state = 1'b0; //if there is a reset signal the state goes to state zero
else state = next_state;
end
always@(din or state) begin
case(state)
zero : //last input was a zero
begin
if(din) next_state = pe;
else next_state = 1'b0;
end
one : //we've seen 1
begin
if(din) next_state = 1'b1;
else next_state = 1'b0;
end
endcase
end
/*
always@(state) begin
case(state)
'zero: out =
'Edge: out =
'one : out =
endcase
end
*/
endmodule
You need to add a third state. In state "one" you will transition immediately to a "terminate" state, where you wait for din to go low before you transition back to "zero" state.
`define zero 1'b0
`define one 1'b1
`define Edge
always@(din or state) begin
case(state)
`zero : //last input was a zero
begin
if(din) next_state = `one;
else next_state = `zero;
end
//this is the state where the pulse is generated??
'Edge :
begin
if(din) next_state =
end else next_state = 'zero;
`one : //we've seen 1
begin
if(din) next_state = `one;
else pe = `zero;
end
endcase
endmodule
My solution assumed the signals were synchronous. I was only building on the OP's original design with the FSM and no asynchronous signals. I was not suggesting a general solution.
/* State Assignments */
`define zero 2'b00
`define Edge 2'b01
`define one 2'b10
module MooreFSM(clk, reset, din, pe);
input clk, reset, din;
output reg pe;
reg [1:0] state; //current state
reg [1:0] next_state; //next state
always@(posedge clk) begin
if(reset) state <= `zero; //if there is a reset signal the state goes to zero
else state <= next_state;
end
always@(din or state) begin
case(state)
`zero : //last input was a zero
begin
if(din)
next_state = `one;
else
next_state = `zero;
pe = 0;
end
`Edge :
begin
if(din) next_state = `one;
else next_state = `zero;
end
`one :
begin
if(din) next_state = `one;
else next_state = `zero;
end
endcase
end
always@(state) begin
case(state)
`zero: pe = 0;
`Edge: pe = 0;
`one : pe = 1;
endcase
end
endmodule
Hi
Your code doesn't follow what I said at all. I had hoped I had written it in such a way that you could turn each paragraph into a state.
You should be simulating your code and then you would see that it is not doing what you want it to do. At very least you could draw the timing diagram with pencil and paper and see the results of your design.
Also note FvM's post. The approach you are taking only works if din is from the same clock domain, and it only works if din is zero when your state machine (once it is working right) comes out of reset. For true generic edge detection FvM's solutions are preferred.
r.b.
Since you would have three states, you would need to have a 2-bit state register. I am in a bit of a rush, and since I don't want to do all your homework for you, I will give a quick description:
State "zero": if din is high, the next state will be state "one" otherwise stay in state "zero". pe is driven low in this state.
`zero : //last input was a zero
begin
if(din)
next_state = `one;
else
next_state = `zero;
pe = 0;
end
State "one": next state is state "terminate". Drive pe high in this state.
`define one 2'b10
`one :
begin
if(din) next_state = `terminate;
pe = 1;
end
State "terminate": if din is low, next state is "zero" otherwise stay in state " terminate". drive pe low here if pe is to be a pulse, drive it high if it is to be driven for a longer period of time.
`define terminate 2'b01
`terminate :
begin
if(!din) next_state = `zero;
else next_state = `terminate;
pe = 0;
end
Since you have a 2bit state register to be thorough you may want to add a default state. You can Google that.
default : next_state = 2'bx; //don't care?
My apologies for confusing you. I was tired and did not read either your code or state diagram very well. You are quite close to your goal.
Your state "Edge" is the same as my state "One" and your State "One" is the same as my state "Terminate". You did me one better by having the ability to go back to state "Zero" if zero is encountered. I forgot to type that. But in order to generate a one-clock-wide pe pulse on detecting the edge, you should set pe to one in the edge state only. You can do this be modifying your second always block to set pe to one in the Edge state rather than the One state. You can simplify it even farther by typing pe=0; in the Zero state, pe=1; in the Edge state and pe=0; in the One State, and getting rid of the second always block.
As for the default state, this is mostly for good design practice. It is used when the number of described states is not a power of two. If for some reason your state register were to take on a value of 2'b11 because of a design error or implementation error, you want the state machine to fail gracefully. In your case, set next_state = Zero and pe=0 in the default state, In very large team designs, where you are required to run your code through linting tools, having default clauses saves you the time of having to sort through extra warnings about missing default state declarations.
You should ask your mentors if you are required to cover the case where din is high when you come out of reset. Your current state machine would give a false positive in that case. In many systems din would be controlled by the same reset that your state machine is, so it will likely be be zero after reset, but that is not always the case. Also, if din is not generated by the clock that is running your state machine, your edge detector will not always work (This a first design; they probably didn't want you to worry about this case).
Since you are taking an internship, ask your mentors to set you up with a Verilog simulator so you can simulate your own designs and see if they operate correctly.
Again, my apologies for confusing you.
r.b.
/*
Output only a function of the current state and the transitions
between states are only functions of the current inputs
*/
/* State Assignments */
`define zero 2'b00
`define Edge 2'b01 //one
`define one 2'b10 //terminate
module MooreFSM(clk, reset, din, pe);
input clk, reset, din;
output reg pe;
reg [1:0] state; //current state
reg [1:0] next_state; //next state
always@(posedge clk or posedge reset) begin
if(reset) state <= `zero; //if there is a reset signal the state goes to zero
else state <= next_state;
end
always@(din or state) begin
case(state)
`zero : //last input was a zero
begin
if(din) next_state <= `one;
else next_state <= `zero;
pe <= 0;
end
//to set a 1-clock wide pe pulse on detecting the edge
//pe set to 1 only in the edge state
`Edge :
begin
if(din) next_state <= `one;
else next_state <= `zero;
pe <= 1;
end
`one :
begin
if(din) next_state <= `one;
else next_state <= `zero;
pe <= 0;
end
default:
begin
next_state <= `zero;
pe <= 0;
end
endcase
end
endmodule
module tb_MooreFSM;
// Inputs
reg clk, reset, din;
// Outputs
wire pe;
initial begin
clk = 1'b0;
forever
#10 clk=~clk;
end
initial begin
$monitor("%g,reset=%b,clk=%b,din=%b,pe=%b", $time, reset, [ATTACH=CONFIG]88460._xfImport[/ATTACH]clk,din,pe);
// Initialize Inputs
#0 reset = 1'b0;
din = 1'b0;
// Wait 100 ns for global reset to finish
//#100;
// Add stimulus here
#5 //reset=1'b1; @(posedge clk)
din=1'b0; @(posedge clk)
din=1'b1; @(posedge clk)
din=1'b0; @(posedge clk)
din=1'b1; @(posedge clk)
din=1'b0; @(posedge clk)
din=1'b1; @(posedge clk)
din=1'b0; @(posedge clk)
din=1'b1; @(posedge clk)
din=1'b0; @(posedge clk)
din=1'b1; @(posedge clk)
din=1'b0; @(posedge clk)
din=1'b1; @(posedge clk)
din=1'b0; @(posedge clk)
din=1'b1; @(posedge clk)
din=1'b0; @(posedge clk)
din=1'b1; @(posedge clk)
din=1'b0; @(posedge clk)
#10 $stop;
end
// Instantiate the Unit Under Test (UUT)
MooreFSM uut (
.clk(clk),
.reset(reset),
.din(din),
.pe(pe)
);
endmodule
module edgedetect(clk, reset, din, pe);
input clk, reset, din;
output reg pe;
reg [2:0] edge_mem;
always@(posedge clk or posedge reset)
if(reset) begin
edge_mem <= 3'b0;
pe <= 1'b0;
end
else begin
edge_mem <= {edge_mem[1:0],din};
pe <= edge_mem[1] && !edge_mem[2];
end
endmodule
/* State Assignments */
`define zero 2'b00
`define Edge 2'b01 //one
`define one 2'b10 //terminate
module MooreFSM(clk, reset, din, pe);
input clk, reset, din;
output reg pe;
reg [1:0] state; //current state
reg [1:0] next_state; //next state
//state register
always@(posedge clk or posedge reset) begin
if(reset) state <= `zero; //if there is a reset signal the state goes to zero
else state <= next_state;
end
//next_state output logic
always@(state or din) begin
next_state <= state;
pe <= 0;
case(state)
`zero :
begin
if(din) next_state <= `Edge;
end
/* set a 1-clock wide pulse on detecting the edge */
`Edge :
begin
pe <= 1;
if(din) next_state <= `one;
else next_state <= `zero;
end
`one : if(~din) next_state <= `zero;
default: next_state <= `zero;
endcase
end
endmodule
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?