Go Back

Source code


Name: risc16f84
Created: May 7, 2002
Updated: Jun 29, 2014
SVN Updated: Jun 29, 2014

Other project properties

Category: Processor
Language: Verilog
Development status: Stable
Additional info: Design done , FPGA proven
WishBone Compliant: No
License: Others


The risc16f84 project is intended to provide a small, easy to use microcontroller in Verilog. The original code was VHDL, but I have done a wonderful translation of it into good clean Verilog code. (Well, I think it is wonderful, anyway.) The VHDL code was called "CQPIC" and it was published in 1999 by Sumio Morioka of Japan, in the December 1999 issue of "Transistor Gijutsu Magazine." I did the translation by hand, and then tested the design in actual hardware by running C code on it, and looking for correct behavior. I realize that this is not 100% test coverage, but I have found and fixed several bugs by this method -- including an error in the carry bit logic of the original code! There are four separate versions of the microcontroller presented here. The "original" one is called "risc16f84.v" and it includes all the logic needed to implement the entire 16f84 chip functionality as published in the original article.

However, I have realized over time, that a person using a microcontroller inside of an FPGA does not have the same constraints (i.e. on port sizes, number of pins, multiple functions needed on each pin, etc.) as the original chip designers, and so I have taken liberty in the other three versions, to simplify the logic by removing items that may not be wanted inside of an FPGA or ASIC implementation. For example, there is a version called "risc16f84_lite.v" which has no interface for the EEPROM...

Another version, called "risc16f84_small.v" further eliminates the multiple interrupt sources present on the original chip (since in a PIC there is only one interrupt vector defined, so interrupt service routines must do some "checking" anyway to determine the source of an interrupt - why bother having separate inputs defined? Just make up your own interrupt structure and use it the way you like inside of your chip!)

Finally, the fourth version, called "risc16f84_clk2x.v" further removes the port A and port B interfaces, since you can create as many ports as you like inside of your own chip. Toward this end, "risc16f84_clk2x.v" also includes an "auxiliary" bus interface, allowing the microcontroller to access 64k bytes of registers, ports and hardware peripherals, all defined within their own address space -- not within the limited register space of the PIC microcontrollers. I have used it to address a screen with 12288 pixels, and each pixel has its own address. It is easy to define addresses for the auxiliary bus components in most PIC code generation tools, so this works out nicely.

The code is written in Verilog, and was sythesized into a Xilinx SpartanII XC2S200 chip. Debugging was done in actual hardware, with an HP16500 series logic analyzer, and there are no simulation testbenches for these modules.

The hardware debugger used to test this core is


- The original "risc16f84.v" supports execution with 4 clocks per instruction, as in PIC microcontrollers.
- The "risc16f84_clk2x" version uses only 2 clocks per instruction.
- Xilinx DPRAM blocks were used to implement the processor register space and program ROM. These RAMs are dual-ported, so I have mapped the other port into the "auxiliary bus" space.
- Debugging is aided by the use of "rs232_syscon.v" which is a hardware "monitor" that allows read/write of addresses on the auxiliary bus. Since program memory is mapped into the auxiliary bus, programs can be downloaded via rs232_syscon.
- Since the registers and all useful peripherals are present on the auxiliary bus, single stepping and hardware breakpoints are implemented through the rs232_syscon interface (a serial port connects to a terminal window.)
- I have been downloading C code through the serial port, in the form of rs232_syscon write commands.
- A PERL script transforms s-record files into rs232_syscon write commands.
- The cores are parameterized.
- The code has good comments.
- Interrupts are supported and tested in "risc16f84_clk2x.v"


- The "risc16f84_clk2x.v" core has been coded completely, synthesized and tested for correct operation (and debugged!) inside a Xilinx XC2S200 chip.
- The "risc16f84_clk2x.v" core was tested running C-code at 65.28 MHz (approx. 32 MIPS), and uses 321 Virtex slices. This test is not exhaustive, I only bumped up the clock speed until the program "froze up."
- The entire debugging environment, including risc16f84_clk2x, rs232_syscon, single stepping and breakpoint logic and registers, consumes about 900 Virtex slices, and runs at frequencies up to 65.28 MHz or so, when implemented inside of a Xilinx XC2S200 FPGA.
- There is no documentation yet. Please email me if you have specific questions and you cannot figure out how the modules work. The code has some good comments in it.
- "risc16f84_clk2x.v" has been rewritten somewhat. It supports a single edge-triggered interrupt now.
- The debugging environment has been updated to include support for generating slow interrupts (user controlled bit) and periodic interrupts (narrow pulses.)
- The entire SoC was compiled using Xilinx WebPack (XST synthesizer) free tools! It works at various clock rates, and has an automatic BAUD rate circuit that resynchronizes when the user changes speeds.
- A user reported a mathematical error on subtract opcodes. This was verified and fixed. Thanks to Stefan Frank for diligently reporting the bug!
- New "README.TXT" file describes some of the helpful hints and arcane tips for running the design. Enjoy!