Mercurial > pygar
changeset 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.
line wrap: on
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/config/pm/Pygar/fullSystem/audio-core.apm Fri Apr 23 02:32:05 2010 -0400 1.3 @@ -0,0 +1,119 @@ 1.4 + 1.5 +[Soft Connections Hybrid Application Environment/Requires] 1.6 +platform_services=Platform Services 1.7 +soft_connections_lib=Soft Connections Library 1.8 +connected_application=Audio Processor Application 1.9 + 1.10 +[VMH hybrid memory] 1.11 +File=modules/hasim/functional-partition/memory-state/memory/hybrid/vmh/vmh-memory.awb 1.12 +Packagehint=hasim 1.13 + 1.14 +[Global] 1.15 +SaveParameters=0 1.16 +DefaultBenchmark= 1.17 +Version=2.1 1.18 +Type=HAsim 1.19 +File=audio-core 1.20 +Class=Asim::Model 1.21 +Name=Bob's Yer Unkle 1.22 +Description= 1.23 +DefaultRunOpts= 1.24 + 1.25 +[Hybrid Project Common Utilities] 1.26 +File=config/pm/hasim/submodels/common/project-common-default.apm 1.27 +Packagehint=hasim 1.28 + 1.29 +[Soft Connections Library] 1.30 +File=config/pm/hasim/submodels/common/soft-connections-lib.apm 1.31 +Packagehint=hasim 1.32 + 1.33 +[Functional Partition Base Types] 1.34 +File=modules/hasim/functional-partition/base-types/funcp-base-types.awb 1.35 +Packagehint=hasim 1.36 + 1.37 +[3-Stage Audio Processor] 1.38 +File=modules/bluespec/Pygar/core/processor.awb 1.39 +Packagehint=Pygar 1.40 + 1.41 +[Audio Processor Soft Core] 1.42 +File=modules/bluespec/Pygar/core/core.awb 1.43 +Packagehint=Pygar 1.44 + 1.45 +[Blocking Data Cache] 1.46 +File=modules/bluespec/Pygar/lab4/data_cache.awb 1.47 +Packagehint=Pygar 1.48 + 1.49 +[Platform Services] 1.50 +File=config/pm/hasim/submodels/platform-services/standard-platform-services.apm 1.51 +Packagehint=hasim 1.52 + 1.53 +[Blocking Instruction Cache] 1.54 +File=modules/bluespec/Pygar/lab4/instruction_cache.awb 1.55 +Packagehint=Pygar 1.56 + 1.57 +[audio core] 1.58 +File=modules/bluespec/Pygar/core/audio_core.awb 1.59 +Packagehint=Pygar 1.60 + 1.61 +[Model] 1.62 +DefaultAttributes= 1.63 +model=HW/SW Hybrid Project Foundation 1.64 + 1.65 +[audio core/Requires] 1.66 +hasim_common=Default HAsim Common Library 1.67 +funcp_simulated_memory=VMH hybrid memory 1.68 +core=Audio Processor Soft Core 1.69 +funcp_base_types=Functional Partition Base Types 1.70 +audio_pipeline_types=FIR Filter Pipeline Types 1.71 + 1.72 +[FPGA Environment] 1.73 +File=config/pm/hasim/submodels/fpgaenv/fpgaenv-hybrid-exe.apm 1.74 +Packagehint=platforms 1.75 + 1.76 +[HW/SW Hybrid Project Foundation] 1.77 +File=modules/project/project-hybrid.awb 1.78 +Packagehint=platforms 1.79 + 1.80 +[Round-robin Audio memory arbiter] 1.81 +File=modules/bluespec/Pygar/core/mem_arb.awb 1.82 +Packagehint=Pygar 1.83 + 1.84 +[Processor Audio Library] 1.85 +File=modules/bluespec/Pygar/core/processor_library.awb 1.86 +Packagehint=Pygar 1.87 + 1.88 +[Audio Processor Application/Requires] 1.89 +audio_pipeline=audio core 1.90 +audio_processor_types=Audio Processor Types 1.91 + 1.92 +[Default HAsim Common Library] 1.93 +File=config/pm/hasim/submodels/common/hasim_common.apm 1.94 +Packagehint=hasim 1.95 + 1.96 +[Audio Processor Application] 1.97 +File=modules/bluespec/Pygar/common/audio_processor_hardware_system.awb 1.98 +Packagehint=Pygar 1.99 + 1.100 +[Soft Connections Hybrid Application Environment] 1.101 +File=modules/application-env/hybrid/soft-connections/application-env-hybrid-soft-conn.awb 1.102 +Packagehint=platforms 1.103 + 1.104 +[HW/SW Hybrid Project Foundation/Requires] 1.105 +project_common=Hybrid Project Common Utilities 1.106 +fpgaenv=FPGA Environment 1.107 +application_env=Soft Connections Hybrid Application Environment 1.108 + 1.109 +[FIR Filter Pipeline Types] 1.110 +File=modules/bluespec/Pygar/lab1/fir_filter_types.awb 1.111 +Packagehint=Pygar 1.112 + 1.113 +[Audio Processor Soft Core/Requires] 1.114 +processor_library=Processor Audio Library 1.115 +processor=3-Stage Audio Processor 1.116 +data_cache=Blocking Data Cache 1.117 +instruction_cache=Blocking Instruction Cache 1.118 +mem_arb=Round-robin Audio memory arbiter 1.119 + 1.120 +[Audio Processor Types] 1.121 +File=modules/bluespec/Pygar/common/audio_processor_types.awb 1.122 +Packagehint=Pygar
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/config/pm/Pygar/fullSystem/audio_processor_exe.apm Fri Apr 23 02:32:05 2010 -0400 2.3 @@ -0,0 +1,71 @@ 2.4 + 2.5 +[Global] 2.6 +SaveParameters=0 2.7 +Description= 2.8 +File=audio_processor_exe 2.9 +Version=2.1 2.10 +Name=Audio Processor 2.11 +DefaultBenchmark=config/bm/bluespec/demos.cfx/benchmarks/null.cfg 2.12 +Type=HAsim 2.13 +Class=Asim::Model 2.14 +DefaultRunOpts= 2.15 + 2.16 +[Model] 2.17 +DefaultAttributes=hybrid simulation 2.18 +model=HW/SW Hybrid Project Foundation 2.19 + 2.20 +[FPGA Environment] 2.21 +File=config/pm/hasim/submodels/fpgaenv/fpgaenv-hybrid-exe.apm 2.22 +Packagehint=platforms 2.23 + 2.24 +[Audio Processor Types] 2.25 +File=modules/bluespec/mit-6.375/common/audio_processor_types.awb 2.26 +Packagehint=mit-6.375 2.27 + 2.28 +[Default Audio Pipeline] 2.29 +File=modules/bluespec/mit-6.375/common/audio_pipeline_default.awb 2.30 +Packagehint=mit-6.375 2.31 + 2.32 + 2.33 + 2.34 +[Soft Connections Hybrid Application Environment/Requires] 2.35 +platform_services=Platform Services 2.36 +soft_connections_lib=Soft Connections Library 2.37 +connected_application=Audio Processor Application 2.38 + 2.39 +[Hybrid Project Common Utilities] 2.40 +File=config/pm/hasim/submodels/common/project-common-default.apm 2.41 +Packagehint=hasim 2.42 + 2.43 +[Soft Connections Library] 2.44 +File=config/pm/hasim/submodels/common/soft-connections-lib.apm 2.45 +Packagehint=hasim 2.46 + 2.47 +[Platform Services] 2.48 +File=config/pm/hasim/submodels/platform-services/standard-platform-services.apm 2.49 +Packagehint=hasim 2.50 + 2.51 +[HW/SW Hybrid Project Foundation] 2.52 +File=modules/project/project-hybrid.awb 2.53 +Packagehint=platforms 2.54 + 2.55 +[Soft Connections Hybrid Application Environment] 2.56 +File=modules/application-env/hybrid/soft-connections/application-env-hybrid-soft-conn.awb 2.57 +Packagehint=platforms 2.58 + 2.59 +[HW/SW Hybrid Project Foundation/Requires] 2.60 +project_common=Hybrid Project Common Utilities 2.61 +fpgaenv=FPGA Environment 2.62 +application_env=Soft Connections Hybrid Application Environment 2.63 + 2.64 + 2.65 +[Audio Processor Application/Requires] 2.66 +audio_processor_types=Audio Processor Types 2.67 +audio_pipeline=Default Audio Pipeline 2.68 + 2.69 +[HW/SW Hybrid Project Foundation/Params] 2.70 +WAIT_FOR_HARDWARE=0 2.71 + 2.72 +[Audio Processor Application] 2.73 +File=modules/bluespec/mit-6.375/common/audio_processor_hardware_system.awb 2.74 +Packagehint=mit-6.375
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/documents/blah.pl Fri Apr 23 02:32:05 2010 -0400 3.3 @@ -0,0 +1,3 @@ 3.4 +#!/usr/bin/perl 3.5 + 3.6 +print "oh Yeah";
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/modules/bluespec/Pygar/common/AudioPipelineDefault.bsv Fri Apr 23 02:32:05 2010 -0400 4.3 @@ -0,0 +1,38 @@ 4.4 +// The MIT License 4.5 + 4.6 +// Copyright (c) 2009 Massachusetts Institute of Technology 4.7 + 4.8 +// Permission is hereby granted, free of charge, to any person obtaining a copy 4.9 +// of this software and associated documentation files (the "Software"), to deal 4.10 +// in the Software without restriction, including without limitation the rights 4.11 +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 4.12 +// copies of the Software, and to permit persons to whom the Software is 4.13 +// furnished to do so, subject to the following conditions: 4.14 + 4.15 +// The above copyright notice and this permission notice shall be included in 4.16 +// all copies or substantial portions of the Software. 4.17 + 4.18 +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 4.19 +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 4.20 +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 4.21 +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 4.22 +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 4.23 +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 4.24 +// THE SOFTWARE. 4.25 + 4.26 +// Author: Kermin Fleming kfleming@mit.edu 4.27 + 4.28 +import Connectable::*; 4.29 +import GetPut::*; 4.30 +import ClientServer::*; 4.31 +import FIFO::*; 4.32 + 4.33 +`include "asim/provides/audio_processor_types.bsh" 4.34 + 4.35 +module mkAudioPipeline (AudioPipeline); 4.36 + FIFO#(AudioProcessorUnit) fifo <- mkFIFO; 4.37 + 4.38 + interface sampleInput = fifoToPut(fifo); 4.39 + interface sampleOutput = fifoToGet(fifo); 4.40 + 4.41 +endmodule
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/modules/bluespec/Pygar/common/AudioProcessor.bsv Fri Apr 23 02:32:05 2010 -0400 5.3 @@ -0,0 +1,77 @@ 5.4 +// The MIT License 5.5 + 5.6 +// Copyright (c) 2009 Massachusetts Institute of Technology 5.7 + 5.8 +// Permission is hereby granted, free of charge, to any person obtaining a copy 5.9 +// of this software and associated documentation files (the "Software"), to deal 5.10 +// in the Software without restriction, including without limitation the rights 5.11 +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 5.12 +// copies of the Software, and to permit persons to whom the Software is 5.13 +// furnished to do so, subject to the following conditions: 5.14 + 5.15 +// The above copyright notice and this permission notice shall be included in 5.16 +// all copies or substantial portions of the Software. 5.17 + 5.18 +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 5.19 +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 5.20 +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 5.21 +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 5.22 +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 5.23 +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 5.24 +// THE SOFTWARE. 5.25 + 5.26 +import Connectable::*; 5.27 +import GetPut::*; 5.28 +import ClientServer::*; 5.29 + 5.30 +//AWB includes 5.31 +`include "asim/provides/low_level_platform_interface.bsh" 5.32 +`include "asim/provides/soft_connections.bsh" 5.33 +`include "asim/provides/common_services.bsh" 5.34 + 5.35 +// Local includes 5.36 +`include "asim/provides/audio_processor_types.bsh" 5.37 +`include "asim/provides/audio_pipeline.bsh" 5.38 + 5.39 +`include "asim/rrr/remote_client_stub_AUDIOPROCESSORRRR.bsh" 5.40 +`include "asim/rrr/remote_server_stub_AUDIOPROCESSORRRR.bsh" 5.41 + 5.42 + 5.43 +module [CONNECTED_MODULE] mkConnectedApplication (); 5.44 + 5.45 + // Instantiate the rrr stubs 5.46 + ClientStub_AUDIOPROCESSORRRR client_stub <- mkClientStub_AUDIOPROCESSORRRR(); 5.47 + ServerStub_AUDIOPROCESSORRRR server_stub <- mkServerStub_AUDIOPROCESSORRRR(); 5.48 + 5.49 + // Instantiate the audio pipeline 5.50 + AudioPipeline pipeline <- mkAudioPipeline(); 5.51 + 5.52 + rule feedInput; 5.53 + let command <- server_stub.acceptRequest_SendUnprocessedStream(); 5.54 + AudioProcessorControl ctrl = unpack(truncate(command.ctrl)); 5.55 + 5.56 + if(ctrl == EndOfFile) 5.57 + begin 5.58 + pipeline.sampleInput.put(tagged EndOfFile); 5.59 + end 5.60 + else 5.61 + begin 5.62 + pipeline.sampleInput.put(tagged Sample unpack(truncate(command.sample))); 5.63 + end 5.64 + endrule 5.65 + 5.66 + rule feedOutput; 5.67 + let pipelineData <- pipeline.sampleOutput.get(); 5.68 + AudioProcessorControl endOfFileTag = EndOfFile; 5.69 + AudioProcessorControl sampleTag = Data; 5.70 + 5.71 + case (pipelineData) matches 5.72 + tagged EndOfFile: client_stub.makeRequest_SendProcessedStream(zeroExtend(pack(endOfFileTag)),?); 5.73 + tagged Sample .sample:client_stub.makeRequest_SendProcessedStream(zeroExtend(pack(sampleTag)), 5.74 + zeroExtend(pack(sample))); 5.75 + endcase 5.76 + endrule 5.77 + 5.78 +endmodule 5.79 + 5.80 +
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/modules/bluespec/Pygar/common/AudioProcessor.cpp Fri Apr 23 02:32:05 2010 -0400 6.3 @@ -0,0 +1,104 @@ 6.4 +#include <stdio.h> 6.5 +#include <pthread.h> 6.6 +#include <semaphore.h> 6.7 + 6.8 +#include "asim/provides/connected_application.h" 6.9 +//#include "asim/provides/SndfileWavUtil.h" 6.10 + 6.11 +#include "asim/rrr/client_stub_AUDIOPROCESSORRRR.h" 6.12 + 6.13 +using namespace std; 6.14 + 6.15 +pthread_mutex_t CONNECTED_APPLICATION_CLASS::lock; 6.16 +pthread_cond_t CONNECTED_APPLICATION_CLASS::cond; 6.17 +sem_t CONNECTED_APPLICATION_CLASS::throttle; 6.18 + 6.19 +// constructor 6.20 +CONNECTED_APPLICATION_CLASS::CONNECTED_APPLICATION_CLASS(VIRTUAL_PLATFORM vp) : 6.21 + clientStub(new AUDIOPROCESSORRRR_CLIENT_STUB_CLASS(this)) 6.22 +{ 6.23 +} 6.24 + 6.25 +// destructor 6.26 +CONNECTED_APPLICATION_CLASS::~CONNECTED_APPLICATION_CLASS() 6.27 +{ 6.28 +} 6.29 + 6.30 +// init 6.31 +void 6.32 +CONNECTED_APPLICATION_CLASS::Init() 6.33 +{ 6.34 + 6.35 + pthread_mutex_init(&lock, NULL); 6.36 + pthread_cond_init(&cond, NULL); 6.37 + sem_init(&throttle, 0, 64); 6.38 + 6.39 +} 6.40 + 6.41 +void 6.42 +CONNECTED_APPLICATION_CLASS::UpdateSemaphore() 6.43 +{ 6.44 + sem_post(&throttle); 6.45 +} 6.46 + 6.47 +void 6.48 +CONNECTED_APPLICATION_CLASS::EndSimulation() 6.49 +{ 6.50 + printf("EndSimulation Called\n"); 6.51 + fflush(stdout); 6.52 + pthread_mutex_lock(&lock); 6.53 + // Do something about the race occuring here 6.54 + pthread_cond_signal(&cond); 6.55 + pthread_mutex_unlock(&lock); 6.56 + printf("EndSimulation done\n"); 6.57 + fflush(stdout); 6.58 +} 6.59 + 6.60 +// main 6.61 +void 6.62 +CONNECTED_APPLICATION_CLASS::Main() 6.63 +{ 6.64 + FILE *inputFile; 6.65 + UINT16 sample; 6.66 + 6.67 + // Convert input wav to pcm 6.68 + generate_pcm("input.wav","input.pcm"); 6.69 + 6.70 + //Send data to the machine here. 6.71 + inputFile = fopen("input.pcm","r"); 6.72 + assert(inputFile); 6.73 + 6.74 + 6.75 + int count = 0; 6.76 + 6.77 + printf("main: about to enter loop %d\n", count); 6.78 + 6.79 + while(fread(&sample, 2, 1, inputFile)) { 6.80 + if(count%1000 == 0) 6.81 + printf("main: %d\n", count); 6.82 + count++; 6.83 + sem_wait(&throttle); 6.84 + clientStub->SendUnprocessedStream(Data,(UINT32)sample); 6.85 + } 6.86 + 6.87 + printf("main: out of loop\n"); 6.88 + 6.89 + // Need to put lock here to prevent potential race condition 6.90 + pthread_mutex_lock(&lock); 6.91 + clientStub->SendUnprocessedStream(EndOfFile,0); 6.92 + 6.93 + printf("main: wait for end of file\n"); 6.94 + 6.95 + pthread_cond_wait(&cond, &lock); 6.96 + pthread_mutex_unlock(&lock); 6.97 + 6.98 + printf("main: lastt data out\n"); 6.99 + 6.100 + // Convert input wav to pcm 6.101 + generate_wav("out_hw.pcm","input.wav","out_hw.wav"); 6.102 + 6.103 + printf("generate wav done\n"); 6.104 + 6.105 + fflush(stdout); 6.106 + exit(0); 6.107 +}
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 7.2 +++ b/modules/bluespec/Pygar/common/AudioProcessor.h Fri Apr 23 02:32:05 2010 -0400 7.3 @@ -0,0 +1,56 @@ 7.4 +// 7.5 +// INTEL CONFIDENTIAL 7.6 +// Copyright (c) 2008 Intel Corp. Recipient is granted a non-sublicensable 7.7 +// copyright license under Intel copyrights to copy and distribute this code 7.8 +// internally only. This code is provided "AS IS" with no support and with no 7.9 +// warranties of any kind, including warranties of MERCHANTABILITY, 7.10 +// FITNESS FOR ANY PARTICULAR PURPOSE or INTELLECTUAL PROPERTY INFRINGEMENT. 7.11 +// By making any use of this code, Recipient agrees that no other licenses 7.12 +// to any Intel patents, trade secrets, copyrights or other intellectual 7.13 +// property rights are granted herein, and no other licenses shall arise by 7.14 +// estoppel, implication or by operation of law. Recipient accepts all risks 7.15 +// of use. 7.16 +// 7.17 + 7.18 +// possibly use include paths to hide existing modules? 7.19 + 7.20 +#ifndef __AUDIO_PROCESSOR_CONNECTED_APPLICATION__ 7.21 +#define __AUDIO_PROCESSOR_CONNECTED_APPLICATION__ 7.22 + 7.23 +#include <stdio.h> 7.24 +#include <pthread.h> 7.25 +#include <semaphore.h> 7.26 + 7.27 +#include "asim/provides/virtual_platform.h" 7.28 + 7.29 +#include "asim/rrr/client_stub_AUDIOPROCESSORRRR.h" 7.30 + 7.31 +typedef enum { 7.32 + EndOfFile = 0, 7.33 + Data = 1 7.34 +} AudioProcessorControl; 7.35 + 7.36 + 7.37 +typedef class CONNECTED_APPLICATION_CLASS* CONNECTED_APPLICATION; 7.38 +class CONNECTED_APPLICATION_CLASS : public PLATFORMS_MODULE_CLASS 7.39 +{ 7.40 + private: 7.41 + AUDIOPROCESSORRRR_CLIENT_STUB clientStub; 7.42 + static sem_t throttle; 7.43 + static pthread_mutex_t lock; 7.44 + static pthread_cond_t cond; 7.45 + 7.46 + public: 7.47 + CONNECTED_APPLICATION_CLASS(VIRTUAL_PLATFORM vp); 7.48 + ~CONNECTED_APPLICATION_CLASS(); 7.49 + static void EndSimulation(); 7.50 + static void UpdateSemaphore(); 7.51 + 7.52 + // init 7.53 + void Init(); 7.54 + 7.55 + // main 7.56 + void Main(); 7.57 +}; 7.58 + 7.59 +#endif
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 8.2 +++ b/modules/bluespec/Pygar/common/AudioProcessorRRR.cpp Fri Apr 23 02:32:05 2010 -0400 8.3 @@ -0,0 +1,93 @@ 8.4 +#include <cstdio> 8.5 +#include <cstdlib> 8.6 +#include <iostream> 8.7 +#include <iomanip> 8.8 +#include <stdio.h> 8.9 +#include <sys/stat.h> 8.10 + 8.11 +#include "asim/rrr/service_ids.h" 8.12 + 8.13 +#include "asim/provides/connected_application.h" 8.14 + 8.15 + 8.16 + 8.17 +using namespace std; 8.18 + 8.19 +// ===== service instantiation ===== 8.20 +AUDIOPROCESSORRRR_SERVER_CLASS AUDIOPROCESSORRRR_SERVER_CLASS::instance; 8.21 + 8.22 +// constructor 8.23 +AUDIOPROCESSORRRR_SERVER_CLASS::AUDIOPROCESSORRRR_SERVER_CLASS() : 8.24 + serverStub(new AUDIOPROCESSORRRR_SERVER_STUB_CLASS(this)) 8.25 +{ 8.26 + // instantiate stub 8.27 + printf("AUDIOPROCESSORRR init called\n"); 8.28 + outputFile = NULL; 8.29 +} 8.30 + 8.31 +// destructor 8.32 +AUDIOPROCESSORRRR_SERVER_CLASS::~AUDIOPROCESSORRRR_SERVER_CLASS() 8.33 +{ 8.34 + Cleanup(); 8.35 +} 8.36 + 8.37 +// init 8.38 +void 8.39 +AUDIOPROCESSORRRR_SERVER_CLASS::Init(PLATFORMS_MODULE p) 8.40 +{ 8.41 + parent = p; 8.42 +} 8.43 + 8.44 +// uninit 8.45 +void 8.46 +AUDIOPROCESSORRRR_SERVER_CLASS::Uninit() 8.47 +{ 8.48 + Cleanup(); 8.49 +} 8.50 + 8.51 +// cleanup 8.52 +void 8.53 +AUDIOPROCESSORRRR_SERVER_CLASS::Cleanup() 8.54 +{ 8.55 + delete serverStub; 8.56 +} 8.57 + 8.58 + 8.59 +// 8.60 +// RRR service methods 8.61 +// 8.62 + 8.63 +void 8.64 +AUDIOPROCESSORRRR_SERVER_CLASS::SendProcessedStream(UINT16 control, UINT16 data) 8.65 +{ 8.66 + 8.67 + AudioProcessorControl audioProcessorControl = (AudioProcessorControl) control; 8.68 + switch(control) { 8.69 + case EndOfFile: 8.70 + if(outputFile != NULL) { 8.71 + fflush(outputFile); 8.72 + fclose(outputFile); 8.73 + outputFile = NULL; 8.74 + } else { 8.75 + outputFile = fopen("out_hw.pcm","w"); 8.76 + assert(outputFile); 8.77 + fflush(outputFile); 8.78 + fclose(outputFile); 8.79 + } 8.80 + 8.81 + CONNECTED_APPLICATION_CLASS::EndSimulation(); 8.82 + break; 8.83 + 8.84 + case Data: 8.85 + if(outputFile == NULL) { 8.86 + outputFile = fopen("out_hw.pcm","w"); 8.87 + assert(outputFile); 8.88 + } 8.89 + 8.90 + CONNECTED_APPLICATION_CLASS::UpdateSemaphore(); 8.91 + fwrite(&data, 2,1 , outputFile); 8.92 + break; 8.93 + } 8.94 + 8.95 +} 8.96 +
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 9.2 +++ b/modules/bluespec/Pygar/common/AudioProcessorRRR.h Fri Apr 23 02:32:05 2010 -0400 9.3 @@ -0,0 +1,50 @@ 9.4 + 9.5 +#ifndef _AUDIOPROCESSORRRR_ 9.6 +#define _AUDIOPROCESSORRRR_ 9.7 + 9.8 +#include <stdio.h> 9.9 +#include <sys/time.h> 9.10 + 9.11 +#include "asim/provides/low_level_platform_interface.h" 9.12 + 9.13 +#include "asim/provides/rrr.h" 9.14 + 9.15 + 9.16 + 9.17 +typedef class AUDIOPROCESSORRRR_SERVER_CLASS* AUDIOPROCESSORRRR_SERVER; 9.18 +class AUDIOPROCESSORRRR_SERVER_CLASS: public RRR_SERVER_CLASS, public PLATFORMS_MODULE_CLASS 9.19 +{ 9.20 + private: 9.21 + // self-instantiation 9.22 + static AUDIOPROCESSORRRR_SERVER_CLASS instance; 9.23 + FILE *outputFile; 9.24 + 9.25 + // server stub 9.26 + RRR_SERVER_STUB serverStub; 9.27 + 9.28 + int count; 9.29 + 9.30 + public: 9.31 + AUDIOPROCESSORRRR_SERVER_CLASS(); 9.32 + ~AUDIOPROCESSORRRR_SERVER_CLASS(); 9.33 + 9.34 + // static methods 9.35 + static AUDIOPROCESSORRRR_SERVER GetInstance() { return &instance; } 9.36 + 9.37 + // required RRR methods 9.38 + void Init(PLATFORMS_MODULE); 9.39 + void Uninit(); 9.40 + void Cleanup(); 9.41 + 9.42 + // 9.43 + // RRR service methods 9.44 + // 9.45 + void SendProcessedStream(UINT16 control, UINT16 data0); 9.46 +}; 9.47 + 9.48 + 9.49 + 9.50 +// include server stub 9.51 +#include "asim/rrr/server_stub_AUDIOPROCESSORRRR.h" 9.52 + 9.53 +#endif
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 10.2 +++ b/modules/bluespec/Pygar/common/AudioProcessorRRR.rrr Fri Apr 23 02:32:05 2010 -0400 10.3 @@ -0,0 +1,14 @@ 10.4 +service AUDIOPROCESSORRRR 10.5 +{ 10.6 + server sw (cpp, method) <- hw (bsv, connection) 10.7 + { 10.8 + method SendProcessedStream (in UINT32[32] ctrl, in UINT32[32] sample); 10.9 + }; 10.10 + 10.11 + server hw (bsv, connection) <- sw (cpp, method) 10.12 + { 10.13 + method SendUnprocessedStream (in UINT32[32] ctrl, in UINT32[32] sample); 10.14 + }; 10.15 + 10.16 + 10.17 + };
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 11.2 +++ b/modules/bluespec/Pygar/common/AudioProcessorTypes.bsv Fri Apr 23 02:32:05 2010 -0400 11.3 @@ -0,0 +1,51 @@ 11.4 +// The MIT License 11.5 + 11.6 +// Copyright (c) 2009 Massachusetts Institute of Technology 11.7 + 11.8 +// Permission is hereby granted, free of charge, to any person obtaining a copy 11.9 +// of this software and associated documentation files (the "Software"), to deal 11.10 +// in the Software without restriction, including without limitation the rights 11.11 +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11.12 +// copies of the Software, and to permit persons to whom the Software is 11.13 +// furnished to do so, subject to the following conditions: 11.14 + 11.15 +// The above copyright notice and this permission notice shall be included in 11.16 +// all copies or substantial portions of the Software. 11.17 + 11.18 +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 11.19 +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 11.20 +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 11.21 +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 11.22 +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 11.23 +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 11.24 +// THE SOFTWARE. 11.25 + 11.26 +// Author: Kermin Fleming kfleming@mit.edu 11.27 + 11.28 +import Connectable::*; 11.29 +import GetPut::*; 11.30 +import ClientServer::*; 11.31 + 11.32 +typedef Int#(16) Sample; 11.33 + 11.34 +typedef enum { 11.35 + EndOfFile = 0, 11.36 + Data = 1 11.37 +} AudioProcessorControl deriving (Bits,Eq); 11.38 + 11.39 + 11.40 +typedef struct { 11.41 + Sample left; 11.42 + Sample right; 11.43 +} StereoSample deriving (Bits,Eq); 11.44 + 11.45 +typedef union tagged{ 11.46 + Sample Sample; 11.47 + void EndOfFile; 11.48 +} AudioProcessorUnit deriving (Bits,Eq); 11.49 + 11.50 +interface AudioPipeline; 11.51 + interface Put#(AudioProcessorUnit) sampleInput; 11.52 + interface Get#(AudioProcessorUnit) sampleOutput; 11.53 +endinterface 11.54 +
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 12.2 +++ b/modules/bluespec/Pygar/common/DFT.cpp Fri Apr 23 02:32:05 2010 -0400 12.3 @@ -0,0 +1,46 @@ 12.4 +#include <stdio.h> 12.5 +#include <stdlib.h> 12.6 +#include <math.h> 12.7 + 12.8 + 12.9 +int DFT(int dir,int m,double *x1,double *y1) 12.10 +{ 12.11 + long i,k; 12.12 + double arg; 12.13 + double cosarg,sinarg; 12.14 + double *x2=NULL,*y2=NULL; 12.15 + 12.16 + x2 = (double *)(malloc(m*sizeof(double))); 12.17 + y2 = (double *)(malloc(m*sizeof(double))); 12.18 + if (x2 == NULL || y2 == NULL) 12.19 + return 0; 12.20 + 12.21 + for (i=0;i<m;i++) { 12.22 + x2[i] = 0; 12.23 + y2[i] = 0; 12.24 + arg = - dir * 2.0 * 3.141592654 * (double)i / (double)m; 12.25 + for (k=0;k<m;k++) { 12.26 + cosarg = cos(k * arg); 12.27 + sinarg = sin(k * arg); 12.28 + x2[i] += (x1[k] * cosarg - y1[k] * sinarg); 12.29 + y2[i] += (x1[k] * sinarg + y1[k] * cosarg); 12.30 + } 12.31 + } 12.32 + 12.33 + /* Copy the data back */ 12.34 + if (dir == 1) { 12.35 + for (i=0;i<m;i++) { 12.36 + x1[i] = x2[i]; 12.37 + y1[i] = y2[i]; 12.38 + } 12.39 + } else { 12.40 + for (i=0;i<m;i++) { 12.41 + x1[i] = x2[i]; 12.42 + y1[i] = y2[i]; 12.43 + } 12.44 + } 12.45 + 12.46 + free(x2); 12.47 + free(y2); 12.48 + return 1; 12.49 +}
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 13.2 +++ b/modules/bluespec/Pygar/common/SndfileWavUtil.cpp Fri Apr 23 02:32:05 2010 -0400 13.3 @@ -0,0 +1,125 @@ 13.4 +#include <stdlib.h> 13.5 +#include <string.h> 13.6 +#include <errno.h> 13.7 +#include <math.h> 13.8 +#include <sndfile.h> 13.9 +#include "SndfileWavUtil.h" 13.10 + 13.11 +void 13.12 +generate_wav(const char * pcmfilename, const char * samplewavfilename, const char * outputwavfilename) 13.13 +{ 13.14 + char outfilename[2048]; 13.15 + SNDFILE * outfile ; 13.16 + SNDFILE * wavfile ; 13.17 + SNDFILE * pcmfile ; 13.18 + SF_INFO wavinfo ; 13.19 + SF_INFO pcminfo ; 13.20 + int buff; 13.21 + SF_INSTRUMENT inst ; 13.22 + 13.23 + memset (&wavinfo, 0, sizeof (wavinfo)) ; 13.24 + 13.25 + 13.26 + wavfile = sf_open(samplewavfilename, SFM_READ, &wavinfo); 13.27 + 13.28 + if (wavfile == NULL){ 13.29 + printf ("\nERROR : Not able to open wav file named '%s' : %s/\n", samplewavfilename, sf_strerror (NULL)) ; 13.30 + exit (1) ; 13.31 + } ; 13.32 + 13.33 + printf("WAV format: %x\n", wavinfo.format); 13.34 + 13.35 + if (!((wavinfo.format & SF_FORMAT_PCM_16) && (wavinfo.channels == 1) && 13.36 + (wavinfo.format & SF_FORMAT_WAV))){ 13.37 + printf("\nERROR : .wav file must be SF_FORMAT_PCM_16 in mono\n"); 13.38 + } 13.39 + 13.40 + pcminfo.format = SF_FORMAT_RAW | SF_FORMAT_PCM_16; 13.41 + pcminfo.samplerate = wavinfo.samplerate; 13.42 + pcminfo.channels = wavinfo.channels; 13.43 + 13.44 + pcmfile = sf_open(pcmfilename, SFM_READ, &pcminfo); 13.45 + 13.46 + if (pcmfile == NULL){ 13.47 + printf ("\nERROR : Not able to open pcm file named '%s' : %s/\n", pcmfilename, sf_strerror (NULL)) ; 13.48 + exit (1) ; 13.49 + } ; 13.50 + 13.51 + 13.52 + 13.53 + outfile = sf_open(outputwavfilename, SFM_WRITE, &wavinfo); 13.54 + 13.55 + memset (&inst, 0, sizeof (inst)) ; 13.56 + 13.57 + for(int i = SF_STR_FIRST; i <= SF_STR_LAST; i = i + 1) { 13.58 + const char * str = sf_get_string(wavfile,i); 13.59 + if(str != NULL) { 13.60 + sf_set_string(outfile,i,str); 13.61 + } 13.62 + } 13.63 + 13.64 + if (outfile == NULL){ 13.65 + printf ("\nERROR : Not able to create wav file named '%s' : %s/\n", outfilename, sf_strerror (NULL)) ; 13.66 + exit (1) ; 13.67 + } ; 13.68 + 13.69 + while(sf_read_int(pcmfile, &buff, 1) == 1){ 13.70 + if(sf_write_int(outfile, &buff, 1) != 1){ 13.71 + printf("\nERROR : unable to write to '%s' : %s/\n", outfilename, sf_strerror(NULL)); 13.72 + } 13.73 + } 13.74 + 13.75 + sf_close (wavfile) ; 13.76 + sf_close (outfile) ; 13.77 + sf_close (pcmfile) ; 13.78 + 13.79 +} 13.80 + 13.81 + 13.82 +void 13.83 +generate_pcm (const char * wavfilename, const char * pcmfilename) 13.84 +{ 13.85 + SNDFILE * wavfile ; 13.86 + SNDFILE * pcmfile ; 13.87 + SF_INFO wavinfo ; 13.88 + SF_INFO pcminfo ; 13.89 + int buff; 13.90 + 13.91 + memset (&wavinfo, 0, sizeof (wavinfo)) ; 13.92 + memset (&pcminfo, 0, sizeof (pcminfo)) ; 13.93 + 13.94 + wavfile = sf_open (wavfilename, SFM_READ, &wavinfo) ; 13.95 + 13.96 + if (wavfile == NULL){ 13.97 + printf ("\nERROR : Not able to open wav file named '%s' : %s/\n", wavfilename, sf_strerror (NULL)) ; 13.98 + exit (1) ; 13.99 + } ; 13.100 + 13.101 + pcminfo.format = SF_FORMAT_RAW | SF_FORMAT_PCM_16; 13.102 + pcminfo.samplerate = wavinfo.samplerate; 13.103 + pcminfo.channels = wavinfo.channels; 13.104 + 13.105 + if ((!wavinfo.format & SF_FORMAT_PCM_16) || (!wavinfo.channels == 1)){ 13.106 + printf("\nERROR : .wav file must be SF_FORMAT_PCM_16 and mono\n"); 13.107 + } 13.108 + 13.109 + pcmfile = sf_open (pcmfilename, SFM_WRITE, &pcminfo) ; 13.110 + 13.111 + if (pcmfile == NULL){ 13.112 + printf ("\nERROR : Not able to create pcm file named '%s' : %s/\n", pcmfilename, sf_strerror (NULL)) ; 13.113 + exit (1) ; 13.114 + } ; 13.115 + 13.116 + while(sf_read_int(wavfile, &buff, 1) == 1){ 13.117 + if(sf_write_int(pcmfile, &buff, 1) != 1){ 13.118 + printf("\nERROR : unable to write to '%s' : %s/\n", pcmfilename, sf_strerror(NULL)); 13.119 + } 13.120 + } 13.121 + 13.122 + sf_close (wavfile) ; 13.123 + sf_close (pcmfile) ; 13.124 +} 13.125 + 13.126 + 13.127 + 13.128 +
14.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 14.2 +++ b/modules/bluespec/Pygar/common/SndfileWavUtil.h Fri Apr 23 02:32:05 2010 -0400 14.3 @@ -0,0 +1,9 @@ 14.4 +#ifndef _SNDFILE_WAV_UTIL_ 14.5 +#define _SNDFILE_WAV_UTIL_ 14.6 + 14.7 +int guess_direction (const char * filename1, const char * filename2) ; 14.8 +int guess_major_format (const char * filename) ; 14.9 +void generate_pcm(const char * wavfilename, const char * pcmfilename); 14.10 +void generate_wav(const char * pcmfilename, const char * samplewavfilename, const char * outputwavfilename); 14.11 + 14.12 +#endif
15.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 15.2 +++ b/modules/bluespec/Pygar/common/audio_pipeline_default.awb Fri Apr 23 02:32:05 2010 -0400 15.3 @@ -0,0 +1,10 @@ 15.4 +%name Default Audio Pipeline 15.5 +%desc A basic copy-though audio pipeline 15.6 + 15.7 +%provides audio_pipeline 15.8 + 15.9 +%attributes 6_375 15.10 + 15.11 +%public AudioPipelineDefault.bsv 15.12 + 15.13 +
16.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 16.2 +++ b/modules/bluespec/Pygar/common/audio_processor_hardware_system.awb Fri Apr 23 02:32:05 2010 -0400 16.3 @@ -0,0 +1,19 @@ 16.4 +%name Audio Processor Application 16.5 +%desc Top level audio processor. This module wraps an Audio Pipeline, providing communications between host and audio processor 16.6 + 16.7 +%provides connected_application 16.8 + 16.9 +%requires audio_processor_types 16.10 +%requires audio_pipeline 16.11 + 16.12 +%attributes 6_375 16.13 + 16.14 +%sources -t H -v PUBLIC AudioProcessor.h 16.15 +%sources -t H -v PUBLIC AudioProcessorRRR.h 16.16 +%sources -t H -v PUBLIC SndfileWavUtil.h 16.17 +%sources -t BSV -v PUBLIC AudioProcessor.bsv 16.18 +%sources -t CPP -v PRIVATE AudioProcessor.cpp 16.19 +%sources -t CPP -v PRIVATE AudioProcessorRRR.cpp 16.20 +%sources -t CPP -v PRIVATE SndfileWavUtil.cpp 16.21 +%sources -t RRR -v PUBLIC AudioProcessorRRR.rrr 16.22 +%library /usr/lib/libsndfile.so
17.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 17.2 +++ b/modules/bluespec/Pygar/common/audio_processor_software_system.awb Fri Apr 23 02:32:05 2010 -0400 17.3 @@ -0,0 +1,16 @@ 17.4 +******************************************************************** 17.5 +* Awb module specification 17.6 +******************************************************************** 17.7 + 17.8 +%AWB_START 17.9 + 17.10 +%name Audio Processor Software 17.11 +%desc Audio Processor Software 17.12 +%provides software_system 17.13 + 17.14 +%attributes 6_375 17.15 + 17.16 +%public AudioProcessor.cpp 17.17 +%public AudioProcessor.h 17.18 + 17.19 +%AWB_END
18.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 18.2 +++ b/modules/bluespec/Pygar/common/audio_processor_types.awb Fri Apr 23 02:32:05 2010 -0400 18.3 @@ -0,0 +1,9 @@ 18.4 +%name Audio Processor Types 18.5 +%desc Audio Processing Pipeline Types 18.6 + 18.7 +%provides audio_processor_types 18.8 + 18.9 +%attributes 6_375 18.10 + 18.11 +%public AudioProcessorTypes.bsv 18.12 +
19.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 19.2 +++ b/modules/bluespec/Pygar/core/BFIFO.bsv Fri Apr 23 02:32:05 2010 -0400 19.3 @@ -0,0 +1,222 @@ 19.4 +import FIFO::*; 19.5 +import FIFOF::*; 19.6 +import List::*; 19.7 +import Assert::*; 19.8 + 19.9 +module mkBFIFO1( FIFO#(item_t) ) provisos ( Bits#(item_t,item_sz) ); 19.10 + 19.11 + RWire#(item_t) inputWire <- mkRWire(); 19.12 + PulseWire deqEnabled <- mkPulseWire(); 19.13 + PulseWire clearEnabled <- mkPulseWire(); 19.14 + 19.15 + Reg#(item_t) register <- mkRegU(); 19.16 + Reg#(Bool) valid <- mkReg(False); 19.17 + 19.18 + // If there is an input item on the inputWire wire and dequeue did not 19.19 + // execute this cycle then we need to store the item in the register 19.20 + 19.21 + (*fire_when_enabled*) 19.22 + rule update ( True ); 19.23 + case (inputWire.wget()) matches 19.24 + tagged Invalid: 19.25 + if (deqEnabled || clearEnabled) 19.26 + valid <= False; 19.27 + tagged Valid .x: 19.28 + begin 19.29 + register <= x; 19.30 + valid <= !(deqEnabled || clearEnabled); 19.31 + end 19.32 + endcase 19.33 + endrule 19.34 + 19.35 + // On enqueue we write the input item to the inputWire wire 19.36 + 19.37 + method Action enq( item_t item ) if ( !valid ); 19.38 + inputWire.wset(item); 19.39 + endmethod 19.40 + 19.41 + // On dequeue we always invalidate the storage register regardless 19.42 + // of whether or not the item was actually bypassed or not. We also 19.43 + // set a combinational signal so that we know not to move the item 19.44 + // into the register this cycle. 19.45 + 19.46 + method Action deq() if ( valid || isValid(inputWire.wget()) ); 19.47 + deqEnabled.send(); 19.48 + endmethod 19.49 + 19.50 + // We get the item either from the register (if register is valid) or 19.51 + // from the combinational bypasss (if the rwire is valid). 19.52 + 19.53 + method item_t first() if ( valid || isValid(inputWire.wget()) ); 19.54 + if ( valid ) 19.55 + return register; 19.56 + else 19.57 + return unJust(inputWire.wget()); 19.58 + endmethod 19.59 + 19.60 + method Action clear(); 19.61 + clearEnabled.send(); 19.62 + endmethod 19.63 + 19.64 +endmodule 19.65 + 19.66 +module mkSizedBFIFO#(Integer n) ( FIFO#(item_t) ) provisos ( Bits#(item_t,item_sz) ); 19.67 + 19.68 + RWire#(item_t) inputWire <- mkRWire(); 19.69 + PulseWire deqEnabled <- mkPulseWire(); 19.70 + PulseWire clearEnabled <- mkPulseWire(); 19.71 + 19.72 + List#(Reg#(item_t)) registers <- replicateM(n, mkRegU); 19.73 + List#(Reg#(Bool)) valids <- replicateM(n, mkReg(False)); 19.74 + 19.75 + function Nat getNextFree (List#(Reg#(Bool)) vs); 19.76 + 19.77 + Nat res = fromInteger(n - 1); 19.78 + 19.79 + for (Integer x = n - 1; x > -1; x = x - 1) 19.80 + res = !vs[x]._read() ? fromInteger(x) : res; 19.81 + 19.82 + return res; 19.83 + 19.84 + endfunction 19.85 + 19.86 + function Bool notFull(); 19.87 + 19.88 + Bool full = True; 19.89 + 19.90 + for (Integer x = 0; x < length(valids); x = x + 1) 19.91 + full = full && valids[x]._read(); 19.92 + 19.93 + return !full; 19.94 + 19.95 + endfunction 19.96 + // If there is an input item on the inputWire wire and dequeue did not 19.97 + // execute this cycle then we need to store the item in the register 19.98 + 19.99 + rule update ( True ); 19.100 + Nat next = getNextFree(valids); 19.101 + 19.102 + next = (deqEnabled) ? next - 1 : next; 19.103 + 19.104 + (valids[next]) <= isValid(inputWire.wget()); 19.105 + (registers[next]) <= validValue(inputWire.wget()); 19.106 + 19.107 + if (deqEnabled && !clearEnabled) 19.108 + begin 19.109 + 19.110 + for (Nat x = 0; x < (next - 1); x = x + 1) 19.111 + begin 19.112 + (valids[x]) <= valids[x+1]._read(); 19.113 + (registers[x]) <= registers[x+1]._read(); 19.114 + end 19.115 + 19.116 + end 19.117 + else if (clearEnabled) 19.118 + begin 19.119 + 19.120 + for (Integer x = 0; x < n; x = x + 1) 19.121 + (valids[x]) <= False; 19.122 + 19.123 + end 19.124 + endrule 19.125 + 19.126 + // On enqueue we write the input item to the inputWire wire 19.127 + 19.128 + method Action enq( item_t item ) if ( notFull ); 19.129 + inputWire.wset(item); 19.130 + endmethod 19.131 + 19.132 + // On dequeue we always invalidate the storage register regardless 19.133 + // of whether or not the item was actually bypassed or not. We also 19.134 + // set a combinational signal so that we know not to move the item 19.135 + // into the register this cycle. 19.136 + 19.137 + method Action deq() if ( valids[0]._read() || isValid(inputWire.wget()) ); 19.138 + deqEnabled.send(); 19.139 + endmethod 19.140 + 19.141 + // We get the item either from the register (if register is valid) or 19.142 + // from the combinational bypasss (if the rwire is valid). 19.143 + 19.144 + method item_t first() if ( valids[0]._read() || isValid(inputWire.wget()) ); 19.145 + if ( valids[0]._read() ) 19.146 + return registers[0]._read(); 19.147 + else 19.148 + return unJust(inputWire.wget()); 19.149 + endmethod 19.150 + 19.151 + 19.152 + method Action clear(); 19.153 + clearEnabled.send(); 19.154 + endmethod 19.155 + 19.156 +endmodule 19.157 + 19.158 + 19.159 +module mkBFIFOF1( FIFOF#(item_t) ) provisos ( Bits#(item_t,item_sz) ); 19.160 + 19.161 + RWire#(item_t) inputWire <- mkRWire(); 19.162 + RWire#(Bool) deqEnabled <- mkRWire(); 19.163 + 19.164 + Reg#(Maybe#(item_t)) register <- mkReg(Invalid); 19.165 + 19.166 + // If there is an input item on the inputWire wire and dequeue did not 19.167 + // execute this cycle then we need to store the item in the register 19.168 + 19.169 + rule noDeq ( isValid(inputWire.wget()) && !isValid(deqEnabled.wget()) ); 19.170 + register <= inputWire.wget(); 19.171 + endrule 19.172 + 19.173 + // On enqueue we write the input item to the inputWire wire 19.174 + 19.175 + method Action enq( item_t item ) if ( !isValid(register) ); 19.176 + inputWire.wset(item); 19.177 + endmethod 19.178 + 19.179 + // On dequeue we always invalidate the storage register regardless 19.180 + // of whether or not the item was actually bypassed or not. We also 19.181 + // set a combinational signal so that we know not to move the item 19.182 + // into the register this cycle. 19.183 + 19.184 + method Action deq() if ( isValid(register) || isValid(inputWire.wget()) ); 19.185 + register <= Invalid; 19.186 + deqEnabled.wset(True); 19.187 + endmethod 19.188 + 19.189 + // We get the item either from the register (if register is valid) or 19.190 + // from the combinational bypasss (if the rwire is valid). 19.191 + 19.192 + method item_t first() if ( isValid(register) || isValid(inputWire.wget()) ); 19.193 + if ( isValid(register) ) 19.194 + return unJust(register); 19.195 + else 19.196 + return unJust(inputWire.wget()); 19.197 + endmethod 19.198 + 19.199 + // FIFOF adds the following two methods 19.200 + 19.201 + method Bool notFull(); 19.202 + return !isValid(register); 19.203 + endmethod 19.204 + 19.205 + method Bool notEmpty(); 19.206 + return (isValid(register) || isValid(inputWire.wget())); 19.207 + endmethod 19.208 + 19.209 + // Not sure about the clear method ... 19.210 + 19.211 + method Action clear(); 19.212 + dynamicAssert( False, "BFIFO.clear() not implemented yet!" ); 19.213 + endmethod 19.214 + 19.215 +endmodule 19.216 + 19.217 +(* synthesize *) 19.218 +module mkBFIFO_16 (FIFO#(Bit#(16))); 19.219 + 19.220 + let f <- mkBFIFO1(); 19.221 + 19.222 + return f; 19.223 + 19.224 +endmodule 19.225 +
20.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 20.2 +++ b/modules/bluespec/Pygar/core/BRegFile.bsv Fri Apr 23 02:32:05 2010 -0400 20.3 @@ -0,0 +1,36 @@ 20.4 +import RegFile::*; 20.5 +import RWire::*; 20.6 +import ProcTypes::*; 20.7 + 20.8 +//----------------------------------------------------------- 20.9 +// Register file module 20.10 +//----------------------------------------------------------- 20.11 + 20.12 +interface BRegFile #(type index_t, type data_t); 20.13 + method Action upd(index_t addr, data_t data); 20.14 + method data_t sub(index_t addr); 20.15 +endinterface 20.16 + 20.17 +module mkBRegFile(RegFile#(index_t, data_t)) 20.18 + provisos (Bits#(index_t, size_index), 20.19 + Bits#(data_t, size_data), 20.20 + Eq#(index_t), 20.21 + Bounded#(index_t) ); 20.22 + 20.23 + RegFile#(index_t, data_t) rf <- mkRegFileWCF(minBound, maxBound); 20.24 + RWire#(Tuple2#(index_t, data_t)) rw <-mkRWire(); 20.25 + 20.26 + method Action upd (index_t r, data_t d); 20.27 + rf.upd(r,d); 20.28 + rw.wset(tuple2(r,d)); 20.29 + endmethod 20.30 + 20.31 + method data_t sub (index_t r); 20.32 + case (rw.wget()) matches 20.33 + tagged Valid {.wr, .d} : 20.34 + return (wr == r) ? d : rf.sub(r); 20.35 + tagged Invalid : return rf.sub(r); 20.36 + endcase 20.37 + endmethod 20.38 + 20.39 +endmodule
21.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 21.2 +++ b/modules/bluespec/Pygar/core/BranchPred.bsv Fri Apr 23 02:32:05 2010 -0400 21.3 @@ -0,0 +1,41 @@ 21.4 +import RegFile::*; 21.5 +import ProcTypes::*; 21.6 +import FIFO::*; 21.7 + 21.8 +typedef Maybe#(Addr) BrPred; 21.9 +typedef Bit#(4) BPindx; 21.10 + 21.11 +typedef struct {Addr brpc; Addr nextpc;} BrPair deriving (Bits,Eq); 21.12 + 21.13 +typedef union tagged 21.14 +{ 21.15 + BrPair Valid; 21.16 + void Invalid; 21.17 +} CBranchPath deriving(Bits, Eq); // have the cache start out invalid and add valid values. 21.18 + 21.19 +interface BranchPred; 21.20 + method BrPred get(Addr pres); //returns a maybe type that is invalid if no predition 21.21 + method Action upd(Addr pres, Addr next); 21.22 +endinterface 21.23 + 21.24 +module mkBranchPred(BranchPred); 21.25 + 21.26 + //state variables 21.27 + RegFile#(BPindx, CBranchPath) bcache <- mkRegFileFull(); // cache to hold 16 (based on BPindx) 21.28 + 21.29 + method Action upd(Addr pres, Addr next); 21.30 + BrPair brp; 21.31 + brp = BrPair {brpc:pres, nextpc:next}; 21.32 + bcache.upd(pres[5:2], tagged Valid brp); 21.33 + endmethod 21.34 + 21.35 + method BrPred get(Addr prespc); 21.36 + BPindx rd = prespc[5:2]; 21.37 + let cbp = bcache.sub(rd); 21.38 + if (cbp matches tagged Valid .bp &&& bp.brpc == prespc) //make sure that the read value was actually put there and the full address matches 21.39 + return tagged Valid bp.nextpc; 21.40 + else return Invalid; 21.41 + endmethod 21.42 + 21.43 +endmodule 21.44 +
22.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 22.2 +++ b/modules/bluespec/Pygar/core/Core.bsv Fri Apr 23 02:32:05 2010 -0400 22.3 @@ -0,0 +1,81 @@ 22.4 +// The MIT License 22.5 + 22.6 +// Copyright (c) 2009 Massachusetts Institute of Technology 22.7 + 22.8 +// Permission is hereby granted, free of charge, to any person obtaining a copy 22.9 +// of this software and associated documentation files (the "Software"), to deal 22.10 +// in the Software without restriction, including without limitation the rights 22.11 +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 22.12 +// copies of the Software, and to permit persons to whom the Software is 22.13 +// furnished to do so, subject to the following conditions: 22.14 + 22.15 +// The above copyright notice and this permission notice shall be included in 22.16 +// all copies or substantial portions of the Software. 22.17 + 22.18 +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22.19 +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22.20 +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22.21 +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22.22 +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22.23 +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22.24 +// THE SOFTWARE. 22.25 + 22.26 +import Connectable::*; 22.27 +import GetPut::*; 22.28 +import ClientServer::*; 22.29 + 22.30 +import DataCacheBlocking::*; 22.31 +import InstCacheBlocking::*; 22.32 +import Processor::*; 22.33 +import MemArb::*; 22.34 +import MemTypes::*; 22.35 + 22.36 +interface CoreStats; 22.37 + interface DCacheStats dcache; 22.38 + interface ICacheStats icache; 22.39 + interface ProcStats proc; 22.40 +endinterface 22.41 + 22.42 +interface Core; 22.43 + 22.44 + // Interface from core to main memory 22.45 + interface Client#(MainMemReq,MainMemResp) mmem_client; 22.46 + 22.47 + // Statistics 22.48 + interface CoreStats stats; 22.49 + 22.50 + // CPU to Host 22.51 + interface CPUToHost tohost; 22.52 + 22.53 +endinterface 22.54 + 22.55 +(* synthesize *) 22.56 +module mkCore(Core); 22.57 + 22.58 + // Instantiate the modules 22.59 + Proc proc <- mkProc(); 22.60 + ICache#(InstReq,InstResp) icache <- mkInstCache(); 22.61 + DCache#(DataReq,DataResp) dcache <- mkDataCache(); 22.62 + MemArb marb <- mkMemArb(); 22.63 + 22.64 + // Internal connections 22.65 + mkConnection( proc.statsEn_get, icache.statsEn_put ); 22.66 + mkConnection( proc.statsEn_get, dcache.statsEn_put ); 22.67 + mkConnection( proc.imem_client, icache.proc_server ); 22.68 + mkConnection( proc.dmem_client, dcache.proc_server ); 22.69 + mkConnection( icache.mmem_client, marb.cache0_server ); 22.70 + mkConnection( dcache.mmem_client, marb.cache1_server ); 22.71 + 22.72 + // Methods 22.73 + interface mmem_client = marb.mmem_client; 22.74 + 22.75 + interface CoreStats stats; 22.76 + interface dcache = dcache.stats; 22.77 + interface icache = icache.stats; 22.78 + interface proc = proc.stats; 22.79 + endinterface 22.80 + 22.81 + interface CPUToHost tohost = proc.tohost; 22.82 + 22.83 +endmodule 22.84 +
23.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 23.2 +++ b/modules/bluespec/Pygar/core/DataCache.dic Fri Apr 23 02:32:05 2010 -0400 23.3 @@ -0,0 +1,3 @@ 23.4 +def STATS.DATA_CACHE.NUM_ACCESSES "DATA_CACHE: Number Of Accesses: "; 23.5 +def STATS.DATA_CACHE.NUM_MISSES "DATA_CACHE: Number Of Misses: "; 23.6 +def STATS.DATA_CACHE.NUM_WRITEBACKS "DATA_CACHE: Number Of Writebacks: "; 23.7 \ No newline at end of file
24.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 24.2 +++ b/modules/bluespec/Pygar/core/DataCacheBlocking.bsv Fri Apr 23 02:32:05 2010 -0400 24.3 @@ -0,0 +1,295 @@ 24.4 +// The MIT License 24.5 + 24.6 +// Copyright (c) 2009 Massachusetts Institute of Technology 24.7 + 24.8 +// Permission is hereby granted, free of charge, to any person obtaining a copy 24.9 +// of this software and associated documentation files (the "Software"), to deal 24.10 +// in the Software without restriction, including without limitation the rights 24.11 +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 24.12 +// copies of the Software, and to permit persons to whom the Software is 24.13 +// furnished to do so, subject to the following conditions: 24.14 + 24.15 +// The above copyright notice and this permission notice shall be included in 24.16 +// all copies or substantial portions of the Software. 24.17 + 24.18 +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 24.19 +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24.20 +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24.21 +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24.22 +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24.23 +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24.24 +// THE SOFTWARE. 24.25 + 24.26 +import Connectable::*; 24.27 +import GetPut::*; 24.28 +import ClientServer::*; 24.29 +import RegFile::*; 24.30 +import FIFO::*; 24.31 +import FIFOF::*; 24.32 + 24.33 +import BFIFO::*; 24.34 +import MemTypes::*; 24.35 +import ProcTypes::*; 24.36 +import Trace::*; 24.37 + 24.38 +interface DCacheStats; 24.39 + interface Get#(Stat) num_accesses; 24.40 + interface Get#(Stat) num_misses; 24.41 + interface Get#(Stat) num_writebacks; 24.42 +endinterface 24.43 + 24.44 +interface DCache#( type req_t, type resp_t ); 24.45 + 24.46 + // Interface from processor to cache 24.47 + interface Server#(req_t,resp_t) proc_server; 24.48 + 24.49 + // Interface from cache to main memory 24.50 + interface Client#(MainMemReq,MainMemResp) mmem_client; 24.51 + 24.52 + // Interface for enabling/disabling statistics 24.53 + interface Put#(Bool) statsEn_put; 24.54 + 24.55 + // Interface for collecting statistics 24.56 + interface DCacheStats stats; 24.57 + 24.58 +endinterface 24.59 + 24.60 + 24.61 +//---------------------------------------------------------------------- 24.62 +// Cache Types 24.63 +//---------------------------------------------------------------------- 24.64 + 24.65 +typedef 10 CacheLineIndexSz; 24.66 +typedef 20 CacheLineTagSz; 24.67 +typedef 32 CacheLineSz; 24.68 + 24.69 +typedef Bit#(CacheLineIndexSz) CacheLineIndex; 24.70 +typedef Bit#(CacheLineTagSz) CacheLineTag; 24.71 +typedef Bit#(CacheLineSz) CacheLine; 24.72 + 24.73 +typedef enum 24.74 +{ 24.75 + Init, 24.76 + Access, 24.77 + RefillReq, 24.78 + RefillResp 24.79 +} 24.80 +CacheStage 24.81 +deriving (Eq,Bits); 24.82 + 24.83 +//---------------------------------------------------------------------- 24.84 +// Helper functions 24.85 +//---------------------------------------------------------------------- 24.86 + 24.87 +function Bit#(AddrSz) getAddr( DataReq req ); 24.88 + 24.89 + Bit#(AddrSz) addr = ?; 24.90 + case ( req ) matches 24.91 + tagged LoadReq .ld : addr = ld.addr; 24.92 + tagged StoreReq .st : addr = st.addr; 24.93 + endcase 24.94 + 24.95 + return addr; 24.96 + 24.97 +endfunction 24.98 + 24.99 +function CacheLineIndex getCacheLineIndex( DataReq req ); 24.100 + Bit#(AddrSz) addr = getAddr(req); 24.101 + Bit#(CacheLineIndexSz) index = truncate( addr >> 2 ); 24.102 + return index; 24.103 +endfunction 24.104 + 24.105 +function CacheLineTag getCacheLineTag( DataReq req ); 24.106 + Bit#(AddrSz) addr = getAddr(req); 24.107 + Bit#(CacheLineTagSz) tag = truncate( addr >> fromInteger(valueOf(CacheLineIndexSz)) >> 2 ); 24.108 + return tag; 24.109 +endfunction 24.110 + 24.111 +function Bit#(AddrSz) getCacheLineAddr( DataReq req ); 24.112 + Bit#(AddrSz) addr = getAddr(req); 24.113 + return ((addr >> 2) << 2); 24.114 +endfunction 24.115 + 24.116 +//---------------------------------------------------------------------- 24.117 +// Main module 24.118 +//---------------------------------------------------------------------- 24.119 + 24.120 +(* doc = "synthesis attribute ram_style mkDataCache distributed;" *) 24.121 +(* synthesize *) 24.122 +module mkDataCache( DCache#(DataReq,DataResp) ); 24.123 + 24.124 + //----------------------------------------------------------- 24.125 + // State 24.126 + 24.127 + Reg#(CacheStage) stage <- mkReg(Init); 24.128 + 24.129 + RegFile#(CacheLineIndex,Maybe#(CacheLineTag)) cacheTagRam <- mkRegFileFull(); 24.130 + RegFile#(CacheLineIndex,CacheLine) cacheDataRam <- mkRegFileFull(); 24.131 + 24.132 + FIFO#(DataReq) reqQ <- mkFIFO(); 24.133 + FIFOF#(DataResp) respQ <- mkBFIFOF1(); 24.134 + 24.135 + FIFO#(MainMemReq) mainMemReqQ <- mkBFIFO1(); 24.136 + FIFO#(MainMemResp) mainMemRespQ <- mkFIFO(); 24.137 + 24.138 + Reg#(CacheLineIndex) initCounter <- mkReg(1); 24.139 + 24.140 + // Statistics state 24.141 + 24.142 + Reg#(Bool) statsEn <- mkReg(False); 24.143 + 24.144 + Reg#(Stat) num_accesses <- mkReg(0); 24.145 + Reg#(Stat) num_misses <- mkReg(0); 24.146 + Reg#(Stat) num_writebacks <- mkReg(0); 24.147 + 24.148 + //----------------------------------------------------------- 24.149 + // Name some wires 24.150 + 24.151 + let req = reqQ.first(); 24.152 + let reqIndex = getCacheLineIndex(req); 24.153 + let reqTag = getCacheLineTag(req); 24.154 + let reqCacheLineAddr = getCacheLineAddr(req); 24.155 + 24.156 + //----------------------------------------------------------- 24.157 + // Initialize 24.158 + 24.159 + rule init ( stage == Init ); 24.160 + traceTiny("mkDataCacheBlocking", "stage","i"); 24.161 + initCounter <= initCounter + 1; 24.162 + cacheTagRam.upd(initCounter,Invalid); 24.163 + if ( initCounter == 0 ) 24.164 + stage <= Access; 24.165 + endrule 24.166 + 24.167 + //----------------------------------------------------------- 24.168 + // Access cache rule 24.169 + 24.170 + rule access ( (stage == Access) && respQ.notFull() ); 24.171 + 24.172 + // Statistics 24.173 + 24.174 + if ( statsEn ) 24.175 + num_accesses <= num_accesses + 1; 24.176 + 24.177 + 24.178 + // Get the corresponding tag from the rams 24.179 + 24.180 + Maybe#(CacheLineTag) cacheLineTag = cacheTagRam.sub(reqIndex); 24.181 + 24.182 + // Handle cache hits ... 24.183 + 24.184 + if ( isValid(cacheLineTag) && ( unJust(cacheLineTag) == reqTag ) ) 24.185 + begin 24.186 + traceTiny("mkDataCacheBlocking", "hitMiss","h"); 24.187 + reqQ.deq(); 24.188 + 24.189 + case ( req ) matches 24.190 + 24.191 + tagged LoadReq .ld : 24.192 + respQ.enq( LoadResp { tag: ld.tag, data: cacheDataRam.sub(reqIndex) } ); 24.193 + 24.194 + tagged StoreReq .st : 24.195 + begin 24.196 + respQ.enq( StoreResp { tag : st.tag } ); 24.197 + cacheDataRam.upd(reqIndex,st.data); 24.198 + end 24.199 + 24.200 + endcase 24.201 + 24.202 + end 24.203 + 24.204 + // Handle cache misses ... 24.205 + 24.206 + else 24.207 + begin 24.208 + traceTiny("mkDataCacheBlocking", "hitMiss","m"); 24.209 + if ( statsEn ) 24.210 + num_misses <= num_misses + 1; 24.211 + 24.212 + // Currently we don't use dirty bits so we always writeback the data if it is valid 24.213 + 24.214 + if ( isValid(cacheLineTag) ) 24.215 + begin 24.216 + 24.217 + if ( statsEn ) 24.218 + num_writebacks <= num_writebacks + 1; 24.219 + 24.220 + MainMemReq wbReq 24.221 + = StoreReq { tag : 0, 24.222 + addr : { unJust(cacheLineTag), reqIndex, 2'b0 }, 24.223 + data : cacheDataRam.sub(reqIndex) }; 24.224 + 24.225 + mainMemReqQ.enq(wbReq); 24.226 + stage <= RefillReq; 24.227 + end 24.228 + 24.229 + // Otherwise we can issue the refill request now 24.230 + 24.231 + else 24.232 + begin 24.233 + mainMemReqQ.enq( LoadReq { tag: 0, addr: reqCacheLineAddr } ); 24.234 + stage <= RefillResp; 24.235 + end 24.236 + 24.237 + end 24.238 + 24.239 + endrule 24.240 + 24.241 + //----------------------------------------------------------- 24.242 + // Refill request rule 24.243 + 24.244 + rule refillReq ( stage == RefillReq ); 24.245 + traceTiny("mkDataCacheBlocking", "stage","r"); 24.246 + mainMemReqQ.enq( LoadReq { tag: 0, addr: reqCacheLineAddr } ); 24.247 + stage <= RefillResp; 24.248 + endrule 24.249 + 24.250 + //----------------------------------------------------------- 24.251 + // Refill response rule 24.252 + 24.253 + rule refillResp ( stage == RefillResp ); 24.254 + traceTiny("mkDataCacheBlocking", "stage","R"); 24.255 + traceTiny("mkDataCacheBlocking", "refill",mainMemRespQ.first()); 24.256 + 24.257 + // Write the new data into the cache and update the tag 24.258 + 24.259 + mainMemRespQ.deq(); 24.260 + case ( mainMemRespQ.first() ) matches 24.261 + 24.262 + tagged LoadResp .ld : 24.263 + begin 24.264 + cacheTagRam.upd(reqIndex,Valid(reqTag)); 24.265 + cacheDataRam.upd(reqIndex,ld.data); 24.266 + end 24.267 + 24.268 + tagged StoreResp .st : 24.269 + noAction; 24.270 + 24.271 + endcase 24.272 + 24.273 + stage <= Access; 24.274 + endrule 24.275 + 24.276 + //----------------------------------------------------------- 24.277 + // Methods 24.278 + 24.279 + interface Client mmem_client; 24.280 + interface Get request = toGet(mainMemReqQ); 24.281 + interface Put response = toPut(mainMemRespQ); 24.282 + endinterface 24.283 + 24.284 + interface Server proc_server; 24.285 + interface Put request = tracePut("mkDataCacheBlocking", "reqTiny",toPut(reqQ)); 24.286 + interface Get response = traceGet("mkDataCacheBlocking", "respTiny",toGet(respQ)); 24.287 + endinterface 24.288 + 24.289 + interface Put statsEn_put = toPut(asReg(statsEn)); 24.290 + 24.291 + interface DCacheStats stats; 24.292 + interface Get num_accesses = toGet(asReg(num_accesses)); 24.293 + interface Get num_misses = toGet(asReg(num_misses)); 24.294 + interface Get num_writebacks = toGet(asReg(num_writebacks)); 24.295 + endinterface 24.296 + 24.297 +endmodule 24.298 +
25.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 25.2 +++ b/modules/bluespec/Pygar/core/FIRFilterPipeline.bsv Fri Apr 23 02:32:05 2010 -0400 25.3 @@ -0,0 +1,46 @@ 25.4 +// The MIT License 25.5 + 25.6 +// Copyright (c) 2009 Massachusetts Institute of Technology 25.7 + 25.8 +// Permission is hereby granted, free of charge, to any person obtaining a copy 25.9 +// of this software and associated documentation files (the "Software"), to deal 25.10 +// in the Software without restriction, including without limitation the rights 25.11 +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 25.12 +// copies of the Software, and to permit persons to whom the Software is 25.13 +// furnished to do so, subject to the following conditions: 25.14 + 25.15 +// The above copyright notice and this permission notice shall be included in 25.16 +// all copies or substantial portions of the Software. 25.17 + 25.18 +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 25.19 +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 25.20 +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25.21 +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25.22 +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25.23 +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25.24 +// THE SOFTWARE. 25.25 + 25.26 +// Author: Kermin Fleming kfleming@mit.edu 25.27 + 25.28 +import Connectable::*; 25.29 +import GetPut::*; 25.30 +import ClientServer::*; 25.31 +import FIFO::*; 25.32 + 25.33 +//AWB includes 25.34 +`include "asim/provides/low_level_platform_interface.bsh" 25.35 +`include "asim/provides/soft_connections.bsh" 25.36 +`include "asim/provides/common_services.bsh" 25.37 + 25.38 +//Local includes 25.39 +`include "asim/provides/audio_processor_types.bsh" 25.40 +`include "asim/provides/audio_pipeline_types.bsh" 25.41 +`include "asim/provides/fir_filter.bsh" 25.42 + 25.43 +module [Connected_Module] mkAudioPipeline (AudioPipeline); 25.44 + FIRFilter filter <- mkFIRFilter; 25.45 + 25.46 + interface sampleInput = filter.sampleInput; 25.47 + interface sampleOutput = filter.sampleOutput; 25.48 + 25.49 +endmodule
26.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 26.2 +++ b/modules/bluespec/Pygar/core/InstCache.dic Fri Apr 23 02:32:05 2010 -0400 26.3 @@ -0,0 +1,3 @@ 26.4 +def STATS.INST_CACHE.NUM_ACCESSES "INST_CACHE: Number Of Accesses: "; 26.5 +def STATS.INST_CACHE.NUM_MISSES "INST_CACHE: Number Of Misses: "; 26.6 +def STATS.INST_CACHE.NUM_EVICTIONS "INST_CACHE: Number Of Evictions: ";
27.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 27.2 +++ b/modules/bluespec/Pygar/core/InstCacheBlocking.d Fri Apr 23 02:32:05 2010 -0400 27.3 @@ -0,0 +1,269 @@ 27.4 +// The MIT License 27.5 + 27.6 +// Copyright (c) 2009 Massachusetts Institute of Technology 27.7 + 27.8 +// Permission is hereby granted, free of charge, to any person obtaining a copy 27.9 +// of this software and associated documentation files (the "Software"), to deal 27.10 +// in the Software without restriction, including without limitation the rights 27.11 +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 27.12 +// copies of the Software, and to permit persons to whom the Software is 27.13 +// furnished to do so, subject to the following conditions: 27.14 + 27.15 +// The above copyright notice and this permission notice shall be included in 27.16 +// all copies or substantial portions of the Software. 27.17 + 27.18 +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 27.19 +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 27.20 +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 27.21 +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 27.22 +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 27.23 +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27.24 +// THE SOFTWARE. 27.25 + 27.26 +import Connectable::*; 27.27 +import GetPut::*; 27.28 +import ClientServer::*; 27.29 +import RegFile::*; 27.30 +import FIFO::*; 27.31 +import FIFOF::*; 27.32 +import RWire::*; 27.33 + 27.34 +import BFIFO::*; 27.35 +import MemTypes::*; 27.36 +import ProcTypes::*; 27.37 +import Trace::*; 27.38 + 27.39 +interface ICacheStats; 27.40 + interface Get#(Stat) num_accesses; 27.41 + interface Get#(Stat) num_misses; 27.42 + interface Get#(Stat) num_evictions; 27.43 +endinterface 27.44 + 27.45 +interface ICache#( type req_t, type resp_t ); 27.46 + 27.47 + // Interface from processor to cache 27.48 + interface Server#(req_t,resp_t) proc_server; 27.49 + 27.50 + // Interface from cache to main memory 27.51 + interface Client#(MainMemReq,MainMemResp) mmem_client; 27.52 + 27.53 + // Interface for enabling/disabling statistics 27.54 + interface Put#(Bool) statsEn_put; 27.55 + 27.56 + // Interface for collecting statistics 27.57 + interface ICacheStats stats; 27.58 + 27.59 +endinterface 27.60 + 27.61 +//---------------------------------------------------------------------- 27.62 +// Cache Types 27.63 +//---------------------------------------------------------------------- 27.64 + 27.65 +typedef 10 CacheLineIndexSz; 27.66 +typedef 20 CacheLineTagSz; 27.67 +typedef 32 CacheLineSz; 27.68 + 27.69 +typedef Bit#(CacheLineIndexSz) CacheLineIndex; 27.70 +typedef Bit#(CacheLineTagSz) CacheLineTag; 27.71 +typedef Bit#(CacheLineSz) CacheLine; 27.72 + 27.73 +typedef enum 27.74 +{ 27.75 + Init, 27.76 + Access, 27.77 + Evict, 27.78 + RefillReq, 27.79 + RefillResp 27.80 +} 27.81 +CacheStage 27.82 +deriving (Eq,Bits); 27.83 + 27.84 +//---------------------------------------------------------------------- 27.85 +// Helper functions 27.86 +//---------------------------------------------------------------------- 27.87 + 27.88 +function Bit#(AddrSz) getAddr( InstReq req ); 27.89 + 27.90 + Bit#(AddrSz) addr = ?; 27.91 + case ( req ) matches 27.92 + tagged LoadReq .ld : addr = ld.addr; 27.93 + tagged StoreReq .st : addr = st.addr; 27.94 + endcase 27.95 + 27.96 + return addr; 27.97 + 27.98 +endfunction 27.99 + 27.100 +function CacheLineIndex getCacheLineIndex( InstReq req ); 27.101 + Bit#(AddrSz) addr = getAddr(req); 27.102 + Bit#(CacheLineIndexSz) index = truncate( addr >> 2 ); 27.103 + return index; 27.104 +endfunction 27.105 + 27.106 +function CacheLineTag getCacheLineTag( InstReq req ); 27.107 + Bit#(AddrSz) addr = getAddr(req); 27.108 + Bit#(CacheLineTagSz) tag = truncate( addr >> fromInteger(valueOf(CacheLineIndexSz)) >> 2 ); 27.109 + return tag; 27.110 +endfunction 27.111 + 27.112 +function Bit#(AddrSz) getCacheLineAddr( InstReq req ); 27.113 + Bit#(AddrSz) addr = getAddr(req); 27.114 + return ((addr >> 2) << 2); 27.115 +endfunction 27.116 + 27.117 +//---------------------------------------------------------------------- 27.118 +// Main module 27.119 +//---------------------------------------------------------------------- 27.120 + 27.121 +(* doc = "synthesis attribute ram_style mkInstCache distributed;" *) 27.122 +(* synthesize *) 27.123 +module mkInstCache( ICache#(InstReq,InstResp) ); 27.124 + 27.125 + //----------------------------------------------------------- 27.126 + // State 27.127 + 27.128 + Reg#(CacheStage) stage <- mkReg(Init); 27.129 + 27.130 + RegFile#(CacheLineIndex,Maybe#(CacheLineTag)) cacheTagRam <- mkRegFileFull(); 27.131 + RegFile#(CacheLineIndex,CacheLine) cacheDataRam <- mkRegFileFull(); 27.132 + 27.133 + FIFO#(InstReq) reqQ <- mkFIFO(); 27.134 + FIFOF#(InstResp) respQ <- mkBFIFOF1(); 27.135 + 27.136 + FIFO#(MainMemReq) mainMemReqQ <- mkBFIFO1(); 27.137 + FIFO#(MainMemResp) mainMemRespQ <- mkFIFO(); 27.138 + 27.139 + Reg#(CacheLineIndex) initCounter <- mkReg(1); 27.140 + 27.141 + // Statistics state 27.142 + 27.143 + Reg#(Bool) statsEn <- mkReg(False); 27.144 + 27.145 + Reg#(Stat) numAccesses <- mkReg(0); 27.146 + Reg#(Stat) numMisses <- mkReg(0); 27.147 + Reg#(Stat) numEvictions <- mkReg(0); 27.148 + 27.149 + //----------------------------------------------------------- 27.150 + // Name some wires 27.151 + 27.152 + let req = reqQ.first(); 27.153 + let reqIndex = getCacheLineIndex(req); 27.154 + let reqTag = getCacheLineTag(req); 27.155 + let reqCacheLineAddr = getCacheLineAddr(req); 27.156 + let refill = mainMemRespQ.first(); 27.157 + 27.158 + //----------------------------------------------------------- 27.159 + // Initialize 27.160 + 27.161 + rule init ( stage == Init ); 27.162 + traceTiny("mkInstCacheBlocking", "stage","i"); 27.163 + initCounter <= initCounter + 1; 27.164 + cacheTagRam.upd(initCounter,Invalid); 27.165 + if ( initCounter == 0 ) 27.166 + stage <= Access; 27.167 + endrule 27.168 + 27.169 + //----------------------------------------------------------- 27.170 + // Cache access rule 27.171 + 27.172 + rule access ( (stage == Access) && respQ.notFull() ); 27.173 + 27.174 + // Statistics 27.175 + 27.176 + if ( statsEn ) 27.177 + numAccesses <= numAccesses + 1; 27.178 + 27.179 + // Check tag and valid bit to see if this is a hit or a miss 27.180 + 27.181 + Maybe#(CacheLineTag) cacheLineTag = cacheTagRam.sub(reqIndex); 27.182 + 27.183 + // Handle cache hits ... 27.184 + 27.185 + if ( isValid(cacheLineTag) && ( unJust(cacheLineTag) == reqTag ) ) 27.186 + begin 27.187 + traceTiny("mkInstCacheBlocking", "hitMiss","h"); 27.188 + reqQ.deq(); 27.189 + 27.190 + case ( req ) matches 27.191 + 27.192 + tagged LoadReq .ld : 27.193 + respQ.enq( LoadResp { tag : ld.tag, data : cacheDataRam.sub(reqIndex) } ); 27.194 + 27.195 + tagged StoreReq .st : 27.196 + $display( " RTL-ERROR : %m : Stores are not allowed on the inst port!" ); 27.197 + 27.198 + endcase 27.199 + 27.200 + end 27.201 + 27.202 + // Handle cache misses - since lines in instruction cache are 27.203 + // never dirty we can always immediately issue a refill request 27.204 + 27.205 + else 27.206 + begin 27.207 + traceTiny("mkInstCacheBlocking", "hitMiss","m"); 27.208 + if ( statsEn ) 27.209 + numMisses <= numMisses + 1; 27.210 + if ( statsEn ) 27.211 + if ( isJust(cacheLineTag) ) 27.212 + numEvictions <= numEvictions + 1; 27.213 + 27.214 + MainMemReq rfReq 27.215 + = LoadReq { tag : 0, 27.216 + addr : reqCacheLineAddr }; 27.217 + 27.218 + mainMemReqQ.enq(rfReq); 27.219 + stage <= RefillResp; 27.220 + end 27.221 + 27.222 + endrule 27.223 + 27.224 + //----------------------------------------------------------- 27.225 + // Refill response rule 27.226 + 27.227 + rule refillResp ( stage == RefillResp ); 27.228 + traceTiny("mkInstCacheBlocking", "stage","R"); 27.229 + traceTiny("mkInstCacheBlocking", "refill",refill); 27.230 + 27.231 + // Write the new data into the cache and update the tag 27.232 + 27.233 + mainMemRespQ.deq(); 27.234 + case ( mainMemRespQ.first() ) matches 27.235 + 27.236 + tagged LoadResp .ld : 27.237 + begin 27.238 + cacheTagRam.upd(reqIndex,Valid(reqTag)); 27.239 + cacheDataRam.upd(reqIndex,ld.data); 27.240 + end 27.241 + 27.242 + tagged StoreResp .st : 27.243 + noAction; 27.244 + 27.245 + endcase 27.246 + 27.247 + stage <= Access; 27.248 + endrule 27.249 + 27.250 + //----------------------------------------------------------- 27.251 + // Methods 27.252 + 27.253 + interface Client mmem_client; 27.254 + interface Get request = fifoToGet(mainMemReqQ); 27.255 + interface Put response = fifoToPut(mainMemRespQ); 27.256 + endinterface 27.257 + 27.258 + interface Server proc_server; 27.259 + interface Put request = tracePut("mkInstCacheBlocking", "reqTiny",toPut(reqQ)); 27.260 + interface Get response = traceGet("mkInstCacheBlocking", "respTiny",toGet(respQ)); 27.261 + endinterface 27.262 + 27.263 + interface Put statsEn_put = toPut(asReg(statsEn)); 27.264 + 27.265 + interface ICacheStats stats; 27.266 + interface Get num_accesses = toGet(asReg(numAccesses)); 27.267 + interface Get num_misses = toGet(asReg(numMisses)); 27.268 + interface Get num_evictions = toGet(asReg(numEvictions)); 27.269 + endinterface 27.270 + 27.271 +endmodule 27.272 +
28.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 28.2 +++ b/modules/bluespec/Pygar/core/MemArb.bsv Fri Apr 23 02:32:05 2010 -0400 28.3 @@ -0,0 +1,141 @@ 28.4 +// The MIT License 28.5 + 28.6 +// Copyright (c) 2009 Massachusetts Institute of Technology 28.7 + 28.8 +// Permission is hereby granted, free of charge, to any person obtaining a copy 28.9 +// of this software and associated documentation files (the "Software"), to deal 28.10 +// in the Software without restriction, including without limitation the rights 28.11 +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 28.12 +// copies of the Software, and to permit persons to whom the Software is 28.13 +// furnished to do so, subject to the following conditions: 28.14 + 28.15 +// The above copyright notice and this permission notice shall be included in 28.16 +// all copies or substantial portions of the Software. 28.17 + 28.18 +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 28.19 +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 28.20 +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 28.21 +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 28.22 +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 28.23 +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 28.24 +// THE SOFTWARE. 28.25 + 28.26 +import Connectable::*; 28.27 +import GetPut::*; 28.28 +import ClientServer::*; 28.29 +import FIFOF::*; 28.30 +import FIFO::*; 28.31 + 28.32 +import BFIFO::*; 28.33 +import MemTypes::*; 28.34 +import Trace::*; 28.35 + 28.36 +interface MemArb; 28.37 + 28.38 + interface Server#(MainMemReq,MainMemResp) cache0_server; 28.39 + interface Server#(MainMemReq,MainMemResp) cache1_server; 28.40 + interface Client#(MainMemReq,MainMemResp) mmem_client; 28.41 + 28.42 +endinterface 28.43 + 28.44 +typedef enum { REQ0, REQ1 } ReqPtr deriving(Eq,Bits); 28.45 + 28.46 +(* synthesize *) 28.47 +module mkMemArb( MemArb ); 28.48 + 28.49 + //----------------------------------------------------------- 28.50 + // State 28.51 + 28.52 + FIFOF#(MainMemReq) req0Q <- mkFIFOF1(); 28.53 + FIFO#(MainMemResp) resp0Q <- mkFIFO1(); 28.54 + 28.55 + FIFOF#(MainMemReq) req1Q <- mkFIFOF1(); 28.56 + FIFO#(MainMemResp) resp1Q <- mkFIFO1(); 28.57 + 28.58 + FIFO#(MainMemReq) mreqQ <- mkFIFO1(); 28.59 + FIFO#(MainMemResp) mrespQ <- mkFIFO1(); 28.60 + 28.61 + Reg#(ReqPtr) nextReq <- mkReg(REQ0); 28.62 + 28.63 + //----------------------------------------------------------- 28.64 + // Some wires 28.65 + 28.66 + let req0avail = req0Q.notEmpty(); 28.67 + let req1avail = req1Q.notEmpty(); 28.68 + 28.69 + //----------------------------------------------------------- 28.70 + // Rules 28.71 + 28.72 + rule chooseReq0 ( req0avail && (!req1avail || (nextReq == REQ0)) ); 28.73 + traceTiny("mkMemArb", "memArb req0",req0Q.first()); 28.74 + 28.75 + // Rewrite tag field if this is a load ... 28.76 + MainMemReq mreq 28.77 + = case ( req0Q.first() ) matches 28.78 + tagged LoadReq .ld : return LoadReq { tag:0, addr:ld.addr }; 28.79 + tagged StoreReq .st : return req0Q.first(); 28.80 + endcase; 28.81 + 28.82 + // Send out the request 28.83 + mreqQ.enq(mreq); 28.84 + nextReq <= REQ1; 28.85 + req0Q.deq(); 28.86 + 28.87 + endrule 28.88 + 28.89 + rule chooseReq1 ( req1avail && (!req0avail || (nextReq == REQ1)) ); 28.90 + traceTiny("mkMemArb", "memArb req1",req1Q.first); 28.91 + 28.92 + // Rewrite tag field if this is a load ... 28.93 + MainMemReq mreq 28.94 + = case ( req1Q.first() ) matches 28.95 + tagged LoadReq .ld : return LoadReq { tag:1, addr:ld.addr }; 28.96 + tagged StoreReq .st : return req1Q.first(); 28.97 + endcase; 28.98 + 28.99 + // Send out the request 28.100 + mreqQ.enq(mreq); 28.101 + nextReq <= REQ0; 28.102 + req1Q.deq(); 28.103 + 28.104 + endrule 28.105 + 28.106 + rule returnResp; 28.107 + traceTiny("mkMemArb", "resp",mrespQ.first()); 28.108 + 28.109 + // Use tag to figure out where to send response 28.110 + mrespQ.deq(); 28.111 + let tag 28.112 + = case ( mrespQ.first() ) matches 28.113 + tagged LoadResp .ld : return ld.tag; 28.114 + tagged StoreResp .st : return st.tag; 28.115 + endcase; 28.116 + 28.117 + if ( tag == 0 ) 28.118 + resp0Q.enq(mrespQ.first()); 28.119 + else 28.120 + resp1Q.enq(mrespQ.first()); 28.121 + 28.122 + endrule 28.123 + 28.124 + //----------------------------------------------------------- 28.125 + // Methods 28.126 + 28.127 + interface Server cache0_server; 28.128 + interface Put request = toPut(req0Q); 28.129 + interface Get response = toGet(resp0Q); 28.130 + endinterface 28.131 + 28.132 + interface Server cache1_server; 28.133 + interface Put request = toPut(req1Q); 28.134 + interface Get response = toGet(resp1Q); 28.135 + endinterface 28.136 + 28.137 + interface Client mmem_client; 28.138 + interface Get request = toGet(mreqQ); 28.139 + interface Put response = toPut(mrespQ); 28.140 + endinterface 28.141 + 28.142 +endmodule 28.143 + 28.144 +
29.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 29.2 +++ b/modules/bluespec/Pygar/core/MemTypes.bsv Fri Apr 23 02:32:05 2010 -0400 29.3 @@ -0,0 +1,93 @@ 29.4 + 29.5 +import Trace::*; 29.6 + 29.7 +//---------------------------------------------------------------------- 29.8 +// Basic memory requests and responses 29.9 +//---------------------------------------------------------------------- 29.10 + 29.11 +typedef union tagged 29.12 +{ 29.13 + struct { Bit#(addrSz) addr; Bit#(tagSz) tag; } LoadReq; 29.14 + struct { Bit#(addrSz) addr; Bit#(tagSz) tag; Bit#(dataSz) data; } StoreReq; 29.15 +} 29.16 +MemReq#( type addrSz, type tagSz, type dataSz ) 29.17 +deriving(Eq,Bits); 29.18 + 29.19 +typedef union tagged 29.20 +{ 29.21 + struct { Bit#(tagSz) tag; Bit#(dataSz) data; } LoadResp; 29.22 + struct { Bit#(tagSz) tag; } StoreResp; 29.23 +} 29.24 +MemResp#( type tagSz, type dataSz ) 29.25 +deriving(Eq,Bits); 29.26 + 29.27 +//---------------------------------------------------------------------- 29.28 +// Specialized req/resp for inst/data/host 29.29 +//---------------------------------------------------------------------- 29.30 + 29.31 +typedef 32 AddrSz; 29.32 +typedef 08 TagSz; 29.33 +typedef 32 DataSz; 29.34 +typedef 32 InstSz; 29.35 +typedef 32 HostDataSz; 29.36 + 29.37 +typedef MemReq#(AddrSz,TagSz,0) InstReq; 29.38 +typedef MemResp#(TagSz,InstSz) InstResp; 29.39 + 29.40 +typedef MemReq#(AddrSz,TagSz,DataSz) DataReq; 29.41 +typedef MemResp#(TagSz,DataSz) DataResp; 29.42 + 29.43 +typedef MemReq#(AddrSz,TagSz,HostDataSz) HostReq; 29.44 +typedef MemResp#(TagSz,HostDataSz) HostResp; 29.45 + 29.46 +//---------------------------------------------------------------------- 29.47 +// Specialized req/resp for main memory 29.48 +//---------------------------------------------------------------------- 29.49 + 29.50 +typedef 32 MainMemAddrSz; 29.51 +typedef 08 MainMemTagSz; 29.52 +typedef 32 MainMemDataSz; 29.53 + 29.54 +typedef MemReq#(MainMemAddrSz,MainMemTagSz,MainMemDataSz) MainMemReq; 29.55 +typedef MemResp#(MainMemTagSz,MainMemDataSz) MainMemResp; 29.56 + 29.57 +//---------------------------------------------------------------------- 29.58 +// Tracing Functions 29.59 +//---------------------------------------------------------------------- 29.60 + 29.61 +instance Traceable#(MemReq#(a,b,c)); 29.62 + 29.63 + function Action traceTiny( String loc, String ttag, MemReq#(a,b,c) req ); 29.64 + case ( req ) matches 29.65 + tagged LoadReq .ld : $fdisplay(stderr, " => %s:%s l%2x", loc, ttag, ld.tag ); 29.66 + tagged StoreReq .st : $fdisplay(stderr, " => %s:%s s%2x", loc, ttag, st.tag ); 29.67 + endcase 29.68 + endfunction 29.69 + 29.70 + function Action traceFull( String loc, String ttag, MemReq#(a,b,c) req ); 29.71 + case ( req ) matches 29.72 + tagged LoadReq .ld : $fdisplay(stderr, " => %s:%s Ld { addr=%x, tag=%x }", loc, ttag, ld.addr, ld.tag ); 29.73 + tagged StoreReq .st : $fdisplay(stderr, " => %s:%s St { addr=%x, tag=%x, data=%x }", loc, ttag, st.addr, st.tag, st.data ); 29.74 + endcase 29.75 + endfunction 29.76 + 29.77 +endinstance 29.78 + 29.79 +instance Traceable#(MemResp#(a,b)); 29.80 + 29.81 + function Action traceTiny( String loc, String ttag, MemResp#(a,b) resp ); 29.82 + case ( resp ) matches 29.83 + tagged LoadResp .ld : $fdisplay(stderr, " => %s:%s l%2x", loc, ttag, ld.tag ); 29.84 + tagged StoreResp .st : $fdisplay(stderr, " => %s:%s s%2x", loc, ttag, st.tag ); 29.85 + endcase 29.86 + endfunction 29.87 + 29.88 + function Action traceFull( String loc, String ttag, MemResp#(a,b) resp ); 29.89 + case ( resp ) matches 29.90 + tagged LoadResp .ld : $fdisplay(stderr, " => %s:%s Ld { tag=%x, data=%x }", loc, ttag, ld.tag, ld.data ); 29.91 + tagged StoreResp .st : $fdisplay(stderr, " => %s:%s St { tag=%x }", loc, ttag, st.tag ); 29.92 + endcase 29.93 + endfunction 29.94 + 29.95 +endinstance 29.96 +
30.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 30.2 +++ b/modules/bluespec/Pygar/core/PathTypes.bsv Fri Apr 23 02:32:05 2010 -0400 30.3 @@ -0,0 +1,31 @@ 30.4 +import Trace::*; 30.5 +import Vector::*; 30.6 + 30.7 +`define MAX_VOICES 4 30.8 +`define MAX_CORES 16 30.9 +`define MAX_PATH_IDS 18 30.10 +`define MAX_PATH_LENGTH 8 30.11 + 30.12 +// The path is hardwired and so should never be stored in a register. Therefore int type rather than Bit type 30.13 + 30.14 +typedef Bit#(32) MemAddr; 30.15 +typedef Int#(TLog#(`MAX_PATH_IDS)) PathId; 30.16 +typedef Int#(24) Sample; 30.17 +typedef Int#(TLog#(`MAX_VOICES)) VoiceId; 30.18 + 30.19 + 30.20 +//The mixer is identified as PathId 0, path end is max 30.21 +PathId mixerId = 0; 30.22 +PathId endId = `MAX_CORES+1; 30.23 + 30.24 +// Path is array of path ids 30.25 +typedef Vector#(`MAX_PATH_LENGTH, PathId) CorePath; 30.26 +CorePath emptyCore = replicate(endId); 30.27 + 30.28 +typedef struct 30.29 +{ 30.30 + VoiceId voice; 30.31 + MemAddr startAddr; 30.32 + CorePath route; 30.33 +} FullPath deriving (Bits, Eq); 30.34 +
31.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 31.2 +++ b/modules/bluespec/Pygar/core/ProcTypes.bsv Fri Apr 23 02:32:05 2010 -0400 31.3 @@ -0,0 +1,375 @@ 31.4 + 31.5 +import Trace::*; 31.6 + 31.7 +//---------------------------------------------------------------------- 31.8 +// Other typedefs 31.9 +//---------------------------------------------------------------------- 31.10 + 31.11 +typedef Bit#(32) Addr; 31.12 +typedef Int#(18) Stat; 31.13 + 31.14 +//---------------------------------------------------------------------- 31.15 +// Basic instruction type 31.16 +//---------------------------------------------------------------------- 31.17 + 31.18 +typedef Bit#(5) Rindx; 31.19 +typedef Bit#(16) Simm; 31.20 +typedef Bit#(16) Zimm; 31.21 +typedef Bit#(8) Epoch; 31.22 +typedef Bit#(5) Shamt; 31.23 +typedef Bit#(26) Target; 31.24 +typedef Bit#(5) CP0indx; 31.25 +typedef Bit#(32) Data; 31.26 + 31.27 +typedef enum 31.28 +{ 31.29 + Taken, 31.30 + NotTaken 31.31 +} 31.32 + Direction 31.33 + deriving(Bits,Eq); 31.34 + 31.35 + 31.36 +//---------------------------------------------------------------------- 31.37 +// Pipeline typedefs 31.38 +//---------------------------------------------------------------------- 31.39 + 31.40 +typedef union tagged 31.41 +{ 31.42 + Tuple2#(Rindx,Data) ALUWB; 31.43 + Rindx MemWB; 31.44 + Tuple2#(Rindx,Data) CoWB; 31.45 +} 31.46 + WritebackType 31.47 + deriving(Bits,Eq); 31.48 + 31.49 +//////////////////////// 31.50 +// I Add Writeback queue type 31.51 +//////////// 31.52 +typedef union tagged 31.53 +{ 31.54 + struct {Bit#(32) data; Rindx dest; } WB_ALU; 31.55 + Bit#(32) WB_Host; 31.56 + Rindx WB_Load; 31.57 + void WB_Store; 31.58 +} 31.59 +WBResult deriving(Eq, Bits); 31.60 + 31.61 +typedef struct{Addr qpc; Addr qnxtpc; Epoch qepoch;} PCStat deriving(Eq, Bits); 31.62 +//typedef struct{Addr qpc; Epoch qepoch;} PCStat deriving(Eq, Bits); 31.63 + 31.64 +typedef union tagged 31.65 +{ 31.66 + 31.67 + struct { Rindx rbase; Rindx rdst; Simm offset; } LW; 31.68 + struct { Rindx rbase; Rindx rsrc; Simm offset; } SW; 31.69 + 31.70 + struct { Rindx rsrc; Rindx rdst; Simm imm; } ADDIU; 31.71 + struct { Rindx rsrc; Rindx rdst; Simm imm; } SLTI; 31.72 + struct { Rindx rsrc; Rindx rdst; Simm imm; } SLTIU; 31.73 + struct { Rindx rsrc; Rindx rdst; Zimm imm; } ANDI; 31.74 + struct { Rindx rsrc; Rindx rdst; Zimm imm; } ORI; 31.75 + struct { Rindx rsrc; Rindx rdst; Zimm imm; } XORI; 31.76 + struct { Rindx rdst; Zimm imm; } LUI; 31.77 + 31.78 + struct { Rindx rsrc; Rindx rdst; Shamt shamt; } SLL; 31.79 + struct { Rindx rsrc; Rindx rdst; Shamt shamt; } SRL; 31.80 + struct { Rindx rsrc; Rindx rdst; Shamt shamt; } SRA; 31.81 + struct { Rindx rsrc; Rindx rdst; Rindx rshamt; } SLLV; 31.82 + struct { Rindx rsrc; Rindx rdst; Rindx rshamt; } SRLV; 31.83 + struct { Rindx rsrc; Rindx rdst; Rindx rshamt; } SRAV; 31.84 + struct { Rindx rsrc1; Rindx rsrc2; Rindx rdst; } ADDU; 31.85 + struct { Rindx rsrc1; Rindx rsrc2; Rindx rdst; } SUBU; 31.86 + struct { Rindx rsrc1; Rindx rsrc2; Rindx rdst; } AND; 31.87 + struct { Rindx rsrc1; Rindx rsrc2; Rindx rdst; } OR; 31.88 + struct { Rindx rsrc1; Rindx rsrc2; Rindx rdst; } XOR; 31.89 + struct { Rindx rsrc1; Rindx rsrc2; Rindx rdst; } NOR; 31.90 + struct { Rindx rsrc1; Rindx rsrc2; Rindx rdst; } SLT; 31.91 + struct { Rindx rsrc1; Rindx rsrc2; Rindx rdst; } SLTU; 31.92 + 31.93 + struct { Target target; } J; 31.94 + struct { Target target; } JAL; 31.95 + struct { Rindx rsrc; } JR; 31.96 + struct { Rindx rsrc; Rindx rdst; } JALR; 31.97 + struct { Rindx rsrc1; Rindx rsrc2; Simm offset; } BEQ; 31.98 + struct { Rindx rsrc1; Rindx rsrc2; Simm offset; } BNE; 31.99 + struct { Rindx rsrc; Simm offset; } BLEZ; 31.100 + struct { Rindx rsrc; Simm offset; } BGTZ; 31.101 + struct { Rindx rsrc; Simm offset; } BLTZ; 31.102 + struct { Rindx rsrc; Simm offset; } BGEZ; 31.103 + 31.104 + struct { Rindx rdst; CP0indx cop0src; } MFC0; 31.105 + struct { Rindx rsrc; CP0indx cop0dst; } MTC0; 31.106 + 31.107 + void ILLEGAL; 31.108 + 31.109 +} 31.110 +Instr deriving(Eq); 31.111 + 31.112 +//---------------------------------------------------------------------- 31.113 +// Pack and Unpack 31.114 +//---------------------------------------------------------------------- 31.115 + 31.116 +Bit#(6) opFUNC = 6'b000000; Bit#(6) fcSLL = 6'b000000; 31.117 +Bit#(6) opRT = 6'b000001; Bit#(6) fcSRL = 6'b000010; 31.118 +Bit#(6) opRS = 6'b010000; Bit#(6) fcSRA = 6'b000011; 31.119 + Bit#(6) fcSLLV = 6'b000100; 31.120 +Bit#(6) opLW = 6'b100011; Bit#(6) fcSRLV = 6'b000110; 31.121 +Bit#(6) opSW = 6'b101011; Bit#(6) fcSRAV = 6'b000111; 31.122 + Bit#(6) fcADDU = 6'b100001; 31.123 +Bit#(6) opADDIU = 6'b001001; Bit#(6) fcSUBU = 6'b100011; 31.124 +Bit#(6) opSLTI = 6'b001010; Bit#(6) fcAND = 6'b100100; 31.125 +Bit#(6) opSLTIU = 6'b001011; Bit#(6) fcOR = 6'b100101; 31.126 +Bit#(6) opANDI = 6'b001100; Bit#(6) fcXOR = 6'b100110; 31.127 +Bit#(6) opORI = 6'b001101; Bit#(6) fcNOR = 6'b100111; 31.128 +Bit#(6) opXORI = 6'b001110; Bit#(6) fcSLT = 6'b101010; 31.129 +Bit#(6) opLUI = 6'b001111; Bit#(6) fcSLTU = 6'b101011; 31.130 + 31.131 +Bit#(6) opJ = 6'b000010; 31.132 +Bit#(6) opJAL = 6'b000011; 31.133 +Bit#(6) fcJR = 6'b001000; 31.134 +Bit#(6) fcJALR = 6'b001001; 31.135 +Bit#(6) opBEQ = 6'b000100; 31.136 +Bit#(6) opBNE = 6'b000101; 31.137 +Bit#(6) opBLEZ = 6'b000110; 31.138 +Bit#(6) opBGTZ = 6'b000111; 31.139 +Bit#(5) rtBLTZ = 5'b00000; 31.140 +Bit#(5) rtBGEZ = 5'b00001; 31.141 + 31.142 +Bit#(5) rsMFC0 = 5'b00000; 31.143 +Bit#(5) rsMTC0 = 5'b00100; 31.144 + 31.145 +instance Bits#(Instr,32); 31.146 + 31.147 + // Pack Function 31.148 + 31.149 + function Bit#(32) pack( Instr instr ); 31.150 + 31.151 + case ( instr ) matches 31.152 + 31.153 + tagged LW .it : return { opLW, it.rbase, it.rdst, it.offset }; 31.154 + tagged SW .it : return { opSW, it.rbase, it.rsrc, it.offset }; 31.155 + 31.156 + tagged ADDIU .it : return { opADDIU, it.rsrc, it.rdst, it.imm }; 31.157 + tagged SLTI .it : return { opSLTI, it.rsrc, it.rdst, it.imm }; 31.158 + tagged SLTIU .it : return { opSLTIU, it.rsrc, it.rdst, it.imm }; 31.159 + tagged ANDI .it : return { opANDI, it.rsrc, it.rdst, it.imm }; 31.160 + tagged ORI .it : return { opORI, it.rsrc, it.rdst, it.imm }; 31.161 + tagged XORI .it : return { opXORI, it.rsrc, it.rdst, it.imm }; 31.162 + tagged LUI .it : return { opLUI, 5'b0, it.rdst, it.imm }; 31.163 + 31.164 + tagged SLL .it : return { opFUNC, 5'b0, it.rsrc, it.rdst, it.shamt, fcSLL }; 31.165 + tagged SRL .it : return { opFUNC, 5'b0, it.rsrc, it.rdst, it.shamt, fcSRL }; 31.166 + tagged SRA .it : return { opFUNC, 5'b0, it.rsrc, it.rdst, it.shamt, fcSRA }; 31.167 + 31.168 + tagged SLLV .it : return { opFUNC, it.rshamt, it.rsrc, it.rdst, 5'b0, fcSLLV }; 31.169 + tagged SRLV .it : return { opFUNC, it.rshamt, it.rsrc, it.rdst, 5'b0, fcSRLV }; 31.170 + tagged SRAV .it : return { opFUNC, it.rshamt, it.rsrc, it.rdst, 5'b0, fcSRAV }; 31.171 + 31.172 + tagged ADDU .it : return { opFUNC, it.rsrc1, it.rsrc2, it.rdst, 5'b0, fcADDU }; 31.173 + tagged SUBU .it : return { opFUNC, it.rsrc1, it.rsrc2, it.rdst, 5'b0, fcSUBU }; 31.174 + tagged AND .it : return { opFUNC, it.rsrc1, it.rsrc2, it.rdst, 5'b0, fcAND }; 31.175 + tagged OR .it : return { opFUNC, it.rsrc1, it.rsrc2, it.rdst, 5'b0, fcOR }; 31.176 + tagged XOR .it : return { opFUNC, it.rsrc1, it.rsrc2, it.rdst, 5'b0, fcXOR }; 31.177 + tagged NOR .it : return { opFUNC, it.rsrc1, it.rsrc2, it.rdst, 5'b0, fcNOR }; 31.178 + tagged SLT .it : return { opFUNC, it.rsrc1, it.rsrc2, it.rdst, 5'b0, fcSLT }; 31.179 + tagged SLTU .it : return { opFUNC, it.rsrc1, it.rsrc2, it.rdst, 5'b0, fcSLTU }; 31.180 + 31.181 + tagged J .it : return { opJ, it.target }; 31.182 + tagged JAL .it : return { opJAL, it.target }; 31.183 + tagged JR .it : return { opFUNC, it.rsrc, 5'b0, 5'b0, 5'b0, fcJR }; 31.184 + tagged JALR .it : return { opFUNC, it.rsrc, 5'b0, it.rdst, 5'b0, fcJALR }; 31.185 + tagged BEQ .it : return { opBEQ, it.rsrc1, it.rsrc2, it.offset }; 31.186 + tagged BNE .it : return { opBNE, it.rsrc1, it.rsrc2, it.offset }; 31.187 + tagged BLEZ .it : return { opBLEZ, it.rsrc, 5'b0, it.offset }; 31.188 + tagged BGTZ .it : return { opBGTZ, it.rsrc, 5'b0, it.offset }; 31.189 + tagged BLTZ .it : return { opRT, it.rsrc, rtBLTZ, it.offset }; 31.190 + tagged BGEZ .it : return { opRT, it.rsrc, rtBGEZ, it.offset }; 31.191 + 31.192 + tagged MFC0 .it : return { opRS, rsMFC0, it.rdst, it.cop0src, 11'b0 }; 31.193 + tagged MTC0 .it : return { opRS, rsMTC0, it.rsrc, it.cop0dst, 11'b0 }; 31.194 + 31.195 + endcase 31.196 + 31.197 + endfunction 31.198 + 31.199 + // Unpack Function 31.200 + 31.201 + function Instr unpack( Bit#(32) instrBits ); 31.202 + 31.203 + let opcode = instrBits[ 31 : 26 ]; 31.204 + let rs = instrBits[ 25 : 21 ]; 31.205 + let rt = instrBits[ 20 : 16 ]; 31.206 + let rd = instrBits[ 15 : 11 ]; 31.207 + let shamt = instrBits[ 10 : 6 ]; 31.208 + let funct = instrBits[ 5 : 0 ]; 31.209 + let imm = instrBits[ 15 : 0 ]; 31.210 + let target = instrBits[ 25 : 0 ]; 31.211 + 31.212 + case ( opcode ) 31.213 + 31.214 + opLW : return LW { rbase:rs, rdst:rt, offset:imm }; 31.215 + opSW : return SW { rbase:rs, rsrc:rt, offset:imm }; 31.216 + opADDIU : return ADDIU { rsrc:rs, rdst:rt, imm:imm }; 31.217 + opSLTI : return SLTI { rsrc:rs, rdst:rt, imm:imm }; 31.218 + opSLTIU : return SLTIU { rsrc:rs, rdst:rt, imm:imm }; 31.219 + opANDI : return ANDI { rsrc:rs, rdst:rt, imm:imm }; 31.220 + opORI : return ORI { rsrc:rs, rdst:rt, imm:imm }; 31.221 + opXORI : return XORI { rsrc:rs, rdst:rt, imm:imm }; 31.222 + opLUI : return LUI { rdst:rt, imm:imm }; 31.223 + opJ : return J { target:target }; 31.224 + opJAL : return JAL { target:target }; 31.225 + opBEQ : return BEQ { rsrc1:rs, rsrc2:rt, offset:imm }; 31.226 + opBNE : return BNE { rsrc1:rs, rsrc2:rt, offset:imm }; 31.227 + opBLEZ : return BLEZ { rsrc:rs, offset:imm }; 31.228 + opBGTZ : return BGTZ { rsrc:rs, offset:imm }; 31.229 + 31.230 + opFUNC : 31.231 + case ( funct ) 31.232 + fcSLL : return SLL { rsrc:rt, rdst:rd, shamt:shamt }; 31.233 + fcSRL : return SRL { rsrc:rt, rdst:rd, shamt:shamt }; 31.234 + fcSRA : return SRA { rsrc:rt, rdst:rd, shamt:shamt }; 31.235 + fcSLLV : return SLLV { rsrc:rt, rdst:rd, rshamt:rs }; 31.236 + fcSRLV : return SRLV { rsrc:rt, rdst:rd, rshamt:rs }; 31.237 + fcSRAV : return SRAV { rsrc:rt, rdst:rd, rshamt:rs }; 31.238 + fcADDU : return ADDU { rsrc1:rs, rsrc2:rt, rdst:rd }; 31.239 + fcSUBU : return SUBU { rsrc1:rs, rsrc2:rt, rdst:rd }; 31.240 + fcAND : return AND { rsrc1:rs, rsrc2:rt, rdst:rd }; 31.241 + fcOR : return OR { rsrc1:rs, rsrc2:rt, rdst:rd }; 31.242 + fcXOR : return XOR { rsrc1:rs, rsrc2:rt, rdst:rd }; 31.243 + fcNOR : return NOR { rsrc1:rs, rsrc2:rt, rdst:rd }; 31.244 + fcSLT : return SLT { rsrc1:rs, rsrc2:rt, rdst:rd }; 31.245 + fcSLTU : return SLTU { rsrc1:rs, rsrc2:rt, rdst:rd }; 31.246 + fcJR : return JR { rsrc:rs }; 31.247 + fcJALR : return JALR { rsrc:rs, rdst:rd }; 31.248 + default : return ILLEGAL; 31.249 + endcase 31.250 + 31.251 + opRT : 31.252 + case ( rt ) 31.253 + rtBLTZ : return BLTZ { rsrc:rs, offset:imm }; 31.254 + rtBGEZ : return BGEZ { rsrc:rs, offset:imm }; 31.255 + default : return ILLEGAL; 31.256 + endcase 31.257 + 31.258 + opRS : 31.259 + case ( rs ) 31.260 + rsMFC0 : return MFC0 { rdst:rt, cop0src:rd }; 31.261 + rsMTC0 : return MTC0 { rsrc:rt, cop0dst:rd }; 31.262 + default : return ILLEGAL; 31.263 + endcase 31.264 + 31.265 + default : return ILLEGAL; 31.266 + 31.267 + endcase 31.268 + 31.269 + endfunction 31.270 + 31.271 +endinstance 31.272 + 31.273 +//---------------------------------------------------------------------- 31.274 +// Trace 31.275 +//---------------------------------------------------------------------- 31.276 + 31.277 +instance Traceable#(Instr); 31.278 + 31.279 + function Action traceTiny( String loc, String ttag, Instr inst ); 31.280 + case ( inst ) matches 31.281 + 31.282 + tagged LW .it : $fdisplay(stderr, " => %s:%s lw", loc, ttag ); 31.283 + tagged SW .it : $fdisplay(stderr, " => %s:%s sw", loc, ttag ); 31.284 + 31.285 + tagged ADDIU .it : $fdisplay(stderr, " => %s:%s addi", loc, ttag ); 31.286 + tagged SLTI .it : $fdisplay(stderr, " => %s:%s sli", loc, ttag ); 31.287 + tagged SLTIU .it : $fdisplay(stderr, " => %s:%s sliu", loc, ttag ); 31.288 + tagged ANDI .it : $fdisplay(stderr, " => %s:%s andi", loc, ttag ); 31.289 + tagged ORI .it : $fdisplay(stderr, " => %s:%s ori", loc, ttag ); 31.290 + tagged XORI .it : $fdisplay(stderr, " => %s:%s xori", loc, ttag ); 31.291 + tagged LUI .it : $fdisplay(stderr, " => %s:%s lui", loc, ttag ); 31.292 + 31.293 + tagged SLL .it : $fdisplay(stderr, " => %s:%s sll", loc, ttag ); 31.294 + tagged SRL .it : $fdisplay(stderr, " => %s:%s srl", loc, ttag ); 31.295 + tagged SRA .it : $fdisplay(stderr, " => %s:%s sra", loc, ttag ); 31.296 + tagged SLLV .it : $fdisplay(stderr, " => %s:%s sllv", loc, ttag ); 31.297 + tagged SRLV .it : $fdisplay(stderr, " => %s:%s srlv", loc, ttag ); 31.298 + tagged SRAV .it : $fdisplay(stderr, " => %s:%s srav", loc, ttag ); 31.299 + 31.300 + tagged ADDU .it : $fdisplay(stderr, " => %s:%s addu", loc, ttag ); 31.301 + tagged SUBU .it : $fdisplay(stderr, " => %s:%s subu", loc, ttag ); 31.302 + tagged AND .it : $fdisplay(stderr, " => %s:%s and", loc, ttag ); 31.303 + tagged OR .it : $fdisplay(stderr, " => %s:%s or", loc, ttag ); 31.304 + tagged XOR .it : $fdisplay(stderr, " => %s:%s xor", loc, ttag ); 31.305 + tagged NOR .it : $fdisplay(stderr, " => %s:%s nor", loc, ttag ); 31.306 + tagged SLT .it : $fdisplay(stderr, " => %s:%s slt", loc, ttag ); 31.307 + tagged SLTU .it : $fdisplay(stderr, " => %s:%s sltu", loc, ttag ); 31.308 + 31.309 + tagged J .it : $fdisplay(stderr, " => %s:%s j", loc, ttag ); 31.310 + tagged JAL .it : $fdisplay(stderr, " => %s:%s jal", loc, ttag ); 31.311 + tagged JR .it : $fdisplay(stderr, " => %s:%s jr", loc, ttag ); 31.312 + tagged JALR .it : $fdisplay(stderr, " => %s:%s jalr", loc, ttag ); 31.313 + tagged BEQ .it : $fdisplay(stderr, " => %s:%s beq", loc, ttag ); 31.314 + tagged BNE .it : $fdisplay(stderr, " => %s:%s bne", loc, ttag ); 31.315 + tagged BLEZ .it : $fdisplay(stderr, " => %s:%s blez", loc, ttag ); 31.316 + tagged BGTZ .it : $fdisplay(stderr, " => %s:%s bgtz", loc, ttag ); 31.317 + tagged BLTZ .it : $fdisplay(stderr, " => %s:%s bltz", loc, ttag ); 31.318 + tagged BGEZ .it : $fdisplay(stderr, " => %s:%s bgez", loc, ttag ); 31.319 + 31.320 + tagged MFC0 .it : $fdisplay(stderr, " => %s:%s mfc0", loc, ttag ); 31.321 + tagged MTC0 .it : $fdisplay(stderr, " => %s:%s mtc0", loc, ttag ); 31.322 + 31.323 + tagged ILLEGAL : $fdisplay(stderr, " => %s:%s ill", loc, ttag ); 31.324 + 31.325 + endcase 31.326 + endfunction 31.327 + 31.328 + function Action traceFull( String loc, String ttag, Instr inst ); 31.329 + case ( inst ) matches 31.330 + 31.331 + tagged LW .it : $fdisplay(stderr, " => %s:%s lw r%0d, 0x%x(r%0d)", loc, ttag, it.rdst, it.offset, it.rbase ); 31.332 + tagged SW .it : $fdisplay(stderr, " => %s:%s sw r%0d, 0x%x(r%0d)", loc, ttag, it.rsrc, it.offset, it.rbase ); 31.333 + 31.334 + tagged ADDIU .it : $fdisplay(stderr, " => %s:%s addiu r%0d, r%0d, 0x%x", loc, ttag, it.rdst, it.rsrc, it.imm ); 31.335 + tagged SLTI .it : $fdisplay(stderr, " => %s:%s slti r%0d, r%0d, 0x%x", loc, ttag, it.rdst, it.rsrc, it.imm ); 31.336 + tagged SLTIU .it : $fdisplay(stderr, " => %s:%s sltiu r%0d, r%0d, 0x%x", loc, ttag, it.rdst, it.rsrc, it.imm ); 31.337 + tagged ANDI .it : $fdisplay(stderr, " => %s:%s andi r%0d, r%0d, 0x%x", loc, ttag, it.rdst, it.rsrc, it.imm ); 31.338 + tagged ORI .it : $fdisplay(stderr, " => %s:%s ori r%0d, r%0d, 0x%x", loc, ttag, it.rdst, it.rsrc, it.imm ); 31.339 + tagged XORI .it : $fdisplay(stderr, " => %s:%s xori r%0d, r%0d, 0x%x", loc, ttag, it.rdst, it.rsrc, it.imm ); 31.340 + tagged LUI .it : $fdisplay(stderr, " => %s:%s lui r%0d, 0x%x", loc, ttag, it.rdst, it.imm ); 31.341 + 31.342 + tagged SLL .it : $fdisplay(stderr, " => %s:%s sll r%0d, r%0d, %0d", loc, ttag, it.rdst, it.rsrc, it.shamt ); 31.343 + tagged SRL .it : $fdisplay(stderr, " => %s:%s srl r%0d, r%0d, %0d", loc, ttag, it.rdst, it.rsrc, it.shamt ); 31.344 + tagged SRA .it : $fdisplay(stderr, " => %s:%s sra r%0d, r%0d, %0d", loc, ttag, it.rdst, it.rsrc, it.shamt ); 31.345 + tagged SLLV .it : $fdisplay(stderr, " => %s:%s sllv r%0d, r%0d, r%0d", loc, ttag, it.rdst, it.rsrc, it.rshamt ); 31.346 + tagged SRLV .it : $fdisplay(stderr, " => %s:%s srlv r%0d, r%0d, r%0d", loc, ttag, it.rdst, it.rsrc, it.rshamt ); 31.347 + tagged SRAV .it : $fdisplay(stderr, " => %s:%s srav r%0d, r%0d, r%0d", loc, ttag, it.rdst, it.rsrc, it.rshamt ); 31.348 + 31.349 + tagged ADDU .it : $fdisplay(stderr, " => %s:%s addu r%0d, r%0d, r%0d", loc, ttag, it.rdst, it.rsrc1, it.rsrc2 ); 31.350 + tagged SUBU .it : $fdisplay(stderr, " => %s:%s subu r%0d, r%0d, r%0d", loc, ttag, it.rdst, it.rsrc1, it.rsrc2 ); 31.351 + tagged AND .it : $fdisplay(stderr, " => %s:%s and r%0d, r%0d, r%0d", loc, ttag, it.rdst, it.rsrc1, it.rsrc2 ); 31.352 + tagged OR .it : $fdisplay(stderr, " => %s:%s or r%0d, r%0d, r%0d", loc, ttag, it.rdst, it.rsrc1, it.rsrc2 ); 31.353 + tagged XOR .it : $fdisplay(stderr, " => %s:%s xor r%0d, r%0d, r%0d", loc, ttag, it.rdst, it.rsrc1, it.rsrc2 ); 31.354 + tagged NOR .it : $fdisplay(stderr, " => %s:%s nor r%0d, r%0d, r%0d", loc, ttag, it.rdst, it.rsrc1, it.rsrc2 ); 31.355 + tagged SLT .it : $fdisplay(stderr, " => %s:%s slt r%0d, r%0d, r%0d", loc, ttag, it.rdst, it.rsrc1, it.rsrc2 ); 31.356 + tagged SLTU .it : $fdisplay(stderr, " => %s:%s sltu r%0d, r%0d, r%0d", loc, ttag, it.rdst, it.rsrc1, it.rsrc2 ); 31.357 + 31.358 + tagged J .it : $fdisplay(stderr, " => %s:%s j 0x%x", loc, ttag, it.target ); 31.359 + tagged JAL .it : $fdisplay(stderr, " => %s:%s jal 0x%x", loc, ttag, it.target ); 31.360 + tagged JR .it : $fdisplay(stderr, " => %s:%s jr r%0d", loc, ttag, it.rsrc ); 31.361 + tagged JALR .it : $fdisplay(stderr, " => %s:%s jalr r%0d", loc, ttag, it.rsrc ); 31.362 + tagged BEQ .it : $fdisplay(stderr, " => %s:%s beq r%0d, r%0d, 0x%x", loc, ttag, it.rsrc1, it.rsrc2, it.offset ); 31.363 + tagged BNE .it : $fdisplay(stderr, " => %s:%s bne r%0d, r%0d, 0x%x", loc, ttag, it.rsrc1, it.rsrc2, it.offset ); 31.364 + tagged BLEZ .it : $fdisplay(stderr, " => %s:%s blez r%0d, 0x%x", loc, ttag, it.rsrc, it.offset ); 31.365 + tagged BGTZ .it : $fdisplay(stderr, " => %s:%s bgtz r%0d, 0x%x", loc, ttag, it.rsrc, it.offset ); 31.366 + tagged BLTZ .it : $fdisplay(stderr, " => %s:%s bltz r%0d, 0x%x", loc, ttag, it.rsrc, it.offset ); 31.367 + tagged BGEZ .it : $fdisplay(stderr, " => %s:%s bgez r%0d, 0x%x", loc, ttag, it.rsrc, it.offset ); 31.368 + 31.369 + tagged MFC0 .it : $fdisplay(stderr, " => %s:%s mfc0 r%0d, cpr%0d", loc, ttag, it.rdst, it.cop0src ); 31.370 + tagged MTC0 .it : $fdisplay(stderr, " => %s:%s mtc0 r%0d, cpr%0d", loc, ttag, it.rsrc, it.cop0dst ); 31.371 + 31.372 + tagged ILLEGAL : $fdisplay(stderr, " => %s:%s illegal instruction", loc, ttag ); 31.373 + 31.374 + endcase 31.375 + endfunction 31.376 + 31.377 +endinstance 31.378 +
32.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 32.2 +++ b/modules/bluespec/Pygar/core/Processor.bsv Fri Apr 23 02:32:05 2010 -0400 32.3 @@ -0,0 +1,590 @@ 32.4 +/// The MIT License 32.5 + 32.6 +// Copyright (c) 2009 Massachusetts Institute of Technology 32.7 + 32.8 +// Permission is hereby granted, free of charge, to any person obtaining a copy 32.9 +// of this software and associated documentation files (the "Software"), to deal 32.10 +// in the Software without restriction, including without limitation the rights 32.11 +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 32.12 +// copies of the Software, and to permit persons to whom the Software is 32.13 +// furnished to do so, subject to the following conditions: 32.14 + 32.15 +// The above copyright notice and this permission notice shall be included in 32.16 +// all copies or substantial portions of the Software. 32.17 + 32.18 +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 32.19 +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 32.20 +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 32.21 +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 32.22 +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 32.23 +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 32.24 +// THE SOFTWARE. 32.25 + 32.26 +import Connectable::*; 32.27 +import GetPut::*; 32.28 +import ClientServer::*; 32.29 +import RegFile::*; 32.30 + 32.31 +import FIFO::*; 32.32 +import FIFOF::*; 32.33 +import SFIFO::*; 32.34 +import RWire::*; 32.35 + 32.36 +import BFIFO::*; 32.37 +import MemTypes::*; 32.38 +import ProcTypes::*; 32.39 +import BRegFile::*; 32.40 +import BranchPred::*; 32.41 +//import PathTypes::*; This is only there to force the debugging 32.42 + 32.43 +import Trace::*; 32.44 + 32.45 +//AWB includes 32.46 +`include "asim/provides/low_level_platform_interface.bsh" 32.47 +`include "asim/provides/soft_connections.bsh" 32.48 +`include "asim/provides/common_services.bsh" 32.49 + 32.50 +// Local includes 32.51 +`include "asim/provides/processor_library.bsh" 32.52 +`include "asim/rrr/remote_server_stub_PROCESSORSYSTEMRRR.bsh" 32.53 +`include "asim/provides/common_services.bsh" 32.54 +`include "asim/dict/STATS_PROCESSOR.bsh" 32.55 + 32.56 +interface ProcStats; 32.57 + interface Get#(Stat) num_cycles; 32.58 + interface Get#(Stat) num_inst; 32.59 +endinterface 32.60 + 32.61 +interface CPUToHost; 32.62 + method Bit#(32) cpuToHost(int req); 32.63 +endinterface 32.64 + 32.65 +interface Proc; 32.66 + 32.67 + // Interface from processor to caches 32.68 + interface Client#(DataReq,DataResp) dmem_client; 32.69 + interface Client#(InstReq,InstResp) imem_client; 32.70 + 32.71 + // Interface for enabling/disabling statistics on the rest of the core 32.72 + interface Get#(Bool) statsEn_get; 32.73 + 32.74 + // Interface for collecting statistics. 32.75 + interface ProcStats stats; 32.76 + 32.77 + // Interface to host 32.78 + interface CPUToHost tohost; 32.79 + 32.80 +endinterface 32.81 + 32.82 + 32.83 +typedef enum { PCgen, Exec, Writeback } Stage deriving(Eq,Bits); 32.84 + 32.85 +//----------------------------------------------------------- 32.86 +// Register file module 32.87 +//----------------------------------------------------------- 32.88 + 32.89 +interface BRFile; 32.90 + method Action wr( Rindx rindx, Bit#(32) data ); 32.91 + method Bit#(32) rd1( Rindx rindx ); 32.92 + method Bit#(32) rd2( Rindx rindx ); 32.93 +endinterface 32.94 + 32.95 +module mkBRFile( BRFile ); 32.96 + 32.97 + RegFile#(Rindx,Bit#(32)) rfile <- mkBRegFile(); 32.98 + 32.99 + method Action wr( Rindx rindx, Bit#(32) data ); 32.100 + rfile.upd( rindx, data ); 32.101 + endmethod 32.102 + 32.103 + method Bit#(32) rd1( Rindx rindx ); 32.104 + return ( rindx == 0 ) ? 0 : rfile.sub(rindx); 32.105 + endmethod 32.106 + 32.107 + method Bit#(32) rd2( Rindx rindx ); 32.108 + return ( rindx == 0 ) ? 0 : rfile.sub(rindx); 32.109 + endmethod 32.110 + 32.111 +endmodule 32.112 + 32.113 +//----------------------------------------------------------- 32.114 +// Helper functions 32.115 +//----------------------------------------------------------- 32.116 + 32.117 +function Bit#(32) slt( Bit#(32) val1, Bit#(32) val2 ); 32.118 + return zeroExtend( pack( signedLT(val1,val2) ) ); 32.119 +endfunction 32.120 + 32.121 +function Bit#(32) sltu( Bit#(32) val1, Bit#(32) val2 ); 32.122 + return zeroExtend( pack( val1 < val2 ) ); 32.123 +endfunction 32.124 + 32.125 +function Bit#(32) rshft( Bit#(32) val ); 32.126 + return zeroExtend(val[4:0]); 32.127 +endfunction 32.128 + 32.129 + 32.130 +//----------------------------------------------------------- 32.131 +// Find funct for wbQ 32.132 +//----------------------------------------------------------- 32.133 +function Bool findwbf(Rindx fVal, WBResult cmpVal); 32.134 + case (cmpVal) matches 32.135 + tagged WB_ALU {data:.res, dest:.rd} : 32.136 + return (fVal == rd); 32.137 + tagged WB_Load .rd : 32.138 + return (fVal == rd); 32.139 + tagged WB_Store .st : 32.140 + return False; 32.141 + tagged WB_Host .x : 32.142 + return False; 32.143 + endcase 32.144 +endfunction 32.145 + 32.146 + 32.147 +//----------------------------------------------------------- 32.148 +// Stall funct for wbQ 32.149 +//----------------------------------------------------------- 32.150 +function Bool stall(Instr inst, SFIFO#(WBResult, Rindx) f); 32.151 + case (inst) matches 32.152 + // -- Memory Ops ------------------------------------------------ 32.153 + tagged LW .it : 32.154 + return f.find(it.rbase); 32.155 + tagged SW {rsrc:.dreg, rbase:.addr, offset:.o} : 32.156 + return (f.find(addr) || f.find2(dreg)); 32.157 + 32.158 + // -- Simple Ops ------------------------------------------------ 32.159 + tagged ADDIU .it : return f.find(it.rsrc); 32.160 + tagged SLTI .it : return f.find(it.rsrc); 32.161 + tagged SLTIU .it : return f.find(it.rsrc); 32.162 + tagged ANDI .it : return f.find(it.rsrc); 32.163 + tagged ORI .it : return f.find(it.rsrc); 32.164 + tagged XORI .it : return f.find(it.rsrc); 32.165 + 32.166 + tagged LUI .it : return f.find(it.rdst); //this rds/wrs itself 32.167 + tagged SLL .it : return f.find(it.rsrc); 32.168 + tagged SRL .it : return f.find(it.rsrc); 32.169 + tagged SRA .it : return f.find(it.rsrc); 32.170 + tagged SLLV .it : return (f.find(it.rsrc) || f.find(it.rshamt)); 32.171 + tagged SRLV .it : return (f.find(it.rsrc) || f.find(it.rshamt)); 32.172 + tagged SRAV .it : return (f.find(it.rsrc) || f.find(it.rshamt)); 32.173 + tagged ADDU .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2)); 32.174 + tagged SUBU .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2)); 32.175 + tagged AND .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2)); 32.176 + tagged OR .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2)); 32.177 + tagged XOR .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2)); 32.178 + tagged NOR .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2)); 32.179 + tagged SLT .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2)); 32.180 + tagged SLTU .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2)); 32.181 + 32.182 + 32.183 + // -- Branches -------------------------------------------------- 32.184 + 32.185 + tagged BLEZ .it : return (f.find(it.rsrc)); 32.186 + tagged BGTZ .it : return (f.find(it.rsrc)); 32.187 + tagged BLTZ .it : return (f.find(it.rsrc)); 32.188 + tagged BGEZ .it : return (f.find(it.rsrc)); 32.189 + tagged BEQ .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2)); 32.190 + tagged BNE .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2)); 32.191 + 32.192 + // -- Jumps ----------------------------------------------------- 32.193 + 32.194 + tagged J .it : return False; 32.195 + tagged JR .it : return f.find(it.rsrc); 32.196 + tagged JALR .it : return f.find(it.rsrc); 32.197 + tagged JAL .it : return False; 32.198 + 32.199 + // -- Cop0 ------------------------------------------------------ 32.200 + 32.201 + tagged MTC0 .it : return f.find(it.rsrc); 32.202 + tagged MFC0 .it : return False; 32.203 + 32.204 + // -- Illegal --------------------------------------------------- 32.205 + 32.206 + default : return False; 32.207 + 32.208 + endcase 32.209 +endfunction 32.210 +//----------------------------------------------------------- 32.211 +// Reference processor 32.212 +//----------------------------------------------------------- 32.213 + 32.214 + 32.215 +//(* doc = "synthesis attribute ram_style mkProc distributed;" *) 32.216 +//(* synthesize *) 32.217 + 32.218 +module [CONNECTED_MODULE] mkProc( Proc ); 32.219 + 32.220 + //----------------------------------------------------------- 32.221 + // Debug port 32.222 + 32.223 + ServerStub_PROCESSORSYSTEMRRR server_stub <- mkServerStub_PROCESSORSYSTEMRRR(); 32.224 + 32.225 + 32.226 + //----------------------------------------------------------- 32.227 + // State 32.228 + 32.229 + // Standard processor state 32.230 + 32.231 + Reg#(Addr) pc <- mkReg(32'h00001000); 32.232 + Reg#(Epoch) epoch <- mkReg(0); 32.233 + Reg#(Stage) stage <- mkReg(PCgen); 32.234 + BRFile rf <- mkBRFile; 32.235 + 32.236 + // Branch Prediction 32.237 + BranchPred bp <- mkBranchPred(); 32.238 + FIFO#(PCStat) execpc <- mkLFIFO(); 32.239 + 32.240 + // Pipelines 32.241 + FIFO#(PCStat) pcQ <-mkSizedFIFO(3); 32.242 + SFIFO#(WBResult, Rindx) wbQ <-mkSFIFO(findwbf); 32.243 + 32.244 + Reg#(Bit#(32)) cp0_tohost <- mkReg(0); 32.245 + Reg#(Bit#(32)) cp0_fromhost <- mkReg(0); 32.246 + Reg#(Bool) cp0_statsEn <- mkReg(False); 32.247 + 32.248 + // Memory request/response state 32.249 + 32.250 + FIFO#(InstReq) instReqQ <- mkBFIFO1(); 32.251 + FIFO#(InstResp) instRespQ <- mkFIFO(); 32.252 + 32.253 + FIFO#(DataReq) dataReqQ <- mkBFIFO1(); 32.254 + FIFO#(DataResp) dataRespQ <- mkFIFO(); 32.255 + 32.256 + // Statistics state 32.257 + Reg#(Stat) num_cycles <- mkReg(0); 32.258 + Reg#(Stat) num_inst <- mkReg(0); 32.259 + 32.260 + //Or: 32.261 + // Statistics state 32.262 + //STAT num_cycles <- mkStatCounter(`STATS_PROCESSOR_CYCLE_COUNT); 32.263 + //STAT num_inst <- mkStatCounter(`STATS_PROCESSOR_INST_COUNT); 32.264 + 32.265 + //----------------------------------------------------------- 32.266 + // Rules 32.267 + 32.268 + (* descending_urgency = "exec, pcgen" *) 32.269 + rule pcgen; //( stage == PCgen ); 32.270 + let pc_plus4 = pc + 4; 32.271 + 32.272 + traceTiny("mkProc", "pc",pc); 32.273 + traceTiny("mkProc", "pcgen","P"); 32.274 + instReqQ.enq( LoadReq{ addr:pc, tag:epoch} ); 32.275 + 32.276 + let next_pc = bp.get(pc); 32.277 + if (next_pc matches tagged Valid .npc) 32.278 + begin 32.279 + pcQ.enq(PCStat {qpc:pc, qnxtpc:npc, qepoch:epoch}); 32.280 + pc <= npc; 32.281 + end 32.282 + else 32.283 + begin 32.284 + pcQ.enq(PCStat {qpc:pc, qnxtpc:pc_plus4, qepoch:epoch}); 32.285 + pc <= pc_plus4; 32.286 + end 32.287 + 32.288 + endrule 32.289 + 32.290 + rule discard (instRespQ.first() matches tagged LoadResp .ld 32.291 + &&& ld.tag != epoch); 32.292 + traceTiny("mkProc", "stage", "D"); 32.293 + instRespQ.deq(); 32.294 + endrule 32.295 + 32.296 + (* conflict_free = "exec, writeback" *) 32.297 + rule exec (instRespQ.first() matches tagged LoadResp.ld 32.298 + &&& (ld.tag == epoch) 32.299 + &&& unpack(ld.data) matches .inst 32.300 + &&& !stall(inst, wbQ)); 32.301 + 32.302 + // Some abbreviations 32.303 + let sext = signExtend; 32.304 + let zext = zeroExtend; 32.305 + let sra = signedShiftRight; 32.306 + 32.307 + // Get the instruction 32.308 + 32.309 + instRespQ.deq(); 32.310 + Instr inst 32.311 + = case ( instRespQ.first() ) matches 32.312 + tagged LoadResp .ld : return unpack(ld.data); 32.313 + tagged StoreResp .st : return ?; 32.314 + endcase; 32.315 + 32.316 + // Get the PC info 32.317 + let instrpc = pcQ.first().qpc; 32.318 + let pc_plus4 = instrpc + 4; 32.319 + 32.320 + Bool branchTaken = False; 32.321 + Addr newPC = pc_plus4; 32.322 + 32.323 + // Tracing 32.324 + traceTiny("mkProc", "exec","X"); 32.325 + traceTiny("mkProc", "exInstTiny",inst); 32.326 + traceFull("mkProc", "exInstFull",inst); 32.327 + 32.328 + case ( inst ) matches 32.329 + 32.330 + // -- Memory Ops ------------------------------------------------ 32.331 + 32.332 + tagged LW .it : 32.333 + begin 32.334 + Addr addr = rf.rd1(it.rbase) + sext(it.offset); 32.335 + dataReqQ.enq( LoadReq{ addr:addr, tag:zeroExtend(it.rdst) } ); 32.336 + wbQ.enq(tagged WB_Load it.rdst); 32.337 + end 32.338 + 32.339 + tagged SW .it : 32.340 + begin 32.341 + Addr addr = rf.rd1(it.rbase) + sext(it.offset); 32.342 + dataReqQ.enq( StoreReq{ tag:0, addr:addr, data:rf.rd2(it.rsrc) } ); 32.343 + wbQ.enq(tagged WB_Store); 32.344 + end 32.345 + 32.346 + // -- Simple Ops ------------------------------------------------ 32.347 + 32.348 + tagged ADDIU .it : 32.349 + begin 32.350 + Bit#(32) result = rf.rd1(it.rsrc) + sext(it.imm); 32.351 + wbQ.enq(tagged WB_ALU {data:result, dest:it.rdst}); 32.352 + end 32.353 + tagged SLTI .it : wbQ.enq(tagged WB_ALU {dest:it.rdst, data:slt( rf.rd1(it.rsrc), sext(it.imm) )}); 32.354 + tagged SLTIU .it : wbQ.enq(tagged WB_ALU {dest:it.rdst, data:sltu( rf.rd1(it.rsrc), sext(it.imm) ) }); 32.355 + tagged ANDI .it : 32.356 + begin 32.357 + Bit#(32) zext_it_imm = zext(it.imm); 32.358 + wbQ.enq(tagged WB_ALU {dest:it.rdst, data:(rf.rd1(it.rsrc) & zext_it_imm)} ); 32.359 + end 32.360 + tagged ORI .it : 32.361 + begin 32.362 + Bit#(32) zext_it_imm = zext(it.imm); 32.363 + wbQ.enq(tagged WB_ALU {dest:it.rdst, data:(rf.rd1(it.rsrc) | zext_it_imm)} ); 32.364 + end 32.365 + tagged XORI .it : 32.366 + begin 32.367 + Bit#(32) zext_it_imm = zext(it.imm); 32.368 + wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc) ^ zext_it_imm )}); 32.369 + end 32.370 + tagged LUI .it : 32.371 + begin 32.372 + Bit#(32) zext_it_imm = zext(it.imm); 32.373 + wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(zext_it_imm << 32'd16) }); 32.374 + end 32.375 + 32.376 + tagged SLL .it : 32.377 + begin 32.378 + Bit#(32) zext_it_shamt = zext(it.shamt); 32.379 + wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc) << zext_it_shamt )} ); 32.380 + end 32.381 + tagged SRL .it : 32.382 + begin 32.383 + Bit#(32) zext_it_shamt = zext(it.shamt); 32.384 + wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc) >> zext_it_shamt )}); 32.385 + end 32.386 + tagged SRA .it : 32.387 + begin 32.388 + Bit#(32) zext_it_shamt = zext(it.shamt); 32.389 + wbQ.enq(tagged WB_ALU {dest: it.rdst, data:sra( rf.rd1(it.rsrc), zext_it_shamt )}); 32.390 + end 32.391 + tagged SLLV .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc) << rshft(rf.rd2(it.rshamt)) )}); 32.392 + tagged SRLV .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc) >> rshft(rf.rd2(it.rshamt)) )} ); 32.393 + tagged SRAV .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:sra( rf.rd1(it.rsrc), rshft(rf.rd2(it.rshamt)) ) }); 32.394 + tagged ADDU .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc1) + rf.rd2(it.rsrc2) )} ); 32.395 + tagged SUBU .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc1) - rf.rd2(it.rsrc2) )} ); 32.396 + tagged AND .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc1) & rf.rd2(it.rsrc2) )} ); 32.397 + tagged OR .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc1) | rf.rd2(it.rsrc2) )} ); 32.398 + tagged XOR .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc1) ^ rf.rd2(it.rsrc2) )} ); 32.399 + tagged NOR .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(~(rf.rd1(it.rsrc1) | rf.rd2(it.rsrc2)) )} ); 32.400 + tagged SLT .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:slt( rf.rd1(it.rsrc1), rf.rd2(it.rsrc2) ) }); 32.401 + tagged SLTU .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:sltu( rf.rd1(it.rsrc1), rf.rd2(it.rsrc2) ) }); 32.402 + 32.403 + // -- Branches -------------------------------------------------- 32.404 + 32.405 + tagged BLEZ .it : 32.406 + if ( signedLE( rf.rd1(it.rsrc), 0 ) ) 32.407 + begin 32.408 + newPC = pc_plus4 + (sext(it.offset) << 2); 32.409 + branchTaken = True; 32.410 + end 32.411 + 32.412 + tagged BGTZ .it : 32.413 + if ( signedGT( rf.rd1(it.rsrc), 0 ) ) 32.414 + begin 32.415 + newPC = pc_plus4 + (sext(it.offset) << 2); 32.416 + branchTaken = True; 32.417 + end 32.418 + 32.419 + tagged BLTZ .it : 32.420 + if ( signedLT( rf.rd1(it.rsrc), 0 ) ) 32.421 + begin 32.422 + newPC = pc_plus4 + (sext(it.offset) << 2); 32.423 + branchTaken = True; 32.424 + end 32.425 + 32.426 + tagged BGEZ .it : 32.427 + if ( signedGE( rf.rd1(it.rsrc), 0 ) ) 32.428 + begin 32.429 + newPC = pc_plus4 + (sext(it.offset) << 2); 32.430 + branchTaken = True; 32.431 + end 32.432 + 32.433 + tagged BEQ .it : 32.434 + if ( rf.rd1(it.rsrc1) == rf.rd2(it.rsrc2) ) 32.435 + begin 32.436 + newPC = pc_plus4 + (sext(it.offset) << 2); 32.437 + branchTaken = True; 32.438 + end 32.439 + 32.440 + tagged BNE .it : 32.441 + if ( rf.rd1(it.rsrc1) != rf.rd2(it.rsrc2) ) 32.442 + begin 32.443 + newPC = pc_plus4 + (sext(it.offset) << 2); 32.444 + branchTaken = True; 32.445 + end 32.446 + 32.447 + // -- Jumps ----------------------------------------------------- 32.448 + 32.449 + tagged J .it : 32.450 + begin 32.451 + newPC = { pc_plus4[31:28], it.target, 2'b0 }; 32.452 + branchTaken = True; 32.453 + end 32.454 + 32.455 + tagged JR .it : 32.456 + begin 32.457 + newPC = rf.rd1(it.rsrc); 32.458 + branchTaken = True; 32.459 + end 32.460 + 32.461 + tagged JAL .it : 32.462 + begin 32.463 + wbQ.enq(tagged WB_ALU {dest:31, data:pc_plus4 }); 32.464 + newPC = { pc_plus4[31:28], it.target, 2'b0 }; 32.465 + branchTaken = True; 32.466 + end 32.467 + 32.468 + tagged JALR .it : 32.469 + begin 32.470 + wbQ.enq(tagged WB_ALU {dest:it.rdst, data:pc_plus4 }); 32.471 + newPC = rf.rd1(it.rsrc); 32.472 + branchTaken = True; 32.473 + end 32.474 + 32.475 + // -- Cop0 ------------------------------------------------------ 32.476 + 32.477 + tagged MTC0 .it : 32.478 + begin 32.479 + case ( it.cop0dst ) 32.480 + 5'd10 : cp0_statsEn <= unpack(truncate(rf.rd1(it.rsrc))); 32.481 + 5'd21 : cp0_tohost <= truncate(rf.rd1(it.rsrc)); 32.482 + default : 32.483 + $display( " RTL-ERROR : %m : Illegal MTC0 cop0dst register!" ); 32.484 + endcase 32.485 + wbQ.enq(tagged WB_Host 0); //no idea wwhat this actually should be. 32.486 + end 32.487 + 32.488 +//this is host stuff? 32.489 + tagged MFC0 .it : 32.490 + begin 32.491 + case ( it.cop0src ) 32.492 + // not actually an ALU instruction but don't have the format otherwise 32.493 + 5'd10 : wbQ.enq(tagged WB_ALU {dest:it.rdst, data:zext(pack(cp0_statsEn)) }); 32.494 + 5'd20 : wbQ.enq(tagged WB_ALU {dest:it.rdst, data:cp0_fromhost }); 32.495 + 5'd21 : wbQ.enq(tagged WB_ALU {dest:it.rdst, data:cp0_tohost }); 32.496 + default : 32.497 + $display( " RTL-ERROR : %m : Illegal MFC0 cop0src register!" ); 32.498 + endcase 32.499 + end 32.500 + 32.501 + // -- Illegal --------------------------------------------------- 32.502 + 32.503 + default : 32.504 + $display( " RTL-ERROR : %m : Illegal instruction !" ); 32.505 + 32.506 + endcase 32.507 + 32.508 +//evaluate branch prediction 32.509 + Addr ppc = pcQ.first().qnxtpc; //predicted branch 32.510 + if (ppc != newPC) //prediction wrong 32.511 + begin 32.512 + epoch <= pcQ.first().qepoch + 1; 32.513 + bp.upd(instrpc, newPC); //update branch predictor 32.514 + pcQ.clear(); 32.515 + pc <= newPC; 32.516 + end 32.517 + else 32.518 + pcQ.deq(); 32.519 + 32.520 + if ( cp0_statsEn ) 32.521 + num_inst <= num_inst+1; 32.522 + 32.523 + endrule 32.524 + 32.525 + rule writeback; // ( stage == Writeback ); 32.526 + traceTiny("mkProc", "writeback","W"); 32.527 + 32.528 + 32.529 + // get what to do off the writeback queue 32.530 + wbQ.deq(); 32.531 + case (wbQ.first()) matches 32.532 + tagged WB_ALU {data:.res, dest:.rdst} : rf.wr(rdst, res); 32.533 + tagged WB_Load .regWr : 32.534 + begin 32.535 + dataRespQ.deq(); 32.536 + if (dataRespQ.first() matches tagged LoadResp .ld) 32.537 + rf.wr(truncate(ld.tag), ld.data); // no need to use Rindx from queue? Duplicate? 32.538 + end 32.539 + tagged WB_Store : dataRespQ.deq(); 32.540 + tagged WB_Host .dat : noAction; 32.541 + endcase 32.542 + 32.543 + endrule 32.544 + 32.545 + rule inc_num_cycles; 32.546 + if ( cp0_statsEn ) 32.547 + num_cycles <= num_cycles+1; 32.548 + endrule 32.549 +// THis rule breaks things 32.550 +// rule handleCPUToHost; 32.551 +// let req <- server_stub.acceptRequest_ReadCPUToHost(); 32.552 +// case (req) 32.553 +// 0: server_stub.sendResponse_ReadCPUToHost(cp0_tohost); 32.554 +// 1: server_stub.sendResponse_ReadCPUToHost(pc); 32.555 +// 2: server_stub.sendResponse_ReadCPUToHost(zeroExtend(pack(stage))); 32.556 +// endcase 32.557 +// endrule 32.558 +//----------------------------------------------------------- 32.559 +// My Adds 32.560 +//----------------------------------------------------------- 32.561 + 32.562 + //----------------------------------------------------------- 32.563 + // Methods 32.564 + 32.565 + interface Client imem_client; 32.566 + interface Get request = toGet(instReqQ); 32.567 + interface Put response = toPut(instRespQ); 32.568 + endinterface 32.569 + 32.570 + interface Client dmem_client; 32.571 + interface Get request = toGet(dataReqQ); 32.572 + interface Put response = toPut(dataRespQ); 32.573 + endinterface 32.574 + 32.575 + interface Get statsEn_get = toGet(asReg(cp0_statsEn)); 32.576 + 32.577 + interface ProcStats stats; 32.578 + interface Get num_cycles = toGet(asReg(num_cycles)); 32.579 + interface Get num_inst = toGet(asReg(num_inst)); 32.580 + endinterface 32.581 + 32.582 + interface CPUToHost tohost; 32.583 + method Bit#(32) cpuToHost(int req); 32.584 + return (case (req) 32.585 + 0: cp0_tohost; 32.586 + 1: pc; 32.587 + 2: zeroExtend(pack(stage)); 32.588 + endcase); 32.589 + endmethod 32.590 + endinterface 32.591 + 32.592 +endmodule 32.593 +
33.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 33.2 +++ b/modules/bluespec/Pygar/core/Processor.dic Fri Apr 23 02:32:05 2010 -0400 33.3 @@ -0,0 +1,2 @@ 33.4 +def STATS.PROCESSOR.CYCLE_COUNT "PROCESSOR: Cycle count: "; 33.5 +def STATS.PROCESSOR.INST_COUNT "PROCESSOR: Instruction count: ";
34.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 34.2 +++ b/modules/bluespec/Pygar/core/RoutingTable.bsv Fri Apr 23 02:32:05 2010 -0400 34.3 @@ -0,0 +1,52 @@ 34.4 +import Trace::*; 34.5 +import Vector::*; 34.6 +import PathTypes::*; 34.7 + 34.8 +function FullPath genEmptyPaths (Integer a) ; 34.9 + FullPath empt = FullPath {voice: fromInteger(a), startAddr: 0, route: emptyCore}; 34.10 + return (empt); 34.11 +endfunction 34.12 + 34.13 +interface RoutingTable; 34.14 + method FullPath getPath(Integer voiceNo); 34.15 +endinterface 34.16 + 34.17 +module mkRoutingTable(RoutingTable); 34.18 + Vector#(`MAX_VOICES, FullPath) routeTable = genWith(genEmptyPaths); 34.19 + 34.20 + function CorePath updateVoice0(Integer len, Vector#(len, PathId) cores, CorePath inPath); 34.21 + CorePath outPath = inPath; 34.22 + for(Integer i = 0; i < len; i = i+1) 34.23 + inPath[i] = cores[i]; 34.24 + return outPath; 34.25 + endfunction 34.26 + 34.27 + //demonstrate two ways of building the routeTable 34.28 + routeTable[0].startAddr = 0; //where is this really going to come from? 34.29 + routeTable[0].route[0] = 3; 34.30 + routeTable[0].route[1] = mixerId; 34.31 + //rest are already initialized toinvalid 34.32 + 34.33 + // or if you just want to update a straight list, this longer emplate works. 34.34 + function CorePath createVoice1Route(); 34.35 + CorePath outPath = emptyCore; 34.36 + 34.37 + Integer len = 3; 34.38 + PathId route[len] = {1, 2, mixerId}; //route to update 34.39 + 34.40 + for(Integer i = 0; i < len; i = i+1) 34.41 + outPath[i] = route[i]; 34.42 + 34.43 + return outPath; 34.44 + endfunction 34.45 + routeTable[1].route = createVoice1Route; 34.46 + routeTable[1].startAddr = 0; 34.47 + 34.48 + //remaining voices are all initialized to empty. 34.49 + 34.50 + method FullPath getPath(Integer a); 34.51 + return routeTable[a]; 34.52 + endmethod 34.53 + 34.54 +endmodule 34.55 +
35.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 35.2 +++ b/modules/bluespec/Pygar/core/SFIFO.bsv Fri Apr 23 02:32:05 2010 -0400 35.3 @@ -0,0 +1,213 @@ 35.4 + 35.5 +import FIFO::*; 35.6 +import ConfigReg::*; 35.7 +import RWire::*; 35.8 + 35.9 +import List::*; 35.10 +import Monad::*; 35.11 + 35.12 +interface SFIFO#(type alpha_T, type search_T); 35.13 + method Action enq(alpha_T x); 35.14 + method Action deq(); 35.15 + method alpha_T first(); 35.16 + method Action clear(); 35.17 + method Bool find(search_T x); 35.18 + method Bool find2(search_T x); 35.19 + 35.20 +endinterface 35.21 + 35.22 +module mkSFIFO#(function Bool searchfunc(search_T s, alpha_T x)) (SFIFO#(alpha_T, search_T)) 35.23 + provisos 35.24 + (Bits#(alpha_T,asz)); 35.25 + 35.26 + Reg#(alpha_T) f0 <- mkConfigRegU(); 35.27 + Reg#(alpha_T) f1 <- mkConfigRegU(); 35.28 + 35.29 + Reg#(Bool) vf0 <- mkConfigReg(False); 35.30 + Reg#(Bool) vf1 <- mkConfigReg(False); 35.31 + 35.32 + PulseWire edge1 <- mkPulseWire(); 35.33 + 35.34 + method Action enq(alpha_T x) if (!(vf0 && vf1)); 35.35 + if (edge1 || !vf0)//empty or we're dequeueing 35.36 + begin 35.37 + vf0 <= True; //True 35.38 + vf1 <= False; 35.39 + f0 <= x; 35.40 + end 35.41 + else // !vf1 35.42 + begin 35.43 + vf1 <= True; 35.44 + f1 <= x; 35.45 + end 35.46 + endmethod 35.47 + 35.48 + method Action deq() if (vf0); 35.49 + edge1.send(); 35.50 + vf0 <= vf1; 35.51 + f0 <= f1; 35.52 + vf1 <= False; 35.53 + endmethod 35.54 + 35.55 + method alpha_T first() if(vf0); 35.56 + return (f0); 35.57 + endmethod 35.58 + 35.59 + method Action clear(); 35.60 + vf0 <= False; 35.61 + vf1 <= False; 35.62 + endmethod 35.63 + 35.64 + method Bool find(search_T sv); 35.65 + Bool nvf0 = edge1 ? False: vf0; 35.66 + Bool nvf1 = vf1; 35.67 + 35.68 + return (nvf0 && searchfunc(sv, f0) || 35.69 + nvf1 && searchfunc(sv, f1)); 35.70 + endmethod 35.71 + 35.72 + method Bool find2(search_T sv); 35.73 + Bool nvf0 = edge1 ? False: vf0; 35.74 + Bool nvf1 = vf1; 35.75 + 35.76 + return (nvf0 && searchfunc(sv, f0) || 35.77 + nvf1 && searchfunc(sv, f1)); 35.78 + endmethod 35.79 + 35.80 +endmodule 35.81 + 35.82 +module mkSFIFO1#(function Bool searchfunc(search_T s, alpha_T x)) (SFIFO#(alpha_T, search_T)) 35.83 + provisos 35.84 + (Bits#(alpha_T,asz), Eq#(alpha_T)); 35.85 + 35.86 + Reg#(alpha_T) f0 <- mkConfigRegU; 35.87 + 35.88 + Reg#(Bool) vf0 <- mkConfigReg(False); 35.89 + 35.90 + PulseWire edge1 <- mkPulseWire(); 35.91 + 35.92 + method Action enq(alpha_T x) if (!vf0); 35.93 + vf0 <= True; //True 35.94 + f0 <= x; 35.95 + endmethod 35.96 + 35.97 + method Action deq() if (vf0); 35.98 + edge1.send(); 35.99 + vf0 <= False; 35.100 + endmethod 35.101 + 35.102 + method alpha_T first() if(vf0); 35.103 + return (f0); 35.104 + endmethod 35.105 + 35.106 + method Action clear(); 35.107 + vf0 <= False; 35.108 + endmethod 35.109 + 35.110 + method Bool find(search_T sv); 35.111 + Bool nvf0 = edge1 ? False: vf0; 35.112 + 35.113 + return (nvf0 && searchfunc(sv, f0)); 35.114 + endmethod 35.115 + 35.116 + method Bool find2(search_T sv); 35.117 + Bool nvf0 = edge1 ? False: vf0; 35.118 + return (nvf0 && searchfunc(sv, f0)); 35.119 + endmethod 35.120 + 35.121 +endmodule 35.122 + 35.123 +module mkSizedSFIFOInternal#(Integer n, 35.124 + function Bool searchfunc1(search_T s, alpha_T x), 35.125 + function Bool searchfunc2(search_T s, alpha_T x)) (SFIFO#(alpha_T, search_T)) 35.126 + 35.127 + provisos ( Bits#(alpha_T,alpha_SZ) ); 35.128 + 35.129 + List#(Reg#(alpha_T)) registers <- replicateM(n, mkRegU); 35.130 + List#(Reg#(Bool)) valids <- replicateM(n, mkReg(False)); 35.131 + 35.132 + function Nat getNextFree (List#(Reg#(Bool)) vs); 35.133 + 35.134 + Nat res = fromInteger(n - 1); 35.135 + 35.136 + for (Integer x = n - 1; x > -1; x = x - 1) 35.137 + res = !vs[x]._read() ? fromInteger(x) : res; 35.138 + 35.139 + return res; 35.140 + 35.141 + endfunction 35.142 + 35.143 + function Bool notFull(); 35.144 + 35.145 + Bool full = True; 35.146 + 35.147 + for (Integer x = 0; x < n; x = x + 1) 35.148 + full = full && valids[x]._read(); 35.149 + 35.150 + return !full; 35.151 + 35.152 + endfunction 35.153 + 35.154 + method Action enq( alpha_T item ) if ( notFull() ); 35.155 + 35.156 + Nat k = getNextFree(valids); 35.157 + select(valids, k)._write(True); 35.158 + select(registers, k)._write(item); 35.159 + 35.160 + endmethod 35.161 + 35.162 + method Action deq() if ( valids[0]._read() ); 35.163 + 35.164 + for (Integer x = 0; x < (n-1); x = x + 1) 35.165 + begin 35.166 + 35.167 + (registers[x]) <= registers[x + 1]._read(); 35.168 + (valids[x]) <= valids[x + 1]._read(); 35.169 + 35.170 + end 35.171 + (valids[n-1]) <= False; 35.172 + endmethod 35.173 + 35.174 + method alpha_T first() if ( valids[0]._read() ); 35.175 + return registers[0]._read(); 35.176 + endmethod 35.177 + 35.178 + method Bool find(search_T sv); 35.179 + Bool res = False; 35.180 + 35.181 + for (Integer x = 0; x < n; x = x + 1) 35.182 + if ( valids[x]._read() && searchfunc1(sv, registers[x]._read()) ) 35.183 + res = True; 35.184 + 35.185 + return res; 35.186 + 35.187 + endmethod 35.188 + 35.189 + method Bool find2(search_T sv); 35.190 + Bool res = False; 35.191 + 35.192 + for (Integer x = 0; x < n; x = x + 1) 35.193 + if ( valids[x]._read() && searchfunc2(sv, registers[x]._read()) ) 35.194 + res = True; 35.195 + 35.196 + return res; 35.197 + 35.198 + endmethod 35.199 + 35.200 + method Action clear(); 35.201 + 35.202 + for (Integer x = 0; x < n; x = x + 1) 35.203 + (valids[x]) <= False; 35.204 + 35.205 + endmethod 35.206 + 35.207 +endmodule 35.208 + 35.209 +module mkSizedSFIFO#(Integer n, function Bool searchfunc(search_T s, alpha_T x)) (SFIFO#(alpha_T, search_T)) 35.210 + provisos 35.211 + (Bits#(alpha_T,asz)); 35.212 + 35.213 + let foo <- mkSizedSFIFOInternal(n, searchfunc, searchfunc); 35.214 + return foo; 35.215 + 35.216 +endmodule
36.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 36.2 +++ b/modules/bluespec/Pygar/core/Trace.bsv Fri Apr 23 02:32:05 2010 -0400 36.3 @@ -0,0 +1,92 @@ 36.4 + 36.5 +import ClientServer::*; 36.6 +import GetPut::*; 36.7 + 36.8 +//---------------------------------------------------------------------- 36.9 +// ToString typeclass 36.10 +//---------------------------------------------------------------------- 36.11 + 36.12 +typeclass Traceable#( type item_t ); 36.13 + function Action traceTiny( String loc, String traceTag, item_t item ); 36.14 + function Action traceFull( String loc, String traceTag, item_t item ); 36.15 +endtypeclass 36.16 + 36.17 +instance Traceable#(String); 36.18 + 36.19 + function Action traceTiny( String loc, String ttag, String str ); 36.20 + $fdisplay(stderr, " => %s:%s %s", loc, ttag, str ); 36.21 + endfunction 36.22 + 36.23 + function Action traceFull( String loc, String ttag, String str ); 36.24 + $fdisplay(stderr, " => %s:%s %s", loc, ttag, str ); 36.25 + endfunction 36.26 + 36.27 +endinstance 36.28 + 36.29 +instance Traceable#(Bit#(n)); 36.30 + 36.31 + function Action traceTiny( String loc, String ttag, Bit#(n) b ); 36.32 + $fdisplay(stderr, " => %s:%s %x", loc, ttag, b ); 36.33 + endfunction 36.34 + 36.35 + function Action traceFull( String loc, String ttag, Bit#(n) b ); 36.36 + $fdisplay(stderr, " => %s:%s %x", loc, ttag, b ); 36.37 + endfunction 36.38 + 36.39 +endinstance 36.40 + 36.41 +//---------------------------------------------------------------------- 36.42 +// Tracing interface wrappers 36.43 +//---------------------------------------------------------------------- 36.44 + 36.45 +function Get#(item_t) traceGet( String locStr, String tagStr, Get#(item_t) g ) 36.46 + provisos ( Traceable#(item_t) ); 36.47 + return 36.48 + ( 36.49 + interface Get 36.50 + method ActionValue#(item_t) get(); 36.51 + item_t item <- g.get(); 36.52 + traceTiny(locStr, tagStr,item); 36.53 + return item; 36.54 + endmethod 36.55 + endinterface 36.56 + ); 36.57 +endfunction 36.58 + 36.59 +function Put#(item_t) tracePut( String locStr, String tagStr, Put#(item_t) p ) 36.60 + provisos ( Traceable#(item_t) ); 36.61 + return 36.62 + ( 36.63 + interface Put 36.64 + method Action put( item_t item ); 36.65 + traceTiny(locStr, tagStr,item); 36.66 + p.put(item); 36.67 + endmethod 36.68 + endinterface 36.69 + ); 36.70 +endfunction 36.71 + 36.72 +function Client#(req_t,resp_t) traceClient( String locStr, String reqTagStr, String respTagStr, 36.73 + Client#(req_t,resp_t) c ) 36.74 + provisos ( Traceable#(req_t), Traceable#(resp_t) ); 36.75 + return 36.76 + ( 36.77 + interface Client 36.78 + interface Get request = traceGet(locStr, reqTagStr,c.request); 36.79 + interface Put response = tracePut(locStr, respTagStr,c.response); 36.80 + endinterface 36.81 + ); 36.82 +endfunction 36.83 + 36.84 +function Server#(req_t,resp_t) traceServer( String locStr, String reqTagStr, String respTagStr, 36.85 + Server#(req_t,resp_t) c ) 36.86 + provisos ( Traceable#(req_t), Traceable#(resp_t) ); 36.87 + return 36.88 + ( 36.89 + interface Server 36.90 + interface Put request = tracePut(locStr, reqTagStr,c.request); 36.91 + interface Get response = traceGet(locStr, respTagStr,c.response); 36.92 + endinterface 36.93 + ); 36.94 +endfunction 36.95 +
37.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 37.2 +++ b/modules/bluespec/Pygar/core/audio_core.awb Fri Apr 23 02:32:05 2010 -0400 37.3 @@ -0,0 +1,16 @@ 37.4 +%name audio core 37.5 +%desc Instantiates a soft core used for audio, wrapped in the audio pipeline interface 37.6 + 37.7 +%provides audio_pipeline 37.8 + 37.9 +%requires audio_pipeline_types 37.10 +%requires core 37.11 +%requires funcp_simulated_memory 37.12 +%requires funcp_base_types 37.13 +%requires hasim_common 37.14 + 37.15 + 37.16 +%attributes 6_375 37.17 + 37.18 +%public FIRFilterPipeline.bsv 37.19 +
38.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 38.2 +++ b/modules/bluespec/Pygar/core/core.awb Fri Apr 23 02:32:05 2010 -0400 38.3 @@ -0,0 +1,16 @@ 38.4 +%name Audio Processor Soft Core 38.5 +%desc Instantiates a processor, some caches, and a memory arbiter 38.6 + 38.7 +%provides core 38.8 + 38.9 +%requires mem_arb 38.10 +%requires instruction_cache 38.11 +%requires data_cache 38.12 +%requires processor 38.13 +%requires processor_library 38.14 + 38.15 +%attributes 6_375 38.16 + 38.17 +%public Core.bsv 38.18 + 38.19 +
39.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 39.2 +++ b/modules/bluespec/Pygar/core/data_cache.d Fri Apr 23 02:32:05 2010 -0400 39.3 @@ -0,0 +1,10 @@ 39.4 +%name Blocking Data Cache 39.5 +%desc Parametric Blocking Data Cache 39.6 + 39.7 +%provides data_cache 39.8 + 39.9 +%attributes 6_375 39.10 + 39.11 +%public DataCacheBlocking.bsv 39.12 +%public DataCache.dic 39.13 +
40.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 40.2 +++ b/modules/bluespec/Pygar/core/instruction_cache.d Fri Apr 23 02:32:05 2010 -0400 40.3 @@ -0,0 +1,11 @@ 40.4 +%name Blocking Instruction Cache 40.5 +%desc Parametric Blocking Instruction Cache 40.6 + 40.7 +%provides instruction_cache 40.8 + 40.9 +%attributes 6_375 40.10 + 40.11 +%public InstCacheBlocking.bsv 40.12 +%public InstCache.dic 40.13 + 40.14 +
41.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 41.2 +++ b/modules/bluespec/Pygar/core/mem_arb.awb Fri Apr 23 02:32:05 2010 -0400 41.3 @@ -0,0 +1,10 @@ 41.4 +%name Round-robin Audio memory arbiter 41.5 +%desc Round-robin memory arbiter 41.6 + 41.7 +%provides mem_arb 41.8 + 41.9 +%attributes 6_375 41.10 + 41.11 +%public MemArb.bsv 41.12 + 41.13 +
42.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 42.2 +++ b/modules/bluespec/Pygar/core/processor.awb Fri Apr 23 02:32:05 2010 -0400 42.3 @@ -0,0 +1,13 @@ 42.4 +%name 3-Stage Audio Processor 42.5 +%desc 3-Stage Processor, one stage per cycle. 42.6 + 42.7 +%provides processor 42.8 + 42.9 +%attributes 6_375 42.10 + 42.11 +%public Processor.bsv ProcTypes.bsv 42.12 +%public Processor.dic 42.13 + 42.14 + 42.15 + 42.16 +
43.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 43.2 +++ b/modules/bluespec/Pygar/core/processor_library.awb Fri Apr 23 02:32:05 2010 -0400 43.3 @@ -0,0 +1,9 @@ 43.4 +%name Processor Audio Library 43.5 +%desc Some generally useful modules, found in the processor cores 43.6 + 43.7 +%provides processor_library 43.8 + 43.9 +%attributes 6_375 43.10 + 43.11 +%public Trace.bsv BFIFO.bsv MemTypes.bsv BRegFile.bsv BranchPred.bsv 43.12 +
44.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 44.2 +++ b/modules/bluespec/Pygar/lab1/FIRFilter.bsv Fri Apr 23 02:32:05 2010 -0400 44.3 @@ -0,0 +1,21 @@ 44.4 +import ClientServer::*; 44.5 +import GetPut::*; 44.6 +import FIFO::*; 44.7 + 44.8 +import AC97Common::*; 44.9 + 44.10 +module FIRFilter (Server#(AC97Sample)); 44.11 + FIFO#(AC97Sample) infifo <- mkFIFO; 44.12 + FIFO#(AC97Sample) outfifo <- mkFIFO; 44.13 + 44.14 + // for now, we don't do anything. 44.15 + rule connectReqResp; 44.16 + $display("FIR copies a data"); 44.17 + outfifo.enq(infifo.first); 44.18 + outfifo.deq; 44.19 + endrule 44.20 + 44.21 + 44.22 + interface request = fifoToPut(infifo); 44.23 + interface response = fifoToGet(outfifo); 44.24 +endmodule 44.25 \ No newline at end of file
45.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 45.2 +++ b/modules/bluespec/Pygar/lab1/FIRFilterDefault.bsv Fri Apr 23 02:32:05 2010 -0400 45.3 @@ -0,0 +1,157 @@ 45.4 +// The MIT License 45.5 + 45.6 +// Copyright (c) 2009 Massachusetts Institute of Technology 45.7 + 45.8 +// Permission is hereby granted, free of charge, to any person obtaining a copy 45.9 +// of this software and associated documentation files (the "Software"), to deal 45.10 +// in the Software without restriction, including without limitation the rights 45.11 +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 45.12 +// copies of the Software, and to permit persons to whom the Software is 45.13 +// furnished to do so, subject to the following conditions: 45.14 + 45.15 +// The above copyright notice and this permission notice shall be included in 45.16 +// all copies or substantial portions of the Software. 45.17 + 45.18 +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 45.19 +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 45.20 +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 45.21 +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 45.22 +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 45.23 +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 45.24 +// THE SOFTWARE. 45.25 + 45.26 +// Author: Kermin Fleming kfleming@mit.edu 45.27 + 45.28 +import Connectable::*; 45.29 +import GetPut::*; 45.30 +import ClientServer::*; 45.31 +import FIFO::*; 45.32 +import FixedPoint::*; 45.33 +import Vector::*; 45.34 + 45.35 +//AWB includes. These import the structure whcih allow us to communicate 45.36 +// with the outside world, and are part of the AWB library code 45.37 + 45.38 +`include "asim/provides/soft_connections.bsh" 45.39 +`include "asim/provides/common_services.bsh" 45.40 + 45.41 +// Local includes. Look for the correspondingly named .awb files 45.42 +// workspace/labs/src/mit-6.375/modules/bluespec/mit-6.375/common/ 45.43 +// to find the actual Bluespec files which are used to generate 45.44 +// these includes. These files are specific to this audio processing 45.45 +// pipeline 45.46 + 45.47 +`include "asim/provides/audio_pipeline_types.bsh" 45.48 +`include "asim/provides/audio_processor_types.bsh" 45.49 + 45.50 +typedef 8 Taps; 45.51 + 45.52 +module [Connected_Module] mkFIRFilter (FIRFilter); 45.53 + 45.54 + 45.55 + // instantiate an input FIFO and an Output FIFO 45.56 + // mkFIFO returns a fifo of length 2 (by default) 45.57 + // AudioProcessorUnit is the name given to the packets 45.58 + // of DATA processed by our audio pipeline. For their 45.59 + // definition, look in the file 45.60 + // workspace/labs/src/mit-6.375/modules/bluespec/mit-6.375/common/AudioProcessorTypes.bsv 45.61 + 45.62 + FIFO#(AudioProcessorUnit) infifo <- mkFIFO; 45.63 + FIFO#(AudioProcessorUnit) outfifo <- mkFIFO; 45.64 + 45.65 + 45.66 + // an alternate syntax for instantiating the samples vector 45.67 + // would have been as follows: 45.68 + // 45.69 + // Vector#(Taps,Reg#(Sample)) samples <- replicateM(mkReg(0)); 45.70 + // 45.71 + // we have used an explicit loop here, to demonstrate how 45.72 + // vectors can be instantiated during the static elaboration 45.73 + // phase, even though replicateM is far more concise. 45.74 + 45.75 + Vector#(Taps,Reg#(Sample)) samples = newVector(); 45.76 + for(Integer i = 0; i < valueof(Taps); i=i+1) 45.77 + samples[i] <- mkReg(0); 45.78 + 45.79 + Vector#(9,Reg#(FixedPoint#(16,16))) pr <- replicateM(mkReg(0)); 45.80 + 45.81 + 45.82 + // fromReal takes a Real number and converts it to a FixedPoint 45.83 + // representation. The compiler is smart enough to infer the 45.84 + // type (bit width) of the fixed point (in this case, we have 16 45.85 + // bits of integer, and 16 bits of fraction. 45.86 + 45.87 + FixedPoint#(16,16) firCoefs [9] = {fromReal(-0.0124), 45.88 + fromReal(0.0), 45.89 + fromReal(-0.0133), 45.90 + fromReal(0.0), 45.91 + fromReal(0.8181), 45.92 + fromReal(0.0), 45.93 + fromReal(-0.0133), 45.94 + fromReal(0.0), 45.95 + fromReal(-0.0124)}; 45.96 + 45.97 + 45.98 + // This rule implements a fir filter. We do the fir computations in 45.99 + // 16.16 fixed point. This preserves the magnitude of the input 45.100 + // pcm. This code was implemented using for loops so as to be more 45.101 + // clear. Using the functions map, fold, readVReg, and writeVReg 45.102 + // would have been more concise. 45.103 + 45.104 + rule process (infifo.first matches tagged Sample .sample); 45.105 + 45.106 + // Advance the fir filter, by shifting all the elements 45.107 + // down the Vector of registers (like a shift register) 45.108 + 45.109 + samples[0] <= sample; 45.110 + for(Integer i = 0; i < valueof(Taps) - 1; i = i + 1) 45.111 + begin 45.112 + samples[i+1] <= samples[i]; 45.113 + end 45.114 + 45.115 + // Filter the values, using an inefficient adder chain. You will 45.116 + // need to shorten the combinatorial path, by pipelining this logic. 45.117 + 45.118 + FixedPoint#(16,16) accumulate= firCoefs[0] * fromInt(sample); 45.119 + for(Integer i = 0; i < valueof(Taps); i = i + 1) 45.120 + begin 45.121 + accumulate = accumulate + firCoefs[1+i] * fromInt(samples[i]); 45.122 + end 45.123 + 45.124 + outfifo.enq(tagged Sample fxptGetInt(accumulate)); 45.125 + 45.126 + infifo.deq; 45.127 + endrule 45.128 + 45.129 + // Handle the end of stream condition. Look at the two rule guards, 45.130 + // these are obviously mutually exclusive. The definition of 45.131 + // AudioProcessorUnit shows that it can be tagged only as a Sample, or 45.132 + // EndOfFile; nothing else! 45.133 + 45.134 + rule endOfFile (infifo.first matches tagged EndOfFile); 45.135 + 45.136 + $display("FIR got end of file"); 45.137 + 45.138 + // Reset state for next invocation 45.139 + for(Integer i = 0; i < valueof(Taps); i = i + 1) 45.140 + begin 45.141 + samples[i] <= 0; 45.142 + pr[i] <= 0; 45.143 + end 45.144 + 45.145 + // pass the end-of-file token down the pipeline, eventually this will 45.146 + // make it back to the software side, to notify it that the stream 45.147 + // has been processed completely 45.148 + 45.149 + outfifo.enq(infifo.first); 45.150 + infifo.deq; 45.151 + endrule 45.152 + 45.153 + 45.154 + // this section connects the fifos instantiated internally to the 45.155 + // externally visible interface 45.156 + 45.157 + interface sampleInput = fifoToPut(infifo); 45.158 + interface sampleOutput = fifoToGet(outfifo); 45.159 + 45.160 +endmodule
46.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 46.2 +++ b/modules/bluespec/Pygar/lab1/FIRFilterPipeline.bsv Fri Apr 23 02:32:05 2010 -0400 46.3 @@ -0,0 +1,46 @@ 46.4 +// The MIT License 46.5 + 46.6 +// Copyright (c) 2009 Massachusetts Institute of Technology 46.7 + 46.8 +// Permission is hereby granted, free of charge, to any person obtaining a copy 46.9 +// of this software and associated documentation files (the "Software"), to deal 46.10 +// in the Software without restriction, including without limitation the rights 46.11 +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 46.12 +// copies of the Software, and to permit persons to whom the Software is 46.13 +// furnished to do so, subject to the following conditions: 46.14 + 46.15 +// The above copyright notice and this permission notice shall be included in 46.16 +// all copies or substantial portions of the Software. 46.17 + 46.18 +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 46.19 +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 46.20 +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 46.21 +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 46.22 +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 46.23 +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 46.24 +// THE SOFTWARE. 46.25 + 46.26 +// Author: Kermin Fleming kfleming@mit.edu 46.27 + 46.28 +import Connectable::*; 46.29 +import GetPut::*; 46.30 +import ClientServer::*; 46.31 +import FIFO::*; 46.32 + 46.33 +//AWB includes 46.34 +`include "asim/provides/low_level_platform_interface.bsh" 46.35 +`include "asim/provides/soft_connections.bsh" 46.36 +`include "asim/provides/common_services.bsh" 46.37 + 46.38 +//Local includes 46.39 +`include "asim/provides/audio_processor_types.bsh" 46.40 +`include "asim/provides/audio_pipeline_types.bsh" 46.41 +`include "asim/provides/fir_filter.bsh" 46.42 + 46.43 +module [Connected_Module] mkAudioPipeline (AudioPipeline); 46.44 + FIRFilter filter <- mkFIRFilter; 46.45 + 46.46 + interface sampleInput = filter.sampleInput; 46.47 + interface sampleOutput = filter.sampleOutput; 46.48 + 46.49 +endmodule
47.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 47.2 +++ b/modules/bluespec/Pygar/lab1/FIRFilterPipelineTypes.bsv Fri Apr 23 02:32:05 2010 -0400 47.3 @@ -0,0 +1,32 @@ 47.4 +// The MIT License 47.5 + 47.6 +// Copyright (c) 2009 Massachusetts Institute of Technology 47.7 + 47.8 +// Permission is hereby granted, free of charge, to any person obtaining a copy 47.9 +// of this software and associated documentation files (the "Software"), to deal 47.10 +// in the Software without restriction, including without limitation the rights 47.11 +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 47.12 +// copies of the Software, and to permit persons to whom the Software is 47.13 +// furnished to do so, subject to the following conditions: 47.14 + 47.15 +// The above copyright notice and this permission notice shall be included in 47.16 +// all copies or substantial portions of the Software. 47.17 + 47.18 +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 47.19 +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 47.20 +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 47.21 +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 47.22 +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 47.23 +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 47.24 +// THE SOFTWARE. 47.25 + 47.26 +// Author: Kermin Fleming kfleming@mit.edu 47.27 + 47.28 +import Connectable::*; 47.29 +import GetPut::*; 47.30 +import ClientServer::*; 47.31 +import FIFO::*; 47.32 + 47.33 +`include "audio_processor_types.bsh" 47.34 + 47.35 +typedef AudioPipeline FIRFilter;
48.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 48.2 +++ b/modules/bluespec/Pygar/lab1/fir_filter_default.awb Fri Apr 23 02:32:05 2010 -0400 48.3 @@ -0,0 +1,9 @@ 48.4 +%name FIR Filter Default Implementation 48.5 +%desc Copy FIR Filter 48.6 + 48.7 +%provides fir_filter 48.8 + 48.9 +%attributes 6_375 48.10 + 48.11 +%public FIRFilterDefault.bsv 48.12 +
49.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 49.2 +++ b/modules/bluespec/Pygar/lab1/fir_filter_pipeline.awb Fri Apr 23 02:32:05 2010 -0400 49.3 @@ -0,0 +1,12 @@ 49.4 +%name FIR Filter Pipeline 49.5 +%desc Instantiates a FIRFilter and wraps it in the audio pipeline interface 49.6 + 49.7 +%provides audio_pipeline 49.8 + 49.9 +%requires audio_pipeline_types 49.10 +%requires fir_filter 49.11 + 49.12 +%attributes 6_375 49.13 + 49.14 +%public FIRFilterPipeline.bsv 49.15 +
50.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 50.2 +++ b/modules/bluespec/Pygar/lab1/fir_filter_types.awb Fri Apr 23 02:32:05 2010 -0400 50.3 @@ -0,0 +1,9 @@ 50.4 +%name FIR Filter Pipeline Types 50.5 +%desc Types for the fir filter. 50.6 + 50.7 +%provides audio_pipeline_types 50.8 + 50.9 +%attributes 6_375 50.10 + 50.11 +%public FIRFilterPipelineTypes.bsv 50.12 +
51.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 51.2 +++ b/modules/bluespec/Pygar/lab4/BFIFO.bsv Fri Apr 23 02:32:05 2010 -0400 51.3 @@ -0,0 +1,222 @@ 51.4 +import FIFO::*; 51.5 +import FIFOF::*; 51.6 +import List::*; 51.7 +import Assert::*; 51.8 + 51.9 +module mkBFIFO1( FIFO#(item_t) ) provisos ( Bits#(item_t,item_sz) ); 51.10 + 51.11 + RWire#(item_t) inputWire <- mkRWire(); 51.12 + PulseWire deqEnabled <- mkPulseWire(); 51.13 + PulseWire clearEnabled <- mkPulseWire(); 51.14 + 51.15 + Reg#(item_t) register <- mkRegU(); 51.16 + Reg#(Bool) valid <- mkReg(False); 51.17 + 51.18 + // If there is an input item on the inputWire wire and dequeue did not 51.19 + // execute this cycle then we need to store the item in the register 51.20 + 51.21 + (*fire_when_enabled*) 51.22 + rule update ( True ); 51.23 + case (inputWire.wget()) matches 51.24 + tagged Invalid: 51.25 + if (deqEnabled || clearEnabled) 51.26 + valid <= False; 51.27 + tagged Valid .x: 51.28 + begin 51.29 + register <= x; 51.30 + valid <= !(deqEnabled || clearEnabled); 51.31 + end 51.32 + endcase 51.33 + endrule 51.34 + 51.35 + // On enqueue we write the input item to the inputWire wire 51.36 + 51.37 + method Action enq( item_t item ) if ( !valid ); 51.38 + inputWire.wset(item); 51.39 + endmethod 51.40 + 51.41 + // On dequeue we always invalidate the storage register regardless 51.42 + // of whether or not the item was actually bypassed or not. We also 51.43 + // set a combinational signal so that we know not to move the item 51.44 + // into the register this cycle. 51.45 + 51.46 + method Action deq() if ( valid || isValid(inputWire.wget()) ); 51.47 + deqEnabled.send(); 51.48 + endmethod 51.49 + 51.50 + // We get the item either from the register (if register is valid) or 51.51 + // from the combinational bypasss (if the rwire is valid). 51.52 + 51.53 + method item_t first() if ( valid || isValid(inputWire.wget()) ); 51.54 + if ( valid ) 51.55 + return register; 51.56 + else 51.57 + return unJust(inputWire.wget()); 51.58 + endmethod 51.59 + 51.60 + method Action clear(); 51.61 + clearEnabled.send(); 51.62 + endmethod 51.63 + 51.64 +endmodule 51.65 + 51.66 +module mkSizedBFIFO#(Integer n) ( FIFO#(item_t) ) provisos ( Bits#(item_t,item_sz) ); 51.67 + 51.68 + RWire#(item_t) inputWire <- mkRWire(); 51.69 + PulseWire deqEnabled <- mkPulseWire(); 51.70 + PulseWire clearEnabled <- mkPulseWire(); 51.71 + 51.72 + List#(Reg#(item_t)) registers <- replicateM(n, mkRegU); 51.73 + List#(Reg#(Bool)) valids <- replicateM(n, mkReg(False)); 51.74 + 51.75 + function Nat getNextFree (List#(Reg#(Bool)) vs); 51.76 + 51.77 + Nat res = fromInteger(n - 1); 51.78 + 51.79 + for (Integer x = n - 1; x > -1; x = x - 1) 51.80 + res = !vs[x]._read() ? fromInteger(x) : res; 51.81 + 51.82 + return res; 51.83 + 51.84 + endfunction 51.85 + 51.86 + function Bool notFull(); 51.87 + 51.88 + Bool full = True; 51.89 + 51.90 + for (Integer x = 0; x < length(valids); x = x + 1) 51.91 + full = full && valids[x]._read(); 51.92 + 51.93 + return !full; 51.94 + 51.95 + endfunction 51.96 + // If there is an input item on the inputWire wire and dequeue did not 51.97 + // execute this cycle then we need to store the item in the register 51.98 + 51.99 + rule update ( True ); 51.100 + Nat next = getNextFree(valids); 51.101 + 51.102 + next = (deqEnabled) ? next - 1 : next; 51.103 + 51.104 + (valids[next]) <= isValid(inputWire.wget()); 51.105 + (registers[next]) <= validValue(inputWire.wget()); 51.106 + 51.107 + if (deqEnabled && !clearEnabled) 51.108 + begin 51.109 + 51.110 + for (Nat x = 0; x < (next - 1); x = x + 1) 51.111 + begin 51.112 + (valids[x]) <= valids[x+1]._read(); 51.113 + (registers[x]) <= registers[x+1]._read(); 51.114 + end 51.115 + 51.116 + end 51.117 + else if (clearEnabled) 51.118 + begin 51.119 + 51.120 + for (Integer x = 0; x < n; x = x + 1) 51.121 + (valids[x]) <= False; 51.122 + 51.123 + end 51.124 + endrule 51.125 + 51.126 + // On enqueue we write the input item to the inputWire wire 51.127 + 51.128 + method Action enq( item_t item ) if ( notFull ); 51.129 + inputWire.wset(item); 51.130 + endmethod 51.131 + 51.132 + // On dequeue we always invalidate the storage register regardless 51.133 + // of whether or not the item was actually bypassed or not. We also 51.134 + // set a combinational signal so that we know not to move the item 51.135 + // into the register this cycle. 51.136 + 51.137 + method Action deq() if ( valids[0]._read() || isValid(inputWire.wget()) ); 51.138 + deqEnabled.send(); 51.139 + endmethod 51.140 + 51.141 + // We get the item either from the register (if register is valid) or 51.142 + // from the combinational bypasss (if the rwire is valid). 51.143 + 51.144 + method item_t first() if ( valids[0]._read() || isValid(inputWire.wget()) ); 51.145 + if ( valids[0]._read() ) 51.146 + return registers[0]._read(); 51.147 + else 51.148 + return unJust(inputWire.wget()); 51.149 + endmethod 51.150 + 51.151 + 51.152 + method Action clear(); 51.153 + clearEnabled.send(); 51.154 + endmethod 51.155 + 51.156 +endmodule 51.157 + 51.158 + 51.159 +module mkBFIFOF1( FIFOF#(item_t) ) provisos ( Bits#(item_t,item_sz) ); 51.160 + 51.161 + RWire#(item_t) inputWire <- mkRWire(); 51.162 + RWire#(Bool) deqEnabled <- mkRWire(); 51.163 + 51.164 + Reg#(Maybe#(item_t)) register <- mkReg(Invalid); 51.165 + 51.166 + // If there is an input item on the inputWire wire and dequeue did not 51.167 + // execute this cycle then we need to store the item in the register 51.168 + 51.169 + rule noDeq ( isValid(inputWire.wget()) && !isValid(deqEnabled.wget()) ); 51.170 + register <= inputWire.wget(); 51.171 + endrule 51.172 + 51.173 + // On enqueue we write the input item to the inputWire wire 51.174 + 51.175 + method Action enq( item_t item ) if ( !isValid(register) ); 51.176 + inputWire.wset(item); 51.177 + endmethod 51.178 + 51.179 + // On dequeue we always invalidate the storage register regardless 51.180 + // of whether or not the item was actually bypassed or not. We also 51.181 + // set a combinational signal so that we know not to move the item 51.182 + // into the register this cycle. 51.183 + 51.184 + method Action deq() if ( isValid(register) || isValid(inputWire.wget()) ); 51.185 + register <= Invalid; 51.186 + deqEnabled.wset(True); 51.187 + endmethod 51.188 + 51.189 + // We get the item either from the register (if register is valid) or 51.190 + // from the combinational bypasss (if the rwire is valid). 51.191 + 51.192 + method item_t first() if ( isValid(register) || isValid(inputWire.wget()) ); 51.193 + if ( isValid(register) ) 51.194 + return unJust(register); 51.195 + else 51.196 + return unJust(inputWire.wget()); 51.197 + endmethod 51.198 + 51.199 + // FIFOF adds the following two methods 51.200 + 51.201 + method Bool notFull(); 51.202 + return !isValid(register); 51.203 + endmethod 51.204 + 51.205 + method Bool notEmpty(); 51.206 + return (isValid(register) || isValid(inputWire.wget())); 51.207 + endmethod 51.208 + 51.209 + // Not sure about the clear method ... 51.210 + 51.211 + method Action clear(); 51.212 + dynamicAssert( False, "BFIFO.clear() not implemented yet!" ); 51.213 + endmethod 51.214 + 51.215 +endmodule 51.216 + 51.217 +(* synthesize *) 51.218 +module mkBFIFO_16 (FIFO#(Bit#(16))); 51.219 + 51.220 + let f <- mkBFIFO1(); 51.221 + 51.222 + return f; 51.223 + 51.224 +endmodule 51.225 +
52.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 52.2 +++ b/modules/bluespec/Pygar/lab4/BRegFile.bsv Fri Apr 23 02:32:05 2010 -0400 52.3 @@ -0,0 +1,36 @@ 52.4 +import RegFile::*; 52.5 +import RWire::*; 52.6 +import ProcTypes::*; 52.7 + 52.8 +//----------------------------------------------------------- 52.9 +// Register file module 52.10 +//----------------------------------------------------------- 52.11 + 52.12 +interface BRegFile #(type index_t, type data_t); 52.13 + method Action upd(index_t addr, data_t data); 52.14 + method data_t sub(index_t addr); 52.15 +endinterface 52.16 + 52.17 +module mkBRegFile(RegFile#(index_t, data_t)) 52.18 + provisos (Bits#(index_t, size_index), 52.19 + Bits#(data_t, size_data), 52.20 + Eq#(index_t), 52.21 + Bounded#(index_t) ); 52.22 + 52.23 + RegFile#(index_t, data_t) rf <- mkRegFileWCF(minBound, maxBound); 52.24 + RWire#(Tuple2#(index_t, data_t)) rw <-mkRWire(); 52.25 + 52.26 + method Action upd (index_t r, data_t d); 52.27 + rf.upd(r,d); 52.28 + rw.wset(tuple2(r,d)); 52.29 + endmethod 52.30 + 52.31 + method data_t sub (index_t r); 52.32 + case (rw.wget()) matches 52.33 + tagged Valid {.wr, .d} : 52.34 + return (wr == r) ? d : rf.sub(r); 52.35 + tagged Invalid : return rf.sub(r); 52.36 + endcase 52.37 + endmethod 52.38 + 52.39 +endmodule
53.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 53.2 +++ b/modules/bluespec/Pygar/lab4/BranchPred.bsv Fri Apr 23 02:32:05 2010 -0400 53.3 @@ -0,0 +1,41 @@ 53.4 +import RegFile::*; 53.5 +import ProcTypes::*; 53.6 +import FIFO::*; 53.7 + 53.8 +typedef Maybe#(Addr) BrPred; 53.9 +typedef Bit#(4) BPindx; 53.10 + 53.11 +typedef struct {Addr brpc; Addr nextpc;} BrPair deriving (Bits,Eq); 53.12 + 53.13 +typedef union tagged 53.14 +{ 53.15 + BrPair Valid; 53.16 + void Invalid; 53.17 +} CBranchPath deriving(Bits, Eq); // have the cache start out invalid and add valid values. 53.18 + 53.19 +interface BranchPred; 53.20 + method BrPred get(Addr pres); //returns a maybe type that is invalid if no predition 53.21 + method Action upd(Addr pres, Addr next); 53.22 +endinterface 53.23 + 53.24 +module mkBranchPred(BranchPred); 53.25 + 53.26 + //state variables 53.27 + RegFile#(BPindx, CBranchPath) bcache <- mkRegFileFull(); // cache to hold 16 (based on BPindx) 53.28 + 53.29 + method Action upd(Addr pres, Addr next); 53.30 + BrPair brp; 53.31 + brp = BrPair {brpc:pres, nextpc:next}; 53.32 + bcache.upd(pres[5:2], tagged Valid brp); 53.33 + endmethod 53.34 + 53.35 + method BrPred get(Addr prespc); 53.36 + BPindx rd = prespc[5:2]; 53.37 + let cbp = bcache.sub(rd); 53.38 + if (cbp matches tagged Valid .bp &&& bp.brpc == prespc) //make sure that the read value was actually put there and the full address matches 53.39 + return tagged Valid bp.nextpc; 53.40 + else return Invalid; 53.41 + endmethod 53.42 + 53.43 +endmodule 53.44 +
54.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 54.2 +++ b/modules/bluespec/Pygar/lab4/CBUFF.bsv Fri Apr 23 02:32:05 2010 -0400 54.3 @@ -0,0 +1,44 @@ 54.4 +import Connectable::*; 54.5 +import GetPut::*; 54.6 +import ClientServer::*; 54.7 + 54.8 +`include "asim/provides/librl_bsv_storage.bsh" 54.9 + 54.10 +typedef SCOREBOARD_FIFO_ENTRY_ID#(t) CBUFFToken#(type t); 54.11 + 54.12 +interface CBUFF #(numeric type n, type element_type); 54.13 + interface Get#(CBUFFToken#(n)) reserve; 54.14 + interface Put#(Tuple2 #(CBUFFToken#(n), element_type)) complete; 54.15 + interface Get#(element_type) drain; 54.16 +endinterface 54.17 + 54.18 +module mkCBUFF(CBUFF#(n, element_type)) 54.19 + provisos(Bits#(element_type,a__)); 54.20 + 54.21 + SCOREBOARD_FIFOF#(n,element_type) cbuff <- mkScoreboardFIFOF(); 54.22 + 54.23 + let res = interface Get; 54.24 + method ActionValue#(CBUFFToken#(n)) get(); 54.25 + let tok <- cbuff.enq(); 54.26 + return tok; 54.27 + endmethod 54.28 + endinterface; 54.29 + 54.30 + let comp = interface Put; 54.31 + method Action put(Tuple2#(CBUFFToken#(n),element_type) t); 54.32 + cbuff.setValue(tpl_1(t), tpl_2(t)); 54.33 + endmethod 54.34 + endinterface; 54.35 + 54.36 + let dr = interface Get; 54.37 + method ActionValue#(element_type) get(); 54.38 + cbuff.deq(); 54.39 + return cbuff.first(); 54.40 + endmethod 54.41 + endinterface; 54.42 + 54.43 + interface Get reserve = res; 54.44 + interface Put complete = comp; 54.45 + interface Get drain = dr; 54.46 + 54.47 +endmodule 54.48 \ No newline at end of file
55.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 55.2 +++ b/modules/bluespec/Pygar/lab4/Core.bsv Fri Apr 23 02:32:05 2010 -0400 55.3 @@ -0,0 +1,70 @@ 55.4 +// The MIT License 55.5 + 55.6 +// Copyright (c) 2009 Massachusetts Institute of Technology 55.7 + 55.8 +// Permission is hereby granted, free of charge, to any person obtaining a copy 55.9 +// of this software and associated documentation files (the "Software"), to deal 55.10 +// in the Software without restriction, including without limitation the rights 55.11 +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 55.12 +// copies of the Software, and to permit persons to whom the Software is 55.13 +// furnished to do so, subject to the following conditions: 55.14 + 55.15 +// The above copyright notice and this permission notice shall be included in 55.16 +// all copies or substantial portions of the Software. 55.17 + 55.18 +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 55.19 +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 55.20 +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 55.21 +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 55.22 +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 55.23 +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 55.24 +// THE SOFTWARE. 55.25 + 55.26 +import Connectable::*; 55.27 +import GetPut::*; 55.28 +import ClientServer::*; 55.29 + 55.30 +//AWB includes 55.31 +`include "asim/provides/low_level_platform_interface.bsh" 55.32 +`include "asim/provides/soft_connections.bsh" 55.33 +`include "asim/provides/common_services.bsh" 55.34 + 55.35 +// Local includes 55.36 +`include "asim/provides/processor_library.bsh" 55.37 +`include "asim/provides/mem_arb.bsh" 55.38 +`include "asim/provides/instruction_cache.bsh" 55.39 +`include "asim/provides/data_cache.bsh" 55.40 +`include "asim/provides/processor.bsh" 55.41 + 55.42 + 55.43 + 55.44 +interface Core; 55.45 + 55.46 + // Interface from core to main memory 55.47 + interface Client#(MainMemReq,MainMemResp) mmem_client; 55.48 + 55.49 +endinterface 55.50 + 55.51 +module [CONNECTED_MODULE] mkCore( Core ); 55.52 + 55.53 + // Instantiate the modules 55.54 + 55.55 + Proc proc <- mkProc(); 55.56 + ICache#(InstReq,InstResp) icache <- mkInstCache(); 55.57 + DCache#(DataReq,DataResp) dcache <- mkDataCache(); 55.58 + MemArb marb <- mkMemArb(); 55.59 + 55.60 + // Internal connections 55.61 + 55.62 + mkConnection( proc.statsEn_get, icache.statsEn_put ); 55.63 + mkConnection( proc.statsEn_get, dcache.statsEn_put ); 55.64 + mkConnection( proc.imem_client, icache.proc_server ); 55.65 + mkConnection( proc.dmem_client, dcache.proc_server ); 55.66 + mkConnection( icache.mmem_client, marb.cache0_server ); 55.67 + mkConnection( dcache.mmem_client, marb.cache1_server ); 55.68 + 55.69 + // Methods 55.70 + 55.71 + interface mmem_client = marb.mmem_client; 55.72 + 55.73 +endmodule
56.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 56.2 +++ b/modules/bluespec/Pygar/lab4/DataCache.dic Fri Apr 23 02:32:05 2010 -0400 56.3 @@ -0,0 +1,3 @@ 56.4 +def STATS.DATA_CACHE.NUM_ACCESSES "DATA_CACHE: Number Of Accesses: "; 56.5 +def STATS.DATA_CACHE.NUM_MISSES "DATA_CACHE: Number Of Misses: "; 56.6 +def STATS.DATA_CACHE.NUM_WRITEBACKS "DATA_CACHE: Number Of Writebacks: "; 56.7 \ No newline at end of file
57.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 57.2 +++ b/modules/bluespec/Pygar/lab4/DataCacheBlocking.bsv Fri Apr 23 02:32:05 2010 -0400 57.3 @@ -0,0 +1,283 @@ 57.4 +// The MIT License 57.5 + 57.6 +// Copyright (c) 2009 Massachusetts Institute of Technology 57.7 + 57.8 +// Permission is hereby granted, free of charge, to any person obtaining a copy 57.9 +// of this software and associated documentation files (the "Software"), to deal 57.10 +// in the Software without restriction, including without limitation the rights 57.11 +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 57.12 +// copies of the Software, and to permit persons to whom the Software is 57.13 +// furnished to do so, subject to the following conditions: 57.14 + 57.15 +// The above copyright notice and this permission notice shall be included in 57.16 +// all copies or substantial portions of the Software. 57.17 + 57.18 +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 57.19 +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 57.20 +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 57.21 +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 57.22 +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 57.23 +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 57.24 +// THE SOFTWARE. 57.25 + 57.26 +// Local includes 57.27 +`include "asim/provides/low_level_platform_interface.bsh" 57.28 +`include "asim/provides/soft_connections.bsh" 57.29 +`include "asim/provides/processor_library.bsh" 57.30 +`include "asim/provides/fpga_components.bsh" 57.31 +`include "asim/provides/common_services.bsh" 57.32 +`include "asim/dict/STATS_DATA_CACHE.bsh" 57.33 + 57.34 +import Connectable::*; 57.35 +import GetPut::*; 57.36 +import ClientServer::*; 57.37 +import RegFile::*; 57.38 +import FIFO::*; 57.39 +import FIFOF::*; 57.40 + 57.41 + 57.42 + 57.43 + 57.44 +interface DCache#( type req_t, type resp_t ); 57.45 + 57.46 + // Interface from processor to cache 57.47 + interface Server#(req_t,resp_t) proc_server; 57.48 + 57.49 + // Interface from cache to main memory 57.50 + interface Client#(MainMemReq,MainMemResp) mmem_client; 57.51 + 57.52 + // Interface for enabling/disabling statistics 57.53 + interface Put#(Bool) statsEn_put; 57.54 + 57.55 +endinterface 57.56 + 57.57 + 57.58 +//---------------------------------------------------------------------- 57.59 +// Cache Types 57.60 +//---------------------------------------------------------------------- 57.61 + 57.62 +typedef 10 CacheLineIndexSz; 57.63 +typedef 20 CacheLineTagSz; 57.64 +typedef 32 CacheLineSz; 57.65 + 57.66 +typedef Bit#(CacheLineIndexSz) CacheLineIndex; 57.67 +typedef Bit#(CacheLineTagSz) CacheLineTag; 57.68 +typedef Bit#(CacheLineSz) CacheLine; 57.69 + 57.70 +typedef enum 57.71 +{ 57.72 + Init, 57.73 + Access, 57.74 + RefillReq, 57.75 + RefillResp 57.76 +} 57.77 +CacheStage 57.78 +deriving (Eq,Bits); 57.79 + 57.80 +//---------------------------------------------------------------------- 57.81 +// Helper functions 57.82 +//---------------------------------------------------------------------- 57.83 + 57.84 +function Bit#(AddrSz) getAddr( DataReq req ); 57.85 + 57.86 + Bit#(AddrSz) addr = ?; 57.87 + case ( req ) matches 57.88 + tagged LoadReq .ld : addr = ld.addr; 57.89 + tagged StoreReq .st : addr = st.addr; 57.90 + endcase 57.91 + 57.92 + return addr; 57.93 + 57.94 +endfunction 57.95 + 57.96 +function CacheLineIndex getCacheLineIndex( DataReq req ); 57.97 + Bit#(AddrSz) addr = getAddr(req); 57.98 + Bit#(CacheLineIndexSz) index = truncate( addr >> 2 ); 57.99 + return index; 57.100 +endfunction 57.101 + 57.102 +function CacheLineTag getCacheLineTag( DataReq req ); 57.103 + Bit#(AddrSz) addr = getAddr(req); 57.104 + Bit#(CacheLineTagSz) tag = truncate( addr >> fromInteger(valueOf(CacheLineIndexSz)) >> 2 ); 57.105 + return tag; 57.106 +endfunction 57.107 + 57.108 +function Bit#(AddrSz) getCacheLineAddr( DataReq req ); 57.109 + Bit#(AddrSz) addr = getAddr(req); 57.110 + return ((addr >> 2) << 2); 57.111 +endfunction 57.112 + 57.113 +//---------------------------------------------------------------------- 57.114 +// Main module 57.115 +//---------------------------------------------------------------------- 57.116 + 57.117 +module [CONNECTED_MODULE] mkDataCache( DCache#(DataReq,DataResp) ); 57.118 + 57.119 + //----------------------------------------------------------- 57.120 + // State 57.121 + 57.122 + Reg#(CacheStage) stage <- mkReg(Init); 57.123 + 57.124 + LUTRAM#(CacheLineIndex,Maybe#(CacheLineTag)) cacheTagRam <- mkLUTRAMU_RegFile(); 57.125 + LUTRAM#(CacheLineIndex,CacheLine) cacheDataRam <- mkLUTRAMU_RegFile(); 57.126 + 57.127 + FIFO#(DataReq) reqQ <- mkFIFO(); 57.128 + FIFOF#(DataResp) respQ <- mkBFIFOF1(); 57.129 + 57.130 + FIFO#(MainMemReq) mainMemReqQ <- mkBFIFO1(); 57.131 + FIFO#(MainMemResp) mainMemRespQ <- mkFIFO(); 57.132 + 57.133 + Reg#(CacheLineIndex) initCounter <- mkReg(1); 57.134 + 57.135 + // Statistics state 57.136 + 57.137 + Reg#(Bool) statsEn <- mkReg(False); 57.138 + 57.139 + STAT num_accesses <- mkStatCounter(`STATS_DATA_CACHE_NUM_ACCESSES); 57.140 + STAT num_misses <- mkStatCounter(`STATS_DATA_CACHE_NUM_MISSES); 57.141 + STAT num_writebacks <- mkStatCounter(`STATS_DATA_CACHE_NUM_WRITEBACKS); 57.142 + 57.143 + //----------------------------------------------------------- 57.144 + // Name some wires 57.145 + 57.146 + let req = reqQ.first(); 57.147 + let reqIndex = getCacheLineIndex(req); 57.148 + let reqTag = getCacheLineTag(req); 57.149 + let reqCacheLineAddr = getCacheLineAddr(req); 57.150 + 57.151 + //----------------------------------------------------------- 57.152 + // Initialize 57.153 + 57.154 + rule init ( stage == Init ); 57.155 + traceTiny("mkDataCacheBlocking", "stage","i"); 57.156 + initCounter <= initCounter + 1; 57.157 + cacheTagRam.upd(initCounter,Invalid); 57.158 + if ( initCounter == 0 ) 57.159 + stage <= Access; 57.160 + endrule 57.161 + 57.162 + //----------------------------------------------------------- 57.163 + // Access cache rule 57.164 + 57.165 + rule access ( (stage == Access) && respQ.notFull() ); 57.166 + 57.167 + // Statistics 57.168 + 57.169 + if ( statsEn ) 57.170 + num_accesses.incr(); 57.171 + 57.172 + 57.173 + // Get the corresponding tag from the rams 57.174 + 57.175 + Maybe#(CacheLineTag) cacheLineTag = cacheTagRam.sub(reqIndex); 57.176 + 57.177 + // Handle cache hits ... 57.178 + 57.179 + if ( isValid(cacheLineTag) && ( unJust(cacheLineTag) == reqTag ) ) 57.180 + begin 57.181 + traceTiny("mkDataCacheBlocking", "hitMiss","h"); 57.182 + reqQ.deq(); 57.183 + 57.184 + case ( req ) matches 57.185 + 57.186 + tagged LoadReq .ld : 57.187 + respQ.enq( LoadResp { tag: ld.tag, data: cacheDataRam.sub(reqIndex) } ); 57.188 + 57.189 + tagged StoreReq .st : 57.190 + begin 57.191 + respQ.enq( StoreResp { tag : st.tag } ); 57.192 + cacheDataRam.upd(reqIndex,st.data); 57.193 + end 57.194 + 57.195 + endcase 57.196 + 57.197 + end 57.198 + 57.199 + // Handle cache misses ... 57.200 + 57.201 + else 57.202 + begin 57.203 + traceTiny("mkDataCacheBlocking", "hitMiss","m"); 57.204 + if ( statsEn ) 57.205 + num_misses.incr(); 57.206 + 57.207 + // Currently we don't use dirty bits so we always writeback the data if it is valid 57.208 + 57.209 + if ( isValid(cacheLineTag) ) 57.210 + begin 57.211 + 57.212 + if ( statsEn ) 57.213 + num_writebacks.incr(); 57.214 + 57.215 + MainMemReq wbReq 57.216 + = StoreReq { tag : 0, 57.217 + addr : { unJust(cacheLineTag), reqIndex, 2'b0 }, 57.218 + data : cacheDataRam.sub(reqIndex) }; 57.219 + 57.220 + mainMemReqQ.enq(wbReq); 57.221 + stage <= RefillReq; 57.222 + end 57.223 + 57.224 + // Otherwise we can issue the refill request now 57.225 + 57.226 + else 57.227 + begin 57.228 + mainMemReqQ.enq( LoadReq { tag: 0, addr: reqCacheLineAddr } ); 57.229 + stage <= RefillResp; 57.230 + end 57.231 + 57.232 + end 57.233 + 57.234 + endrule 57.235 + 57.236 + //----------------------------------------------------------- 57.237 + // Refill request rule 57.238 + 57.239 + rule refillReq ( stage == RefillReq ); 57.240 + traceTiny("mkDataCacheBlocking", "stage","r"); 57.241 + mainMemReqQ.enq( LoadReq { tag: 0, addr: reqCacheLineAddr } ); 57.242 + stage <= RefillResp; 57.243 + endrule 57.244 + 57.245 + //----------------------------------------------------------- 57.246 + // Refill response rule 57.247 + 57.248 + rule refillResp ( stage == RefillResp ); 57.249 + traceTiny("mkDataCacheBlocking", "stage","R"); 57.250 + traceTiny("mkDataCacheBlocking", "refill",mainMemRespQ.first()); 57.251 + 57.252 + // Write the new data into the cache and update the tag 57.253 + 57.254 + mainMemRespQ.deq(); 57.255 + case ( mainMemRespQ.first() ) matches 57.256 + 57.257 + tagged LoadResp .ld : 57.258 + begin 57.259 + cacheTagRam.upd(reqIndex,Valid(reqTag)); 57.260 + cacheDataRam.upd(reqIndex,ld.data); 57.261 + end 57.262 + 57.263 + tagged StoreResp .st : 57.264 + noAction; 57.265 + 57.266 + endcase 57.267 + 57.268 + stage <= Access; 57.269 + endrule 57.270 + 57.271 + //----------------------------------------------------------- 57.272 + // Methods 57.273 + 57.274 + interface Client mmem_client; 57.275 + interface Get request = fifoToGet(mainMemReqQ); 57.276 + interface Put response = fifoToPut(mainMemRespQ); 57.277 + endinterface 57.278 + 57.279 + interface Server proc_server; 57.280 + interface Put request = tracePut("mkDataCacheBlocking", "reqTiny",fifoToPut(reqQ)); 57.281 + interface Get response = traceGet("mkDataCacheBlocking", "respTiny",fifofToGet(respQ)); 57.282 + endinterface 57.283 + 57.284 + interface Put statsEn_put = regToPut(statsEn); 57.285 + 57.286 +endmodule
58.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 58.2 +++ b/modules/bluespec/Pygar/lab4/FIFOUtility.bsv Fri Apr 23 02:32:05 2010 -0400 58.3 @@ -0,0 +1,54 @@ 58.4 +import FIFO::*; 58.5 +import FIFOF::*; 58.6 +import Clocks::*; 58.7 +import GetPut::*; 58.8 + 58.9 +function FIFO#(fifo_type) guardedfifofToFifo( FIFOF#(fifo_type) fifo); 58.10 + 58.11 + FIFO#(fifo_type) f = interface FIFO#(fifo_type); 58.12 + method first = fifo.first; 58.13 + method enq = fifo.enq; 58.14 + method deq = fifo.deq; 58.15 + method clear = fifo.clear; 58.16 + endinterface; 58.17 + return f; 58.18 +endfunction 58.19 + 58.20 +function Get#(fifo_type) syncFifoToGet( SyncFIFOIfc#(fifo_type) fifo); 58.21 + Get#(fifo_type) f = interface Get#(fifo_type); 58.22 + method ActionValue#(fifo_type) get(); 58.23 + fifo.deq; 58.24 + return fifo.first; 58.25 + endmethod 58.26 + endinterface; 58.27 + return f; 58.28 +endfunction 58.29 + 58.30 +function Put#(fifo_type) syncFifoToPut( SyncFIFOIfc#(fifo_type) fifo); 58.31 + Put#(fifo_type) f = interface Put#(fifo_type); 58.32 + method Action put(fifo_type data); 58.33 + fifo.enq(data); 58.34 + endmethod 58.35 + endinterface; 58.36 + return f; 58.37 +endfunction 58.38 + 58.39 +function String fifofState(FIFOF#(data) fifo); 58.40 + String s = ""; 58.41 + 58.42 + if(!fifo.notEmpty) 58.43 + begin 58.44 + s = "Empty"; 58.45 + end 58.46 + else if (!fifo.notFull) 58.47 + begin 58.48 + s = "Full"; 58.49 + end 58.50 + else 58.51 + begin 58.52 + s = "Neither Empty Nor Full"; 58.53 + end 58.54 + 58.55 + return s; 58.56 +endfunction 58.57 +
59.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 59.2 +++ b/modules/bluespec/Pygar/lab4/FPGATypes.bsv Fri Apr 23 02:32:05 2010 -0400 59.3 @@ -0,0 +1,24 @@ 59.4 +typedef 30 AvalonAddressWidth; 59.5 +typedef 32 AvalonDataWidth; 59.6 + 59.7 +// need length + 1 spacing between CBusGet/Puts 59.8 +// Be warned - consider the word size of each address before 59.9 +// assigning new ones!!! 59.10 +// These are word addresses 59.11 +// Multiply by 4 to get byte address 59.12 +typedef 0 ToHostRegAddr; 59.13 +typedef 4 FromHostRegAddr; 59.14 +typedef 8 BreakpointRegAddr; 59.15 +typedef 12 BreakpointClearedAddr; 59.16 +typedef 16 PCRegAddr; 59.17 +typedef 20 StatsEnRegAddr; 59.18 +typedef 24 DCacheNumAccessesRegAddr; 59.19 +typedef 28 DCacheNumMissesRegAddr; 59.20 +typedef 32 DCacheNumWriteBacksRegAddr; 59.21 +typedef 36 ICacheNumAccessesRegAddr; 59.22 +typedef 40 ICacheNumMissesRegAddr; 59.23 +typedef 44 ICacheNumWriteBacksRegAddr; 59.24 +typedef 48 NumCyclesRegAddr; 59.25 +typedef 52 NumInstRegAddr; 59.26 +typedef 256 RegFileAddr; // The regfile is super long. Be careful of assigning conflicting addresses. 59.27 +
60.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 60.2 +++ b/modules/bluespec/Pygar/lab4/GetPutExt.bsv Fri Apr 23 02:32:05 2010 -0400 60.3 @@ -0,0 +1,108 @@ 60.4 +import FIFOF::*; 60.5 +import RWire::*; 60.6 +import GetPut::*; 60.7 + 60.8 +// Convert a FIFOF into a put interface 60.9 + 60.10 +function Put#(item_t) fifofToPut( FIFOF#(item_t) f ) provisos ( ); 60.11 + return 60.12 + ( 60.13 + interface Put 60.14 + method Action put( item_t item ); 60.15 + f.enq(item); 60.16 + endmethod 60.17 + endinterface 60.18 + ); 60.19 +endfunction 60.20 + 60.21 +// Convert a FIFOF into a get interface 60.22 + 60.23 +function Get#(item_t) fifofToGet( FIFOF#(item_t) f ) provisos ( ); 60.24 + return 60.25 + ( 60.26 + interface Get 60.27 + method ActionValue#(item_t) get(); 60.28 + f.deq(); 60.29 + return f.first(); 60.30 + endmethod 60.31 + endinterface 60.32 + ); 60.33 +endfunction 60.34 + 60.35 +// Convert a register into an (always ready) put interface 60.36 + 60.37 +function Put#(item_t) regToPut( Reg#(item_t) r ) provisos ( ); 60.38 + return 60.39 + ( 60.40 + interface Put 60.41 + method Action put( item_t item ); 60.42 + r <= item; 60.43 + endmethod 60.44 + endinterface 60.45 + ); 60.46 +endfunction 60.47 + 60.48 +// Convert a register into an (always ready) get interface 60.49 + 60.50 +function Get#(item_t) regToGet( Reg#(item_t) r ) provisos ( ); 60.51 + return 60.52 + ( 60.53 + interface Get 60.54 + method ActionValue#(item_t) get(); 60.55 + return r; 60.56 + endmethod 60.57 + endinterface 60.58 + ); 60.59 +endfunction 60.60 + 60.61 +// Convert a Wire into a put interface 60.62 + 60.63 +function Put#(item_t) wireToPut( Wire#(item_t) w ) provisos ( ); 60.64 + return 60.65 + ( 60.66 + interface Put 60.67 + method Action put( item_t item ); 60.68 + w._write(item); 60.69 + endmethod 60.70 + endinterface 60.71 + ); 60.72 +endfunction 60.73 + 60.74 +// Convert a WIREF into a get interface 60.75 + 60.76 +function Get#(item_t) wireToGet( Wire#(item_t) w ) provisos ( ); 60.77 + return 60.78 + ( 60.79 + interface Get 60.80 + method ActionValue#(item_t) get(); 60.81 + return w._read(); 60.82 + endmethod 60.83 + endinterface 60.84 + ); 60.85 +endfunction 60.86 + 60.87 +// Convert a RWire into a put interface 60.88 + 60.89 +function Put#(item_t) rwireToPut( RWire#(item_t) w ) provisos ( ); 60.90 + return 60.91 + ( 60.92 + interface Put 60.93 + method Action put( item_t item ); 60.94 + w.wset(item); 60.95 + endmethod 60.96 + endinterface 60.97 + ); 60.98 +endfunction 60.99 + 60.100 +// Convert a RWire into a get interface 60.101 + 60.102 +function Get#(item_t) rwireToGet( RWire#(item_t) w ) provisos ( ); 60.103 + return 60.104 + ( 60.105 + interface Get 60.106 + method ActionValue#(item_t) get() if ( isValid(w.wget()) ); 60.107 + return unJust(w.wget()); 60.108 + endmethod 60.109 + endinterface 60.110 + ); 60.111 +endfunction
61.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 61.2 +++ b/modules/bluespec/Pygar/lab4/InstCache.dic Fri Apr 23 02:32:05 2010 -0400 61.3 @@ -0,0 +1,3 @@ 61.4 +def STATS.INST_CACHE.NUM_ACCESSES "INST_CACHE: Number Of Accesses: "; 61.5 +def STATS.INST_CACHE.NUM_MISSES "INST_CACHE: Number Of Misses: "; 61.6 +def STATS.INST_CACHE.NUM_EVICTIONS "INST_CACHE: Number Of Evictions: ";
62.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 62.2 +++ b/modules/bluespec/Pygar/lab4/InstCacheBlocking.bsv Fri Apr 23 02:32:05 2010 -0400 62.3 @@ -0,0 +1,255 @@ 62.4 +// The MIT License 62.5 + 62.6 +// Copyright (c) 2009 Massachusetts Institute of Technology 62.7 + 62.8 +// Permission is hereby granted, free of charge, to any person obtaining a copy 62.9 +// of this software and associated documentation files (the "Software"), to deal 62.10 +// in the Software without restriction, including without limitation the rights 62.11 +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 62.12 +// copies of the Software, and to permit persons to whom the Software is 62.13 +// furnished to do so, subject to the following conditions: 62.14 + 62.15 +// The above copyright notice and this permission notice shall be included in 62.16 +// all copies or substantial portions of the Software. 62.17 + 62.18 +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 62.19 +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 62.20 +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 62.21 +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 62.22 +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 62.23 +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 62.24 +// THE SOFTWARE. 62.25 + 62.26 +import Connectable::*; 62.27 +import GetPut::*; 62.28 +import ClientServer::*; 62.29 +import RegFile::*; 62.30 +import FIFO::*; 62.31 +import FIFOF::*; 62.32 +import RWire::*; 62.33 + 62.34 +// Local includes 62.35 +`include "asim/provides/low_level_platform_interface.bsh" 62.36 +`include "asim/provides/soft_connections.bsh" 62.37 +`include "asim/provides/processor_library.bsh" 62.38 +`include "asim/provides/fpga_components.bsh" 62.39 +`include "asim/provides/common_services.bsh" 62.40 +`include "asim/dict/STATS_INST_CACHE.bsh" 62.41 + 62.42 +interface ICache#( type req_t, type resp_t ); 62.43 + 62.44 + // Interface from processor to cache 62.45 + interface Server#(req_t,resp_t) proc_server; 62.46 + 62.47 + // Interface from cache to main memory 62.48 + interface Client#(MainMemReq,MainMemResp) mmem_client; 62.49 + 62.50 + // Interface for enabling/disabling statistics 62.51 + interface Put#(Bool) statsEn_put; 62.52 + 62.53 +endinterface 62.54 + 62.55 +//---------------------------------------------------------------------- 62.56 +// Cache Types 62.57 +//---------------------------------------------------------------------- 62.58 + 62.59 +typedef 10 CacheLineIndexSz; 62.60 +typedef 20 CacheLineTagSz; 62.61 +typedef 32 CacheLineSz; 62.62 + 62.63 +typedef Bit#(CacheLineIndexSz) CacheLineIndex; 62.64 +typedef Bit#(CacheLineTagSz) CacheLineTag; 62.65 +typedef Bit#(CacheLineSz) CacheLine; 62.66 + 62.67 +typedef enum 62.68 +{ 62.69 + Init, 62.70 + Access, 62.71 + Evict, 62.72 + RefillReq, 62.73 + RefillResp 62.74 +} 62.75 +CacheStage 62.76 +deriving (Eq,Bits); 62.77 + 62.78 +//---------------------------------------------------------------------- 62.79 +// Helper functions 62.80 +//---------------------------------------------------------------------- 62.81 + 62.82 +function Bit#(AddrSz) getAddr( InstReq req ); 62.83 + 62.84 + Bit#(AddrSz) addr = ?; 62.85 + case ( req ) matches 62.86 + tagged LoadReq .ld : addr = ld.addr; 62.87 + tagged StoreReq .st : addr = st.addr; 62.88 + endcase 62.89 + 62.90 + return addr; 62.91 + 62.92 +endfunction 62.93 + 62.94 +function CacheLineIndex getCacheLineIndex( InstReq req ); 62.95 + Bit#(AddrSz) addr = getAddr(req); 62.96 + Bit#(CacheLineIndexSz) index = truncate( addr >> 2 ); 62.97 + return index; 62.98 +endfunction 62.99 + 62.100 +function CacheLineTag getCacheLineTag( InstReq req ); 62.101 + Bit#(AddrSz) addr = getAddr(req); 62.102 + Bit#(CacheLineTagSz) tag = truncate( addr >> fromInteger(valueOf(CacheLineIndexSz)) >> 2 ); 62.103 + return tag; 62.104 +endfunction 62.105 + 62.106 +function Bit#(AddrSz) getCacheLineAddr( InstReq req ); 62.107 + Bit#(AddrSz) addr = getAddr(req); 62.108 + return ((addr >> 2) << 2); 62.109 +endfunction 62.110 + 62.111 +//---------------------------------------------------------------------- 62.112 +// Main module 62.113 +//---------------------------------------------------------------------- 62.114 + 62.115 +module [CONNECTED_MODULE] mkInstCache( ICache#(InstReq,InstResp) ); 62.116 + 62.117 + //----------------------------------------------------------- 62.118 + // State 62.119 + 62.120 + Reg#(CacheStage) stage <- mkReg(Init); 62.121 + 62.122 + LUTRAM#(CacheLineIndex,Maybe#(CacheLineTag)) cacheTagRam <- mkLUTRAMU_RegFile(); 62.123 + LUTRAM#(CacheLineIndex,CacheLine) cacheDataRam <- mkLUTRAMU_RegFile(); 62.124 + 62.125 + FIFO#(InstReq) reqQ <- mkFIFO(); 62.126 + FIFOF#(InstResp) respQ <- mkBFIFOF1(); 62.127 + 62.128 + FIFO#(MainMemReq) mainMemReqQ <- mkBFIFO1(); 62.129 + FIFO#(MainMemResp) mainMemRespQ <- mkFIFO(); 62.130 + 62.131 + Reg#(CacheLineIndex) initCounter <- mkReg(1); 62.132 + 62.133 + // Statistics state 62.134 + 62.135 + Reg#(Bool) statsEn <- mkReg(False); 62.136 + 62.137 + STAT num_accesses <- mkStatCounter(`STATS_INST_CACHE_NUM_ACCESSES); 62.138 + STAT num_misses <- mkStatCounter(`STATS_INST_CACHE_NUM_MISSES); 62.139 + STAT num_evictions <- mkStatCounter(`STATS_INST_CACHE_NUM_EVICTIONS); 62.140 + 62.141 + //----------------------------------------------------------- 62.142 + // Name some wires 62.143 + 62.144 + let req = reqQ.first(); 62.145 + let reqIndex = getCacheLineIndex(req); 62.146 + let reqTag = getCacheLineTag(req); 62.147 + let reqCacheLineAddr = getCacheLineAddr(req); 62.148 + let refill = mainMemRespQ.first(); 62.149 + 62.150 + //----------------------------------------------------------- 62.151 + // Initialize 62.152 + 62.153 + rule init ( stage == Init ); 62.154 + traceTiny("mkInstCacheBlocking", "stage","i"); 62.155 + initCounter <= initCounter + 1; 62.156 + cacheTagRam.upd(initCounter,Invalid); 62.157 + if ( initCounter == 0 ) 62.158 + stage <= Access; 62.159 + endrule 62.160 + 62.161 + //----------------------------------------------------------- 62.162 + // Cache access rule 62.163 + 62.164 + rule access ( (stage == Access) && respQ.notFull() ); 62.165 + 62.166 + // Statistics 62.167 + 62.168 + if ( statsEn ) 62.169 + num_accesses.incr(); 62.170 + 62.171 + // Check tag and valid bit to see if this is a hit or a miss 62.172 + 62.173 + Maybe#(CacheLineTag) cacheLineTag = cacheTagRam.sub(reqIndex); 62.174 + 62.175 + // Handle cache hits ... 62.176 + 62.177 + if ( isValid(cacheLineTag) && ( unJust(cacheLineTag) == reqTag ) ) 62.178 + begin 62.179 + traceTiny("mkInstCacheBlocking", "hitMiss","h"); 62.180 + reqQ.deq(); 62.181 + 62.182 + case ( req ) matches 62.183 + 62.184 + tagged LoadReq .ld : 62.185 + respQ.enq( LoadResp { tag : ld.tag, data : cacheDataRam.sub(reqIndex) } ); 62.186 + 62.187 + tagged StoreReq .st : 62.188 + $display( " RTL-ERROR : %m : Stores are not allowed on the inst port!" ); 62.189 + 62.190 + endcase 62.191 + 62.192 + end 62.193 + 62.194 + // Handle cache misses - since lines in instruction cache are 62.195 + // never dirty we can always immediately issue a refill request 62.196 + 62.197 + else 62.198 + begin 62.199 + traceTiny("mkInstCacheBlocking", "hitMiss","m"); 62.200 + if ( statsEn ) 62.201 + num_misses.incr(); 62.202 + if ( statsEn ) 62.203 + if ( isJust(cacheLineTag) ) 62.204 + num_evictions.incr(); 62.205 + 62.206 + MainMemReq rfReq 62.207 + = LoadReq { tag : 0, 62.208 + addr : reqCacheLineAddr }; 62.209 + 62.210 + mainMemReqQ.enq(rfReq); 62.211 + stage <= RefillResp; 62.212 + end 62.213 + 62.214 + endrule 62.215 + 62.216 + //----------------------------------------------------------- 62.217 + // Refill response rule 62.218 + 62.219 + rule refillResp ( stage == RefillResp ); 62.220 + traceTiny("mkInstCacheBlocking", "stage","R"); 62.221 + traceTiny("mkInstCacheBlocking", "refill",refill); 62.222 + 62.223 + // Write the new data into the cache and update the tag 62.224 + 62.225 + mainMemRespQ.deq(); 62.226 + case ( mainMemRespQ.first() ) matches 62.227 + 62.228 + tagged LoadResp .ld : 62.229 + begin 62.230 + cacheTagRam.upd(reqIndex,Valid(reqTag)); 62.231 + cacheDataRam.upd(reqIndex,ld.data); 62.232 + end 62.233 + 62.234 + tagged StoreResp .st : 62.235 + noAction; 62.236 + 62.237 + endcase 62.238 + 62.239 + stage <= Access; 62.240 + endrule 62.241 + 62.242 + //----------------------------------------------------------- 62.243 + // Methods 62.244 + 62.245 + interface Client mmem_client; 62.246 + interface Get request = fifoToGet(mainMemReqQ); 62.247 + interface Put response = fifoToPut(mainMemRespQ); 62.248 + endinterface 62.249 + 62.250 + interface Server proc_server; 62.251 + interface Put request = tracePut("mkInstCacheBlocking", "reqTiny",fifoToPut(reqQ)); 62.252 + interface Get response = traceGet("mkInstCacheBlocking", "respTiny",fifofToGet(respQ)); 62.253 + endinterface 62.254 + 62.255 + interface Put statsEn_put = regToPut(statsEn); 62.256 + 62.257 +endmodule 62.258 +
63.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 63.2 +++ b/modules/bluespec/Pygar/lab4/MemArb.bsv Fri Apr 23 02:32:05 2010 -0400 63.3 @@ -0,0 +1,139 @@ 63.4 +// The MIT License 63.5 + 63.6 +// Copyright (c) 2009 Massachusetts Institute of Technology 63.7 + 63.8 +// Permission is hereby granted, free of charge, to any person obtaining a copy 63.9 +// of this software and associated documentation files (the "Software"), to deal 63.10 +// in the Software without restriction, including without limitation the rights 63.11 +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 63.12 +// copies of the Software, and to permit persons to whom the Software is 63.13 +// furnished to do so, subject to the following conditions: 63.14 + 63.15 +// The above copyright notice and this permission notice shall be included in 63.16 +// all copies or substantial portions of the Software. 63.17 + 63.18 +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 63.19 +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 63.20 +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 63.21 +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 63.22 +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 63.23 +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 63.24 +// THE SOFTWARE. 63.25 + 63.26 +import Connectable::*; 63.27 +import GetPut::*; 63.28 +import ClientServer::*; 63.29 +import FIFOF::*; 63.30 +import FIFO::*; 63.31 + 63.32 +// Local includes 63.33 +`include "asim/provides/processor_library.bsh" 63.34 + 63.35 +interface MemArb; 63.36 + 63.37 + interface Server#(MainMemReq,MainMemResp) cache0_server; 63.38 + interface Server#(MainMemReq,MainMemResp) cache1_server; 63.39 + interface Client#(MainMemReq,MainMemResp) mmem_client; 63.40 + 63.41 +endinterface 63.42 + 63.43 +typedef enum { REQ0, REQ1 } ReqPtr deriving(Eq,Bits); 63.44 + 63.45 +module mkMemArb( MemArb ); 63.46 + 63.47 + //----------------------------------------------------------- 63.48 + // State 63.49 + 63.50 + FIFOF#(MainMemReq) req0Q <- mkBFIFOF1(); 63.51 + FIFO#(MainMemResp) resp0Q <- mkBFIFO1(); 63.52 + 63.53 + FIFOF#(MainMemReq) req1Q <- mkBFIFOF1(); 63.54 + FIFO#(MainMemResp) resp1Q <- mkBFIFO1(); 63.55 + 63.56 + FIFO#(MainMemReq) mreqQ <- mkBFIFO1(); 63.57 + FIFO#(MainMemResp) mrespQ <- mkBFIFO1(); 63.58 + 63.59 + Reg#(ReqPtr) nextReq <- mkReg(REQ0); 63.60 + 63.61 + //----------------------------------------------------------- 63.62 + // Some wires 63.63 + 63.64 + let req0avail = req0Q.notEmpty(); 63.65 + let req1avail = req1Q.notEmpty(); 63.66 + 63.67 + //----------------------------------------------------------- 63.68 + // Rules 63.69 + 63.70 + rule chooseReq0 ( req0avail && (!req1avail || (nextReq == REQ0)) ); 63.71 + traceTiny("mkMemArb", "memArb req0",req0Q.first()); 63.72 + 63.73 + // Rewrite tag field if this is a load ... 63.74 + MainMemReq mreq 63.75 + = case ( req0Q.first() ) matches 63.76 + tagged LoadReq .ld : return LoadReq { tag:0, addr:ld.addr }; 63.77 + tagged StoreReq .st : return req0Q.first(); 63.78 + endcase; 63.79 + 63.80 + // Send out the request 63.81 + mreqQ.enq(mreq); 63.82 + nextReq <= REQ1; 63.83 + req0Q.deq(); 63.84 + 63.85 + endrule 63.86 + 63.87 + rule chooseReq1 ( req1avail && (!req0avail || (nextReq == REQ1)) ); 63.88 + traceTiny("mkMemArb", "memArb req1",req1Q.first); 63.89 + 63.90 + // Rewrite tag field if this is a load ... 63.91 + MainMemReq mreq 63.92 + = case ( req1Q.first() ) matches 63.93 + tagged LoadReq .ld : return LoadReq { tag:1, addr:ld.addr }; 63.94 + tagged StoreReq .st : return req1Q.first(); 63.95 + endcase; 63.96 + 63.97 + // Send out the request 63.98 + mreqQ.enq(mreq); 63.99 + nextReq <= REQ0; 63.100 + req1Q.deq(); 63.101 + 63.102 + endrule 63.103 + 63.104 + rule returnResp; 63.105 + traceTiny("mkMemArb", "resp",mrespQ.first()); 63.106 + 63.107 + // Use tag to figure out where to send response 63.108 + mrespQ.deq(); 63.109 + let tag 63.110 + = case ( mrespQ.first() ) matches 63.111 + tagged LoadResp .ld : return ld.tag; 63.112 + tagged StoreResp .st : return st.tag; 63.113 + endcase; 63.114 + 63.115 + if ( tag == 0 ) 63.116 + resp0Q.enq(mrespQ.first()); 63.117 + else 63.118 + resp1Q.enq(mrespQ.first()); 63.119 + 63.120 + endrule 63.121 + 63.122 + //----------------------------------------------------------- 63.123 + // Methods 63.124 + 63.125 + interface Server cache0_server; 63.126 + interface Put request = fifofToPut(req0Q); 63.127 + interface Get response = fifoToGet(resp0Q); 63.128 + endinterface 63.129 + 63.130 + interface Server cache1_server; 63.131 + interface Put request = fifofToPut(req1Q); 63.132 + interface Get response = fifoToGet(resp1Q); 63.133 + endinterface 63.134 + 63.135 + interface Client mmem_client; 63.136 + interface Get request = fifoToGet(mreqQ); 63.137 + interface Put response = fifoToPut(mrespQ); 63.138 + endinterface 63.139 + 63.140 +endmodule 63.141 + 63.142 +
64.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 64.2 +++ b/modules/bluespec/Pygar/lab4/MemTypes.bsv Fri Apr 23 02:32:05 2010 -0400 64.3 @@ -0,0 +1,92 @@ 64.4 +import Trace::*; 64.5 + 64.6 +//---------------------------------------------------------------------- 64.7 +// Basic memory requests and responses 64.8 +//---------------------------------------------------------------------- 64.9 + 64.10 +typedef union tagged 64.11 +{ 64.12 + struct { Bit#(addrSz) addr; Bit#(tagSz) tag; } LoadReq; 64.13 + struct { Bit#(addrSz) addr; Bit#(tagSz) tag; Bit#(dataSz) data; } StoreReq; 64.14 +} 64.15 +MemReq#( type addrSz, type tagSz, type dataSz ) 64.16 +deriving(Eq,Bits); 64.17 + 64.18 +typedef union tagged 64.19 +{ 64.20 + struct { Bit#(tagSz) tag; Bit#(dataSz) data; } LoadResp; 64.21 + struct { Bit#(tagSz) tag; } StoreResp; 64.22 +} 64.23 +MemResp#( type tagSz, type dataSz ) 64.24 +deriving(Eq,Bits); 64.25 + 64.26 +//---------------------------------------------------------------------- 64.27 +// Specialized req/resp for inst/data/host 64.28 +//---------------------------------------------------------------------- 64.29 + 64.30 +typedef 32 AddrSz; 64.31 +typedef 08 TagSz; 64.32 +typedef 32 DataSz; 64.33 +typedef 32 InstSz; 64.34 +typedef 32 HostDataSz; 64.35 + 64.36 +typedef MemReq#(AddrSz,TagSz,0) InstReq; 64.37 +typedef MemResp#(TagSz,InstSz) InstResp; 64.38 + 64.39 +typedef MemReq#(AddrSz,TagSz,DataSz) DataReq; 64.40 +typedef MemResp#(TagSz,DataSz) DataResp; 64.41 + 64.42 +typedef MemReq#(AddrSz,TagSz,HostDataSz) HostReq; 64.43 +typedef MemResp#(TagSz,HostDataSz) HostResp; 64.44 + 64.45 +//---------------------------------------------------------------------- 64.46 +// Specialized req/resp for main memory 64.47 +//---------------------------------------------------------------------- 64.48 + 64.49 +typedef 32 MainMemAddrSz; 64.50 +typedef 08 MainMemTagSz; 64.51 +typedef 32 MainMemDataSz; 64.52 + 64.53 +typedef MemReq#(MainMemAddrSz,MainMemTagSz,MainMemDataSz) MainMemReq; 64.54 +typedef MemResp#(MainMemTagSz,MainMemDataSz) MainMemResp; 64.55 + 64.56 +//---------------------------------------------------------------------- 64.57 +// Tracing Functions 64.58 +//---------------------------------------------------------------------- 64.59 + 64.60 +instance Traceable#(MemReq#(a,b,c)); 64.61 + 64.62 + function Action traceTiny( String loc, String ttag, MemReq#(a,b,c) req ); 64.63 + case ( req ) matches 64.64 + tagged LoadReq .ld : $fdisplay(stderr, " => %s:%s l%2x", loc, ttag, ld.tag ); 64.65 + tagged StoreReq .st : $fdisplay(stderr, " => %s:%s s%2x", loc, ttag, st.tag ); 64.66 + endcase 64.67 + endfunction 64.68 + 64.69 + function Action traceFull( String loc, String ttag, MemReq#(a,b,c) req ); 64.70 + case ( req ) matches 64.71 + tagged LoadReq .ld : $fdisplay(stderr, " => %s:%s Ld { addr=%x, tag=%x }", loc, ttag, ld.addr, ld.tag ); 64.72 + tagged StoreReq .st : $fdisplay(stderr, " => %s:%s St { addr=%x, tag=%x, data=%x }", loc, ttag, st.addr, st.tag, st.data ); 64.73 + endcase 64.74 + endfunction 64.75 + 64.76 +endinstance 64.77 + 64.78 +instance Traceable#(MemResp#(a,b)); 64.79 + 64.80 + function Action traceTiny( String loc, String ttag, MemResp#(a,b) resp ); 64.81 + case ( resp ) matches 64.82 + tagged LoadResp .ld : $fdisplay(stderr, " => %s:%s l%2x", loc, ttag, ld.tag ); 64.83 + tagged StoreResp .st : $fdisplay(stderr, " => %s:%s s%2x", loc, ttag, st.tag ); 64.84 + endcase 64.85 + endfunction 64.86 + 64.87 + function Action traceFull( String loc, String ttag, MemResp#(a,b) resp ); 64.88 + case ( resp ) matches 64.89 + tagged LoadResp .ld : $fdisplay(stderr, " => %s:%s Ld { tag=%x, data=%x }", loc, ttag, ld.tag, ld.data ); 64.90 + tagged StoreResp .st : $fdisplay(stderr, " => %s:%s St { tag=%x }", loc, ttag, st.tag ); 64.91 + endcase 64.92 + endfunction 64.93 + 64.94 +endinstance 64.95 +
65.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 65.2 +++ b/modules/bluespec/Pygar/lab4/Proc.bsv Fri Apr 23 02:32:05 2010 -0400 65.3 @@ -0,0 +1,342 @@ 65.4 +import CBusUtils::*; 65.5 +import Register::*; 65.6 + 65.7 +import Trace::*; 65.8 +import MemTypes::*; 65.9 +import IProc::*; 65.10 +import ProcTypes::*; 65.11 +import FPGATypes::*; 65.12 +import RegFile::*; 65.13 +import FIFO::*; 65.14 +import BFIFO::*; 65.15 +import Assert::*; 65.16 + 65.17 +import GetPut::*; 65.18 +import GetPutExt::*; 65.19 +import ClientServer::*; 65.20 +import CBus::*; 65.21 + 65.22 + 65.23 +interface IProc; 65.24 + 65.25 + // Interface for testrig 65.26 + interface Put#(Bit#(8)) testrig_fromhost; 65.27 + interface Get#(Bit#(8)) testrig_tohost; 65.28 + 65.29 + // Interface from processor to caches 65.30 + interface Client#(DataReq,DataResp) dmem_client; 65.31 + interface Client#(InstReq,InstResp) imem_client; 65.32 + 65.33 + // Interface for enabling/disabling statistics on the rest of the core 65.34 + interface Get#(Bool) statsEn_get; 65.35 + 65.36 +endinterface 65.37 + 65.38 + 65.39 +typedef enum { PCgen, Exec, Writeback } Stage deriving(Eq,Bits); 65.40 + 65.41 +//----------------------------------------------------------- 65.42 +// Register file module 65.43 +//----------------------------------------------------------- 65.44 + 65.45 +interface RFile; 65.46 + method Action wr( Rindx rindx, Bit#(32) data ); 65.47 + method Bit#(32) rd1( Rindx rindx ); 65.48 + method Bit#(32) rd2( Rindx rindx ); 65.49 +endinterface 65.50 + 65.51 +module mkRFile( RFile ); 65.52 + 65.53 + RegFile#(Rindx,Bit#(32)) rfile <- mkRegFileFull(); 65.54 + 65.55 + method Action wr( Rindx rindx, Bit#(32) data ); 65.56 + rfile.upd( rindx, data ); 65.57 + endmethod 65.58 + 65.59 + method Bit#(32) rd1( Rindx rindx ); 65.60 + return ( rindx == 0 ) ? 0 : rfile.sub(rindx); 65.61 + endmethod 65.62 + 65.63 + method Bit#(32) rd2( Rindx rindx ); 65.64 + return ( rindx == 0 ) ? 0 : rfile.sub(rindx); 65.65 + endmethod 65.66 + 65.67 +endmodule 65.68 + 65.69 +//----------------------------------------------------------- 65.70 +// Helper functions 65.71 +//----------------------------------------------------------- 65.72 + 65.73 +function Bit#(32) slt( Bit#(32) val1, Bit#(32) val2 ); 65.74 + return zeroExtend( pack( signedLT(val1,val2) ) ); 65.75 +endfunction 65.76 + 65.77 +function Bit#(32) sltu( Bit#(32) val1, Bit#(32) val2 ); 65.78 + return zeroExtend( pack( val1 < val2 ) ); 65.79 +endfunction 65.80 + 65.81 +function Bit#(32) rshft( Bit#(32) val ); 65.82 + return zeroExtend(val[4:0]); 65.83 +endfunction 65.84 + 65.85 +//----------------------------------------------------------- 65.86 +// Reference processor 65.87 +//----------------------------------------------------------- 65.88 + 65.89 + 65.90 +module [ModWithCBus#(AvalonAddressWidth,AvalonDataWidth)] mkProc( IProc ); 65.91 + 65.92 + //----------------------------------------------------------- 65.93 + // State 65.94 + 65.95 + // Standard processor state 65.96 + 65.97 + Reg#(Addr) pc <- mkReg(32'h00001000); 65.98 + Reg#(Stage) stage <- mkReg(PCgen); 65.99 + RFile rf <- mkRFile; 65.100 + 65.101 + // Coprocessor state 65.102 + 65.103 + Reg#(Bit#(8)) cp0_tohost <- mkReg(0); 65.104 + mkCBusWideRegRW(valueof(ToHostRegAddr),cp0_tohost); 65.105 + Reg#(Bit#(8)) cp0_fromhost <- mkReg(0); 65.106 + mkCBusWideRegRW(valueof(FromHostRegAddr),cp0_fromhost); 65.107 + Reg#(Bool) cp0_statsEn <- mkReg(False); 65.108 + mkCBusWideRegRW(valueof(StatsEnRegAddr),cp0_statsEn); 65.109 + // Memory request/response state 65.110 + 65.111 + FIFO#(InstReq) instReqQ <- mkBFIFO1(); 65.112 + FIFO#(InstResp) instRespQ <- mkFIFO(); 65.113 + 65.114 + FIFO#(DataReq) dataReqQ <- mkBFIFO1(); 65.115 + FIFO#(DataResp) dataRespQ <- mkFIFO(); 65.116 + 65.117 + // Statistics state 65.118 + 65.119 + Reg#(Int#(25)) num_cycles <- mkReg(25'h0); 65.120 + Reg#(Int#(25)) num_inst <- mkReg(25'h0); 65.121 + 65.122 + //----------------------------------------------------------- 65.123 + // Rules 65.124 + 65.125 + let pc_plus4 = pc + 4; 65.126 + 65.127 + rule pcgen ( stage == PCgen ); 65.128 + traceTiny("pc",pc); 65.129 + traceTiny("stage","P"); 65.130 + instReqQ.enq( LoadReq{ addr:pc, tag:0 } ); 65.131 + stage <= Exec; 65.132 + endrule 65.133 + 65.134 + rule exec ( stage == Exec ); 65.135 + 65.136 + // Some abbreviations 65.137 + let sext = signExtend; 65.138 + let zext = zeroExtend; 65.139 + let sra = signedShiftRight; 65.140 + 65.141 + // Get the instruction 65.142 + 65.143 + instRespQ.deq(); 65.144 + Instr inst 65.145 + = case ( instRespQ.first() ) matches 65.146 + tagged LoadResp .ld : return unpack(ld.data); 65.147 + tagged StoreResp .st : return ?; 65.148 + endcase; 65.149 + 65.150 + // Some default variables 65.151 + Stage next_stage = PCgen; 65.152 + Addr next_pc = pc_plus4; 65.153 + 65.154 + // Tracing 65.155 + traceTiny("stage","X"); 65.156 + traceTiny("exInstTiny",inst); 65.157 + traceFull("exInstFull",inst); 65.158 + 65.159 + case ( inst ) matches 65.160 + 65.161 + // -- Memory Ops ------------------------------------------------ 65.162 + 65.163 + tagged LW .it : 65.164 + begin 65.165 + Addr addr = rf.rd1(it.rbase) + sext(it.offset); 65.166 + dataReqQ.enq( LoadReq{ addr:addr, tag:zeroExtend(it.rdst) } ); 65.167 + next_stage = Writeback; 65.168 + end 65.169 + 65.170 + tagged SW .it : 65.171 + begin 65.172 + Addr addr = rf.rd1(it.rbase) + sext(it.offset); 65.173 + dataReqQ.enq( StoreReq{ tag:0, addr:addr, data:rf.rd1(it.rsrc) } ); 65.174 + next_stage = Writeback; 65.175 + end 65.176 + 65.177 + // -- Simple Ops ------------------------------------------------ 65.178 + 65.179 + tagged ADDIU .it : rf.wr( it.rdst, rf.rd1(it.rsrc) + sext(it.imm) ); 65.180 + tagged SLTI .it : rf.wr( it.rdst, slt( rf.rd1(it.rsrc), sext(it.imm) ) ); 65.181 + tagged SLTIU .it : rf.wr( it.rdst, sltu( rf.rd1(it.rsrc), sext(it.imm) ) ); 65.182 + tagged ANDI .it : 65.183 + begin 65.184 + Bit#(32) zext_it_imm = zext(it.imm); 65.185 + rf.wr( it.rdst, rf.rd1(it.rsrc) & zext_it_imm ); 65.186 + end 65.187 + tagged ORI .it : 65.188 + begin 65.189 + Bit#(32) zext_it_imm = zext(it.imm); 65.190 + rf.wr( it.rdst, rf.rd1(it.rsrc) | zext_it_imm ); 65.191 + end 65.192 + tagged XORI .it : 65.193 + begin 65.194 + Bit#(32) zext_it_imm = zext(it.imm); 65.195 + rf.wr( it.rdst, rf.rd1(it.rsrc) ^ zext_it_imm ); 65.196 + end 65.197 + tagged LUI .it : 65.198 + begin 65.199 + Bit#(32) zext_it_imm = zext(it.imm); 65.200 + rf.wr( it.rdst, (zext_it_imm << 32'd16) ); 65.201 + end 65.202 + 65.203 + tagged SLL .it : 65.204 + begin 65.205 + Bit#(32) zext_it_shamt = zext(it.shamt); 65.206 + rf.wr( it.rdst, rf.rd1(it.rsrc) << zext_it_shamt ); 65.207 + end 65.208 + tagged SRL .it : 65.209 + begin 65.210 + Bit#(32) zext_it_shamt = zext(it.shamt); 65.211 + rf.wr( it.rdst, rf.rd1(it.rsrc) >> zext_it_shamt ); 65.212 + end 65.213 + tagged SRA .it : 65.214 + begin 65.215 + Bit#(32) zext_it_shamt = zext(it.shamt); 65.216 + rf.wr( it.rdst, sra( rf.rd1(it.rsrc), zext_it_shamt )); 65.217 + end 65.218 + tagged SLLV .it : rf.wr( it.rdst, rf.rd1(it.rsrc) << rshft(rf.rd2(it.rshamt)) ); 65.219 + tagged SRLV .it : rf.wr( it.rdst, rf.rd1(it.rsrc) >> rshft(rf.rd2(it.rshamt)) ); 65.220 + tagged SRAV .it : rf.wr( it.rdst, sra( rf.rd1(it.rsrc), rshft(rf.rd2(it.rshamt)) ) ); 65.221 + tagged ADDU .it : rf.wr( it.rdst, rf.rd1(it.rsrc1) + rf.rd2(it.rsrc2) ); 65.222 + tagged SUBU .it : rf.wr( it.rdst, rf.rd1(it.rsrc1) - rf.rd2(it.rsrc2) ); 65.223 + tagged AND .it : rf.wr( it.rdst, rf.rd1(it.rsrc1) & rf.rd2(it.rsrc2) ); 65.224 + tagged OR .it : rf.wr( it.rdst, rf.rd1(it.rsrc1) | rf.rd2(it.rsrc2) ); 65.225 + tagged XOR .it : rf.wr( it.rdst, rf.rd1(it.rsrc1) ^ rf.rd2(it.rsrc2) ); 65.226 + tagged NOR .it : rf.wr( it.rdst, ~(rf.rd1(it.rsrc1) | rf.rd2(it.rsrc2)) ); 65.227 + tagged SLT .it : rf.wr( it.rdst, slt( rf.rd1(it.rsrc1), rf.rd2(it.rsrc2) ) ); 65.228 + tagged SLTU .it : rf.wr( it.rdst, sltu( rf.rd1(it.rsrc1), rf.rd2(it.rsrc2) ) ); 65.229 + 65.230 + // -- Branches -------------------------------------------------- 65.231 + 65.232 + tagged BLEZ .it : 65.233 + if ( signedLE( rf.rd1(it.rsrc), 0 ) ) 65.234 + next_pc = pc_plus4 + (sext(it.offset) << 2); 65.235 + 65.236 + tagged BGTZ .it : 65.237 + if ( signedGT( rf.rd1(it.rsrc), 0 ) ) 65.238 + next_pc = pc_plus4 + (sext(it.offset) << 2); 65.239 + 65.240 + tagged BLTZ .it : 65.241 + if ( signedLT( rf.rd1(it.rsrc), 0 ) ) 65.242 + next_pc = pc_plus4 + (sext(it.offset) << 2); 65.243 + 65.244 + tagged BGEZ .it : 65.245 + if ( signedGE( rf.rd1(it.rsrc), 0 ) ) 65.246 + next_pc = pc_plus4 + (sext(it.offset) << 2); 65.247 + 65.248 + tagged BEQ .it : 65.249 + if ( rf.rd1(it.rsrc1) == rf.rd2(it.rsrc2) ) 65.250 + next_pc = pc_plus4 + (sext(it.offset) << 2); 65.251 + 65.252 + tagged BNE .it : 65.253 + if ( rf.rd1(it.rsrc1) != rf.rd2(it.rsrc2) ) 65.254 + next_pc = pc_plus4 + (sext(it.offset) << 2); 65.255 + 65.256 + // -- Jumps ----------------------------------------------------- 65.257 + 65.258 + tagged J .it : 65.259 + next_pc = { pc_plus4[31:28], it.target, 2'b0 }; 65.260 + 65.261 + tagged JR .it : 65.262 + next_pc = rf.rd1(it.rsrc); 65.263 + 65.264 + tagged JAL .it : 65.265 + begin 65.266 + rf.wr( 31, pc_plus4 ); 65.267 + next_pc = { pc_plus4[31:28], it.target, 2'b0 }; 65.268 + end 65.269 + 65.270 + tagged JALR .it : 65.271 + begin 65.272 + rf.wr( it.rdst, pc_plus4 ); 65.273 + next_pc = rf.rd1(it.rsrc); 65.274 + end 65.275 + 65.276 + // -- Cop0 ------------------------------------------------------ 65.277 + 65.278 + tagged MTC0 .it : 65.279 + case ( it.cop0dst ) 65.280 + 5'd10 : cp0_statsEn <= unpack(truncate(rf.rd1(it.rsrc))); 65.281 + 5'd21 : cp0_tohost <= truncate(rf.rd1(it.rsrc)); 65.282 + default : 65.283 + $display( " RTL-ERROR : %m : Illegal MTC0 cop0dst register!" ); 65.284 + endcase 65.285 + 65.286 + tagged MFC0 .it : 65.287 + case ( it.cop0src ) 65.288 + 5'd10 : rf.wr( it.rdst, zext(pack(cp0_statsEn)) ); 65.289 + 5'd20 : rf.wr( it.rdst, zext(cp0_fromhost) ); 65.290 + 5'd21 : rf.wr( it.rdst, zext(cp0_tohost) ); 65.291 + default : 65.292 + $display( " RTL-ERROR : %m : Illegal MFC0 cop0src register!" ); 65.293 + endcase 65.294 + 65.295 + // -- Illegal --------------------------------------------------- 65.296 + 65.297 + default : 65.298 + $display( " RTL-ERROR : %m : Illegal instruction !" ); 65.299 + 65.300 + endcase 65.301 + 65.302 + stage <= next_stage; 65.303 + pc <= next_pc; 65.304 + 65.305 + if ( cp0_statsEn ) 65.306 + num_inst <= num_inst + 1; 65.307 + 65.308 + endrule 65.309 + 65.310 + rule writeback ( stage == Writeback ); 65.311 + traceTiny("stage","W"); 65.312 + 65.313 + dataRespQ.deq(); 65.314 + case ( dataRespQ.first() ) matches 65.315 + tagged LoadResp .ld : rf.wr( truncate(ld.tag), ld.data ); 65.316 + tagged StoreResp .st : noAction; 65.317 + endcase 65.318 + 65.319 + stage <= PCgen; 65.320 + endrule 65.321 + 65.322 + rule inc_num_cycles; 65.323 + if ( cp0_statsEn ) 65.324 + num_cycles <= num_cycles + 1; 65.325 + endrule 65.326 + 65.327 + //----------------------------------------------------------- 65.328 + // Methods 65.329 + 65.330 + interface Client imem_client; 65.331 + interface Get request = fifoToGet(instReqQ); 65.332 + interface Put response = fifoToPut(instRespQ); 65.333 + endinterface 65.334 + 65.335 + interface Client dmem_client; 65.336 + interface Get request = fifoToGet(dataReqQ); 65.337 + interface Put response = fifoToPut(dataRespQ); 65.338 + endinterface 65.339 + 65.340 + interface Get testrig_tohost = regToGet(cp0_tohost); 65.341 + interface Put testrig_fromhost = regToPut(cp0_fromhost); 65.342 + interface Get statsEn_get = regToGet(cp0_statsEn); 65.343 + 65.344 +endmodule 65.345 +
66.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 66.2 +++ b/modules/bluespec/Pygar/lab4/ProcTypes.bsv Fri Apr 23 02:32:05 2010 -0400 66.3 @@ -0,0 +1,375 @@ 66.4 + 66.5 +import Trace::*; 66.6 + 66.7 +//---------------------------------------------------------------------- 66.8 +// Other typedefs 66.9 +//---------------------------------------------------------------------- 66.10 + 66.11 +typedef Bit#(32) Addr; 66.12 +typedef Int#(18) Stat; 66.13 + 66.14 +//---------------------------------------------------------------------- 66.15 +// Basic instruction type 66.16 +//---------------------------------------------------------------------- 66.17 + 66.18 +typedef Bit#(5) Rindx; 66.19 +typedef Bit#(16) Simm; 66.20 +typedef Bit#(16) Zimm; 66.21 +typedef Bit#(8) Epoch; 66.22 +typedef Bit#(5) Shamt; 66.23 +typedef Bit#(26) Target; 66.24 +typedef Bit#(5) CP0indx; 66.25 +typedef Bit#(32) Data; 66.26 + 66.27 +typedef enum 66.28 +{ 66.29 + Taken, 66.30 + NotTaken 66.31 +} 66.32 + Direction 66.33 + deriving(Bits,Eq); 66.34 + 66.35 + 66.36 +//---------------------------------------------------------------------- 66.37 +// Pipeline typedefs 66.38 +//---------------------------------------------------------------------- 66.39 + 66.40 +typedef union tagged 66.41 +{ 66.42 + Tuple2#(Rindx,Data) ALUWB; 66.43 + Rindx MemWB; 66.44 + Tuple2#(Rindx,Data) CoWB; 66.45 +} 66.46 + WritebackType 66.47 + deriving(Bits,Eq); 66.48 + 66.49 +//////////////////////// 66.50 +// I Add Writeback queue type 66.51 +//////////// 66.52 +typedef union tagged 66.53 +{ 66.54 + struct {Bit#(32) data; Rindx dest; } WB_ALU; 66.55 + Bit#(32) WB_Host; 66.56 + Rindx WB_Load; 66.57 + void WB_Store; 66.58 +} 66.59 +WBResult deriving(Eq, Bits); 66.60 + 66.61 +typedef struct{Addr qpc; Addr qnxtpc; Epoch qepoch;} PCStat deriving(Eq, Bits); 66.62 +//typedef struct{Addr qpc; Epoch qepoch;} PCStat deriving(Eq, Bits); 66.63 + 66.64 +typedef union tagged 66.65 +{ 66.66 + 66.67 + struct { Rindx rbase; Rindx rdst; Simm offset; } LW; 66.68 + struct { Rindx rbase; Rindx rsrc; Simm offset; } SW; 66.69 + 66.70 + struct { Rindx rsrc; Rindx rdst; Simm imm; } ADDIU; 66.71 + struct { Rindx rsrc; Rindx rdst; Simm imm; } SLTI; 66.72 + struct { Rindx rsrc; Rindx rdst; Simm imm; } SLTIU; 66.73 + struct { Rindx rsrc; Rindx rdst; Zimm imm; } ANDI; 66.74 + struct { Rindx rsrc; Rindx rdst; Zimm imm; } ORI; 66.75 + struct { Rindx rsrc; Rindx rdst; Zimm imm; } XORI; 66.76 + struct { Rindx rdst; Zimm imm; } LUI; 66.77 + 66.78 + struct { Rindx rsrc; Rindx rdst; Shamt shamt; } SLL; 66.79 + struct { Rindx rsrc; Rindx rdst; Shamt shamt; } SRL; 66.80 + struct { Rindx rsrc; Rindx rdst; Shamt shamt; } SRA; 66.81 + struct { Rindx rsrc; Rindx rdst; Rindx rshamt; } SLLV; 66.82 + struct { Rindx rsrc; Rindx rdst; Rindx rshamt; } SRLV; 66.83 + struct { Rindx rsrc; Rindx rdst; Rindx rshamt; } SRAV; 66.84 + struct { Rindx rsrc1; Rindx rsrc2; Rindx rdst; } ADDU; 66.85 + struct { Rindx rsrc1; Rindx rsrc2; Rindx rdst; } SUBU; 66.86 + struct { Rindx rsrc1; Rindx rsrc2; Rindx rdst; } AND; 66.87 + struct { Rindx rsrc1; Rindx rsrc2; Rindx rdst; } OR; 66.88 + struct { Rindx rsrc1; Rindx rsrc2; Rindx rdst; } XOR; 66.89 + struct { Rindx rsrc1; Rindx rsrc2; Rindx rdst; } NOR; 66.90 + struct { Rindx rsrc1; Rindx rsrc2; Rindx rdst; } SLT; 66.91 + struct { Rindx rsrc1; Rindx rsrc2; Rindx rdst; } SLTU; 66.92 + 66.93 + struct { Target target; } J; 66.94 + struct { Target target; } JAL; 66.95 + struct { Rindx rsrc; } JR; 66.96 + struct { Rindx rsrc; Rindx rdst; } JALR; 66.97 + struct { Rindx rsrc1; Rindx rsrc2; Simm offset; } BEQ; 66.98 + struct { Rindx rsrc1; Rindx rsrc2; Simm offset; } BNE; 66.99 + struct { Rindx rsrc; Simm offset; } BLEZ; 66.100 + struct { Rindx rsrc; Simm offset; } BGTZ; 66.101 + struct { Rindx rsrc; Simm offset; } BLTZ; 66.102 + struct { Rindx rsrc; Simm offset; } BGEZ; 66.103 + 66.104 + struct { Rindx rdst; CP0indx cop0src; } MFC0; 66.105 + struct { Rindx rsrc; CP0indx cop0dst; } MTC0; 66.106 + 66.107 + void ILLEGAL; 66.108 + 66.109 +} 66.110 +Instr deriving(Eq); 66.111 + 66.112 +//---------------------------------------------------------------------- 66.113 +// Pack and Unpack 66.114 +//---------------------------------------------------------------------- 66.115 + 66.116 +Bit#(6) opFUNC = 6'b000000; Bit#(6) fcSLL = 6'b000000; 66.117 +Bit#(6) opRT = 6'b000001; Bit#(6) fcSRL = 6'b000010; 66.118 +Bit#(6) opRS = 6'b010000; Bit#(6) fcSRA = 6'b000011; 66.119 + Bit#(6) fcSLLV = 6'b000100; 66.120 +Bit#(6) opLW = 6'b100011; Bit#(6) fcSRLV = 6'b000110; 66.121 +Bit#(6) opSW = 6'b101011; Bit#(6) fcSRAV = 6'b000111; 66.122 + Bit#(6) fcADDU = 6'b100001; 66.123 +Bit#(6) opADDIU = 6'b001001; Bit#(6) fcSUBU = 6'b100011; 66.124 +Bit#(6) opSLTI = 6'b001010; Bit#(6) fcAND = 6'b100100; 66.125 +Bit#(6) opSLTIU = 6'b001011; Bit#(6) fcOR = 6'b100101; 66.126 +Bit#(6) opANDI = 6'b001100; Bit#(6) fcXOR = 6'b100110; 66.127 +Bit#(6) opORI = 6'b001101; Bit#(6) fcNOR = 6'b100111; 66.128 +Bit#(6) opXORI = 6'b001110; Bit#(6) fcSLT = 6'b101010; 66.129 +Bit#(6) opLUI = 6'b001111; Bit#(6) fcSLTU = 6'b101011; 66.130 + 66.131 +Bit#(6) opJ = 6'b000010; 66.132 +Bit#(6) opJAL = 6'b000011; 66.133 +Bit#(6) fcJR = 6'b001000; 66.134 +Bit#(6) fcJALR = 6'b001001; 66.135 +Bit#(6) opBEQ = 6'b000100; 66.136 +Bit#(6) opBNE = 6'b000101; 66.137 +Bit#(6) opBLEZ = 6'b000110; 66.138 +Bit#(6) opBGTZ = 6'b000111; 66.139 +Bit#(5) rtBLTZ = 5'b00000; 66.140 +Bit#(5) rtBGEZ = 5'b00001; 66.141 + 66.142 +Bit#(5) rsMFC0 = 5'b00000; 66.143 +Bit#(5) rsMTC0 = 5'b00100; 66.144 + 66.145 +instance Bits#(Instr,32); 66.146 + 66.147 + // Pack Function 66.148 + 66.149 + function Bit#(32) pack( Instr instr ); 66.150 + 66.151 + case ( instr ) matches 66.152 + 66.153 + tagged LW .it : return { opLW, it.rbase, it.rdst, it.offset }; 66.154 + tagged SW .it : return { opSW, it.rbase, it.rsrc, it.offset }; 66.155 + 66.156 + tagged ADDIU .it : return { opADDIU, it.rsrc, it.rdst, it.imm }; 66.157 + tagged SLTI .it : return { opSLTI, it.rsrc, it.rdst, it.imm }; 66.158 + tagged SLTIU .it : return { opSLTIU, it.rsrc, it.rdst, it.imm }; 66.159 + tagged ANDI .it : return { opANDI, it.rsrc, it.rdst, it.imm }; 66.160 + tagged ORI .it : return { opORI, it.rsrc, it.rdst, it.imm }; 66.161 + tagged XORI .it : return { opXORI, it.rsrc, it.rdst, it.imm }; 66.162 + tagged LUI .it : return { opLUI, 5'b0, it.rdst, it.imm }; 66.163 + 66.164 + tagged SLL .it : return { opFUNC, 5'b0, it.rsrc, it.rdst, it.shamt, fcSLL }; 66.165 + tagged SRL .it : return { opFUNC, 5'b0, it.rsrc, it.rdst, it.shamt, fcSRL }; 66.166 + tagged SRA .it : return { opFUNC, 5'b0, it.rsrc, it.rdst, it.shamt, fcSRA }; 66.167 + 66.168 + tagged SLLV .it : return { opFUNC, it.rshamt, it.rsrc, it.rdst, 5'b0, fcSLLV }; 66.169 + tagged SRLV .it : return { opFUNC, it.rshamt, it.rsrc, it.rdst, 5'b0, fcSRLV }; 66.170 + tagged SRAV .it : return { opFUNC, it.rshamt, it.rsrc, it.rdst, 5'b0, fcSRAV }; 66.171 + 66.172 + tagged ADDU .it : return { opFUNC, it.rsrc1, it.rsrc2, it.rdst, 5'b0, fcADDU }; 66.173 + tagged SUBU .it : return { opFUNC, it.rsrc1, it.rsrc2, it.rdst, 5'b0, fcSUBU }; 66.174 + tagged AND .it : return { opFUNC, it.rsrc1, it.rsrc2, it.rdst, 5'b0, fcAND }; 66.175 + tagged OR .it : return { opFUNC, it.rsrc1, it.rsrc2, it.rdst, 5'b0, fcOR }; 66.176 + tagged XOR .it : return { opFUNC, it.rsrc1, it.rsrc2, it.rdst, 5'b0, fcXOR }; 66.177 + tagged NOR .it : return { opFUNC, it.rsrc1, it.rsrc2, it.rdst, 5'b0, fcNOR }; 66.178 + tagged SLT .it : return { opFUNC, it.rsrc1, it.rsrc2, it.rdst, 5'b0, fcSLT }; 66.179 + tagged SLTU .it : return { opFUNC, it.rsrc1, it.rsrc2, it.rdst, 5'b0, fcSLTU }; 66.180 + 66.181 + tagged J .it : return { opJ, it.target }; 66.182 + tagged JAL .it : return { opJAL, it.target }; 66.183 + tagged JR .it : return { opFUNC, it.rsrc, 5'b0, 5'b0, 5'b0, fcJR }; 66.184 + tagged JALR .it : return { opFUNC, it.rsrc, 5'b0, it.rdst, 5'b0, fcJALR }; 66.185 + tagged BEQ .it : return { opBEQ, it.rsrc1, it.rsrc2, it.offset }; 66.186 + tagged BNE .it : return { opBNE, it.rsrc1, it.rsrc2, it.offset }; 66.187 + tagged BLEZ .it : return { opBLEZ, it.rsrc, 5'b0, it.offset }; 66.188 + tagged BGTZ .it : return { opBGTZ, it.rsrc, 5'b0, it.offset }; 66.189 + tagged BLTZ .it : return { opRT, it.rsrc, rtBLTZ, it.offset }; 66.190 + tagged BGEZ .it : return { opRT, it.rsrc, rtBGEZ, it.offset }; 66.191 + 66.192 + tagged MFC0 .it : return { opRS, rsMFC0, it.rdst, it.cop0src, 11'b0 }; 66.193 + tagged MTC0 .it : return { opRS, rsMTC0, it.rsrc, it.cop0dst, 11'b0 }; 66.194 + 66.195 + endcase 66.196 + 66.197 + endfunction 66.198 + 66.199 + // Unpack Function 66.200 + 66.201 + function Instr unpack( Bit#(32) instrBits ); 66.202 + 66.203 + let opcode = instrBits[ 31 : 26 ]; 66.204 + let rs = instrBits[ 25 : 21 ]; 66.205 + let rt = instrBits[ 20 : 16 ]; 66.206 + let rd = instrBits[ 15 : 11 ]; 66.207 + let shamt = instrBits[ 10 : 6 ]; 66.208 + let funct = instrBits[ 5 : 0 ]; 66.209 + let imm = instrBits[ 15 : 0 ]; 66.210 + let target = instrBits[ 25 : 0 ]; 66.211 + 66.212 + case ( opcode ) 66.213 + 66.214 + opLW : return LW { rbase:rs, rdst:rt, offset:imm }; 66.215 + opSW : return SW { rbase:rs, rsrc:rt, offset:imm }; 66.216 + opADDIU : return ADDIU { rsrc:rs, rdst:rt, imm:imm }; 66.217 + opSLTI : return SLTI { rsrc:rs, rdst:rt, imm:imm }; 66.218 + opSLTIU : return SLTIU { rsrc:rs, rdst:rt, imm:imm }; 66.219 + opANDI : return ANDI { rsrc:rs, rdst:rt, imm:imm }; 66.220 + opORI : return ORI { rsrc:rs, rdst:rt, imm:imm }; 66.221 + opXORI : return XORI { rsrc:rs, rdst:rt, imm:imm }; 66.222 + opLUI : return LUI { rdst:rt, imm:imm }; 66.223 + opJ : return J { target:target }; 66.224 + opJAL : return JAL { target:target }; 66.225 + opBEQ : return BEQ { rsrc1:rs, rsrc2:rt, offset:imm }; 66.226 + opBNE : return BNE { rsrc1:rs, rsrc2:rt, offset:imm }; 66.227 + opBLEZ : return BLEZ { rsrc:rs, offset:imm }; 66.228 + opBGTZ : return BGTZ { rsrc:rs, offset:imm }; 66.229 + 66.230 + opFUNC : 66.231 + case ( funct ) 66.232 + fcSLL : return SLL { rsrc:rt, rdst:rd, shamt:shamt }; 66.233 + fcSRL : return SRL { rsrc:rt, rdst:rd, shamt:shamt }; 66.234 + fcSRA : return SRA { rsrc:rt, rdst:rd, shamt:shamt }; 66.235 + fcSLLV : return SLLV { rsrc:rt, rdst:rd, rshamt:rs }; 66.236 + fcSRLV : return SRLV { rsrc:rt, rdst:rd, rshamt:rs }; 66.237 + fcSRAV : return SRAV { rsrc:rt, rdst:rd, rshamt:rs }; 66.238 + fcADDU : return ADDU { rsrc1:rs, rsrc2:rt, rdst:rd }; 66.239 + fcSUBU : return SUBU { rsrc1:rs, rsrc2:rt, rdst:rd }; 66.240 + fcAND : return AND { rsrc1:rs, rsrc2:rt, rdst:rd }; 66.241 + fcOR : return OR { rsrc1:rs, rsrc2:rt, rdst:rd }; 66.242 + fcXOR : return XOR { rsrc1:rs, rsrc2:rt, rdst:rd }; 66.243 + fcNOR : return NOR { rsrc1:rs, rsrc2:rt, rdst:rd }; 66.244 + fcSLT : return SLT { rsrc1:rs, rsrc2:rt, rdst:rd }; 66.245 + fcSLTU : return SLTU { rsrc1:rs, rsrc2:rt, rdst:rd }; 66.246 + fcJR : return JR { rsrc:rs }; 66.247 + fcJALR : return JALR { rsrc:rs, rdst:rd }; 66.248 + default : return ILLEGAL; 66.249 + endcase 66.250 + 66.251 + opRT : 66.252 + case ( rt ) 66.253 + rtBLTZ : return BLTZ { rsrc:rs, offset:imm }; 66.254 + rtBGEZ : return BGEZ { rsrc:rs, offset:imm }; 66.255 + default : return ILLEGAL; 66.256 + endcase 66.257 + 66.258 + opRS : 66.259 + case ( rs ) 66.260 + rsMFC0 : return MFC0 { rdst:rt, cop0src:rd }; 66.261 + rsMTC0 : return MTC0 { rsrc:rt, cop0dst:rd }; 66.262 + default : return ILLEGAL; 66.263 + endcase 66.264 + 66.265 + default : return ILLEGAL; 66.266 + 66.267 + endcase 66.268 + 66.269 + endfunction 66.270 + 66.271 +endinstance 66.272 + 66.273 +//---------------------------------------------------------------------- 66.274 +// Trace 66.275 +//---------------------------------------------------------------------- 66.276 + 66.277 +instance Traceable#(Instr); 66.278 + 66.279 + function Action traceTiny( String loc, String ttag, Instr inst ); 66.280 + case ( inst ) matches 66.281 + 66.282 + tagged LW .it : $fdisplay(stderr, " => %s:%s lw", loc, ttag ); 66.283 + tagged SW .it : $fdisplay(stderr, " => %s:%s sw", loc, ttag ); 66.284 + 66.285 + tagged ADDIU .it : $fdisplay(stderr, " => %s:%s addi", loc, ttag ); 66.286 + tagged SLTI .it : $fdisplay(stderr, " => %s:%s sli", loc, ttag ); 66.287 + tagged SLTIU .it : $fdisplay(stderr, " => %s:%s sliu", loc, ttag ); 66.288 + tagged ANDI .it : $fdisplay(stderr, " => %s:%s andi", loc, ttag ); 66.289 + tagged ORI .it : $fdisplay(stderr, " => %s:%s ori", loc, ttag ); 66.290 + tagged XORI .it : $fdisplay(stderr, " => %s:%s xori", loc, ttag ); 66.291 + tagged LUI .it : $fdisplay(stderr, " => %s:%s lui", loc, ttag ); 66.292 + 66.293 + tagged SLL .it : $fdisplay(stderr, " => %s:%s sll", loc, ttag ); 66.294 + tagged SRL .it : $fdisplay(stderr, " => %s:%s srl", loc, ttag ); 66.295 + tagged SRA .it : $fdisplay(stderr, " => %s:%s sra", loc, ttag ); 66.296 + tagged SLLV .it : $fdisplay(stderr, " => %s:%s sllv", loc, ttag ); 66.297 + tagged SRLV .it : $fdisplay(stderr, " => %s:%s srlv", loc, ttag ); 66.298 + tagged SRAV .it : $fdisplay(stderr, " => %s:%s srav", loc, ttag ); 66.299 + 66.300 + tagged ADDU .it : $fdisplay(stderr, " => %s:%s addu", loc, ttag ); 66.301 + tagged SUBU .it : $fdisplay(stderr, " => %s:%s subu", loc, ttag ); 66.302 + tagged AND .it : $fdisplay(stderr, " => %s:%s and", loc, ttag ); 66.303 + tagged OR .it : $fdisplay(stderr, " => %s:%s or", loc, ttag ); 66.304 + tagged XOR .it : $fdisplay(stderr, " => %s:%s xor", loc, ttag ); 66.305 + tagged NOR .it : $fdisplay(stderr, " => %s:%s nor", loc, ttag ); 66.306 + tagged SLT .it : $fdisplay(stderr, " => %s:%s slt", loc, ttag ); 66.307 + tagged SLTU .it : $fdisplay(stderr, " => %s:%s sltu", loc, ttag ); 66.308 + 66.309 + tagged J .it : $fdisplay(stderr, " => %s:%s j", loc, ttag ); 66.310 + tagged JAL .it : $fdisplay(stderr, " => %s:%s jal", loc, ttag ); 66.311 + tagged JR .it : $fdisplay(stderr, " => %s:%s jr", loc, ttag ); 66.312 + tagged JALR .it : $fdisplay(stderr, " => %s:%s jalr", loc, ttag ); 66.313 + tagged BEQ .it : $fdisplay(stderr, " => %s:%s beq", loc, ttag ); 66.314 + tagged BNE .it : $fdisplay(stderr, " => %s:%s bne", loc, ttag ); 66.315 + tagged BLEZ .it : $fdisplay(stderr, " => %s:%s blez", loc, ttag ); 66.316 + tagged BGTZ .it : $fdisplay(stderr, " => %s:%s bgtz", loc, ttag ); 66.317 + tagged BLTZ .it : $fdisplay(stderr, " => %s:%s bltz", loc, ttag ); 66.318 + tagged BGEZ .it : $fdisplay(stderr, " => %s:%s bgez", loc, ttag ); 66.319 + 66.320 + tagged MFC0 .it : $fdisplay(stderr, " => %s:%s mfc0", loc, ttag ); 66.321 + tagged MTC0 .it : $fdisplay(stderr, " => %s:%s mtc0", loc, ttag ); 66.322 + 66.323 + tagged ILLEGAL : $fdisplay(stderr, " => %s:%s ill", loc, ttag ); 66.324 + 66.325 + endcase 66.326 + endfunction 66.327 + 66.328 + function Action traceFull( String loc, String ttag, Instr inst ); 66.329 + case ( inst ) matches 66.330 + 66.331 + tagged LW .it : $fdisplay(stderr, " => %s:%s lw r%0d, 0x%x(r%0d)", loc, ttag, it.rdst, it.offset, it.rbase ); 66.332 + tagged SW .it : $fdisplay(stderr, " => %s:%s sw r%0d, 0x%x(r%0d)", loc, ttag, it.rsrc, it.offset, it.rbase ); 66.333 + 66.334 + tagged ADDIU .it : $fdisplay(stderr, " => %s:%s addiu r%0d, r%0d, 0x%x", loc, ttag, it.rdst, it.rsrc, it.imm ); 66.335 + tagged SLTI .it : $fdisplay(stderr, " => %s:%s slti r%0d, r%0d, 0x%x", loc, ttag, it.rdst, it.rsrc, it.imm ); 66.336 + tagged SLTIU .it : $fdisplay(stderr, " => %s:%s sltiu r%0d, r%0d, 0x%x", loc, ttag, it.rdst, it.rsrc, it.imm ); 66.337 + tagged ANDI .it : $fdisplay(stderr, " => %s:%s andi r%0d, r%0d, 0x%x", loc, ttag, it.rdst, it.rsrc, it.imm ); 66.338 + tagged ORI .it : $fdisplay(stderr, " => %s:%s ori r%0d, r%0d, 0x%x", loc, ttag, it.rdst, it.rsrc, it.imm ); 66.339 + tagged XORI .it : $fdisplay(stderr, " => %s:%s xori r%0d, r%0d, 0x%x", loc, ttag, it.rdst, it.rsrc, it.imm ); 66.340 + tagged LUI .it : $fdisplay(stderr, " => %s:%s lui r%0d, 0x%x", loc, ttag, it.rdst, it.imm ); 66.341 + 66.342 + tagged SLL .it : $fdisplay(stderr, " => %s:%s sll r%0d, r%0d, %0d", loc, ttag, it.rdst, it.rsrc, it.shamt ); 66.343 + tagged SRL .it : $fdisplay(stderr, " => %s:%s srl r%0d, r%0d, %0d", loc, ttag, it.rdst, it.rsrc, it.shamt ); 66.344 + tagged SRA .it : $fdisplay(stderr, " => %s:%s sra r%0d, r%0d, %0d", loc, ttag, it.rdst, it.rsrc, it.shamt ); 66.345 + tagged SLLV .it : $fdisplay(stderr, " => %s:%s sllv r%0d, r%0d, r%0d", loc, ttag, it.rdst, it.rsrc, it.rshamt ); 66.346 + tagged SRLV .it : $fdisplay(stderr, " => %s:%s srlv r%0d, r%0d, r%0d", loc, ttag, it.rdst, it.rsrc, it.rshamt ); 66.347 + tagged SRAV .it : $fdisplay(stderr, " => %s:%s srav r%0d, r%0d, r%0d", loc, ttag, it.rdst, it.rsrc, it.rshamt ); 66.348 + 66.349 + tagged ADDU .it : $fdisplay(stderr, " => %s:%s addu r%0d, r%0d, r%0d", loc, ttag, it.rdst, it.rsrc1, it.rsrc2 ); 66.350 + tagged SUBU .it : $fdisplay(stderr, " => %s:%s subu r%0d, r%0d, r%0d", loc, ttag, it.rdst, it.rsrc1, it.rsrc2 ); 66.351 + tagged AND .it : $fdisplay(stderr, " => %s:%s and r%0d, r%0d, r%0d", loc, ttag, it.rdst, it.rsrc1, it.rsrc2 ); 66.352 + tagged OR .it : $fdisplay(stderr, " => %s:%s or r%0d, r%0d, r%0d", loc, ttag, it.rdst, it.rsrc1, it.rsrc2 ); 66.353 + tagged XOR .it : $fdisplay(stderr, " => %s:%s xor r%0d, r%0d, r%0d", loc, ttag, it.rdst, it.rsrc1, it.rsrc2 ); 66.354 + tagged NOR .it : $fdisplay(stderr, " => %s:%s nor r%0d, r%0d, r%0d", loc, ttag, it.rdst, it.rsrc1, it.rsrc2 ); 66.355 + tagged SLT .it : $fdisplay(stderr, " => %s:%s slt r%0d, r%0d, r%0d", loc, ttag, it.rdst, it.rsrc1, it.rsrc2 ); 66.356 + tagged SLTU .it : $fdisplay(stderr, " => %s:%s sltu r%0d, r%0d, r%0d", loc, ttag, it.rdst, it.rsrc1, it.rsrc2 ); 66.357 + 66.358 + tagged J .it : $fdisplay(stderr, " => %s:%s j 0x%x", loc, ttag, it.target ); 66.359 + tagged JAL .it : $fdisplay(stderr, " => %s:%s jal 0x%x", loc, ttag, it.target ); 66.360 + tagged JR .it : $fdisplay(stderr, " => %s:%s jr r%0d", loc, ttag, it.rsrc ); 66.361 + tagged JALR .it : $fdisplay(stderr, " => %s:%s jalr r%0d", loc, ttag, it.rsrc ); 66.362 + tagged BEQ .it : $fdisplay(stderr, " => %s:%s beq r%0d, r%0d, 0x%x", loc, ttag, it.rsrc1, it.rsrc2, it.offset ); 66.363 + tagged BNE .it : $fdisplay(stderr, " => %s:%s bne r%0d, r%0d, 0x%x", loc, ttag, it.rsrc1, it.rsrc2, it.offset ); 66.364 + tagged BLEZ .it : $fdisplay(stderr, " => %s:%s blez r%0d, 0x%x", loc, ttag, it.rsrc, it.offset ); 66.365 + tagged BGTZ .it : $fdisplay(stderr, " => %s:%s bgtz r%0d, 0x%x", loc, ttag, it.rsrc, it.offset ); 66.366 + tagged BLTZ .it : $fdisplay(stderr, " => %s:%s bltz r%0d, 0x%x", loc, ttag, it.rsrc, it.offset ); 66.367 + tagged BGEZ .it : $fdisplay(stderr, " => %s:%s bgez r%0d, 0x%x", loc, ttag, it.rsrc, it.offset ); 66.368 + 66.369 + tagged MFC0 .it : $fdisplay(stderr, " => %s:%s mfc0 r%0d, cpr%0d", loc, ttag, it.rdst, it.cop0src ); 66.370 + tagged MTC0 .it : $fdisplay(stderr, " => %s:%s mtc0 r%0d, cpr%0d", loc, ttag, it.rsrc, it.cop0dst ); 66.371 + 66.372 + tagged ILLEGAL : $fdisplay(stderr, " => %s:%s illegal instruction", loc, ttag ); 66.373 + 66.374 + endcase 66.375 + endfunction 66.376 + 66.377 +endinstance 66.378 +
67.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 67.2 +++ b/modules/bluespec/Pygar/lab4/Processor.bsv Fri Apr 23 02:32:05 2010 -0400 67.3 @@ -0,0 +1,590 @@ 67.4 +/// The MIT License 67.5 + 67.6 +// Copyright (c) 2009 Massachusetts Institute of Technology 67.7 + 67.8 +// Permission is hereby granted, free of charge, to any person obtaining a copy 67.9 +// of this software and associated documentation files (the "Software"), to deal 67.10 +// in the Software without restriction, including without limitation the rights 67.11 +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 67.12 +// copies of the Software, and to permit persons to whom the Software is 67.13 +// furnished to do so, subject to the following conditions: 67.14 + 67.15 +// The above copyright notice and this permission notice shall be included in 67.16 +// all copies or substantial portions of the Software. 67.17 + 67.18 +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 67.19 +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 67.20 +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 67.21 +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 67.22 +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 67.23 +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 67.24 +// THE SOFTWARE. 67.25 + 67.26 +import Connectable::*; 67.27 +import GetPut::*; 67.28 +import ClientServer::*; 67.29 +import RegFile::*; 67.30 + 67.31 +import FIFO::*; 67.32 +import FIFOF::*; 67.33 +import SFIFO::*; 67.34 +import RWire::*; 67.35 + 67.36 +import BFIFO::*; 67.37 +import MemTypes::*; 67.38 +import ProcTypes::*; 67.39 +import BRegFile::*; 67.40 +import BranchPred::*; 67.41 +//import PathTypes::*; This is only there to force the debugging 67.42 + 67.43 +import Trace::*; 67.44 + 67.45 +//AWB includes 67.46 +`include "asim/provides/low_level_platform_interface.bsh" 67.47 +`include "asim/provides/soft_connections.bsh" 67.48 +`include "asim/provides/common_services.bsh" 67.49 + 67.50 +// Local includes 67.51 +`include "asim/provides/processor_library.bsh" 67.52 +`include "asim/rrr/remote_server_stub_PROCESSORSYSTEMRRR.bsh" 67.53 +`include "asim/provides/common_services.bsh" 67.54 +`include "asim/dict/STATS_PROCESSOR.bsh" 67.55 + 67.56 +interface ProcStats; 67.57 + interface Get#(Stat) num_cycles; 67.58 + interface Get#(Stat) num_inst; 67.59 +endinterface 67.60 + 67.61 +interface CPUToHost; 67.62 + method Bit#(32) cpuToHost(int req); 67.63 +endinterface 67.64 + 67.65 +interface Proc; 67.66 + 67.67 + // Interface from processor to caches 67.68 + interface Client#(DataReq,DataResp) dmem_client; 67.69 + interface Client#(InstReq,InstResp) imem_client; 67.70 + 67.71 + // Interface for enabling/disabling statistics on the rest of the core 67.72 + interface Get#(Bool) statsEn_get; 67.73 + 67.74 + // Interface for collecting statistics. 67.75 + interface ProcStats stats; 67.76 + 67.77 + // Interface to host 67.78 + interface CPUToHost tohost; 67.79 + 67.80 +endinterface 67.81 + 67.82 + 67.83 +typedef enum { PCgen, Exec, Writeback } Stage deriving(Eq,Bits); 67.84 + 67.85 +//----------------------------------------------------------- 67.86 +// Register file module 67.87 +//----------------------------------------------------------- 67.88 + 67.89 +interface BRFile; 67.90 + method Action wr( Rindx rindx, Bit#(32) data ); 67.91 + method Bit#(32) rd1( Rindx rindx ); 67.92 + method Bit#(32) rd2( Rindx rindx ); 67.93 +endinterface 67.94 + 67.95 +module mkBRFile( BRFile ); 67.96 + 67.97 + RegFile#(Rindx,Bit#(32)) rfile <- mkBRegFile(); 67.98 + 67.99 + method Action wr( Rindx rindx, Bit#(32) data ); 67.100 + rfile.upd( rindx, data ); 67.101 + endmethod 67.102 + 67.103 + method Bit#(32) rd1( Rindx rindx ); 67.104 + return ( rindx == 0 ) ? 0 : rfile.sub(rindx); 67.105 + endmethod 67.106 + 67.107 + method Bit#(32) rd2( Rindx rindx ); 67.108 + return ( rindx == 0 ) ? 0 : rfile.sub(rindx); 67.109 + endmethod 67.110 + 67.111 +endmodule 67.112 + 67.113 +//----------------------------------------------------------- 67.114 +// Helper functions 67.115 +//----------------------------------------------------------- 67.116 + 67.117 +function Bit#(32) slt( Bit#(32) val1, Bit#(32) val2 ); 67.118 + return zeroExtend( pack( signedLT(val1,val2) ) ); 67.119 +endfunction 67.120 + 67.121 +function Bit#(32) sltu( Bit#(32) val1, Bit#(32) val2 ); 67.122 + return zeroExtend( pack( val1 < val2 ) ); 67.123 +endfunction 67.124 + 67.125 +function Bit#(32) rshft( Bit#(32) val ); 67.126 + return zeroExtend(val[4:0]); 67.127 +endfunction 67.128 + 67.129 + 67.130 +//----------------------------------------------------------- 67.131 +// Find funct for wbQ 67.132 +//----------------------------------------------------------- 67.133 +function Bool findwbf(Rindx fVal, WBResult cmpVal); 67.134 + case (cmpVal) matches 67.135 + tagged WB_ALU {data:.res, dest:.rd} : 67.136 + return (fVal == rd); 67.137 + tagged WB_Load .rd : 67.138 + return (fVal == rd); 67.139 + tagged WB_Store .st : 67.140 + return False; 67.141 + tagged WB_Host .x : 67.142 + return False; 67.143 + endcase 67.144 +endfunction 67.145 + 67.146 + 67.147 +//----------------------------------------------------------- 67.148 +// Stall funct for wbQ 67.149 +//----------------------------------------------------------- 67.150 +function Bool stall(Instr inst, SFIFO#(WBResult, Rindx) f); 67.151 + case (inst) matches 67.152 + // -- Memory Ops ------------------------------------------------ 67.153 + tagged LW .it : 67.154 + return f.find(it.rbase); 67.155 + tagged SW {rsrc:.dreg, rbase:.addr, offset:.o} : 67.156 + return (f.find(addr) || f.find2(dreg)); 67.157 + 67.158 + // -- Simple Ops ------------------------------------------------ 67.159 + tagged ADDIU .it : return f.find(it.rsrc); 67.160 + tagged SLTI .it : return f.find(it.rsrc); 67.161 + tagged SLTIU .it : return f.find(it.rsrc); 67.162 + tagged ANDI .it : return f.find(it.rsrc); 67.163 + tagged ORI .it : return f.find(it.rsrc); 67.164 + tagged XORI .it : return f.find(it.rsrc); 67.165 + 67.166 + tagged LUI .it : return f.find(it.rdst); //this rds/wrs itself 67.167 + tagged SLL .it : return f.find(it.rsrc); 67.168 + tagged SRL .it : return f.find(it.rsrc); 67.169 + tagged SRA .it : return f.find(it.rsrc); 67.170 + tagged SLLV .it : return (f.find(it.rsrc) || f.find(it.rshamt)); 67.171 + tagged SRLV .it : return (f.find(it.rsrc) || f.find(it.rshamt)); 67.172 + tagged SRAV .it : return (f.find(it.rsrc) || f.find(it.rshamt)); 67.173 + tagged ADDU .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2)); 67.174 + tagged SUBU .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2)); 67.175 + tagged AND .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2)); 67.176 + tagged OR .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2)); 67.177 + tagged XOR .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2)); 67.178 + tagged NOR .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2)); 67.179 + tagged SLT .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2)); 67.180 + tagged SLTU .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2)); 67.181 + 67.182 + 67.183 + // -- Branches -------------------------------------------------- 67.184 + 67.185 + tagged BLEZ .it : return (f.find(it.rsrc)); 67.186 + tagged BGTZ .it : return (f.find(it.rsrc)); 67.187 + tagged BLTZ .it : return (f.find(it.rsrc)); 67.188 + tagged BGEZ .it : return (f.find(it.rsrc)); 67.189 + tagged BEQ .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2)); 67.190 + tagged BNE .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2)); 67.191 + 67.192 + // -- Jumps ----------------------------------------------------- 67.193 + 67.194 + tagged J .it : return False; 67.195 + tagged JR .it : return f.find(it.rsrc); 67.196 + tagged JALR .it : return f.find(it.rsrc); 67.197 + tagged JAL .it : return False; 67.198 + 67.199 + // -- Cop0 ------------------------------------------------------ 67.200 + 67.201 + tagged MTC0 .it : return f.find(it.rsrc); 67.202 + tagged MFC0 .it : return False; 67.203 + 67.204 + // -- Illegal --------------------------------------------------- 67.205 + 67.206 + default : return False; 67.207 + 67.208 + endcase 67.209 +endfunction 67.210 +//----------------------------------------------------------- 67.211 +// Reference processor 67.212 +//----------------------------------------------------------- 67.213 + 67.214 + 67.215 +//(* doc = "synthesis attribute ram_style mkProc distributed;" *) 67.216 +//(* synthesize *) 67.217 + 67.218 +module [CONNECTED_MODULE] mkProc( Proc ); 67.219 + 67.220 + //----------------------------------------------------------- 67.221 + // Debug port 67.222 + 67.223 + ServerStub_PROCESSORSYSTEMRRR server_stub <- mkServerStub_PROCESSORSYSTEMRRR(); 67.224 + 67.225 + 67.226 + //----------------------------------------------------------- 67.227 + // State 67.228 + 67.229 + // Standard processor state 67.230 + 67.231 + Reg#(Addr) pc <- mkReg(32'h00001000); 67.232 + Reg#(Epoch) epoch <- mkReg(0); 67.233 + Reg#(Stage) stage <- mkReg(PCgen); 67.234 + BRFile rf <- mkBRFile; 67.235 + 67.236 + // Branch Prediction 67.237 + BranchPred bp <- mkBranchPred(); 67.238 + FIFO#(PCStat) execpc <- mkLFIFO(); 67.239 + 67.240 + // Pipelines 67.241 + FIFO#(PCStat) pcQ <-mkSizedFIFO(3); 67.242 + SFIFO#(WBResult, Rindx) wbQ <-mkSFIFO(findwbf); 67.243 + 67.244 + Reg#(Bit#(32)) cp0_tohost <- mkReg(0); 67.245 + Reg#(Bit#(32)) cp0_fromhost <- mkReg(0); 67.246 + Reg#(Bool) cp0_statsEn <- mkReg(False); 67.247 + 67.248 + // Memory request/response state 67.249 + 67.250 + FIFO#(InstReq) instReqQ <- mkBFIFO1(); 67.251 + FIFO#(InstResp) instRespQ <- mkFIFO(); 67.252 + 67.253 + FIFO#(DataReq) dataReqQ <- mkBFIFO1(); 67.254 + FIFO#(DataResp) dataRespQ <- mkFIFO(); 67.255 + 67.256 + // Statistics state 67.257 + Reg#(Stat) num_cycles <- mkReg(0); 67.258 + Reg#(Stat) num_inst <- mkReg(0); 67.259 + 67.260 + //Or: 67.261 + // Statistics state 67.262 + //STAT num_cycles <- mkStatCounter(`STATS_PROCESSOR_CYCLE_COUNT); 67.263 + //STAT num_inst <- mkStatCounter(`STATS_PROCESSOR_INST_COUNT); 67.264 + 67.265 + //----------------------------------------------------------- 67.266 + // Rules 67.267 + 67.268 + (* descending_urgency = "exec, pcgen" *) 67.269 + rule pcgen; //( stage == PCgen ); 67.270 + let pc_plus4 = pc + 4; 67.271 + 67.272 + traceTiny("mkProc", "pc",pc); 67.273 + traceTiny("mkProc", "pcgen","P"); 67.274 + instReqQ.enq( LoadReq{ addr:pc, tag:epoch} ); 67.275 + 67.276 + let next_pc = bp.get(pc); 67.277 + if (next_pc matches tagged Valid .npc) 67.278 + begin 67.279 + pcQ.enq(PCStat {qpc:pc, qnxtpc:npc, qepoch:epoch}); 67.280 + pc <= npc; 67.281 + end 67.282 + else 67.283 + begin 67.284 + pcQ.enq(PCStat {qpc:pc, qnxtpc:pc_plus4, qepoch:epoch}); 67.285 + pc <= pc_plus4; 67.286 + end 67.287 + 67.288 + endrule 67.289 + 67.290 + rule discard (instRespQ.first() matches tagged LoadResp .ld 67.291 + &&& ld.tag != epoch); 67.292 + traceTiny("mkProc", "stage", "D"); 67.293 + instRespQ.deq(); 67.294 + endrule 67.295 + 67.296 + (* conflict_free = "exec, writeback" *) 67.297 + rule exec (instRespQ.first() matches tagged LoadResp.ld 67.298 + &&& (ld.tag == epoch) 67.299 + &&& unpack(ld.data) matches .inst 67.300 + &&& !stall(inst, wbQ)); 67.301 + 67.302 + // Some abbreviations 67.303 + let sext = signExtend; 67.304 + let zext = zeroExtend; 67.305 + let sra = signedShiftRight; 67.306 + 67.307 + // Get the instruction 67.308 + 67.309 + instRespQ.deq(); 67.310 + Instr inst 67.311 + = case ( instRespQ.first() ) matches 67.312 + tagged LoadResp .ld : return unpack(ld.data); 67.313 + tagged StoreResp .st : return ?; 67.314 + endcase; 67.315 + 67.316 + // Get the PC info 67.317 + let instrpc = pcQ.first().qpc; 67.318 + let pc_plus4 = instrpc + 4; 67.319 + 67.320 + Bool branchTaken = False; 67.321 + Addr newPC = pc_plus4; 67.322 + 67.323 + // Tracing 67.324 + traceTiny("mkProc", "exec","X"); 67.325 + traceTiny("mkProc", "exInstTiny",inst); 67.326 + traceFull("mkProc", "exInstFull",inst); 67.327 + 67.328 + case ( inst ) matches 67.329 + 67.330 + // -- Memory Ops ------------------------------------------------ 67.331 + 67.332 + tagged LW .it : 67.333 + begin 67.334 + Addr addr = rf.rd1(it.rbase) + sext(it.offset); 67.335 + dataReqQ.enq( LoadReq{ addr:addr, tag:zeroExtend(it.rdst) } ); 67.336 + wbQ.enq(tagged WB_Load it.rdst); 67.337 + end 67.338 + 67.339 + tagged SW .it : 67.340 + begin 67.341 + Addr addr = rf.rd1(it.rbase) + sext(it.offset); 67.342 + dataReqQ.enq( StoreReq{ tag:0, addr:addr, data:rf.rd2(it.rsrc) } ); 67.343 + wbQ.enq(tagged WB_Store); 67.344 + end 67.345 + 67.346 + // -- Simple Ops ------------------------------------------------ 67.347 + 67.348 + tagged ADDIU .it : 67.349 + begin 67.350 + Bit#(32) result = rf.rd1(it.rsrc) + sext(it.imm); 67.351 + wbQ.enq(tagged WB_ALU {data:result, dest:it.rdst}); 67.352 + end 67.353 + tagged SLTI .it : wbQ.enq(tagged WB_ALU {dest:it.rdst, data:slt( rf.rd1(it.rsrc), sext(it.imm) )}); 67.354 + tagged SLTIU .it : wbQ.enq(tagged WB_ALU {dest:it.rdst, data:sltu( rf.rd1(it.rsrc), sext(it.imm) ) }); 67.355 + tagged ANDI .it : 67.356 + begin 67.357 + Bit#(32) zext_it_imm = zext(it.imm); 67.358 + wbQ.enq(tagged WB_ALU {dest:it.rdst, data:(rf.rd1(it.rsrc) & zext_it_imm)} ); 67.359 + end 67.360 + tagged ORI .it : 67.361 + begin 67.362 + Bit#(32) zext_it_imm = zext(it.imm); 67.363 + wbQ.enq(tagged WB_ALU {dest:it.rdst, data:(rf.rd1(it.rsrc) | zext_it_imm)} ); 67.364 + end 67.365 + tagged XORI .it : 67.366 + begin 67.367 + Bit#(32) zext_it_imm = zext(it.imm); 67.368 + wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc) ^ zext_it_imm )}); 67.369 + end 67.370 + tagged LUI .it : 67.371 + begin 67.372 + Bit#(32) zext_it_imm = zext(it.imm); 67.373 + wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(zext_it_imm << 32'd16) }); 67.374 + end 67.375 + 67.376 + tagged SLL .it : 67.377 + begin 67.378 + Bit#(32) zext_it_shamt = zext(it.shamt); 67.379 + wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc) << zext_it_shamt )} ); 67.380 + end 67.381 + tagged SRL .it : 67.382 + begin 67.383 + Bit#(32) zext_it_shamt = zext(it.shamt); 67.384 + wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc) >> zext_it_shamt )}); 67.385 + end 67.386 + tagged SRA .it : 67.387 + begin 67.388 + Bit#(32) zext_it_shamt = zext(it.shamt); 67.389 + wbQ.enq(tagged WB_ALU {dest: it.rdst, data:sra( rf.rd1(it.rsrc), zext_it_shamt )}); 67.390 + end 67.391 + tagged SLLV .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc) << rshft(rf.rd2(it.rshamt)) )}); 67.392 + tagged SRLV .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc) >> rshft(rf.rd2(it.rshamt)) )} ); 67.393 + tagged SRAV .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:sra( rf.rd1(it.rsrc), rshft(rf.rd2(it.rshamt)) ) }); 67.394 + tagged ADDU .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc1) + rf.rd2(it.rsrc2) )} ); 67.395 + tagged SUBU .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc1) - rf.rd2(it.rsrc2) )} ); 67.396 + tagged AND .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc1) & rf.rd2(it.rsrc2) )} ); 67.397 + tagged OR .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc1) | rf.rd2(it.rsrc2) )} ); 67.398 + tagged XOR .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc1) ^ rf.rd2(it.rsrc2) )} ); 67.399 + tagged NOR .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(~(rf.rd1(it.rsrc1) | rf.rd2(it.rsrc2)) )} ); 67.400 + tagged SLT .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:slt( rf.rd1(it.rsrc1), rf.rd2(it.rsrc2) ) }); 67.401 + tagged SLTU .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:sltu( rf.rd1(it.rsrc1), rf.rd2(it.rsrc2) ) }); 67.402 + 67.403 + // -- Branches -------------------------------------------------- 67.404 + 67.405 + tagged BLEZ .it : 67.406 + if ( signedLE( rf.rd1(it.rsrc), 0 ) ) 67.407 + begin 67.408 + newPC = pc_plus4 + (sext(it.offset) << 2); 67.409 + branchTaken = True; 67.410 + end 67.411 + 67.412 + tagged BGTZ .it : 67.413 + if ( signedGT( rf.rd1(it.rsrc), 0 ) ) 67.414 + begin 67.415 + newPC = pc_plus4 + (sext(it.offset) << 2); 67.416 + branchTaken = True; 67.417 + end 67.418 + 67.419 + tagged BLTZ .it : 67.420 + if ( signedLT( rf.rd1(it.rsrc), 0 ) ) 67.421 + begin 67.422 + newPC = pc_plus4 + (sext(it.offset) << 2); 67.423 + branchTaken = True; 67.424 + end 67.425 + 67.426 + tagged BGEZ .it : 67.427 + if ( signedGE( rf.rd1(it.rsrc), 0 ) ) 67.428 + begin 67.429 + newPC = pc_plus4 + (sext(it.offset) << 2); 67.430 + branchTaken = True; 67.431 + end 67.432 + 67.433 + tagged BEQ .it : 67.434 + if ( rf.rd1(it.rsrc1) == rf.rd2(it.rsrc2) ) 67.435 + begin 67.436 + newPC = pc_plus4 + (sext(it.offset) << 2); 67.437 + branchTaken = True; 67.438 + end 67.439 + 67.440 + tagged BNE .it : 67.441 + if ( rf.rd1(it.rsrc1) != rf.rd2(it.rsrc2) ) 67.442 + begin 67.443 + newPC = pc_plus4 + (sext(it.offset) << 2); 67.444 + branchTaken = True; 67.445 + end 67.446 + 67.447 + // -- Jumps ----------------------------------------------------- 67.448 + 67.449 + tagged J .it : 67.450 + begin 67.451 + newPC = { pc_plus4[31:28], it.target, 2'b0 }; 67.452 + branchTaken = True; 67.453 + end 67.454 + 67.455 + tagged JR .it : 67.456 + begin 67.457 + newPC = rf.rd1(it.rsrc); 67.458 + branchTaken = True; 67.459 + end 67.460 + 67.461 + tagged JAL .it : 67.462 + begin 67.463 + wbQ.enq(tagged WB_ALU {dest:31, data:pc_plus4 }); 67.464 + newPC = { pc_plus4[31:28], it.target, 2'b0 }; 67.465 + branchTaken = True; 67.466 + end 67.467 + 67.468 + tagged JALR .it : 67.469 + begin 67.470 + wbQ.enq(tagged WB_ALU {dest:it.rdst, data:pc_plus4 }); 67.471 + newPC = rf.rd1(it.rsrc); 67.472 + branchTaken = True; 67.473 + end 67.474 + 67.475 + // -- Cop0 ------------------------------------------------------ 67.476 + 67.477 + tagged MTC0 .it : 67.478 + begin 67.479 + case ( it.cop0dst ) 67.480 + 5'd10 : cp0_statsEn <= unpack(truncate(rf.rd1(it.rsrc))); 67.481 + 5'd21 : cp0_tohost <= truncate(rf.rd1(it.rsrc)); 67.482 + default : 67.483 + $display( " RTL-ERROR : %m : Illegal MTC0 cop0dst register!" ); 67.484 + endcase 67.485 + wbQ.enq(tagged WB_Host 0); //no idea wwhat this actually should be. 67.486 + end 67.487 + 67.488 +//this is host stuff? 67.489 + tagged MFC0 .it : 67.490 + begin 67.491 + case ( it.cop0src ) 67.492 + // not actually an ALU instruction but don't have the format otherwise 67.493 + 5'd10 : wbQ.enq(tagged WB_ALU {dest:it.rdst, data:zext(pack(cp0_statsEn)) }); 67.494 + 5'd20 : wbQ.enq(tagged WB_ALU {dest:it.rdst, data:cp0_fromhost }); 67.495 + 5'd21 : wbQ.enq(tagged WB_ALU {dest:it.rdst, data:cp0_tohost }); 67.496 + default : 67.497 + $display( " RTL-ERROR : %m : Illegal MFC0 cop0src register!" ); 67.498 + endcase 67.499 + end 67.500 + 67.501 + // -- Illegal --------------------------------------------------- 67.502 + 67.503 + default : 67.504 + $display( " RTL-ERROR : %m : Illegal instruction !" ); 67.505 + 67.506 + endcase 67.507 + 67.508 +//evaluate branch prediction 67.509 + Addr ppc = pcQ.first().qnxtpc; //predicted branch 67.510 + if (ppc != newPC) //prediction wrong 67.511 + begin 67.512 + epoch <= pcQ.first().qepoch + 1; 67.513 + bp.upd(instrpc, newPC); //update branch predictor 67.514 + pcQ.clear(); 67.515 + pc <= newPC; 67.516 + end 67.517 + else 67.518 + pcQ.deq(); 67.519 + 67.520 + if ( cp0_statsEn ) 67.521 + num_inst <= num_inst+1; 67.522 + 67.523 + endrule 67.524 + 67.525 + rule writeback; // ( stage == Writeback ); 67.526 + traceTiny("mkProc", "writeback","W"); 67.527 + 67.528 + 67.529 + // get what to do off the writeback queue 67.530 + wbQ.deq(); 67.531 + case (wbQ.first()) matches 67.532 + tagged WB_ALU {data:.res, dest:.rdst} : rf.wr(rdst, res); 67.533 + tagged WB_Load .regWr : 67.534 + begin 67.535 + dataRespQ.deq(); 67.536 + if (dataRespQ.first() matches tagged LoadResp .ld) 67.537 + rf.wr(truncate(ld.tag), ld.data); // no need to use Rindx from queue? Duplicate? 67.538 + end 67.539 + tagged WB_Store : dataRespQ.deq(); 67.540 + tagged WB_Host .dat : noAction; 67.541 + endcase 67.542 + 67.543 + endrule 67.544 + 67.545 + rule inc_num_cycles; 67.546 + if ( cp0_statsEn ) 67.547 + num_cycles <= num_cycles+1; 67.548 + endrule 67.549 +// THis rule breaks things 67.550 +// rule handleCPUToHost; 67.551 +// let req <- server_stub.acceptRequest_ReadCPUToHost(); 67.552 +// case (req) 67.553 +// 0: server_stub.sendResponse_ReadCPUToHost(cp0_tohost); 67.554 +// 1: server_stub.sendResponse_ReadCPUToHost(pc); 67.555 +// 2: server_stub.sendResponse_ReadCPUToHost(zeroExtend(pack(stage))); 67.556 +// endcase 67.557 +// endrule 67.558 +//----------------------------------------------------------- 67.559 +// My Adds 67.560 +//----------------------------------------------------------- 67.561 + 67.562 + //----------------------------------------------------------- 67.563 + // Methods 67.564 + 67.565 + interface Client imem_client; 67.566 + interface Get request = toGet(instReqQ); 67.567 + interface Put response = toPut(instRespQ); 67.568 + endinterface 67.569 + 67.570 + interface Client dmem_client; 67.571 + interface Get request = toGet(dataReqQ); 67.572 + interface Put response = toPut(dataRespQ); 67.573 + endinterface 67.574 + 67.575 + interface Get statsEn_get = toGet(asReg(cp0_statsEn)); 67.576 + 67.577 + interface ProcStats stats; 67.578 + interface Get num_cycles = toGet(asReg(num_cycles)); 67.579 + interface Get num_inst = toGet(asReg(num_inst)); 67.580 + endinterface 67.581 + 67.582 + interface CPUToHost tohost; 67.583 + method Bit#(32) cpuToHost(int req); 67.584 + return (case (req) 67.585 + 0: cp0_tohost; 67.586 + 1: pc; 67.587 + 2: zeroExtend(pack(stage)); 67.588 + endcase); 67.589 + endmethod 67.590 + endinterface 67.591 + 67.592 +endmodule 67.593 +
68.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 68.2 +++ b/modules/bluespec/Pygar/lab4/Processor.dic Fri Apr 23 02:32:05 2010 -0400 68.3 @@ -0,0 +1,2 @@ 68.4 +def STATS.PROCESSOR.CYCLE_COUNT "PROCESSOR: Cycle count: "; 68.5 +def STATS.PROCESSOR.INST_COUNT "PROCESSOR: Instruction count: ";
69.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 69.2 +++ b/modules/bluespec/Pygar/lab4/ProcessorSystem.bsv Fri Apr 23 02:32:05 2010 -0400 69.3 @@ -0,0 +1,82 @@ 69.4 +// The MIT License 69.5 + 69.6 +// Copyright (c) 2009 Massachusetts Institute of Technology 69.7 + 69.8 +// Permission is hereby granted, free of charge, to any person obtaining a copy 69.9 +// of this software and associated documentation files (the "Software"), to deal 69.10 +// in the Software without restriction, including without limitation the rights 69.11 +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 69.12 +// copies of the Software, and to permit persons to whom the Software is 69.13 +// furnished to do so, subject to the following conditions: 69.14 + 69.15 +// The above copyright notice and this permission notice shall be included in 69.16 +// all copies or substantial portions of the Software. 69.17 + 69.18 +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 69.19 +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 69.20 +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 69.21 +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 69.22 +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 69.23 +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 69.24 +// THE SOFTWARE. 69.25 + 69.26 +import Connectable::*; 69.27 +import GetPut::*; 69.28 +import ClientServer::*; 69.29 +import FIFO::*; 69.30 +import SpecialFIFOs::*; 69.31 + 69.32 +//AWB includes 69.33 +`include "asim/provides/low_level_platform_interface.bsh" 69.34 +`include "asim/provides/soft_connections.bsh" 69.35 +`include "asim/provides/common_services.bsh" 69.36 + 69.37 + 69.38 +// Local includes 69.39 +`include "asim/provides/core.bsh" 69.40 +`include "asim/provides/processor_library.bsh" 69.41 +`include "asim/provides/processor_library.bsh" 69.42 +`include "asim/provides/fpga_components.bsh" 69.43 +`include "asim/rrr/remote_client_stub_PROCESSORSYSTEMRRR.bsh" 69.44 + 69.45 +module [CONNECTED_MODULE] mkConnectedApplication (); 69.46 + 69.47 + Core core <- mkCore; 69.48 + Reg#(int) cycle <- mkReg(0); 69.49 + 69.50 + //External memory 69.51 + // I'm not comfortable assuming that the memory subsystem is in order 69.52 + // So I'll insert a completion buffer here. 69.53 + ClientStub_PROCESSORSYSTEMRRR client_stub <- mkClientStub_PROCESSORSYSTEMRRR(); 69.54 + // Make this big enough so that several outstanding requests may be supported 69.55 + FIFO#(Bit#(MainMemTagSz)) tags <- mkSizedFIFO(8); 69.56 + 69.57 + // this is for the tracing 69.58 + rule printCycles; 69.59 + cycle <= cycle+1; 69.60 + $fdisplay(stderr, " => Cycle = %d", cycle); 69.61 + endrule 69.62 + 69.63 + 69.64 + rule sendMemReq; 69.65 + let coreReq <- core.mmem_client.request.get; 69.66 + case (coreReq) matches 69.67 + tagged LoadReq .load: begin 69.68 + //Allocate ROB space 69.69 + client_stub.makeRequest_MemoryRequestLoad(load.addr); 69.70 + tags.enq(load.tag); 69.71 + end 69.72 + tagged StoreReq .store: begin 69.73 + client_stub.makeRequest_MemoryRequestStore(store.addr,store.data); 69.74 + end 69.75 + endcase 69.76 + endrule 69.77 + 69.78 + rule receiveMemResp; 69.79 + let memResp <- client_stub.getResponse_MemoryRequestLoad(); 69.80 + tags.deq; 69.81 + core.mmem_client.response.put(tagged LoadResp {data:memResp, 69.82 + tag: tags.first}); 69.83 + endrule 69.84 + 69.85 +endmodule 69.86 \ No newline at end of file
70.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 70.2 +++ b/modules/bluespec/Pygar/lab4/ProcessorSystem.cpp Fri Apr 23 02:32:05 2010 -0400 70.3 @@ -0,0 +1,69 @@ 70.4 +#include <stdio.h> 70.5 +#include <pthread.h> 70.6 +#include <semaphore.h> 70.7 + 70.8 +#include "asim/provides/connected_application.h" 70.9 +#include "asim/provides/stats_device.h" 70.10 + 70.11 + 70.12 +using namespace std; 70.13 + 70.14 +// constructor 70.15 +CONNECTED_APPLICATION_CLASS::CONNECTED_APPLICATION_CLASS(VIRTUAL_PLATFORM vp) : 70.16 + clientStub(new PROCESSORSYSTEMRRR_CLIENT_STUB_CLASS(this)) 70.17 +{ 70.18 + 70.19 +} 70.20 + 70.21 +// destructor 70.22 +CONNECTED_APPLICATION_CLASS::~CONNECTED_APPLICATION_CLASS() 70.23 +{ 70.24 +} 70.25 + 70.26 +// init 70.27 +void 70.28 +CONNECTED_APPLICATION_CLASS::Init() 70.29 +{ 70.30 + 70.31 + // enable stats 70.32 + STATS_DEVICE_SERVER_CLASS::GetInstance()->SetupStats(); 70.33 + 70.34 +} 70.35 + 70.36 + 70.37 +// main 70.38 +void 70.39 +CONNECTED_APPLICATION_CLASS::Main() 70.40 +{ 70.41 + int sleepCount = 0; 70.42 + int result = 0; 70.43 + 70.44 + fflush(stdout); 70.45 + 70.46 + while ((result = clientStub->ReadCPUToHost(0)) != 1) { 70.47 + sleep(1); 70.48 + //printf("System controller sleeps with result: %d\n", result); 70.49 + sleepCount++; 70.50 + if(sleepCount == 100) { 70.51 + printf("Failed to get response from hardware, bailing\n\n"); 70.52 + printf("This means that either your hardware is hanging\n"); 70.53 + printf("or that the software hasn't given it enough time\n"); 70.54 + printf("to complete. If you think it needs more time, then\n"); 70.55 + printf("edit CONNECTED_APPLICATION_CLASS::Main() in ProcessorSystem.cpp\n"); 70.56 + printf("(connected_application)\n"); 70.57 + exit(0); 70.58 + } 70.59 + } 70.60 + 70.61 + if(result == 1) { 70.62 + printf("\n***PASSED***\n"); 70.63 + } 70.64 + 70.65 + // Dump the stats file 70.66 + 70.67 + STATS_DEVICE_SERVER_CLASS::GetInstance()->DumpStats(); 70.68 + STATS_DEVICE_SERVER_CLASS::GetInstance()->EmitFile(); 70.69 + 70.70 + fflush(stdout); 70.71 + exit(0); 70.72 +}
71.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 71.2 +++ b/modules/bluespec/Pygar/lab4/ProcessorSystem.h Fri Apr 23 02:32:05 2010 -0400 71.3 @@ -0,0 +1,44 @@ 71.4 +// 71.5 +// INTEL CONFIDENTIAL 71.6 +// Copyright (c) 2008 Intel Corp. Recipient is granted a non-sublicensable 71.7 +// copyright license under Intel copyrights to copy and distribute this code 71.8 +// internally only. This code is provided "AS IS" with no support and with no 71.9 +// warranties of any kind, including warranties of MERCHANTABILITY, 71.10 +// FITNESS FOR ANY PARTICULAR PURPOSE or INTELLECTUAL PROPERTY INFRINGEMENT. 71.11 +// By making any use of this code, Recipient agrees that no other licenses 71.12 +// to any Intel patents, trade secrets, copyrights or other intellectual 71.13 +// property rights are granted herein, and no other licenses shall arise by 71.14 +// estoppel, implication or by operation of law. Recipient accepts all risks 71.15 +// of use. 71.16 +// 71.17 + 71.18 +// possibly use include paths to hide existing modules? 71.19 + 71.20 +#ifndef __PROCESSOR_SYSTEM_CONNECTED_APPLICATION__ 71.21 +#define __PROCESSOR_SYSTEM_CONNECTED_APPLICATION__ 71.22 + 71.23 +#include <stdio.h> 71.24 +#include <pthread.h> 71.25 + 71.26 +#include "asim/provides/virtual_platform.h" 71.27 + 71.28 +#include "asim/rrr/client_stub_PROCESSORSYSTEMRRR.h" 71.29 + 71.30 +typedef class CONNECTED_APPLICATION_CLASS* CONNECTED_APPLICATION; 71.31 +class CONNECTED_APPLICATION_CLASS : public PLATFORMS_MODULE_CLASS 71.32 +{ 71.33 + private: 71.34 + PROCESSORSYSTEMRRR_CLIENT_STUB clientStub; 71.35 + 71.36 + public: 71.37 + CONNECTED_APPLICATION_CLASS(VIRTUAL_PLATFORM vp); 71.38 + ~CONNECTED_APPLICATION_CLASS(); 71.39 + 71.40 + // init 71.41 + void Init(); 71.42 + 71.43 + // main 71.44 + void Main(); 71.45 +}; 71.46 + 71.47 +#endif
72.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 72.2 +++ b/modules/bluespec/Pygar/lab4/ProcessorSystemRRR.cpp Fri Apr 23 02:32:05 2010 -0400 72.3 @@ -0,0 +1,83 @@ 72.4 +#include <cstdio> 72.5 +#include <cstdlib> 72.6 +#include <iostream> 72.7 +#include <iomanip> 72.8 +#include <stdio.h> 72.9 +#include <sys/stat.h> 72.10 + 72.11 +#include "asim/rrr/service_ids.h" 72.12 + 72.13 +#include "asim/provides/connected_application.h" 72.14 + 72.15 + 72.16 + 72.17 +using namespace std; 72.18 + 72.19 +// ===== service instantiation ===== 72.20 +PROCESSORSYSTEMRRR_SERVER_CLASS PROCESSORSYSTEMRRR_SERVER_CLASS::instance; 72.21 + 72.22 +// constructor 72.23 +PROCESSORSYSTEMRRR_SERVER_CLASS::PROCESSORSYSTEMRRR_SERVER_CLASS() : 72.24 + serverStub(new PROCESSORSYSTEMRRR_SERVER_STUB_CLASS(this)) 72.25 +{ 72.26 + // instantiate stub 72.27 + memory = NULL; 72.28 + fflush(stdout); 72.29 +} 72.30 + 72.31 +// destructor 72.32 +PROCESSORSYSTEMRRR_SERVER_CLASS::~PROCESSORSYSTEMRRR_SERVER_CLASS() 72.33 +{ 72.34 + Cleanup(); 72.35 +} 72.36 + 72.37 +// init 72.38 +void 72.39 +PROCESSORSYSTEMRRR_SERVER_CLASS::Init(PLATFORMS_MODULE p) 72.40 +{ 72.41 + parent = p; 72.42 +} 72.43 + 72.44 +// uninit 72.45 +void 72.46 +PROCESSORSYSTEMRRR_SERVER_CLASS::Uninit() 72.47 +{ 72.48 + Cleanup(); 72.49 +} 72.50 + 72.51 +// cleanup 72.52 +void 72.53 +PROCESSORSYSTEMRRR_SERVER_CLASS::Cleanup() 72.54 +{ 72.55 + delete serverStub; 72.56 +} 72.57 + 72.58 + 72.59 +// 72.60 +// RRR service methods 72.61 +// 72.62 + 72.63 +UINT32 72.64 +PROCESSORSYSTEMRRR_SERVER_CLASS::MemoryRequestLoad (UINT32 address) 72.65 +{ 72.66 + UINT32 returnVal; 72.67 + 72.68 + if(memory == NULL) { 72.69 + memory = new FUNCP_SIMULATED_MEMORY_CLASS(); 72.70 + } 72.71 + 72.72 + 72.73 + 72.74 + memory->Read(0,(UINT64) address, sizeof(UINT32), &returnVal); 72.75 + return returnVal; 72.76 +} 72.77 + 72.78 +void 72.79 +PROCESSORSYSTEMRRR_SERVER_CLASS::MemoryRequestStore (UINT32 address, UINT32 data) 72.80 +{ 72.81 + if(memory == NULL) { 72.82 + memory = new FUNCP_SIMULATED_MEMORY_CLASS(); 72.83 + } 72.84 + 72.85 + memory->Write(0,(UINT64) address, sizeof(UINT32), &data); 72.86 +}
73.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 73.2 +++ b/modules/bluespec/Pygar/lab4/ProcessorSystemRRR.h Fri Apr 23 02:32:05 2010 -0400 73.3 @@ -0,0 +1,53 @@ 73.4 + 73.5 +#ifndef _PROCESSORSYSTEMRRR_ 73.6 +#define _PROCESSORSYSTEMRRR_ 73.7 + 73.8 +#include <stdio.h> 73.9 +#include <sys/time.h> 73.10 + 73.11 +#include "asim/provides/low_level_platform_interface.h" 73.12 +#include "asim/provides/funcp_simulated_memory.h" 73.13 +#include "asim/provides/rrr.h" 73.14 + 73.15 + 73.16 + 73.17 +typedef class PROCESSORSYSTEMRRR_SERVER_CLASS* PROCESSORSYSTEMRRR_SERVER; 73.18 +class PROCESSORSYSTEMRRR_SERVER_CLASS: public RRR_SERVER_CLASS, public PLATFORMS_MODULE_CLASS 73.19 +{ 73.20 + private: 73.21 + // self-instantiation 73.22 + static PROCESSORSYSTEMRRR_SERVER_CLASS instance; 73.23 + FUNCP_SIMULATED_MEMORY_CLASS *memory; 73.24 + 73.25 + 73.26 + // server stub 73.27 + RRR_SERVER_STUB serverStub; 73.28 + 73.29 + int count; 73.30 + 73.31 + public: 73.32 + PROCESSORSYSTEMRRR_SERVER_CLASS(); 73.33 + ~PROCESSORSYSTEMRRR_SERVER_CLASS(); 73.34 + 73.35 + // static methods 73.36 + static PROCESSORSYSTEMRRR_SERVER GetInstance() { return &instance; } 73.37 + 73.38 + // required RRR methods 73.39 + void Init(PLATFORMS_MODULE); 73.40 + void Uninit(); 73.41 + void Cleanup(); 73.42 + 73.43 + // 73.44 + // RRR service methods 73.45 + // 73.46 + 73.47 + UINT32 MemoryRequestLoad (UINT32 address); 73.48 + void MemoryRequestStore (UINT32 address, UINT32 data); 73.49 +}; 73.50 + 73.51 + 73.52 + 73.53 +// include server stub 73.54 +#include "asim/rrr/server_stub_PROCESSORSYSTEMRRR.h" 73.55 + 73.56 +#endif
74.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 74.2 +++ b/modules/bluespec/Pygar/lab4/ProcessorSystemRRR.rrr Fri Apr 23 02:32:05 2010 -0400 74.3 @@ -0,0 +1,15 @@ 74.4 +service PROCESSORSYSTEMRRR 74.5 +{ 74.6 + server hw (bsv, connection) <- sw (cpp, method) 74.7 + { 74.8 + method ReadCPUToHost (out UINT32[32] regValue, in UINT32[32] dummy); 74.9 + method WriteHostToCPU (in UINT32[32] regValue); 74.10 + }; 74.11 + 74.12 + server sw (cpp, method) <- hw (bsv, connection) 74.13 + { 74.14 + method MemoryRequestLoad (in UINT32[32] address, out UINT32[32] value); 74.15 + method MemoryRequestStore (in UINT32[32] address, in UINT32[32] value); 74.16 + }; 74.17 + 74.18 + };
75.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 75.2 +++ b/modules/bluespec/Pygar/lab4/SFIFO.bsv Fri Apr 23 02:32:05 2010 -0400 75.3 @@ -0,0 +1,213 @@ 75.4 + 75.5 +import FIFO::*; 75.6 +import ConfigReg::*; 75.7 +import RWire::*; 75.8 + 75.9 +import List::*; 75.10 +import Monad::*; 75.11 + 75.12 +interface SFIFO#(type alpha_T, type search_T); 75.13 + method Action enq(alpha_T x); 75.14 + method Action deq(); 75.15 + method alpha_T first(); 75.16 + method Action clear(); 75.17 + method Bool find(search_T x); 75.18 + method Bool find2(search_T x); 75.19 + 75.20 +endinterface 75.21 + 75.22 +module mkSFIFO#(function Bool searchfunc(search_T s, alpha_T x)) (SFIFO#(alpha_T, search_T)) 75.23 + provisos 75.24 + (Bits#(alpha_T,asz)); 75.25 + 75.26 + Reg#(alpha_T) f0 <- mkConfigRegU(); 75.27 + Reg#(alpha_T) f1 <- mkConfigRegU(); 75.28 + 75.29 + Reg#(Bool) vf0 <- mkConfigReg(False); 75.30 + Reg#(Bool) vf1 <- mkConfigReg(False); 75.31 + 75.32 + PulseWire edge1 <- mkPulseWire(); 75.33 + 75.34 + method Action enq(alpha_T x) if (!(vf0 && vf1)); 75.35 + if (edge1 || !vf0)//empty or we're dequeueing 75.36 + begin 75.37 + vf0 <= True; //True 75.38 + vf1 <= False; 75.39 + f0 <= x; 75.40 + end 75.41 + else // !vf1 75.42 + begin 75.43 + vf1 <= True; 75.44 + f1 <= x; 75.45 + end 75.46 + endmethod 75.47 + 75.48 + method Action deq() if (vf0); 75.49 + edge1.send(); 75.50 + vf0 <= vf1; 75.51 + f0 <= f1; 75.52 + vf1 <= False; 75.53 + endmethod 75.54 + 75.55 + method alpha_T first() if(vf0); 75.56 + return (f0); 75.57 + endmethod 75.58 + 75.59 + method Action clear(); 75.60 + vf0 <= False; 75.61 + vf1 <= False; 75.62 + endmethod 75.63 + 75.64 + method Bool find(search_T sv); 75.65 + Bool nvf0 = edge1 ? False: vf0; 75.66 + Bool nvf1 = vf1; 75.67 + 75.68 + return (nvf0 && searchfunc(sv, f0) || 75.69 + nvf1 && searchfunc(sv, f1)); 75.70 + endmethod 75.71 + 75.72 + method Bool find2(search_T sv); 75.73 + Bool nvf0 = edge1 ? False: vf0; 75.74 + Bool nvf1 = vf1; 75.75 + 75.76 + return (nvf0 && searchfunc(sv, f0) || 75.77 + nvf1 && searchfunc(sv, f1)); 75.78 + endmethod 75.79 + 75.80 +endmodule 75.81 + 75.82 +module mkSFIFO1#(function Bool searchfunc(search_T s, alpha_T x)) (SFIFO#(alpha_T, search_T)) 75.83 + provisos 75.84 + (Bits#(alpha_T,asz), Eq#(alpha_T)); 75.85 + 75.86 + Reg#(alpha_T) f0 <- mkConfigRegU; 75.87 + 75.88 + Reg#(Bool) vf0 <- mkConfigReg(False); 75.89 + 75.90 + PulseWire edge1 <- mkPulseWire(); 75.91 + 75.92 + method Action enq(alpha_T x) if (!vf0); 75.93 + vf0 <= True; //True 75.94 + f0 <= x; 75.95 + endmethod 75.96 + 75.97 + method Action deq() if (vf0); 75.98 + edge1.send(); 75.99 + vf0 <= False; 75.100 + endmethod 75.101 + 75.102 + method alpha_T first() if(vf0); 75.103 + return (f0); 75.104 + endmethod 75.105 + 75.106 + method Action clear(); 75.107 + vf0 <= False; 75.108 + endmethod 75.109 + 75.110 + method Bool find(search_T sv); 75.111 + Bool nvf0 = edge1 ? False: vf0; 75.112 + 75.113 + return (nvf0 && searchfunc(sv, f0)); 75.114 + endmethod 75.115 + 75.116 + method Bool find2(search_T sv); 75.117 + Bool nvf0 = edge1 ? False: vf0; 75.118 + return (nvf0 && searchfunc(sv, f0)); 75.119 + endmethod 75.120 + 75.121 +endmodule 75.122 + 75.123 +module mkSizedSFIFOInternal#(Integer n, 75.124 + function Bool searchfunc1(search_T s, alpha_T x), 75.125 + function Bool searchfunc2(search_T s, alpha_T x)) (SFIFO#(alpha_T, search_T)) 75.126 + 75.127 + provisos ( Bits#(alpha_T,alpha_SZ) ); 75.128 + 75.129 + List#(Reg#(alpha_T)) registers <- replicateM(n, mkRegU); 75.130 + List#(Reg#(Bool)) valids <- replicateM(n, mkReg(False)); 75.131 + 75.132 + function Nat getNextFree (List#(Reg#(Bool)) vs); 75.133 + 75.134 + Nat res = fromInteger(n - 1); 75.135 + 75.136 + for (Integer x = n - 1; x > -1; x = x - 1) 75.137 + res = !vs[x]._read() ? fromInteger(x) : res; 75.138 + 75.139 + return res; 75.140 + 75.141 + endfunction 75.142 + 75.143 + function Bool notFull(); 75.144 + 75.145 + Bool full = True; 75.146 + 75.147 + for (Integer x = 0; x < n; x = x + 1) 75.148 + full = full && valids[x]._read(); 75.149 + 75.150 + return !full; 75.151 + 75.152 + endfunction 75.153 + 75.154 + method Action enq( alpha_T item ) if ( notFull() ); 75.155 + 75.156 + Nat k = getNextFree(valids); 75.157 + select(valids, k)._write(True); 75.158 + select(registers, k)._write(item); 75.159 + 75.160 + endmethod 75.161 + 75.162 + method Action deq() if ( valids[0]._read() ); 75.163 + 75.164 + for (Integer x = 0; x < (n-1); x = x + 1) 75.165 + begin 75.166 + 75.167 + (registers[x]) <= registers[x + 1]._read(); 75.168 + (valids[x]) <= valids[x + 1]._read(); 75.169 + 75.170 + end 75.171 + (valids[n-1]) <= False; 75.172 + endmethod 75.173 + 75.174 + method alpha_T first() if ( valids[0]._read() ); 75.175 + return registers[0]._read(); 75.176 + endmethod 75.177 + 75.178 + method Bool find(search_T sv); 75.179 + Bool res = False; 75.180 + 75.181 + for (Integer x = 0; x < n; x = x + 1) 75.182 + if ( valids[x]._read() && searchfunc1(sv, registers[x]._read()) ) 75.183 + res = True; 75.184 + 75.185 + return res; 75.186 + 75.187 + endmethod 75.188 + 75.189 + method Bool find2(search_T sv); 75.190 + Bool res = False; 75.191 + 75.192 + for (Integer x = 0; x < n; x = x + 1) 75.193 + if ( valids[x]._read() && searchfunc2(sv, registers[x]._read()) ) 75.194 + res = True; 75.195 + 75.196 + return res; 75.197 + 75.198 + endmethod 75.199 + 75.200 + method Action clear(); 75.201 + 75.202 + for (Integer x = 0; x < n; x = x + 1) 75.203 + (valids[x]) <= False; 75.204 + 75.205 + endmethod 75.206 + 75.207 +endmodule 75.208 + 75.209 +module mkSizedSFIFO#(Integer n, function Bool searchfunc(search_T s, alpha_T x)) (SFIFO#(alpha_T, search_T)) 75.210 + provisos 75.211 + (Bits#(alpha_T,asz)); 75.212 + 75.213 + let foo <- mkSizedSFIFOInternal(n, searchfunc, searchfunc); 75.214 + return foo; 75.215 + 75.216 +endmodule
76.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 76.2 +++ b/modules/bluespec/Pygar/lab4/Trace.bsv Fri Apr 23 02:32:05 2010 -0400 76.3 @@ -0,0 +1,92 @@ 76.4 + 76.5 +import ClientServer::*; 76.6 +import GetPut::*; 76.7 + 76.8 +//---------------------------------------------------------------------- 76.9 +// ToString typeclass 76.10 +//---------------------------------------------------------------------- 76.11 + 76.12 +typeclass Traceable#( type item_t ); 76.13 + function Action traceTiny( String loc, String traceTag, item_t item ); 76.14 + function Action traceFull( String loc, String traceTag, item_t item ); 76.15 +endtypeclass 76.16 + 76.17 +instance Traceable#(String); 76.18 + 76.19 + function Action traceTiny( String loc, String ttag, String str ); 76.20 + $fdisplay(stderr, " => %s:%s %s", loc, ttag, str ); 76.21 + endfunction 76.22 + 76.23 + function Action traceFull( String loc, String ttag, String str ); 76.24 + $fdisplay(stderr, " => %s:%s %s", loc, ttag, str ); 76.25 + endfunction 76.26 + 76.27 +endinstance 76.28 + 76.29 +instance Traceable#(Bit#(n)); 76.30 + 76.31 + function Action traceTiny( String loc, String ttag, Bit#(n) b ); 76.32 + $fdisplay(stderr, " => %s:%s %x", loc, ttag, b ); 76.33 + endfunction 76.34 + 76.35 + function Action traceFull( String loc, String ttag, Bit#(n) b ); 76.36 + $fdisplay(stderr, " => %s:%s %x", loc, ttag, b ); 76.37 + endfunction 76.38 + 76.39 +endinstance 76.40 + 76.41 +//---------------------------------------------------------------------- 76.42 +// Tracing interface wrappers 76.43 +//---------------------------------------------------------------------- 76.44 + 76.45 +function Get#(item_t) traceGet( String locStr, String tagStr, Get#(item_t) g ) 76.46 + provisos ( Traceable#(item_t) ); 76.47 + return 76.48 + ( 76.49 + interface Get 76.50 + method ActionValue#(item_t) get(); 76.51 + item_t item <- g.get(); 76.52 + traceTiny(locStr, tagStr,item); 76.53 + return item; 76.54 + endmethod 76.55 + endinterface 76.56 + ); 76.57 +endfunction 76.58 + 76.59 +function Put#(item_t) tracePut( String locStr, String tagStr, Put#(item_t) p ) 76.60 + provisos ( Traceable#(item_t) ); 76.61 + return 76.62 + ( 76.63 + interface Put 76.64 + method Action put( item_t item ); 76.65 + traceTiny(locStr, tagStr,item); 76.66 + p.put(item); 76.67 + endmethod 76.68 + endinterface 76.69 + ); 76.70 +endfunction 76.71 + 76.72 +function Client#(req_t,resp_t) traceClient( String locStr, String reqTagStr, String respTagStr, 76.73 + Client#(req_t,resp_t) c ) 76.74 + provisos ( Traceable#(req_t), Traceable#(resp_t) ); 76.75 + return 76.76 + ( 76.77 + interface Client 76.78 + interface Get request = traceGet(locStr, reqTagStr,c.request); 76.79 + interface Put response = tracePut(locStr, respTagStr,c.response); 76.80 + endinterface 76.81 + ); 76.82 +endfunction 76.83 + 76.84 +function Server#(req_t,resp_t) traceServer( String locStr, String reqTagStr, String respTagStr, 76.85 + Server#(req_t,resp_t) c ) 76.86 + provisos ( Traceable#(req_t), Traceable#(resp_t) ); 76.87 + return 76.88 + ( 76.89 + interface Server 76.90 + interface Put request = tracePut(locStr, reqTagStr,c.request); 76.91 + interface Get response = traceGet(locStr, respTagStr,c.response); 76.92 + endinterface 76.93 + ); 76.94 +endfunction 76.95 +
77.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 77.2 +++ b/modules/bluespec/Pygar/lab4/core.awb Fri Apr 23 02:32:05 2010 -0400 77.3 @@ -0,0 +1,16 @@ 77.4 +%name Simple Processor Core 77.5 +%desc Instantiates a processor, some caches, and a memory arbiter 77.6 + 77.7 +%provides core 77.8 + 77.9 +%requires mem_arb 77.10 +%requires instruction_cache 77.11 +%requires data_cache 77.12 +%requires processor 77.13 +%requires processor_library 77.14 + 77.15 +%attributes 6_375 77.16 + 77.17 +%public Core.bsv 77.18 + 77.19 +
78.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 78.2 +++ b/modules/bluespec/Pygar/lab4/data_cache.awb Fri Apr 23 02:32:05 2010 -0400 78.3 @@ -0,0 +1,10 @@ 78.4 +%name Blocking Data Cache 78.5 +%desc Parametric Blocking Data Cache 78.6 + 78.7 +%provides data_cache 78.8 + 78.9 +%attributes 6_375 78.10 + 78.11 +%public DataCacheBlocking.bsv 78.12 +%public DataCache.dic 78.13 +
79.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 79.2 +++ b/modules/bluespec/Pygar/lab4/instruction_cache.awb Fri Apr 23 02:32:05 2010 -0400 79.3 @@ -0,0 +1,11 @@ 79.4 +%name Blocking Instruction Cache 79.5 +%desc Parametric Blocking Instruction Cache 79.6 + 79.7 +%provides instruction_cache 79.8 + 79.9 +%attributes 6_375 79.10 + 79.11 +%public InstCacheBlocking.bsv 79.12 +%public InstCache.dic 79.13 + 79.14 +
80.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 80.2 +++ b/modules/bluespec/Pygar/lab4/mem_arb.awb Fri Apr 23 02:32:05 2010 -0400 80.3 @@ -0,0 +1,10 @@ 80.4 +%name Round-robin memory arbiter 80.5 +%desc Round-robin memory arbiter 80.6 + 80.7 +%provides mem_arb 80.8 + 80.9 +%attributes 6_375 80.10 + 80.11 +%public MemArb.bsv 80.12 + 80.13 +
81.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 81.2 +++ b/modules/bluespec/Pygar/lab4/oProcTypes.bsv Fri Apr 23 02:32:05 2010 -0400 81.3 @@ -0,0 +1,335 @@ 81.4 + 81.5 +import Trace::*; 81.6 + 81.7 +//---------------------------------------------------------------------- 81.8 +// Other typedefs 81.9 +//---------------------------------------------------------------------- 81.10 + 81.11 +typedef Bit#(32) Addr; 81.12 + 81.13 +//---------------------------------------------------------------------- 81.14 +// Basic instruction type 81.15 +//---------------------------------------------------------------------- 81.16 + 81.17 +typedef Bit#(5) Rindx; 81.18 +typedef Bit#(16) Simm; 81.19 +typedef Bit#(16) Zimm; 81.20 +typedef Bit#(5) Shamt; 81.21 +typedef Bit#(26) Target; 81.22 +typedef Bit#(5) CP0indx; 81.23 + 81.24 +typedef union tagged 81.25 +{ 81.26 + 81.27 + struct { Rindx rbase; Rindx rdst; Simm offset; } LW; 81.28 + struct { Rindx rbase; Rindx rsrc; Simm offset; } SW; 81.29 + 81.30 + struct { Rindx rsrc; Rindx rdst; Simm imm; } ADDIU; 81.31 + struct { Rindx rsrc; Rindx rdst; Simm imm; } SLTI; 81.32 + struct { Rindx rsrc; Rindx rdst; Simm imm; } SLTIU; 81.33 + struct { Rindx rsrc; Rindx rdst; Zimm imm; } ANDI; 81.34 + struct { Rindx rsrc; Rindx rdst; Zimm imm; } ORI; 81.35 + struct { Rindx rsrc; Rindx rdst; Zimm imm; } XORI; 81.36 + struct { Rindx rdst; Zimm imm; } LUI; 81.37 + 81.38 + struct { Rindx rsrc; Rindx rdst; Shamt shamt; } SLL; 81.39 + struct { Rindx rsrc; Rindx rdst; Shamt shamt; } SRL; 81.40 + struct { Rindx rsrc; Rindx rdst; Shamt shamt; } SRA; 81.41 + struct { Rindx rsrc; Rindx rdst; Rindx rshamt; } SLLV; 81.42 + struct { Rindx rsrc; Rindx rdst; Rindx rshamt; } SRLV; 81.43 + struct { Rindx rsrc; Rindx rdst; Rindx rshamt; } SRAV; 81.44 + struct { Rindx rsrc1; Rindx rsrc2; Rindx rdst; } ADDU; 81.45 + struct { Rindx rsrc1; Rindx rsrc2; Rindx rdst; } SUBU; 81.46 + struct { Rindx rsrc1; Rindx rsrc2; Rindx rdst; } AND; 81.47 + struct { Rindx rsrc1; Rindx rsrc2; Rindx rdst; } OR; 81.48 + struct { Rindx rsrc1; Rindx rsrc2; Rindx rdst; } XOR; 81.49 + struct { Rindx rsrc1; Rindx rsrc2; Rindx rdst; } NOR; 81.50 + struct { Rindx rsrc1; Rindx rsrc2; Rindx rdst; } SLT; 81.51 + struct { Rindx rsrc1; Rindx rsrc2; Rindx rdst; } SLTU; 81.52 + 81.53 + struct { Target target; } J; 81.54 + struct { Target target; } JAL; 81.55 + struct { Rindx rsrc; } JR; 81.56 + struct { Rindx rsrc; Rindx rdst; } JALR; 81.57 + struct { Rindx rsrc1; Rindx rsrc2; Simm offset; } BEQ; 81.58 + struct { Rindx rsrc1; Rindx rsrc2; Simm offset; } BNE; 81.59 + struct { Rindx rsrc; Simm offset; } BLEZ; 81.60 + struct { Rindx rsrc; Simm offset; } BGTZ; 81.61 + struct { Rindx rsrc; Simm offset; } BLTZ; 81.62 + struct { Rindx rsrc; Simm offset; } BGEZ; 81.63 + 81.64 + struct { Rindx rdst; CP0indx cop0src; } MFC0; 81.65 + struct { Rindx rsrc; CP0indx cop0dst; } MTC0; 81.66 + 81.67 + void ILLEGAL; 81.68 + 81.69 +} 81.70 +Instr deriving(Eq); 81.71 + 81.72 +//---------------------------------------------------------------------- 81.73 +// Pack and Unpack 81.74 +//---------------------------------------------------------------------- 81.75 + 81.76 +Bit#(6) opFUNC = 6'b000000; Bit#(6) fcSLL = 6'b000000; 81.77 +Bit#(6) opRT = 6'b000001; Bit#(6) fcSRL = 6'b000010; 81.78 +Bit#(6) opRS = 6'b010000; Bit#(6) fcSRA = 6'b000011; 81.79 + Bit#(6) fcSLLV = 6'b000100; 81.80 +Bit#(6) opLW = 6'b100011; Bit#(6) fcSRLV = 6'b000110; 81.81 +Bit#(6) opSW = 6'b101011; Bit#(6) fcSRAV = 6'b000111; 81.82 + Bit#(6) fcADDU = 6'b100001; 81.83 +Bit#(6) opADDIU = 6'b001001; Bit#(6) fcSUBU = 6'b100011; 81.84 +Bit#(6) opSLTI = 6'b001010; Bit#(6) fcAND = 6'b100100; 81.85 +Bit#(6) opSLTIU = 6'b001011; Bit#(6) fcOR = 6'b100101; 81.86 +Bit#(6) opANDI = 6'b001100; Bit#(6) fcXOR = 6'b100110; 81.87 +Bit#(6) opORI = 6'b001101; Bit#(6) fcNOR = 6'b100111; 81.88 +Bit#(6) opXORI = 6'b001110; Bit#(6) fcSLT = 6'b101010; 81.89 +Bit#(6) opLUI = 6'b001111; Bit#(6) fcSLTU = 6'b101011; 81.90 + 81.91 +Bit#(6) opJ = 6'b000010; 81.92 +Bit#(6) opJAL = 6'b000011; 81.93 +Bit#(6) fcJR = 6'b001000; 81.94 +Bit#(6) fcJALR = 6'b001001; 81.95 +Bit#(6) opBEQ = 6'b000100; 81.96 +Bit#(6) opBNE = 6'b000101; 81.97 +Bit#(6) opBLEZ = 6'b000110; 81.98 +Bit#(6) opBGTZ = 6'b000111; 81.99 +Bit#(5) rtBLTZ = 5'b00000; 81.100 +Bit#(5) rtBGEZ = 5'b00001; 81.101 + 81.102 +Bit#(5) rsMFC0 = 5'b00000; 81.103 +Bit#(5) rsMTC0 = 5'b00100; 81.104 + 81.105 +instance Bits#(Instr,32); 81.106 + 81.107 + // Pack Function 81.108 + 81.109 + function Bit#(32) pack( Instr instr ); 81.110 + 81.111 + case ( instr ) matches 81.112 + 81.113 + tagged LW .it : return { opLW, it.rbase, it.rdst, it.offset }; 81.114 + tagged SW .it : return { opSW, it.rbase, it.rsrc, it.offset }; 81.115 + 81.116 + tagged ADDIU .it : return { opADDIU, it.rsrc, it.rdst, it.imm }; 81.117 + tagged SLTI .it : return { opSLTI, it.rsrc, it.rdst, it.imm }; 81.118 + tagged SLTIU .it : return { opSLTIU, it.rsrc, it.rdst, it.imm }; 81.119 + tagged ANDI .it : return { opANDI, it.rsrc, it.rdst, it.imm }; 81.120 + tagged ORI .it : return { opORI, it.rsrc, it.rdst, it.imm }; 81.121 + tagged XORI .it : return { opXORI, it.rsrc, it.rdst, it.imm }; 81.122 + tagged LUI .it : return { opLUI, 5'b0, it.rdst, it.imm }; 81.123 + 81.124 + tagged SLL .it : return { opFUNC, 5'b0, it.rsrc, it.rdst, it.shamt, fcSLL }; 81.125 + tagged SRL .it : return { opFUNC, 5'b0, it.rsrc, it.rdst, it.shamt, fcSRL }; 81.126 + tagged SRA .it : return { opFUNC, 5'b0, it.rsrc, it.rdst, it.shamt, fcSRA }; 81.127 + 81.128 + tagged SLLV .it : return { opFUNC, it.rshamt, it.rsrc, it.rdst, 5'b0, fcSLLV }; 81.129 + tagged SRLV .it : return { opFUNC, it.rshamt, it.rsrc, it.rdst, 5'b0, fcSRLV }; 81.130 + tagged SRAV .it : return { opFUNC, it.rshamt, it.rsrc, it.rdst, 5'b0, fcSRAV }; 81.131 + 81.132 + tagged ADDU .it : return { opFUNC, it.rsrc1, it.rsrc2, it.rdst, 5'b0, fcADDU }; 81.133 + tagged SUBU .it : return { opFUNC, it.rsrc1, it.rsrc2, it.rdst, 5'b0, fcSUBU }; 81.134 + tagged AND .it : return { opFUNC, it.rsrc1, it.rsrc2, it.rdst, 5'b0, fcAND }; 81.135 + tagged OR .it : return { opFUNC, it.rsrc1, it.rsrc2, it.rdst, 5'b0, fcOR }; 81.136 + tagged XOR .it : return { opFUNC, it.rsrc1, it.rsrc2, it.rdst, 5'b0, fcXOR }; 81.137 + tagged NOR .it : return { opFUNC, it.rsrc1, it.rsrc2, it.rdst, 5'b0, fcNOR }; 81.138 + tagged SLT .it : return { opFUNC, it.rsrc1, it.rsrc2, it.rdst, 5'b0, fcSLT }; 81.139 + tagged SLTU .it : return { opFUNC, it.rsrc1, it.rsrc2, it.rdst, 5'b0, fcSLTU }; 81.140 + 81.141 + tagged J .it : return { opJ, it.target }; 81.142 + tagged JAL .it : return { opJAL, it.target }; 81.143 + tagged JR .it : return { opFUNC, it.rsrc, 5'b0, 5'b0, 5'b0, fcJR }; 81.144 + tagged JALR .it : return { opFUNC, it.rsrc, 5'b0, it.rdst, 5'b0, fcJALR }; 81.145 + tagged BEQ .it : return { opBEQ, it.rsrc1, it.rsrc2, it.offset }; 81.146 + tagged BNE .it : return { opBNE, it.rsrc1, it.rsrc2, it.offset }; 81.147 + tagged BLEZ .it : return { opBLEZ, it.rsrc, 5'b0, it.offset }; 81.148 + tagged BGTZ .it : return { opBGTZ, it.rsrc, 5'b0, it.offset }; 81.149 + tagged BLTZ .it : return { opRT, it.rsrc, rtBLTZ, it.offset }; 81.150 + tagged BGEZ .it : return { opRT, it.rsrc, rtBGEZ, it.offset }; 81.151 + 81.152 + tagged MFC0 .it : return { opRS, rsMFC0, it.rdst, it.cop0src, 11'b0 }; 81.153 + tagged MTC0 .it : return { opRS, rsMTC0, it.rsrc, it.cop0dst, 11'b0 }; 81.154 + 81.155 + endcase 81.156 + 81.157 + endfunction 81.158 + 81.159 + // Unpack Function 81.160 + 81.161 + function Instr unpack( Bit#(32) instrBits ); 81.162 + 81.163 + let opcode = instrBits[ 31 : 26 ]; 81.164 + let rs = instrBits[ 25 : 21 ]; 81.165 + let rt = instrBits[ 20 : 16 ]; 81.166 + let rd = instrBits[ 15 : 11 ]; 81.167 + let shamt = instrBits[ 10 : 6 ]; 81.168 + let funct = instrBits[ 5 : 0 ]; 81.169 + let imm = instrBits[ 15 : 0 ]; 81.170 + let target = instrBits[ 25 : 0 ]; 81.171 + 81.172 + case ( opcode ) 81.173 + 81.174 + opLW : return LW { rbase:rs, rdst:rt, offset:imm }; 81.175 + opSW : return SW { rbase:rs, rsrc:rt, offset:imm }; 81.176 + opADDIU : return ADDIU { rsrc:rs, rdst:rt, imm:imm }; 81.177 + opSLTI : return SLTI { rsrc:rs, rdst:rt, imm:imm }; 81.178 + opSLTIU : return SLTIU { rsrc:rs, rdst:rt, imm:imm }; 81.179 + opANDI : return ANDI { rsrc:rs, rdst:rt, imm:imm }; 81.180 + opORI : return ORI { rsrc:rs, rdst:rt, imm:imm }; 81.181 + opXORI : return XORI { rsrc:rs, rdst:rt, imm:imm }; 81.182 + opLUI : return LUI { rdst:rt, imm:imm }; 81.183 + opJ : return J { target:target }; 81.184 + opJAL : return JAL { target:target }; 81.185 + opBEQ : return BEQ { rsrc1:rs, rsrc2:rt, offset:imm }; 81.186 + opBNE : return BNE { rsrc1:rs, rsrc2:rt, offset:imm }; 81.187 + opBLEZ : return BLEZ { rsrc:rs, offset:imm }; 81.188 + opBGTZ : return BGTZ { rsrc:rs, offset:imm }; 81.189 + 81.190 + opFUNC : 81.191 + case ( funct ) 81.192 + fcSLL : return SLL { rsrc:rt, rdst:rd, shamt:shamt }; 81.193 + fcSRL : return SRL { rsrc:rt, rdst:rd, shamt:shamt }; 81.194 + fcSRA : return SRA { rsrc:rt, rdst:rd, shamt:shamt }; 81.195 + fcSLLV : return SLLV { rsrc:rt, rdst:rd, rshamt:rs }; 81.196 + fcSRLV : return SRLV { rsrc:rt, rdst:rd, rshamt:rs }; 81.197 + fcSRAV : return SRAV { rsrc:rt, rdst:rd, rshamt:rs }; 81.198 + fcADDU : return ADDU { rsrc1:rs, rsrc2:rt, rdst:rd }; 81.199 + fcSUBU : return SUBU { rsrc1:rs, rsrc2:rt, rdst:rd }; 81.200 + fcAND : return AND { rsrc1:rs, rsrc2:rt, rdst:rd }; 81.201 + fcOR : return OR { rsrc1:rs, rsrc2:rt, rdst:rd }; 81.202 + fcXOR : return XOR { rsrc1:rs, rsrc2:rt, rdst:rd }; 81.203 + fcNOR : return NOR { rsrc1:rs, rsrc2:rt, rdst:rd }; 81.204 + fcSLT : return SLT { rsrc1:rs, rsrc2:rt, rdst:rd }; 81.205 + fcSLTU : return SLTU { rsrc1:rs, rsrc2:rt, rdst:rd }; 81.206 + fcJR : return JR { rsrc:rs }; 81.207 + fcJALR : return JALR { rsrc:rs, rdst:rd }; 81.208 + default : return ILLEGAL; 81.209 + endcase 81.210 + 81.211 + opRT : 81.212 + case ( rt ) 81.213 + rtBLTZ : return BLTZ { rsrc:rs, offset:imm }; 81.214 + rtBGEZ : return BGEZ { rsrc:rs, offset:imm }; 81.215 + default : return ILLEGAL; 81.216 + endcase 81.217 + 81.218 + opRS : 81.219 + case ( rs ) 81.220 + rsMFC0 : return MFC0 { rdst:rt, cop0src:rd }; 81.221 + rsMTC0 : return MTC0 { rsrc:rt, cop0dst:rd }; 81.222 + default : return ILLEGAL; 81.223 + endcase 81.224 + 81.225 + default : return ILLEGAL; 81.226 + 81.227 + endcase 81.228 + 81.229 + endfunction 81.230 + 81.231 +endinstance 81.232 + 81.233 +//---------------------------------------------------------------------- 81.234 +// Trace 81.235 +//---------------------------------------------------------------------- 81.236 + 81.237 +instance Traceable#(Instr); 81.238 + 81.239 + function Action traceTiny( String loc, String ttag, Instr inst ); 81.240 + case ( inst ) matches 81.241 + 81.242 + tagged LW .it : $fdisplay(stderr, " => %s:%s lw", loc, ttag ); 81.243 + tagged SW .it : $fdisplay(stderr, " => %s:%s sw", loc, ttag ); 81.244 + 81.245 + tagged ADDIU .it : $fdisplay(stderr, " => %s:%s addi", loc, ttag ); 81.246 + tagged SLTI .it : $fdisplay(stderr, " => %s:%s sli", loc, ttag ); 81.247 + tagged SLTIU .it : $fdisplay(stderr, " => %s:%s sliu", loc, ttag ); 81.248 + tagged ANDI .it : $fdisplay(stderr, " => %s:%s andi", loc, ttag ); 81.249 + tagged ORI .it : $fdisplay(stderr, " => %s:%s ori", loc, ttag ); 81.250 + tagged XORI .it : $fdisplay(stderr, " => %s:%s xori", loc, ttag ); 81.251 + tagged LUI .it : $fdisplay(stderr, " => %s:%s lui", loc, ttag ); 81.252 + 81.253 + tagged SLL .it : $fdisplay(stderr, " => %s:%s sll", loc, ttag ); 81.254 + tagged SRL .it : $fdisplay(stderr, " => %s:%s srl", loc, ttag ); 81.255 + tagged SRA .it : $fdisplay(stderr, " => %s:%s sra", loc, ttag ); 81.256 + tagged SLLV .it : $fdisplay(stderr, " => %s:%s sllv", loc, ttag ); 81.257 + tagged SRLV .it : $fdisplay(stderr, " => %s:%s srlv", loc, ttag ); 81.258 + tagged SRAV .it : $fdisplay(stderr, " => %s:%s srav", loc, ttag ); 81.259 + 81.260 + tagged ADDU .it : $fdisplay(stderr, " => %s:%s addu", loc, ttag ); 81.261 + tagged SUBU .it : $fdisplay(stderr, " => %s:%s subu", loc, ttag ); 81.262 + tagged AND .it : $fdisplay(stderr, " => %s:%s and", loc, ttag ); 81.263 + tagged OR .it : $fdisplay(stderr, " => %s:%s or", loc, ttag ); 81.264 + tagged XOR .it : $fdisplay(stderr, " => %s:%s xor", loc, ttag ); 81.265 + tagged NOR .it : $fdisplay(stderr, " => %s:%s nor", loc, ttag ); 81.266 + tagged SLT .it : $fdisplay(stderr, " => %s:%s slt", loc, ttag ); 81.267 + tagged SLTU .it : $fdisplay(stderr, " => %s:%s sltu", loc, ttag ); 81.268 + 81.269 + tagged J .it : $fdisplay(stderr, " => %s:%s j", loc, ttag ); 81.270 + tagged JAL .it : $fdisplay(stderr, " => %s:%s jal", loc, ttag ); 81.271 + tagged JR .it : $fdisplay(stderr, " => %s:%s jr", loc, ttag ); 81.272 + tagged JALR .it : $fdisplay(stderr, " => %s:%s jalr", loc, ttag ); 81.273 + tagged BEQ .it : $fdisplay(stderr, " => %s:%s beq", loc, ttag ); 81.274 + tagged BNE .it : $fdisplay(stderr, " => %s:%s bne", loc, ttag ); 81.275 + tagged BLEZ .it : $fdisplay(stderr, " => %s:%s blez", loc, ttag ); 81.276 + tagged BGTZ .it : $fdisplay(stderr, " => %s:%s bgtz", loc, ttag ); 81.277 + tagged BLTZ .it : $fdisplay(stderr, " => %s:%s bltz", loc, ttag ); 81.278 + tagged BGEZ .it : $fdisplay(stderr, " => %s:%s bgez", loc, ttag ); 81.279 + 81.280 + tagged MFC0 .it : $fdisplay(stderr, " => %s:%s mfc0", loc, ttag ); 81.281 + tagged MTC0 .it : $fdisplay(stderr, " => %s:%s mtc0", loc, ttag ); 81.282 + 81.283 + tagged ILLEGAL : $fdisplay(stderr, " => %s:%s ill", loc, ttag ); 81.284 + 81.285 + endcase 81.286 + endfunction 81.287 + 81.288 + function Action traceFull( String loc, String ttag, Instr inst ); 81.289 + case ( inst ) matches 81.290 + 81.291 + tagged LW .it : $fdisplay(stderr, " => %s:%s lw r%0d, 0x%x(r%0d)", loc, ttag, it.rdst, it.offset, it.rbase ); 81.292 + tagged SW .it : $fdisplay(stderr, " => %s:%s sw r%0d, 0x%x(r%0d)", loc, ttag, it.rsrc, it.offset, it.rbase ); 81.293 + 81.294 + tagged ADDIU .it : $fdisplay(stderr, " => %s:%s addiu r%0d, r%0d, 0x%x", loc, ttag, it.rdst, it.rsrc, it.imm ); 81.295 + tagged SLTI .it : $fdisplay(stderr, " => %s:%s slti r%0d, r%0d, 0x%x", loc, ttag, it.rdst, it.rsrc, it.imm ); 81.296 + tagged SLTIU .it : $fdisplay(stderr, " => %s:%s sltiu r%0d, r%0d, 0x%x", loc, ttag, it.rdst, it.rsrc, it.imm ); 81.297 + tagged ANDI .it : $fdisplay(stderr, " => %s:%s andi r%0d, r%0d, 0x%x", loc, ttag, it.rdst, it.rsrc, it.imm ); 81.298 + tagged ORI .it : $fdisplay(stderr, " => %s:%s ori r%0d, r%0d, 0x%x", loc, ttag, it.rdst, it.rsrc, it.imm ); 81.299 + tagged XORI .it : $fdisplay(stderr, " => %s:%s xori r%0d, r%0d, 0x%x", loc, ttag, it.rdst, it.rsrc, it.imm ); 81.300 + tagged LUI .it : $fdisplay(stderr, " => %s:%s lui r%0d, 0x%x", loc, ttag, it.rdst, it.imm ); 81.301 + 81.302 + tagged SLL .it : $fdisplay(stderr, " => %s:%s sll r%0d, r%0d, %0d", loc, ttag, it.rdst, it.rsrc, it.shamt ); 81.303 + tagged SRL .it : $fdisplay(stderr, " => %s:%s srl r%0d, r%0d, %0d", loc, ttag, it.rdst, it.rsrc, it.shamt ); 81.304 + tagged SRA .it : $fdisplay(stderr, " => %s:%s sra r%0d, r%0d, %0d", loc, ttag, it.rdst, it.rsrc, it.shamt ); 81.305 + tagged SLLV .it : $fdisplay(stderr, " => %s:%s sllv r%0d, r%0d, r%0d", loc, ttag, it.rdst, it.rsrc, it.rshamt ); 81.306 + tagged SRLV .it : $fdisplay(stderr, " => %s:%s srlv r%0d, r%0d, r%0d", loc, ttag, it.rdst, it.rsrc, it.rshamt ); 81.307 + tagged SRAV .it : $fdisplay(stderr, " => %s:%s srav r%0d, r%0d, r%0d", loc, ttag, it.rdst, it.rsrc, it.rshamt ); 81.308 + 81.309 + tagged ADDU .it : $fdisplay(stderr, " => %s:%s addu r%0d, r%0d, r%0d", loc, ttag, it.rdst, it.rsrc1, it.rsrc2 ); 81.310 + tagged SUBU .it : $fdisplay(stderr, " => %s:%s subu r%0d, r%0d, r%0d", loc, ttag, it.rdst, it.rsrc1, it.rsrc2 ); 81.311 + tagged AND .it : $fdisplay(stderr, " => %s:%s and r%0d, r%0d, r%0d", loc, ttag, it.rdst, it.rsrc1, it.rsrc2 ); 81.312 + tagged OR .it : $fdisplay(stderr, " => %s:%s or r%0d, r%0d, r%0d", loc, ttag, it.rdst, it.rsrc1, it.rsrc2 ); 81.313 + tagged XOR .it : $fdisplay(stderr, " => %s:%s xor r%0d, r%0d, r%0d", loc, ttag, it.rdst, it.rsrc1, it.rsrc2 ); 81.314 + tagged NOR .it : $fdisplay(stderr, " => %s:%s nor r%0d, r%0d, r%0d", loc, ttag, it.rdst, it.rsrc1, it.rsrc2 ); 81.315 + tagged SLT .it : $fdisplay(stderr, " => %s:%s slt r%0d, r%0d, r%0d", loc, ttag, it.rdst, it.rsrc1, it.rsrc2 ); 81.316 + tagged SLTU .it : $fdisplay(stderr, " => %s:%s sltu r%0d, r%0d, r%0d", loc, ttag, it.rdst, it.rsrc1, it.rsrc2 ); 81.317 + 81.318 + tagged J .it : $fdisplay(stderr, " => %s:%s j 0x%x", loc, ttag, it.target ); 81.319 + tagged JAL .it : $fdisplay(stderr, " => %s:%s jal 0x%x", loc, ttag, it.target ); 81.320 + tagged JR .it : $fdisplay(stderr, " => %s:%s jr r%0d", loc, ttag, it.rsrc ); 81.321 + tagged JALR .it : $fdisplay(stderr, " => %s:%s jalr r%0d", loc, ttag, it.rsrc ); 81.322 + tagged BEQ .it : $fdisplay(stderr, " => %s:%s beq r%0d, r%0d, 0x%x", loc, ttag, it.rsrc1, it.rsrc2, it.offset ); 81.323 + tagged BNE .it : $fdisplay(stderr, " => %s:%s bne r%0d, r%0d, 0x%x", loc, ttag, it.rsrc1, it.rsrc2, it.offset ); 81.324 + tagged BLEZ .it : $fdisplay(stderr, " => %s:%s blez r%0d, 0x%x", loc, ttag, it.rsrc, it.offset ); 81.325 + tagged BGTZ .it : $fdisplay(stderr, " => %s:%s bgtz r%0d, 0x%x", loc, ttag, it.rsrc, it.offset ); 81.326 + tagged BLTZ .it : $fdisplay(stderr, " => %s:%s bltz r%0d, 0x%x", loc, ttag, it.rsrc, it.offset ); 81.327 + tagged BGEZ .it : $fdisplay(stderr, " => %s:%s bgez r%0d, 0x%x", loc, ttag, it.rsrc, it.offset ); 81.328 + 81.329 + tagged MFC0 .it : $fdisplay(stderr, " => %s:%s mfc0 r%0d, cpr%0d", loc, ttag, it.rdst, it.cop0src ); 81.330 + tagged MTC0 .it : $fdisplay(stderr, " => %s:%s mtc0 r%0d, cpr%0d", loc, ttag, it.rsrc, it.cop0dst ); 81.331 + 81.332 + tagged ILLEGAL : $fdisplay(stderr, " => %s:%s illegal instruction", loc, ttag ); 81.333 + 81.334 + endcase 81.335 + endfunction 81.336 + 81.337 +endinstance 81.338 +
82.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 82.2 +++ b/modules/bluespec/Pygar/lab4/oProcessor.bsv Fri Apr 23 02:32:05 2010 -0400 82.3 @@ -0,0 +1,373 @@ 82.4 +// The MIT License 82.5 + 82.6 +// Copyright (c) 2009 Massachusetts Institute of Technology 82.7 + 82.8 +// Permission is hereby granted, free of charge, to any person obtaining a copy 82.9 +// of this software and associated documentation files (the "Software"), to deal 82.10 +// in the Software without restriction, including without limitation the rights 82.11 +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 82.12 +// copies of the Software, and to permit persons to whom the Software is 82.13 +// furnished to do so, subject to the following conditions: 82.14 + 82.15 +// The above copyright notice and this permission notice shall be included in 82.16 +// all copies or substantial portions of the Software. 82.17 + 82.18 +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 82.19 +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 82.20 +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 82.21 +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 82.22 +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 82.23 +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 82.24 +// THE SOFTWARE. 82.25 + 82.26 +import Connectable::*; 82.27 +import GetPut::*; 82.28 +import ClientServer::*; 82.29 +import RegFile::*; 82.30 +import FIFO::*; 82.31 +import FIFOF::*; 82.32 +import RWire::*; 82.33 + 82.34 +//AWB includes 82.35 +`include "asim/provides/low_level_platform_interface.bsh" 82.36 +`include "asim/provides/soft_connections.bsh" 82.37 +`include "asim/provides/common_services.bsh" 82.38 + 82.39 +// Local includes 82.40 +`include "asim/provides/processor_library.bsh" 82.41 +`include "asim/rrr/remote_server_stub_PROCESSORSYSTEMRRR.bsh" 82.42 +`include "asim/provides/common_services.bsh" 82.43 +`include "asim/dict/STATS_PROCESSOR.bsh" 82.44 + 82.45 +interface Proc; 82.46 + 82.47 + // Interface from processor to caches 82.48 + interface Client#(DataReq,DataResp) dmem_client; 82.49 + interface Client#(InstReq,InstResp) imem_client; 82.50 + 82.51 + // Interface for enabling/disabling statistics on the rest of the core 82.52 + interface Get#(Bool) statsEn_get; 82.53 + 82.54 +endinterface 82.55 + 82.56 + 82.57 +typedef enum { PCgen, Exec, Writeback } Stage deriving(Eq,Bits); 82.58 + 82.59 +//----------------------------------------------------------- 82.60 +// Register file module 82.61 +//----------------------------------------------------------- 82.62 + 82.63 +interface RFile; 82.64 + method Action wr( Rindx rindx, Bit#(32) data ); 82.65 + method Bit#(32) rd1( Rindx rindx ); 82.66 + method Bit#(32) rd2( Rindx rindx ); 82.67 +endinterface 82.68 + 82.69 +module mkRFile( RFile ); 82.70 + 82.71 + RegFile#(Rindx,Bit#(32)) rfile <- mkRegFileFull(); 82.72 + 82.73 + method Action wr( Rindx rindx, Bit#(32) data ); 82.74 + rfile.upd( rindx, data ); 82.75 + endmethod 82.76 + 82.77 + method Bit#(32) rd1( Rindx rindx ); 82.78 + return ( rindx == 0 ) ? 0 : rfile.sub(rindx); 82.79 + endmethod 82.80 + 82.81 + method Bit#(32) rd2( Rindx rindx ); 82.82 + return ( rindx == 0 ) ? 0 : rfile.sub(rindx); 82.83 + endmethod 82.84 + 82.85 +endmodule 82.86 + 82.87 +//----------------------------------------------------------- 82.88 +// Helper functions 82.89 +//----------------------------------------------------------- 82.90 + 82.91 +function Bit#(32) slt( Bit#(32) val1, Bit#(32) val2 ); 82.92 + return zeroExtend( pack( signedLT(val1,val2) ) ); 82.93 +endfunction 82.94 + 82.95 +function Bit#(32) sltu( Bit#(32) val1, Bit#(32) val2 ); 82.96 + return zeroExtend( pack( val1 < val2 ) ); 82.97 +endfunction 82.98 + 82.99 +function Bit#(32) rshft( Bit#(32) val ); 82.100 + return zeroExtend(val[4:0]); 82.101 +endfunction 82.102 + 82.103 +//----------------------------------------------------------- 82.104 +// Reference processor 82.105 +//----------------------------------------------------------- 82.106 + 82.107 + 82.108 +module [CONNECTED_MODULE] mkProc( Proc ); 82.109 + 82.110 + //----------------------------------------------------------- 82.111 + // Debug port 82.112 + 82.113 + ServerStub_PROCESSORSYSTEMRRR server_stub <- mkServerStub_PROCESSORSYSTEMRRR(); 82.114 + 82.115 + //----------------------------------------------------------- 82.116 + // State 82.117 + 82.118 + // Standard processor state 82.119 + 82.120 + Reg#(Addr) pc <- mkReg(32'h00001000); 82.121 + Reg#(Stage) stage <- mkReg(PCgen); 82.122 + RFile rf <- mkRFile; 82.123 + 82.124 + // Coprocessor state - connected by way of RRR 82.125 + 82.126 + Reg#(Bit#(32)) cp0_tohost <- mkReg(0); 82.127 + 82.128 + Reg#(Bit#(32)) cp0_fromhost <- mkReg(0); 82.129 + 82.130 + Reg#(Bool) cp0_statsEn <- mkReg(False); 82.131 + 82.132 + // Memory request/response state 82.133 + 82.134 + FIFO#(InstReq) instReqQ <- mkBFIFO1(); 82.135 + FIFO#(InstResp) instRespQ <- mkFIFO(); 82.136 + 82.137 + FIFO#(DataReq) dataReqQ <- mkBFIFO1(); 82.138 + FIFO#(DataResp) dataRespQ <- mkFIFO(); 82.139 + 82.140 + // Statistics state 82.141 + STAT num_cycles <- mkStatCounter(`STATS_PROCESSOR_CYCLE_COUNT); 82.142 + STAT num_inst <- mkStatCounter(`STATS_PROCESSOR_INST_COUNT); 82.143 + 82.144 + //----------------------------------------------------------- 82.145 + // Rules 82.146 + 82.147 + let pc_plus4 = pc + 4; 82.148 + 82.149 + rule pcgen ( stage == PCgen ); 82.150 + traceTiny("mkProc", "pc",pc); 82.151 + traceTiny("mkProc", "pcgen","P"); 82.152 + instReqQ.enq( LoadReq{ addr:pc, tag:0 } ); 82.153 + stage <= Exec; 82.154 + endrule 82.155 + 82.156 + rule exec ( stage == Exec ); 82.157 + 82.158 + // Some abbreviations 82.159 + let sext = signExtend; 82.160 + let zext = zeroExtend; 82.161 + let sra = signedShiftRight; 82.162 + 82.163 + // Get the instruction 82.164 + 82.165 + instRespQ.deq(); 82.166 + Instr inst 82.167 + = case ( instRespQ.first() ) matches 82.168 + tagged LoadResp .ld : return unpack(ld.data); 82.169 + tagged StoreResp .st : return ?; 82.170 + endcase; 82.171 + 82.172 + // Some default variables 82.173 + Stage next_stage = PCgen; 82.174 + Addr next_pc = pc_plus4; 82.175 + 82.176 + // Tracing 82.177 + traceTiny("mkProc", "exec","X"); 82.178 + traceTiny("mkProc", "exInstTiny",inst); 82.179 + traceFull("mkProc", "exInstFull",inst); 82.180 + 82.181 + case ( inst ) matches 82.182 + 82.183 + // -- Memory Ops ------------------------------------------------ 82.184 + 82.185 + tagged LW .it : 82.186 + begin 82.187 + Addr addr = rf.rd1(it.rbase) + sext(it.offset); 82.188 + dataReqQ.enq( LoadReq{ addr:addr, tag:zeroExtend(it.rdst) } ); 82.189 + next_stage = Writeback; 82.190 + end 82.191 + 82.192 + tagged SW .it : 82.193 + begin 82.194 + Addr addr = rf.rd1(it.rbase) + sext(it.offset); 82.195 + dataReqQ.enq( StoreReq{ tag:0, addr:addr, data:rf.rd1(it.rsrc) } ); 82.196 + next_stage = Writeback; 82.197 + end 82.198 + 82.199 + // -- Simple Ops ------------------------------------------------ 82.200 + 82.201 + tagged ADDIU .it : rf.wr( it.rdst, rf.rd1(it.rsrc) + sext(it.imm) ); 82.202 + tagged SLTI .it : rf.wr( it.rdst, slt( rf.rd1(it.rsrc), sext(it.imm) ) ); 82.203 + tagged SLTIU .it : rf.wr( it.rdst, sltu( rf.rd1(it.rsrc), sext(it.imm) ) ); 82.204 + tagged ANDI .it : 82.205 + begin 82.206 + Bit#(32) zext_it_imm = zext(it.imm); 82.207 + rf.wr( it.rdst, rf.rd1(it.rsrc) & zext_it_imm ); 82.208 + end 82.209 + tagged ORI .it : 82.210 + begin 82.211 + Bit#(32) zext_it_imm = zext(it.imm); 82.212 + rf.wr( it.rdst, rf.rd1(it.rsrc) | zext_it_imm ); 82.213 + end 82.214 + tagged XORI .it : 82.215 + begin 82.216 + Bit#(32) zext_it_imm = zext(it.imm); 82.217 + rf.wr( it.rdst, rf.rd1(it.rsrc) ^ zext_it_imm ); 82.218 + end 82.219 + tagged LUI .it : 82.220 + begin 82.221 + Bit#(32) zext_it_imm = zext(it.imm); 82.222 + rf.wr( it.rdst, (zext_it_imm << 32'd16) ); 82.223 + end 82.224 + 82.225 + tagged SLL .it : 82.226 + begin 82.227 + Bit#(32) zext_it_shamt = zext(it.shamt); 82.228 + rf.wr( it.rdst, rf.rd1(it.rsrc) << zext_it_shamt ); 82.229 + end 82.230 + tagged SRL .it : 82.231 + begin 82.232 + Bit#(32) zext_it_shamt = zext(it.shamt); 82.233 + rf.wr( it.rdst, rf.rd1(it.rsrc) >> zext_it_shamt ); 82.234 + end 82.235 + tagged SRA .it : 82.236 + begin 82.237 + Bit#(32) zext_it_shamt = zext(it.shamt); 82.238 + rf.wr( it.rdst, sra( rf.rd1(it.rsrc), zext_it_shamt )); 82.239 + end 82.240 + tagged SLLV .it : rf.wr( it.rdst, rf.rd1(it.rsrc) << rshft(rf.rd2(it.rshamt)) ); 82.241 + tagged SRLV .it : rf.wr( it.rdst, rf.rd1(it.rsrc) >> rshft(rf.rd2(it.rshamt)) ); 82.242 + tagged SRAV .it : rf.wr( it.rdst, sra( rf.rd1(it.rsrc), rshft(rf.rd2(it.rshamt)) ) ); 82.243 + tagged ADDU .it : rf.wr( it.rdst, rf.rd1(it.rsrc1) + rf.rd2(it.rsrc2) ); 82.244 + tagged SUBU .it : rf.wr( it.rdst, rf.rd1(it.rsrc1) - rf.rd2(it.rsrc2) ); 82.245 + tagged AND .it : rf.wr( it.rdst, rf.rd1(it.rsrc1) & rf.rd2(it.rsrc2) ); 82.246 + tagged OR .it : rf.wr( it.rdst, rf.rd1(it.rsrc1) | rf.rd2(it.rsrc2) ); 82.247 + tagged XOR .it : rf.wr( it.rdst, rf.rd1(it.rsrc1) ^ rf.rd2(it.rsrc2) ); 82.248 + tagged NOR .it : rf.wr( it.rdst, ~(rf.rd1(it.rsrc1) | rf.rd2(it.rsrc2)) ); 82.249 + tagged SLT .it : rf.wr( it.rdst, slt( rf.rd1(it.rsrc1), rf.rd2(it.rsrc2) ) ); 82.250 + tagged SLTU .it : rf.wr( it.rdst, sltu( rf.rd1(it.rsrc1), rf.rd2(it.rsrc2) ) ); 82.251 + 82.252 + // -- Branches -------------------------------------------------- 82.253 + 82.254 + tagged BLEZ .it : 82.255 + if ( signedLE( rf.rd1(it.rsrc), 0 ) ) 82.256 + next_pc = pc_plus4 + (sext(it.offset) << 2); 82.257 + 82.258 + tagged BGTZ .it : 82.259 + if ( signedGT( rf.rd1(it.rsrc), 0 ) ) 82.260 + next_pc = pc_plus4 + (sext(it.offset) << 2); 82.261 + 82.262 + tagged BLTZ .it : 82.263 + if ( signedLT( rf.rd1(it.rsrc), 0 ) ) 82.264 + next_pc = pc_plus4 + (sext(it.offset) << 2); 82.265 + 82.266 + tagged BGEZ .it : 82.267 + if ( signedGE( rf.rd1(it.rsrc), 0 ) ) 82.268 + next_pc = pc_plus4 + (sext(it.offset) << 2); 82.269 + 82.270 + tagged BEQ .it : 82.271 + if ( rf.rd1(it.rsrc1) == rf.rd2(it.rsrc2) ) 82.272 + next_pc = pc_plus4 + (sext(it.offset) << 2); 82.273 + 82.274 + tagged BNE .it : 82.275 + if ( rf.rd1(it.rsrc1) != rf.rd2(it.rsrc2) ) 82.276 + next_pc = pc_plus4 + (sext(it.offset) << 2); 82.277 + 82.278 + // -- Jumps ----------------------------------------------------- 82.279 + 82.280 + tagged J .it : 82.281 + next_pc = { pc_plus4[31:28], it.target, 2'b0 }; 82.282 + 82.283 + tagged JR .it : 82.284 + next_pc = rf.rd1(it.rsrc); 82.285 + 82.286 + tagged JAL .it : 82.287 + begin 82.288 + rf.wr( 31, pc_plus4 ); 82.289 + next_pc = { pc_plus4[31:28], it.target, 2'b0 }; 82.290 + end 82.291 + 82.292 + tagged JALR .it : 82.293 + begin 82.294 + rf.wr( it.rdst, pc_plus4 ); 82.295 + next_pc = rf.rd1(it.rsrc); 82.296 + end 82.297 + 82.298 + // -- Cop0 ------------------------------------------------------ 82.299 + 82.300 + tagged MTC0 .it : 82.301 + case ( it.cop0dst ) 82.302 + 5'd10 : cp0_statsEn <= unpack(truncate(rf.rd1(it.rsrc))); 82.303 + 5'd21 : cp0_tohost <= truncate(rf.rd1(it.rsrc)); 82.304 + default : 82.305 + $display( " RTL-ERROR : %m : Illegal MTC0 cop0dst register!" ); 82.306 + endcase 82.307 + 82.308 + tagged MFC0 .it : 82.309 + case ( it.cop0src ) 82.310 + 5'd10 : rf.wr( it.rdst, zext(pack(cp0_statsEn)) ); 82.311 + 5'd20 : rf.wr( it.rdst, cp0_fromhost ); 82.312 + 5'd21 : rf.wr( it.rdst, cp0_tohost ); 82.313 + default : 82.314 + $display( " RTL-ERROR : %m : Illegal MFC0 cop0src register!" ); 82.315 + endcase 82.316 + 82.317 + // -- Illegal --------------------------------------------------- 82.318 + 82.319 + default : 82.320 + $display( " RTL-ERROR : %m : Illegal instruction !" ); 82.321 + 82.322 + endcase 82.323 + 82.324 + stage <= next_stage; 82.325 + pc <= next_pc; 82.326 + 82.327 + if ( cp0_statsEn ) 82.328 + num_inst.incr(); 82.329 + 82.330 + endrule 82.331 + 82.332 + rule writeback ( stage == Writeback ); 82.333 + traceTiny("mkProc", "writeback","W"); 82.334 + 82.335 + dataRespQ.deq(); 82.336 + case ( dataRespQ.first() ) matches 82.337 + tagged LoadResp .ld : rf.wr( truncate(ld.tag), ld.data ); 82.338 + tagged StoreResp .st : noAction; 82.339 + endcase 82.340 + 82.341 + stage <= PCgen; 82.342 + endrule 82.343 + 82.344 + rule inc_num_cycles; 82.345 + if ( cp0_statsEn ) 82.346 + num_cycles.incr(); 82.347 + endrule 82.348 + 82.349 + rule handleCPUToHost; 82.350 + let req <- server_stub.acceptRequest_ReadCPUToHost(); 82.351 + case (req) 82.352 + 0: server_stub.sendResponse_ReadCPUToHost(cp0_tohost); 82.353 + 1: server_stub.sendResponse_ReadCPUToHost(pc); 82.354 + 2: server_stub.sendResponse_ReadCPUToHost(zeroExtend(pack(stage))); 82.355 + endcase 82.356 + endrule 82.357 + 82.358 + 82.359 + 82.360 + //----------------------------------------------------------- 82.361 + // Methods 82.362 + 82.363 + interface Client imem_client; 82.364 + interface Get request = fifoToGet(instReqQ); 82.365 + interface Put response = fifoToPut(instRespQ); 82.366 + endinterface 82.367 + 82.368 + interface Client dmem_client; 82.369 + interface Get request = fifoToGet(dataReqQ); 82.370 + interface Put response = fifoToPut(dataRespQ); 82.371 + endinterface 82.372 + 82.373 + interface Get statsEn_get = regToGet(cp0_statsEn); 82.374 + 82.375 +endmodule 82.376 +
83.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 83.2 +++ b/modules/bluespec/Pygar/lab4/oSFIFO.bsv Fri Apr 23 02:32:05 2010 -0400 83.3 @@ -0,0 +1,234 @@ 83.4 + 83.5 +import FIFO::*; 83.6 +import ConfigReg::*; 83.7 +import RWire::*; 83.8 + 83.9 +import List::*; 83.10 +import Monad::*; 83.11 + 83.12 +interface SFIFO#(type alpha_T, type search_T); 83.13 + method Action enq(alpha_T x); 83.14 + method Action deq(); 83.15 + method alpha_T first(); 83.16 + method Action clear(); 83.17 + method Bool find(search_T x); 83.18 + method Bool find2(search_T x); 83.19 + method Bool notEmpty(); 83.20 + method Bool notFull(); 83.21 +endinterface 83.22 + 83.23 +module mkSFIFO#(function Bool searchfunc(search_T s, alpha_T x)) (SFIFO#(alpha_T, search_T)) 83.24 + provisos 83.25 + (Bits#(alpha_T,asz)); 83.26 + 83.27 + Reg#(alpha_T) f0 <- mkConfigRegU; 83.28 + Reg#(alpha_T) f1 <- mkConfigRegU; 83.29 + 83.30 + Reg#(Bool) vf0 <- mkConfigReg(False); 83.31 + Reg#(Bool) vf1 <- mkConfigReg(False); 83.32 + 83.33 + PulseWire edge1 <- mkPulseWire(); 83.34 + 83.35 + method Action enq(alpha_T x) if (!(vf0 && vf1)); 83.36 + if (edge1 || !vf0)//empty or we're dequeueing 83.37 + begin 83.38 + vf0 <= True; //True 83.39 + vf1 <= False; 83.40 + f0 <= x; 83.41 + end 83.42 + else // !vf1 83.43 + begin 83.44 + vf1 <= True; 83.45 + f1 <= x; 83.46 + end 83.47 + endmethod 83.48 + 83.49 + method Action deq() if (vf0); 83.50 + edge1.send(); 83.51 + vf0 <= vf1; 83.52 + f0 <= f1; 83.53 + vf1 <= False; 83.54 + endmethod 83.55 + 83.56 + method alpha_T first() if(vf0); 83.57 + return (f0); 83.58 + endmethod 83.59 + 83.60 + method Action clear(); 83.61 + vf0 <= False; 83.62 + vf1 <= False; 83.63 + endmethod 83.64 + 83.65 + method Bool find(search_T sv); 83.66 + Bool nvf0 = edge1 ? False: vf0; 83.67 + Bool nvf1 = vf1; 83.68 + 83.69 + return (nvf0 && searchfunc(sv, f0) || 83.70 + nvf1 && searchfunc(sv, f1)); 83.71 + endmethod 83.72 + 83.73 + method Bool find2(search_T sv); 83.74 + Bool nvf0 = edge1 ? False: vf0; 83.75 + Bool nvf1 = vf1; 83.76 + 83.77 + return (nvf0 && searchfunc(sv, f0) || 83.78 + nvf1 && searchfunc(sv, f1)); 83.79 + endmethod 83.80 + 83.81 + method notEmpty() = vf0._read; 83.82 + 83.83 + method Bool notFull(); 83.84 + return !(vf0 && vf1); 83.85 + endmethod 83.86 + 83.87 +endmodule 83.88 + 83.89 +module mkSFIFO1#(function Bool searchfunc(search_T s, alpha_T x)) (SFIFO#(alpha_T, search_T)) 83.90 + provisos 83.91 + (Bits#(alpha_T,asz), Eq#(alpha_T)); 83.92 + 83.93 + Reg#(alpha_T) f0 <- mkConfigRegU; 83.94 + 83.95 + Reg#(Bool) vf0 <- mkConfigReg(False); 83.96 + 83.97 + PulseWire edge1 <- mkPulseWire(); 83.98 + 83.99 + method Action enq(alpha_T x) if (!vf0); 83.100 + vf0 <= True; //True 83.101 + f0 <= x; 83.102 + endmethod 83.103 + 83.104 + method Action deq() if (vf0); 83.105 + edge1.send(); 83.106 + vf0 <= False; 83.107 + endmethod 83.108 + 83.109 + method alpha_T first() if(vf0); 83.110 + return (f0); 83.111 + endmethod 83.112 + 83.113 + method Action clear(); 83.114 + vf0 <= False; 83.115 + endmethod 83.116 + 83.117 + method Bool find(search_T sv); 83.118 + Bool nvf0 = edge1 ? False: vf0; 83.119 + 83.120 + return (nvf0 && searchfunc(sv, f0)); 83.121 + endmethod 83.122 + 83.123 + method Bool find2(search_T sv); 83.124 + Bool nvf0 = edge1 ? False: vf0; 83.125 + return (nvf0 && searchfunc(sv, f0)); 83.126 + endmethod 83.127 + 83.128 + method notEmpty() = vf0._read; 83.129 + 83.130 + method Bool notFull(); 83.131 + return !vf0; 83.132 + endmethod 83.133 + 83.134 +endmodule 83.135 + 83.136 +module mkSizedSFIFOInternal#(Integer n, 83.137 + function Bool searchfunc1(search_T s, alpha_T x), 83.138 + function Bool searchfunc2(search_T s, alpha_T x)) (SFIFO#(alpha_T, search_T)) 83.139 + 83.140 + provisos ( Bits#(alpha_T,alpha_SZ) ); 83.141 + 83.142 + List#(Reg#(alpha_T)) registers <- replicateM(n, mkRegU); 83.143 + List#(Reg#(Bool)) valids <- replicateM(n, mkReg(False)); 83.144 + 83.145 + function Nat getNextFree (List#(Reg#(Bool)) vs); 83.146 + 83.147 + Nat res = fromInteger(n - 1); 83.148 + 83.149 + for (Integer x = n - 1; x > -1; x = x - 1) 83.150 + res = !vs[x]._read() ? fromInteger(x) : res; 83.151 + 83.152 + return res; 83.153 + 83.154 + endfunction 83.155 + 83.156 + function Bool notFullHelper(); 83.157 + 83.158 + Bool full = True; 83.159 + 83.160 + for (Integer x = 0; x < n; x = x + 1) 83.161 + full = full && valids[x]._read(); 83.162 + 83.163 + return !full; 83.164 + 83.165 + endfunction 83.166 + 83.167 + method Action enq( alpha_T item ) if ( notFullHelper() ); 83.168 + 83.169 + Nat k = getNextFree(valids); 83.170 + select(valids, k)._write(True); 83.171 + select(registers, k)._write(item); 83.172 + 83.173 + endmethod 83.174 + 83.175 + method Action deq() if ( valids[0]._read() ); 83.176 + 83.177 + for (Integer x = 0; x < (n-1); x = x + 1) 83.178 + begin 83.179 + 83.180 + (registers[x]) <= registers[x + 1]._read(); 83.181 + (valids[x]) <= valids[x + 1]._read(); 83.182 + 83.183 + end 83.184 + (valids[n-1]) <= False; 83.185 + endmethod 83.186 + 83.187 + method alpha_T first() if ( valids[0]._read() ); 83.188 + return registers[0]._read(); 83.189 + endmethod 83.190 + 83.191 + method Bool find(search_T sv); 83.192 + Bool res = False; 83.193 + 83.194 + for (Integer x = 0; x < n; x = x + 1) 83.195 + if ( valids[x]._read() && searchfunc1(sv, registers[x]._read()) ) 83.196 + res = True; 83.197 + 83.198 + return res; 83.199 + 83.200 + endmethod 83.201 + 83.202 + method Bool find2(search_T sv); 83.203 + Bool res = False; 83.204 + 83.205 + for (Integer x = 0; x < n; x = x + 1) 83.206 + if ( valids[x]._read() && searchfunc2(sv, registers[x]._read()) ) 83.207 + res = True; 83.208 + 83.209 + return res; 83.210 + 83.211 + endmethod 83.212 + 83.213 + method Action clear(); 83.214 + 83.215 + for (Integer x = 0; x < n; x = x + 1) 83.216 + (valids[x]) <= False; 83.217 + 83.218 + endmethod 83.219 + 83.220 + method Bool notEmpty(); 83.221 + return valids[0]._read(); 83.222 + endmethod 83.223 + 83.224 + method Bool notFull(); 83.225 + return notFullHelper(); 83.226 + endmethod 83.227 + 83.228 +endmodule 83.229 + 83.230 +module mkSizedSFIFO#(Integer n, function Bool searchfunc(search_T s, alpha_T x)) (SFIFO#(alpha_T, search_T)) 83.231 + provisos 83.232 + (Bits#(alpha_T,asz)); 83.233 + 83.234 + let foo <- mkSizedSFIFOInternal(n, searchfunc, searchfunc); 83.235 + return foo; 83.236 + 83.237 +endmodule 83.238 \ No newline at end of file
84.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 84.2 +++ b/modules/bluespec/Pygar/lab4/processor.awb Fri Apr 23 02:32:05 2010 -0400 84.3 @@ -0,0 +1,13 @@ 84.4 +%name 3-Stage Processor 84.5 +%desc 3-Stage Processor, one stage per cycle. 84.6 + 84.7 +%provides processor 84.8 + 84.9 +%attributes 6_375 84.10 + 84.11 +%public Processor.bsv ProcTypes.bsv 84.12 +%public Processor.dic 84.13 + 84.14 + 84.15 + 84.16 +
85.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 85.2 +++ b/modules/bluespec/Pygar/lab4/processor_library.awb Fri Apr 23 02:32:05 2010 -0400 85.3 @@ -0,0 +1,8 @@ 85.4 +%name Processor Library 85.5 +%desc Some generally useful modules, found in the processor cores 85.6 + 85.7 +%provides processor_library 85.8 + 85.9 +%attributes 6_375 85.10 + 85.11 +%public Trace.bsv BFIFO.bsv MemTypes.bsv FIFOUtility.bsv GetPutExt.bsv SFIFO.bsv CBUFF.bsv BRegFile.bsv BranchPred.bsv 85.12 \ No newline at end of file
86.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 86.2 +++ b/modules/bluespec/Pygar/lab4/processor_system.awb Fri Apr 23 02:32:05 2010 -0400 86.3 @@ -0,0 +1,20 @@ 86.4 +%name Single Processor Application 86.5 +%desc Top level processor. This module wraps a processor, which at its highest level is just a memory stream. 86.6 + 86.7 +%provides connected_application 86.8 + 86.9 +%requires core 86.10 +%requires funcp_simulated_memory 86.11 +%requires funcp_base_types 86.12 +%requires hasim_common 86.13 + 86.14 +%attributes 6_375 86.15 + 86.16 +%sources -t BSV -v PUBLIC ProcessorSystem.bsv 86.17 +%sources -t CPP -v PUBLIC ProcessorSystem.cpp 86.18 +%sources -t H -v PUBLIC ProcessorSystem.h 86.19 +%sources -t CPP -v PUBLIC ProcessorSystemRRR.cpp 86.20 +%sources -t H -v PUBLIC ProcessorSystemRRR.h 86.21 +%sources -t RRR -v PUBLIC ProcessorSystemRRR.rrr 86.22 + 86.23 +