📄 main.~pas
字号:
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 + -