Mercurial > pygar
comparison modules/bluespec/Pygar/lab4/Proc.bsv @ 8:74716e9a81cc pygar svn.9
[svn r9] Pygar now has the proper directory structure to play nicely with awb. Also, the apm file for audio-core willcompile successfully.
author | rlm |
---|---|
date | Fri, 23 Apr 2010 02:32:05 -0400 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
7:7393cd19371e | 8:74716e9a81cc |
---|---|
1 import CBusUtils::*; | |
2 import Register::*; | |
3 | |
4 import Trace::*; | |
5 import MemTypes::*; | |
6 import IProc::*; | |
7 import ProcTypes::*; | |
8 import FPGATypes::*; | |
9 import RegFile::*; | |
10 import FIFO::*; | |
11 import BFIFO::*; | |
12 import Assert::*; | |
13 | |
14 import GetPut::*; | |
15 import GetPutExt::*; | |
16 import ClientServer::*; | |
17 import CBus::*; | |
18 | |
19 | |
20 interface IProc; | |
21 | |
22 // Interface for testrig | |
23 interface Put#(Bit#(8)) testrig_fromhost; | |
24 interface Get#(Bit#(8)) testrig_tohost; | |
25 | |
26 // Interface from processor to caches | |
27 interface Client#(DataReq,DataResp) dmem_client; | |
28 interface Client#(InstReq,InstResp) imem_client; | |
29 | |
30 // Interface for enabling/disabling statistics on the rest of the core | |
31 interface Get#(Bool) statsEn_get; | |
32 | |
33 endinterface | |
34 | |
35 | |
36 typedef enum { PCgen, Exec, Writeback } Stage deriving(Eq,Bits); | |
37 | |
38 //----------------------------------------------------------- | |
39 // Register file module | |
40 //----------------------------------------------------------- | |
41 | |
42 interface RFile; | |
43 method Action wr( Rindx rindx, Bit#(32) data ); | |
44 method Bit#(32) rd1( Rindx rindx ); | |
45 method Bit#(32) rd2( Rindx rindx ); | |
46 endinterface | |
47 | |
48 module mkRFile( RFile ); | |
49 | |
50 RegFile#(Rindx,Bit#(32)) rfile <- mkRegFileFull(); | |
51 | |
52 method Action wr( Rindx rindx, Bit#(32) data ); | |
53 rfile.upd( rindx, data ); | |
54 endmethod | |
55 | |
56 method Bit#(32) rd1( Rindx rindx ); | |
57 return ( rindx == 0 ) ? 0 : rfile.sub(rindx); | |
58 endmethod | |
59 | |
60 method Bit#(32) rd2( Rindx rindx ); | |
61 return ( rindx == 0 ) ? 0 : rfile.sub(rindx); | |
62 endmethod | |
63 | |
64 endmodule | |
65 | |
66 //----------------------------------------------------------- | |
67 // Helper functions | |
68 //----------------------------------------------------------- | |
69 | |
70 function Bit#(32) slt( Bit#(32) val1, Bit#(32) val2 ); | |
71 return zeroExtend( pack( signedLT(val1,val2) ) ); | |
72 endfunction | |
73 | |
74 function Bit#(32) sltu( Bit#(32) val1, Bit#(32) val2 ); | |
75 return zeroExtend( pack( val1 < val2 ) ); | |
76 endfunction | |
77 | |
78 function Bit#(32) rshft( Bit#(32) val ); | |
79 return zeroExtend(val[4:0]); | |
80 endfunction | |
81 | |
82 //----------------------------------------------------------- | |
83 // Reference processor | |
84 //----------------------------------------------------------- | |
85 | |
86 | |
87 module [ModWithCBus#(AvalonAddressWidth,AvalonDataWidth)] mkProc( IProc ); | |
88 | |
89 //----------------------------------------------------------- | |
90 // State | |
91 | |
92 // Standard processor state | |
93 | |
94 Reg#(Addr) pc <- mkReg(32'h00001000); | |
95 Reg#(Stage) stage <- mkReg(PCgen); | |
96 RFile rf <- mkRFile; | |
97 | |
98 // Coprocessor state | |
99 | |
100 Reg#(Bit#(8)) cp0_tohost <- mkReg(0); | |
101 mkCBusWideRegRW(valueof(ToHostRegAddr),cp0_tohost); | |
102 Reg#(Bit#(8)) cp0_fromhost <- mkReg(0); | |
103 mkCBusWideRegRW(valueof(FromHostRegAddr),cp0_fromhost); | |
104 Reg#(Bool) cp0_statsEn <- mkReg(False); | |
105 mkCBusWideRegRW(valueof(StatsEnRegAddr),cp0_statsEn); | |
106 // Memory request/response state | |
107 | |
108 FIFO#(InstReq) instReqQ <- mkBFIFO1(); | |
109 FIFO#(InstResp) instRespQ <- mkFIFO(); | |
110 | |
111 FIFO#(DataReq) dataReqQ <- mkBFIFO1(); | |
112 FIFO#(DataResp) dataRespQ <- mkFIFO(); | |
113 | |
114 // Statistics state | |
115 | |
116 Reg#(Int#(25)) num_cycles <- mkReg(25'h0); | |
117 Reg#(Int#(25)) num_inst <- mkReg(25'h0); | |
118 | |
119 //----------------------------------------------------------- | |
120 // Rules | |
121 | |
122 let pc_plus4 = pc + 4; | |
123 | |
124 rule pcgen ( stage == PCgen ); | |
125 traceTiny("pc",pc); | |
126 traceTiny("stage","P"); | |
127 instReqQ.enq( LoadReq{ addr:pc, tag:0 } ); | |
128 stage <= Exec; | |
129 endrule | |
130 | |
131 rule exec ( stage == Exec ); | |
132 | |
133 // Some abbreviations | |
134 let sext = signExtend; | |
135 let zext = zeroExtend; | |
136 let sra = signedShiftRight; | |
137 | |
138 // Get the instruction | |
139 | |
140 instRespQ.deq(); | |
141 Instr inst | |
142 = case ( instRespQ.first() ) matches | |
143 tagged LoadResp .ld : return unpack(ld.data); | |
144 tagged StoreResp .st : return ?; | |
145 endcase; | |
146 | |
147 // Some default variables | |
148 Stage next_stage = PCgen; | |
149 Addr next_pc = pc_plus4; | |
150 | |
151 // Tracing | |
152 traceTiny("stage","X"); | |
153 traceTiny("exInstTiny",inst); | |
154 traceFull("exInstFull",inst); | |
155 | |
156 case ( inst ) matches | |
157 | |
158 // -- Memory Ops ------------------------------------------------ | |
159 | |
160 tagged LW .it : | |
161 begin | |
162 Addr addr = rf.rd1(it.rbase) + sext(it.offset); | |
163 dataReqQ.enq( LoadReq{ addr:addr, tag:zeroExtend(it.rdst) } ); | |
164 next_stage = Writeback; | |
165 end | |
166 | |
167 tagged SW .it : | |
168 begin | |
169 Addr addr = rf.rd1(it.rbase) + sext(it.offset); | |
170 dataReqQ.enq( StoreReq{ tag:0, addr:addr, data:rf.rd1(it.rsrc) } ); | |
171 next_stage = Writeback; | |
172 end | |
173 | |
174 // -- Simple Ops ------------------------------------------------ | |
175 | |
176 tagged ADDIU .it : rf.wr( it.rdst, rf.rd1(it.rsrc) + sext(it.imm) ); | |
177 tagged SLTI .it : rf.wr( it.rdst, slt( rf.rd1(it.rsrc), sext(it.imm) ) ); | |
178 tagged SLTIU .it : rf.wr( it.rdst, sltu( rf.rd1(it.rsrc), sext(it.imm) ) ); | |
179 tagged ANDI .it : | |
180 begin | |
181 Bit#(32) zext_it_imm = zext(it.imm); | |
182 rf.wr( it.rdst, rf.rd1(it.rsrc) & zext_it_imm ); | |
183 end | |
184 tagged ORI .it : | |
185 begin | |
186 Bit#(32) zext_it_imm = zext(it.imm); | |
187 rf.wr( it.rdst, rf.rd1(it.rsrc) | zext_it_imm ); | |
188 end | |
189 tagged XORI .it : | |
190 begin | |
191 Bit#(32) zext_it_imm = zext(it.imm); | |
192 rf.wr( it.rdst, rf.rd1(it.rsrc) ^ zext_it_imm ); | |
193 end | |
194 tagged LUI .it : | |
195 begin | |
196 Bit#(32) zext_it_imm = zext(it.imm); | |
197 rf.wr( it.rdst, (zext_it_imm << 32'd16) ); | |
198 end | |
199 | |
200 tagged SLL .it : | |
201 begin | |
202 Bit#(32) zext_it_shamt = zext(it.shamt); | |
203 rf.wr( it.rdst, rf.rd1(it.rsrc) << zext_it_shamt ); | |
204 end | |
205 tagged SRL .it : | |
206 begin | |
207 Bit#(32) zext_it_shamt = zext(it.shamt); | |
208 rf.wr( it.rdst, rf.rd1(it.rsrc) >> zext_it_shamt ); | |
209 end | |
210 tagged SRA .it : | |
211 begin | |
212 Bit#(32) zext_it_shamt = zext(it.shamt); | |
213 rf.wr( it.rdst, sra( rf.rd1(it.rsrc), zext_it_shamt )); | |
214 end | |
215 tagged SLLV .it : rf.wr( it.rdst, rf.rd1(it.rsrc) << rshft(rf.rd2(it.rshamt)) ); | |
216 tagged SRLV .it : rf.wr( it.rdst, rf.rd1(it.rsrc) >> rshft(rf.rd2(it.rshamt)) ); | |
217 tagged SRAV .it : rf.wr( it.rdst, sra( rf.rd1(it.rsrc), rshft(rf.rd2(it.rshamt)) ) ); | |
218 tagged ADDU .it : rf.wr( it.rdst, rf.rd1(it.rsrc1) + rf.rd2(it.rsrc2) ); | |
219 tagged SUBU .it : rf.wr( it.rdst, rf.rd1(it.rsrc1) - rf.rd2(it.rsrc2) ); | |
220 tagged AND .it : rf.wr( it.rdst, rf.rd1(it.rsrc1) & rf.rd2(it.rsrc2) ); | |
221 tagged OR .it : rf.wr( it.rdst, rf.rd1(it.rsrc1) | rf.rd2(it.rsrc2) ); | |
222 tagged XOR .it : rf.wr( it.rdst, rf.rd1(it.rsrc1) ^ rf.rd2(it.rsrc2) ); | |
223 tagged NOR .it : rf.wr( it.rdst, ~(rf.rd1(it.rsrc1) | rf.rd2(it.rsrc2)) ); | |
224 tagged SLT .it : rf.wr( it.rdst, slt( rf.rd1(it.rsrc1), rf.rd2(it.rsrc2) ) ); | |
225 tagged SLTU .it : rf.wr( it.rdst, sltu( rf.rd1(it.rsrc1), rf.rd2(it.rsrc2) ) ); | |
226 | |
227 // -- Branches -------------------------------------------------- | |
228 | |
229 tagged BLEZ .it : | |
230 if ( signedLE( rf.rd1(it.rsrc), 0 ) ) | |
231 next_pc = pc_plus4 + (sext(it.offset) << 2); | |
232 | |
233 tagged BGTZ .it : | |
234 if ( signedGT( rf.rd1(it.rsrc), 0 ) ) | |
235 next_pc = pc_plus4 + (sext(it.offset) << 2); | |
236 | |
237 tagged BLTZ .it : | |
238 if ( signedLT( rf.rd1(it.rsrc), 0 ) ) | |
239 next_pc = pc_plus4 + (sext(it.offset) << 2); | |
240 | |
241 tagged BGEZ .it : | |
242 if ( signedGE( rf.rd1(it.rsrc), 0 ) ) | |
243 next_pc = pc_plus4 + (sext(it.offset) << 2); | |
244 | |
245 tagged BEQ .it : | |
246 if ( rf.rd1(it.rsrc1) == rf.rd2(it.rsrc2) ) | |
247 next_pc = pc_plus4 + (sext(it.offset) << 2); | |
248 | |
249 tagged BNE .it : | |
250 if ( rf.rd1(it.rsrc1) != rf.rd2(it.rsrc2) ) | |
251 next_pc = pc_plus4 + (sext(it.offset) << 2); | |
252 | |
253 // -- Jumps ----------------------------------------------------- | |
254 | |
255 tagged J .it : | |
256 next_pc = { pc_plus4[31:28], it.target, 2'b0 }; | |
257 | |
258 tagged JR .it : | |
259 next_pc = rf.rd1(it.rsrc); | |
260 | |
261 tagged JAL .it : | |
262 begin | |
263 rf.wr( 31, pc_plus4 ); | |
264 next_pc = { pc_plus4[31:28], it.target, 2'b0 }; | |
265 end | |
266 | |
267 tagged JALR .it : | |
268 begin | |
269 rf.wr( it.rdst, pc_plus4 ); | |
270 next_pc = rf.rd1(it.rsrc); | |
271 end | |
272 | |
273 // -- Cop0 ------------------------------------------------------ | |
274 | |
275 tagged MTC0 .it : | |
276 case ( it.cop0dst ) | |
277 5'd10 : cp0_statsEn <= unpack(truncate(rf.rd1(it.rsrc))); | |
278 5'd21 : cp0_tohost <= truncate(rf.rd1(it.rsrc)); | |
279 default : | |
280 $display( " RTL-ERROR : %m : Illegal MTC0 cop0dst register!" ); | |
281 endcase | |
282 | |
283 tagged MFC0 .it : | |
284 case ( it.cop0src ) | |
285 5'd10 : rf.wr( it.rdst, zext(pack(cp0_statsEn)) ); | |
286 5'd20 : rf.wr( it.rdst, zext(cp0_fromhost) ); | |
287 5'd21 : rf.wr( it.rdst, zext(cp0_tohost) ); | |
288 default : | |
289 $display( " RTL-ERROR : %m : Illegal MFC0 cop0src register!" ); | |
290 endcase | |
291 | |
292 // -- Illegal --------------------------------------------------- | |
293 | |
294 default : | |
295 $display( " RTL-ERROR : %m : Illegal instruction !" ); | |
296 | |
297 endcase | |
298 | |
299 stage <= next_stage; | |
300 pc <= next_pc; | |
301 | |
302 if ( cp0_statsEn ) | |
303 num_inst <= num_inst + 1; | |
304 | |
305 endrule | |
306 | |
307 rule writeback ( stage == Writeback ); | |
308 traceTiny("stage","W"); | |
309 | |
310 dataRespQ.deq(); | |
311 case ( dataRespQ.first() ) matches | |
312 tagged LoadResp .ld : rf.wr( truncate(ld.tag), ld.data ); | |
313 tagged StoreResp .st : noAction; | |
314 endcase | |
315 | |
316 stage <= PCgen; | |
317 endrule | |
318 | |
319 rule inc_num_cycles; | |
320 if ( cp0_statsEn ) | |
321 num_cycles <= num_cycles + 1; | |
322 endrule | |
323 | |
324 //----------------------------------------------------------- | |
325 // Methods | |
326 | |
327 interface Client imem_client; | |
328 interface Get request = fifoToGet(instReqQ); | |
329 interface Put response = fifoToPut(instRespQ); | |
330 endinterface | |
331 | |
332 interface Client dmem_client; | |
333 interface Get request = fifoToGet(dataReqQ); | |
334 interface Put response = fifoToPut(dataRespQ); | |
335 endinterface | |
336 | |
337 interface Get testrig_tohost = regToGet(cp0_tohost); | |
338 interface Put testrig_fromhost = regToPut(cp0_fromhost); | |
339 interface Get statsEn_get = regToGet(cp0_statsEn); | |
340 | |
341 endmodule | |
342 |