Sunteți pe pagina 1din 57

1

FPGA based control unit for Solid State Marx Adder by Anshuman Sahoo

Under the guidance of, Mr.Abhijit Tillu Mr.Harshit Tyagi Electron Beam Centre, BARC

ABSTRACT
In an N stage solid state Marx adder it is desirable to be able to control each Marx cell individually. This feature is required to operate on different voltage levels, isolating a cell in case of failure of its components, improving the reliability of the system by implementing some backup Marx cells. FPGA is used to provide pulse source to gate drive and it also provides optical fibre isolation. The requirement of this control system is to be fast and able to control a large N number of modules. A Field Programmable Gate Array(FPGA) is a choice based on the above requirements and the flexibility in creating usable modules through Hardware Description Languages(HDL). The implemented control system can control all modules as well as individual ones. It can turn them on/off and edit parameters such as pulse width, rise and fall point of square wave.

ACKNOWLEDGMENTS
I would like to express my deepest appreciation to all those who provided me the possibility to complete this project. A special gratitude I give to my supervisors, Mr. Abhijit Tillu, SO/E, Accelerator and Pulsed Power Division(APPD), BARC and Mr. Harshit Tyagi, SO/C, APPD, BARC whose contribution in stimulating suggestions and encouragement, helped me to coordinate my project. Furthermore I would also like to acknowledge with much appreciation the crucial role of Madam Smt. Kavita Dixit, SO/H, APPD, BARC who gave me the administrative guidelines necessary to complete the task. I would like to thank Dr. K. C. Mittal (Head APPD & Project Manager, Electron Beam Centre) for his support in undertaking this project and for providing all facilities and infrastructure required to develop the project.

TABLE OF CONTENTS ABSTRACT................................................................................................................................2 ACKNOWLEDGEMENTS........................................................................................................3 INTRODUCTION.......................................................................................................................5 DESIGN......................................................................................................................................9 EXPERIMENTAL DETAILS....................................................................................................17 RESULTS AND DISCUSSIONS.............................................................................................17 CONCLUSIONS AND FUTURE SCOPE...............................................................................17 REFERENCES.........................................................................................................................19

APPENDIX A Calculation of number of clock cycles from pulse width...............20 APPENDIX B VERILOG CODE..........................................................................................21 APPENDIX C ASSEMBLY AND C CODE.........................................................................36 APPENDIX D NETLIST VIEWERS....................................................................................56

INTRODUCTION
The klystron modulator(Nunnally, Engel ) is an important component of the working of an electron beam accelerator. The modulator system is characterized by its energy storage system from which the energy can be released in the form of a high power pulse to the load, by means of a switching device. The modulator also has the means to shape as well as control the pulse. The limiting device in a modulator system is often the switch, which limits the pulse peak power and the repetition rate. The conventional approach in Pulsed Power designs is to use a gas switch such as a thyratron, ignitron or spark gap. However these devices have limited lifetime, high cost, low repetition rate and high losses. Due to the continued improvement of the high power semiconductors in switching speed, voltage and current rating, solid state switches have become the device of choice. The modulators which use the solid-state semiconductor devices for switching the power are called Solid-State Modulators. In modern pulsed power systems fast solid state switches like MOSFETs and Insulated Gate Bipolar Transistor (IGBT) modules are used to generate short high power pulses. Since each device is limited in its power-handling capability, solid-state switches are connected in various topologies to obtain the required output pulsed power. Marx 'Adder' topology is one of the most popular, consisting of modular blocks called 'Marx Cells'. A number of cells are stacked to obtain the desired output voltage at the load. Each Marx cell has a capacitor, an IGBT and a freewheeling diode. When the IGBTs are in OFF state, the capacitors are charged from a relatively low voltage DC source in parallel, through chain of common-mode inductive isolators. Before the end of the charging period the capacitors should attain the voltage equal to the source voltage. Now the circuit is ready to be pulsed. By pulsing the circuit appropriate gate voltages are applied to all the IGBTs to turn them ON in synchronization and circuit configuration changes in such a way that all the charged capacitors form a series connection across the load. Hence the desired HV output appears across the load for the duration of the pulse.

Fig 1.: Basic IGBT MARX Design

The drive to the IGBT gates needs isolation between logic level signal side and the part that directly drives the IGBTs. The value of isolation needed depends upon the voltage that is generated in the Marx Adder and the position of the Marx cell. This requirement arises since during the discharging period the capacitors in the Marx cell are in series and each cell floats at a certain added voltage depending upon the no. of stages below it. Besides that there is a need to give gate pulse to all the IGBTs in synchronization to get the full output voltage and the desired output pulse shape. The diode present in each cell bypasses a stage and starts to conduct if any IGBT fails to turn-on at all or is unsynchronised from the others and avoids an overvoltage across the IGBT. During this discharging period, the inductors block the voltages and provide isolation between the Marx cells floating at different voltages and also

with the DC voltage source. There are single-point failure risks in the basic Marx design of Fig. 1. The failure of any single IGBT or capacitor will fail the entire modulator by shorting out the input DC power. The probability of failure increases as the number of cells is increased. Thus the failure of the modulator due to single point failure of the critical components has to be completely eliminated in any practical Marx having large number of cells by making improvements in the basic design. Failure of any IGBT or capacitor in the Marx design of Fig. 2.1 will fail the entire modulator. The effect of these failures are mitigated here by adding an IGBT on the high side of the capacitor charging path to each cell as shown in Fig. 2 below.

Fig 2: Improved Marx with IGBT added in the charging path

In this project, we are concerned with building a control system that can receive feedback from the local control units and synchronize them by changing individual wave parameters. Due to the widespread popularity and efficiency of readymade FPGA chips, it was chosen for this project.

A field-programmable gate array (FPGA) is an integrated circuit designed to be configured by a customer or a designer after manufacturinghence "field-programmable". The FPGA configuration is generally specified using a hardware description language (HDL), similar to that used for an application-specific integrated circuit (ASIC) (circuit diagrams were previously used to specify the configuration, as they were for ASICs, but this is increasingly rare). Contemporary FPGAs have large resources of logic gates and RAM blocks to implement complex digital computations. As FPGA designs employ very fast IOs and bidirectional data buses it becomes a challenge to verify correct timing of valid data within setup time and hold time. Floor planning enables resources allocation within FPGA to meet these time constraints. FPGAs can be used to implement any logical function that an ASIC could perform. The design of the control unit for a Marx Adder generator is done on an Altera Cyclone IV E FPGA (EP4CE115F29C7). Two designs were implemented on the FPGA and the better one will be decided upon testing stage: 1) Microcontroller Design using Hardware Description Language(Verilog) 2) Microprocessor Design based on NIOS II processor coded in Assembly and C. The FPGA is connected to GPIO(General Purpose Input Output) pins which convert the digital signal from the FPGA to an analog Low Voltage TTL signal (3.3 V). The output is a square wave. This signal is then stepped up using comparators for further use on the control chain. The module is designed to be fast and efficient, and implemented with the idea of being easily integrated with other hardware in the Marx Adder.

Fig 3. Altera Development Borad with an FPGA

DESIGN
Design Philosophy The microcontroller design in this project is an efficient way of controlling the hardware through the FPGA chip. Circuits are 'programmed' and can be tested easily on the board itself, which is a good alternate to building application specific chips. The design was done considering the timing requirements and user feasibility by trying to control the complete circuit with one 50MHz clock.

10

The difference between the two designs implemented is that the Microcontroller design was done entirely on the FPGA chip, whereas the Microprocessor uses a NIOS II processor and a Hardware Abstraction Layer to make the job easier for the programmer.

1) Microcontroller Design
High Level Design

Fig 4. High Level Design of MicroController

The Microcontroller takes in input from a fibre optic bus receiver that receives a signal reporting the status of each module. Other input is from the user to control the functionality of the system. The top_module is a top level circuit that has 2 functions 1) Take initial input and give final output of the setup(provide a black box for the system)

11

2) Connect internal wires to appropriate blocks that perform specific functions The design gives importance to reusability and flexibility. The design uses the module feature to repeat the logic units for each GPIO separately. The logic units hold all the parameters of that port. All inputs are displayed by blue arrows and outputs by red. The model is hierarchical with the top_module branching out to other sub-modules to perform certain functions. IR Receiver module The module receives a signal called IRDA_RXD from the remote controller. The signal is encoded in the following fashion,

Fig 5. The transmitting frame of the IR remote controller

When the IR receiver situated on the DE2 board receives the initial lead bit from the remote, it looks for the code in the remaining bits according to the above format. The module basically decodes the signal and returns the 8-bit hexadecimal key code to the top_module. The circuit design of the IR module was,

12

Fig 6. RTL (Register transfer level) view of module

Logic unit The logic unit circuit is instantiated multiple times in this program, once for each Marx cell. It controls the individual parameter for that cell along with the accompanying logic. This helps in individual control of each module. It can also help if we want to remove a particular module from the system.

Fig 7. RTL (Register transfer level) view of logic_unit module

13

Top_module The top_module controls all the input and output signals and sends them to their appropriate circuits. It decides the appropriate output on the GPIO pins and the menu program on the 7 segment hexadecimal LEDs. Menu Navigation Button Power Menu 1 2 3 State System on/off Menu activated Toggle all pins Select pin Edit parameter Display ABCD/0000 0A ALL/OFF DATA/DONE SEL/DATA/DONE

2) Microprocessor based design


The NIOS II CPU has memory locations which can be read/written into. Upon read/write, these locations communicate with the FPGA through a layer called Avalon. This makes it easier to program in C and Assembly and hence, perform higher level functionalities much easier than HDLs in the previous design. It can also handle interrupts.

14

Fig 7.How NIOS II works

High Level Design

Expansion header

Fig 8.High Level Design/Layout of system

The above design made the job of the programmer to communicate with the devices very easy. The user control in this design is achieved through a PS/2 interrupt, and the display is done on a VGA screen. The expansion header is clocked using the timer interrupt. All programming is done efficiently in C and Assembly.

15

Fig 9. The programming setup

In the C code, each of the peripherals is designated a memory location in hexadecimal format. It is assigned to a volatile pointer of type integer. These can now be used to manipulate the required devices. Using the pointer to the expansion header, we can control the current to the pins. Using the pixel and character buffer, we can manipulate the VGA display, and so on. Added to this, we also have interrupts from the timer and PS/2 keyboard that can be used. Following are the various screenshots of the system at work.

Fig 10. The standby screen(left) and home screen(right)

16

The home screen displays a list of all the cells along with status, pulse width and pulse repetition rate. The menu can be activated by pressing 'M'. Pressing 1) Allows toggling all pins at once 2) Allows toggling selected pin 3) Allows editing pulse width and pulse repetition rate

Fig 10. The standby screen(left) and home screen(right)

17

EXPERIMENTAL DETAILS
Design equipment: Altera DE2-115 Development Board with embedded Cyclone IV E FPGA Altera Terasic IR remote controller and receiver module USB Blaster Oscilloscope to measure GPIO pin output

RESULTS AND DISCUSSION The project was successful in controlling individual pins on the expansion header of the module in both design cases. The design with the Microprocessor was more user friendly as it allowed for easy use of a VGA display and other peripherals in conjunction with the program logic. The Verilog code was more informative from the hardware point of view. The storage and integration of this system can be easily done by housing the FPGA in a safe electromagnetic disturbance proof area and connecting the control system to the Marx cells through fibre optic cables. CONCLUSIONS AND FUTURE SCOPE The control of solid state Marx cells individually becomes important when you need to be sensitive to the disparity between the IGBTs. Even in a single batch, there is quite a fluctuation in the performance of each IGBT. Therefore, in such a case where monitoring these devices is very important to avoid failure, a control system such as the one implemented becomes important in ensuring that all IGBTs operate synchronously.

18

It is recommended to use a development board which provides around 100 pins in the expansion header since we are building a Marx adder with about 80-100 modules. Else, it is also feasible to purchase an FPGA on a single chip and connect it to LV-TTL pins manually to suit our specific situation. However, efficient control of Marx cells can be achieved through FPGAs and this is a good control system for the requirements of this particular project.

19

REFERENCES
Roche, D. S. (n.d.). Solid State Pulsed Power Systems. Nunnally, W.C.; Engel, T.G., "Review of klystron modulator technology for particle accelerators," Pulsed Power Conference, 1999. Digest of Technical Papers. 12th IEEE International , vol.2, no., pp.967,970 vol.2, 27-30 June 1999

DE2 User Manual DE2-115 Media Computer manual My First NIOS II Fundamentals of Digital Logic with Verilog Design by Zvonko G Vranesic

20

APPENDIX A: Calculation of number of clock cycles from pulse width


Frequency of clock on FPGA : 50 MHz Time period of clock = 20 ns Pulse width in terms of number of clock cycles for 250 pulse per second, 10 microsecond pulses 250 pulse per second => Each wave time period = 4000 microseconds = 200000 cycles Therefore, each cycle 500 cycles ON 199500 cycles OFF

**Similar Calculations for variable pulse widths

21

APPENDIX B: Verilog Code


top_module.v
////////////////////////////////////////////////////////////////////////////////// //SQUARE WAVE GENERATION AND IT'S PULSE WIDTH MODULATION by ANSHUMAN SAHOO //DEFAULT PARAMETERS: 5V, 10 MICROSECOND PULSE WIDTH, 250 PULSE PER SECOND ////////////////////////////////////////////////////////////////////////////////// // //

//TOP LEVEL PORT DEFINITIONS module top_module( //////// IR Receiver ////////// IRDA_RXD, //////// VGA ///////////////// VGA_R,VGA_G,VGA_B, VGA_CLK, VGA_BLANK_N, VGA_HS, VGA_VS, VGA_SYNC_N, /////////GPIO//////////////// GPIO, ////////LEDs//////////////// LEDG, LEDR, //////// SEG7 ////////// HEX0, HEX1, HEX2, HEX3, HEX4, HEX5, HEX6, HEX7, ///////SWITCHES//////////// SW, //////KEYS//////////////// KEY, /////CLOCKs////////////// CLOCK_50); //======================================================= // PORT declarations //=======================================================

22

input [17:0]SW; input [3:0]KEY; input CLOCK_50; input IRDA_RXD; output [35:0]GPIO; output [17:0]LEDR; output [7:0]LEDG; output output output output output output output output [6:0] [6:0] [6:0] [6:0] [6:0] [6:0] [6:0] [6:0] HEX0; HEX1; HEX2; HEX3; HEX4; HEX5; HEX6; HEX7;

output [7:0] VGA_R,VGA_G,VGA_B; output VGA_CLK; output VGA_BLANK_N; output VGA_HS; output VGA_VS; output VGA_SYNC_N; //============================================================================= // REG/WIRE declarations //============================================================================= wire data_ready; wire [31:0]hex_data; reg home,menu,allonoff,selectonoff,editparam,selaorb,seldone; reg [8:0]seg76_data; reg [15:0]seg4321_data; reg [35:0]onoroff; reg [35:0] SEL; reg [35:0]selection; reg [35:0] temp; integer ctr; integer pulse_width0; integer pulse_width1; integer pulse_width2; integer pulse_width3; integer pulse_width4; integer pulse_width5; integer pulse_width6; integer pulse_width7; integer pulse_width8; integer pulse_width9; integer pulse_width10; integer pulse_width11; integer pulse_width12; integer pulse_width13; integer pulse_width14; integer pulse_width15; integer pulse_width16; integer pulse_width17; integer pulse_width18; integer pulse_width19; integer pulse_width20; integer pulse_width21; integer pulse_width22; integer pulse_width23;

23
integer pulse_width24; integer pulse_width25; integer pulse_width26; integer pulse_width27; integer pulse_width28; integer pulse_width29; integer pulse_width30; integer pulse_width31; integer pulse_width32; integer pulse_width33; integer pulse_width34; integer pulse_width35; integer select_new; integer pulse_width_new; //============================================================================= // Structural Coding //============================================================================= assign LEDG[3:0] = home; assign HEX4 = 7'b1111111; assign HEX5 = 7'b1111111; assign LEDR[17:0] = onoroff[17:0]; //Takes input of clock and signal from IR and outputs the scan code in hexadecimal value IR_RECEIVE receiver( ///clk 50MHz//// .iCLK(CLOCK_50), //reset .iRST_n(KEY[0]), //IRDA code input .iIRDA(IRDA_RXD), //read command .oDATA_READY(data_ready), //decoded data 32bit .oDATA(hex_data) ); SEG7_LUT SEG7_LUT SEG7_LUT SEG7_LUT SEG7_LUT SEG7_LUT initial begin ctr = 0; onoroff <= 36'd0; select_new = 0; pulse_width_new = 0; home = 0; menu = 0; allonoff = 0; selectonoff = 0; editparam = 0; selaorb = 0; seldone = 0; seg76_data = 0; seg4321_data = 0; pulse_width0= 500; l0 l1 l2 l3 l4 l5 ( HEX7,seg76_data[7:4]); ( HEX6,seg76_data[3:0]); ( HEX3,seg4321_data[15:12]); ( HEX2,seg4321_data[11:8]); ( HEX1,seg4321_data[7:4]); ( HEX0,seg4321_data[3:0]);

24
pulse_width1= 500; pulse_width2= 500; pulse_width3= 500; pulse_width4= 500; pulse_width5= 500; pulse_width6= 500; pulse_width7= 500; pulse_width8= 500; pulse_width9= 500; pulse_width10= 500; pulse_width11= 500; pulse_width12= 500; pulse_width13= 500; pulse_width14= 500; pulse_width15= 500; pulse_width16= 500; pulse_width17= 500; pulse_width18= 500; pulse_width19= 500; pulse_width20= 500; pulse_width21= 500; pulse_width22= 500; pulse_width23= 500; pulse_width24= 500; pulse_width25= 500; pulse_width26= 500; pulse_width27= 500; pulse_width28= 500; pulse_width29= 500; pulse_width30= 500; pulse_width31= 500; pulse_width32= 500; pulse_width33= 500; pulse_width34= 500; pulse_width35= 500; end always@ (posedge IRDA_RXD) begin if(home == 0 && hex_data[23:16] == 8'h12 && data_ready) begin home = 1; seg4321_data = 16'habcd; end else if(home == 1 && hex_data[23:16] == 8'h12 && data_ready ) begin onoroff <= 36'd0; select_new = 0; pulse_width_new = 0; home = 0; menu = 0; allonoff = 0; selectonoff = 0; editparam = 0; selaorb = 0; seldone = 0; seg76_data = 0; seg4321_data = 0; pulse_width0= 500; pulse_width1= 500; pulse_width2= 500; pulse_width3= 500; pulse_width4= 500; pulse_width5= 500; pulse_width6= 500; pulse_width7= 500;

25
pulse_width8= 500; pulse_width9= 500; pulse_width10= 500; pulse_width11= 500; pulse_width12= 500; pulse_width13= 500; pulse_width14= 500; pulse_width15= 500; pulse_width16= 500; pulse_width17= 500; pulse_width18= 500; pulse_width19= 500; pulse_width20= 500; pulse_width21= 500; pulse_width22= 500; pulse_width23= 500; pulse_width24= 500; pulse_width25= 500; pulse_width26= 500; pulse_width27= 500; pulse_width28= 500; pulse_width29= 500; pulse_width30= 500; pulse_width31= 500; pulse_width32= 500; pulse_width33= 500; pulse_width34= 500; pulse_width35= 500; end else if(home == 1 && hex_data[23:16] == 8'h11 && data_ready ) begin menu = 1; seg76_data = 8'h0a; seg4321_data = 0; allonoff = 0; selectonoff = 0; editparam = 0; selaorb = 0; seldone = 0; end else if(menu == 1 && home == 1 && hex_data[23:16] == 8'h01 && data_ready && !selectonoff) begin allonoff = 1; seg76_data = 8'h01; seg4321_data = 16'hda7a; end else if(allonoff == 1 && menu == 1 && home == 1 && hex_data[23:16] == 8'h17 && data_ready && !selectonoff) begin if(onoroff == 36'b111111111111111111111111111111111111) begin onoroff <= 0; seg4321_data = 16'h00ff; end else if(onoroff == 0) begin onoroff <= 36'b111111111111111111111111111111111111; seg4321_data = 16'h0a11; end else begin onoroff <= 36'b111111111111111111111111111111111111; seg4321_data = 16'h0a11; end allonoff = 0; end else if(menu == 1 && home == 1 && hex_data[23:16] == 8'h02 && data_ready) begin

26
selectonoff = 1; seg76_data = 8'h02; seg4321_data = 16'hda7a; end else if(selectonoff == 1 && menu == 1 && home == 1 && hex_data[23:16] != 8'h17 && data_ready && hex_data[23:16] <= 8'h09) begin select_new <= select_new*10 + hex_data[23:16]; seg4321_data = select_new[15:0]; end else if(selectonoff == 1 && menu == 1 && home == 1 && hex_data[23:16] == 8'h17 && data_ready) begin if(select_new < 36) begin if (select_new == 0) SEL[35:0] <= 36'b000000000000000000000000000000000001; else if (select_new == 1) SEL[35:0] <= 36'b000000000000000000000000000000000010; else if (select_new == 2) SEL[35:0] <= 36'b000000000000000000000000000000000100; else if (select_new == 3) SEL[35:0] <= 36'b000000000000000000000000000000001000; else if (select_new == 4) SEL[35:0] <= 36'b000000000000000000000000000000010000; else if (select_new == 5) SEL[35:0] <= 36'b000000000000000000000000000000100000; else if (select_new == 6) SEL[35:0] <= 36'b000000000000000000000000000001000000; else if (select_new == 7) SEL[35:0] <= 36'b000000000000000000000000000010000000; else if (select_new == 8) SEL[35:0] <= 36'b000000000000000000000000000100000000; else if (select_new == 9) SEL[35:0] <= 36'b000000000000000000000000001000000000; else if (select_new == 10) SEL[35:0] <= 36'b000000000000000000000000010000000000; else if (select_new == 11) SEL[35:0] <= 36'b000000000000000000000000100000000000; else if (select_new == 12) SEL[35:0] <= 36'b000000000000000000000001000000000000; else if (select_new == 13) SEL[35:0] <= 36'b000000000000000000000010000000000000; else if (select_new == 14) SEL[35:0] <= 36'b000000000000000000000100000000000000; else if (select_new == 15) SEL[35:0] <= 36'b000000000000000000001000000000000000; else if (select_new == 16) SEL[35:0] <= 36'b000000000000000000010000000000000000; else if (select_new == 17) SEL[35:0] <= 36'b000000000000000000100000000000000000; else if (select_new == 18) SEL[35:0] <= 36'b000000000000000001000000000000000000; else if (select_new == 19) SEL[35:0] <= 36'b000000000000000010000000000000000000; else if (select_new == 20) SEL[35:0] <= 36'b000000000000000100000000000000000000; else if (select_new == 21) SEL[35:0] <= 36'b000000000000001000000000000000000000; else if (select_new == 22) SEL[35:0] <= 36'b000000000000010000000000000000000000; else if (select_new == 23) SEL[35:0] <= 36'b000000000000100000000000000000000000; else if (select_new == 24) SEL[35:0] <= 36'b000000000001000000000000000000000000; else if (select_new == 25) SEL[35:0] <= 36'b000000000010000000000000000000000000; else if (select_new == 26) SEL[35:0] <= 36'b000000000100000000000000000000000000; else if (select_new == 27) SEL[35:0] <= 36'b000000001000000000000000000000000000;

27
else if (select_new == 28) SEL[35:0] <= 36'b000000010000000000000000000000000000; else if (select_new == 29) SEL[35:0] <= 36'b000000100000000000000000000000000000; else if (select_new == 30) SEL[35:0] <= 36'b000001000000000000000000000000000000; else if (select_new == 31) SEL[35:0] <= 36'b000010000000000000000000000000000000; else if (select_new == 32) SEL[35:0] <= 36'b000100000000000000000000000000000000; else if (select_new == 33) SEL[35:0] <= 36'b001000000000000000000000000000000000; else if (select_new == 34) SEL[35:0] <= 36'b010000000000000000000000000000000000; else if (select_new == 35) SEL[35:0] <= 36'b100000000000000000000000000000000000; select_new <= 0; temp <= onoroff; temp <= temp | SEL; if(onoroff == temp) onoroff <= onoroff & ~SEL; else onoroff <= temp; end else begin seg4321_data = 16'he770; select_new <= 0; end selectonoff = 0; end else if(menu == 1 && home == 1 && hex_data[23:16] == 8'h03 && data_ready) begin editparam = 1; seg76_data = 8'h03; seg4321_data = 16'h5e1; end else if(editparam == 1 && menu == 1 && home == 1 && hex_data[23:16] == 8'h0f && data_ready) begin seg4321_data = 16'hda7a; selaorb = 0; end else if(editparam == 1 && menu == 1 && home == 1 && hex_data[23:16] == 8'h13 && data_ready) begin seg4321_data = 16'hda7a; selaorb = 1; end else if(editparam == 1 && menu == 1 && home == 1 && selaorb == 0 && hex_data[23:16] != 8'h17 && data_ready && hex_data[23:16] <= 8'h09) begin pulse_width_new <= pulse_width_new*10 + hex_data[23:16]; seg4321_data = pulse_width_new[15:0]; end else if(editparam == 1 && menu == 1 && home == 1 && selaorb == 0 && hex_data[23:16] == 8'h17 && data_ready) begin seg4321_data = 16'hd07e; pulse_width0= pulse_width_new; pulse_width1= pulse_width_new; pulse_width2= pulse_width_new; pulse_width3= pulse_width_new; pulse_width4= pulse_width_new; pulse_width5= pulse_width_new; pulse_width6= pulse_width_new; pulse_width7= pulse_width_new; pulse_width8= pulse_width_new; pulse_width9= pulse_width_new;

28
pulse_width10= pulse_width_new; pulse_width11= pulse_width_new; pulse_width12= pulse_width_new; pulse_width13= pulse_width_new; pulse_width14= pulse_width_new; pulse_width15= pulse_width_new; pulse_width16= pulse_width_new; pulse_width17= pulse_width_new; pulse_width18= pulse_width_new; pulse_width19= pulse_width_new; pulse_width20= pulse_width_new; pulse_width21= pulse_width_new; pulse_width22= pulse_width_new; pulse_width23= pulse_width_new; pulse_width24= pulse_width_new; pulse_width25= pulse_width_new; pulse_width26= pulse_width_new; pulse_width27= pulse_width_new; pulse_width28= pulse_width_new; pulse_width29= pulse_width_new; pulse_width30= pulse_width_new; pulse_width31= pulse_width_new; pulse_width32= pulse_width_new; pulse_width33= pulse_width_new; pulse_width34= pulse_width_new; pulse_width35= pulse_width_new; editparam = 0; end else if(editparam == 1 && menu == 1 && home == 1 && selaorb == 1 && data_ready) begin if(hex_data[23:16] != 8'h17 && seldone == 0) begin select_new <= select_new*10 + hex_data[23:16]; seg4321_data = select_new[15:0]; end else if(hex_data[23:16] == 8'h17) begin seldone = 1; seg4321_data = 16'hda7a; end if(hex_data[23:16] != 8'h17 && seldone == 1) begin pulse_width_new <= pulse_width_new*10 + hex_data[23:16]; seg4321_data = pulse_width_new[15:0]; end else if(hex_data[23:16] == 8'h17 && seldone == 1) begin seg4321_data = 16'hd07e; if (select_new == 0) pulse_width0= pulse_width_new; else if (select_new == 1) pulse_width1= pulse_width_new; else if (select_new == 2) pulse_width2= pulse_width_new; else if (select_new == 3) pulse_width3= pulse_width_new; else if (select_new == 4) pulse_width4= pulse_width_new; else if (select_new == 5) pulse_width5= pulse_width_new; else if (select_new == 6) pulse_width6= pulse_width_new; else if (select_new == 7) pulse_width7= pulse_width_new; else if (select_new == 8) pulse_width8= pulse_width_new; else if (select_new == 9)

29
pulse_width9= pulse_width_new; else if (select_new == 10) pulse_width10= pulse_width_new; else if (select_new == 11) pulse_width11= pulse_width_new; else if (select_new == 12) pulse_width12= pulse_width_new; else if (select_new == 13) pulse_width13= pulse_width_new; else if (select_new == 14) pulse_width14= pulse_width_new; else if (select_new == 15) pulse_width15= pulse_width_new; else if (select_new == 16) pulse_width16= pulse_width_new; else if (select_new == 17) pulse_width17= pulse_width_new; else if (select_new == 18) pulse_width18= pulse_width_new; else if (select_new == 19) pulse_width19= pulse_width_new; else if (select_new == 20) pulse_width20= pulse_width_new; else if (select_new == 21) pulse_width21= pulse_width_new; else if (select_new == 22) pulse_width22= pulse_width_new; else if (select_new == 23) pulse_width23= pulse_width_new; else if (select_new == 24) pulse_width24= pulse_width_new; else if (select_new == 25) pulse_width25= pulse_width_new; else if (select_new == 26) pulse_width26= pulse_width_new; else if (select_new == 27) pulse_width27= pulse_width_new; else if (select_new == 28) pulse_width28= pulse_width_new; else if (select_new == 29) pulse_width29= pulse_width_new; else if (select_new == 30) pulse_width30= pulse_width_new; else if (select_new == 31) pulse_width31= pulse_width_new; else if (select_new == 32) pulse_width32= pulse_width_new; else if (select_new == 33) pulse_width33= pulse_width_new; else if (select_new == 34) pulse_width34= pulse_width_new; else if (select_new == 35) pulse_width35= pulse_width_new; editparam = 0; end end end

logic_unit u0(CLOCK_50,SW[0], onoroff[0], pulse_width0, ctr, GPIO[0]); logic_unit u1(CLOCK_50,SW[0], onoroff[1], pulse_width1,ctr, GPIO[1]); logic_unit u2(CLOCK_50,SW[0], onoroff[2], pulse_width2,ctr, GPIO[2]); logic_unit u3(CLOCK_50,SW[0], onoroff[3], pulse_width3,ctr, GPIO[3]); logic_unit u4(CLOCK_50,SW[0], onoroff[4], pulse_width4, ctr, GPIO[4]); logic_unit u5(CLOCK_50,SW[0], onoroff[5], pulse_width5, ctr, GPIO[5]); logic_unit u6(CLOCK_50,SW[0], onoroff[6], pulse_width6,ctr, GPIO[6]); logic_unit u7(CLOCK_50,SW[0], onoroff[7], pulse_width7,ctr, GPIO[7]);

30
logic_unit u8(CLOCK_50,SW[0], onoroff[8], pulse_width8,ctr, GPIO[8]); logic_unit u9(CLOCK_50,SW[0], onoroff[9], pulse_width9, ctr,GPIO[9]); logic_unit u10(CLOCK_50,SW[0], onoroff[10], pulse_width10,ctr, GPIO[10]); logic_unit u11(CLOCK_50,SW[0], onoroff[11], pulse_width11,ctr, GPIO[11]); logic_unit u12(CLOCK_50,SW[0], onoroff[12], pulse_width12,ctr, GPIO[12]); logic_unit u13(CLOCK_50,SW[0], onoroff[13], pulse_width13,ctr, GPIO[13]); logic_unit u14(CLOCK_50,SW[0], onoroff[14], pulse_width14,ctr, GPIO[14]); logic_unit u15(CLOCK_50,SW[0], onoroff[15], pulse_width15,ctr, GPIO[15]); logic_unit u16(CLOCK_50,SW[0], onoroff[16], pulse_width16,ctr, GPIO[16]); logic_unit u17(CLOCK_50,SW[0], onoroff[17], pulse_width17,ctr, GPIO[17]); logic_unit u18(CLOCK_50,SW[0], onoroff[18], pulse_width18,ctr, GPIO[18]); logic_unit u19(CLOCK_50,SW[0], onoroff[19], pulse_width19,ctr, GPIO[19]); logic_unit u20(CLOCK_50,SW[0], onoroff[20], pulse_width20,ctr, GPIO[20]); logic_unit u21(CLOCK_50,SW[0], onoroff[21], pulse_width21, ctr,GPIO[21]); logic_unit u22(CLOCK_50,SW[0], onoroff[22], pulse_width22, ctr,GPIO[22]); logic_unit u23(CLOCK_50,SW[0], onoroff[23], pulse_width23, ctr,GPIO[23]); logic_unit u24(CLOCK_50,SW[0], onoroff[24], pulse_width24, ctr,GPIO[24]); logic_unit u25(CLOCK_50,SW[0], onoroff[25], pulse_width25, ctr,GPIO[25]); logic_unit u26(CLOCK_50,SW[0], onoroff[26], pulse_width26, ctr,GPIO[26]); logic_unit u27(CLOCK_50,SW[0], onoroff[27], pulse_width27, ctr,GPIO[27]); logic_unit u28(CLOCK_50,SW[0], onoroff[28], pulse_width28, ctr,GPIO[28]); logic_unit u29(CLOCK_50,SW[0], onoroff[29], pulse_width29, ctr,GPIO[29]); logic_unit u30(CLOCK_50,SW[0], onoroff[30], pulse_width30, ctr,GPIO[30]); logic_unit u31(CLOCK_50,SW[0], onoroff[31], pulse_width31, ctr,GPIO[31]); logic_unit u32(CLOCK_50,SW[0], onoroff[32], pulse_width32, ctr,GPIO[32]); logic_unit u33(CLOCK_50,SW[0], onoroff[33], pulse_width33, ctr,GPIO[33]); logic_unit u34(CLOCK_50,SW[0], onoroff[34], pulse_width34, ctr,GPIO[34]); logic_unit u35(CLOCK_50,SW[0], onoroff[35], pulse_width35, ctr,GPIO[35]); always@ (posedge CLOCK_50) begin if(ctr > 200000) ctr <= 0; else ctr <= ctr + 1; end /* //Video Controller// vga_controller controller( .screen_number(screen_number), .iRST_n(DLY_RST), .iVGA_CLK(VGA_CTRL_CLK), .oBLANK_n(VGA_BLANK_N), .oHS(VGA_HS), .oVS(VGA_VS), .b_data(VGA_B), .g_data(VGA_G), .r_data(VGA_R)); */ endmodule

IR_RECEIVE.v
module IR_RECEIVE( iCLK, //clk 50MHz iRST_n, //reset iIRDA, //IR code input oDATA_READY, //data ready oDATA //decode data output ); //======================================================= // PARAMETER declarations

31
//======================================================= parameter IDLE = 2'b00; //always high voltage level parameter GUIDANCE = 2'b01; //9ms low voltage and 4.5 ms high voltage parameter DATAREAD = 2'b10; //0.6ms low voltage start and with 0.52ms high voltage is 0,with 1.66ms high voltage is 1, 32bit in sum. parameter IDLE_HIGH_DUR = 262143; // data_count 262143*0.02us = 5.24ms, threshold for DATAREAD-----> IDLE parameter GUIDE_LOW_DUR = 230000; // idle_count 230000*0.02us = 4.60ms, threshold for IDLE--------->GUIDANCE parameter GUIDE_HIGH_DUR = 210000; // state_count 210000*0.02us = 4.20ms, 4.5-4.2 = 0.3ms < BIT_AVAILABLE_DUR = 0.4ms,threshold for GUIDANCE------->DATAREAD parameter DATA_HIGH_DUR = 41500; // data_count 41500 *0.02us = 0.83ms, sample time from the posedge of iIRDA parameter BIT_AVAILABLE_DUR = 20000; // data_count 20000 *0.02us = 0.4ms, the sample bit pointer,can inhibit the interference from iIRDA signal //======================================================= // PORT declarations //======================================================= input iCLK; //input clk,50MHz input iRST_n; //rst input iIRDA; //Irda RX output decoded data output oDATA_READY; //data ready output [31:0] oDATA; //output data,32bit //======================================================= // Signal Declarations //======================================================= reg [31:0] oDATA; //data output reg reg [17:0] idle_count; //idle_count counter works under data_read state reg idle_count_flag; //idle_count conter flag //wire idle_count_max; reg [17:0] state_count; //state_count counter works under guide state reg state_count_flag; //state_count conter flag reg [17:0] data_count; //data_count counter works under data_read state reg data_count_flag; //data_count conter flag reg [5:0] bitcount; //sample bit pointer reg [1:0] state; //state reg reg [31:0] data; //data reg reg [31:0] data_buf; //data buf reg data_ready; //data ready flag //======================================================= // Structural coding //======================================================= assign oDATA_READY = data_ready; //idle counter works on iclk under IDLE state only always @(posedge iCLK or negedge iRST_n) if (!iRST_n) idle_count <= 0; else if (idle_count_flag) //the counter works when the flag is 1 idle_count <= idle_count + 1'b1; else idle_count <= 0; //the counter resets when the flag is 0 //idle counter switch when iIRDA is low under IDLE state always @(posedge iCLK or negedge iRST_n) if (!iRST_n) idle_count_flag <= 1'b0; else if ((state == IDLE) && !iIRDA) idle_count_flag <= 1'b1; else idle_count_flag <= 1'b0; //state counter works on iclk under GUIDE state only always @(posedge iCLK or negedge iRST_n) if (!iRST_n) state_count <= 0;

32
else if (state_count_flag) //the counter works when the flag is 1 state_count <= state_count + 1'b1; else state_count <= 0; //the counter resets when the flag is 0 //state counter switch when iIRDA is high under GUIDE state always @(posedge iCLK or negedge iRST_n) if (!iRST_n) state_count_flag <= 1'b0; else if ((state == GUIDANCE) && iIRDA) state_count_flag <= 1'b1; else state_count_flag <= 1'b0; //data read decode counter based on iCLK always @(posedge iCLK or negedge iRST_n) if (!iRST_n) data_count <= 1'b0; else if(data_count_flag) //the counter works when the flag is 1 data_count <= data_count + 1'b1; else data_count <= 1'b0; //the counter resets when the flag is 0 //data counter switch always @(posedge iCLK or negedge iRST_n) if (!iRST_n) data_count_flag <= 0; else if ((state == DATAREAD) && iIRDA) data_count_flag <= 1'b1; else data_count_flag <= 1'b0; //data reg pointer counter always @(posedge iCLK or negedge iRST_n) if (!iRST_n) bitcount <= 6'b0; else if (state == DATAREAD) begin if (data_count == 20000) bitcount <= bitcount + 1'b1; //add 1 when iIRDA posedge end else bitcount <= 6'b0; //state change between IDLE,GUIDE,DATA_READ according to irda edge or counter always @(posedge iCLK or negedge iRST_n) if (!iRST_n) state <= IDLE; else case (state) IDLE : if (idle_count > GUIDE_LOW_DUR) // state chang from IDLE to Guidance when detect the negedge and the low voltage last for > 4.6ms state <= GUIDANCE; GUIDANCE : if (state_count > GUIDE_HIGH_DUR)//state change from GUIDANCE to DATAREAD when detect the posedge and the high voltage last for > 4.2ms state <= DATAREAD; DATAREAD : if ((data_count >= IDLE_HIGH_DUR) || (bitcount >= 33)) state <= IDLE; default : state <= IDLE; //default endcase //data decode base on the value of data_count always @(posedge iCLK or negedge iRST_n) if (!iRST_n) data <= 0; else if (state == DATAREAD) begin if (data_count >= DATA_HIGH_DUR) //2^15 = 32767*0.02us = 0.64us data[bitcount-1'b1] <= 1'b1; //>0.52ms sample the bit 1 end

33
else data <= 0; //set the data_ready flag always @(posedge iCLK or negedge iRST_n) if (!iRST_n) data_ready <= 1'b0; else if (bitcount == 32) begin if (data[31:24] == ~data[23:16]) begin data_buf <= data; //fetch the value to the databuf from the data reg data_ready <= 1'b1; //set the data ready flag end else data_ready <= 1'b0 ; //data error end else data_ready <= 1'b0 ; //read data always @(posedge iCLK or negedge iRST_n) if (!iRST_n) oDATA <= 32'b0000; else if (data_ready) oDATA <= data_buf; //output endmodule

logic_unit.v
module logic_unit(clk,switch,keepon, pulse_width, ctr, port); input clk; input keepon; input [31:0]pulse_width; input [31:0]ctr; input switch; output reg port = 0;

always @(negedge clk) begin if(keepon == 1 || switch) begin if(ctr > 0 && ctr < pulse_width) begin port = 1; end if(ctr > pulse_width && ctr < 200000) begin port = 0; end if (ctr > 200000) begin port = 0; end end

end endmodule

SEG7_LUT.v
module SEG7_LUT( input [3:0] output [6:0] reg oSEG,iDIG iDIG; oSEG; [6:0] oSEG; );

34
always @(iDIG) begin case(iDIG) 4'h1: oSEG = 7'b1111001; 4'h2: oSEG = 7'b0100100; 4'h3: oSEG = 7'b0110000; 4'h4: oSEG = 7'b0011001; 4'h5: oSEG = 7'b0010010; 4'h6: oSEG = 7'b0000010; 4'h7: oSEG = 7'b1111000; 4'h8: oSEG = 7'b0000000; 4'h9: oSEG = 7'b0011000; 4'ha: oSEG = 7'b0001000; 4'hb: oSEG = 7'b0000011; 4'hc: oSEG = 7'b1000110; 4'hd: oSEG = 7'b0100001; 4'he: oSEG = 7'b0000110; 4'hf: oSEG = 7'b0001110; 4'h0: oSEG = 7'b1000000; endcase end endmodule // ---t---// | | // lt rt // | | // ---m---// | | // lb rb // | | // ---b----

vga_controller.v
module vga_controller( screen_number, iRST_n, iVGA_CLK, oBLANK_n, oHS, oVS, b_data, g_data, r_data); input screen_number; input iRST_n; input iVGA_CLK; output reg oBLANK_n; output reg oHS; output reg oVS; output [7:0] b_data; output [7:0] g_data; output [7:0] r_data; ///////// //// reg [18:0] ADDR; reg [23:0] bgr_data; reg [7:0] indexst; wire VGA_CLK_n; wire [7:0] index,index1,index2; wire [23:0] bgr_data_raw; wire cBLANK_n,cHS,cVS,rst; //// assign rst = ~iRST_n; video_sync_generator LTM_ins (.vga_clk(iVGA_CLK), .reset(rst), .blank_n(cBLANK_n), .HS(cHS), .VS(cVS)); //// ////Addresss generator always@(posedge iVGA_CLK,negedge iRST_n) begin if (!iRST_n) ADDR<=19'd0; else if (cHS==1'b0 && cVS==1'b0) ADDR<=19'd0;

35
else if (cBLANK_n==1'b1) ADDR<=ADDR+ 19'd1; end ////////////////////////// //////INDEX addr. assign VGA_CLK_n = ~iVGA_CLK; assign index = indexst; background_img_dataimg_data_inst ( .address ( ADDR ), .clock ( VGA_CLK_n ), .q ( index1 ) ); menu_select_img_data inst2 ( .address ( ADDR ), .clock ( VGA_CLK_n ), .q ( index2 ) ); always @(posedge iVGA_CLK) begin if(screen_number == 0) indexst = index1; else if(screen_number == 1) indexst = index2; end //////Color table output img_index img_index_inst ( .address ( index ), .clock ( iVGA_CLK ), .q ( bgr_data_raw) ); ////// //////latch valid data at falling edge; always@(posedge VGA_CLK_n) bgr_data <= bgr_data_raw; assign b_data = bgr_data[23:16]; assign g_data = bgr_data[15:8]; assign r_data = bgr_data[7:0]; /////////////////// //////Delay the iHD, iVD,iDEN for one clock cycle; always@(negedge iVGA_CLK) begin oHS<=cHS; oVS<=cVS; oBLANK_n<=cBLANK_n; end endmodule

riseandfalltime.v
//Module that takes in a select signal and outputs required delay module riseandfalltime(clk, pulse_width, select_channel, delay_value, stop_signal); input [35:0]select_channel; //channel selected. In case of moving to t < 0 space, invert signal. input [7:0]delay_value; //value in number of pulses that are needed to be delayed input clk; // CLOCK_50 input [31:0]pulse_width; // current pulse width of the required channel output reg [35:0] stop_signal = 36'b111111111111111111111111111111111111; //output override to rearrange GPIO signal according to requirement integer counter = 0; always@ (posedge clk) begin

36
if(counter <= delay_value) begin stop_signal <= ~select_channel & stop_signal; counter <= counter + 1; end else begin counter <= 0; end end endmodule

APPENDIX C: ASSEMBLY AND C CODE


Main.c
/******************************************************************************** PULSE GENERATOR CONTROL ********************************************************************************/ void write_pixel(int x, int y, int colour); void clear_screen(); void write_char(int x, int y, char c); void display_welcome_screen(); void display_menu(); void display_status(int *status); void highlight_menu(int onoff); void display_parameters(int params[2][32]); void edit_param(int params[2][32]); int choose_pin(); int main(void) { /* Declare volatile pointers to I/O registers (volatile means that IO load and store instructions (e.g., ldwio, stwio) will be used to access these pointer locations) */ volatile int * red_LED_ptr = (int *) 0x10000000; // red LED address volatile int * green_LED_ptr = (int *) 0x10000010; // green LED address volatile int * HEX3_HEX0_ptr = (int *) 0x10000020; // HEX3_HEX0 address volatile int * HEX7_HEX4_ptr = (int *) 0x10000030; // HEX7_HEX4 address volatile int * SW_switch_ptr = (int *) 0x10000040; // SW slider switch address volatile int * KEY_ptr = (int *) 0x10000050; // pushbutton KEY address volatile int * JP5_ptr = (int *) 0x10000060; // GPIO pins volatile int * pixelbuffer_ptr = (int *) 0x08000000; // Pixel Buffer volatile int * charbuffer_ptr = (int *) 0x09000000; // Character Buffer volatile int * TIMERSR_ptr = (int *) 0x10002000; // Timer Status Register volatile int * TIMERCR_ptr = (int *) 0x10002004; // Timer Control Register volatile int * PS2_ptr = (int *) 0x10000100; // PS/2 port address int HEX_bits = 0x0000000F; // pattern for HEX displays int SW_value, KEY_value, delay_count; int status[32]; int params[2][32]; //params[0] = pulse width. params[1] = pulse repetition rate int i; char inp; int select_pin; for(i = 0; i <32; i = i+1) status[i] = 0; for(i = 0; i < 32; i++){ params[0][i] = 500; params[1][i] = 250;

37
} //enable_interrupts(); display_welcome_screen(); while(1){ if(POLL() == '\n'){ clear_screen(); display_menu(); break; } } display_status(status); display_parameters(params); while(1){ while(1){ inp = POLL(); if(inp == 'm' || inp == 'M'){ highlight_menu(1); break; } } while(1){ inp = POLL(); if(inp == '1'){ highlight_menu(0); for(i = 0; i <32; i = i+1) status[i] = ~status[i]; display_status(status); //toggle_state(status, params); break; } else if(inp == '2'){ select_pin = choose_pin(); status[select_pin - 1] = ~status[select_pin - 1]; display_status(status); break; } else if(inp == '3'){ edit_param(params); break; } else if(inp == 'm' || inp == 'M'){ highlight_menu(0); break; } } } return 0; }

POLL.s
.text .align 2 .global POLL

38
POLL: movia r7, 0x10001000 /* r7 now contains the base address */ ldwio r2, 0(r7) /* Load from the JTAG */ andi r3, r2, 0x8000 /* Mask other bits */ beq r3, r0, POLL /* If this is 0 (branch true), data is not valid */ andi r2,r2,0xff ret

display_welcome_screen.c

/* set a single pixel on the screen at x,y * x in [0,319], y in [0,239], and colour in [0,65535] */ void write_pixel(int x, int y, int colour) { volatile short *vga_addr=(volatile int*)(0x08000000 + (y<<10) + (x<<1)); *vga_addr=colour; } /* use write_pixel to set entire screen to black (does not clear the character buffer) */ void clear_screen() { int x, y; for (x = 0; x < 320; x++) { for (y = 0; y < 240; y++) { write_pixel(x,y,0); } } for (x = 0; x < 80; x++) { for (y = 0; y < 60; y++) { write_char(x,y,' '); } } } /* write a single character to the character buffer at x,y * x in [0,79], y in [0,59] */ void write_char(int x, int y, char c) { // VGA character buffer volatile char * character_buffer = (char *) (0x09000000 + (y<<7) + x); *character_buffer = c; } void display_welcome_screen() { clear_screen(); int x,y; //paint screen BLACK for (x = 0; x < 320; x++) { for (y = 0; y < 240; y++) { write_pixel(x,y,0); } } char* hw = "SQUARE WAVE CONTROL"; x = 25; while (*hw) { write_char(x, 10, *hw); x++; hw++; } hw = "ELECTRON BEAM CENTRE, BARC"; x = 25; while (*hw) {

39
write_char(x, 13, *hw); x++; hw++; } hw = "Press Enter to Continue"; x = 25; while (*hw) { write_char(x, 25, *hw); x++; hw++; } } void display_menu(){ int x,y; //paint screen BLACK for (y = 0; y < 240; y++) { x= 2; write_pixel(x,y,0xffff00); } for (y = 0; y < 240; y++) { x= 318; write_pixel(x,y,0xffff00); } for (x = 0; x < 320; x++) { y = 2; write_pixel(x,y,0xffff00); } for (x = 0; x < 320; x++) { y = 238; write_pixel(x,y,0xffff00); } for (y = 0; y < 240; y++) { x= 90; write_pixel(x,y,0xffff00); } char* hw = "MENU(press M)"; x = 5; while (*hw) { write_char(x, 10, *hw); x++; hw++; } hw = "1.SWITCH ALL ON/OFF"; x = 2; while (*hw) { write_char(x, 15, *hw); x++; hw++; } hw = "2.SELECT PINS"; x = 2; while (*hw) { write_char(x, 17, *hw); x++; hw++; }

40
hw = "3.EDIT PARAMETERS"; x = 2; while (*hw) { write_char(x, 19, *hw); x++; hw++; } } void display_status(int *status){ int x,y; char* hw = "PIN 01]"; x = 25; while (*hw) { write_char(x, 5, *hw); x++; hw++; } hw = "PIN 02]"; x = 25; while (*hw) { write_char(x, 7, *hw); x++; hw++; } hw = "PIN 03]"; x = 25; while (*hw) { write_char(x, 9, *hw); x++; hw++; } hw = "PIN 04]"; x = 25; while (*hw) { write_char(x, 11, *hw); x++; hw++; } hw = "PIN 05]"; x = 25; while (*hw) { write_char(x, 13, *hw); x++; hw++; } hw = "PIN 06]"; x = 25; while (*hw) { write_char(x, 15, *hw); x++; hw++; } hw = "PIN 07]"; x = 25; while (*hw) { write_char(x, 17, *hw); x++; hw++; } hw = "PIN 08]";

41
x = 25; while (*hw) { write_char(x, 19, *hw); x++; hw++; } hw = "PIN 09]"; x = 25; while (*hw) { write_char(x, 21, *hw); x++; hw++; } hw = "PIN 10]"; x = 25; while (*hw) { write_char(x, 23, *hw); x++; hw++; } hw = "PIN 11]"; x = 25; while (*hw) { write_char(x, 25, *hw); x++; hw++; } hw = "PIN 12]"; x = 25; while (*hw) { write_char(x, 27, *hw); x++; hw++; } hw = "PIN 13]"; x = 25; while (*hw) { write_char(x, 29, *hw); x++; hw++; } hw = "PIN 14]"; x = 25; while (*hw) { write_char(x, 31, *hw); x++; hw++; } hw = "PIN 25]"; x = 25; while (*hw) { write_char(x, 33, *hw); x++; hw++; } hw = "PIN 16]"; x = 25; while (*hw) { write_char(x, 35, *hw); x++; hw++; }

42

hw = "PIN 17]"; x = 55; while (*hw) { write_char(x, 5, *hw); x++; hw++; } hw = "PIN 18]"; x = 55; while (*hw) { write_char(x, 7, *hw); x++; hw++; } hw = "PIN 19]"; x = 55; while (*hw) { write_char(x, 9, *hw); x++; hw++; } hw = "PIN 20]"; x = 55; while (*hw) { write_char(x, 11, *hw); x++; hw++; } hw = "PIN 21]"; x = 55; while (*hw) { write_char(x, 13, *hw); x++; hw++; } hw = "PIN 22]"; x = 55; while (*hw) { write_char(x, 15, *hw); x++; hw++; } hw = "PIN 23]"; x = 55; while (*hw) { write_char(x, 17, *hw); x++; hw++; } hw = "PIN 24]"; x = 55; while (*hw) { write_char(x, 19, *hw); x++; hw++; } hw = "PIN 25]"; x = 55; while (*hw) { write_char(x, 21, *hw); x++;

43
hw++; } hw = "PIN 26]"; x = 55; while (*hw) { write_char(x, 23, *hw); x++; hw++; } hw = "PIN 27]"; x = 55; while (*hw) { write_char(x, 25, *hw); x++; hw++; } hw = "PIN 28]"; x = 55; while (*hw) { write_char(x, 27, *hw); x++; hw++; } hw = "PIN 29]"; x = 55; while (*hw) { write_char(x, 29, *hw); x++; hw++; } hw = "PIN 30]"; x = 55; while (*hw) { write_char(x, 31, *hw); x++; hw++; } hw = "PIN 31]"; x = 55; while (*hw) { write_char(x, 33, *hw); x++; hw++; } hw = "PIN 32]"; x = 55; while (*hw) { write_char(x, 35, *hw); x++; hw++; } int i; for(i = 0; i<16; i = i+1){ if(status[i] == 0) hw = "off"; else hw = "on "; x = 35; while (*hw) { write_char(x,(5+i*2), *hw);

44
x++; hw++; } }

for(i = 0; i<16; i = i+1){ if(status[i+16] == 0) hw = "off"; else hw = "on "; x = 65; while (*hw) { write_char(x,(5+i*2), *hw); x++; hw++; } } } void display_parameters(int params[2][32]){ int x,y,temp,temp2; for (x = 91; x < 318; x++) { y = 170; write_pixel(x,y,0xffff00); } char* hw = "DEFAULT PULSE WIDTH(PW): 10000 ns "; x = 25; while (*hw) { write_char(x, 45, *hw); x++; hw++; }

hw = "DEFAULT PULSE REPETITION RATE(PRR): 250 pps "; x = 25; while (*hw) { write_char(x, 47, *hw); x++; hw++; } hw = "PW PRR"; x = 40; while (*hw) { write_char(x, 3, *hw); x++; hw++; } hw = "PW PRR"; x = 70; while (*hw) { write_char(x, 3, *hw); x++; hw++; } int i = 0;

45
int j = 0; for(i = 0; i<16; i++){ temp = params[0][i]; j = 0; while(1){ temp2 = temp % 10; write_char(42-j,5+i*2,temp2+48); j++; temp = temp/10; if(temp == 0) break; } write_char(42-j,5+i*2,' '); temp = params[1][i]; j = 0; while(1){ temp2 = temp % 10; write_char(48-j,5+i*2,temp2+48); j++; temp = temp/10; if(temp == 0) break; } write_char(48-j,5+i*2,' '); } for(i = 0; i<16; i++){ temp = params[0][i+16]; j = 0; while(1){ temp2 = temp % 10; write_char(72-j,5+i*2,temp2+48); j++; temp = temp/10; if(temp == 0) break; } write_char(72-j,5+i*2,' '); temp = params[1][i+16]; j = 0; while(1){ temp2 = temp % 10; write_char(78-j,5+i*2,temp2+48); j++; temp = temp/10; if(temp == 0) break; } write_char(78-j,5+i*2,' '); }

} void highlight_menu(int onoff){ int x,y, color; if(onoff == 0) color = 0; else color = 0xffffff;

46

for (x = 5; x < 88; x++) { y = 50; write_pixel(x,y,color); } for (x = 5; x < 88; x++) { y = 90; write_pixel(x,y,color); } } int choose_pin(){ int x,y; char inp; int pin = 0; char* hw = "Enter the GPIO pin"; x = 2; while (*hw) { write_char(x, 25, *hw); x++; hw++; } hw = "to toggle: "; x = 2; while (*hw) { write_char(x, 27, *hw); x++; hw++; } for (x = 5; x < 88; x++) { y = 160; write_pixel(x,y,0xffffff); } int i = 0; while(1){ inp = POLL(); if(inp == '\n' && pin < 32 && pin > 0) break; else if(pin < 32 && (inp - 48) <= 9){ pin = ((int)inp-48) + pin*10; write_char(5+i,29,inp); i++; } else{ hw = "ERROR: input too big"; x = 2; while (*hw) { write_char(x, 32, *hw); x++; hw++; } pin = 0; if(POLL() == '\n') break; } } hw = " x = 2; while (*hw) { ";

47
write_char(x, 25, *hw); x++; hw++; } hw = " "; x = 2; while (*hw) { write_char(x, 29, *hw); x++; hw++; } hw = " "; x = 2; while (*hw) { write_char(x, 32, *hw); x++; hw++; } for (x = 5; x < 88; x++) { y = 160; write_pixel(x,y,0); } hw = " "; x = 2; while (*hw) { write_char(x, 27, *hw); x++; hw++; } highlight_menu(0); return pin; } void edit_param(int params[2][32]){ int x,y; char inp; char choice = '\0'; int val, pin,i; char* hw = "a)PW(all)"; x = 2; while (*hw) { write_char(x, 25, *hw); x++; hw++; } hw = "b)PRR(all)"; x = 2; while (*hw) { write_char(x, 28, *hw); x++; hw++; } hw = "c)PW(select)"; x = 2; while (*hw) { write_char(x, 31, *hw); x++; hw++; } hw = "d)PRR(select)"; x = 2;

48
while (*hw) { write_char(x, 34, *hw); x++; hw++; } for (x = 5; x < 88; x++) { y = 200; write_pixel(x,y,0xffffff); } while(1){ inp = POLL(); if(inp == 'a' || inp == 'A'){ choice = 'a'; break; } else if(inp == 'b' || inp == 'B'){ choice = 'b'; break; } else if(inp == 'c' || inp == 'C'){ choice = 'c'; break; } else if(inp == 'd' || inp == 'D'){ choice = 'd'; break; } } if(choice == 'a'){ hw = "Enter New Value: x = 2; while (*hw) { write_char(x, 25, *hw); x++; hw++; } hw = " "; x = 2; while (*hw) { write_char(x, 28, *hw); x++; hw++; } hw = " "; x = 2; while (*hw) { write_char(x, 31, *hw); x++; hw++; } hw = " "; x = 2; while (*hw) { write_char(x, 34, *hw); x++; hw++; } i = 0; while(1){ ";

49
inp = POLL(); if(inp == '\n') break; else if((inp - 48) <= 9){ val = ((int)inp-48) + val*10; write_char(5+i,29,inp); i++; } } if(val/20 == 0){ hw = "ERROR: input too small"; x = 2; while (*hw) { write_char(x, 32, *hw); x++; hw++; } } for(i = 0; i<32; i++) params[0][i] = val; display_parameters(params); }

if(choice == 'b'){ hw = "Enter New Value: x = 2; while (*hw) { write_char(x, 25, *hw); x++; hw++; } hw = " "; x = 2; while (*hw) { write_char(x, 28, *hw); x++; hw++; } hw = " "; x = 2; while (*hw) { write_char(x, 31, *hw); x++; hw++; } hw = " "; x = 2; while (*hw) { write_char(x, 34, *hw); x++; hw++; } i = 0; while(1){ inp = POLL(); if(inp == '\n') ";

50
break; else if((inp - 48) <= 9){ val = ((int)inp-48) + val*10; write_char(5+i,29,inp); i++; } }

for(i = 0; i<32; i++) params[1][i] = val; display_parameters(params); }

if(choice == 'c'){ hw = "Enter pin number: "; x = 2; while (*hw) { write_char(x, 25, *hw); x++; hw++; } hw = " "; x = 2; while (*hw) { write_char(x, 28, *hw); x++; hw++; } hw = " "; x = 2; while (*hw) { write_char(x, 31, *hw); x++; hw++; } hw = " "; x = 2; while (*hw) { write_char(x, 34, *hw); x++; hw++; } int i = 0; while(1){ inp = POLL(); if(inp == '\n') break; else if(pin < 32 && (inp - 48) <= 9){ pin = ((int)inp-48) + pin*10; write_char(5+i,29,inp); i++; } } if(pin > 32 || pin == 0){ hw = "ERROR: input too big";

51
x = 2; while (*hw) { write_char(x, 32, *hw); x++; hw++; } if(POLL() == '\n'){ hw = " "; x = 2; while (*hw) { write_char(x, 28, *hw); x++; hw++; } hw = " "; x = 2; while (*hw) { write_char(x, 31, *hw); x++; hw++; } hw = " "; x = 2; while (*hw) { write_char(x, 34, *hw); x++; hw++; } hw = " "; x = 2; while (*hw) { write_char(x, 32, *hw); x++; hw++; } for (x = 5; x < 88; x++) { y = 200; write_pixel(x,y,0); } highlight_menu(0); } } else{ hw = "Enter New Value: x = 2; while (*hw) { write_char(x, 25, *hw); x++; hw++; } hw = " "; x = 2; while (*hw) { write_char(x, 29, *hw); x++; hw++; } i = 0; while(1){ inp = POLL(); if(inp == '\n') ";

52
break; else if((inp - 48) <= 9){ val = ((int)inp-48) + val*10; write_char(5+i,29,inp); i++; } } if(val/20 == 0){ hw = "ERROR:Least size"; x = 2; while (*hw) { write_char(x, 32, *hw); x++; hw++; } hw = "is 20 ns"; x = 2; while (*hw) { write_char(x, 34, *hw); x++; hw++; } if(POLL() == '\n'){ hw = " "; x = 2; while (*hw) { write_char(x, 25, *hw); x++; hw++; } hw = " "; x = 2; while (*hw) { write_char(x, 29, *hw); x++; hw++; } hw = " "; x = 2; while (*hw) { write_char(x, 32, *hw); x++; hw++; } hw = " "; x = 2; while (*hw) { write_char(x, 34, *hw); x++; hw++; } for (x = 5; x < 88; x++) { y = 200; write_pixel(x,y,0); } highlight_menu(0); }

53
} else{ params[0][pin-1] = val; display_parameters(params); } } } if(choice == 'd'){ hw = "Enter pin number: "; x = 2; while (*hw) { write_char(x, 25, *hw); x++; hw++; } hw = " "; x = 2; while (*hw) { write_char(x, 28, *hw); x++; hw++; } hw = " "; x = 2; while (*hw) { write_char(x, 31, *hw); x++; hw++; } hw = " "; x = 2; while (*hw) { write_char(x, 34, *hw); x++; hw++; } int i = 0; while(1){ inp = POLL(); if(inp == '\n') break; else if(pin < 32 && (inp - 48) <= 9){ pin = ((int)inp-48) + pin*10; write_char(5+i,29,inp); i++; } } if(pin > 32 || pin == 0){ hw = "ERROR: input too big"; x = 2; while (*hw) { write_char(x, 32, *hw); x++; hw++; } if(POLL() == '\n'){ hw = " x = 2; while (*hw) { ";

54
write_char(x, 28, *hw); x++; hw++; } hw = " "; x = 2; while (*hw) { write_char(x, 31, *hw); x++; hw++; } hw = " "; x = 2; while (*hw) { write_char(x, 34, *hw); x++; hw++; } for (x = 5; x < 88; x++) { y = 200; write_pixel(x,y,0); } highlight_menu(0); } } else{ hw = "Enter New Value: x = 2; while (*hw) { write_char(x, 25, *hw); x++; hw++; } hw = " "; x = 2; while (*hw) { write_char(x, 29, *hw); x++; hw++; } i = 0; while(1){ inp = POLL(); if(inp == '\n') break; else if((inp - 48) <= 9){ val = ((int)inp-48) + val*10; write_char(5+i,29,inp); i++; } } params[1][pin-1] = val; display_parameters(params); } } ";

55
hw = " "; x = 2; while (*hw) { write_char(x, 32, *hw); x++; hw++; } hw = " "; x = 2; while (*hw) { write_char(x, 28, *hw); x++; hw++; } hw = " "; x = 2; while (*hw) { write_char(x, 31, *hw); x++; hw++; } hw = " "; x = 2; while (*hw) { write_char(x, 34, *hw); x++; hw++; } hw = " "; x = 2; while (*hw) { write_char(x, 29, *hw); x++; hw++; } hw = " "; x = 2; while (*hw) { write_char(x, 25, *hw); x++; hw++; } hw = " "; x = 2; while (*hw) { write_char(x, 27, *hw); x++; hw++; } for (x = 5; x < 88; x++) { y = 200; write_pixel(x,y,0); } highlight_menu(0); }

56

APPENDIX D: NETLIST VIEWERS

57

RTL viewer of Top_module.v

S-ar putea să vă placă și