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

📄 main.~pas

📁 动态调度算法实验
💻 ~PAS
📖 第 1 页 / 共 4 页
字号:
unit main;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Grids, StdCtrls, Mask, Buttons, Menus, ToolWin, ComCtrls,Input,SetValue,
  ExtCtrls, jpeg,ClockSpeed,about;

{ constant define }
const LOADSIZE = 3;       // LOAD等待队列的大小
const STORESIZE = 3;      // STORE等待队列的大小
const ADDERSIZE = 3;      // 浮点加法器个数
const MULTIPLIERSIZE = 2; // 浮点乘法器个数
const QUEUESIZE=50;       // 指令队列长度
const RSSIZE=5;           // 预约站大小
const FUSIZE=10;          // 浮点寄存器个数
const RUSIZE=10;          // 整形寄存器个数
const MEMSIZE=20;         // 内存大小

type ModeType = (VALUE,NOVALUE);          //运行模式:带值计算或表达式运行
type StatusType=(AVAILABLE,NONAVAILABLE); //数据状态:有效或无效
type OperandType=(FUTYPE,RUTYPE,IMMTYPE); //操作数类型:浮点,整型,立即数
type InstructionType = (LD,SD,ADDD,SUBD,MULTD,DIVD,BNEZ); //指令类型
type BroadcastType=(LoadType,AddType,MultType);           //广播结果的功能单元类型
type ResourceType = (ADDER,MULTIPLIER);                   //资源类性

type MemRecord =record          // 内存纪录
     fvalue:real;               // 数值
     Address:integer;           // 地址
     end;

type OperandRecord = record     // 操作数纪录
     data:string;               // 数据表达式
     Optype:OperandType;        // 操作数类型
     Status:StatusType;         // 判断当前操作数是否有效
     index:integer;             // 寄存器号
     value:integer;             // 存整形值(仅对RUTYPE有效)
     fvalue:real;               // 存浮点值 (仅对FUTYPE有效)
     end;


type ReservationStation = record//预约站纪录
      StartCount: boolean;      // 是否开始计数
      Time: integer;            // 剩余时钟周期
      Name: string;             // 预约站部件名称
      RStype:ResourceType;      // 预约站部件类型
      Busy: boolean;            // 是否忙
      OP: InstructionType;      // 正在执行的指令类型
      Vj: OperandRecord;        // StatusRecord;
      Vk: OperandRecord;        // StatusRecord;
      Qj: OperandRecord;        // StatusRecord;
      Qk: OperandRecord;        // StatusRecord;
      oldPC: integer;           // 纪录那条指令
    end;

type InstructionRecord = record //指令纪录
      completed:boolean;        //是否执行完
      Name: string;             //指令名
      OP: InstructionType;      //指令类型
      OpDest: OperandRecord;    //目的操作数纪录
      OpSourcej: OperandRecord; //源操作数j纪录
      OpSourcek: OperandRecord; //源操作数k纪录
      //////Status Station////////
      Issue: integer;           //纪录发射周期
      ExecutionComplete:integer;//纪录执行周期
      WriteResult: integer;     //纪录写结果周期
      end;

type LoadRecord = record        //Load执行单元纪录
     Busy: boolean;             //忙信号
     Address: string;           //地址表达式
     AddressValue:integer;      //地址值
     Time:integer;              //剩余执行时间
     oldPC:integer;             //纪录执行指令的PC
     complete:boolean;          //读取操作是否执行完毕
     cache:real;                //缓存
     //.......
     end;

type StoreRecord = record       ////Load执行单元纪录
     Busy: boolean;             //忙信号
     Address: string;           //写入的内存地址表达式
     AddressValue:integer;      //写入的内存地址
     Time:integer;              //剩余执行时间
     oldPC:integer;             // 纪录Store指令的PC
     Qi:OperandRecord;          //StatusRecord;   // 写入值
     complete:boolean;          //是否store执行完
     //startcount:boolean;      // 是否开始计数,只有当写入数据有效时为真
     end;

type TClockClass = class        //时钟周期控制
public
    procedure startclock;
    procedure clearclock;
public
    count :integer;             //当前的时钟周期
    start :boolean;             //是否开始计时
end;

type
  TForm1 = class(TForm)
    { 各种控件 }
    StatusGrid: TStringGrid;
    ReservationGrid: TStringGrid;
    LoadGrid: TStringGrid;
    FUGrid: TStringGrid;
    Label1: TLabel;
    Label2: TLabel;
    InstructionGrid: TStringGrid;
    ClockLabel: TLabel;
    Label4: TLabel;
    Label5: TLabel;
    Label6: TLabel;
    MainMenu1: TMainMenu;
    File1: TMenuItem;
    X1: TMenuItem;
    H1: TMenuItem;
    O1: TMenuItem;
    Label7: TLabel;
    InstrNumLabel: TLabel;
    StoreGrid: TStringGrid;
    Label8: TLabel;
    Label9: TLabel;
    RUGrid: TStringGrid;
    MemGrid: TStringGrid;
    Label10: TLabel;
    Label11: TLabel;
    Label12: TLabel;
    Label13: TLabel;
    Label14: TLabel;
    Label15: TLabel;
    Label16: TLabel;
    Label17: TLabel;
    S1: TMenuItem;
    N1: TMenuItem;
    N2: TMenuItem;
    DefaulInput: TMenuItem;
    ManualInput: TMenuItem;
    ClearInstrMenu: TMenuItem;
    StartRun: TMenuItem;
    N3: TMenuItem;
    SetRUMenu: TMenuItem;
    SetMemMenu: TMenuItem;
    NextClock: TMenuItem;
    H2: TMenuItem;
    AboutA1: TMenuItem;
    ValueMenu: TMenuItem;
    NoValueMenu: TMenuItem;
    ToolBar1: TToolBar;
    NextSpeedButton: TSpeedButton;
    SpeedButton1: TSpeedButton;
    SpeedButton2: TSpeedButton;
    PaintBox1: TPaintBox;
    SpeedButton4: TSpeedButton;
    SpeedButton5: TSpeedButton;
    ToolButton1: TToolButton;
    ToolButton2: TToolButton;
    SpeedButton3: TSpeedButton;
    ToolButton3: TToolButton;
    SpeedButton6: TSpeedButton;
    SpeedButton7: TSpeedButton;
    ClockSpeedImage: TImage;
    Label3: TLabel;
    PCLabel: TLabel;

    procedure FormCreate(Sender: TObject);              // 创建窗口初始化
    procedure StartClick(Sender: TObject);              // 启动执行
    procedure SetRUMenuClick(Sender: TObject);          // 寄存器赋值
    procedure SetMemMenuClick(Sender: TObject);         // 内存赋值
    procedure NoValueMenuClick(Sender: TObject);        // NoValue Mode 表达式
    procedure ValueMenuClick(Sender: TObject);          // Value mode
    procedure ClearInstrMenuClick(Sender: TObject);     // 清除指令队列
    procedure DefaulInputClick(Sender: TObject);        // 默认输入
    procedure ManualInputClick(Sender: TObject);        // 手动输入
    procedure StartRunClick(Sender: TObject);           // 开始运行指令
    procedure NextClockClick(Sender: TObject);          // 进入下一个时钟运行
    procedure X1Click(Sender: TObject);
    procedure NextSpeedButtonClick(Sender: TObject);

    procedure SpeedButton1Click(Sender: TObject);
    procedure DrawFromInstrToLoad(Rowi,Rowj:integer);
    procedure SpeedButton4Click(Sender: TObject);
    procedure SpeedButton5Click(Sender: TObject);
    procedure SpeedButton6Click(Sender: TObject);
    procedure SpeedButton7Click(Sender: TObject);
    procedure SpeedButton3Click(Sender: TObject);
    procedure SpeedButton2Click(Sender: TObject);
    procedure TimerAction(Sender: TObject);             //控制自动播放Timer响应
    procedure ClockSpeedImageClick(Sender: TObject);             //控制始终速度
    procedure AboutA1Click(Sender: TObject);    //
  private
    { Private declarations }
  public
    { Public declarations }
    m_sAdd:string;
    PC:    integer;                                     // 当前指令计数器 PC
    FU:    array[0..FUSIZE] of OperandRecord;           // 浮点寄存器
    RU:    array[0..RUSIZE] of OperandRecord;           // 整形寄存器
    Mem:   array[1..MEMSIZE] of MemRecord;              // 内存
    memNum :integer;                                    // 当前有效内存单元数目
    InstrNum: integer;                                  // 指令条数
    Instr: array[1..QUEUESIZE] of InstructionRecord;    // 指令队列
    Load:  array[1..LOADSIZE] of  LoadRecord;           // Load缓冲栈
    Store: array[1..STORESIZE] of StoreRecord;          // Store缓冲栈
    RS:    array[1..RSSIZE] of ReservationStation;      // 保存站
    Clock : TClockClass;
    ModeFlag: MODETYPE;

  public
   {main methods 主程序主要功能}
    procedure InstrGridAdd(index:integer; opname,dest,sj,sk:string);
    function  CheckAllCompleted:boolean;
    function  CheckNoIssueConflict(pc:integer):boolean;
    procedure IssueProcess;
    procedure ResponseClockEvent;
    procedure BroadcastResult(BroadType:BroadCastType; index:integer; UnitName:string; data:string; fvalue:real); //广播结果到预约站
    procedure SetRSOperand(row:integer; pc:integer);
    procedure CheckStartCount;
    procedure ADDInstrFromInput(opname:string; di,sj,sk:string);
    function  ReadMem(address:integer):real;
    procedure WriteMem(address:integer; fvalue:real);
  public
    {Draw Dataflow 数据流画图}
    procedure DrawFromInstrToFU(Rowi,Colj:integer);
    procedure DrawFromInstrToRS(Rowi,Rowj:integer);
    procedure DrawFromLoadToFU(Rowi,Colj:integer);
    procedure DrawFromRSToFU(Rowi,Colj:integer);
    procedure DrawFromMemToLoad(Address:integer; Row:integer);
  public
    { Refresh 刷新方法}
    procedure RefreshInstrGrid;
    procedure RefreshIssue;
    procedure RefreshRU;
    procedure RefreshFU;
    procedure RefreshMem;

  public
    { Initial 初始化方法 }
    procedure InitialReservation;
    procedure InitialGrid;
    procedure InitialValue;
  end;

var
  Form1: TForm1;
  InputDlg1: TInputDlg;
  SetValueDlg1: TSetValueDlg;
  ClockSpeedDlg1: TClockSpeedDlg;
  timer1:Ttimer;
implementation

{$R *.dfm}

procedure TClockClass.clearclock;
begin
  start:=false;
  count:=0;
  form1.ClockLabel.Caption:=inttostr(count);
end;
procedure TClockClass.startclock;
begin
  start:=true;
end;
{
procedure TForm1.BitBtn1Click(Sender: TObject);
begin
 close;
end;
}
procedure Tform1.InitialGrid;
var i:integer;
begin
  StatusGrid.cells[0,0]:='发射指令';
  StatusGrid.cells[1,0]:='执行完毕';
  StatusGrid.cells[2,0]:='写回结果';

  InstructionGrid.cells[0,0]:='Name';
  InstructionGrid.cells[1,0]:='Desti';
  InstructionGrid.cells[2,0]:='Sourcej';
  InstructionGrid.cells[3,0]:='Sourcek';

  LoadGrid.cells[1,0]:='Busy';
  LoadGrid.cells[2,0]:='Address';
  LoadGrid.cells[3,0]:='Cache';
  LoadGrid.cells[0,1]:='Load1';
  LoadGrid.cells[0,2]:='Load2';
  LoadGrid.cells[0,3]:='Load3';

  StoreGrid.cells[1,0]:='Busy';
  StoreGrid.cells[2,0]:='Address';
  StoreGrid.cells[3,0]:='Qi';
  StoreGrid.cells[0,1]:='Store1';
  StoreGrid.cells[0,2]:='Store2';
  StoreGrid.cells[0,3]:='Store3';

  ReservationGrid.cells[0,0]:='Time';
  ReservationGrid.cells[1,0]:='Name';
  ReservationGrid.cells[2,0]:='Busy';
  ReservationGrid.cells[3,0]:='Op';
  ReservationGrid.cells[4,0]:='Vj';
  ReservationGrid.cells[5,0]:='Vk';
  ReservationGrid.cells[6,0]:='Qj';
  ReservationGrid.cells[7,0]:='Qk';

  for i:=0 to FUSIZE do
  FUGrid.cells[i,0]:='F'+inttostr(i);
  for i:=0 to FUSIZE do
  RUGrid.cells[i,0]:='R'+inttostr(i);
end;

procedure TForm1.InitialReservation;
  var i:integer;
begin
  for i:=1 to RSSIZE do
  with RS[i] do
  begin
      StartCount:= false;//是否开始计数
      Time:=0;
      Name:='';
      Busy:=false;
  end;

  for i:=1 to ADDERSIZE do
  begin
    RS[i].RStype:=ADDER;
    RS[i].Name:='Add'+inttostr(i);
  end;
  for i:=ADDERSIZE+1 to ADDERSIZE+MULTIPLIERSIZE do
  begin
    RS[i].RStype:=MULTIPLIER;
    RS[i].Name:='Mult'+inttostr(i-ADDERSIZE);
  end;

  for i:=1 to RSSIZE do
  ReservationGrid.cells[1,i]:=RS[i].Name;
end;

procedure Tform1.InitialValue;
var i:integer;
begin
  for i:=0 to RUSIZE do
  RU[i].value:=0;
  for i:=0 to FUSIZE do
  FU[i].fvalue:=0;
  MemNum:=0;
end;
procedure TForm1.FormCreate(Sender: TObject);
  var i:integer;
begin
  InitialGrid;
  InitialReservation;
  InitialValue;
 // InitialLoadQueue;
 // InitialStoreQueue;
  paintbox1.Left:=0;//form1.Left;
  paintbox1.Top:=0; //form1.Top;
  //paintbox1.Height:=form1.Height;
  //paintbox1.Width:=form1.Width;
  ModeFlag:=VALUE;
  PC:=0;
  InstrNum:=0;
  Clock := TClockClass.Create;
  Clock.clearclock;
  InputDlg1:= TInputDlg.Create(form1);
  SetValueDlg1:= TSetValueDlg.Create(form1);

  ClockSpeedDlg1:=TClockSpeedDlg.Create(form1);
  timer1:=Ttimer.Create(self);
  timer1.Interval:=1000;
  timer1.OnTimer:=TimerAction;
  timer1.Enabled:=false;
end;

procedure Tform1.InstrGridAdd(index:integer; opname,dest,sj,sk:string);
begin
  InstructionGrid.cells[0,index]:=opname;
  InstructionGrid.cells[1,index]:=dest;
  InstructionGrid.cells[2,index]:=sj;
  InstructionGrid.cells[3,index]:=sk;
end;

function Tform1.CheckAllCompleted:boolean;
var i:integer;
begin
  CheckAllCompleted:=false;
  for i:=1 to instrnum do
  if not Instr[i].completed then exit;

  CheckAllCompleted:=true;
end;

function Tform1.CheckNoIssueConflict(pc:integer):boolean;
var i:integer; //判断是否有发射冲突
begin
  {if (Instr[pc].OpDest.OpType = FUTYPE) then //不需要
  begin
    if (FU[Instr[pc].OpDest.index].status = NONAVAILABLE) then
    exit; // 解决 WAW 现象
  end
  else}
  CheckNoIssueConflict:=true;
  case (Instr[pc].OP) of
  LD: begin
        for i:=1 to LOADSIZE do
        if not Load[i].Busy then  exit;
      end;
  SD: begin
        for i:=1 to STORESIZE do
        if not Store[i].Busy then exit;
      end;
  ADDD,SUBD:
      begin
        for i:=1 to RSSIZE do
        if (RS[i].RStype = ADDER) and (not RS[i].busy) then
          exit;
      end;
  MULTD,DIVD:
      begin
        for i:=1 to RSSIZE do
        if (RS[i].RStype = MULTIPLIER) and (not RS[i].busy) then
          exit;
      end;
  else begin
       end;
  end;
  CheckNoIssueConflict:=false;
end;

procedure Tform1.RefreshIssue;
var i:integer;
begin
  PCLabel.Caption:=inttostr(PC);
  { Refresh StatusGrid }
  for i:=1 to PC do
  begin
    if (instr[i].Issue>0 ) then
        StatusGrid.Cells[0,i]:=inttostr(instr[i].Issue);
    if (instr[i].ExecutionComplete>0 ) then
        StatusGrid.Cells[1,i]:=inttostr(instr[i].ExecutionComplete);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -