1+ #include " parser.cpp"
2+ class ReservationStationALU
3+ {
4+ const static int N=100 ;
5+ enum state {wait,calc,done};
6+ public:
7+ struct ReservationStation
8+ {
9+ int bid,bva;
10+ struct node
11+ {
12+ bool busy;
13+ int dest,vj,vk,qj,qk,op,id,ret;
14+ int st;
15+ node (){busy=false ;dest=vj=vk=op=ret=id=0 ;qj=qk=-1 ;st=wait;}
16+ node (int dest,int vj,int vk,int qj,int qk,int op,int id): dest(dest),vj(vj),vk(vk),qj(qj),qk(qk),op(op),id(id) {busy=true ;st=wait;ret=0 ;}
17+ } rs[N];
18+ ReservationStation (){bid=-2 ,bva=0 ;}
19+ void clear ()
20+ {
21+ for (int i=0 ;i<N;i++) rs[i]=node ();
22+ }
23+ void ins (int dest,int vj,int vk,int qj,int qk,int op,int id)
24+ {
25+ for (int i=0 ;i<N;i++)
26+ {
27+ if (!rs[i].busy )
28+ {
29+ rs[i]=node (dest,vj,vk,qj,qk,op,id);
30+ if (rs[i].qj ==bid) rs[i].qj =-1 ,rs[i].vj =bva;
31+ if (rs[i].qk ==bid) rs[i].qk =-1 ,rs[i].vk =bva;
32+ return ;
33+ }
34+ }
35+ }
36+ void del (int pos) {rs[pos]=node ();}
37+ int findReady ()
38+ {
39+ for (int i=0 ;i<N;i++)
40+ {
41+ if (!rs[i].busy ||rs[i].st !=wait) continue ;
42+ if (rs[i].qj ==-1 &&rs[i].qk ==-1 ) return i;
43+ }
44+ return -1 ;
45+ }
46+ int findDone (int st)
47+ {
48+ for (int i=st;i<N;i++)
49+ {
50+ if (!rs[i].busy ) continue ;
51+ if (rs[i].st ==done) return i;
52+ }
53+ return -1 ;
54+ }
55+ int getx (int pos){return rs[pos].vj ;}
56+ int gety (int pos){return rs[pos].vk ;}
57+ int getop (int pos){return rs[pos].op ;}
58+ int getid (int pos){return rs[pos].id ;}
59+ int getret (int pos){return rs[pos].ret ;}
60+ void nextState (int pos){rs[pos].st ++;}
61+ } now,next;
62+ void nextClock (){now=next;next.bid =-2 ,next.bva =0 ;}
63+ void broadcast (int id,int va)
64+ {
65+ next.bid =id,next.bva =va;
66+ for (int i=0 ;i<N;i++)
67+ {
68+ if (next.rs [i].qj ==id) next.rs [i].qj =-1 ,next.rs [i].vj =va;
69+ if (next.rs [i].qk ==id) next.rs [i].qk =-1 ,next.rs [i].vk =va;
70+ }
71+ }
72+ void prepare (int pos,int va)
73+ {
74+ next.rs [pos].ret =va;
75+ next.rs [pos].st =done;
76+ if (next.rs [pos].dest ) broadcast (next.rs [pos].id ,va);
77+ }
78+ } RS ;
79+ class ALU
80+ {
81+ int rem,res,pos;
82+ int rem2,res2,pos2;
83+ public:
84+ ALU (){rem=res=rem2=res2=0 ;pos=pos2=-1 ;}
85+ void clear () {rem2=res2=0 ;pos2=-1 ;}
86+ void nextClock (){rem=rem2,res=res2,pos=pos2;}
87+ bool busy (){return rem>0 ;}
88+ void calc ()
89+ {
90+ if (busy ())
91+ {
92+ prompt ();
93+ return ;
94+ }
95+ int tmp=RS .now .findReady ();
96+ if (tmp==-1 ) return ;
97+ int x=RS .now .getx (tmp),y=RS .now .gety (tmp),op=RS .now .getop (tmp);
98+ RS .next .nextState (tmp);
99+ rem2=1 ;pos2=tmp;
100+ switch (op)
101+ {
102+ case eq:res2=(x==y);break ;
103+ case neq:res2=(x!=y);break ;
104+ case le:res2=(x<y);break ;
105+ case geq:res2=(x>=y);break ;
106+ case leu:
107+ {
108+ unsigned int tx=x,ty=y;
109+ res2=(tx<ty);break ;
110+ }
111+ case gequ:
112+ {
113+ unsigned int tx=x,ty=y;
114+ res2=(tx>=ty);break ;
115+ }
116+ case add:res2=(x+y);break ;
117+ case xori:res2=(x^y);break ;
118+ case ori:res2=(x|y);break ;
119+ case andi:res2=(x&y);break ;
120+ case slli:res2=(x<<(y&31 ));break ;
121+ case srli:
122+ {
123+ unsigned int tx=x;
124+ res2=(tx>>(y&31 ));break ;
125+ }
126+ case srai:res2=(x>>(y&31 ));break ;
127+ case sub:res2=(x-y);break ;
128+ case mul:res2=(x*y);break ;
129+ case dv:res2=(x/y);break ;
130+ }
131+ prompt2 ();
132+ }
133+ void prompt ()
134+ {
135+ if (!rem) return ;
136+ rem2=rem-1 ;
137+ if (!rem2) RS .prepare (pos,res);
138+ }
139+ void prompt2 ()
140+ {
141+ if (!rem2) return ;
142+ rem2--;
143+ if (!rem2) RS .prepare (pos2,res2);
144+ }
145+ } alu;
0 commit comments