Commit b8236916 authored by Majd Hafiri's avatar Majd Hafiri
Browse files

refactor code

parent 760e45b6
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 06/18/2022 03:50:18 PM
// Design Name:
// Module Name: automated_process
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module automated_process(
input [2:0] slowCounter,
input enable,
output wire [17:0] positionServo1, positionServo2, positionServo3, positionServo4
);
logic [17:0] positionServoOne, positionServoTwo, positionServoThree, positionServoFour = 18'd100000;
/*adding small amount to pulse width to change servo angle slightly using push buttons*/
always @(slowCounter) begin
if(enable) begin
case (slowCounter)
3'd1: positionServoOne = positionServoOne + 18'd50000;
3'd2: positionServoTwo = positionServoTwo + 18'd50000;
3'd3: positionServoThree = positionServoThree + 18'd50000;
3'd4: positionServoFour = positionServoFour + 18'd50000;
3'd5: positionServoOne = positionServoOne - 18'd50000;
3'd6: positionServoTwo = positionServoTwo - 18'd50000;
3'd7: positionServoThree = positionServoThree - 18'd50000;
3'd0: positionServoFour = positionServoFour - 18'd50000;
endcase
end
end
assign positionServo1 = positionServoOne;
assign positionServo2 = positionServoTwo;
assign positionServo3 = positionServoThree;
assign positionServo4 = positionServoFour;
endmodule
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 06/18/2022 04:30:50 PM
// Design Name:
// Module Name: one_Hz_clock
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
/*
module name: oneHz_clock
Description: This module is used to generate a slow clock (1 Hz) which is used for the slow_counter module. one change every half second
*/
module one_Hz_clock(
input clk,
output logic oneHzClock,
output logic [25:0] oneHzCnt
);
// logic [25:0] oneHzCnt;
);
always @ (posedge(clk))
begin
always @ (posedge(clk)) begin
if (oneHzCnt == 49999999) begin
oneHzCnt = 0;
oneHzClock = ~oneHzClock;
if (oneHzCnt == 27'd49999999) begin // when the counter reaches the value 49999999,
oneHzCnt = 27'd0; // reset counter value
oneHzClock = ~oneHzClock; // the slow clock signal is set to the opposite of it's previous state
end
else oneHzCnt = oneHzCnt + 1;
else
oneHzCnt = oneHzCnt + 1'd1;
end
endmodule
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 06/18/2022 01:04:52 AM
// Design Name:
// Module Name: pwm_generator
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
/*
module name: pwm_generator
Description: This module is responsible to generate a pwm signal that drives the servo motors.
- The servo motors work at a refresh rate of 20ms. this module takes the position input which represents the pulse width and adds it
to the refresh rate. and drives the pwm signal low when the counter reaches the position value
*/
module pwm_generator(
input clk,
input [17:0] position,
output logic pwm
input clk,
input [17:0] position,
output logic pwm
);
logic [20:0] counter = 21'd0;
always @(posedge clk) begin
if(counter == position) //counts the width of the pulse ( this value is changed when using push buttons to change angle)
pwm = 1'b0;
if(counter == 21'd2000000) begin //counts the refresh rate which is 20 ms
counter = 21'b0;
pwm = 1'b1;
if(counter == position) //counts the width of the pulse ( this value is changed when using push buttons to change angle)
pwm = 1'b0; //driving pwm signal to low
if(counter == 21'd2000000) begin //reset counter and drive pwm signal high when the refresh rate reaches 20ms
counter = 21'b0;
pwm = 1'b1;
end
else
counter = counter + 1'b1;
counter = counter + 1'b1; //Increment counter
end
endmodule
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// University: Deggendorf Institute of Technology
// Student: Majd Hafiri
//
// Create Date: 06/17/2022 09:43:12 PM
// Design Name:
// Module Name: robotic_arm
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
/*
module name: robotic_arm
Description: This is the main module for the robotic arm project. several instances from other modules are instantiated and connected to each other
Inputs and outputs:
- Four slide switches are used to enable controlling four individual servo motors.
- Two push buttons are used to increase and decrease the pulse width to change the servo angle.
- Board clock (100 MHz) used to create slower clock and synchronize other modules.
- One slide switch to change the mode of the robotic arm to Automatic ( Automated process )
- Two seven segment display to display Auto mode (A) and enabled servo number
*/
module robotic_arm(
input servo1Switch, servo2Switch, servo3Switch, servo4Switch,
input btnIncreasePulseWidth, btnDecreasePulseWidth,
input clk,
input automatedProcessSwitch,
output [7:0] D0_SEG, D1_SEG,
output [3:0] D0_AN, D1_AN,
output [3:0] servo
input servo1Switch, servo2Switch, servo3Switch, servo4Switch, //enable switches for the connected 4 servos
input btnIncreasePulseWidth, btnDecreasePulseWidth, //push buttons for changing servo angles
input clk, //100Mhz clock
input automatedProcessSwitch, //last slide switch for automated process
output [7:0] D0_SEG, D1_SEG, //cathodes for the two 7seg displays
output [3:0] D0_AN, D1_AN, //Anode for the two 7seg displays
output [3:0] servo //pins for servos
);
logic [17:0] positionServoOne, positionServoTwo, positionServoThree, positionServoFour;
logic [3:0] pwmSignals;
logic [3:0] servoSelection = {servo4Switch, servo3Switch, servo2Switch, servo1Switch };
logic slowClk;
logic [2:0] counterToEight;
logic oneHzClock;
logic [25:0] oneHzCnt;
logic [17:0] positionServoOne, positionServoTwo, positionServoThree, positionServoFour; //4 registers to store the value of each servo pulse width
logic [3:0] pwmSignals; //4 bit register to store the four pwm signals for the servos
logic [3:0] servoSelection = {servo4Switch, servo3Switch, servo2Switch, servo1Switch }; //4 bit register to store the values of the selection switches
logic slowClk; //one bit register to store the slow clock signal ( to detect push buttons signals)
logic [2:0] counterToEight; //3 bit register used to direct a module to change pulse width for
//the four servos automatically
logic oneHzClock; //one bit register to store a signal of 1Hz clock
logic [25:0] oneHzCnt; //stores the value of the 1Hz clock counter
slow_clock slow_clock_instance(
/*
creating an instance of the slow clock module. and generate a slow clock
Input: clk
Output: slowClk
*/
slow_clock slow_clock_instance(
.clk(clk),
.slowClk(slowClk)
.slowClk(slowClk)
);
/*
instantiating four instances of PWM generator and generate pwm signals for the 4 servos
creating four instances of PWM generator and generate pwm signals for the 4 servos
Inputs: clk, position
Output: pwm
*/
pwm_generator pwm_instance_servo1(
.clk(clk),
......@@ -72,45 +72,74 @@ logic [25:0] oneHzCnt;
.position(positionServoFour),
.pwm(pwmSignals[3])
);
servo_control servo_control_instance(
/*
Creating an instance of servo_control. It is responsible to change the value of position for the servos which is passed to
pwm_generator module.
Inputs:
- btnIncreasePulseWidth, btnDecreasePulseWidth
- slowClk, servoSelection, automatedProcessSwitch
- counterToEight, oneHzCnt
Outputs:
- positionServo1, positionServo2, positionServo3, positionServo4
*/
servo_control servo_control_instance(
.btnIncreasePulseWidth(btnIncreasePulseWidth),
.btnDecreasePulseWidth(btnDecreasePulseWidth),
.slowClk(slowClk),
.servoSelection(servoSelection),
.enable(automatedProcessSwitch),
.slowCounter(counterToEight),
.automatedProcessSwitch(automatedProcessSwitch),
.counterToEight(counterToEight),
.oneHzCnt(oneHzCnt),
.positionServo1(positionServoOne), .positionServo2(positionServoTwo),
.positionServo3(positionServoThree), .positionServo4(positionServoFour)
.positionServo3(positionServoThree), .positionServo4(positionServoFour)
);
/*
Instance of seven_segment_display used to display the number of the selected servo on 1st display,
or letter A (for automated process) on the second display
Inputs: automatedProcessSwitch, switchSelection
Outputs: D0_SEG, D1_SEG, D0_AN, D1_AN
*/
seven_segment_display seven_segment_instance(
.automatedProcessSwitch(automatedProcessSwitch),
.switchSelection(servoSelection),
.D0_SEG(D0_SEG),
.D0_AN(D0_AN),
.D1_SEG(D1_SEG),
.D1_AN(D1_AN),
.automatedProcessSwitch(automatedProcessSwitch),
.switchSelection(servoSelection)
.D1_AN(D1_AN)
);
/*
Instance of slow_counter used to generate a counter to 8 that is used for automated process.
Inputs: oneHzClock, automatedProcessSwitch
Outputs: counterToEight
*/
slow_counter slow_counter_instance(
.slowClk(oneHzClock),
.enable(automatedProcessSwitch),
.oneHzClock(oneHzClock),
.automatedProcessSwitch(automatedProcessSwitch),
.counterToEight(counterToEight)
);
/*
instance of one_Hz_clock used to generate a slower at 1Hz from the original clock 100MHz
Inputs: clk
Outputs: oneHzClock, oneHzCnt
*/
one_Hz_clock one_hz_clock_instance(
.clk(clk),
.oneHzClock(oneHzClock),
.oneHzCnt(oneHzCnt)
);
assign servo = pwmSignals;
assign servo = pwmSignals; //Assigning the pulse width modulation signals to the servo pins
endmodule
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 06/18/2022 01:19:55 AM
// Design Name:
// Module Name: servo_control
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
/*
module name: servo_control
Description: This module is responsible to change the position value(pulse width) for the servos.
- If automatic process is selected (automatedProcessSwitch),
the module uses the 3 bit counter(counterToEight) to increase and decrease the pulse width (position) of the servos after some time (1Hz clock)
- If automatic process is not selected and one of the other four switches is selected, it changes the pusle width (position) of the selected servo
according the the value added or subtracted by the two push buttons
*/
module servo_control(
......@@ -25,19 +17,21 @@ module servo_control(
input btnIncreasePulseWidth, btnDecreasePulseWidth,
input slowClk,
input [3:0] servoSelection,
input [2:0] slowCounter,
input logic [25:0] oneHzCnt,
input enable,
output wire [17:0] positionServo1, positionServo2, positionServo3, positionServo4
input [2:0] counterToEight,
input automatedProcessSwitch,
output wire [17:0] positionServo1, positionServo2, positionServo3, positionServo4
);
logic [17:0] positionServoOne, positionServoTwo, positionServoThree, positionServoFour = 18'd100000;
/*adding small amount to pulse width to change servo angle slightly using push buttons*/
logic [17:0] positionServoOne, positionServoTwo, positionServoThree, positionServoFour = 18'd100000; //four registers to hold position values of the 4 servos
always @(posedge slowClk) begin
if(enable) begin
case (slowCounter)
if(automatedProcessSwitch) begin
/*IF the automated process switch is on, the switch statement increases and decreases small values to/from servo positions( pulse widths ),
counterToEight is used to select one of the four servos positions after every small amount of time.
*/
case (counterToEight)
3'd1: positionServoOne = positionServoOne + 18'd1000;
3'd2: positionServoTwo = positionServoTwo + 18'd1000;
3'd3: positionServoThree = positionServoThree + 18'd1000;
......@@ -49,30 +43,33 @@ module servo_control(
3'd0: positionServoFour = positionServoFour - 18'd1000;
endcase
end
else if(~enable) begin
if(btnIncreasePulseWidth == 1) begin
//increase angle by increasing pulse width(position)
case (servoSelection)
4'b0001: positionServoOne = positionServoOne + 18'd1000;
4'b0010: positionServoTwo = positionServoTwo + 18'd1000;
4'b0100: positionServoThree = positionServoThree + 18'd1000;
4'b1000: positionServoFour = positionServoFour + 18'd1000;
endcase
end
else if(btnDecreasePulseWidth == 1) begin
//decrease angle by decreasing pulse width
case (servoSelection)
4'b0001: positionServoOne = positionServoOne - 18'd1000;
4'b0010: positionServoTwo = positionServoTwo - 18'd1000;
4'b0100: positionServoThree = positionServoThree - 18'd1000;
4'b1000: positionServoFour = positionServoFour - 18'd1000;
endcase
end
/*If the automated process switch is OFF, the pulse width of the selected servo( first four slide switches) is increase and decreased by small amounts
using the two push button*/
else if(~automatedProcessSwitch) begin
if(btnIncreasePulseWidth == 1) begin
//increase angle by increasing pulse width(position)
case (servoSelection)
4'b0001: positionServoOne = positionServoOne + 18'd1000;
4'b0010: positionServoTwo = positionServoTwo + 18'd1000;
4'b0100: positionServoThree = positionServoThree + 18'd1000;
4'b1000: positionServoFour = positionServoFour + 18'd1000;
endcase
end
else if(btnDecreasePulseWidth == 1) begin
//decrease angle by decreasing pulse width
case (servoSelection)
4'b0001: positionServoOne = positionServoOne - 18'd1000;
4'b0010: positionServoTwo = positionServoTwo - 18'd1000;
4'b0100: positionServoThree = positionServoThree - 18'd1000;
4'b1000: positionServoFour = positionServoFour - 18'd1000;
endcase
end
end
end
//Assigning the value of the pulse widths to the output wires which will be used by the PWM module
assign positionServo1 = positionServoOne;
assign positionServo2 = positionServoTwo;
assign positionServo3 = positionServoThree;
......
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 06/18/2022 01:29:01 PM
// Design Name:
// Module Name: seven_segment_display
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
/*
module name: seven_segment_display
Description: This module is responsible to Display the number of the selected servo , and letter A on the two seven segment displays.
- when a servo is selected by a switch, the first display shows the number of that servo motor. and the other display shows the letter A
when the automated process switch is on.
*/
module seven_segment_display(
output logic [7:0] D0_SEG, D1_SEG,
output logic [3:0] D0_AN, D1_AN,
input [3:0] switchSelection,
input automatedProcessSwitch
);
input automatedProcessSwitch,
output logic [7:0] D0_SEG, D1_SEG,
output logic [3:0] D0_AN, D1_AN
);
logic automated;
always @ (switchSelection, automated) begin
logic automatedProcess;
always @ (switchSelection, automatedProcess) begin //this block is triggered whenever the values of the 5 switches is changed
if(automated) begin
D1_SEG = 8'b10001000; //display A which indicates automated process mode is on
D0_SEG = 8'b11111111; //turn of the seven segment display leds for servos
if(automatedProcess) begin
D1_SEG = 8'b10001000; //display A which indicates automated process mode is on
D0_SEG = 8'b11111111; //turn of the seven segment display for the servo numbers
end
else begin
case (switchSelection)
4'b0001 : //Hexadecimal 1
4'b0001 : // Servo 1
D0_SEG = 8'b11111001;
4'b0010 : // Hexadecimal 2
4'b0010 : // Servo 2
D0_SEG = 8'b10100100;
4'b0100 : // Hexadecimal 3
4'b0100 : // Servo 3
D0_SEG = 8'b10110000;
4'b1000 : // Hexadecimal 4
4'b1000 : // Servo 4
D0_SEG = 8'b10011001 ;
default: D0_SEG = 8'b11111111 ;
endcase
D1_SEG = 8'b11111111;
end
end
end
end
//turn off other digits by driving the Anodes with signal 1( low active )
assign D0_AN = 4'b1110;
assign D1_AN = 4'b1110;
assign automated = automatedProcessSwitch;
assign automatedProcess = automatedProcessSwitch;
endmodule
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// University: Deggendorf Institute of Technology
// Student: Majd Hafiri
//
// Create Date: 06/17/2022 09:55:52 PM
// Design Name:
// Module Name: slow_clock
// Project Name: Robotic Arm on FPGA
// Target Devices:
// Tool Versions:
// Description:
// This module is responsible to create a slow clock which
// is used to detect user input from push button to increase the pulse width
//////////////////////////////////////////////////////////////////////////////////
/*
module name: slow_clock
Description: This module is responsible to generate a slow clock. the main purpose is to read the push button signals at a slower speed than the original clock.
- every clock cycle of the (100MHz) clock is 10 nanoseconds. every 5ns (half cycle) the counter adds 1.
- 5 * 1 000 000 = 5 000 000 ns => half cycle for the slow clock
- Every 10 000 000 ns = full cycle every 0.01 second = one full cycle which is 100 Hz
*/
module slow_clock(