Our efforts in this project were to create a version of a Microchip mid-range PIC microcontroller in verilog to run on an Altera DE2 board.  It was primarily planned to create a machine that would follow a set of pre-determined instructions and perform computation, interpretation, and control of input and output ports.  In order to prove that there was actually a processor under the hood we decided to have the controller interface with (1) a human user, (2) and LCD display, and (3) control a ship from the Redhawk Duals project.  There is actually action taken on input from all three sources and control output to the LCD and Basic Ship of the duals project.  In an attempt to make writing the code for the controller as easy as possible, the architecture was made to resemble a true PIC so that a C compiler could be used to generate the software interface.


Background of problem:

  The guts of a PIC are comprised of a program counter, instruction decode, ALU, scratch register (Wreg), rom to store the program, ram to store results of computations, and finally special function registers (timers, status of calculations, in/out control, and indirect addressing of ram).  The interplay of the different components is a bit complex but is manageable when taken in small parts.  For example the program counter needed to be able to be updated during a call or goto instruction so the instruction decoder had to interface with it, while at the same time the program counter could be updated like ram by writing to a PCL register of the special function registers also had to interface with the counter.

  Almost all of the instruction words would be needed to be compatible with the compiler, so after building the verilog PIC every instruction would be needed to be simulated and tested with different values to ensure that the PIC acts as expected.  The words not needed are CLRWDT to clear the unimplemented watch-dog timer, RETFIE which is used during returns from interupts which are not implemented, and SLEEP which puts the PIC in low power mode.

The IO ports are 8 bit bidirectional ports that are direction controlled from a TRIS port that determines whether the pins are input or out put, and can control it on a bit by bit basis, or not by requiring the designer to make all 8 bits one direction or another.  So they needed to be built bit by bit, and then grouped into groups of 8 for an 8 bit port.

 Timing is big consideration when designing this PIC because there are four steps in one instruction clock cycle, thus the master clock is 4 times the rate of an instruction cycle.  The pic must decode the instruction word, read the memory to the ALU, execute the operation in the ALU, and finally write back the value to the proper register.  So, all modules work on the master clock and the given “Q-cycle” state of the PIC.  The Instructions in a true PIC are pipe-lined as in the picture below, but our PIC does not quite work this way.  In simulation, the count of the PC at the given time is one count ahead of the execution, but it is only because the PC is incremented at the same time as the instruction word is latched in.


Initial testing showed timing issues with a bidirectional data-bus (dbus) shared with ALU and SFR module.  The clock was adjusted from negative edge (determined before explained in lecture) to positive edge, and all modules only operated on the main clock in not transitions of Q-cycle pules (again a mistake made before lecture explanation).  The shared dbus was scrapped because it caused many timing and data-corruption issues.   


The general purpose ram was originally created using arrays of 8 bit registers.  This was a major disaster that wasn’t realized until late in the project design when the program wasn’t quite running properly on the DE2 board.  As it turned out the optimization of the “Analysis and Synthesis” reported it lost fan-outs and the bulk of the ram was removed.  After getting really nervous that late into the game some internet research guided us into the right direction.  We used the mega-functions of quartus and instantiated a ram module.  It was later modified again to allow dual access for indirect addressing of ram.


After realizing that mega-functions were a viable option, the program rom was reworked and created out of a mega-function to conserve resources of the Cyclone ii.  Both these mega-functions made it possible to increase the size of the program memory and ram to actually mirror a PIC16F877 micro-controller.

The timer1 and timer0 modules are implemented and both can be pre-scaled to allow for different timing intervals.  The timer1 module is actually used for a delay of one second, were the program waits in a loop for the timer1 overflow flag to be set before continuing on.  This turned out to be a fairly accurate delay!


Since it would only take a little modification of the verilog to make it compliant with a true PIC C-compiler the verilog was again updated to make the program look more impressive.  Using the compiler required modifying of PC from ram location to do look up tables for LCD.  Also FSR was used a lot by the compiler to access different ram locations and during initialization code to clear the memory, so that was why the ram mega-function was changed to a dual access module.  Also some ram locations are shared across ram banks are used by compiler and needed to be implemented since they are used to store values when calling functions.


Code from previous PIC projects for writing to LCD was used to test compatibility and to our surprise worked the first time around.  The reason the LCD interface required bi-directional pins was because in the C-code, after writing a value the data port of the LCD is polled to see if the LCD is ready for more data to be written.


The basic ship verilog files needed to be modified to interface with the controller and errors were found when interfacing IO ports with output ports of Basic ship (from Ethernet module).  The quartus program whined about connecting the two inside the chip, so in order for the PIC to interpret data (sensor readings) from the basic ship module the data had to be redirected out the GPIO_0 port of the DE2 board and then wired right back in which was directed to PORTC of the PIC.


After over 100 hours of work (which some how still included last minute scrabbling) the PIC was able to run as a beefed up PIC16F877 with more I/O pins, and the compiler code worked seamlessly which our artificial PIC.  A novice in programing PICs should be able to write a program for a 16F877 and load the code right into this emulated PIC. 


This was a large project and most of the proposal was met requiring over 100 hours for development and testing. Because of last minute scrambles the verilog files may be a bit inefficient or choppy.  If more time was allowed we would breakup the bloated SFR module into separate modules for the individual special function register and make the ram stand alone.  The interrupts that were not implemented could easily be added to allow for interruptible program based on different condition changes.  Also, sleep and watchdog-timer were not implemented but if there were a need for them they also could be added.  The watch-dog timer would require another clock source (typically not in the Mhz range).  SFRs not implemented include TIMER2, USART, and CCP modules which again could easily be added for completeness. Another flaw of this PIC is that SFRs are not accessible from indirect addressing, and this is where it may be beneficial to break up the bulky SFR module and design a way to make this happen.  In conclusion we have met our proposal requirements and are very happy with the knowledge we learned, not only of verilog but of the thought considerations that go into designing a micro-controller.