1
\$\begingroup\$

This is code for a lift (elevator). I am getting some delay in output. How can I get rid of these delays?

Code:

module lift(input clk_in,rst,input [1:0]r,output reg [2:0]out,
output reg clk_out);
parameter g0 = 4'b0000; //ground floor with no action
parameter g1 = 4'b0001; //ground floor with d1 output
parameter g2 = 4'b0010; //ground floor with d2 output
parameter f0 = 4'b0011; //first floor
parameter f1 = 4'b0100; //first floor with up1
parameter f2 = 4'b0101; //first floor with d1
parameter s0 = 4'b0110; //second floor
parameter s1 = 4'b0111; //second floor with up1
parameter s2 = 4'b1000; //second floor with up2
//outputs
parameter n = 3'b000;
parameter d1 = 3'b001;
parameter d2 = 3'b010;
parameter up1 = 3'b011;
parameter up2 = 3'b100;
//inputs
parameter r0 = 2'b00;
parameter r1 = 2'b01;
parameter r2 = 2'b10;
//current and next state registers
reg [3:0] state, nxt_state;
//clockDivider
reg[15:0]counter=16'd0;
parameter DIVISOR = 16'd32768;
always @(posedge clk_in)
begin
counter<=counter+16'd1;
if(counter>=(DIVISOR-1))
begin
counter<=16'd0;
end
clk_out<=(counter<DIVISOR/2)?1'b1:1'b0;
end
always@(posedge clk_out,posedge rst) begin
if(rst == 1)
state <= g0;
else
state <= nxt_state;
end
always@(state ,r) begin
case(state)
g0 : begin
if(r == r0)
nxt_state <= g0;
else if(r==r1)
nxt_state <= f1;
else
nxt_state <= s2;
end
g1 : begin
if(r == r0)
nxt_state <= g0;
else if(r==r1)
nxt_state <= f1;
else
nxt_state <= s2;
end
g2 : begin
if(r == r0)
nxt_state <= g0;
else if(r==r1)
nxt_state <= f1;
else
nxt_state <= s2;
end
f0 : begin
if(r == r1)
nxt_state <= f0;
else if(r == r0)
nxt_state <= g1;
else
nxt_state <= s1;
end
f1 : begin
if(r == r1)
nxt_state <= f0;
else if(r == r0)
nxt_state <= g1;
else
nxt_state <= s1;
end
f2 : begin
if(r == r1)
nxt_state <= f0;
else if(r == r0)
nxt_state <= g1;
else
nxt_state <= s1;
end
s0 : begin
if(r == r2)
nxt_state <= s0;
else if(r == r0)
nxt_state <= g2;
else
nxt_state <= f2;
end
s1 : begin
if(r == r2)
nxt_state <= s0;
else if(r == r0)
nxt_state <= g2;
else
nxt_state <= f2;
end
s2 : begin
if(r == r2)
nxt_state <= s0;
else if(r == r0)
nxt_state <= g2;
else
nxt_state <= f2;
end
default : nxt_state <= g0;
endcase
end
always@(state) begin
case(state)
g0 : out <= n;
g1 : out <= d1;
g2 : out <= d2;
f0 : out <= n;
f1 : out <= up1;
f2 : out <= d1;
s0 : out <= n;
s1 : out <= up1;
s2 : out <= up2;
endcase
end
endmodule

testbench:

module tb();
reg clk_in;
reg rst;
reg [1:0]r;
wire [2:0] out;
wire clk_out;
lift uut(clk_in,rst,r,out,clk_out);
initial begin
clk_in = 0;
forever #15259 clk_in=~clk_in;
end
initial begin
// Initialize Inputs
r = 2'b00;
rst = 1;
// Wait 100 ns for global reset to finish
#91554;
rst = 0;
@(negedge clk_out);
r = 2'b00;
@(negedge clk_out);
r = 2'b01;
@(negedge clk_out);
r = 2'b10;
@(negedge clk_out);
r = 2'b00;
@(negedge clk_out);
r = 2'b10;
@(negedge clk_out);
r = 2'b01;
$finish;
end
endmodule 

Simulation

\$\endgroup\$
0

2 Answers 2

0
\$\begingroup\$

always@(posedge clk_out,posedge rst) begin

Apparently your FSM is clocked by clk_out. You cannot get rid of this delay, it is an inherent property of clock-synchronous logic design. The entire idea of robust digital logic is based on these delays. If you want to reduce the delay, use faster clock.

\$\endgroup\$
0
\$\begingroup\$

You can control the delay between the r input and the out output by changing the testbench code.

Your testbench currently waits for the negedge of clk_out before changing the r input, but you can change r at any time you like.

For example, if you change

@(negedge clk_out);
r = 2'b00;

to

@(posedge clk_out);
r = 2'b00;

That will remove the delay between r and out (as seen in the waves below). You can change negedge to posedge everywhere in the testbench.

waves

You need to make sure this satisfies your timing requirements.

Here is the full initial block:

initial begin
  // Initialize Inputs
  r = 2'b00;
  rst = 1;
  // Wait 100 ns for global reset to finish
  #91554;
  rst = 0;
  @(posedge clk_out);
  r = 2'b00;
  @(posedge clk_out);
  r = 2'b01;
  @(posedge clk_out);
  r = 2'b10;
  @(posedge clk_out);
  r = 2'b00;
  @(posedge clk_out);
  r = 2'b10; 
  @(posedge clk_out);
  r = 2'b01;
  $finish;
end
\$\endgroup\$
2
  • \$\begingroup\$ when it changed to posedge, r changes at first posedge and out changes at the next posedge which increased the delay \$\endgroup\$
    – had
    Commented Jan 25 at 7:21
  • \$\begingroup\$ @had: I added waveforms to my answer to show that there is no delay between r and out. They change at the same time. I also added the full code so you can reproduce it. This was just one possible suggestion. You can change r at any time you like. \$\endgroup\$
    – toolic
    Commented Jan 25 at 12:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.