Mercurial > pygar
diff 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 |
line wrap: on
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/modules/bluespec/Pygar/lab4/oProcessor.bsv Fri Apr 23 02:32:05 2010 -0400 1.3 @@ -0,0 +1,373 @@ 1.4 +// The MIT License 1.5 + 1.6 +// Copyright (c) 2009 Massachusetts Institute of Technology 1.7 + 1.8 +// Permission is hereby granted, free of charge, to any person obtaining a copy 1.9 +// of this software and associated documentation files (the "Software"), to deal 1.10 +// in the Software without restriction, including without limitation the rights 1.11 +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 1.12 +// copies of the Software, and to permit persons to whom the Software is 1.13 +// furnished to do so, subject to the following conditions: 1.14 + 1.15 +// The above copyright notice and this permission notice shall be included in 1.16 +// all copies or substantial portions of the Software. 1.17 + 1.18 +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1.19 +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1.20 +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 1.21 +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 1.22 +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 1.23 +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 1.24 +// THE SOFTWARE. 1.25 + 1.26 +import Connectable::*; 1.27 +import GetPut::*; 1.28 +import ClientServer::*; 1.29 +import RegFile::*; 1.30 +import FIFO::*; 1.31 +import FIFOF::*; 1.32 +import RWire::*; 1.33 + 1.34 +//AWB includes 1.35 +`include "asim/provides/low_level_platform_interface.bsh" 1.36 +`include "asim/provides/soft_connections.bsh" 1.37 +`include "asim/provides/common_services.bsh" 1.38 + 1.39 +// Local includes 1.40 +`include "asim/provides/processor_library.bsh" 1.41 +`include "asim/rrr/remote_server_stub_PROCESSORSYSTEMRRR.bsh" 1.42 +`include "asim/provides/common_services.bsh" 1.43 +`include "asim/dict/STATS_PROCESSOR.bsh" 1.44 + 1.45 +interface Proc; 1.46 + 1.47 + // Interface from processor to caches 1.48 + interface Client#(DataReq,DataResp) dmem_client; 1.49 + interface Client#(InstReq,InstResp) imem_client; 1.50 + 1.51 + // Interface for enabling/disabling statistics on the rest of the core 1.52 + interface Get#(Bool) statsEn_get; 1.53 + 1.54 +endinterface 1.55 + 1.56 + 1.57 +typedef enum { PCgen, Exec, Writeback } Stage deriving(Eq,Bits); 1.58 + 1.59 +//----------------------------------------------------------- 1.60 +// Register file module 1.61 +//----------------------------------------------------------- 1.62 + 1.63 +interface RFile; 1.64 + method Action wr( Rindx rindx, Bit#(32) data ); 1.65 + method Bit#(32) rd1( Rindx rindx ); 1.66 + method Bit#(32) rd2( Rindx rindx ); 1.67 +endinterface 1.68 + 1.69 +module mkRFile( RFile ); 1.70 + 1.71 + RegFile#(Rindx,Bit#(32)) rfile <- mkRegFileFull(); 1.72 + 1.73 + method Action wr( Rindx rindx, Bit#(32) data ); 1.74 + rfile.upd( rindx, data ); 1.75 + endmethod 1.76 + 1.77 + method Bit#(32) rd1( Rindx rindx ); 1.78 + return ( rindx == 0 ) ? 0 : rfile.sub(rindx); 1.79 + endmethod 1.80 + 1.81 + method Bit#(32) rd2( Rindx rindx ); 1.82 + return ( rindx == 0 ) ? 0 : rfile.sub(rindx); 1.83 + endmethod 1.84 + 1.85 +endmodule 1.86 + 1.87 +//----------------------------------------------------------- 1.88 +// Helper functions 1.89 +//----------------------------------------------------------- 1.90 + 1.91 +function Bit#(32) slt( Bit#(32) val1, Bit#(32) val2 ); 1.92 + return zeroExtend( pack( signedLT(val1,val2) ) ); 1.93 +endfunction 1.94 + 1.95 +function Bit#(32) sltu( Bit#(32) val1, Bit#(32) val2 ); 1.96 + return zeroExtend( pack( val1 < val2 ) ); 1.97 +endfunction 1.98 + 1.99 +function Bit#(32) rshft( Bit#(32) val ); 1.100 + return zeroExtend(val[4:0]); 1.101 +endfunction 1.102 + 1.103 +//----------------------------------------------------------- 1.104 +// Reference processor 1.105 +//----------------------------------------------------------- 1.106 + 1.107 + 1.108 +module [CONNECTED_MODULE] mkProc( Proc ); 1.109 + 1.110 + //----------------------------------------------------------- 1.111 + // Debug port 1.112 + 1.113 + ServerStub_PROCESSORSYSTEMRRR server_stub <- mkServerStub_PROCESSORSYSTEMRRR(); 1.114 + 1.115 + //----------------------------------------------------------- 1.116 + // State 1.117 + 1.118 + // Standard processor state 1.119 + 1.120 + Reg#(Addr) pc <- mkReg(32'h00001000); 1.121 + Reg#(Stage) stage <- mkReg(PCgen); 1.122 + RFile rf <- mkRFile; 1.123 + 1.124 + // Coprocessor state - connected by way of RRR 1.125 + 1.126 + Reg#(Bit#(32)) cp0_tohost <- mkReg(0); 1.127 + 1.128 + Reg#(Bit#(32)) cp0_fromhost <- mkReg(0); 1.129 + 1.130 + Reg#(Bool) cp0_statsEn <- mkReg(False); 1.131 + 1.132 + // Memory request/response state 1.133 + 1.134 + FIFO#(InstReq) instReqQ <- mkBFIFO1(); 1.135 + FIFO#(InstResp) instRespQ <- mkFIFO(); 1.136 + 1.137 + FIFO#(DataReq) dataReqQ <- mkBFIFO1(); 1.138 + FIFO#(DataResp) dataRespQ <- mkFIFO(); 1.139 + 1.140 + // Statistics state 1.141 + STAT num_cycles <- mkStatCounter(`STATS_PROCESSOR_CYCLE_COUNT); 1.142 + STAT num_inst <- mkStatCounter(`STATS_PROCESSOR_INST_COUNT); 1.143 + 1.144 + //----------------------------------------------------------- 1.145 + // Rules 1.146 + 1.147 + let pc_plus4 = pc + 4; 1.148 + 1.149 + rule pcgen ( stage == PCgen ); 1.150 + traceTiny("mkProc", "pc",pc); 1.151 + traceTiny("mkProc", "pcgen","P"); 1.152 + instReqQ.enq( LoadReq{ addr:pc, tag:0 } ); 1.153 + stage <= Exec; 1.154 + endrule 1.155 + 1.156 + rule exec ( stage == Exec ); 1.157 + 1.158 + // Some abbreviations 1.159 + let sext = signExtend; 1.160 + let zext = zeroExtend; 1.161 + let sra = signedShiftRight; 1.162 + 1.163 + // Get the instruction 1.164 + 1.165 + instRespQ.deq(); 1.166 + Instr inst 1.167 + = case ( instRespQ.first() ) matches 1.168 + tagged LoadResp .ld : return unpack(ld.data); 1.169 + tagged StoreResp .st : return ?; 1.170 + endcase; 1.171 + 1.172 + // Some default variables 1.173 + Stage next_stage = PCgen; 1.174 + Addr next_pc = pc_plus4; 1.175 + 1.176 + // Tracing 1.177 + traceTiny("mkProc", "exec","X"); 1.178 + traceTiny("mkProc", "exInstTiny",inst); 1.179 + traceFull("mkProc", "exInstFull",inst); 1.180 + 1.181 + case ( inst ) matches 1.182 + 1.183 + // -- Memory Ops ------------------------------------------------ 1.184 + 1.185 + tagged LW .it : 1.186 + begin 1.187 + Addr addr = rf.rd1(it.rbase) + sext(it.offset); 1.188 + dataReqQ.enq( LoadReq{ addr:addr, tag:zeroExtend(it.rdst) } ); 1.189 + next_stage = Writeback; 1.190 + end 1.191 + 1.192 + tagged SW .it : 1.193 + begin 1.194 + Addr addr = rf.rd1(it.rbase) + sext(it.offset); 1.195 + dataReqQ.enq( StoreReq{ tag:0, addr:addr, data:rf.rd1(it.rsrc) } ); 1.196 + next_stage = Writeback; 1.197 + end 1.198 + 1.199 + // -- Simple Ops ------------------------------------------------ 1.200 + 1.201 + tagged ADDIU .it : rf.wr( it.rdst, rf.rd1(it.rsrc) + sext(it.imm) ); 1.202 + tagged SLTI .it : rf.wr( it.rdst, slt( rf.rd1(it.rsrc), sext(it.imm) ) ); 1.203 + tagged SLTIU .it : rf.wr( it.rdst, sltu( rf.rd1(it.rsrc), sext(it.imm) ) ); 1.204 + tagged ANDI .it : 1.205 + begin 1.206 + Bit#(32) zext_it_imm = zext(it.imm); 1.207 + rf.wr( it.rdst, rf.rd1(it.rsrc) & zext_it_imm ); 1.208 + end 1.209 + tagged ORI .it : 1.210 + begin 1.211 + Bit#(32) zext_it_imm = zext(it.imm); 1.212 + rf.wr( it.rdst, rf.rd1(it.rsrc) | zext_it_imm ); 1.213 + end 1.214 + tagged XORI .it : 1.215 + begin 1.216 + Bit#(32) zext_it_imm = zext(it.imm); 1.217 + rf.wr( it.rdst, rf.rd1(it.rsrc) ^ zext_it_imm ); 1.218 + end 1.219 + tagged LUI .it : 1.220 + begin 1.221 + Bit#(32) zext_it_imm = zext(it.imm); 1.222 + rf.wr( it.rdst, (zext_it_imm << 32'd16) ); 1.223 + end 1.224 + 1.225 + tagged SLL .it : 1.226 + begin 1.227 + Bit#(32) zext_it_shamt = zext(it.shamt); 1.228 + rf.wr( it.rdst, rf.rd1(it.rsrc) << zext_it_shamt ); 1.229 + end 1.230 + tagged SRL .it : 1.231 + begin 1.232 + Bit#(32) zext_it_shamt = zext(it.shamt); 1.233 + rf.wr( it.rdst, rf.rd1(it.rsrc) >> zext_it_shamt ); 1.234 + end 1.235 + tagged SRA .it : 1.236 + begin 1.237 + Bit#(32) zext_it_shamt = zext(it.shamt); 1.238 + rf.wr( it.rdst, sra( rf.rd1(it.rsrc), zext_it_shamt )); 1.239 + end 1.240 + tagged SLLV .it : rf.wr( it.rdst, rf.rd1(it.rsrc) << rshft(rf.rd2(it.rshamt)) ); 1.241 + tagged SRLV .it : rf.wr( it.rdst, rf.rd1(it.rsrc) >> rshft(rf.rd2(it.rshamt)) ); 1.242 + tagged SRAV .it : rf.wr( it.rdst, sra( rf.rd1(it.rsrc), rshft(rf.rd2(it.rshamt)) ) ); 1.243 + tagged ADDU .it : rf.wr( it.rdst, rf.rd1(it.rsrc1) + rf.rd2(it.rsrc2) ); 1.244 + tagged SUBU .it : rf.wr( it.rdst, rf.rd1(it.rsrc1) - rf.rd2(it.rsrc2) ); 1.245 + tagged AND .it : rf.wr( it.rdst, rf.rd1(it.rsrc1) & rf.rd2(it.rsrc2) ); 1.246 + tagged OR .it : rf.wr( it.rdst, rf.rd1(it.rsrc1) | rf.rd2(it.rsrc2) ); 1.247 + tagged XOR .it : rf.wr( it.rdst, rf.rd1(it.rsrc1) ^ rf.rd2(it.rsrc2) ); 1.248 + tagged NOR .it : rf.wr( it.rdst, ~(rf.rd1(it.rsrc1) | rf.rd2(it.rsrc2)) ); 1.249 + tagged SLT .it : rf.wr( it.rdst, slt( rf.rd1(it.rsrc1), rf.rd2(it.rsrc2) ) ); 1.250 + tagged SLTU .it : rf.wr( it.rdst, sltu( rf.rd1(it.rsrc1), rf.rd2(it.rsrc2) ) ); 1.251 + 1.252 + // -- Branches -------------------------------------------------- 1.253 + 1.254 + tagged BLEZ .it : 1.255 + if ( signedLE( rf.rd1(it.rsrc), 0 ) ) 1.256 + next_pc = pc_plus4 + (sext(it.offset) << 2); 1.257 + 1.258 + tagged BGTZ .it : 1.259 + if ( signedGT( rf.rd1(it.rsrc), 0 ) ) 1.260 + next_pc = pc_plus4 + (sext(it.offset) << 2); 1.261 + 1.262 + tagged BLTZ .it : 1.263 + if ( signedLT( rf.rd1(it.rsrc), 0 ) ) 1.264 + next_pc = pc_plus4 + (sext(it.offset) << 2); 1.265 + 1.266 + tagged BGEZ .it : 1.267 + if ( signedGE( rf.rd1(it.rsrc), 0 ) ) 1.268 + next_pc = pc_plus4 + (sext(it.offset) << 2); 1.269 + 1.270 + tagged BEQ .it : 1.271 + if ( rf.rd1(it.rsrc1) == rf.rd2(it.rsrc2) ) 1.272 + next_pc = pc_plus4 + (sext(it.offset) << 2); 1.273 + 1.274 + tagged BNE .it : 1.275 + if ( rf.rd1(it.rsrc1) != rf.rd2(it.rsrc2) ) 1.276 + next_pc = pc_plus4 + (sext(it.offset) << 2); 1.277 + 1.278 + // -- Jumps ----------------------------------------------------- 1.279 + 1.280 + tagged J .it : 1.281 + next_pc = { pc_plus4[31:28], it.target, 2'b0 }; 1.282 + 1.283 + tagged JR .it : 1.284 + next_pc = rf.rd1(it.rsrc); 1.285 + 1.286 + tagged JAL .it : 1.287 + begin 1.288 + rf.wr( 31, pc_plus4 ); 1.289 + next_pc = { pc_plus4[31:28], it.target, 2'b0 }; 1.290 + end 1.291 + 1.292 + tagged JALR .it : 1.293 + begin 1.294 + rf.wr( it.rdst, pc_plus4 ); 1.295 + next_pc = rf.rd1(it.rsrc); 1.296 + end 1.297 + 1.298 + // -- Cop0 ------------------------------------------------------ 1.299 + 1.300 + tagged MTC0 .it : 1.301 + case ( it.cop0dst ) 1.302 + 5'd10 : cp0_statsEn <= unpack(truncate(rf.rd1(it.rsrc))); 1.303 + 5'd21 : cp0_tohost <= truncate(rf.rd1(it.rsrc)); 1.304 + default : 1.305 + $display( " RTL-ERROR : %m : Illegal MTC0 cop0dst register!" ); 1.306 + endcase 1.307 + 1.308 + tagged MFC0 .it : 1.309 + case ( it.cop0src ) 1.310 + 5'd10 : rf.wr( it.rdst, zext(pack(cp0_statsEn)) ); 1.311 + 5'd20 : rf.wr( it.rdst, cp0_fromhost ); 1.312 + 5'd21 : rf.wr( it.rdst, cp0_tohost ); 1.313 + default : 1.314 + $display( " RTL-ERROR : %m : Illegal MFC0 cop0src register!" ); 1.315 + endcase 1.316 + 1.317 + // -- Illegal --------------------------------------------------- 1.318 + 1.319 + default : 1.320 + $display( " RTL-ERROR : %m : Illegal instruction !" ); 1.321 + 1.322 + endcase 1.323 + 1.324 + stage <= next_stage; 1.325 + pc <= next_pc; 1.326 + 1.327 + if ( cp0_statsEn ) 1.328 + num_inst.incr(); 1.329 + 1.330 + endrule 1.331 + 1.332 + rule writeback ( stage == Writeback ); 1.333 + traceTiny("mkProc", "writeback","W"); 1.334 + 1.335 + dataRespQ.deq(); 1.336 + case ( dataRespQ.first() ) matches 1.337 + tagged LoadResp .ld : rf.wr( truncate(ld.tag), ld.data ); 1.338 + tagged StoreResp .st : noAction; 1.339 + endcase 1.340 + 1.341 + stage <= PCgen; 1.342 + endrule 1.343 + 1.344 + rule inc_num_cycles; 1.345 + if ( cp0_statsEn ) 1.346 + num_cycles.incr(); 1.347 + endrule 1.348 + 1.349 + rule handleCPUToHost; 1.350 + let req <- server_stub.acceptRequest_ReadCPUToHost(); 1.351 + case (req) 1.352 + 0: server_stub.sendResponse_ReadCPUToHost(cp0_tohost); 1.353 + 1: server_stub.sendResponse_ReadCPUToHost(pc); 1.354 + 2: server_stub.sendResponse_ReadCPUToHost(zeroExtend(pack(stage))); 1.355 + endcase 1.356 + endrule 1.357 + 1.358 + 1.359 + 1.360 + //----------------------------------------------------------- 1.361 + // Methods 1.362 + 1.363 + interface Client imem_client; 1.364 + interface Get request = fifoToGet(instReqQ); 1.365 + interface Put response = fifoToPut(instRespQ); 1.366 + endinterface 1.367 + 1.368 + interface Client dmem_client; 1.369 + interface Get request = fifoToGet(dataReqQ); 1.370 + interface Put response = fifoToPut(dataRespQ); 1.371 + endinterface 1.372 + 1.373 + interface Get statsEn_get = regToGet(cp0_statsEn); 1.374 + 1.375 +endmodule 1.376 +