📄 main.~pas
字号:
if (instr[i].WriteResult>0 ) then
StatusGrid.Cells[2,i]:=inttostr(instr[i].WriteResult);
end;
RefreshRU;
RefreshFU;
RefreshMEM;
{ Refresh LoadGrid }
for i:=1 to LOADSIZE do
begin
if Load[i].Busy then
begin
LoadGrid.Cells[1,i]:='YES';
if (Load[i].Time=0) then
LoadGrid.Cells[3,i]:=floattostr(Load[i].cache);
end
else
LoadGrid.Cells[1,i]:='NO';
LoadGrid.cells[2,i]:=Load[i].Address;
end;
{ Refresh StoreGrid }
for i:=1 to STORESIZE do
begin
if Store[i].Busy then
StoreGrid.Cells[1,i]:='YES'
else
StoreGrid.Cells[1,i]:='NO';
StoreGrid.cells[2,i]:=Store[i].Address;
StoreGrid.Cells[3,i]:=Store[i].Qi.data;
end;
{ Refresh Reservation Grid }
for i:=1 to RSSIZE do
if RS[i].Busy then
begin
//if RS[i].StartCount then
ReservationGrid.cells[0,i]:=inttostr(RS[i].Time);
//ReservationGrid.cells[1,i]:=RS[i].Name;
ReservationGrid.cells[2,i]:='YES';
case (RS[i].OP) of
ADDD: ReservationGrid.cells[3,i]:='ADDD';
SUBD: ReservationGrid.cells[3,i]:='SUBD';
MULTD: ReservationGrid.cells[3,i]:='MULTD';
DIVD: ReservationGrid.cells[3,i]:='DIVD';
end;
ReservationGrid.cells[4,i]:=RS[i].Vj.data;
ReservationGrid.cells[5,i]:=RS[i].Vk.data;
ReservationGrid.cells[6,i]:=RS[i].Qj.data;
ReservationGrid.cells[7,i]:=RS[i].Qk.data;
end else
ReservationGrid.cells[2,i]:='NO';
end;
procedure Tform1.SetRSOperand(row:integer; pc:integer);
var i:integer;
begin
i:=row;
case (instr[pc].OpSourcej.OpType) of
FUTYPE:
if (FU[instr[pc].OpSourcej.index].status = NONAVAILABLE) then
begin
RS[i].Qj.status:=NONAVAILABLE;
RS[i].Qj.data:=FU[instr[pc].OpSourcej.index].data;
RS[i].Vj.status:=NONAVAILABLE;
RS[i].Vj.data:='';
end else
begin
RS[i].Qj.status:=AVAILABLE;
RS[i].Qj.data:='';
RS[i].Vj.status:=AVAILABLE;
if (FU[instr[pc].OpSourcej.index].data<>'') then
begin
RS[i].Vj.data:=FU[instr[pc].OpSourcej.index].data;
RS[i].Vj.fvalue:=FU[instr[pc].OpSourcej.index].fvalue;
end
else
begin
RS[i].Vj.data:='R(F'+inttostr(instr[pc].OpSourcej.index)+')';
RS[i].Vj.fvalue:=FU[instr[pc].OpSourcej.index].fvalue;
end;
end;
RUTYPE:
begin
RS[i].Qj.status:=AVAILABLE;
RS[i].Qj.data:='';
RS[i].Vj.status:=AVAILABLE;
//RS[i].Vj.data:=FU[instr[pc].OpSourcej.index].data;
RS[i].Vj.data:='R'+inttostr(instr[pc].OpSourcej.index);
RS[i].Vj.fvalue:=RU[instr[pc].OpSourcej.index].fvalue;
end;
IMMTYPE:
//error process
else begin end;
end;
case (instr[pc].OpSourcek.OpType) of
FUTYPE:
if (FU[instr[pc].OpSourcek.index].status = NONAVAILABLE) then
begin
RS[i].Qk.status:=NONAVAILABLE;
RS[i].Qk.data:=FU[instr[pc].OpSourcek.index].data;
RS[i].Vk.status:=NONAVAILABLE;
RS[i].Vk.data:='';
end else
begin
RS[i].Qk.status:=AVAILABLE;
RS[i].Qk.data:='';
RS[i].Vk.status:=AVAILABLE;
if (FU[instr[pc].OpSourcek.index].data<>'') then
begin
RS[i].Vk.data:=FU[instr[pc].OpSourcek.index].data;
RS[i].Vk.fvalue:=FU[instr[pc].OpSourcek.index].fvalue;
end
else
RS[i].Vk.data:='R(F'+inttostr(instr[pc].OpSourcek.index)+')';
RS[i].Vk.fvalue:=FU[instr[pc].OpSourcek.index].fvalue;
end;
RUTYPE:
begin
RS[i].Qk.status:=AVAILABLE;
RS[i].Qk.data:='';
RS[i].Vk.status:=AVAILABLE;
RS[i].Vk.data:='R'+inttostr(instr[pc].OpSourcek.index);
RS[i].Vk.fvalue:=RU[instr[pc].OpSourcek.index].fvalue;
end;
IMMTYPE:
//error process
else begin end;
end;
end;
procedure Tform1.IssueProcess;
var i:integer;
str1:string;
begin
case Instr[pc].OP of
LD:begin
for i:=1 to LOADSIZE do
if not Load[i].Busy then
with Load[i] do
begin
DrawFromInstrToLoad(PC,i);
Busy:=true;
Address:=Instr[pc].OpSourcej.data+'+'+Instr[pc].OpSourcek.data;
AddressValue:=Instr[pc].OpSourcej.value+Instr[pc].OpSourcek.value;
Time:=2;
// DestType:=Instr[pc].OpDest.OpType;
// Dest:=Instr[pc].OpDest.index;
Load[i].oldPC:=pc;
if (instr[pc].OpDest.OpType = FUTYPE) then
begin
FU[instr[pc].OpDest.index].data:='Load'+inttostr(i);
FU[instr[pc].OpDest.index].status:=NONAVAILABLE;
DrawFromInstrToFU(PC,instr[pc].OpDest.index);
end;
break;
end;
end;
SD:begin
for i:=1 to STORESIZE do
if not Store[i].Busy then
with Store[i] do
begin
Busy:=true;
complete:=false;
Time:=2;
oldPC:=pc;
Address:=Instr[pc].OpSourcej.data+'+'+Instr[pc].OpSourcek.data;
AddressValue:=Instr[pc].OpSourcej.value+Instr[pc].OpSourcek.value;
if (Instr[pc].OpDest.Optype = FUTYPE) then
begin // 这里的OpDest表示要写入的数据所在的寄存器
if (FU[instr[pc].OpDest.index].Status = AVAILABLE) then
begin // 数值可用
Qi.data:='F'+inttostr(instr[pc].OpDest.index);
Qi.Status:=AVAILABLE;
Qi.fvalue:=FU[instr[pc].OpDest.index].fvalue;
end
else
begin
Qi.data:=FU[Instr[pc].OpDest.index].data;
Qi.Status:=NONAVAILABLE;
end;
end;
break;
end;
end;
ADDD:
begin
for i:=1 to ADDERSIZE do
if not RS[i].Busy then
with RS[i] do
begin
DrawFromInstrToRS(PC,i); //数据流表示
Busy:=true;
oldPC:=pc;
Time:=2;
RS[i].OP:=ADDD;
SetRSOperand(i,pc);
if (RS[i].Qj.status = AVAILABLE) and (RS[i].Qk.status = AVAILABLE) then
StartCount:=true;
if (instr[pc].OpDest.OpType = FUTYPE) then
begin
FU[instr[pc].OpDest.index].data:='Add'+inttostr(i);
FU[instr[pc].OpDest.index].status:=NONAVAILABLE;
DrawFromInstrToFU(PC,instr[pc].OpDest.index);
end;
break;
end;
end;
SUBD:
begin
for i:=1 to ADDERSIZE do
if not RS[i].Busy then
with RS[i] do
begin
DrawFromInstrToRS(PC,i); //数据流表示
Busy:=true;
oldPC:=pc;
Time:=2;
RS[i].OP:=SUBD;
SetRSOperand(i,pc);
if (RS[i].Qj.status = AVAILABLE) and (RS[i].Qk.status = AVAILABLE) then
StartCount:=true;
if (instr[pc].OpDest.OpType = FUTYPE) then
begin
FU[instr[pc].OpDest.index].data:='Add'+inttostr(i);
FU[instr[pc].OpDest.index].status:=NONAVAILABLE;
DrawFromInstrToFU(PC,instr[pc].OpDest.index);
end;
break;
end;
end;
MULTD:
begin
for i:=ADDERSIZE+1 to ADDERSIZE+MULTIPLIERSIZE do
if not RS[i].Busy then
with RS[i] do
begin
DrawFromInstrToRS(PC,i); //数据流表示
Busy:=true;
oldPC:=PC;
Time:=10;
RS[i].OP:=MULTD;
SetRSOperand(i,pc);
if (RS[i].Qj.status = AVAILABLE) and (RS[i].Qk.status = AVAILABLE) then
StartCount:=true;
if (instr[PC].OpDest.OpType = FUTYPE) then
begin
FU[instr[pc].OpDest.index].data:='Mult'+inttostr(i-ADDERSIZE);
FU[instr[pc].OpDest.index].status:=NONAVAILABLE;
DrawFromInstrToFU(PC,instr[pc].OpDest.index);
end;
break;
end;
end;
DIVD:
begin
for i:=ADDERSIZE+1 to ADDERSIZE+MULTIPLIERSIZE do
if not RS[i].Busy then
with RS[i] do
begin
Busy:=true;
oldPC:=pc;
Time:=40;
RS[i].OP:=DIVD;
SetRSOperand(i,pc);
if (RS[i].Qj.status = AVAILABLE) and (RS[i].Qk.status = AVAILABLE) then
StartCount:=true;
if (instr[pc].OpDest.OpType = FUTYPE) then
begin
FU[instr[pc].OpDest.index].data:='Mult'+inttostr(i-ADDERSIZE);
FU[instr[pc].OpDest.index].status:=NONAVAILABLE;
DrawFromInstrToFU(PC,instr[pc].OpDest.index);
end;
break;
end;
end;
else
begin
end;
end;
end;
procedure Tform1.BroadcastResult(BroadType:BroadCastType; index:integer; UnitName:string; data:string; fvalue:real); //广播结果到预约站
//procedure Tform1.BroadcastResult(index:string; data:string; fvalue:real);
var i:integer;
begin
for i:=1 to RSSIZE do
if RS[i].Busy then
begin
if (RS[i].Qj.status = NONAVAILABLE) and (RS[i].Qj.data=UnitName)then
begin
RS[i].Qj.data:='';
RS[i].Qj.status:=AVAILABLE;
RS[i].Vj.data:=data;
RS[i].Vj.status:=AVAILABLE;
RS[i].Vj.fvalue:=fvalue;
//if (RS[i].Qk.status=AVAILABLE) then RS[i].StartCount:=true;
end;
if (RS[i].Qk.status = NONAVAILABLE) and (RS[i].Qk.data=UnitName)then
begin
RS[i].Qk.data:='';
RS[i].Qk.status:=AVAILABLE;
RS[i].Vk.data:=data;
RS[i].Vk.fvalue:=fvalue;
RS[i].Vk.status:=AVAILABLE;
//if (RS[i].Qj.status=AVAILABLE) then RS[i].StartCount:=true;
end;
end;
for i:=0 to FUSIZE do
if (FU[i].status = NONAVAILABLE) and (FU[i].data=UnitName) then
begin
Case (BroadType) of
LoadType: DrawFromLoadToFU(index,i);
AddType: DrawFromRStoFU(index,i);//DrawFromRSToFU(index,i);
MultType: DrawFromRStoFU(index+ADDERSIZE,i);//DrawFromRSToFU(index+ADDERSIZE,i);
end;
FU[i].data:=data;
FU[i].fvalue:=fvalue;
FU[i].status:=AVAILABLE;
end;
for i:=1 to STORESIZE do
if (Store[i].Busy) and (Store[i].Qi.Status=NONAVAILABLE) and (Store[i].Qi.data=UnitName) then
begin
Store[i].Qi.fvalue:=fvalue;
Store[i].Qi.Status:=AVAILABLE;
end;
end;
function Tform1.ReadMem(address:integer):real;
var i:integer;
begin
for i:=1 to MemNum do
if (Mem[i].Address = address) then
begin
ReadMem:=Mem[i].fvalue;
exit;
end;
ReadMem:=0;
end;
procedure Tform1.WriteMem(address:integer; fvalue:real);
var i:integer;
begin
for i:=1 to MemNum do
if (Mem[i].Address = address) then
begin
Mem[i].fvalue:=fvalue;
exit;
end;
Inc(MemNum);
Mem[MemNum].Address:=address;
Mem[MemNum].fvalue:=fvalue;
end;
procedure Tform1.ResponseClockEvent;
var i:integer;
begin
for i:=1 to RSSIZE do
if (RS[i].Busy) and (RS[i].StartCount) and (RS[i].Time>0) then
begin // 对预约站的所有正在计数的计算单元处理始终响应
RS[i].Time:=RS[i].Time-1;
if (RS[i].Time = 0) then
instr[RS[i].oldPC].ExecutionComplete:=Clock.count;
end
else
if (Instr[RS[i].oldPC].ExecutionComplete>0) and (Instr[RS[i].oldPC].WriteResult=Clock.count)
then // 在写回时进行广播
begin
RS[i].Busy:=false;
Rs[i].Qj.status:=AVAILABLE;
Rs[i].Qk.status:=AVAILABLE;
case RS[i].OP of
ADDD:
BroadcastResult(AddType,i,RS[i].Name,RS[i].Vj.data+'+'+RS[i].Vk.data,RS[i].Vj.fvalue+RS[i].Vk.fvalue);
SUBD:
BroadcastResult(AddType,i,RS[i].Name,RS[i].Vj.data+'-'+RS[i].Vk.data,RS[i].Vj.fvalue-RS[i].Vk.fvalue);
MULTD:
BroadcastResult(MultType,i-ADDERSIZE,RS[i].Name,RS[i].Vj.data+'*'+RS[i].Vk.data,RS[i].Vj.fvalue*RS[i].Vk.fvalue);
DIVD:
if (RS[i].Vk.fvalue<>0) then
BroadcastResult(MultType,i-ADDERSIZE,RS[i].Name,RS[i].Vj.data+'/'+RS[i].Vk.data,RS[i].Vj.fvalue/RS[i].Vk.fvalue)
else // error process
BroadcastResult(MultType,i-ADDERSIZE,RS[i].Name,RS[i].Vj.data+'/'+RS[i].Vk.data,0)
else begin end;
end;
Rs[i].Vj.data:='';
Rs[i].Vk.data:='';
Rs[i].Qj.data:='';
Rs[i].Qk.data:='';
ReservationGrid.cells[3,i]:='';
ReservationGrid.cells[4,i]:=RS[i].Vj.data;
ReservationGrid.cells[5,i]:=RS[i].Vk.data;
ReservationGrid.cells[6,i]:=RS[i].Qj.data;
ReservationGrid.cells[7,i]:=RS[i].Qk.data;
end;
for i:=1 to LOADSIZE do
if (Load[i].Busy) then
begin
if (Load[i].Time>0) then
begin
Load[i].Time:=Load[i].Time-1;
if Load[i].Time = 0 then
begin
Instr[Load[i].oldPC].ExecutionComplete:=Clock.count;
Load[i].cache:=ReadMem(Load[i].AddressValue);
DrawFromMemToLoad(Load[i].AddressValue,i);
//mem->load
end;
end
else
if (Instr[Load[i].oldPC].ExecutionComplete>0) and (Instr[Load[i].oldPC].WriteResult=Clock.count)then
begin
Load[i].Busy:=false; //广播结果
BroadcastResult(LoadType,i,'Load'+inttostr(i),'M('+Load[i].Address+')',Load[i].cache);
Load[i].Address:='';
end;
end;
for i:=1 to STORESIZE do
if (Store[i].Busy) then
begin
if (Store[i].Time>0) and (Store[i].Qi.Status = AVAILABLE) then
begin
Dec(Store[i].Time);
if (Store[i].Time = 0) then
begin
//store to memory mem[address]:=Qi
Instr[Store[i].oldPC].ExecutionComplete:=Clock.count;
WriteMem(Store[i].AddressValue,Store[i].Qi.fvalue);
end;
end
else
if (Instr[Store[i].oldPC].ExecutionComplete>0) and (Instr[Store[i].oldPC].WriteResult=Clock.count)then
begin
Store[i].busy:=false;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -