Skip to content

Instantly share code, notes, and snippets.

@prydin
Last active December 20, 2024 00:16
Show Gist options
  • Save prydin/ffee25a16d2dcc75489833910757b922 to your computer and use it in GitHub Desktop.
Save prydin/ffee25a16d2dcc75489833910757b922 to your computer and use it in GitHub Desktop.
ESC Part 0
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 12/17/2024 08:29:18 AM
// Design Name:
// Module Name: main
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module esc(
input clk, // Master clock
output [0:1] led,
output pio1, // U phase hi
output pio2, // V phase hi
output pio3, // W phase hi
output pio4, // U phase lo
output pio5, // V phase lo
output pio6 // W phase lo
);
assign u_hi = pio1;
assign u_lo = pio2;
assign v_hi = pio3;
assign v_lo = pio4;
assign w_hi = pio5;
assign w_lo = pio6;
// Master 200MHz clock
wire master_clk;
// Clock locked flag (not used)
wire locked;
// Create a 200MHz clock
clk_wiz_0 clock (
.clk_out1(master_clk),
.reset(0), // TODO: Implement reset
.locked(locked),
.clk_in1(clk));
// Main pulse generator logic
pulse_gen pulse_gen(
master_clk,
100000,
duty_cycle,
u_hi,
u_lo,
v_hi,
v_lo,
w_hi,
w_lo);
// Test/demo code
reg [31:0] blink_count;
reg blink;
reg [9:0] duty_cycle;
assign led[0] = blink;
always @(posedge master_clk)
begin
if(blink_count == 0)
begin
blink_count <= 100_000_000;
blink <= ~blink;
if(duty_cycle == 900)
begin
duty_cycle <= 100;
end else begin
duty_cycle <= duty_cycle + 100;
end
end else begin
blink_count <= blink_count - 1;
end
end
endmodule
module div_by_3(
input unsigned [26:0] x,
output unsigned [26:0] y);
// Power series approximation of x / 3
assign y = (x >> 1) - (x >> 2) + (x >> 3) - (x >> 4) + (x >> 5) - (x >> 6) + (x >> 7) - (x >> 8) + (x >> 9) - (x >> 10);
endmodule
module div_by_6(
input unsigned [26:0] x,
output unsigned [26:0] y);
wire [26:0] tmp;
div_by_3 div_by_3(
x,
tmp);
assign y = tmp >> 1;
endmodule
module pwm_chopper(
input clk,
input [9:0] t_on,
input [9:0] t_off,
input in,
output reg out);
reg [9:0] counter = 0;
reg active = 0;
always @(posedge clk)
begin
counter <= counter - 1;
if(active)
begin
out <= in;
end else begin
out <= 0;
end
if(counter == 0)
begin
if(active)
begin
active <= 0;
counter <= t_off;
out <= 0;
end else begin
active <= 1;
counter <= t_on;
end
end
end
endmodule
module pulse_gen(
input clk,
input [26:0] period,
input [9:0] power,
output wire u_hi_pwm,
output wire v_hi_pwm,
output wire w_hi_pwm,
output wire u_lo_pwm,
output wire v_lo_pwm,
output wire w_lo_pwm
);
reg u_hi = 0, u_lo = 0, v_hi = 0, v_lo = 0, w_hi = 0, w_lo = 0;
reg unsigned [26:0] counter = 0;
reg unsigned [2:0] step = 0;
reg [26:0] current_period = 0;
wire [26:0] sub_period;
wire [9:0] t_on = power;
wire [9:0] t_off = 1000 - power;
// Calculate length of sub-perdiod
div_by_6 div_by_6(
current_period,
sub_period);
// Set up pwm choppers
pwm_chopper pc_uh(clk, t_on, t_off, u_hi, u_hi_pwm);
pwm_chopper pc_ul(clk, t_on, t_off, u_lo, u_lo_pwm);
pwm_chopper pc_vh(clk, t_on, t_off, v_hi, v_hi_pwm);
pwm_chopper pc_vl(clk, t_on, t_off, v_lo, v_lo_pwm);
pwm_chopper pc_wh(clk, t_on, t_off, w_hi, w_hi_pwm);
pwm_chopper pc_wl(clk, t_on, t_off, w_lo, w_lo_pwm);
always @(posedge clk)
begin
// Have we reached the end of a sub period?
if(counter == 0)
begin
if(step == 0)
begin
// Make any period changes take effect at the start of the first step
current_period <= period;
end
if(step == 5)
begin
step <= 0;
end else begin
step <= step + 1;
end
end
case(step)
0: begin
u_hi <= 1;
u_lo <= 0;
v_hi <= 0;
v_lo <= 0;
w_hi <= 0;
w_lo <= 1;
end
1: begin
u_hi <= 0;
u_lo <= 0;
v_hi <= 1;
v_lo <= 0;
w_hi <= 0;
w_lo <= 1;
end
2: begin
u_hi <= 0;
u_lo <= 1;
v_hi <= 1;
v_lo <= 0;
w_hi <= 0;
w_lo <= 0;
end
3: begin
u_hi <= 0;
u_lo <= 1;
v_hi <= 0;
v_lo <= 0;
w_hi <= 1;
w_lo <= 0;
end
4: begin
u_hi <= 0;
u_lo <= 0;
v_hi <= 0;
v_lo <= 1;
w_hi <= 1;
w_lo <= 0;
end
5: begin
u_hi <= 1;
u_lo <= 0;
v_hi <= 0;
v_lo <= 1;
w_hi <= 0;
w_lo <= 0;
end
endcase
// Update counter
if(counter == sub_period - 1)
begin
counter <= 0;
end else begin
counter <= counter + 1;
end
end
endmodule
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment