⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.~pas

📁 动态调度算法实验
💻 ~PAS
📖 第 1 页 / 共 4 页
字号:
    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 + -