📄 8251_8055_verilog.txt
字号:
end
endtask
/* fetch and execute instructions */
task execute_instructions;
forever begin
instruction = instruction + 1;
if(dflags[3])
$display("executing instruction %d", instruction);
@ec1 // clock cycle 1
addr = pc;
s = 0;
iomff = 0;
read = 1;
write = 1;
acontrol = 1;
dcontrol = 1;
aleff = 1;
if(haltff) begin
haltff = 1;
s0ff = 0;
s1ff = 0;
haltreq;
end
else begin
s0ff = 1;
s1ff = 1;
end
@ec2
aleff = 0;
@ec1 // clock cycle 2
read = 0;
dcontrol = 0;
@ec2
ready_hold;
@ec2 // clock cycle 3
read = 1;
data = ad;
ir = ad;
@ec1 // clock cycle 4
if(do6cycles(ir)) begin
// do a 6-cycle instruction fetch
@ec1 @ec2 // conditional clock cycle 5
if(hold) begin
holdff =1 ;
acontrol = 0;
dcontrol = 0;
@ec2 hldaff = 1;
end
else begin
holdff = 0;
hldaff = 0;
end
@ec1; // conditional clock cycle 6
end
if(holdff) holdit;
checkint;
do_instruction;
while(hold) @ec2 begin
acontrol = 0;
dcontrol = 0;
end
holdff = 0;
hldaff = 0;
if(validint) interrupt;
end
endtask
function do6cycles;
input[7:0] ireg;
begin
do6cycles = 0;
case(ireg[2:0])
0, 4, 5, 7: if(ireg[7:6] == 3) do6cycles = 1;
1: if((ireg[3] == 1) && (ireg[7:5] == 7)) do6cycles = 1;
3: if(ireg[7:6] == 0) do6cycles = 1;
endcase
end
endfunction
task checkint;
begin
if(rst6p5)
if((intmask[3] == 1) && (intmask[1] == 0)) intmask[6] = 1;
else
intmask[6] = 0;
if(rst5p5)
if((intmask[3] == 1) && (intmask[0] == 0)) intmask[5] = 1;
else
intmask[5] = 0;
if({intmask[7], intmask[3:2]} == 6)
intmask[4] = 1;
else
intmask[4] = 0;
validint = (intmask[6:4] == 7) | trapff | intr;
end
endtask
// concurently with executing instructions,
// process primary inputs for processor interrupt
always @(posedge trap) trapff = 1;
always @(negedge trap) trapff = 0;
always @(posedge rst7p5) intmask[7] = 1;
/* check condition of ready and hold inputs */
task ready_hold;
begin
while(!ready) @ec2;
@ec1
if(hold) begin
holdff = 1;
@ec2 hldaff = 1;
end
end
endtask
/* hold */
task holdit;
begin
while(hold) @ec2 begin
acontrol = 0;
dcontrol = 0;
end
holdff = 0;
@ec2 hldaff = 0;
end
endtask
/* halt request */
task haltreq;
forever begin
@ec2
if(validint) begin
haltff = 0;
interrupt;
disable haltreq;
end
else begin
while(hold) @ec2 hldaff = 1;
hldaff = 0;
@ec2;
end
@ec1 #10
dcontrol = 0;
acontrol = 0;
checkint;
end
endtask
/* memory read */
task memread;
output[7:0] rdata;
input[15:0] raddr;
begin
@ec1
addr = raddr;
s = 0;
acontrol = 1;
dcontrol = 1;
iomff = int;
s0ff = int;
s1ff = 1;
aleff = 1;
@ec2
aleff = 0;
@ec1
dcontrol = 0;
if(int)
intaff = 0;
else
read = 0;
@ec2
ready_hold;
checkint;
@ec2
intaff = 1;
read = 1;
rdata = ad;
if(holdff) holdit;
end
endtask
/* memory write */
task memwrite;
input[7:0] wdata;
input[15:0] waddr;
begin
@ec1
aleff = 1;
s0ff = 1;
s1ff = 0;
s = 0;
iomff = 0;
addr = waddr;
acontrol = 1;
dcontrol = 1;
@ec2
aleff = 0;
@ec1
data = wdata;
write = 0;
s = 1;
@ec2
ready_hold;
checkint;
@ec2
write = 1;
if(holdff) holdit;
end
endtask
/* reads from an i/o port */
task ioread;
input[7:0] sa;
begin
@ec1
aleff = 1;
s0ff = 0;
s1ff = 1;
s = 0;
iomff = 1;
addr = {sa, sa};
acontrol = 1;
dcontrol = 1;
@ec2
aleff = 0;
@ec1
dcontrol = 0;
if(int)
intaff = 0;
else
read = 0;
@ec2
ready_hold;
checkint;
@ec2
intaff = 1;
read = 1;
acc = ad;
if(dflags[2])
$display("IN %h data = %h", sa, acc);
end
endtask
/* writes into i/o port */
task iowrite;
input[7:0] sa;
begin
@ec1
addr = {sa, sa};
aleff = 1;
s0ff = 1;
s1ff = 0;
s = 0;
iomff = 1;
acontrol = 1;
dcontrol = 1;
@ec2
aleff = 0;
@ec1
data = acc;
write = 0;
s = 1;
if(dflags[2])
$display("OUT %h data = %h", sa, acc);
@ec2
ready_hold;
checkint;
@ec2
write = 1;
if(holdff) holdit;
end
endtask
task interrupt;
begin
@ec1
if(hold) begin
holdff = 1;
holdit;
@ec2 hldaff = 1;
end
if(trapff) begin
inte = intmask[3];
trapi = 1;
intic;
pc = 'h24;
trapi = 1;
trapff = 0;
end
else if(intmask[7]) begin
intic;
pc = 'h3c;
intmask[7] = 0;
end
else if(intmask[6]) begin
intic;
pc = 'h34;
intmask[6] = 0;
end
else if(intmask[5]) begin
intic;
pc = 'h2c;
intmask[5] = 0;
end
else if(intr) begin
//?
end
end
endtask
task intic;
begin
aleff = 1;
s0ff = 1;
s1ff = 1;
s = 0;
iomff = 1;
addr = pc;
read = 1;
write = 1;
acontrol = 1;
dcontrol = 1;
@ec2 aleff = 0;
@ec1 dcontrol = 0;
repeat(4) @ec1;
push2b(pc[15:8], pc[7:0]);
end
endtask
/* execute instruction */
task do_instruction;
begin
if(dflags[1])
$display( "C%bZ%bM%bE%bI%b A=%h B=%h%h D=%h%h H=%h%h S=%h P=%h IR=%h",
cc, cz, cs, cp, cac, acc, regb,regc, regd,rege, regh,regl,
sp, pc, ir);
pc = pc + 1;
@ec2 // instruction decode synchronized with clock 2 event
case(ir[7:6])
0:
case(ir[2:0])
0: newops;
1: if(ir[3]) addhl; else lrpi;
2: sta_lda;
3: inx_dcx;
4: inr;
5: dcr;
6: movi;
7: racc_spec;
endcase
1:
move;
2:
rmop;
3:
case(ir[2:0])
0,
2,
4: condjcr;
1: if(ir[3]) decode1; else pop;
3: decode2;
5: if(ir[3]) decode3; else push;
6: immacc;
7: restart;
endcase
endcase
end
endtask
/* 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) haltff = 1; // HLT
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
/* 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
begin
memread(data, pc);
memwrite(data, {regh, regl});
end
7: memread(acc, pc); // MVI A
endcase
pc = pc + 1;
end
endtask
/* 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
/* enabled only from incrm */
task doinc;
inout[7:0] sr;
begin
cac = sr[3:0] == 'b1111;
sr = sr + 1;
calpsz(sr);
end
endtask
/* decrement register and memory contents */
task dcr;
case(ir[5:3])
0: dodec(regb); // DCR B
1: dodec(regc); // DCR C
2: dodec(regd); // DCR D
3: dodec(rege); // DCR E
4: dodec(regh); // DCR H
5: dodec(regl); // DCR L
6: // DCR M
begin
memread(data, {regh, regl});
dodec(data);
memwrite(data, {regh, regl});
end
7: dodec(acc); // DCR A
endcase
endtask
/* enabled only from decrm */
task dodec;
inout[7:0] sr;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -