Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Servo controller in verilog. Takes an 8-bit position and converts it into the pwm signal required by a servo motor.
/*
servo controller
Based on code from Mojo tutorial
https://embeddedmicro.com/tutorials/mojo/servos
Takes an 8-bit position as an input
Output a single pwm signal with period of ~20ms
Pulse width = 1ms -> 2ms full scale. 1.5ms is center position
*/
module servo_controller (
input clk,
input rst,
input [7:0] position,
output servo
);
reg pwm_q, pwm_d;
reg [19:0] ctr_q, ctr_d;
assign servo = pwm_q;
//position (0-255) maps to 50,000-100,000 (which corresponds to 1ms-2ms @ 50MHz)
//this is approximately (position+165)<<8
//The servo output is set by comparing the position input with the value of the counter (ctr_q)
always @(*) begin
ctr_d = ctr_q + 1'b1;
if (position + 9'd165 > ctr_q[19:8]) begin
pwm_d = 1'b1;
end else begin
pwm_d = 1'b0;
end
end
always @(posedge clk) begin
if (rst) begin
ctr_q <= 1'b0;
end else begin
ctr_q <= ctr_d;
end
pwm_q <= pwm_d;
end
endmodule
@issmgbln
Copy link

issmgbln commented Feb 18, 2018

Hi, I was wondering how do you adjust the pulse width? like how do i change the 1ms to 0.5ms?

@keesj
Copy link

keesj commented May 1, 2019

the pulse with is influenced by the value of "position" e.g. if position changes the comparison on line 25 will cause the pulse with to change.
This design also assumed a 50MHz clock and in the same line (25) the value is compared against ctr_q[19:8]

@bussss
Copy link

bussss commented May 4, 2019

hello, How do I write the test bench of this code?,Please, help me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment