-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
d62caf8
commit cf6a871
Showing
16 changed files
with
1,092 additions
and
0 deletions.
There are no files selected for viewing
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,159 @@ | ||
module PID( | ||
input i_Clk, | ||
input [13:0]number_of_pulses, | ||
input [4:0]SW, | ||
input PID_timer, | ||
output reset_nop_0, | ||
input reset, | ||
output [13:0]signal_dc, | ||
input [35:0] KP, | ||
input [35:0] KI, | ||
input [35:0] KD | ||
///////DEBUG/////// | ||
//output [2:0]state_pid | ||
/////////////////// | ||
); | ||
|
||
reg reset_nop; | ||
assign reset_nop_0 = reset_nop; | ||
|
||
reg [2:0]PID_STATE; | ||
reg [35:0]sample_data; | ||
wire [35:0]mult_out_0, mult_out_1, mult_out_2, mult_out_3; | ||
reg [35:0]mult_out_0_reg, mult_out_1_reg, mult_out_2_reg, mult_out_3_reg; | ||
wire [71:0]mult_step_0, mult_step_1, mult_step_2, mult_step_3; | ||
reg [35:0]current_speed, desired_speed; | ||
reg [35:0]e_speed ,e_speed_pre, e_speed_sum, e_speed_de, pwm_pulse; | ||
reg [13:0]dc_out; | ||
|
||
///////DEBUG/////// | ||
//assign state_pid = PID_STATE; | ||
/////////////////// | ||
|
||
parameter WAIT_TIME = 3'd0, | ||
CALCULATE_PWM_0 = 3'd1, | ||
CALCULATE_PWM_1 = 3'd2, | ||
CALCULATE_PWM_2 = 3'd3, | ||
CALCULATE_PWM_3 = 3'd4, | ||
CALCULATE_PWM_4 = 3'd5, | ||
CALCULATE_PWM_5 = 3'd6, | ||
LIMIT_CHECK = 3'd7; | ||
|
||
parameter FP_36_9_d10 = 36'b1010_000_000_000; | ||
/* | ||
KP = 36'b0_1011_1111_1010_000_000_000, | ||
KI = 36'b0_1111_1101_1010_000_000_000, | ||
KD = 36'b0_1111_1111_1001_000_000_000; | ||
*/ | ||
// FIXED POINT NUMBERS 36 BIT, 1 SIGN 26 DECIMAL 9 FRACTION | ||
/////////////////////////////////////////////////// | ||
|
||
//pwm_pulse = e_speed*kp + e_speed_sum*ki + e_speed_de*kd; | ||
assign signal_dc = dc_out; | ||
|
||
always@(posedge i_Clk) | ||
begin | ||
case(PID_STATE) | ||
WAIT_TIME: begin | ||
if(reset)begin | ||
PID_STATE <= WAIT_TIME; | ||
reset_nop <= 1'b1; | ||
e_speed_pre <= 0; | ||
e_speed <= 0; | ||
e_speed_sum <= 0; | ||
pwm_pulse <= 0; | ||
dc_out <= 0; | ||
end | ||
else if(PID_timer)begin | ||
sample_data <= {1'b0, 12'b0, number_of_pulses, 9'b0}; | ||
desired_speed <= {1'b0, 21'b0, SW[4:0], 9'b0}; | ||
reset_nop <= 1'b1; | ||
PID_STATE <= CALCULATE_PWM_0; | ||
end | ||
else begin | ||
reset_nop <= 1'b0; | ||
PID_STATE <= WAIT_TIME; | ||
dc_out <= pwm_pulse[22:9]; | ||
end | ||
end | ||
CALCULATE_PWM_0: begin | ||
mult_out_0_reg <= mult_out_0; | ||
PID_STATE <= CALCULATE_PWM_1; | ||
end | ||
CALCULATE_PWM_1: begin | ||
current_speed <= mult_out_0_reg >> 9; | ||
PID_STATE <= CALCULATE_PWM_2; | ||
end | ||
CALCULATE_PWM_2: begin | ||
e_speed <= desired_speed - current_speed; | ||
PID_STATE <= CALCULATE_PWM_3; | ||
end | ||
CALCULATE_PWM_3: begin | ||
mult_out_1_reg <= mult_out_1; | ||
mult_out_2_reg <= mult_out_2; | ||
e_speed_de <= (e_speed - e_speed_pre); | ||
PID_STATE <= CALCULATE_PWM_4; | ||
end | ||
CALCULATE_PWM_4: begin | ||
mult_out_3_reg <= mult_out_3; | ||
pwm_pulse <= mult_out_2_reg + mult_out_1_reg; | ||
PID_STATE <= CALCULATE_PWM_5; | ||
end | ||
CALCULATE_PWM_5: begin | ||
pwm_pulse <= pwm_pulse + mult_out_3_reg; | ||
e_speed_pre <= e_speed; //save last (previous) error | ||
e_speed_sum <= e_speed_sum + e_speed; //sum of error | ||
PID_STATE <= LIMIT_CHECK; | ||
end | ||
LIMIT_CHECK: begin | ||
if(pwm_pulse[22:9] > 14'd10_000) begin | ||
pwm_pulse[22:9] <= 14'd10_000; | ||
end | ||
PID_STATE <= WAIT_TIME; | ||
end | ||
default: begin | ||
PID_STATE <= WAIT_TIME; | ||
end | ||
endcase | ||
end | ||
|
||
assign mult_step_0 = $signed(sample_data) * $signed(FP_36_9_d10); | ||
assign mult_out_0 = {mult_step_0[71], mult_step_0[43:9]}; | ||
|
||
assign mult_step_1 = $signed(e_speed) * $signed(KP); | ||
assign mult_out_1 = {mult_step_1[71], mult_step_1[43:9]}; | ||
|
||
assign mult_step_2 = $signed(e_speed_sum) * $signed(KI); | ||
assign mult_out_2 = {mult_step_2[71], mult_step_2[43:9]}; | ||
|
||
assign mult_step_3 = $signed(e_speed_de) * $signed(KD); | ||
assign mult_out_3 = {mult_step_3[71], mult_step_3[43:9]}; | ||
|
||
///////DEBUG/////// | ||
/* | ||
wire [26:0]sample_data_D; | ||
wire [26:0]mult_out_0_reg_D, mult_out_1_reg_D, mult_out_2_reg_D, mult_out_3_reg_D; | ||
wire [26:0]current_speed_D, desired_speed_D; | ||
wire [26:0]e_speed_D ,e_speed_pre_D, e_speed_sum_D, e_speed_de_D; | ||
wire [26:0]KP_D, KI_D, KD_D; | ||
assign sample_data_D = sample_data[35:9]; | ||
assign mult_out_0_reg_D = mult_out_0_reg[35:9]; | ||
assign mult_out_1_reg_D = mult_out_1_reg[35:9]; | ||
assign mult_out_2_reg_D = mult_out_2_reg[35:9]; | ||
assign mult_out_3_reg_D = mult_out_3_reg[35:9]; | ||
assign current_speed_D = current_speed[35:9]; | ||
assign desired_speed_D = desired_speed[35:9]; | ||
assign e_speed_D = e_speed[35:9]; | ||
assign e_speed_pre_D = e_speed_pre[35:9]; | ||
assign e_speed_sum_D = e_speed_sum[35:9]; | ||
assign e_speed_de_D = e_speed_de[35:9]; | ||
assign KP_D = KP[35:9]; | ||
assign KI_D = KI[35:9]; | ||
assign KD_D = KD[35:9]; | ||
*/ | ||
////////////////////////////////////// | ||
endmodule |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
module PWM( | ||
input clk, | ||
output PWM_signal, | ||
input [13:0]DC | ||
); | ||
|
||
|
||
parameter PWM_ONE = 14'b1; | ||
parameter PWM_ZERO = 14'b0; | ||
reg [13:0]PWM_counter; | ||
|
||
reg PWM_signal_0; | ||
assign PWM_signal = PWM_signal_0; | ||
////parameter DUTY_CYCLE = 12'b0001_1111_0100; //%25 dtycycle | ||
parameter RESOLUTION = 14'b10_0111_0001_0000; //10000 dtycycle>> 5khz | ||
|
||
always@(posedge clk) | ||
begin | ||
if(PWM_counter < RESOLUTION) | ||
PWM_counter <= PWM_counter + PWM_ONE; | ||
else | ||
PWM_counter <= PWM_ZERO; | ||
|
||
if((PWM_counter <= DC) && (PWM_counter != 14'b0)) | ||
PWM_signal_0 <= 1'b1; | ||
else | ||
PWM_signal_0 <= 1'b0; | ||
end | ||
endmodule |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
////////////////////////////////////////////////////////////////////// | ||
// File Downloaded from http://www.nandland.com | ||
////////////////////////////////////////////////////////////////////// | ||
// This file contains the UART Receiver. This receiver is able to | ||
// receive 8 bits of serial data, one start bit, one stop bit, | ||
// and no parity bit. When receive is complete o_rx_dv will be | ||
// driven high for one clock cycle. pp | ||
// | ||
// Set Parameter CLKS_PER_BIT as follows: | ||
// CLKS_PER_BIT = (Frequency of i_Clock)/(Frequency of UART) | ||
// Example: 25 MHz Clock, 115200 baud UART | ||
// (25000000)/(115200) = 217 | ||
////////////////////////////////////////////////////////////////////// | ||
// Edited by Emre Hakan Demirli 03/02/2021 | ||
// Changed Content(s): r_Clock_Count | ||
////////////////////////////////////////////////////////////////////// | ||
module UART_RX | ||
#(parameter CLKS_PER_BIT = 217) | ||
( | ||
input i_Clock, | ||
input i_RX_Serial, | ||
output o_RX_DV, | ||
output [7:0] o_RX_Byte | ||
); | ||
|
||
parameter IDLE = 3'b000; | ||
parameter RX_START_BIT = 3'b001; | ||
parameter RX_DATA_BITS = 3'b010; | ||
parameter RX_STOP_BIT = 3'b011; | ||
parameter CLEANUP = 3'b100; | ||
|
||
reg [13:0] r_Clock_Count = 0; | ||
reg [2:0] r_Bit_Index = 0; //8 bits total | ||
reg [7:0] r_RX_Byte = 0; | ||
reg r_RX_DV = 0; | ||
reg [2:0] r_SM_Main = 0; | ||
|
||
|
||
// Purpose: Control RX state machine | ||
always @(posedge i_Clock) | ||
begin | ||
|
||
case (r_SM_Main) | ||
IDLE : | ||
begin | ||
r_RX_DV <= 1'b0; | ||
r_Clock_Count <= 0; | ||
r_Bit_Index <= 0; | ||
|
||
if (i_RX_Serial == 1'b0) // Start bit detected | ||
r_SM_Main <= RX_START_BIT; | ||
else | ||
r_SM_Main <= IDLE; | ||
end | ||
|
||
// Check middle of start bit to make sure it's still low | ||
RX_START_BIT : | ||
begin | ||
if (r_Clock_Count == (CLKS_PER_BIT-1)/2) | ||
begin | ||
if (i_RX_Serial == 1'b0) | ||
begin | ||
r_Clock_Count <= 0; // reset counter, found the middle | ||
r_SM_Main <= RX_DATA_BITS; | ||
end | ||
else | ||
r_SM_Main <= IDLE; | ||
end | ||
else | ||
begin | ||
r_Clock_Count <= r_Clock_Count + 1; | ||
r_SM_Main <= RX_START_BIT; | ||
end | ||
end // case: RX_START_BIT | ||
|
||
|
||
// Wait CLKS_PER_BIT-1 clock cycles to sample serial data | ||
RX_DATA_BITS : | ||
begin | ||
if (r_Clock_Count < CLKS_PER_BIT-1) | ||
begin | ||
r_Clock_Count <= r_Clock_Count + 1; | ||
r_SM_Main <= RX_DATA_BITS; | ||
end | ||
else | ||
begin | ||
r_Clock_Count <= 0; | ||
r_RX_Byte[r_Bit_Index] <= i_RX_Serial; | ||
|
||
// Check if we have received all bits | ||
if (r_Bit_Index < 7) | ||
begin | ||
r_Bit_Index <= r_Bit_Index + 1; | ||
r_SM_Main <= RX_DATA_BITS; | ||
end | ||
else | ||
begin | ||
r_Bit_Index <= 0; | ||
r_SM_Main <= RX_STOP_BIT; | ||
end | ||
end | ||
end // case: RX_DATA_BITS | ||
|
||
|
||
// Receive Stop bit. Stop bit = 1 | ||
RX_STOP_BIT : | ||
begin | ||
// Wait CLKS_PER_BIT-1 clock cycles for Stop bit to finish | ||
if (r_Clock_Count < CLKS_PER_BIT-1) | ||
begin | ||
r_Clock_Count <= r_Clock_Count + 1; | ||
r_SM_Main <= RX_STOP_BIT; | ||
end | ||
else | ||
begin | ||
r_RX_DV <= 1'b1; | ||
r_Clock_Count <= 0; | ||
//r_SM_Main <= CLEANUP; | ||
r_SM_Main <= IDLE; | ||
end | ||
end // case: RX_STOP_BIT | ||
|
||
|
||
// Stay here 1 clock | ||
CLEANUP : | ||
begin | ||
r_SM_Main <= IDLE; | ||
r_RX_DV <= 1'b0; | ||
end | ||
|
||
|
||
default : | ||
r_SM_Main <= IDLE; | ||
|
||
endcase | ||
end | ||
|
||
assign o_RX_DV = r_RX_DV; | ||
assign o_RX_Byte = r_RX_Byte; | ||
|
||
endmodule // UART_RX |
Oops, something went wrong.