RoboCockroach v2

Figure 1 : robo-cockroach junior

The son of the original robo-cockroach (Link), a smaller version aimed at teaching digital circuit design techniques. Many moons ago i taught the module: Digital and Analogue Circuit Design (DACS), for the final individual project we developed a series of CPLD boards, using these the students designed and built Goliath type robots (Link). With the move to FESC these were not being used, so decided to put them to some use, as shown in figure 1, golden rule of robotics: everything is made better with googly eyes :).

Table of Contents

Circuits & PCB
Chassis
Logic design
State machine design
Version 2.0 ...

Circuits & PCB

The original CPLD PCB was designed to plug into bread-boards allowing students to minimise their designs by using a Xilinx 9572XL CPLD (Link), (Link). The PCB adaptor circuit diagram and PCB layout are shown in figures 2 and 3. Basically this board is a surface mount to pins-through-board adaptor, with a 3.3V regulator and JTAG programming socket.

Figure 2 : CPLD circuit diagram

Figure 3 : CPLD PCB

At the time this was a very nice little board, 5V tolerant and the CPLDs were only £2 each, making then reasonably robust and affordable for teaching purposes. One key point to note is NEVER connect an IO pins directly to +5V, even through its 5V tolerant. When powered by the 3.3V regulator connecting a pin to 5V is fine, but if you turn the power OFF then ON again, there will be a small delay before the 3.3V supply comes up, during this time the CPLD will self power through these IO pins. As its a 3.3V device, powering it with +5V through the IO pins will cause it to go pop. We lost sooooo many boards before i spotted this joy. Rule number 2: always use a pull-up resistor :).






Figure 4 : CPLD module

After the first term we found that the fine pins (shown in figure 4) used to connect the PCB to the breadboard were getting snapped off, mostly during removal i.e. levering the PCB out, causing the back legs to be bent +90 degrees. Therefore, we decided to move to a motherboard based solution, also added a button board: LED + SW + OSC board, using the same footprint. The button board circuit diagram and PCB are shown in figure 5 and 6. The aim of the button board was to replicate the key positions of a games controller, to allow students to drive their Goliath like robot around the lab, have robot wars etc.

Figure 5 : Button board circuit diagram

Figure 6 : Button board PCB




Figure 7 : Button board module

Going to a motherboard based solution allowed these modules to be permanently mounted on this PCB. IO was provided via KK connectors, with some buffering (extra protection) via 7414 NOT gates. If needed some of the button boards pins could be reassigned to general IO using jumpers. This did restrict IO choices a little, but added another layer of protection. Following this theme, the motherboard also had reverse protection diodes and a +5V regulator to protect the CPLD board form over-voltage and reverse-voltage PSU problems. The circuit diagram and PCB are shown in figures 8 and 9.

Figure 8 : motherboard circuit diagram

Figure 9 : motherboard PCB


Figure 10 : motherboard module

To control the robot's two drive motors i used the same motor driver board as the original robo-cockroach (again originally developed for DACS), this gives two H-bridge drivers and some input buffering / filtering. The circuit diagram and PCB are shown in figures 11 and 12.






Figure 11 : motor driver circuit diagram

Figure 12 : motor driver PCB

Figure 13 : motor driver module

During testing the PWM speed control signal caused these motor controllers behaved very strangely, it seemed to trigger some sort of positive feedback resulting in strange oscillations, such that the motor would stall (basically sat there and buzzed). After a little messing around i found that adding the filter circuit shown in figure 14 seemed to fix the problem, but still not sure why it occurred in the first place, it seemed to be a particular problem with the motors used in this robot, other motors seemed to work ok, hmmmmm, perhaps current limiting, not sure ....

Figure 14 : filter circuit

Used the same battery pack and power unit as the Roach robot (Link), stuck with the XL6009 boost converter module for the moment as i thought it may give a cleaner supply voltage, extend battery life a little for the CPLD module (motors always produce a lot of noise). The internal mounting and wiring of these modules is shown in figure 15. Note, filter caps mounted above drive motors.




Figure 15 : internal wiring

Chassis

The chassis is based on the previous microBit robot (Link), some small changes to mounting holes, reused most of the 3D printed parts, so basically the same. Decided to only use a single front and rear bumper switch, the long lever micro-switches used on the microBit robot worked fine, but they were a little fragile, not quite up to your typical lab usage. The only new 3D prited part was the all important eye mounting bracket, shown in figure 18. The assembled robot is shown in figure 19.

Figure 16 : chassis




Figure 17 : 3D printed parts


Figure 18 : 3D printed eyes mount










Figure 19 : Robot

Logic design

The first aim of this robot is to show a practical example of digital logic circuit design. To this end the students design and implement a simple control pad, allowing them to steer the robot around the desk. To start with we will only consider the centre four buttons: forwards, backwards, rotate left, rotate right, using these buttons to control the two h-bridge's i.e. the two drive motors. Each h-bridges has two digital inputs: CTL1 and CTL0, as shown in the table below:

CTL1 CTL0 Description
0 0 Stop
0 1 Forwards
1 0 Backwards
1 1 Break

Using control signals CTL1 and CTL0 the direction of each motor can be controlled. For this design motor speed is constant, later designs will use simple PWM to varying the speed of each motor, allowing the robot to move in an arcs etc. The push buttons are active low (figure 5) i.e. generate a logic 0 when pressed. Each switch on the control pad is assign a movement as shown in the table below.

B7 B5 B4 B3 LMCTL1 LMCTL0 RMCTL1 RMCTL0 Description
1 1 1 1 0 0 0 0 Stop
1 1 1 0 1 0 1 0 Forwards
1 1 0 1 0 1 1 0 Rotate Left
1 0 1 1 1 0 0 1 Rotate Right
0 1 1 1 0 1 0 1 Backwards

To minimise the Boolean logic used to generate these outputs we can use a four input KMap, as shown in figure 20. Unfortunately in its present form no minimisation is possible. The circuit diagram and simulation of this solution is shown in figure 21.


LMCTL1 = B7.B5.B4./B3 + B7./B5.B4.B3
LMCTL0 = B7.B5./B4.B3 + /B7.B5.B4.B3
RMCTL1 = B7.B5.B4./B3 + B7.B5./B4.B3
RMCTL0 = /B7.B5.B4.B3 + B7./B5.B4.B3

Figure 20 : control pad truth table




Figure 21 : control pad circuit diagram & simulation

For this truth table logic term can not be minimised using KMAPs, however, you can half the number of logic gates by spotting that there are redundant (repeated terms), reusing these gates minimises the current in figure 21 to that shown in figure 22.

Figure 22 : control pad circuit diagram v2

Another way to minimise a logic circuit is to identify don't care states, these are states that are independent of one or more inputs, as shown in the table below e.g. if the backwards button is pressed the robot will move backwards and ignore any other button pressed.


B7 B5 B4 B3 LMCTL1 LMCTL0 RMCTL1 RMCTL0 Description
1 1 1 1 0 0 0 0 Stop
1 1 1 0 1 0 1 0 Forwards
1 1 0 X 0 1 1 0 Rotate Left
1 0 X X 1 0 0 1 Rotate Right
0 X X X 0 1 0 1 Backwards

Don't care state can now be used to create larger groupings in the KMaps, thus minimising the number of logic gates. The circuit diagram and simulation of this solution is shown in figure 23.


LMCTL1 = B7./B5 + B7.B4./B3
LMCTL0 = /B7 + B5./B4
RMCTL1 = B7.B5./B4 + B7.B5./B3
RMCTL0 = /B7 + /B5



Figure 23 : control pad circuit diagram & simulation v3

To improve the control-ability of the robot we can use more switches to define different types of movement, as shown in the table below:

B8 B7 B6 B5 B4 B3 B2 B1 LMCTL1 LMCTL0 RMCTL1 RMCTL0 Description
1 1 1 1 1 1 1 1 0 0 0 0 Stop
1 1 1 1 1 1 1 0 1 0 0 0 Turn Left
1 1 1 1 1 1 0 1 0 0 1 0 Turn Right
1 1 1 1 1 0 1 1 1 0 1 0 Forwards
1 1 1 1 0 1 1 1 0 1 1 0 Rotate Left
1 1 1 0 1 1 1 1 1 0 0 1 Rotate Right
1 1 0 1 1 1 1 1 0 0 0 0 Stop
1 0 1 1 1 1 1 1 0 1 0 1 Backwards
0 1 1 1 1 1 1 1 0 0 0 0 Stop

However, minimising eight variable KMAPs is slightly on the tricky side (5 input is normally the max). The simplest approach is to take an adhoc design approach by inverting the button signals to produce an active high signal, then combine these together using OR gates, as shown in figures 24 and 25. This is a nice intuitive approach using each logic 0 input to produce a logic 1 on the associated output e.g. the two logic 1 states for RM0 are produced by a two input OR gate driven by /B5 and /B7. The Boolean equations for this circuit diagram are:

LMCTL1 = /B1 + /B3 + /B5
LMCTL0 = /B4 + /B7
RMCTL1 = /B2 + /B3 + /B4
RMCTL0 = /B5 + /B7

Figure 24 : control pad logic circuit


Figure 25 : control pad logic circuit simulation

The down side of this simple design is that it assumes that only one button is pressed at a time, if multiple buttons are pressed at the same time the robot will perform non-specified movements. It could be argued that this is ok as the above truth table is not complete, but typically when designing a circuit you would want the system to enter a specific safe output state if/when an undefined input state does occur.

State machine design

There is a lot of discussion of traditional / formal state machine design on the previous robo-cockroach web page (Link), so rather than repeating this i'm going to show a more ad hoc approach based around standard Xilinx ISE library components e.g. binary counters. The aim here is to built a Graffiti-bot i.e. attach a pen to the robot and let it loose on the world writing words on the ground as it travels, a fire and forget graffiti bomb :). To configure this robot to write, you "simply" need to break down the required lines in to a list of movements and rotations. It also needs to respond to front and rear bumpers i.e. moving the robot away from the obstacle and turning it to face open space. As with the original robo-cockroach these movements use simple open loop control i.e. optimistically assuming a constant speed and no non-systematic errors, making the robot's movements proportional to time (good enough for this demo). The main clock runs at 4MHz i.e. 250ns period, therefore, to generate control signals every second or so, you need to divide this down using a counter as shown in figure 26.






Figure 26 : Clock divider circuit

At the heart of this circuit is the standard library unit: CB8CE, 8bit counters, generating a pulse on D0 every 0.25 seconds, movements and rotations are then made up of multiple 0.25 second steps. Note, the AND gate and single flip-flop implement a rising edge detector, producing a logic '1' pulse for one clock cycle, each time there is a transition from a logic '0' to logic '1' on counter bit 19.




Figure 27 : Top level circuit

The main state machine is again based around a standard library unit: CB8CLE, 8bit loadable binary counter, as shown in figure 27. The counter's 8bit binary output represents the system's state, which is passed to the DECODER to produce the required motor control signals, as shown in figure 28. Therefore, this ad hoc design is a Moore state machine, the counter has replaced the input forming logic and state register, and the decoder the output forming logic (effectively implementing a read only memory (ROM) using logic gates). The counter is updated using the LOAD and CLOCK_ENABLE inputs, controlled using two OR gates. The CLOCK_ENABLE signal is driven by the clock divider's UPDATE signal, incrementing the count every 0.25 seconds. The CLOCK_ENABLE input is also used in conjunction with the LOAD input to change the counter's value e.g. when the front/rear bumper is pressed. When a bumper is pressed the active low signal is feed into the falling edge detector circuit shown in figure 29, this pulse drives both the LOAD and CLOCK_ENABLE inputs, loading the selected constant input produced by the CONSTANT_SELECT module shown in figure 30, updating the systems state e.g. when the front bumper is pressed the system moves to state 100 which contains the associated sequence of movements for that bumper. To return the system to the main drawing/writing loop the output decoder module can set the RST lines, this again triggers an update of the main counter returning the system to state 0. Note, to save time implemented the decoder and constant select in VHDL.



Figure 28 : output logic decoder


Figure 29 : edge detector



Figure 30 : branch address logic

A simulation of the the system responding to the front bumper being pressed is shown in figure 31. When designing this hardware i was a little concerned about hardware usage, but as figure 32 shows for this simple test system we still have quite a lot of hardware free to define the required writing/drawing movements.


Figure 31 : Front bumper simulation


Figure 32 : Hardware usage

Unfortunately, i forgot the pen would not be mounted between the drive wheels :(, so the first implementation did not go well. With the pen mounted between the motors when the robot rotates it does not draw a line i.e. the pen does not move. With the pen mounted in front of the centre-of-rotation, when the robot rotates you draw an arc, significantly complicating the original plan :(. In an attempt to fix the problem i used a pair of solenoids to lift the pen off the ground between positional movements. These were mounted in the 3D printed frame shown in figure 33.






Figure 33 : solenoid bracket

Normally would of gone for a small servo, as these are cheaper and use less power, but this would need a PWM hardware module. Could of made this by modifying the clock divider as you only need two waveforms i.e. up and down positions, but solenoids are a lot easier to control, a simple on/off signal, but they do take about 100mA each. To control the solenoids added a simple open collector driver, as shown in figure 34, mounted in a small 3D printed box. A short video of the solenoid is available here: (Link).




Figure 34 : open collector driver

Hmmmm, not having the pen at the centre of rotation makes a simple problem into a really nasty problem, i think this needs a rethink, perhaps a raster scan, drawing the image using a series of horizontal lines, rather than the vector "display" i had originally planned for...

Version 2.0

Thought about this one for a day or so, then decided life was too short, so decided it was a good time to have a play with the new 3D printer (TAZ6), knock up a different chassis, one where the pen was mounted in-between the drive wheels. The roughed out design is shown in figure 35. Went for a quick and easy design, reused a number of elements from past projects in order to minimise development/construction time. To be honest at this stage this robot was driven by professional pride, i wanted to show that it would work, even if it didn't work on the original robots :).


Figure 35 : version 2 3D model

The new 3D printer is good, self-levelling was a new feature i had not seen before, gives a nice clean first layer, but you do have to make sure the extruder is spotless, otherwise it gets confused during the calibration phase. This time i also used OpenScad's DXF feature, allowing you to convert the top and base layers into 2D models for the laser cutter. Works well, but as always assumes you can measure things accurately (pen mounting was a little off centre as i measured the size of the motor's wrongly). Things always work perfectly in simulations/models :). Print run was 15 hours :(, but after that didn't take long to assemble. Final robot shown in figure 35.






Figure 36 : version 2

Basically the same design as version 1, but went for a 11V battery for this proto-type, partly because thats what i had spare, but also as the solenoids are 12V, so it avoided the need for a boost converter. Also, the solenoids do take a little current, around 100mA each, so the higher capacity battery also increased running time. The linear regulator on the CPLD motherboard doesn't have a heatsink, so the 11V to 5V step down i.e. dropping 6V across the regulator, could dissipate a bit of power in this device. Therefore, i decided to add a dump power resistor to drop the voltage a little. After testing a 22 ohms resistor seemed to do the job, reducing the input voltage to 9V-ish. Given the reverse voltage diode on the motherboard this gives 8.3V-ish on the input of the regulator. As there was space, added a buck converter, a step down switching power supply module, to produce the motor drive voltage. The idea here was to allow some fine adjustments to the robot's rotations/movements i.e. as all movements are open loop, movement is proportional to time and motor speed, having the ability to adjust the motor drive voltage (variable resistor on buck converter) gives you some fine adjustment control of the motor speed, and therefore the angle turned.


Figure 37 : version 2 power supply

A short video of the robot in action is available here: (Link).


Figure 38 : robot in action

The VHDL to encode the movements to write "MIKE" are shown in figure 39.

----------------------------------------------------------------------------------
-- decoder.vhd
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;

entity decoder is
Port ( state : in  STD_LOGIC_VECTOR (7 downto 0);
       lm1 : out  STD_LOGIC;
       lm0 : out  STD_LOGIC;
       rm1 : out  STD_LOGIC;
       rm0 : out  STD_LOGIC;
       sol : out  STD_LOGIC;		 
		 rst : out  STD_LOGIC);
end decoder;

architecture decoder_arch of decoder is

	SIGNAL control : STD_LOGIC_VECTOR(5 DOWNTO 0);
	SIGNAL state_variable : INTEGER;
	
	CONSTANT stop           : STD_LOGIC_VECTOR(5 DOWNTO 0) := "000000";	
	CONSTANT forwards_up    : STD_LOGIC_VECTOR(5 DOWNTO 0) := "101010";
	CONSTANT forwards_down  : STD_LOGIC_VECTOR(5 DOWNTO 0) := "001010";	
	CONSTANT backwards_down : STD_LOGIC_VECTOR(5 DOWNTO 0) := "000101";
	CONSTANT backwards_up   : STD_LOGIC_VECTOR(5 DOWNTO 0) := "100101";	
	CONSTANT rotateLeft     : STD_LOGIC_VECTOR(5 DOWNTO 0) := "001001";
	CONSTANT rotateRight    : STD_LOGIC_VECTOR(5 DOWNTO 0) := "000110";	
	CONSTANT reset          : STD_LOGIC_VECTOR(5 DOWNTO 0) := "010000";		
	
begin
	sol <= control(5);
	rst <= control(4);
	lm1 <= control(3);
	lm0 <= control(2);	
	rm1 <= control(1);
	rm0 <= control(0);
	
	state_variable <= conv_integer(unsigned( state ));
	
	-- FD RR135 FD RL90 FD RR135 FD S
	-- RL90 FU RL90 S
	-- FD
	-- RR90 FU RR90 S
	-- FD RL90 FU RL135 FD RR90 FD RR45 S
	-- FU
	
	decode_logic : PROCESS( state_variable )
	BEGIN
		CASE state_variable IS
			-- MIKE
			WHEN 0      => control <= forwards_down;  --M
			WHEN 1      => control <= forwards_down;			
			WHEN 2      => control <= rotateRight;
			WHEN 3      => control <= rotateRight;
			WHEN 4      => control <= rotateRight;
			WHEN 5      => control <= rotateRight;
			WHEN 6      => control <= rotateRight;
			WHEN 7      => control <= rotateRight;
			WHEN 8      => control <= forwards_down;
			WHEN 9      => control <= rotateLeft;
			WHEN 10     => control <= rotateLeft;
			WHEN 11     => control <= rotateLeft;
			WHEN 12     => control <= rotateLeft;			
			WHEN 13     => control <= forwards_down;			
			WHEN 14     => control <= rotateRight;	
			WHEN 15     => control <= rotateRight;
			WHEN 16     => control <= rotateRight;	
			WHEN 17     => control <= rotateRight;	
			WHEN 18     => control <= rotateRight;
			WHEN 19     => control <= rotateRight;				
			WHEN 20     => control <= forwards_down;	
			WHEN 21     => control <= forwards_down;				
			WHEN 22     => control <= rotateLeft;
			WHEN 23     => control <= rotateLeft;
			WHEN 24     => control <= rotateLeft;
			WHEN 25     => control <= rotateLeft;			
			WHEN 26     => control <= forwards_up;
			WHEN 27     => control <= rotateLeft;
			WHEN 28     => control <= rotateLeft;
			WHEN 29     => control <= rotateLeft;
			WHEN 30     => control <= rotateLeft;			
			WHEN 31     => control <= forwards_down; --I
			WHEN 32     => control <= forwards_down;			
			WHEN 33     => control <= rotateRight;
			WHEN 34     => control <= rotateRight;
			WHEN 35     => control <= rotateRight;
			WHEN 36     => control <= rotateRight;			
			WHEN 37     => control <= forwards_up;
			WHEN 38     => control <= rotateRight;	
			WHEN 39     => control <= rotateRight;	
			WHEN 40     => control <= rotateRight;	
			WHEN 41     => control <= rotateRight;				
			WHEN 42     => control <= forwards_down; --K	
			WHEN 43     => control <= forwards_down;				
			WHEN 44     => control <= rotateLeft;	
			WHEN 45     => control <= rotateLeft;
			WHEN 46     => control <= rotateLeft;	
			WHEN 47     => control <= rotateLeft;			
			WHEN 48     => control <= forwards_up;	
			WHEN 49     => control <= rotateLeft;	
			WHEN 50     => control <= rotateLeft;	
			WHEN 51     => control <= rotateLeft;	
			WHEN 52     => control <= rotateLeft;	
			WHEN 53     => control <= rotateLeft;	
			WHEN 54     => control <= rotateLeft;			
			WHEN 55     => control <= forwards_down; 
			WHEN 56     => control <= rotateRight;				
			WHEN 57     => control <= rotateRight;
			WHEN 58     => control <= rotateRight;				
			WHEN 59     => control <= rotateRight;			
			WHEN 60     => control <= forwards_down;
			WHEN 61     => control <= rotateRight;	
			WHEN 62     => control <= rotateRight;				
			WHEN 63     => control <= forwards_up;				
			WHEN 64     => control <= rotateRight;
			WHEN 65     => control <= rotateRight;			
			WHEN 66     => control <= rotateRight;			
			WHEN 67     => control <= rotateRight;	
			WHEN 68     => control <= forwards_down; --E			
			WHEN 69     => control <= forwards_down;				
			WHEN 70     => control <= rotateLeft;
			WHEN 71     => control <= rotateLeft;			
			WHEN 72     => control <= rotateLeft;	
			WHEN 73     => control <= rotateLeft;			
			WHEN 74     => control <= forwards_down;				
			WHEN 75     => control <= rotateLeft;	
			WHEN 76     => control <= rotateLeft;	
			WHEN 77     => control <= rotateLeft;	
			WHEN 78     => control <= rotateLeft;	
			WHEN 79     => control <= forwards_up;
			WHEN 80     => control <= rotateLeft;	
			WHEN 81     => control <= rotateLeft;	
			WHEN 82     => control <= rotateLeft;	
			WHEN 83     => control <= rotateLeft;		
			WHEN 84     => control <= forwards_down; 
			WHEN 85     => control <= rotateRight;
			WHEN 86     => control <= rotateRight;			
			WHEN 87     => control <= rotateRight;			
			WHEN 88     => control <= rotateRight;	
			WHEN 89     => control <= rotateRight;
			WHEN 90     => control <= rotateRight;			
			WHEN 91     => control <= rotateRight;			
			WHEN 92     => control <= rotateRight;	
			WHEN 93     => control <= forwards_up;
			WHEN 94     => control <= rotateLeft;	
			WHEN 95     => control <= rotateLeft;	
			WHEN 96     => control <= rotateLeft;	
			WHEN 97     => control <= rotateLeft;	
			WHEN 98     => control <= forwards_up;
			WHEN 99     => control <= rotateLeft;	
			WHEN 100    => control <= rotateLeft;	
			WHEN 101    => control <= rotateLeft;	
			WHEN 102    => control <= rotateLeft;			
			WHEN 103    => control <= forwards_down;
			WHEN 104    => control <= rotateRight;	
			WHEN 105    => control <= rotateRight;	
			WHEN 106    => control <= rotateRight;	
			WHEN 107    => control <= rotateRight;	
			WHEN 108    => control <= forwards_up; --MOVE
			WHEN 109    => control <= forwards_up;			
			WHEN 110    => control <= forwards_up;
			WHEN 111    => control <= forwards_up;	
			WHEN 112    => control <= rotateRight;	
			WHEN 113    => control <= rotateRight;				
			WHEN 114    => control <= reset;
				
			-- BACK BUMPERS
			WHEN 150     => control <= stop;
			WHEN 151     => control <= forwards_up;
			WHEN 152     => control <= forwards_up;
			WHEN 153     => control <= forwards_up;
			WHEN 154     => control <= forwards_up;
			WHEN 155     => control <= forwards_up;
			WHEN 156     => control <= forwards_up;
			WHEN 157     => control <= stop;
			WHEN 158     => control <= rotateRight;	
			WHEN 159     => control <= rotateRight;
			WHEN 160     => control <= rotateRight;	
			WHEN 161     => control <= rotateRight;
			WHEN 162     => control <= rotateRight;	
			WHEN 163     => control <= rotateRight;
			WHEN 164     => control <= rotateRight;	
			WHEN 165     => control <= rotateRight;
			WHEN 166     => control <= reset;
			
			-- FRONT BUMPERS
			WHEN 170    => control <= stop;
			WHEN 171    => control <= backwards_up;
			WHEN 172    => control <= backwards_up;
			WHEN 173    => control <= backwards_up;
			WHEN 174    => control <= backwards_up;
			WHEN 175    => control <= backwards_up;
			WHEN 176    => control <= backwards_up;
			WHEN 177    => control <= stop;
			WHEN 178    => control <= rotateLeft;	
			WHEN 179    => control <= rotateLeft;
			WHEN 180    => control <= rotateLeft;	
			WHEN 181    => control <= rotateLeft;
			WHEN 182    => control <= rotateLeft;	
			WHEN 183    => control <= rotateLeft;
			WHEN 184    => control <= rotateLeft;	
			WHEN 185    => control <= rotateLeft;
			WHEN 186    => control <= reset;
			
			WHEN OTHERS => control <= stop;
		END CASE;
	END PROCESS;
		
end decoder_arch;

Creative Commons Licence

This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License.

Contact details: email - mike.freeman@york.ac.uk, telephone - 01904 32(5473)

Back