view 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
line wrap: on
line source
1 import CBusUtils::*;
2 import Register::*;
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::*;
14 import GetPut::*;
15 import GetPutExt::*;
16 import ClientServer::*;
17 import CBus::*;
20 interface IProc;
22 // Interface for testrig
23 interface Put#(Bit#(8)) testrig_fromhost;
24 interface Get#(Bit#(8)) testrig_tohost;
26 // Interface from processor to caches
27 interface Client#(DataReq,DataResp) dmem_client;
28 interface Client#(InstReq,InstResp) imem_client;
30 // Interface for enabling/disabling statistics on the rest of the core
31 interface Get#(Bool) statsEn_get;
33 endinterface
36 typedef enum { PCgen, Exec, Writeback } Stage deriving(Eq,Bits);
38 //-----------------------------------------------------------
39 // Register file module
40 //-----------------------------------------------------------
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
48 module mkRFile( RFile );
50 RegFile#(Rindx,Bit#(32)) rfile <- mkRegFileFull();
52 method Action wr( Rindx rindx, Bit#(32) data );
53 rfile.upd( rindx, data );
54 endmethod
56 method Bit#(32) rd1( Rindx rindx );
57 return ( rindx == 0 ) ? 0 : rfile.sub(rindx);
58 endmethod
60 method Bit#(32) rd2( Rindx rindx );
61 return ( rindx == 0 ) ? 0 : rfile.sub(rindx);
62 endmethod
64 endmodule
66 //-----------------------------------------------------------
67 // Helper functions
68 //-----------------------------------------------------------
70 function Bit#(32) slt( Bit#(32) val1, Bit#(32) val2 );
71 return zeroExtend( pack( signedLT(val1,val2) ) );
72 endfunction
74 function Bit#(32) sltu( Bit#(32) val1, Bit#(32) val2 );
75 return zeroExtend( pack( val1 < val2 ) );
76 endfunction
78 function Bit#(32) rshft( Bit#(32) val );
79 return zeroExtend(val[4:0]);
80 endfunction
82 //-----------------------------------------------------------
83 // Reference processor
84 //-----------------------------------------------------------
87 module [ModWithCBus#(AvalonAddressWidth,AvalonDataWidth)] mkProc( IProc );
89 //-----------------------------------------------------------
90 // State
92 // Standard processor state
94 Reg#(Addr) pc <- mkReg(32'h00001000);
95 Reg#(Stage) stage <- mkReg(PCgen);
96 RFile rf <- mkRFile;
98 // Coprocessor state
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
108 FIFO#(InstReq) instReqQ <- mkBFIFO1();
109 FIFO#(InstResp) instRespQ <- mkFIFO();
111 FIFO#(DataReq) dataReqQ <- mkBFIFO1();
112 FIFO#(DataResp) dataRespQ <- mkFIFO();
114 // Statistics state
116 Reg#(Int#(25)) num_cycles <- mkReg(25'h0);
117 Reg#(Int#(25)) num_inst <- mkReg(25'h0);
119 //-----------------------------------------------------------
120 // Rules
122 let pc_plus4 = pc + 4;
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
131 rule exec ( stage == Exec );
133 // Some abbreviations
134 let sext = signExtend;
135 let zext = zeroExtend;
136 let sra = signedShiftRight;
138 // Get the instruction
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;
147 // Some default variables
148 Stage next_stage = PCgen;
149 Addr next_pc = pc_plus4;
151 // Tracing
152 traceTiny("stage","X");
153 traceTiny("exInstTiny",inst);
154 traceFull("exInstFull",inst);
156 case ( inst ) matches
158 // -- Memory Ops ------------------------------------------------
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
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
174 // -- Simple Ops ------------------------------------------------
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
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) ) );
227 // -- Branches --------------------------------------------------
229 tagged BLEZ .it :
230 if ( signedLE( rf.rd1(it.rsrc), 0 ) )
231 next_pc = pc_plus4 + (sext(it.offset) << 2);
233 tagged BGTZ .it :
234 if ( signedGT( rf.rd1(it.rsrc), 0 ) )
235 next_pc = pc_plus4 + (sext(it.offset) << 2);
237 tagged BLTZ .it :
238 if ( signedLT( rf.rd1(it.rsrc), 0 ) )
239 next_pc = pc_plus4 + (sext(it.offset) << 2);
241 tagged BGEZ .it :
242 if ( signedGE( rf.rd1(it.rsrc), 0 ) )
243 next_pc = pc_plus4 + (sext(it.offset) << 2);
245 tagged BEQ .it :
246 if ( rf.rd1(it.rsrc1) == rf.rd2(it.rsrc2) )
247 next_pc = pc_plus4 + (sext(it.offset) << 2);
249 tagged BNE .it :
250 if ( rf.rd1(it.rsrc1) != rf.rd2(it.rsrc2) )
251 next_pc = pc_plus4 + (sext(it.offset) << 2);
253 // -- Jumps -----------------------------------------------------
255 tagged J .it :
256 next_pc = { pc_plus4[31:28], it.target, 2'b0 };
258 tagged JR .it :
259 next_pc = rf.rd1(it.rsrc);
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
267 tagged JALR .it :
268 begin
269 rf.wr( it.rdst, pc_plus4 );
270 next_pc = rf.rd1(it.rsrc);
271 end
273 // -- Cop0 ------------------------------------------------------
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
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
292 // -- Illegal ---------------------------------------------------
294 default :
295 $display( " RTL-ERROR : %m : Illegal instruction !" );
297 endcase
299 stage <= next_stage;
300 pc <= next_pc;
302 if ( cp0_statsEn )
303 num_inst <= num_inst + 1;
305 endrule
307 rule writeback ( stage == Writeback );
308 traceTiny("stage","W");
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
316 stage <= PCgen;
317 endrule
319 rule inc_num_cycles;
320 if ( cp0_statsEn )
321 num_cycles <= num_cycles + 1;
322 endrule
324 //-----------------------------------------------------------
325 // Methods
327 interface Client imem_client;
328 interface Get request = fifoToGet(instReqQ);
329 interface Put response = fifoToPut(instRespQ);
330 endinterface
332 interface Client dmem_client;
333 interface Get request = fifoToGet(dataReqQ);
334 interface Put response = fifoToPut(dataRespQ);
335 endinterface
337 interface Get testrig_tohost = regToGet(cp0_tohost);
338 interface Put testrig_fromhost = regToPut(cp0_fromhost);
339 interface Get statsEn_get = regToGet(cp0_statsEn);
341 endmodule