The words you are searching are inside this book. To get more targeted content, please make full-text search by clicking here.
Discover the best professional documents and content resources in AnyFlip Document Base.
Search
Published by auditditom, 2023-04-02 23:49:26

Tutorial for FPGA Beginners

Tutorial for FPGA Beginners

A Tutorial for FPGA beginners 96 4.5 Implement a 74HC165 8-bit Parallel-load Shift Registers 74HC165 Logic Functions 74HC165 is an 8-bit Shift Register capable to generate parallel or serial output data. It has been widely used for Programable Logic Controllers (PLC) and output expander applications. The pin diagram and description are shown in Figure 4.5.1. Pin Description A-H Parallel inputs CLK Clock input CLK INH When High, no output change SER Serial input SH/LD’ Shift or load input QH Serial output QH’ Complementary serial output Figure 4.5.1: Pin diagram of 74HC165 Until this stage, you have practiced abundant circuit building skills therefore the breadboard testing circuits for logic chips are not shown in the last two sections in this chapter, though you may easily find demo circuit examples online. Implement 74HC165 with FPGA A 74HC165 has the following input and output pins: • 2 power pins for VCC and GND • 8 input pins for parallel 8-bit input signals • 1 input pins for serial input data • 2 input pins for clock signal • 1 input pin to tell the chip using either Shift or Parallel-load • 2 output pins for Q and its complementary output Q’ Code 4.5 uses simple Behavioral-level description to describe the logic function of 74HC165. Code 4.5: Verilog code to implement 74HC165 module sn74hc165 (pin1,pin2,pin3,pin4,pin5,pin6,pin7,pin8, pin9,pin10,pin11,pin12,pin13,pin14,pin15,pin16); input pin3,pin4,pin5,pin6,pin11,pin12,pin13,pin14; // 8-bit parallel input input pin2,pin15; // clk (generated by OR operation) input pin1; // Shift or Load input input pin10; // Serial input output pin8,pin16; // Connect to VCC and GND output pin7,pin9; // Serial output and Complementary wire [7:0] data; wire clk,load,sel; reg [7:0] q;


Chapter 4 97 assign pin8 = 1'b0; assign pin16 = 1'b1; assign data[0] = pin11; assign data[1] = pin12; assign data[2] = pin13; assign data[3] = pin14; assign data[4] = pin3; assign data[5] = pin4; assign data[6] = pin5; assign data[7] = pin6; assign clk = pin2|pin15; assign load = pin1; assign pin9 = q[7]; //Q assign pin7 = ~q[7]; //~Q assign sel = pin10; always @ (posedge clk or negedge load) begin if(!load) q <= data; else q <= {q[6:0],sel}; end endmodule Note that the behavior to realize logic shifting simply uses a non-block statement <= that loads the data into the internal 8-bit Register q which is essentially composed by 8 Flip-flops. 4.6 Implement a 74HC393 Dual 4-Stage Binary Counter 74HC393 Logic Functions 74HC393 has two 4-stage Binary Counters each can count 4-bit binary number from 0000 to 1111, which corresponds to decimal numbers from 0 to 15 or hexadecimal numbers from 0 to F. The pin map and equivalent logic structure of 74HC393 are shown in Figure 4.6.1. Figure 4.6.1: Pin diagram of 74HC393


A Tutorial for FPGA beginners 98 Binary counters have the simplest hardware design since the outputs just naturally coming out of the Flip-Flops. Other counters such as decimal counter (counts from 0 to 9 only) requires further circuitry to realize certain patterns of counting. Implement 74HC393 with FPGA A 74HC393 has the following input and output pins: • 2 power pins for VCC and GND • 2 input pins for enabling data clear for the two binary counters • 2 input pins for clock signal of the two binary counters • 8 output pins for two 4-bit binary counter output The complete code to implement 74HC393 is given in Code 4.6. Code 4.6: Verilog code to implement 74HC393 module sn74hc393 (pin1,pin2,pin3,pin4,pin5,pin6,pin7,pin8, pin9,pin10,pin11,pin12,pin13,pin14); input pin1,pin13; // two Clock signal input pin2,pin12; // two Clear enable signal output pin7,pin14; // Connects to VCC and GND output pin3,pin4,pin5,pin6,pin11,pin10,pin9,pin8; // two 4-bit Binary counter output wire clk1,clk2,clr1,clr2; reg [3:0] count1,count2; assign pin7 = 1'b0; assign pin14 = 1'b1; assign clk1 = pin1; assign clk2 = pin13; assign clr1 = pin2; assign clr2 = pin12; assign pin3 = count1[0]; assign pin4 = count1[1]; assign pin5 = count1[2]; assign pin6 = count1[3]; assign pin11 = count2[0]; assign pin10 = count2[1]; assign pin9 = count2[2]; assign pin8 = count2[3]; always@(negedge clk1 or posedge clr1)begin if(clr1) count1 <= 4'b0000; else begin if(count1 == 4'b1111) count1 <= 4'b0000; else count1 <= count1 + 1'b1; end end always@(negedge clk2 or posedge clr2)begin if(clr2) count2 <= 4'b0000; else begin if(count2 == 4'b1111) count2 <= 4'b0000;


Chapter 4 99 else count2 <= count2 + 1'b1; end end endmodule


A Tutorial for FPGA beginners 100


Chapter 5 101 Chapter 5: Some Projects with FPGAs 5.1 An 8-bit LED Chaser Project Overview LED chaser allows a series of LEDs turning ON and OFF sequentially in a periodical manner. LED chasers are often seen in building decorations or used as an eye-catching sign. As it is one of the simplest projects for microcontroller beginners to try out, we will also implement this module on the STEPFPGA board. State Machine Diagram There are multiple ways to design a LED chaser, if you have a finite number of lighting patterns, using a State Machine is definitely a good approach. As you may recall from Section 1.5, a Finite State Machine works for events with finite states and trigger conditions are available so the system can jump from one state to the other. If we breakdown the actions of the whole event, a complete cycle of LED chasing can be outlined in Figure 5.1.1 (for 8 LEDs). Figure 5.1.1: A State Diagram of an 8 LED chaser Imaging if the entire process is very slow, then we can observe that only a single LED turns ON at each moment. So this 8-bit LED chaser has 8 states, and the triggering condition is a timer. The time interval between each LED should be within 50ms to 200ms to generate an effect like waterflow. Implement the LED chaser To implementing a State Machine with Verilog, we need to first specify all states. Usually we use parameter to assign an identical number for each state, so the 8 states can be written as:


A Tutorial for FPGA beginners 102 parameter S0 = 3'b000, S1 = 3'b001, S2 = 3'b010, S3 = 3'b011, S4 = 3'b100, S5 = 3'b101, S6 = 3'b110, S7 = 3'b111; Next, we determine the actions to be carried out in each state, which in this example, specifies the lighting patterns at each moment. In the code, always @ (*) means this block statement is unconditionally implemented so you can think of it as a combinational logic. reg [2: 0] state; always @ (*) begin case (state) S0: LEDs = 8'b11111110; S1: LEDs = 8'b11111101; S2: LEDs = 8'b11111011; S3: LEDs = 8'b11110111; S4: LEDs = 8'b11101111; S5: LEDs = 8'b11011111; S6: LEDs = 8'b10111111; S7: LEDs = 8'b01111111; endcase end The last step is to determine the triggering condition to enable state transitions. This example generates a 50ms timer with a counter cnt that counts 600000 times; every time when this counter is full, the current state will increment to next adjacent state. reg [23: 0] cnt; parameter CNT_NUM = 600_000; always @ (posedge clk) begin if (cnt == CNT_NUM-1) cnt <= 20'b0; else cnt <= cnt + 1'b1; end always @ (posedge clk) begin if (cnt == CNT_NUM-1) state <= state + 1'b1; end Combining all the code pieces above we have the completed code for an 8-bit LED chaser, as shown in Code 5.1. Code 5.1: Complete Verilog code for 8-bit LED chaser with 50ms time interval module LEDchaser ( input clk, output reg [7:0] LEDs ) ;


Chapter 5 103 /**************** Defining the 8 states with binary numbers *******************/ parameter S0 = 3'b000, S1 = 3'b001, S2 = 3'b010, S3 = 3'b011, S4 = 3'b100, S5 = 3'b101, S6 = 3'b110, S7 = 3'b111; /**************** Describing the LED actions in each state *******************/ reg [2: 0] state; always @ (posedge clk) begin case (state) S0: LEDs = 8'b11111110; S1: LEDs = 8'b11111101; S2: LEDs = 8'b11111011; S3: LEDs = 8'b11110111; S4: LEDs = 8'b11101111; S5: LEDs = 8'b11011111; S6: LEDs = 8'b10111111; S7: LEDs = 8'b01111111; endcase end /**************** Enable jumping among different states **********************/ reg [23: 0] cnt; parameter CNT_NUM = 600000; always @ (posedge clk) begin if (cnt == CNT_NUM-1) cnt <= 20'b0; else cnt <= cnt + 1'b1; end always @ (posedge clk) begin if (cnt == CNT_NUM-1) state <= state + 1'b1; end endmodule 5.2 A Simple Traffic Light Control System Project Overview We see traffic lights every day, how do they work? A simple traffic light system controls the red, yellow and green lighting patterns by timers, and we can use a simple state machine to describe the entire process. Figure 5.2.1 is a crossroads scenario. Two pairs of RYG lights control the traffic volume on Main Road and Secondary Road respectively. Figure 5.2.1: A simple crossroad with 2 pairs of traffic lights


A Tutorial for FPGA beginners 104 We know STEPFPGA has two on-board RGB lights so they can be used to simulate a simple crossroad scenario. Specifically, in this project the intervals of Red, Yellow and Green on Main Road light are 15s/3s/10s and on Secondary Road they are 7s/3s/18s. State Machine Diagram Traffic light system is another perfect example of applications of Finite State Machines in real life. The project requirement specifies the timing rule of the crossroad, and the best way to analyze the event is to draw a state timing diagram as shown in Figure 5.2.2. Figure 5.2.2: The state timing diagram of the simple crossroad traffic light system The system is continuously running in four states as described in the following state machine diagram, see Figure 5.2.3. S1: Main Road Green, Secondary Road Red, last for 15s S2: Main Road Yellow, Secondary Road Red, last for 3s S3: Main Road Red, Secondary Road Green, last for 10s S4: Main Road Red, Secondary Road Yellow, last for 3s Figure 5.2.3: State machine of the system Defining the Module A State Machine is like someone’s brain for the management of all intelligent work, but you still need arms and legs to constitute a complete body. Having this sense in mind, we draw the structure of the module traffic in Figure 5.2.4.


Chapter 5 105 Figure 5.2.4: The digital structure of the traffic module For this simple_traffic module, we need a 6-bit output signal [5:0] RGB_out to control the two pairs of RGB lights. In Verilog, we first write the basic definition of the module and work on the State Machine in next part. module simple_raffic ( input clk, rst_n, output reg [5:0] RGB_out ); Implement the State Machine Now it comes to the code implementation of the State Machine. In Figure 5.2.5 there are four unique states, so we use a 2-bit register state and also name the 4 states as S1…S4 (you can certainly use other names). Figure 5.2.5: State machine of the traffic light reg [1:0] state; parameter S1 = 2'b00, S2 = 2'b01, S3 = 2'b10, S4 = 2'b11;


A Tutorial for FPGA beginners 106 Then we describe the actions to be proceeded in each state. For example, in state 1 (S1), the Main Road light turns Green and Secondary Road light turns Red; this corresponds to RGB_out = 6’b101011 (RGB-RGB). always @ (*) begin case (state) S1: RGB_out = 6'b101_011; S2: RGB_out = 6'b001_011; S3: RGB_out = 6'b011_101; S4: RGB_out = 6'b011_001; default: RGB_out = 6'b101_011; endcase end The last step is to implement the transition between different states. According to the state machine, time is the trigger condition for state transitions. The smallest timestep in traffic lights is seconds so we use a 1Hz clock signal clk1hz. A 4-bit counter time_cnt is also needed to hold up to 15 counts. In actual code, the counter size is increased to 5 bits in case we need longer time for red light (up to 32s). reg [4:0] time_cnt; always @ (posedge clk1hz or negedge rst_n) begin if(!rst_n) begin state <= S1; time_cnt <= 0; end else begin case (state) S1: if (time_cnt < 4'd15) begin state <= S1; time_cnt <= time_cnt + 1; end else begin state <= S2; time_cnt <= 0; end S2: if (time_cnt < 4'd9) begin state <= S2; time_cnt <= time_cnt + 1; end else begin state <= S3; time_cnt <= 0; end S3: if (time_cnt < 4'd7) begin state <= S3; time_cnt <= time_cnt + 1; end else begin state <= S4; time_cnt <= 0; end


Chapter 5 107 S4: if (time_cnt < 4'd3) begin state <= S4; time_cnt <= time_cnt + 1; end else begin state <= S1; time_cnt <= 0; end default: begin state <= S1; time_cnt <= 0; end endcase end end The completed code for this simple traffic light control system can be found at: https://github.com/eimtechnology/STEPFPGAMXO2Core/blob/main/Tutorial%20Level1/Chapter5/5.2_SimpleTraffic/Simple_Traffic.v 5.3 A More Complex Traffic System Having done enough experiments and two warmup projects, now it’s the time to add more fun and challenge. Starting from Section 5.3, we will include some interactive sensors and actuator modules to extend our knowledge and skills, and see some real-world applications of the theories and digital modules we learned in previous contents. Project Overview In Canada (perhaps similar in many other countries), the traffic lights for small streets or avenues usually added some ‘intelligent control’ features to increase the traffic efficiency of the crossroad. For example, Figure 5.3.1 shows a crossroad of Hastings St. (main road with constant vehicles passing) and Granville St. (secondary road with more pedestrians and occasional vehicles passing). Figure 5.3.1: A crossroad in Vancouver downtown (a screenshot of Google Street view)


A Tutorial for FPGA beginners 108 Having the experiences of passing this crossroad hundreds of times, a reasonable guess for the working mechanism of these traffic lights has two modes. In daylight mode where both roads are busy, the traffic lights alternative normally. In nighttime mode, the main road light stays constant green light unless the pedestrian walking button is pushed or a vehicle on the secondary road is waiting to cross the street. In this project we will implement a similar traffic control system with a more complex digital design with some sensors and LEDs. We also recommend for the traffic light crossroad board shown in Figure 5.3.2 (included in Fantastic Building Kit) to assist building the entire system. If you do not have the board that’s also fine since we will explain the basic working principles of the sensers and the design methods of each digital module. Figure 5.3.2: Hardware overview of the crossroad model Hardware functionalities of the Traffic Model Let us first get familiar with this crossroad traffic model and have a sense of what it can do. Figure 5.3.3 is a detailed illustration of the hardware.


Chapter 5 109 Figure 5.3.3: A detailed illustration of the crossroad traffic control board It is reasonable to assume the Small Ave. has less traffic flow than the Main St., therefore we may assign the traffic lights to standby mode at nighttime, and only operate when some sensors are activated. Table 5.1 lists some important functional ports on this board. Table 5.1: Functional ports on the crossroad traffic control board ❶ System Power 5V. Connects to VBUS (pin40) on STEPFPGA board ❷ 8 × Road lights all driven by an N-type BJT ❸ 4 × R/Y/G LEDs for traffic light ❹ 2 × Hall-effect sensors on the Small Ave. detecting vehicle transpassing ❺ Battery is wired to System 5V to power up the STEPFPGA board Charge converts solar panel to constant 4.2V to charge the battery ❻ 2 × Pushbuttons on the Small Ave. to detect predestrian passing ❼ Light dependent Resistor (LDR) to sense the ambient light ❽ A potentiometer to manually adjust the sensitivity of the LDR circuit ❾ A potentiometer to manually set an Identification of the board


A Tutorial for FPGA beginners 110 A closer look of the pin names on the board is shown in Figure 5.3.4, where GPIO6 to GPIO19 are wired to the traffic & road lights and sensors on board. There are still 22 free GPIOs left in case you want to further extend the application. Figure 5.3.4: Wirings of the IO pins on the crossroad traffic control board We will explain the FPGA interface with all these modules to achieve certain functionalities in coming contents. Detection of Vehicles and Pedestrians Adding some fun to the project, we placed two Hall-effect magnetic sensors and two pushbuttons on the Small Ave. (NO.2 and NO.4). The magnetic sensor detects if a vehicle is waiting to pass the crossroad, and of course a magnet must attach onto the vehicle model. The magnetic sensor is EST248, a bipolar hall-effect switch where its functional block diagram is shown in Figure 5.3.5. Figure 5.3.5: Block diagram of EST248 Hall-effect sensor chip


Chapter 5 111 The output is open-drain structure therefore we need to connect a pull-up resistor. When magnetic field is detected, the output shorts to ground by the Field Effect Transistor (FET) which produces a logic 0. Note that the magnet must be placed in a way such that the flux is projected onto the sensing active area. To verify this, you can use a magnet and scope the output signal using Zoolark or an oscilloscope. Figure 5.3.6 shows the schematic of the magnetic field sensing circuit built on the board. The 10kΩ resistor pulls up the open drain output to VCC when no field is detected, and only generates a logic 0 when a car (with magnet) approaches. Figure 5.3.6: Circuit schematic of the Hall-effect sensor To design a digital module on Verilog, we simply detect the logic level of the two input signals CarSignal_2 and CarSignal_4 that will switch the logic levels when magnetic fields are detected. Ambient Light Sensing A nighttime the traffic lights on Small Ave. will turn into stand-by mode and all road lights should automatically turn on at evening. One simple and cost-effective way to determine daytime or nighttime is to judge based on amebient light intensity, thus a Light Sensing Resistor (also called Light Dependent Resistor, LDR) is needed. Figure 5.3.7 illustrates the appearance of an LDR and its characteristic curve.


A Tutorial for FPGA beginners 112 Figure 5.3.7: Change in resistance of a LED at different ambient light intensity An LDR is essentially a variable resistor of which the resistance decreases when light hits onto the top photosensitive film layer. Depending on the light intensity, the resistance may vary from 1MΩ (very dark) down to few hundred ohms (very bright). The circuit shown in Figure 5.3.8 is a voltage divider circuit which generates a continuous analog output voltage indicating the brightness of the ambient environment. VLDR = Vcc RLDR R + RLDR Figure 5.3.8: Getting the analog output signal of LDR by a voltage divider circuit Since FPGA only deal with ones and zeros, we have to convert the analog output to digital signals. Recalling from Section 1.6, an ADC with high resolution bits and fast sampling rate may precisely convert a voltage signal to digital ones and zeros. However, in this scenario the system only needs to know if it is dark or bright outside, which suggesting that a 1-bit digital signal is sufficient. The simplest form to build a 1-bit ADC is using a comparator as indicated in Figure 5.3.9. Figure 5.3.9: Build a single bit ADC with a voltage comparator


Chapter 5 113 In Verilog implementation, digital module takes LDR_Sense as the input, and again, the logic level of this input indicates for daytime (when LDR_Sense == 0) and nighttime (when LDR_Sense == 1). Adjusting the potentiometer LDR_Sensor on board gives different threshold reference voltage for VREF thus changes the sensitivity of the LDR sensor. State Machine of the Traffic Control System At daytime, we assume the traffic flow on Main St. and Small Ave. stay usual, thus we use the same State Diagram as in Figure 5.2.3 for daytime. At nighttime, the traffic flow on the Small Ave. may see a significant decrease, thus the traffic lights should entire into standby mode. In this mode, Small Ave. always stay at red light status unless a pedestrian presses the button or a vehicle is waiting to pass the crossroad. Meanwhile, the system turns on all road lights at night. The entire process can be described with the State Machine in Figure 5.3.10. Figure 5.3.10: State Machine of the smart traffic control module The status of the traffic road lights in each state are specified in Table 5.2. Table 5.2: Definition of the states State Description of the state S1 Main St. light turns to Green, Small Ave. light is Red S2 Main St. light turns to Yellow, Small Ave. light is Red S3 Main St. light turns to Red, Small Ave. light turns to Green S4 Main St. light is Red, Small Ave. light turns to Yellow S5 Main St. light turns to Green, Small Ave. light turns to Red S6 Main St. light turns to Yellow, Small Ave. light is Red S7 Main St. light turns to Red, Small Ave. light turns to Green S8 Main St. light is Red, Small Ave. light turns to Yellow In Verilog, we use a 3-segment structure to describe the state machine in this project.


A Tutorial for FPGA beginners 114 Segment 1: Execute the transitions of the states. A complete state machine always has a sequential logic part which has all states synchronized to a clock. This clock is not necessarily the system clock of the FPGA depending on your design. The code below generates a 1Hz clock clk_1Hz and we use this signal to execute the transitions of states. // Segment 1 – Implement the transitions of states synchronized to clock // Generate 1Hz signal reg clk_1Hz; reg [23:0] cnt; always @(posedge clk or negedge rst_n) begin if(!rst_n) begin cnt <= 0; clk_1Hz <= 0; end else if(cnt == 24'd5_999_999) begin cnt<=0; clk_1Hz <= ~clk_1Hz; end else cnt<=cnt+1'b1; end reg [7:0] timecnt; always @(posedge clk_1Hz or negedge rst_n) if(!rst_n) c_state <= S1; else c_state <= n_state; end Segment 2: Describe the transition of states. This part describes where the state will jump to when different trigger conditions are given. The states react to the trigger signals immediately and no timing is involved, therefore we can use combination logic here. See code below. // Segment 2 - Describe the transitions of states reg [2:0] c_state,n_state; wire SmallAve_Wakeup = pedestrain2 & pedestrain4 & CarSignal_2 & CarSignal_4; always @(*) begin if(!rst_n)begin n_state = S1; end else begin case(c_state) S1: if(!timecnt)begin if(LDR_Sen) n_state = S5; else n_state = S2; end else n_state = S1; S2: if(!timecnt)begin if(LDR_Sen) n_state = S5; else n_state = S3; end else n_state = S2; S3: if(!timecnt)begin if(LDR_Sen) n_state = S5; else n_state = S4; end else n_state = S3; S4: if(!timecnt)begin if(LDR_Sen) n_state = S5; else n_state = S1; end else n_state = S4; S5: if(!LDR_Sen) n_state = S3;


Chapter 5 115 else if (SmallAve_Wakeup) n_state = S5; else n_state = S6; S6: if(!timecnt) begin if(!LDR_Sen) n_state = S1; else n_state = S7; end else n_state = S6; S7: if(!timecnt)begin if(!LDR_Sen) n_state = S1; else n_state = S8; end else n_state = S7; S8: if(!timecnt)begin if(!LDR_Sen) n_state = S1; else n_state = S5; end else n_state = S8; default:n_state = S1; endcase end end Segment 3: Describe the actions to be carried out in each state. This part is a sequential logic synchronized to the state machine clock that eventually tells what happens to all registers and output signals at each state. See code below. // Segment 3 - Describe the actions implemented in each state, synchronized to clock always @(posedge clk_1Hz or negedge rst_n) begin if(!rst_n)begin timecnt <= 8'd15; TrafficLights_Main <= GREEN; TrafficLights_Small <= RED; end else begin case(n_state) S1: begin TrafficLights_Main <= GREEN; TrafficLights_Small <= RED; if(timecnt==0) timecnt <= 8'd15; else timecnt <= timecnt - 1'b1; end S2: begin TrafficLights_Main <= YELLOW; TrafficLights_Small <= RED; if(timecnt==0) timecnt <= 8'd2; else timecnt <= timecnt - 1'b1; end S3: begin TrafficLights_Main <= RED; TrafficLights_Small <= GREEN; if(timecnt==0) timecnt <= 8'd7; else timecnt <= timecnt - 1'b1; end S4: begin TrafficLights_Main <= RED; TrafficLights_Small <= YELLOW; if(timecnt==0) timecnt <= 8'd2; else timecnt <= timecnt - 1'b1; end S5:begin TrafficLights_Main <= GREEN; TrafficLights_Small <= RED; timecnt <= 8'd0; end S6: begin TrafficLights_Main <= YELLOW; TrafficLights_Small <= RED; if(timecnt==0) timecnt <= 8'd2;


A Tutorial for FPGA beginners 116 else timecnt <= timecnt - 1'b1; end S7: begin TrafficLights_Main <= RED; TrafficLights_Small <= GREEN; if(timecnt==0) timecnt <= 8'd5; else timecnt <= timecnt - 1'b1; end S8: begin TrafficLights_Main <= RED; TrafficLights_Small <= YELLOW; if(timecnt==0) timecnt <= 8'd2; else timecnt <= timecnt - 1'b1; end default:; endcase end end Other functionalities of the board For applications that require more precise measurements of the analog sensor readout, 1-bit output from a comparator is obviously insufficient. One choice is to use a better ADC hardware with higher bit-depth. Here we will show another great approach called 1-bit ADC (or Sigma-delta ADC), namely uses a single GPIO to sample a precisely enough digital data representing the analog signal. The structure of this 1-bit ADC is shown in Figure 5.3.11. Figure 5.3.11: 1-bit ADC block diagram This module ADC_top is a generic digital module published by Lattice Semiconductor (you may the complete code at: https://www.latticesemi.com/products/designsoftwareandip/intellectualproperty/referencedesigns/referencedesign03/s implesigmadeltaadc This module is an implementation of the Sigma-delta modulation technique which we will review the topic again in later piano project. To use this module, you need a comparator and an RC low pass filter. The component value of RC is calculated as: RC ≫ 1 2πfsample


Chapter 5 117 If we use 8 bit depth for the digital output, the sampling frequency fsample is: fsample = 12MHz 28 = 47kHz Therefore using a R = 3kΩ, C = 1nF satisfies the equation. Furthermore, with a 47kHz sampling frequency, this circuitry is fast enough to sample analog signals slower than 23kHz according to the Nyquist Sampling theorem. If you need to sample higher frequency signal, either increase the clock frequency or lower the bit depth of the digital output. There is another potentiometer called Board_Addr placed adjacent to the LDR circuit. Figure 5.3.12 shows the interface of the 1-bit ADC module with this potentiometer. Figure 5.3.12: Implementing a Sigma-delta ADC with STEPFPGA board While manually rotate this pot, the amplitude of the analog voltage changes, and the Sigma-delta ADC module converts the amplitude to an 8-bit digital data, which can be represented by the 8 LEDs on the STEPFPGA board. This means if you want to build a road system with multiple crossroad boards, each board can be identified with a unique ID by rotate the pot to different positions. The complete code of this traffic light project can be found at the link below, where you will need to assign the GPIO pins of the FPGA to match the signals of the digital module. https://github.com/eimtechnology/STEPFPGAMXO2Core/blob/main/Tutorial%20Level1/Chapter5/5.3_SmartTraffic/All_In_One_Style/Crossroad_Smart.v Project Summary The entire project is summarized in Figure 5.3.13.


A Tutorial for FPGA beginners 118 Figure 5.3.13: Summary of the smart crossroad traffic control project


Chapter 5 119 5.4 FPGA for Elevator Control Project Overview In this project let us build an elevator control system. A simplified elevator is illustrated in Figure 5.4.1, which is constructed by a rigid wall structure, a powerful motor (usually comes with a pulley system) for descending and ascending, and a cage holding passengers. Obviously, control panels should be installed both inside the cage and each floor. For simplicity, in this project we only consider the control panel inside of the cage. Figure 5.4.1 A simplified illustration of an elevator system If you have the Fantastic Building Kit accompanied with the STEPFPGA board, then we can first build the elevator model as shown in Figure 5.4.2 (takes approximately 30 minutes). If you do not have the complete kit, we recommend you at least get an ultrasonic sensor module (HR-04), a motor driver, a DC motor, a power supply and some pushbuttons.


A Tutorial for FPGA beginners 120 Figure 5.4.2: Illustration of the constructed model of the elevator system This simple electro-mechanical system has a sensor (ultrasonic) to provide feedback signals and an actuator (DC motor) to generate power for kinematic movements. We can also utilize the on-board LEDs and segment displays on STEPFPGA to display some basic information such as the elevation of current position. System Level Design This time we first start with system level design. Electrically, this system contains four parts: 1. an input interface allowing users to select for the designated floor 2. a position sensor that tells the current location of the elevator cage 3. a motor control circuit that controls the ascending/descending/braking of the elevator motor 4. a digital controller unit that operates the whole system Figure 5.4.3 is the schematic of the hardware system.


Chapter 5 121 Figure 5.4.3: Circuit schematic of the elevator system A ‘moderner’ option for user interface input would be a keypad matrix, but it is a bit complicated so we will explain that in Section 5.5; instead we use 5 pushbuttons corresponding floor 1 to 5. These buttons are set to pull-down structure so the GPIO will only read a logic 1 after the button is pushed. The circuit is built on breadboard as shown in Figure 5.4.4. Figure 5.4.4: Breadboard implementation of the elevator controller circuit The ultrasonic sensor can be placed at the bottom to measure the distance between ground and elevator cage so you need longer jumper wires. Note that real elevators use much more complicated measurement system to ensure your safety, so the ultrasonic solution is purely for hobby-level purpose. To drive a DC motor, we use a popular H-bridge motor drive chip L293 to serve the purpose. Again, this DC motor is placed on top of the elevator so you need to use longer wires.


A Tutorial for FPGA beginners 122 Switch Debouncing Design Dealing with mechanical switches or pushbuttons is not as easy as it sounds. When we close a switch or press a button, we see from our eyes that the two contacting metals come together instantly, but in reality they are not. Figure 5.4.5 shows a ‘microscopic’ view when the switches are pressed: multiple transitions have been generated before the signal reaches to a steady voltage level. Depending on the elasticity of the metal or the way of pressing, the bouncing glitches may take hundreds of microseconds or few milliseconds. These glitches may result in false alarm or cause unexpected system errors therefore must be handled properly, and the technique is usually referred as switch debouncing. Figure 5.4.5: Bouncing effect when interfacing a mechanical switch Figure 5.4.6 is the hardware method to debounce the glitches by shunting a filtering capacitor to the pull-up or pull-down resistor. A capacitor takes some time to charge or discharge therefore any rapid transitions will be flattened. This capacitor basically serves the same function as the shock absorbers on your bike. Figure 5.4.6: Debouncing a switch by adding a filtering capacitor


Chapter 5 123 However, imagine you run a production of 1000 devices where each one has 10 pushbuttons, so you will need ten thousand capacitors to deal with switch bouncing issue. A more cost-friendly way to deal with switch bouncing is by means of timing control, also known as software debouncing. As indicated in Figure 5.4.7, we ‘ask’ the system to confirm the status of the key signal after 20ms instead of reacting immediately; if the signal is confirmed to be flipped, then the system sends a short pulse through the GPIO indicating the key has been pressed once. Figure 5.4.7: Debouncing a switch using software method There are multiple ways to implement a soft-debouncing module on Verilog. As indicated in Figure 5.4.8, we can generate a 50Hz slow clock slow_clk and add Flip-flops synchronized to this slow clock. Since the bouncing lasts for less than 10ms, it means the data stored by the Flip-flops will not be affected by the bouncing noise. Figure 5.4.8: Using two D Flip-flops to generate a single pulse for each press


A Tutorial for FPGA beginners 124 Code 5.2 is the Verilog implementation for the top module debounce which instantiate three submodules. The code may not be the smartest way to implement a soft key debouncing module but serves a good illustration purpose to show a structural coding style. Code 5.2: Implementation of debounce module module debounce ( input clk, key, output key_deb ); wire slow_clk; wire Q1,Q2,Q2_bar; divider_integer #(.WIDTH(17),.N(240000)) U1 ( .clk(clk), .clkout(slow_clk) ); dff U2 ( .clk(slow_clk), .D(key), .Q(Q1) ); dff U3 ( .clk(slow_clk), .D(Q1), .Q(Q2) ); assign Q2_bar = ~Q2; assign key_deb = Q1 & Q2_bar; endmodule Note that this code generates only a single pulse every time you press a key; if you would like the output signal hold the current voltage level unless you release the key, then change the assignment to: assign key_deb = Q2; endmodule Reading Position from a Distance Sensor Knowing the fact that sound travels in the air with 343m/s speed, an ultrasonic sensor measures distance by calculating the time interval between the transmitted sound wave and the returned echo wave from the target object, as being illustrated in Figure 5.4.9. Since the human audible frequency lies in the range from 20Hz to 20kHz, most ultrasonic sensors use 40kHz frequency for a good balance of radiation power and energy pattern.


Chapter 5 125 Figure 5.3.9: Working principle of an ultrasonic distance sensor Taking the well-known SR04 ultrasonic sensor module as the example. As shown in Figure 5.4.10, a 10us pulse width trigger signal initiates a 40kHz burst to be transmitted into the air from one ultrasonic transducer. If an object was placed in front, the reflected echo wave returns and received by the other ultrasonic transducer. The pulse width of the Echo pin records the time interval between transmitted wave and reflected wave, thus allowing distance being calculated. Figure 5.4.10: Waveform diagram of SR04 ultrasonic distance sensor module To interface with the sensor board, the module hr_sr04 basically needs to do the following actions: • Generate pulses (with 10us pulse width) continuously to the Trig pin on HC-SR04 board • Measure the pulse width send back from the Echo pin from HC-SR04 board Figure 5.4.11 shows a process to generate a 10us pulse width signal at a 1Hz frequency: Figure 5.4.11: Sending a 10us pulse width signal at 1kHz frequency using a counter


A Tutorial for FPGA beginners 126 Once the ultrasonic module receives the trig signal it will measure the object distance by calculating the pulse width of the reflected signal. Quantitatively, the distance is calculated as: Range = Thigh × 343m/s 2 ≈ 170Thigh(m) where Thigh is the pulse width of the reflected signal from the Echo pin of the ultrasonic sensor. There are many methods to estimate Thigh, and we will do this by counting the number of clock cycles. For example, the above equation can be written as, Range = 170 × N fclk Where fclk is a clock where the frequency is in multiples of 170Hz. In Figure 5.4.12, we use 1700Hz, 17kHz and 34kHz clock frequencies to estimate for the same Thigh. Figure 5.4.12: Estimating Thigh by counting the number of cycles of a faster clock The illustration suggests that the measurement resolution can be improved with faster clocks. For our application, using a clk17k is enough. Though it is easy for an FPGA to generate much faster clock frequency than 17kHz, the measurement resolution cannot go beyond the hardware limitation of the SR-04 ultrasonic sensor. In Verilog, we write the basic definition of the module hc_sr04 to interface with HC-SR04 board. The code of the hc_sr04 module can be found at the link below. But be aware that the output is a 16- bit data which you cannot observe anything with your eyes. https://github.com/eimtechnology/STEPFGA/blob/main/Tutorial%20Level1/Chapter5/5.4_Elevator/Seperate_Style/hrsr 04.v module hc_sr04 ( input clk, rst_n, // STPFFPGA has on board frequency of 12MHz input echo, // Module input, connects to HC_SR04 -> echo output trig, // Module output, connects to HC_SR04 -> trig output reg [15:0] distance );


Chapter 5 127 Figure 5.4.13 shows the connection of the SR-04 hardware to the digital module hr_sr04. Surely we need to assign the inputs and outputs of this module to the physical IO pins on the STEPFPGA to setup physical electrical connections. Figure 5.4.13: Interface with the ultrasonic sensor hardware In the code, we reserved a 16 bit-width output data distance[0:15] (up to 65535 counts) to hold for potential higher counts. For example, if you want to boost the measurement resolution and therefore uses a 170kHz clock, the number of counts for Thigh will be almost 10 times more than using a 17kHz clock. Adding a 16 bit-width output makes this module more general for other ultrasonic sensors hardware with longer sensing range and higher resolution. Binary to BCD Converter In case we would like to display the measured distance from the ultrasonic sensor, for example to display distance on the two segment tubes of the STEPFPGA board, then we need a Binary Coded Decimal converter, known as BCD converter. Humans love decimal numbers so we want segment display only show numbers from 0 to 9. Table 5.3 is the complete list for the ten BCD codes corresponding to digit 0 to 9. Table 5.3: The BCD code for the 10 decimal numbers Decimal Number BCD Code 0 0000 1 0001 2 0010 3 0011 4 0100 5 0101 6 0110 7 0111 8 1000 9 1001 The ‘double dabble’ algorithm, also known as shift-and-add-3 algorithm, is used to convert binary numbers to BCD. There are plenty of articles explaining the mathematical principles of the algorithm


A Tutorial for FPGA beginners 128 so we do not cover the details in this tutorial. From practical engineering perspective, to design a module on Verilog, we need to figure out the basic definition of the module. For better illustration, Figure 5.4.14 shows structure of module bin_to_bcd. Figure 5.4.14: The definition of a BCD module that converts a 16-bit input The 16-bit input signal distance is the output data from the ultrasonic sensor module hc_sr04 that represents the measured distance. The maximum possible decimal number for a 16-bit binary data is 65,535, which means if you want to display the whole number in decimal, at least five segment tubes are needed. Recalling from Section 3.5 that driving each segment tube requires a 4-bit input signal, therefore the output bcd_dist should have a bit width of 20. In this project, we set the unit of measurement in centimeters, and knowing the height of the elevator is certainly less than 99cm, only two segment display tubes are needed. As shown in Figure 5.4.15, the two segment driver modules segment7 only takes the lower eight bits from the 20-bit output. Figure 5.4.15: Taking the last 8 bits from the BCD module output to display two decimal digits The Verilog code to implement the 16-bit input module bin_to_bcd is given in Code 5.3. Code 5.3: Implementation of a 16-bit input BCD module (show up to 5 decimal digits) module bin_to_bcd ( input rst_n, input [15:0] bin_code, output reg [19:0] bcd_code ); reg [35:0] shift_reg; always @ (bin_code or rst_n) begin shift_reg = {20'h0,bin_code}; if(!rst_n) bcd_code = 0; else begin repeat(16) begin // repeat for 16 times if (shift_reg[19:16] >= 5) shift_reg[19:16] = shift_reg[19:16] + 2'b11; if (shift_reg[23:20] >= 5)


Chapter 5 129 shift_reg[23:20] = shift_reg[23:20] + 2'b11; if (shift_reg[27:24] >= 5) shift_reg[27:24] = shift_reg[27:24] + 2'b11; if (shift_reg[31:28] >= 5) shift_reg[31:28] = shift_reg[31:28] + 2'b11; if (shift_reg[35:32] >= 5) shift_reg[35:32] = shift_reg[35:32] + 2'b11; shift_reg = shift_reg << 1; end bcd_code = shift_reg[35:16]; end end endmodule If we design a digital system combining the ultrasonic module, BCD converter and segment display driver, then we can display two digits data on STEPFPGA board when it has been properly wired to the HC-SR04 board. Code 5.4 is a top module SR04_display to test the ultrasonic sensor where the measured result can be displayed on the segment tubes on STEPFPGA board. Code 5.4: Top module to display the distance (in cm) measured by the ultrasonic module module SR04_display( input clk, rst_n , input echo, // reads the ECHO signal from HC_SR04 output trig, // send trigger pulse to HC_SR04 module output [8:0] segment_led_1, // 7-Segment display 1 output [8:0] segment_led_2 // 7-Segment display 2 ); hc_sr04 ultrsonic (clk, rst_n, echo, trig, distance); wire [15:0] distance; // 16-bit binary output from SR-04 sensor bin_to_bcd bin_to_bcd_U(rst_n, distance, bcd_distance); wire [19:0] bcd_distance; // 19-bit BCD output from BCD module wire [3:0] bcd_digit1; wire [3:0] bcd_digit2; assign bcd_digit1 = bcd_distance[3:0]; // convert smaller 4 bits BCD to binary assign bcd_digit2 = bcd_distance[7:4]; // convert higher 4 bits BCD to binary segment7 seg_x1( // display the first digit on Segment1 .seg_data(bcd_digit1), .segment_led (segment_led_1) ); segment7 seg_x10( // display the second digital on Segment2 .seg_data(bcd_digit2), .segment_led (segment_led_2) ); endmodule Controlling the Motor Direction To move the elevator up and down, we need to control the orientation of the motor, which is determined by the direction of electrical current flowing through the coil. A commonly used method circuit to control the bi-directional DC motor movements is called H-bridge, which takes its simplest abstract form, can be explained with 4 switches as indicated in Figure 5.4.16.


A Tutorial for FPGA beginners 130 Figure 5.4.16: Controlling the orientation of a DC motor by changing current direction Since current always flows from high voltage to low voltage, the direction for which the current enters the motor can be manipulated with different pairs of the diagonal switches. In circuit level, these switches can be replaced by transistors so that the ON/OFF current path can be controlled electrically. In Figure 5.4.17, the transistors used are Bipolar Junction Transistors (BJT) which is a currentcontrolled transistor. More detailed explanations of transistors will be covered in our microelectronics tutorial, in this tutorial, we should know that the orientations of the DC motor can be controlled by setting CCW/CW to logic 1,0 or logic 0,1 respectively. Figure 5.4.17: Bidirectional movement of a DC motor controlled by an H-bridge with 4 BJTs Instead of building the circuit with lots of transistors, there are motor driver ICs available such as L9110 or L293N. In Figure 5.4.18, we use L293N and connect GPIO8, GPIO9 on STEPFPGA board. GPIO7 is for chip enable. Depending on the internal wiring of the DC motor, you may need to add a current limiting resistor if this motor draws too much current during operation. The other option is to set the motor control pins to PWM mode to reduce the average voltage applied onto the motor, due to the complexity level of this project, the PWM is not implemented in the Verilog code but you are encouraged to try by yourself as a great exercise.


Chapter 5 131 Figure 5.4.18: Control a DC motor using L293 chip Table 5.4 summaries the operations of the L293N chip at different logic inputs. Note that ‘x’ means don’t care. The Turn-right and Turn-left actions of motor correspond to ascending and descending of the elevator. When the elevator halts at a certain floor, the motor should break when the elevator stops at a certain floor during operation. Table 5.4: Operations of the DC motor at different logic control inputs EN (GPIO7) 1A (GPIO8) 2A (GPIO9) Action 1 0 0 Fast brake 1 0 1 Turn right 1 1 0 Turn left 1 1 1 Fast brake 0 x x Free-run stop Designing the State Machine Knowing the functionality of each module, we need a State Machine to handle the control algorithm for this elevator system. The whole event of this project can break into 5 states for Floor 1 to Floor 5. Drawing lots of arrows for each state is tedious therefore Figure 5.4.19 only shows a partial State Machine representing a 3-


A Tutorial for FPGA beginners 132 story elevator. The trigger condition for state transition is the signal from the push buttons representing the 5 floors. Figure 5.4.19: Partial state machine of the elevator movement controller In each state, the system should continuously check the distance data sent from the ultrasonic module to determine the actions of the DC motor driver. Final Implementation Eventually we will build a top module that integrated all independent building pieces into an organic digital system. The module elevatorCtrl shown in Figure 5.4.20 is the digital system implemented by FPGA. Figure 5.4.20: Top level module of the Elevator Controller system A closer view of the entire hardware system is outlined in Figure 5.4.21. The entire hardware system consists of the elevatorCtrl digital module implemented on FPGA board, which is the core of the system. Moreover, you need to ensure the peripheral modules such as ultrasonic sensors, motor drivers, key buttons, segment display tubes (on STEPFPGA board) are properly powered and connected to the right GPIOs of the STEPFPGA board.


Chapter 5 133 Figure 5.4.21: Digital system of the top module for elevator controller Due to the length of code, the complete Verilog code can be found at the link below where all submodules are integrated into a single Verilog file. https://github.com/eimtechnology/STEPFGA/blob/main/Tutorial%20Level1/Chapter5/5.4_Elevator/All_In_One_Style/el evatorCtrl.v To test this code, make sure the Trig and Echo pins of the ultrasonic senor are corrected connected to the GPIOs of your FPGA pin assignment. Also, if the motor is spinning too fast, you may add a series resistor (>1W, 10Ω) to limit the current. Project Summary The entire project is summarized in Figure 5.4.22.


A Tutorial for FPGA beginners 134 Figure 5.4.22: Summary of the elevator controller project


Chapter 5 135 5.5 Implement a Digital Locker Project Overview Digital lockers are commonly seen in daily life. A simple digital locker shown in Figure 5.5.1 usually contains a digital panel for typing the password and an electronically controlled bolt to lock or release the door. If the user typed in the wrong password, the LED indicator or buzzer may trigger to prompt the user for new attempts. Figure 5.5.1: A simple illustration of digital locker with a keyboard panel In this project, we use a keyboard panel with ten digits and two functional keys * and #. While opening the door, user should press *, then type in the four digits password quickly and follow up with a single press of # key to complete the action. If there is a long waiting time after * being pressed, or a wrong password was attempted by user, the system will reset and the buzzer gives an alarm. By default, the password to open this door is ‘1234’. Hardware Setup Figure 5.5.2 shows the circuit schematic of the simplified digital locker controlled by the STEPFPGA board. The keypad is arranged in matrix structure to save the number of occupied GPIOs. In this example, the 12 keys can be controlled using only 7 GPIOs. Figure 5.5.2: The hardware structure of a simplified digital locker model


A Tutorial for FPGA beginners 136 When * is pressed and released, the system turns into ‘listening mode’. The user should finish typing the four digits password within 5s. At the fifth second, if # is detected, the system will check against the correct password. The correct password triggers the gate latch (which is represented as a servo motor with a bar) to rotate some degrees to open the door. Otherwise the latch does not move and the buzzer sounds a short alarm. Reading Data from Matrix Keyboard All experiments we have seen in this book so far use one GPIO to control one switch, obviously this way is simple but not efficient in terms of IO usage, since controlling a 12 keypad occupies 12 GPIOs, not to mention a keyboard that has over 100 keys. To improve the efficiency of IO usage, the matrix keyboard was designed. Figure 5.5.3 shows the wiring of a 4x3 switch matrix. Figure 5.5.3: Controlling a 4x3 matrix keyboard with seven GPIOs (without pull-up/down resistors) We can arrange the 12 keys with a 4x3 matrix, thus using 7 GPIOs are enough to locate every single key. The matrix is arranged such that four row signals, Row 0, Row1, Row2 and Row3 set to output scan mode, and the rest three column signals, Col0, Col1 and Col2 connect to three GPIOs set to input reading mode. Figure 5.5.4 shows the moment when the four row signals are scanning: Row0, Row2, Row3 stay at 1, and Row1 sets to 0. And if at this moment key ‘6’ has been pressed, the logic 0 will be detected by Col2 which constantly monitors the voltage level at the other end of the pushbutton. Figure 5.5.4: The mechanism to detect button ‘6’ being pressed


Chapter 5 137 Obviously the four rows must constantly scan to detect any changes on the keyboard. Figure 5.5.5 is the moment when Row0, Row1, Row3 are 1 and Row 2 is 0. If the user pressed key ‘8’, then Col1 will detect the 0 as the switch is closed. Figure 5.5.5: Detecting key 8 being pressed with continuous scan Due to the working mechanism illustrated above, a State Machine in Figure 5.5.6 is designed to interface with the keypad matrix. The 4 states of Row0_SCAN, Row1_SCAN, Row2_SCAN and Row3_SCAN will check the voltage level of the keys corresponding to each row, and a 200Hz clock continuously scans the 4 states to ensure any changes of the key can be updated on time. Figure 5.5.6: State machine of the keypad control module The Verilog code of keypad_3by4 module which interfaces with a 3 by 4 keypad matrix board can be found at: https://github.com/eimtechnology/STEPFPGAMXO2Core/blob/main/Tutorial%20Level1/Chapter5/5.5_DigitalLocker/Seperate_Style/keypad_3by4.v As an exercise, you can implement this code on STEPFPGA board. The number you pressed on the keypad will be displayed by the two segment tubes, but you need to connect 3 additional pull up resistors at the 3 column pins. Referring more tails in the System Design and Implementation part. Check the password Once the user has typed the password, we need a simple computing module to determine if the password is correct, and then prompt other parts of the system for corresponding actions. Again, we describe the logic of actions with a state diagram as shown in Figure 5.5.7.


A Tutorial for FPGA beginners 138 Figure 5.5.7: State machine of the password checker module With this algorithm, the module pwd_checker is designed to implement the state machine. The 4- bit input keyUserInput is connected to the output of keypad_3by4 allowing the keypad data sent to the state machine. If the 4 digits plus confirmed ‘#’ password input matches to the correct password then the output signal pw_true generates logic 1, otherwise pw_false will be 1. The other output signal timeout_flag indicates for time out. The basic definition of the pwd_checker module is shown in Figure 5.5.8, whereas the complete Verilog code can be found at the link: Figure 5.5.8: Basic definition of password checker module https://github.com/eimtechnology/STEPFGA/blob/main/Tutorial%20Level1/Chapter5/5.5_DigitalLocker/Seperate_Styl e/pwd_checker.v Controlling a Servo Motor A servomotor allows precise control of the position, velocity and acceleration. Figure 5.5.9 shows the structure of a servomotor. In this closed-loop feedback system, the status of output shaft will be converted to electrical signal through a potentiometer. This signal will be constantly compared with the input command signal. A DC motor inside the enclosure runs continuously until the output shaft reaches to the designated position.


Chapter 5 139 Figure 5.5.9: Illustration of a servo motor structure Surprisingly, controlling a servomotor might be simpler as you thought since it only uses one PWM signal. For example, Figure 5.5.10. shows the timing diagram to control an SG90 servo motor. A PWM signal of 50Hz (20ms period) is constantly fed to the input signal. The pulse width may vary from 1ms to 2ms which maps to -90 to 90 degrees. Note that the rotation angles of most servomotors are limited to 180 degrees. If your application requires full revolutions then you should go for DC/AC motors or stepper motors. Figure 5.5.10: Controlling the angular movement of a SG90 servo by a PWM signal In Verilog, we design this servo module to control the angle rotation of a servo motor. The 8-bit input rotate_angle receives the instruction for the angle of rotation from 0 degree up to 180 degrees. Since a servomotor cannot go beyond 180 degrees, a localparam UpLimit = 179 sets for the upper limit rotational angle in the code. The module definition of the servo motor control module is given in Figure 5.5.11, where the Verilog code to control the SG90 servo motor can be found at the link below.


A Tutorial for FPGA beginners 140 Figure 5.5.11: Structure of servo motor rotation control module https://github.com/eimtechnology/STEPFGA/blob/main/Tutorial%20Level1/Chapter5/5.5_DigitalLocker/Seperate_Styl e/servo.v To test this module, you need an 8-bit input data to set the angle of rotation, where the output signal servo_pwm connects to the input command wire of a servo motor. As a fun exercise, you may use the piano keyboard or find 8 switches to the GPIOs of the FPGA and manually control the servo movement. The servo should be powered independently with a power supply at 5V. Beep the Buzzer Buzzers and speakers are two common electronic transducers that convert electrical signals into sound. Figure 5.5.12 shows the structure of a piezo-buzzer which essentially utilizes the piezoelectric effects. While the current passes through the coil, the piezoelectric plates vibrate the air thus producing audible pressure waves. Figure 5.5.12: Illustration of a piezo buzzer structure Buzzers are driven by digital signals for which the sound harmonics follow a fixed pattern. Unlike speakers, buzzers are not suited for reproducing high quality sound or music with complex tones, but the advantages of being smaller, cheaper and less power-hungry make buzzers widely used in applications such as alarms, beepers and sound indicators. The human hearing range is commonly given as 20Hz to 20kHz. If you have Zoolark (a multifunctional circuiting tool as shown in Figure 5.5.13) or other a function generator, connecting a pulse signal directly to the buzzer will generate sound at that frequency. Long time exposure to high frequencies may cause headaches or tinnitus so you should better use a frequency in range of 200Hz to 3kHz.


Chapter 5 141 Figure 5.5.13: Sound a pizeo buzzer by feeding a 1kHz PWM signal using Zoolark A buzzer is mainly used for simple tunes or sound indicators thus we should not expect a high audio quality. We will explore more about audio signals in next two sections. System Design and Implementation Figure 5.5.14 shows the structure of the top digital module DigitalLockerCtrl. We added an ServoAngle module to control the rotational degree of the servomotor. To control the buzzer, the module buzzer has an internal state machine to set for different tones. This buzzer module in this project has customized sound which is not a universal module. Figure 5.5.14: Structure of the digital module for digital locker controller To implement a functional hardware for demonstration purpose, we can build the hardware on a breadboard as shown in Figure 5.5.15. The digital locker enclosure is included in the Fantastic Building Kit and takes approximately 1 hour to build. You noticed that there is a green circuit board with a program preloaded microcontroller included in the kit. To control the matrix keypad, servo motor and buzzer, you can replace the microcontroller board by the STEPFPGA.


A Tutorial for FPGA beginners 142 Figure 5.5.15: Build the digital locker hardware In Figure 5.5.15 you may notice that we also added 3 pull-up resistors for the 3 input column pins, this is to detect the falling edge when a key is pressed. Without these resistors the results become unstable. The complete code of this project can be found at: https://github.com/eimtechnology/STEPFGA/blob/main/Tutorial%20Level1/Chapter5/5.5_DigitalLocker/All_In_One_St yle/DigitalLockerCtrl.v Project Summary The entire project is summarized in Figure 5.5.16.


Chapter 5 143 Figure 5.5.16: Summary of the digital locker control project


A Tutorial for FPGA beginners 144 5.6 A Simple Electronic Piano Project Overview Electronic keyboard is an electronic musical instrument capable of playing a wide range of instrument sounds such as piano, violin, organ, saxophone, etc. Usually electronic keyboards have prestored discrete audio samples of different instruments and have the tunes played when the corresponding keys are pressed. Working with a huge memory of audio samples is tedious and beyond the scope of this tutorial, this project investigates a more interesting approach to generate musical tones using sinusoidal waves. Audio and Sound Sometimes we use the word sound interchangeable with audio, but as far as engineering is concerned these two are different physics quantities, and the key difference is the energy form. Sound is a mechanical wave that propagates through mediums that may cause molecular vibrations such as gas, liquid or solid. Audio, on the other hand, is made of electrical energy in forms of analog or digital signals that represent sound specifically in the audible range of 20Hz to 20kHz. The concept of sound and audio can be better understood by comparing a traditional piano with an electronic keyboard. Figure 5.6.1 is an anatomy view of a grand piano which includes tuning pins, strings, hammers and sound board. When the keys are pressed, hammers will be raised and then knocked onto the strings to generate sounds. Figure 5.6.1: Photograph of a grand piano interior Unlike pianos, the sounds coming from an electronic keyboard are audio signals played by a speaker. On the keyboard, each key corresponds to distinctive frequencies that match to our familiar musical tones such as ‘Do-Re-Mi’…In Figure 5.6.2 we listed the base frequencies that match to musical notes from F3 to B5, and specifically in this project we will implement a full Octave from C4 to C5 (including half tones).


Chapter 5 145 Figure 5.6.2: The base frequencies of some keys on a piano Hardware System for Audio Play Figure 5.6.3 shows a typical way to convert audio signals into audible sounds. Audio signals are usually analog signals with weak output capability of electrical current. For a low wattage speaker such as earphone, the current is sufficient to cause vibrations of the internal coils to generate low volume sounds. However, the audio source is incapable to drive power thirsty large speakers directly thus a power amplifier is needed to significantly boost current capability. Figure 5.6.3: Converting audio signals into audible sound Power amplifiers are categorized in many classes. Figure 5.6.4 lists 4 types of commonly constructed classical amplifiers including Class A, Class B, Class AB and Class C. Another family of power amplifiers are switching type and will not be covered in this book. The speaker module included in the Fantastic Building Kit is a Class AB power amplifier built with 8002B.


Click to View FlipBook Version