Sunteți pe pagina 1din 9

Design an 8-bit Processor with Verilog

at Behavioral Level
We use the Intel 8085 all time popular 8-bit processor as an
example.
A complete functional Verilog model for the Intel 8085 will be
presented.
Lecture outline
1. review the architecture, chip layout, pin definition
2. instruction set
3. 8085 Verilog models
4. 8085 Verilog test bench.
1

Architecture of the 8085


The 8085 has:
A 16-bit program counter (PC)
A 16-bit stack pointer (SP)
An 8-bit instruction register
An 8-bit accumulator
Six 8-bit general purpose registers, B, C, D, E, H, L
BC, DE, HL can be accessed in pairs or individually.
A temporary register pair: W, Z
Instructions are 1 to 3 bytes in length and the first byte is the OPCODE
Seven different machine cycles
(each machine cycle may take up to 4 clock cycles)
1. opcode fetch
2. memory read
3. memory write
4. I/O read
5. I/O write
6. interrupt acknowledge
7. bus idle

S0, S1 (Output)

READY (Input)

Data Bus Status. Encoded status of the bus cycle:

If Ready is high during a read or write cycle, it indicates that the memory
or peripheral is ready to send or receive data.
If Ready is low, the CPU will wait for Ready to go high before
completing the read or write cycle.

S1 S0
0 0
0 1
1 0
1 1

HALT
WRITE
READ
FETCH

HOLD (Input)

RD (Output 3state)

HOLD; indicates that another Master is requesting the use of the Address
and Data Buses. The CPU, upon receiving the Hold request. will relinquish
the use of buses as soon as the completion of the current machine cycle.
Internal processing can continue. The processor can regain the buses only
after the Hold is removed.
When the Hold is acknowledged, the Address, Data, RD, WR, and IO/M lines
are 3stated.

READ; indicates the selected memory or I/O device is to be read


and that the Data Bus is available for the data transfer.
3stated during Hold and Halt.
WR (Output 3state)
WRITE; indicates the data on the Data Bus is to be written into
the selected memory or I/O location. 3stated during Hold and Halt modes.
5

HLDA (Output)

TRAP (Input)

HOLD ACKNOWLEDGE; indicates that the CPU has received the Hold request
and that it will relinquish thebuses in the next clock cycle.
HLDA goes low after the Hold request is removed.
The CPU takes the buses one half clock cycle after HLDA goes low.

Trap interrupt is a nonmaskable restart interrupt.


It is recognized at the same time as INTR.
It is unaffected by any mask or Interrupt Enable.
It has the highest priority of any interrupt.

RESTART INTERRUPTS;
These three inputs have the same timing as INTR except they cause
an internal RESTART to be automatically inserted.

Name

RESTART Address (Hex)

TRAP
RST 5.5
RST 6.5
RST 7.5

2416
2C16
3416
3C16

RST 7.5 Highest Priority


RST 6.5
RST 5.5 Lowest Priority

RESET IN (Input)

The priority of these interrupts is ordered as shown above.


These interrupts have a higher priority than the INTR.

Reset sets the Program Counter to zero and resets the Interrupt Enable
and HLDA flip flops.

IO/M (Output)

module s85; // simulation testbench module

IO/M indicates whether the Read/Write is to memory or l/O


Tristated during Hold and Halt modes.

reg [8:1]
dflags;
initial
dflags = 0;
// diag flags:
// 1 = printmem
// 2 = dump state at end
// 3 = test reset control
// 4 = monitor the transmit and receive lines

RESET OUT (Output)


Indicates CPU is being reset. Can be used as a system RESET.
The signal is synchronized to the processor clock.
X1, X2 (Input)
Crystal or R/C network connections to set the internal clock generator
X1 can also be an external clock input instead of a crystal.
The input frequency is divided by 2 to give the internal operating frequency.

wire

s0, ale, rxd, txd, clock;

tri[7:0]
tri1

ad, a;
read, write, iomout;

reg

trap, rst7p5, rst6p5, rst5p5,


intr, ready, nreset, hold, pclock;

CLK (Output)
Clock Output for use as a system clock

module intel_8085a
(clock, x2, resetff, sodff, sid, trap,
rst7p5, rst6p5, rst5p5, intr, intaff,
ad, a, s0, aleff, writeout, readout, s1,
iomout, ready, nreset,
clockff, hldaff, hold);

//instantiate the clock


osc timebase(clock);
//instantiate the RAM module
ram85a
r0(ale, ad, a, write, read, iomout);

reg [8:1]
dflags;
initial
dflags = 'b000;
// diag flags:
// 1 = trace instructions
// 2 = trace IN and OUT instructions
// 3 = trace instruction count

//instantiate the 8085a processor module


intel_8085a i85(clock, , , , , trap,
rst7p5, rst6p5, rst5p5, intr, ,
ad, a, s0, ale, write, read, ,
iomout, ready, nreset,
, , hold);

output
resetff, sodff, intaff, s0, aleff,
writeout, readout, s1, iomout, clockff, hldaff;

initial
begin
$write("\n");

..
..
endmodule

10

11

inout[7:0] ad, a; // a is address bus low byte output only


input
clock, x2, sid, trap,
rst7p5, rst6p5, rst5p5,
intr, ready, nreset, hold;

12

reg[15:0]
pc,
sp,
addr;
reg[8:0]
intmask;
reg[7:0]
acc,
regb,
regc,
regd,
rege,
regh,
regl,
ir,
data;
reg
aleff,
s0ff,
s1ff,
hldaff,
holdff,

// program counter
// stack pointer
// address output

intaff,
trapff,
trapi,
inte,
int,
validint,
haltff,
resetff,
clockff,
sodff,
read,
write,
iomff,
acontrol,
dcontrol,
s,
cs,
cz,
cac,
cp,
cc;

// interrupt mask and status

// accumulator
// general
// general
// general
// general
// general
// general
// instruction
// data output
// address latch enable
// status line 0
// status line 1
// hold acknowledge
// internal hold

13

The condition flags


Z
Zero
S
Sign
P
Parity
C
Carry
A
Auxiliary carry

14

Overview of Instruction set


1. Data Transfer Group
2. Logic Group
3. Branch Group
4. Stack and Machine Control Group
5. Arithmetic Group

Registers: A, B, C, D, E, H, L
Register pairs: BC, DE, HL
Symbols and abbreviations used in Assembly language
accumulator
Register A
addr
16-bit address
data
8-bit data
data 16
16-bit data
byte 2
the second byte of the instruction
byte 3
the third byte of the instruction
port
8-bit address of an I/O device
r, r1, r2
one of the registers A, B, C, D, E, H, L
DDD, SSS
destination, source
rp
register pair
( )
the contents of the memory location or register
enclosed in the parentheses

// interrupt acknowledge
// trap interrupt request
// trap execution for RIM instruction (RIM:read interrupt mask)
// previous state of interrupt enable flag
// interrupt acknowledge in progress
// interrupt pending
// halt request
// reset output
// clock output
// serial output data
// read request signal
// write request signal
// i/o memory select
// address output control
// data output control
// data source control
// sign condition code
// zero condition code
// aux carry condition code
// parity condition code
// carry condition code

Data Transfer Instructions


IN
port
(A) (port)
OUT
port
(port) (A)

// move data at port to Accumulator


// two byte instruction, first byte is OPCODE
//second byte is port address
//move data from A to port

For examples
IN 5
OUT 1

15

16

LDA addr
(A) ((byte 3) (byte 2))

//load accumulator direct

STA addr
((byte 3)(byte 2)) (A)

//store accumulator direct

example:
LDA First
STA First

// First is a 16-bit address

LHLD addr
//load H and L direct
(L) ((byte3) (byte 2))
(H) ((byte 3) (byte 2) + 1)
SHLD addr
//store H and L direct
((byte 3)(byte 2)) (L)
((byte 3)(byte 2) + 1) (H)
MOV r, M
(r) ((H)(L))
example
MOV B, M

//move from memory specified by HL


//to a register r

MOV M, r

//store r in memory

LDAX rp
(A) ((rp))

//load accumulator indirect

STAX rp
((rp)) (A)

//store accumulator indirect

MVI r, data
(r) (byte 2)

//move immediate

LXI rp, data 16


(rl) (byte 2)
(rh) (byte 3)

//load register pair immediate

MVI M, data
((H)(L)) (byte 2)

//move to memory immediate

17

18

Verilog Model Examples for Data Transfer Instructions


/* move register to register */
task move;
case(ir[2:0])
0: rmov(regb); // MOV -,B
1: rmov(regc); // MOV -,C
2: rmov(regd); // MOV -,D
3: rmov(rege); // MOV -,E
4: rmov(regh); // MOV -,H
5: rmov(regl); // MOV -,L
6:
if(ir[5:3] == 6)
begin
haltff = 1; // HLT
end
else begin // MOV -,M
memread(data, {regh, regl});
rmov(data);
end
7: rmov(acc); // MOV -,A
endcase
endtask

/* enabled only by move */


task rmov;
input[7:0] fromreg;
case(ir[5:3])
0: regb = fromreg; // MOV B,1: regc = fromreg; // MOV C,2: regd = fromreg; // MOV D,3: rege = fromreg; // MOV E,4: regh = fromreg; // MOV H,5: regl = fromreg; // MOV L,6: memwrite(fromreg, {regh, regl}); // MOV M,7: acc = fromreg; // MOV A,endcase
endtask

19

20

/* increment register and memory contents */


task inr;
case(ir[5:3])
0: doinc(regb); // INR B
1: doinc(regc); // INR C
2: doinc(regd); // INR D
3: doinc(rege); // INR E
4: doinc(regh); // INR H
5: doinc(regl); // INR L
6: // INR M
begin
memread(data, {regh, regl});
doinc(data);
memwrite(data, {regh, regl});
end

/* move register and memory immediate */


task movi;
begin
case(ir[5:3])
0: memread(regb, pc);
// MVI B, -1: memread(regc, pc);
// MVI C, -2: memread(regd, pc);
// MVI D, -3: memread(rege, pc);
// MVI E, -4: memread(regh, pc);
// MVI H, -5: memread(regl, pc);
// MVI L, -6:
// MVI M, -- ; ((H)(L)) <-- (byte 2)
begin
memread(data, pc);
memwrite(data, {regh, regl});
end

7: doinc(acc); // INR A
endcase
endtask

7: memread(acc, pc); // MVI A


endcase
pc = pc + 1;
end
endtask
21

/* enabled only from incrm */


task doinc;
inout[7:0] sr;
begin
cac = sr[3:0] == 'b1111;//auxiliary carry is set least 4 bits = 1111
// i.e., ac is 1 when ----1111 is incremented
//by one
sr = sr + 1;
calpsz(sr);
end
endtask

22

/* store and load instruction */


task sta_lda;
reg[15:0] ra;
case(ir[5:3])
0: memwrite(acc, {regb, regc}); // STAX B
1: memread(acc, {regb, regc}); // LDAX B
2: memwrite(acc, {regd, rege}); // STAX D
3: memread(acc, {regd, rege}); // LDAX D
4: // SHLD
begin
adread(ra);
memwrite(regl, ra);
memwrite(regh, ra + 1);
end
5: // LHLD
begin
adread(ra);
memread(regl, ra);
memread(regh, ra + 1);
end

/* calculate cp cs and cz */
task calpsz;
input[7:0] tr;
begin
cp = ^tr;
//parity, ^Exclusive or all bits of tr
cz = tr == 0; //zero flag
cs = tr[7];
//sign flag
end
endtask
23

24

6: // STA
begin
adread(ra);
memwrite(acc, ra);
end
7: // LDA
begin
adread(ra);
memread(acc, ra);
end
endcase
endtask
/* fetch address from pc+1, pc+2 */
task adread;
output[15:0] address;
begin
memread(address[7:0], pc);
pc = pc + 1;
memread(address[15:8], pc);
if(!int) pc = pc + 1; // if interrupt is not true, pc = pc+1
end
endtask

/* memory read */
task memread;
output[7:0] rdata;
input[15:0] raddr;
begin
@(posedge clock)
addr = raddr;
s = 0;
acontrol = 1;
dcontrol = 1;
iomff = int;
s0ff = int;
s1ff = 1;
aleff = 1;
@(posedge clock)
aleff = 0;

@(posedge clock)
dcontrol = 0;
if(int)
intaff = 0;
else
read = 0;
@(posedge clock)
ready_hold;
checkint;
@(posedge clock)
intaff = 1;
read = 1;
rdata = ad;
if(holdff) holdit;
end
endtask

25

26

Logic and Arithmetic operations


/* memory write */
task memwrite;
input[7:0] wdata;
input[15:0] waddr;
begin
@(posedge clock)
aleff = 1;
s0ff = 1;
s1ff = 0;
s = 0;
iomff = 0;
addr = waddr;
acontrol = 1;
dcontrol = 1;
@(posedge clock)
aleff = 0;

CMA
(A) (A)
CMC
(CY) (CY)

@(posedge clock)
data = wdata;
write = 0;
s = 1;
@(posedge clock)
ready_hold;
checkint;

STC
ANI data
ANA r
ANA M
ORI
ORA r
ORA M
XRI data
XRA r
XRA M
CPI data
CMP r
CMP M

@(posedge clock)
write = 1;
if(holdff) holdit;
end
endtask

27

// complement the accumulator


// complement the carry flag
// set the carry flag
// AND immediate, A and with byte 2
// A and with register r
// A and with memory
// OR immediate, A or with byte 2
// A or with register r
// A or with memory
// Exclusive_OR immediate
// A xor with register r
// A xor with memory
// compare immediate
// compare register
// compare memory
28

RLC
rotate accumulator left
(CY) A7;
A0 A7;

An+1 An

RRC
rotate accumulator right
(CY) A0;
A7 A0;

An An+1

RAL
RAR

rotate left through carry


rotate right through carry

ADD r add register


(A) (A) + (r)
ADD M add memory
ADI data add immediate
ADC r add register with carry
ADC M add memory with carry
ACI data add immediate with carry
SUB r subtract register
SUB M subtract memory
SUI data subtract immediate
SBB r subtract register with borrow
SBB M subtract memory with borrow

SBI data

subtract immediate with borrow

INR r
INR M
DCR r
DCR M
INX rp
DCX rp

increment register
increment memory
decrement register
decrement memory
increment register pair
decrement register pair

DAD rp
DAA

add register pair to H and L


decimal adjust accumulator

29

/* operate on accumulator */
task doacci;
input[7:0] sr;
reg[3:0] null4;
reg[7:0] null8;
case(ir[5:3])
0: // ADD ADI
begin
{cac, null4} = acc + sr;
{cc, acc} = {1'b0, acc} + sr;
calpsz(acc);
end
1: // ADC ACI
begin
{cac, null4} = acc + sr + cc;
{cc, acc} = {1'b0, acc} + sr + cc;
calpsz(acc);
end

30

5: // XRA XRI
begin
acc = acc ^ sr;
cac = 0;
cc = 0;
calpsz(acc);
end

2: // SUB SUI
begin
{cac, null4} = acc - sr;
{cc, acc} = {1'b0, acc} - sr;
calpsz(acc);
end
3: // SBB SBI
begin
{cac, null4} = acc - sr - cc;
{cc, acc} = {1'b0, acc} - sr - cc;
calpsz(acc);
end
4: // ANA ANI
begin
acc = acc & sr;
cac = 1;
cc = 0;
calpsz(acc);
end
31

6: // ORA ORI
begin
acc = acc | sr;
cac = 0;
cc = 0;
calpsz(acc);
end
7: // CMP CPI
begin
{cac, null4} = acc - sr;
{cc, null8} = {1'b0, acc} - sr;
calpsz(null8);
end
endcase
endtask

32

/* rotate acc and special instructions */


task racc_spec;
case(ir[5:3])
0: // RLC
begin
acc = {acc[6:0], acc[7]};
cc = acc[7];
end

3: // RAR
{acc, cc} = {cc, acc};
4: // DAA, decimal adjust
begin
if((acc[3:0] > 9) || cac) acc = acc + 6;
if((acc[7:4] > 9) || cc) {cc, acc} = {1'b0, acc} + 'h60;
end

1: // RRC
begin
acc = {acc[0], acc[7:1]};
cc = acc[0];
end

5: // CMA
acc = ~acc;
6: // STC
cc = 1;

2: // RAL
{cc, acc} = {acc, cc};

7: // CMC
cc = ~cc;
endcase
endtask

33

/* increment and decrement register pair */


task inx_dcx;
case(ir[5:3])
0: {regb, regc} = {regb, regc} + 1;
1: {regb, regc} = {regb, regc} - 1;
2: {regd, rege} = {regd, rege} + 1;
3: {regd, rege} = {regd, rege} - 1;
4: {regh, regl} = {regh, regl} + 1;
5: {regh, regl} = {regh, regl} - 1;
6: sp = sp + 1;
7: sp = sp - 1;
endcase
endtask
/* load register pair immediate */
task lrpi;
case(ir[5:4])
0: adread({regb, regc});
1: adread({regd, rege});
2: adread({regh, regl});
3: adread(sp);
endcase
endtask

34

/* add into regh, regl pair */


task addhl;
begin
case(ir[5:4])
0: {cc, regh, regl} = {1'b0, regh, regl} + {regb, regc}; // DAD B
1: {cc, regh, regl} = {1'b0, regh, regl} + {regd, rege}; // DAD D
2: {cc, regh, regl} = {1'b0, regh, regl} + {regh, regl}; // DAD H
3: {cc, regh, regl} = {1'b0, regh, regl} + sp;
// DAD SP
endcase
end
endtask

// INX B
// DCX B
// INX D
// DCX D
// INX H
// DCX H
// INX SP
// DCX SP

// LXI B
// LXI D
// LXI H
// LXI SP
35

36

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