Mercurial > pygar
comparison modules/bluespec/Pygar/lab4/oProcessor.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 // The MIT License | |
2 | |
3 // Copyright (c) 2009 Massachusetts Institute of Technology | |
4 | |
5 // Permission is hereby granted, free of charge, to any person obtaining a copy | |
6 // of this software and associated documentation files (the "Software"), to deal | |
7 // in the Software without restriction, including without limitation the rights | |
8 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
9 // copies of the Software, and to permit persons to whom the Software is | |
10 // furnished to do so, subject to the following conditions: | |
11 | |
12 // The above copyright notice and this permission notice shall be included in | |
13 // all copies or substantial portions of the Software. | |
14 | |
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
17 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
18 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
19 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
20 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
21 // THE SOFTWARE. | |
22 | |
23 import Connectable::*; | |
24 import GetPut::*; | |
25 import ClientServer::*; | |
26 import RegFile::*; | |
27 import FIFO::*; | |
28 import FIFOF::*; | |
29 import RWire::*; | |
30 | |
31 //AWB includes | |
32 `include "asim/provides/low_level_platform_interface.bsh" | |
33 `include "asim/provides/soft_connections.bsh" | |
34 `include "asim/provides/common_services.bsh" | |
35 | |
36 // Local includes | |
37 `include "asim/provides/processor_library.bsh" | |
38 `include "asim/rrr/remote_server_stub_PROCESSORSYSTEMRRR.bsh" | |
39 `include "asim/provides/common_services.bsh" | |
40 `include "asim/dict/STATS_PROCESSOR.bsh" | |
41 | |
42 interface Proc; | |
43 | |
44 // Interface from processor to caches | |
45 interface Client#(DataReq,DataResp) dmem_client; | |
46 interface Client#(InstReq,InstResp) imem_client; | |
47 | |
48 // Interface for enabling/disabling statistics on the rest of the core | |
49 interface Get#(Bool) statsEn_get; | |
50 | |
51 endinterface | |
52 | |
53 | |
54 typedef enum { PCgen, Exec, Writeback } Stage deriving(Eq,Bits); | |
55 | |
56 //----------------------------------------------------------- | |
57 // Register file module | |
58 //----------------------------------------------------------- | |
59 | |
60 interface RFile; | |
61 method Action wr( Rindx rindx, Bit#(32) data ); | |
62 method Bit#(32) rd1( Rindx rindx ); | |
63 method Bit#(32) rd2( Rindx rindx ); | |
64 endinterface | |
65 | |
66 module mkRFile( RFile ); | |
67 | |
68 RegFile#(Rindx,Bit#(32)) rfile <- mkRegFileFull(); | |
69 | |
70 method Action wr( Rindx rindx, Bit#(32) data ); | |
71 rfile.upd( rindx, data ); | |
72 endmethod | |
73 | |
74 method Bit#(32) rd1( Rindx rindx ); | |
75 return ( rindx == 0 ) ? 0 : rfile.sub(rindx); | |
76 endmethod | |
77 | |
78 method Bit#(32) rd2( Rindx rindx ); | |
79 return ( rindx == 0 ) ? 0 : rfile.sub(rindx); | |
80 endmethod | |
81 | |
82 endmodule | |
83 | |
84 //----------------------------------------------------------- | |
85 // Helper functions | |
86 //----------------------------------------------------------- | |
87 | |
88 function Bit#(32) slt( Bit#(32) val1, Bit#(32) val2 ); | |
89 return zeroExtend( pack( signedLT(val1,val2) ) ); | |
90 endfunction | |
91 | |
92 function Bit#(32) sltu( Bit#(32) val1, Bit#(32) val2 ); | |
93 return zeroExtend( pack( val1 < val2 ) ); | |
94 endfunction | |
95 | |
96 function Bit#(32) rshft( Bit#(32) val ); | |
97 return zeroExtend(val[4:0]); | |
98 endfunction | |
99 | |
100 //----------------------------------------------------------- | |
101 // Reference processor | |
102 //----------------------------------------------------------- | |
103 | |
104 | |
105 module [CONNECTED_MODULE] mkProc( Proc ); | |
106 | |
107 //----------------------------------------------------------- | |
108 // Debug port | |
109 | |
110 ServerStub_PROCESSORSYSTEMRRR server_stub <- mkServerStub_PROCESSORSYSTEMRRR(); | |
111 | |
112 //----------------------------------------------------------- | |
113 // State | |
114 | |
115 // Standard processor state | |
116 | |
117 Reg#(Addr) pc <- mkReg(32'h00001000); | |
118 Reg#(Stage) stage <- mkReg(PCgen); | |
119 RFile rf <- mkRFile; | |
120 | |
121 // Coprocessor state - connected by way of RRR | |
122 | |
123 Reg#(Bit#(32)) cp0_tohost <- mkReg(0); | |
124 | |
125 Reg#(Bit#(32)) cp0_fromhost <- mkReg(0); | |
126 | |
127 Reg#(Bool) cp0_statsEn <- mkReg(False); | |
128 | |
129 // Memory request/response state | |
130 | |
131 FIFO#(InstReq) instReqQ <- mkBFIFO1(); | |
132 FIFO#(InstResp) instRespQ <- mkFIFO(); | |
133 | |
134 FIFO#(DataReq) dataReqQ <- mkBFIFO1(); | |
135 FIFO#(DataResp) dataRespQ <- mkFIFO(); | |
136 | |
137 // Statistics state | |
138 STAT num_cycles <- mkStatCounter(`STATS_PROCESSOR_CYCLE_COUNT); | |
139 STAT num_inst <- mkStatCounter(`STATS_PROCESSOR_INST_COUNT); | |
140 | |
141 //----------------------------------------------------------- | |
142 // Rules | |
143 | |
144 let pc_plus4 = pc + 4; | |
145 | |
146 rule pcgen ( stage == PCgen ); | |
147 traceTiny("mkProc", "pc",pc); | |
148 traceTiny("mkProc", "pcgen","P"); | |
149 instReqQ.enq( LoadReq{ addr:pc, tag:0 } ); | |
150 stage <= Exec; | |
151 endrule | |
152 | |
153 rule exec ( stage == Exec ); | |
154 | |
155 // Some abbreviations | |
156 let sext = signExtend; | |
157 let zext = zeroExtend; | |
158 let sra = signedShiftRight; | |
159 | |
160 // Get the instruction | |
161 | |
162 instRespQ.deq(); | |
163 Instr inst | |
164 = case ( instRespQ.first() ) matches | |
165 tagged LoadResp .ld : return unpack(ld.data); | |
166 tagged StoreResp .st : return ?; | |
167 endcase; | |
168 | |
169 // Some default variables | |
170 Stage next_stage = PCgen; | |
171 Addr next_pc = pc_plus4; | |
172 | |
173 // Tracing | |
174 traceTiny("mkProc", "exec","X"); | |
175 traceTiny("mkProc", "exInstTiny",inst); | |
176 traceFull("mkProc", "exInstFull",inst); | |
177 | |
178 case ( inst ) matches | |
179 | |
180 // -- Memory Ops ------------------------------------------------ | |
181 | |
182 tagged LW .it : | |
183 begin | |
184 Addr addr = rf.rd1(it.rbase) + sext(it.offset); | |
185 dataReqQ.enq( LoadReq{ addr:addr, tag:zeroExtend(it.rdst) } ); | |
186 next_stage = Writeback; | |
187 end | |
188 | |
189 tagged SW .it : | |
190 begin | |
191 Addr addr = rf.rd1(it.rbase) + sext(it.offset); | |
192 dataReqQ.enq( StoreReq{ tag:0, addr:addr, data:rf.rd1(it.rsrc) } ); | |
193 next_stage = Writeback; | |
194 end | |
195 | |
196 // -- Simple Ops ------------------------------------------------ | |
197 | |
198 tagged ADDIU .it : rf.wr( it.rdst, rf.rd1(it.rsrc) + sext(it.imm) ); | |
199 tagged SLTI .it : rf.wr( it.rdst, slt( rf.rd1(it.rsrc), sext(it.imm) ) ); | |
200 tagged SLTIU .it : rf.wr( it.rdst, sltu( rf.rd1(it.rsrc), sext(it.imm) ) ); | |
201 tagged ANDI .it : | |
202 begin | |
203 Bit#(32) zext_it_imm = zext(it.imm); | |
204 rf.wr( it.rdst, rf.rd1(it.rsrc) & zext_it_imm ); | |
205 end | |
206 tagged ORI .it : | |
207 begin | |
208 Bit#(32) zext_it_imm = zext(it.imm); | |
209 rf.wr( it.rdst, rf.rd1(it.rsrc) | zext_it_imm ); | |
210 end | |
211 tagged XORI .it : | |
212 begin | |
213 Bit#(32) zext_it_imm = zext(it.imm); | |
214 rf.wr( it.rdst, rf.rd1(it.rsrc) ^ zext_it_imm ); | |
215 end | |
216 tagged LUI .it : | |
217 begin | |
218 Bit#(32) zext_it_imm = zext(it.imm); | |
219 rf.wr( it.rdst, (zext_it_imm << 32'd16) ); | |
220 end | |
221 | |
222 tagged SLL .it : | |
223 begin | |
224 Bit#(32) zext_it_shamt = zext(it.shamt); | |
225 rf.wr( it.rdst, rf.rd1(it.rsrc) << zext_it_shamt ); | |
226 end | |
227 tagged SRL .it : | |
228 begin | |
229 Bit#(32) zext_it_shamt = zext(it.shamt); | |
230 rf.wr( it.rdst, rf.rd1(it.rsrc) >> zext_it_shamt ); | |
231 end | |
232 tagged SRA .it : | |
233 begin | |
234 Bit#(32) zext_it_shamt = zext(it.shamt); | |
235 rf.wr( it.rdst, sra( rf.rd1(it.rsrc), zext_it_shamt )); | |
236 end | |
237 tagged SLLV .it : rf.wr( it.rdst, rf.rd1(it.rsrc) << rshft(rf.rd2(it.rshamt)) ); | |
238 tagged SRLV .it : rf.wr( it.rdst, rf.rd1(it.rsrc) >> rshft(rf.rd2(it.rshamt)) ); | |
239 tagged SRAV .it : rf.wr( it.rdst, sra( rf.rd1(it.rsrc), rshft(rf.rd2(it.rshamt)) ) ); | |
240 tagged ADDU .it : rf.wr( it.rdst, rf.rd1(it.rsrc1) + rf.rd2(it.rsrc2) ); | |
241 tagged SUBU .it : rf.wr( it.rdst, rf.rd1(it.rsrc1) - rf.rd2(it.rsrc2) ); | |
242 tagged AND .it : rf.wr( it.rdst, rf.rd1(it.rsrc1) & rf.rd2(it.rsrc2) ); | |
243 tagged OR .it : rf.wr( it.rdst, rf.rd1(it.rsrc1) | rf.rd2(it.rsrc2) ); | |
244 tagged XOR .it : rf.wr( it.rdst, rf.rd1(it.rsrc1) ^ rf.rd2(it.rsrc2) ); | |
245 tagged NOR .it : rf.wr( it.rdst, ~(rf.rd1(it.rsrc1) | rf.rd2(it.rsrc2)) ); | |
246 tagged SLT .it : rf.wr( it.rdst, slt( rf.rd1(it.rsrc1), rf.rd2(it.rsrc2) ) ); | |
247 tagged SLTU .it : rf.wr( it.rdst, sltu( rf.rd1(it.rsrc1), rf.rd2(it.rsrc2) ) ); | |
248 | |
249 // -- Branches -------------------------------------------------- | |
250 | |
251 tagged BLEZ .it : | |
252 if ( signedLE( rf.rd1(it.rsrc), 0 ) ) | |
253 next_pc = pc_plus4 + (sext(it.offset) << 2); | |
254 | |
255 tagged BGTZ .it : | |
256 if ( signedGT( rf.rd1(it.rsrc), 0 ) ) | |
257 next_pc = pc_plus4 + (sext(it.offset) << 2); | |
258 | |
259 tagged BLTZ .it : | |
260 if ( signedLT( rf.rd1(it.rsrc), 0 ) ) | |
261 next_pc = pc_plus4 + (sext(it.offset) << 2); | |
262 | |
263 tagged BGEZ .it : | |
264 if ( signedGE( rf.rd1(it.rsrc), 0 ) ) | |
265 next_pc = pc_plus4 + (sext(it.offset) << 2); | |
266 | |
267 tagged BEQ .it : | |
268 if ( rf.rd1(it.rsrc1) == rf.rd2(it.rsrc2) ) | |
269 next_pc = pc_plus4 + (sext(it.offset) << 2); | |
270 | |
271 tagged BNE .it : | |
272 if ( rf.rd1(it.rsrc1) != rf.rd2(it.rsrc2) ) | |
273 next_pc = pc_plus4 + (sext(it.offset) << 2); | |
274 | |
275 // -- Jumps ----------------------------------------------------- | |
276 | |
277 tagged J .it : | |
278 next_pc = { pc_plus4[31:28], it.target, 2'b0 }; | |
279 | |
280 tagged JR .it : | |
281 next_pc = rf.rd1(it.rsrc); | |
282 | |
283 tagged JAL .it : | |
284 begin | |
285 rf.wr( 31, pc_plus4 ); | |
286 next_pc = { pc_plus4[31:28], it.target, 2'b0 }; | |
287 end | |
288 | |
289 tagged JALR .it : | |
290 begin | |
291 rf.wr( it.rdst, pc_plus4 ); | |
292 next_pc = rf.rd1(it.rsrc); | |
293 end | |
294 | |
295 // -- Cop0 ------------------------------------------------------ | |
296 | |
297 tagged MTC0 .it : | |
298 case ( it.cop0dst ) | |
299 5'd10 : cp0_statsEn <= unpack(truncate(rf.rd1(it.rsrc))); | |
300 5'd21 : cp0_tohost <= truncate(rf.rd1(it.rsrc)); | |
301 default : | |
302 $display( " RTL-ERROR : %m : Illegal MTC0 cop0dst register!" ); | |
303 endcase | |
304 | |
305 tagged MFC0 .it : | |
306 case ( it.cop0src ) | |
307 5'd10 : rf.wr( it.rdst, zext(pack(cp0_statsEn)) ); | |
308 5'd20 : rf.wr( it.rdst, cp0_fromhost ); | |
309 5'd21 : rf.wr( it.rdst, cp0_tohost ); | |
310 default : | |
311 $display( " RTL-ERROR : %m : Illegal MFC0 cop0src register!" ); | |
312 endcase | |
313 | |
314 // -- Illegal --------------------------------------------------- | |
315 | |
316 default : | |
317 $display( " RTL-ERROR : %m : Illegal instruction !" ); | |
318 | |
319 endcase | |
320 | |
321 stage <= next_stage; | |
322 pc <= next_pc; | |
323 | |
324 if ( cp0_statsEn ) | |
325 num_inst.incr(); | |
326 | |
327 endrule | |
328 | |
329 rule writeback ( stage == Writeback ); | |
330 traceTiny("mkProc", "writeback","W"); | |
331 | |
332 dataRespQ.deq(); | |
333 case ( dataRespQ.first() ) matches | |
334 tagged LoadResp .ld : rf.wr( truncate(ld.tag), ld.data ); | |
335 tagged StoreResp .st : noAction; | |
336 endcase | |
337 | |
338 stage <= PCgen; | |
339 endrule | |
340 | |
341 rule inc_num_cycles; | |
342 if ( cp0_statsEn ) | |
343 num_cycles.incr(); | |
344 endrule | |
345 | |
346 rule handleCPUToHost; | |
347 let req <- server_stub.acceptRequest_ReadCPUToHost(); | |
348 case (req) | |
349 0: server_stub.sendResponse_ReadCPUToHost(cp0_tohost); | |
350 1: server_stub.sendResponse_ReadCPUToHost(pc); | |
351 2: server_stub.sendResponse_ReadCPUToHost(zeroExtend(pack(stage))); | |
352 endcase | |
353 endrule | |
354 | |
355 | |
356 | |
357 //----------------------------------------------------------- | |
358 // Methods | |
359 | |
360 interface Client imem_client; | |
361 interface Get request = fifoToGet(instReqQ); | |
362 interface Put response = fifoToPut(instRespQ); | |
363 endinterface | |
364 | |
365 interface Client dmem_client; | |
366 interface Get request = fifoToGet(dataReqQ); | |
367 interface Put response = fifoToPut(dataRespQ); | |
368 endinterface | |
369 | |
370 interface Get statsEn_get = regToGet(cp0_statsEn); | |
371 | |
372 endmodule | |
373 |