Last active
December 20, 2024 00:16
-
-
Save prydin/ffee25a16d2dcc75489833910757b922 to your computer and use it in GitHub Desktop.
ESC Part 0
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
`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