Introducing Micro-Controllers in DSCH: 1 Logic Model of The 8051
Introducing Micro-Controllers in DSCH: 1 Logic Model of The 8051
This document details the implementation of two microcontroller models: the 8051 from Intel and the
16f54 from PIC.
The 8051 core includes an arithmetic and logic unit to support a huge set of instructions. Most of the
data format is in 8 bit format. We consider here the following instructions, listed in table 1. Some
instructions do not appear in this list, such as the multiplication and division.
Immediate value
Accumulator A
8 bits
8 bits
OpCode CarryIn
input Arithmetic and
Logic Unit
8 bits
Result S CarryOut
For example:
• ADD A,R0 (Opcode 0x28) overwrites the accumulator with the result of the addition of
A and the content of R0.
• SUBB A,#2 (Opcode 0x94 0x02) overwrites the accumulator with the result of the
subtraction of A and the sum of the Carry and the byte 0x02.
• INC A (0x04) increments the content of the accumulator.
• DEC A (0x14) Decrements the content of the accumulator.
• ANL A,#10 (0x54) overwrites the accumulator with by the AND-gating of A and the
constant 0x10.
• ORL A,R7 (0x4F) overwrites the accumulator with by the OR-gating of A and the
content of R7.
• XRL A, R1 (0x69) overwrites the accumulator with the result of the XOR-gating of A
and the content of the internal register R1.
A simplified model of the 8-bit micro-controller 8051 exists through the symbol “8051.SYM”
accessible using the command Insert → User Symbol. The symbol is also directly accessible through
the symbol palette starting version 3.5.
Figure 3. The IEEE symbol library contains the 8051 symbol (8051.SYM)
Figure 4. Access to the 8051 symbol from the palette, in the “Advanced” list
The symbol consists mainly of general purpose input/output ports (P0,P1,P2 and P3), a clock and a
reset control signals. The basic connection consists of a clock on the Clock input and a button on the
Reset input (Figure 5).
After a double-click in the symbol, the embedded code appears. That code may be edited and modified
(Figure 6). When the button Assembly is pressed, the assembly text is translated into executable
binary format. Once the logic simulation is running, the code is executed as soon as the reset input is
deactivated. The value of the program counter, the accumulator A, the current op_code and the
registers is displayed.
In the chronograms, the accumulator variations versus the time are displayed. It can be noticed that
this core operates with one single clock cycle per instruction, except for some instructions such as
MOV (Move data) and AJMP (Jump to a specific address).
Figure 6. The default code proposed in the 8051 component compiled using DSCH3
(8051.SYM)
Figure 7. The simulation of the arithmetic and logic operation using the 8051 micro-controller
(8051.SCH)
An example of code and schematic diagram for traffic light control is proposed below. Notice the
subroutine call through the instruction “AJUMP”.
Figure 8. A simple code for 8051 micro-controller for traffic light control
(8051_traffic_lights.sch)
Figure 9. Interface for compiling the code for the traffic light controller
(8051_traffic_lights.sch)
Ports are activated using control commands such as “MOV P3,#0”, while port input pins are tested
through the instruction such as “JB P2.2,URG”. See table 2 for the complete code embedded in the
8051 processor.
The following program is used to activate the Port B as output. The schematic diagram which
implements this code is “16f84.SCH” (Fig. 10). The corresponding simulation is reported in Fig. 11.
org 0
loop movlw 0x55 ; load W with a pattern (hexa format)
movwf PortB ; Moves the pattern to port B
movlw 0xaa ; load W with an other pattern
movwf PortB ; Moves the pattern to port B
goto loop ; and again
An example file can be found in 16f84adder.SCH. Double click the 16f84 symbol, and click
Assembly to convert the text lines into binary executable code.
org 0
movlw 5
movwf oper1
movlw 2
movwf oper2
movf oper1,0
addwf oper2,0
movwf result
sleep
Then click OK, run the simulation. Click the Reset button to activate the processor. The default code
realizes the addition of two numbers (Instruction addwf) and stores the result in the internal registers.
Modify the code to perform the AND (Instruction andwf), OR (Instruction iorwf) , XOR
(Instruction xorwf) and SUB (Instruction subwf) operations.
3 References
E. Sicard, S. Ben Dhia “Basic CMOS cell Design” Mc Graw Hill professional series, 2006, http://books.mcgraw-
hill.com
E. Sicard. Microwind & Dsch user's manual version 3.5 on-line at http://www.microwind.org
4 Appendix
CASE muCode OF
$0 : ;
$1 : muAddress:= NextByte(1);
$3 : if (muregA AND $01) <> 0 then muregA:=(muregA shr 1)+$80
else muregA:=(muregA shr 1);
$4 : IF muRegA<$FF THEN // Inc
Inc(muRegA)
ELSE
muRegA := 0;
$08,$09,$0A,$0B,$0C,$0D,$0E,$0F: inc(mureg[mucode-$8]);
$11 :begin
mustak[muSp]:= muAddress+2;
muAddress:=NextByte(1);
inc(muSp);
end;
$14 : IF muRegA=0 THEN
muRegA := $FF
ELSE
Dec(muRegA); // DEC
$18,$19,$1A,$1B,$1C,$1D,$1E,$1F: dec(mureg[mucode-$18]);
$20 : IF Pin(BitPin(1))=logic1 THEN JumpRelative(2) else
muAddress:= muAddress+3;
$22 : begin
dec(muSp);
muAddress:=mustak[muSp];
end;
$23 : BEGIN
if (muregA AND $80)<>0 then
myVal:=(muregA shl 1)+1
else
myVal:=(muregA shl 1);
muRegA := myVal AND $00FF;
END;
$24 : BEGIN
myVal:=muRegA+NextByte(1);
muRegA := myVal AND $00FF;
END;
$28,$29,$2A,$2B,$2C,$2D,$2E,$2F:
BEGIN
myVal:=muregA+mureg[mucode-$28];
muRegA := myVal AND $00FF;
END;
$30 : IF Pin(BitPin(1))=logic0 THEN
JumpRelative(2)
else
muAddress:= muAddress+3;
$44 : muregA:=muregA or NextByte(1); // ORL
$48,$49,$4A,$4B,$4C,$4D,$4E,$4F:muregA:=muregA or mureg[mucode-$48];
$54 : muregA:=muregA and NextByte(1);
IF words[2]='ADDLW' then
dataWord := addlw OR (HexAdr(words[3]) AND $FF)
else
IF words[2]='ANDLW' then
dataWord := andlw OR (HexAdr(words[3]) AND $FF)
else
IF words[2]='ADDWF' then
dataWord := addwf OR (HexAdr(words[3]) AND $7F) OR ((HexAdr(words[4]) AND $01) SHL 8)
else
IF words[2]='ANDWF' then
dataWord := andwf OR (HexAdr(words[3]) AND $7F) OR ((HexAdr(words[4]) AND $01) SHL 8)
IF words[2]='BCF' then
dataWord := bcf OR (HexAdr(words[4]) SHL 7) OR (HexAdr(words[3]) AND $7F)
else
IF words[2]='BTFSC' then
dataWord := btfsc OR (HexAdr(words[4]) SHL 7) OR (HexAdr(words[3]) AND $7F)
else
IF words[2]='BSF' then
dataWord := bsf OR (HexAdr(words[4]) SHL 7) OR (HexAdr(words[3]) AND $7F)
else
IF words[2]='BTFSS' then
dataWord := btfss OR (HexAdr(words[4]) SHL 7) OR (HexAdr(words[3]) AND $7F)
IF words[2]='CALL' then
dataWord := call OR (HexAdr(words[3]) AND $7FF)
else
IF words[2]='CLRF' then
dataWord := clrf OR (HexAdr(words[3]) AND $7F)
else
IF words[2]='CLRW' then
dataWord := clrw OR (HexAdr(words[3]) AND $7F)
else
IF words[2]='CLRWDT' then
dataWord := clrwdt
else
IF words[2]='COMF' then
dataWord := comf OR ((HexAdr(words[4]) AND $01) SHL 7) OR (HexAdr(words[3]) AND $7F)
IF words[2]='DECFSZ' then
dataWord := decfsz OR ((HexAdr(words[4]) AND $01) SHL 7) OR (HexAdr(words[3]) AND $7F)
else
IF words[2]='DECF' then
dataWord := decf OR ((HexAdr(words[4]) AND $01) SHL 7) OR (HexAdr(words[3]) AND $7F)
IF words[2]='GOTO' then
BEGIN
dataWord := goto1 OR (HexAdr(words[3]) AND $7FF);
END
IF words[2]='INCF' then
dataWord := incf OR ((HexAdr(words[4]) AND $01) SHL 7) OR (HexAdr(words[3]) AND $7F)
else
IF words[2]='INCFSZ' then
dataWord := incfsz OR ((HexAdr(words[4]) AND $01) SHL 7) OR (HexAdr(words[3]) AND $7F)
else
IF words[2]='IORLW' then
dataWord := iorlw OR (HexAdr(words[3]) AND $FF)
else
IF words[2]='IORWF' then
dataWord := iorwf OR ((HexAdr(words[4]) AND $01) SHL 7) OR (HexAdr(words[3]) AND $7F)
IF words[2]='MOVLW' then
dataWord := movlw OR (HexAdr(words[3]) AND $FF)
else
IF words[2]='MOVF' then
dataWord := movf OR (HexAdr(words[3]) AND $7F) OR ((HexAdr(words[4]) AND $01) SHL 7)
else
IF words[2]='MOVWF' then
dataWord := movwf OR (HexAdr(words[3]) AND $7F)
IF words[2]='NOP' then
dataWord := nop;
IF words[2]='ORG' then
BEGIN
actualAddress:=HexAdr(words[3]);
byteNumber :=0;
ignoreLine := TRUE;
END
IF words[2]='RETFIE' then
dataWord :=retfie
else
IF words[2]='RETLW' then
dataWord :=retlw OR (HexAdr(words[3]) AND $FF)
else
IF words[2]='RETURN' then
dataWord :=return
else
IF words[2]='RLF' then
dataWord := rlf OR (HexAdr(words[3]) AND $7F) OR ((HexAdr(words[4]) AND $01) SHL 7)
else
IF words[2]='RRF' then
dataWord := rrf OR (HexAdr(words[3]) AND $7F) OR ((HexAdr(words[4]) AND $01) SHL 7)
IF words[2]='SLEEP' then
dataWord := sleep1
else
IF words[2]='SUBLW' then
dataWord :=sublw OR (HexAdr(words[3]) AND $FF)
else
IF words[2]='SUBWF' then
dataWord := subwf OR (HexAdr(words[3]) AND $7F) OR ((HexAdr(words[4]) AND $01) SHL 7)
else
IF words[2]='SWAPF' then
dataWord := swapf OR (HexAdr(words[3]) AND $7F) OR ((HexAdr(words[4]) AND $01) SHL 7)
IF words[2]='XORLW' then
dataWord := xorlw OR (HexAdr(words[3]) AND $FF)
else
IF words[2]='XORWF' then
dataWord := xorwf OR (HexAdr(words[3]) AND $7F) OR ((HexAdr(words[4]) AND $01) SHL 7)