Mercurial > pygar
diff 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 diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/modules/bluespec/Pygar/lab4/Proc.bsv Fri Apr 23 02:32:05 2010 -0400 1.3 @@ -0,0 +1,342 @@ 1.4 +import CBusUtils::*; 1.5 +import Register::*; 1.6 + 1.7 +import Trace::*; 1.8 +import MemTypes::*; 1.9 +import IProc::*; 1.10 +import ProcTypes::*; 1.11 +import FPGATypes::*; 1.12 +import RegFile::*; 1.13 +import FIFO::*; 1.14 +import BFIFO::*; 1.15 +import Assert::*; 1.16 + 1.17 +import GetPut::*; 1.18 +import GetPutExt::*; 1.19 +import ClientServer::*; 1.20 +import CBus::*; 1.21 + 1.22 + 1.23 +interface IProc; 1.24 + 1.25 + // Interface for testrig 1.26 + interface Put#(Bit#(8)) testrig_fromhost; 1.27 + interface Get#(Bit#(8)) testrig_tohost; 1.28 + 1.29 + // Interface from processor to caches 1.30 + interface Client#(DataReq,DataResp) dmem_client; 1.31 + interface Client#(InstReq,InstResp) imem_client; 1.32 + 1.33 + // Interface for enabling/disabling statistics on the rest of the core 1.34 + interface Get#(Bool) statsEn_get; 1.35 + 1.36 +endinterface 1.37 + 1.38 + 1.39 +typedef enum { PCgen, Exec, Writeback } Stage deriving(Eq,Bits); 1.40 + 1.41 +//----------------------------------------------------------- 1.42 +// Register file module 1.43 +//----------------------------------------------------------- 1.44 + 1.45 +interface RFile; 1.46 + method Action wr( Rindx rindx, Bit#(32) data ); 1.47 + method Bit#(32) rd1( Rindx rindx ); 1.48 + method Bit#(32) rd2( Rindx rindx ); 1.49 +endinterface 1.50 + 1.51 +module mkRFile( RFile ); 1.52 + 1.53 + RegFile#(Rindx,Bit#(32)) rfile <- mkRegFileFull(); 1.54 + 1.55 + method Action wr( Rindx rindx, Bit#(32) data ); 1.56 + rfile.upd( rindx, data ); 1.57 + endmethod 1.58 + 1.59 + method Bit#(32) rd1( Rindx rindx ); 1.60 + return ( rindx == 0 ) ? 0 : rfile.sub(rindx); 1.61 + endmethod 1.62 + 1.63 + method Bit#(32) rd2( Rindx rindx ); 1.64 + return ( rindx == 0 ) ? 0 : rfile.sub(rindx); 1.65 + endmethod 1.66 + 1.67 +endmodule 1.68 + 1.69 +//----------------------------------------------------------- 1.70 +// Helper functions 1.71 +//----------------------------------------------------------- 1.72 + 1.73 +function Bit#(32) slt( Bit#(32) val1, Bit#(32) val2 ); 1.74 + return zeroExtend( pack( signedLT(val1,val2) ) ); 1.75 +endfunction 1.76 + 1.77 +function Bit#(32) sltu( Bit#(32) val1, Bit#(32) val2 ); 1.78 + return zeroExtend( pack( val1 < val2 ) ); 1.79 +endfunction 1.80 + 1.81 +function Bit#(32) rshft( Bit#(32) val ); 1.82 + return zeroExtend(val[4:0]); 1.83 +endfunction 1.84 + 1.85 +//----------------------------------------------------------- 1.86 +// Reference processor 1.87 +//----------------------------------------------------------- 1.88 + 1.89 + 1.90 +module [ModWithCBus#(AvalonAddressWidth,AvalonDataWidth)] mkProc( IProc ); 1.91 + 1.92 + //----------------------------------------------------------- 1.93 + // State 1.94 + 1.95 + // Standard processor state 1.96 + 1.97 + Reg#(Addr) pc <- mkReg(32'h00001000); 1.98 + Reg#(Stage) stage <- mkReg(PCgen); 1.99 + RFile rf <- mkRFile; 1.100 + 1.101 + // Coprocessor state 1.102 + 1.103 + Reg#(Bit#(8)) cp0_tohost <- mkReg(0); 1.104 + mkCBusWideRegRW(valueof(ToHostRegAddr),cp0_tohost); 1.105 + Reg#(Bit#(8)) cp0_fromhost <- mkReg(0); 1.106 + mkCBusWideRegRW(valueof(FromHostRegAddr),cp0_fromhost); 1.107 + Reg#(Bool) cp0_statsEn <- mkReg(False); 1.108 + mkCBusWideRegRW(valueof(StatsEnRegAddr),cp0_statsEn); 1.109 + // Memory request/response state 1.110 + 1.111 + FIFO#(InstReq) instReqQ <- mkBFIFO1(); 1.112 + FIFO#(InstResp) instRespQ <- mkFIFO(); 1.113 + 1.114 + FIFO#(DataReq) dataReqQ <- mkBFIFO1(); 1.115 + FIFO#(DataResp) dataRespQ <- mkFIFO(); 1.116 + 1.117 + // Statistics state 1.118 + 1.119 + Reg#(Int#(25)) num_cycles <- mkReg(25'h0); 1.120 + Reg#(Int#(25)) num_inst <- mkReg(25'h0); 1.121 + 1.122 + //----------------------------------------------------------- 1.123 + // Rules 1.124 + 1.125 + let pc_plus4 = pc + 4; 1.126 + 1.127 + rule pcgen ( stage == PCgen ); 1.128 + traceTiny("pc",pc); 1.129 + traceTiny("stage","P"); 1.130 + instReqQ.enq( LoadReq{ addr:pc, tag:0 } ); 1.131 + stage <= Exec; 1.132 + endrule 1.133 + 1.134 + rule exec ( stage == Exec ); 1.135 + 1.136 + // Some abbreviations 1.137 + let sext = signExtend; 1.138 + let zext = zeroExtend; 1.139 + let sra = signedShiftRight; 1.140 + 1.141 + // Get the instruction 1.142 + 1.143 + instRespQ.deq(); 1.144 + Instr inst 1.145 + = case ( instRespQ.first() ) matches 1.146 + tagged LoadResp .ld : return unpack(ld.data); 1.147 + tagged StoreResp .st : return ?; 1.148 + endcase; 1.149 + 1.150 + // Some default variables 1.151 + Stage next_stage = PCgen; 1.152 + Addr next_pc = pc_plus4; 1.153 + 1.154 + // Tracing 1.155 + traceTiny("stage","X"); 1.156 + traceTiny("exInstTiny",inst); 1.157 + traceFull("exInstFull",inst); 1.158 + 1.159 + case ( inst ) matches 1.160 + 1.161 + // -- Memory Ops ------------------------------------------------ 1.162 + 1.163 + tagged LW .it : 1.164 + begin 1.165 + Addr addr = rf.rd1(it.rbase) + sext(it.offset); 1.166 + dataReqQ.enq( LoadReq{ addr:addr, tag:zeroExtend(it.rdst) } ); 1.167 + next_stage = Writeback; 1.168 + end 1.169 + 1.170 + tagged SW .it : 1.171 + begin 1.172 + Addr addr = rf.rd1(it.rbase) + sext(it.offset); 1.173 + dataReqQ.enq( StoreReq{ tag:0, addr:addr, data:rf.rd1(it.rsrc) } ); 1.174 + next_stage = Writeback; 1.175 + end 1.176 + 1.177 + // -- Simple Ops ------------------------------------------------ 1.178 + 1.179 + tagged ADDIU .it : rf.wr( it.rdst, rf.rd1(it.rsrc) + sext(it.imm) ); 1.180 + tagged SLTI .it : rf.wr( it.rdst, slt( rf.rd1(it.rsrc), sext(it.imm) ) ); 1.181 + tagged SLTIU .it : rf.wr( it.rdst, sltu( rf.rd1(it.rsrc), sext(it.imm) ) ); 1.182 + tagged ANDI .it : 1.183 + begin 1.184 + Bit#(32) zext_it_imm = zext(it.imm); 1.185 + rf.wr( it.rdst, rf.rd1(it.rsrc) & zext_it_imm ); 1.186 + end 1.187 + tagged ORI .it : 1.188 + begin 1.189 + Bit#(32) zext_it_imm = zext(it.imm); 1.190 + rf.wr( it.rdst, rf.rd1(it.rsrc) | zext_it_imm ); 1.191 + end 1.192 + tagged XORI .it : 1.193 + begin 1.194 + Bit#(32) zext_it_imm = zext(it.imm); 1.195 + rf.wr( it.rdst, rf.rd1(it.rsrc) ^ zext_it_imm ); 1.196 + end 1.197 + tagged LUI .it : 1.198 + begin 1.199 + Bit#(32) zext_it_imm = zext(it.imm); 1.200 + rf.wr( it.rdst, (zext_it_imm << 32'd16) ); 1.201 + end 1.202 + 1.203 + tagged SLL .it : 1.204 + begin 1.205 + Bit#(32) zext_it_shamt = zext(it.shamt); 1.206 + rf.wr( it.rdst, rf.rd1(it.rsrc) << zext_it_shamt ); 1.207 + end 1.208 + tagged SRL .it : 1.209 + begin 1.210 + Bit#(32) zext_it_shamt = zext(it.shamt); 1.211 + rf.wr( it.rdst, rf.rd1(it.rsrc) >> zext_it_shamt ); 1.212 + end 1.213 + tagged SRA .it : 1.214 + begin 1.215 + Bit#(32) zext_it_shamt = zext(it.shamt); 1.216 + rf.wr( it.rdst, sra( rf.rd1(it.rsrc), zext_it_shamt )); 1.217 + end 1.218 + tagged SLLV .it : rf.wr( it.rdst, rf.rd1(it.rsrc) << rshft(rf.rd2(it.rshamt)) ); 1.219 + tagged SRLV .it : rf.wr( it.rdst, rf.rd1(it.rsrc) >> rshft(rf.rd2(it.rshamt)) ); 1.220 + tagged SRAV .it : rf.wr( it.rdst, sra( rf.rd1(it.rsrc), rshft(rf.rd2(it.rshamt)) ) ); 1.221 + tagged ADDU .it : rf.wr( it.rdst, rf.rd1(it.rsrc1) + rf.rd2(it.rsrc2) ); 1.222 + tagged SUBU .it : rf.wr( it.rdst, rf.rd1(it.rsrc1) - rf.rd2(it.rsrc2) ); 1.223 + tagged AND .it : rf.wr( it.rdst, rf.rd1(it.rsrc1) & rf.rd2(it.rsrc2) ); 1.224 + tagged OR .it : rf.wr( it.rdst, rf.rd1(it.rsrc1) | rf.rd2(it.rsrc2) ); 1.225 + tagged XOR .it : rf.wr( it.rdst, rf.rd1(it.rsrc1) ^ rf.rd2(it.rsrc2) ); 1.226 + tagged NOR .it : rf.wr( it.rdst, ~(rf.rd1(it.rsrc1) | rf.rd2(it.rsrc2)) ); 1.227 + tagged SLT .it : rf.wr( it.rdst, slt( rf.rd1(it.rsrc1), rf.rd2(it.rsrc2) ) ); 1.228 + tagged SLTU .it : rf.wr( it.rdst, sltu( rf.rd1(it.rsrc1), rf.rd2(it.rsrc2) ) ); 1.229 + 1.230 + // -- Branches -------------------------------------------------- 1.231 + 1.232 + tagged BLEZ .it : 1.233 + if ( signedLE( rf.rd1(it.rsrc), 0 ) ) 1.234 + next_pc = pc_plus4 + (sext(it.offset) << 2); 1.235 + 1.236 + tagged BGTZ .it : 1.237 + if ( signedGT( rf.rd1(it.rsrc), 0 ) ) 1.238 + next_pc = pc_plus4 + (sext(it.offset) << 2); 1.239 + 1.240 + tagged BLTZ .it : 1.241 + if ( signedLT( rf.rd1(it.rsrc), 0 ) ) 1.242 + next_pc = pc_plus4 + (sext(it.offset) << 2); 1.243 + 1.244 + tagged BGEZ .it : 1.245 + if ( signedGE( rf.rd1(it.rsrc), 0 ) ) 1.246 + next_pc = pc_plus4 + (sext(it.offset) << 2); 1.247 + 1.248 + tagged BEQ .it : 1.249 + if ( rf.rd1(it.rsrc1) == rf.rd2(it.rsrc2) ) 1.250 + next_pc = pc_plus4 + (sext(it.offset) << 2); 1.251 + 1.252 + tagged BNE .it : 1.253 + if ( rf.rd1(it.rsrc1) != rf.rd2(it.rsrc2) ) 1.254 + next_pc = pc_plus4 + (sext(it.offset) << 2); 1.255 + 1.256 + // -- Jumps ----------------------------------------------------- 1.257 + 1.258 + tagged J .it : 1.259 + next_pc = { pc_plus4[31:28], it.target, 2'b0 }; 1.260 + 1.261 + tagged JR .it : 1.262 + next_pc = rf.rd1(it.rsrc); 1.263 + 1.264 + tagged JAL .it : 1.265 + begin 1.266 + rf.wr( 31, pc_plus4 ); 1.267 + next_pc = { pc_plus4[31:28], it.target, 2'b0 }; 1.268 + end 1.269 + 1.270 + tagged JALR .it : 1.271 + begin 1.272 + rf.wr( it.rdst, pc_plus4 ); 1.273 + next_pc = rf.rd1(it.rsrc); 1.274 + end 1.275 + 1.276 + // -- Cop0 ------------------------------------------------------ 1.277 + 1.278 + tagged MTC0 .it : 1.279 + case ( it.cop0dst ) 1.280 + 5'd10 : cp0_statsEn <= unpack(truncate(rf.rd1(it.rsrc))); 1.281 + 5'd21 : cp0_tohost <= truncate(rf.rd1(it.rsrc)); 1.282 + default : 1.283 + $display( " RTL-ERROR : %m : Illegal MTC0 cop0dst register!" ); 1.284 + endcase 1.285 + 1.286 + tagged MFC0 .it : 1.287 + case ( it.cop0src ) 1.288 + 5'd10 : rf.wr( it.rdst, zext(pack(cp0_statsEn)) ); 1.289 + 5'd20 : rf.wr( it.rdst, zext(cp0_fromhost) ); 1.290 + 5'd21 : rf.wr( it.rdst, zext(cp0_tohost) ); 1.291 + default : 1.292 + $display( " RTL-ERROR : %m : Illegal MFC0 cop0src register!" ); 1.293 + endcase 1.294 + 1.295 + // -- Illegal --------------------------------------------------- 1.296 + 1.297 + default : 1.298 + $display( " RTL-ERROR : %m : Illegal instruction !" ); 1.299 + 1.300 + endcase 1.301 + 1.302 + stage <= next_stage; 1.303 + pc <= next_pc; 1.304 + 1.305 + if ( cp0_statsEn ) 1.306 + num_inst <= num_inst + 1; 1.307 + 1.308 + endrule 1.309 + 1.310 + rule writeback ( stage == Writeback ); 1.311 + traceTiny("stage","W"); 1.312 + 1.313 + dataRespQ.deq(); 1.314 + case ( dataRespQ.first() ) matches 1.315 + tagged LoadResp .ld : rf.wr( truncate(ld.tag), ld.data ); 1.316 + tagged StoreResp .st : noAction; 1.317 + endcase 1.318 + 1.319 + stage <= PCgen; 1.320 + endrule 1.321 + 1.322 + rule inc_num_cycles; 1.323 + if ( cp0_statsEn ) 1.324 + num_cycles <= num_cycles + 1; 1.325 + endrule 1.326 + 1.327 + //----------------------------------------------------------- 1.328 + // Methods 1.329 + 1.330 + interface Client imem_client; 1.331 + interface Get request = fifoToGet(instReqQ); 1.332 + interface Put response = fifoToPut(instRespQ); 1.333 + endinterface 1.334 + 1.335 + interface Client dmem_client; 1.336 + interface Get request = fifoToGet(dataReqQ); 1.337 + interface Put response = fifoToPut(dataRespQ); 1.338 + endinterface 1.339 + 1.340 + interface Get testrig_tohost = regToGet(cp0_tohost); 1.341 + interface Put testrig_fromhost = regToPut(cp0_fromhost); 1.342 + interface Get statsEn_get = regToGet(cp0_statsEn); 1.343 + 1.344 +endmodule 1.345 +