1

This is my code to control a RC Servo Motor. The code basically turns the 50MHz frequency to 1KHz.

I am using one of the switches on the FPGA to control the motor. Until the switch is on, none of the program should run. But that doesn't seem to be happening. I don't know what I'm doing wrong. It's probably a very silly mistake.

module servo(clk,rst,clk_out,switch);
  input clk,rst,switch;
  output reg clk_out;
  reg [15:0] counter;

  always @(posedge clk or posedge rst or posedge switch)
    if (switch) begin
     if(rst) begin
       counter <=16'd0;
       clk_out <= 1'b0;
     end
     else if(counter==16'd25000) begin
       counter <=16'd0;
       clk_out <= ~clk_out;
     end
     else begin
       counter<=counter+1;
     end
   end
endmodule

Also I tried changing the duty cycle so the motor rotates faster, but this doesn't seem to be working.

module servo (clk,rst,clk_out,switch);
input clk,rst,switch;
output reg clk_out;
reg [15:0] counter;
always @(posedge clk or posedge rst)

if(rst)
begin
counter<=16'd0;
clk_out <= 1'b0;
end

else if (switch)

begin
  if(counter==16'd12500)
   begin
  clk_out <= 1'b1;
  counter<=counter+1;
   end
else
if(counter==16'd50000)
  begin
counter <= 16'd0;
clk_out <= 1'b0;
  end
else
  begin
counter<=counter+1;
  end
end
endmodule

1 Answer 1

1

Here's my cut at it - I haven't simulated it, so beware!

module servo(clk,rst,clk_out,switch);
input clk,rst,switch;
output reg clk_out;
reg [15:0] counter;

// clocked blocks should only have the clock and maybe a reset
// in the sensitivity list
always @(posedge clk or posedge rst) begin
    if(rst) begin
        counter <=16'd0;
        clk_out <= 1'b0;
    end
    else if (switch) begin  // 'switch' used as an enable
        if(counter==16'd25000) begin
            counter <=16'd0;
            clk_out <= ~clk_out;
        end
        else begin
            counter<=counter+1;
        end
    end
    else begin
        counter <= 16'd0;
    end
end
endmodule

First thing I did was to remove the entry for switch in the sensitivity list - for synchronous logic, there should only be a clock and maybe a reset here.

The reset clause for the logic should be first, so I moved the test for switch using it as an enable signal in the main body of the always block. The counter will only run now if switch is high.

Sign up to request clarification or add additional context in comments.

5 Comments

Yes I tried doing something like this but the counter would keep incrementing. I have a question: say the counter value is currently 1 and switch is high. Thus it will skip the "if(counter==16'd25000)" bit and go straight to incrementing the counter by 1. and then go back to the beginning of the loop. So what is the need of the end bit: else begin counter <= 16'd0; end
NB: Implying Set Reset flip-flops have 3 edge sensitive signals in the sensitivity list.
It's not really needed, I suppose.
@user1847610 so when you disable it, then turn it back on it starts from the beginning.
Hope I'm not pushing it too much but I'd be very grateful if you could help me with altering the duty cycle. I've added it to my question.

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.