Data Transfer Instructions

advertisement
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
2
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
3
4
S0, S1 (Output)
Data Bus Status. Encoded status of the bus cycle:
S1 S0
0 0
0 1
1 0
1 1
HALT
WRITE
READ
FETCH
RD (Output 3state)
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
READY (Input)
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.
HOLD (Input)
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.
6
HLDA (Output)
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.
RESTART INTERRUPTS;
These three inputs have the same timing as INTR except they cause
an internal RESTART to be automatically inserted.
RST 7.5 Highest Priority
RST 6.5
RST 5.5 Lowest Priority
The priority of these interrupts is ordered as shown above.
These interrupts have a higher priority than the INTR.
7
TRAP (Input)
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.
Name
RESTART Address (Hex)
TRAP
RST 5.5
RST 6.5
RST 7.5
2416
2C16
3416
3C16
RESET IN (Input)
Reset sets the Program Counter to zero and resets the Interrupt Enable
and HLDA flip flops.
8
IO/M (Output)
IO/M indicates whether the Read/Write is to memory or l/O
Tristated during Hold and Halt modes.
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.
CLK (Output)
Clock Output for use as a system clock
9
module s85; // simulation testbench module
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
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;
10
//instantiate the clock
osc timebase(clock);
//instantiate the RAM module
ram85a
r0(ale, ad, a, write, read, iomout);
//instantiate the 8085a processor module
intel_8085a i85(clock, , , , , trap,
rst7p5, rst6p5, rst5p5, intr, ,
ad, a, s0, ale, write, read, ,
iomout, ready, nreset,
, , hold);
initial
begin
$write("\n");
…..
…..
endmodule
11
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);
reg [8:1]
dflags;
initial
dflags = 'b000;
// diag flags:
// 1 = trace instructions
// 2 = trace IN and OUT instructions
// 3 = trace instruction count
output
resetff, sodff, intaff, s0, aleff,
writeout, readout, s1, iomout, clockff, hldaff;
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
// 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
intaff,
trapff,
trapi,
inte,
int,
validint,
haltff,
resetff,
clockff,
sodff,
read,
write,
iomff,
acontrol,
dcontrol,
s,
cs,
cz,
cac,
cp,
cc;
// 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
14
The condition flags
Z
Zero
S
Sign
P
Parity
C
Carry
A
Auxiliary carry
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
15
Overview of Instruction set
1. Data Transfer Group
2. Logic Group
3. Branch Group
4. Stack and Machine Control Group
5. Arithmetic Group
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
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
17
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
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
19
/* 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
20
/* 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: memread(acc, pc); // MVI A
endcase
pc = pc + 1;
end
endtask
21
/* 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
7: doinc(acc); // INR A
endcase
endtask
22
/* 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
/* 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
/* 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
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
25
/* 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
26
/* 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;
@(posedge clock)
data = wdata;
write = 0;
s = 1;
@(posedge clock)
ready_hold;
checkint;
@(posedge clock)
write = 1;
if(holdff) holdit;
end
endtask
27
Logic and Arithmetic operations
CMA
(A)  (A)
CMC
(CY)  (CY)
// complement the accumulator
STC
ANI data
ANA r
ANA M
ORI
ORA r
ORA M
XRI data
XRA r
XRA M
CPI data
CMP r
CMP M
// 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
// complement the carry flag
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
29
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
30
/* 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
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
5: // XRA XRI
begin
acc = acc ^ sr;
cac = 0;
cc = 0;
calpsz(acc);
end
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
1: // RRC
begin
acc = {acc[0], acc[7:1]};
cc = acc[0];
end
2: // RAL
{cc, acc} = {acc, cc};
33
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
5: // CMA
acc = ~acc;
6: // STC
cc = 1;
7: // CMC
cc = ~cc;
endcase
endtask
34
/* 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
// 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
/* 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
36
Download