view modules/bluespec/Pygar/lab4/oProcessor.bsv @ 54:9b4f237e77e1 pygar svn.55

[svn r55] input a bit more parameterized
author punk
date Sun, 09 May 2010 12:24:35 -0400
parents 74716e9a81cc
children
line wrap: on
line source
1 // The MIT License
3 // Copyright (c) 2009 Massachusetts Institute of Technology
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:
12 // The above copyright notice and this permission notice shall be included in
13 // all copies or substantial portions of the Software.
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.
23 import Connectable::*;
24 import GetPut::*;
25 import ClientServer::*;
26 import RegFile::*;
27 import FIFO::*;
28 import FIFOF::*;
29 import RWire::*;
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"
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"
42 interface Proc;
44 // Interface from processor to caches
45 interface Client#(DataReq,DataResp) dmem_client;
46 interface Client#(InstReq,InstResp) imem_client;
48 // Interface for enabling/disabling statistics on the rest of the core
49 interface Get#(Bool) statsEn_get;
51 endinterface
54 typedef enum { PCgen, Exec, Writeback } Stage deriving(Eq,Bits);
56 //-----------------------------------------------------------
57 // Register file module
58 //-----------------------------------------------------------
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
66 module mkRFile( RFile );
68 RegFile#(Rindx,Bit#(32)) rfile <- mkRegFileFull();
70 method Action wr( Rindx rindx, Bit#(32) data );
71 rfile.upd( rindx, data );
72 endmethod
74 method Bit#(32) rd1( Rindx rindx );
75 return ( rindx == 0 ) ? 0 : rfile.sub(rindx);
76 endmethod
78 method Bit#(32) rd2( Rindx rindx );
79 return ( rindx == 0 ) ? 0 : rfile.sub(rindx);
80 endmethod
82 endmodule
84 //-----------------------------------------------------------
85 // Helper functions
86 //-----------------------------------------------------------
88 function Bit#(32) slt( Bit#(32) val1, Bit#(32) val2 );
89 return zeroExtend( pack( signedLT(val1,val2) ) );
90 endfunction
92 function Bit#(32) sltu( Bit#(32) val1, Bit#(32) val2 );
93 return zeroExtend( pack( val1 < val2 ) );
94 endfunction
96 function Bit#(32) rshft( Bit#(32) val );
97 return zeroExtend(val[4:0]);
98 endfunction
100 //-----------------------------------------------------------
101 // Reference processor
102 //-----------------------------------------------------------
105 module [CONNECTED_MODULE] mkProc( Proc );
107 //-----------------------------------------------------------
108 // Debug port
110 ServerStub_PROCESSORSYSTEMRRR server_stub <- mkServerStub_PROCESSORSYSTEMRRR();
112 //-----------------------------------------------------------
113 // State
115 // Standard processor state
117 Reg#(Addr) pc <- mkReg(32'h00001000);
118 Reg#(Stage) stage <- mkReg(PCgen);
119 RFile rf <- mkRFile;
121 // Coprocessor state - connected by way of RRR
123 Reg#(Bit#(32)) cp0_tohost <- mkReg(0);
125 Reg#(Bit#(32)) cp0_fromhost <- mkReg(0);
127 Reg#(Bool) cp0_statsEn <- mkReg(False);
129 // Memory request/response state
131 FIFO#(InstReq) instReqQ <- mkBFIFO1();
132 FIFO#(InstResp) instRespQ <- mkFIFO();
134 FIFO#(DataReq) dataReqQ <- mkBFIFO1();
135 FIFO#(DataResp) dataRespQ <- mkFIFO();
137 // Statistics state
138 STAT num_cycles <- mkStatCounter(`STATS_PROCESSOR_CYCLE_COUNT);
139 STAT num_inst <- mkStatCounter(`STATS_PROCESSOR_INST_COUNT);
141 //-----------------------------------------------------------
142 // Rules
144 let pc_plus4 = pc + 4;
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
153 rule exec ( stage == Exec );
155 // Some abbreviations
156 let sext = signExtend;
157 let zext = zeroExtend;
158 let sra = signedShiftRight;
160 // Get the instruction
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;
169 // Some default variables
170 Stage next_stage = PCgen;
171 Addr next_pc = pc_plus4;
173 // Tracing
174 traceTiny("mkProc", "exec","X");
175 traceTiny("mkProc", "exInstTiny",inst);
176 traceFull("mkProc", "exInstFull",inst);
178 case ( inst ) matches
180 // -- Memory Ops ------------------------------------------------
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
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
196 // -- Simple Ops ------------------------------------------------
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
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) ) );
249 // -- Branches --------------------------------------------------
251 tagged BLEZ .it :
252 if ( signedLE( rf.rd1(it.rsrc), 0 ) )
253 next_pc = pc_plus4 + (sext(it.offset) << 2);
255 tagged BGTZ .it :
256 if ( signedGT( rf.rd1(it.rsrc), 0 ) )
257 next_pc = pc_plus4 + (sext(it.offset) << 2);
259 tagged BLTZ .it :
260 if ( signedLT( rf.rd1(it.rsrc), 0 ) )
261 next_pc = pc_plus4 + (sext(it.offset) << 2);
263 tagged BGEZ .it :
264 if ( signedGE( rf.rd1(it.rsrc), 0 ) )
265 next_pc = pc_plus4 + (sext(it.offset) << 2);
267 tagged BEQ .it :
268 if ( rf.rd1(it.rsrc1) == rf.rd2(it.rsrc2) )
269 next_pc = pc_plus4 + (sext(it.offset) << 2);
271 tagged BNE .it :
272 if ( rf.rd1(it.rsrc1) != rf.rd2(it.rsrc2) )
273 next_pc = pc_plus4 + (sext(it.offset) << 2);
275 // -- Jumps -----------------------------------------------------
277 tagged J .it :
278 next_pc = { pc_plus4[31:28], it.target, 2'b0 };
280 tagged JR .it :
281 next_pc = rf.rd1(it.rsrc);
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
289 tagged JALR .it :
290 begin
291 rf.wr( it.rdst, pc_plus4 );
292 next_pc = rf.rd1(it.rsrc);
293 end
295 // -- Cop0 ------------------------------------------------------
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
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
314 // -- Illegal ---------------------------------------------------
316 default :
317 $display( " RTL-ERROR : %m : Illegal instruction !" );
319 endcase
321 stage <= next_stage;
322 pc <= next_pc;
324 if ( cp0_statsEn )
325 num_inst.incr();
327 endrule
329 rule writeback ( stage == Writeback );
330 traceTiny("mkProc", "writeback","W");
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
338 stage <= PCgen;
339 endrule
341 rule inc_num_cycles;
342 if ( cp0_statsEn )
343 num_cycles.incr();
344 endrule
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
357 //-----------------------------------------------------------
358 // Methods
360 interface Client imem_client;
361 interface Get request = fifoToGet(instReqQ);
362 interface Put response = fifoToPut(instRespQ);
363 endinterface
365 interface Client dmem_client;
366 interface Get request = fifoToGet(dataReqQ);
367 interface Put response = fifoToPut(dataRespQ);
368 endinterface
370 interface Get statsEn_get = regToGet(cp0_statsEn);
372 endmodule