# HG changeset patch # User rlm # Date 1272004325 14400 # Node ID 74716e9a81cc7b1d6db2b329b9f3e7a58dae7145 # Parent 7393cd19371e63fa3d16d550820c2d03f5c72d89 [svn r9] Pygar now has the proper directory structure to play nicely with awb. Also, the apm file for audio-core willcompile successfully. diff -r 7393cd19371e -r 74716e9a81cc config/pm/Pygar/fullSystem/audio-core.apm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/config/pm/Pygar/fullSystem/audio-core.apm Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,119 @@ + +[Soft Connections Hybrid Application Environment/Requires] +platform_services=Platform Services +soft_connections_lib=Soft Connections Library +connected_application=Audio Processor Application + +[VMH hybrid memory] +File=modules/hasim/functional-partition/memory-state/memory/hybrid/vmh/vmh-memory.awb +Packagehint=hasim + +[Global] +SaveParameters=0 +DefaultBenchmark= +Version=2.1 +Type=HAsim +File=audio-core +Class=Asim::Model +Name=Bob's Yer Unkle +Description= +DefaultRunOpts= + +[Hybrid Project Common Utilities] +File=config/pm/hasim/submodels/common/project-common-default.apm +Packagehint=hasim + +[Soft Connections Library] +File=config/pm/hasim/submodels/common/soft-connections-lib.apm +Packagehint=hasim + +[Functional Partition Base Types] +File=modules/hasim/functional-partition/base-types/funcp-base-types.awb +Packagehint=hasim + +[3-Stage Audio Processor] +File=modules/bluespec/Pygar/core/processor.awb +Packagehint=Pygar + +[Audio Processor Soft Core] +File=modules/bluespec/Pygar/core/core.awb +Packagehint=Pygar + +[Blocking Data Cache] +File=modules/bluespec/Pygar/lab4/data_cache.awb +Packagehint=Pygar + +[Platform Services] +File=config/pm/hasim/submodels/platform-services/standard-platform-services.apm +Packagehint=hasim + +[Blocking Instruction Cache] +File=modules/bluespec/Pygar/lab4/instruction_cache.awb +Packagehint=Pygar + +[audio core] +File=modules/bluespec/Pygar/core/audio_core.awb +Packagehint=Pygar + +[Model] +DefaultAttributes= +model=HW/SW Hybrid Project Foundation + +[audio core/Requires] +hasim_common=Default HAsim Common Library +funcp_simulated_memory=VMH hybrid memory +core=Audio Processor Soft Core +funcp_base_types=Functional Partition Base Types +audio_pipeline_types=FIR Filter Pipeline Types + +[FPGA Environment] +File=config/pm/hasim/submodels/fpgaenv/fpgaenv-hybrid-exe.apm +Packagehint=platforms + +[HW/SW Hybrid Project Foundation] +File=modules/project/project-hybrid.awb +Packagehint=platforms + +[Round-robin Audio memory arbiter] +File=modules/bluespec/Pygar/core/mem_arb.awb +Packagehint=Pygar + +[Processor Audio Library] +File=modules/bluespec/Pygar/core/processor_library.awb +Packagehint=Pygar + +[Audio Processor Application/Requires] +audio_pipeline=audio core +audio_processor_types=Audio Processor Types + +[Default HAsim Common Library] +File=config/pm/hasim/submodels/common/hasim_common.apm +Packagehint=hasim + +[Audio Processor Application] +File=modules/bluespec/Pygar/common/audio_processor_hardware_system.awb +Packagehint=Pygar + +[Soft Connections Hybrid Application Environment] +File=modules/application-env/hybrid/soft-connections/application-env-hybrid-soft-conn.awb +Packagehint=platforms + +[HW/SW Hybrid Project Foundation/Requires] +project_common=Hybrid Project Common Utilities +fpgaenv=FPGA Environment +application_env=Soft Connections Hybrid Application Environment + +[FIR Filter Pipeline Types] +File=modules/bluespec/Pygar/lab1/fir_filter_types.awb +Packagehint=Pygar + +[Audio Processor Soft Core/Requires] +processor_library=Processor Audio Library +processor=3-Stage Audio Processor +data_cache=Blocking Data Cache +instruction_cache=Blocking Instruction Cache +mem_arb=Round-robin Audio memory arbiter + +[Audio Processor Types] +File=modules/bluespec/Pygar/common/audio_processor_types.awb +Packagehint=Pygar diff -r 7393cd19371e -r 74716e9a81cc config/pm/Pygar/fullSystem/audio_processor_exe.apm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/config/pm/Pygar/fullSystem/audio_processor_exe.apm Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,71 @@ + +[Global] +SaveParameters=0 +Description= +File=audio_processor_exe +Version=2.1 +Name=Audio Processor +DefaultBenchmark=config/bm/bluespec/demos.cfx/benchmarks/null.cfg +Type=HAsim +Class=Asim::Model +DefaultRunOpts= + +[Model] +DefaultAttributes=hybrid simulation +model=HW/SW Hybrid Project Foundation + +[FPGA Environment] +File=config/pm/hasim/submodels/fpgaenv/fpgaenv-hybrid-exe.apm +Packagehint=platforms + +[Audio Processor Types] +File=modules/bluespec/mit-6.375/common/audio_processor_types.awb +Packagehint=mit-6.375 + +[Default Audio Pipeline] +File=modules/bluespec/mit-6.375/common/audio_pipeline_default.awb +Packagehint=mit-6.375 + + + +[Soft Connections Hybrid Application Environment/Requires] +platform_services=Platform Services +soft_connections_lib=Soft Connections Library +connected_application=Audio Processor Application + +[Hybrid Project Common Utilities] +File=config/pm/hasim/submodels/common/project-common-default.apm +Packagehint=hasim + +[Soft Connections Library] +File=config/pm/hasim/submodels/common/soft-connections-lib.apm +Packagehint=hasim + +[Platform Services] +File=config/pm/hasim/submodels/platform-services/standard-platform-services.apm +Packagehint=hasim + +[HW/SW Hybrid Project Foundation] +File=modules/project/project-hybrid.awb +Packagehint=platforms + +[Soft Connections Hybrid Application Environment] +File=modules/application-env/hybrid/soft-connections/application-env-hybrid-soft-conn.awb +Packagehint=platforms + +[HW/SW Hybrid Project Foundation/Requires] +project_common=Hybrid Project Common Utilities +fpgaenv=FPGA Environment +application_env=Soft Connections Hybrid Application Environment + + +[Audio Processor Application/Requires] +audio_processor_types=Audio Processor Types +audio_pipeline=Default Audio Pipeline + +[HW/SW Hybrid Project Foundation/Params] +WAIT_FOR_HARDWARE=0 + +[Audio Processor Application] +File=modules/bluespec/mit-6.375/common/audio_processor_hardware_system.awb +Packagehint=mit-6.375 diff -r 7393cd19371e -r 74716e9a81cc documents/blah.pl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/documents/blah.pl Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,3 @@ +#!/usr/bin/perl + +print "oh Yeah"; diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/common/AudioPipelineDefault.bsv --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/common/AudioPipelineDefault.bsv Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,38 @@ +// The MIT License + +// Copyright (c) 2009 Massachusetts Institute of Technology + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +// Author: Kermin Fleming kfleming@mit.edu + +import Connectable::*; +import GetPut::*; +import ClientServer::*; +import FIFO::*; + +`include "asim/provides/audio_processor_types.bsh" + +module mkAudioPipeline (AudioPipeline); + FIFO#(AudioProcessorUnit) fifo <- mkFIFO; + + interface sampleInput = fifoToPut(fifo); + interface sampleOutput = fifoToGet(fifo); + +endmodule diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/common/AudioProcessor.bsv --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/common/AudioProcessor.bsv Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,77 @@ +// The MIT License + +// Copyright (c) 2009 Massachusetts Institute of Technology + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import Connectable::*; +import GetPut::*; +import ClientServer::*; + +//AWB includes +`include "asim/provides/low_level_platform_interface.bsh" +`include "asim/provides/soft_connections.bsh" +`include "asim/provides/common_services.bsh" + +// Local includes +`include "asim/provides/audio_processor_types.bsh" +`include "asim/provides/audio_pipeline.bsh" + +`include "asim/rrr/remote_client_stub_AUDIOPROCESSORRRR.bsh" +`include "asim/rrr/remote_server_stub_AUDIOPROCESSORRRR.bsh" + + +module [CONNECTED_MODULE] mkConnectedApplication (); + + // Instantiate the rrr stubs + ClientStub_AUDIOPROCESSORRRR client_stub <- mkClientStub_AUDIOPROCESSORRRR(); + ServerStub_AUDIOPROCESSORRRR server_stub <- mkServerStub_AUDIOPROCESSORRRR(); + + // Instantiate the audio pipeline + AudioPipeline pipeline <- mkAudioPipeline(); + + rule feedInput; + let command <- server_stub.acceptRequest_SendUnprocessedStream(); + AudioProcessorControl ctrl = unpack(truncate(command.ctrl)); + + if(ctrl == EndOfFile) + begin + pipeline.sampleInput.put(tagged EndOfFile); + end + else + begin + pipeline.sampleInput.put(tagged Sample unpack(truncate(command.sample))); + end + endrule + + rule feedOutput; + let pipelineData <- pipeline.sampleOutput.get(); + AudioProcessorControl endOfFileTag = EndOfFile; + AudioProcessorControl sampleTag = Data; + + case (pipelineData) matches + tagged EndOfFile: client_stub.makeRequest_SendProcessedStream(zeroExtend(pack(endOfFileTag)),?); + tagged Sample .sample:client_stub.makeRequest_SendProcessedStream(zeroExtend(pack(sampleTag)), + zeroExtend(pack(sample))); + endcase + endrule + +endmodule + + diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/common/AudioProcessor.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/common/AudioProcessor.cpp Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,104 @@ +#include +#include +#include + +#include "asim/provides/connected_application.h" +//#include "asim/provides/SndfileWavUtil.h" + +#include "asim/rrr/client_stub_AUDIOPROCESSORRRR.h" + +using namespace std; + +pthread_mutex_t CONNECTED_APPLICATION_CLASS::lock; +pthread_cond_t CONNECTED_APPLICATION_CLASS::cond; +sem_t CONNECTED_APPLICATION_CLASS::throttle; + +// constructor +CONNECTED_APPLICATION_CLASS::CONNECTED_APPLICATION_CLASS(VIRTUAL_PLATFORM vp) : + clientStub(new AUDIOPROCESSORRRR_CLIENT_STUB_CLASS(this)) +{ +} + +// destructor +CONNECTED_APPLICATION_CLASS::~CONNECTED_APPLICATION_CLASS() +{ +} + +// init +void +CONNECTED_APPLICATION_CLASS::Init() +{ + + pthread_mutex_init(&lock, NULL); + pthread_cond_init(&cond, NULL); + sem_init(&throttle, 0, 64); + +} + +void +CONNECTED_APPLICATION_CLASS::UpdateSemaphore() +{ + sem_post(&throttle); +} + +void +CONNECTED_APPLICATION_CLASS::EndSimulation() +{ + printf("EndSimulation Called\n"); + fflush(stdout); + pthread_mutex_lock(&lock); + // Do something about the race occuring here + pthread_cond_signal(&cond); + pthread_mutex_unlock(&lock); + printf("EndSimulation done\n"); + fflush(stdout); +} + +// main +void +CONNECTED_APPLICATION_CLASS::Main() +{ + FILE *inputFile; + UINT16 sample; + + // Convert input wav to pcm + generate_pcm("input.wav","input.pcm"); + + //Send data to the machine here. + inputFile = fopen("input.pcm","r"); + assert(inputFile); + + + int count = 0; + + printf("main: about to enter loop %d\n", count); + + while(fread(&sample, 2, 1, inputFile)) { + if(count%1000 == 0) + printf("main: %d\n", count); + count++; + sem_wait(&throttle); + clientStub->SendUnprocessedStream(Data,(UINT32)sample); + } + + printf("main: out of loop\n"); + + // Need to put lock here to prevent potential race condition + pthread_mutex_lock(&lock); + clientStub->SendUnprocessedStream(EndOfFile,0); + + printf("main: wait for end of file\n"); + + pthread_cond_wait(&cond, &lock); + pthread_mutex_unlock(&lock); + + printf("main: lastt data out\n"); + + // Convert input wav to pcm + generate_wav("out_hw.pcm","input.wav","out_hw.wav"); + + printf("generate wav done\n"); + + fflush(stdout); + exit(0); +} diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/common/AudioProcessor.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/common/AudioProcessor.h Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,56 @@ +// +// INTEL CONFIDENTIAL +// Copyright (c) 2008 Intel Corp. Recipient is granted a non-sublicensable +// copyright license under Intel copyrights to copy and distribute this code +// internally only. This code is provided "AS IS" with no support and with no +// warranties of any kind, including warranties of MERCHANTABILITY, +// FITNESS FOR ANY PARTICULAR PURPOSE or INTELLECTUAL PROPERTY INFRINGEMENT. +// By making any use of this code, Recipient agrees that no other licenses +// to any Intel patents, trade secrets, copyrights or other intellectual +// property rights are granted herein, and no other licenses shall arise by +// estoppel, implication or by operation of law. Recipient accepts all risks +// of use. +// + +// possibly use include paths to hide existing modules? + +#ifndef __AUDIO_PROCESSOR_CONNECTED_APPLICATION__ +#define __AUDIO_PROCESSOR_CONNECTED_APPLICATION__ + +#include +#include +#include + +#include "asim/provides/virtual_platform.h" + +#include "asim/rrr/client_stub_AUDIOPROCESSORRRR.h" + +typedef enum { + EndOfFile = 0, + Data = 1 +} AudioProcessorControl; + + +typedef class CONNECTED_APPLICATION_CLASS* CONNECTED_APPLICATION; +class CONNECTED_APPLICATION_CLASS : public PLATFORMS_MODULE_CLASS +{ + private: + AUDIOPROCESSORRRR_CLIENT_STUB clientStub; + static sem_t throttle; + static pthread_mutex_t lock; + static pthread_cond_t cond; + + public: + CONNECTED_APPLICATION_CLASS(VIRTUAL_PLATFORM vp); + ~CONNECTED_APPLICATION_CLASS(); + static void EndSimulation(); + static void UpdateSemaphore(); + + // init + void Init(); + + // main + void Main(); +}; + +#endif diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/common/AudioProcessorRRR.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/common/AudioProcessorRRR.cpp Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,93 @@ +#include +#include +#include +#include +#include +#include + +#include "asim/rrr/service_ids.h" + +#include "asim/provides/connected_application.h" + + + +using namespace std; + +// ===== service instantiation ===== +AUDIOPROCESSORRRR_SERVER_CLASS AUDIOPROCESSORRRR_SERVER_CLASS::instance; + +// constructor +AUDIOPROCESSORRRR_SERVER_CLASS::AUDIOPROCESSORRRR_SERVER_CLASS() : + serverStub(new AUDIOPROCESSORRRR_SERVER_STUB_CLASS(this)) +{ + // instantiate stub + printf("AUDIOPROCESSORRR init called\n"); + outputFile = NULL; +} + +// destructor +AUDIOPROCESSORRRR_SERVER_CLASS::~AUDIOPROCESSORRRR_SERVER_CLASS() +{ + Cleanup(); +} + +// init +void +AUDIOPROCESSORRRR_SERVER_CLASS::Init(PLATFORMS_MODULE p) +{ + parent = p; +} + +// uninit +void +AUDIOPROCESSORRRR_SERVER_CLASS::Uninit() +{ + Cleanup(); +} + +// cleanup +void +AUDIOPROCESSORRRR_SERVER_CLASS::Cleanup() +{ + delete serverStub; +} + + +// +// RRR service methods +// + +void +AUDIOPROCESSORRRR_SERVER_CLASS::SendProcessedStream(UINT16 control, UINT16 data) +{ + + AudioProcessorControl audioProcessorControl = (AudioProcessorControl) control; + switch(control) { + case EndOfFile: + if(outputFile != NULL) { + fflush(outputFile); + fclose(outputFile); + outputFile = NULL; + } else { + outputFile = fopen("out_hw.pcm","w"); + assert(outputFile); + fflush(outputFile); + fclose(outputFile); + } + + CONNECTED_APPLICATION_CLASS::EndSimulation(); + break; + + case Data: + if(outputFile == NULL) { + outputFile = fopen("out_hw.pcm","w"); + assert(outputFile); + } + + CONNECTED_APPLICATION_CLASS::UpdateSemaphore(); + fwrite(&data, 2,1 , outputFile); + break; + } + +} + diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/common/AudioProcessorRRR.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/common/AudioProcessorRRR.h Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,50 @@ + +#ifndef _AUDIOPROCESSORRRR_ +#define _AUDIOPROCESSORRRR_ + +#include +#include + +#include "asim/provides/low_level_platform_interface.h" + +#include "asim/provides/rrr.h" + + + +typedef class AUDIOPROCESSORRRR_SERVER_CLASS* AUDIOPROCESSORRRR_SERVER; +class AUDIOPROCESSORRRR_SERVER_CLASS: public RRR_SERVER_CLASS, public PLATFORMS_MODULE_CLASS +{ + private: + // self-instantiation + static AUDIOPROCESSORRRR_SERVER_CLASS instance; + FILE *outputFile; + + // server stub + RRR_SERVER_STUB serverStub; + + int count; + + public: + AUDIOPROCESSORRRR_SERVER_CLASS(); + ~AUDIOPROCESSORRRR_SERVER_CLASS(); + + // static methods + static AUDIOPROCESSORRRR_SERVER GetInstance() { return &instance; } + + // required RRR methods + void Init(PLATFORMS_MODULE); + void Uninit(); + void Cleanup(); + + // + // RRR service methods + // + void SendProcessedStream(UINT16 control, UINT16 data0); +}; + + + +// include server stub +#include "asim/rrr/server_stub_AUDIOPROCESSORRRR.h" + +#endif diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/common/AudioProcessorRRR.rrr --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/common/AudioProcessorRRR.rrr Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,14 @@ +service AUDIOPROCESSORRRR +{ + server sw (cpp, method) <- hw (bsv, connection) + { + method SendProcessedStream (in UINT32[32] ctrl, in UINT32[32] sample); + }; + + server hw (bsv, connection) <- sw (cpp, method) + { + method SendUnprocessedStream (in UINT32[32] ctrl, in UINT32[32] sample); + }; + + + }; diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/common/AudioProcessorTypes.bsv --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/common/AudioProcessorTypes.bsv Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,51 @@ +// The MIT License + +// Copyright (c) 2009 Massachusetts Institute of Technology + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +// Author: Kermin Fleming kfleming@mit.edu + +import Connectable::*; +import GetPut::*; +import ClientServer::*; + +typedef Int#(16) Sample; + +typedef enum { + EndOfFile = 0, + Data = 1 +} AudioProcessorControl deriving (Bits,Eq); + + +typedef struct { + Sample left; + Sample right; +} StereoSample deriving (Bits,Eq); + +typedef union tagged{ + Sample Sample; + void EndOfFile; +} AudioProcessorUnit deriving (Bits,Eq); + +interface AudioPipeline; + interface Put#(AudioProcessorUnit) sampleInput; + interface Get#(AudioProcessorUnit) sampleOutput; +endinterface + diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/common/DFT.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/common/DFT.cpp Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,46 @@ +#include +#include +#include + + +int DFT(int dir,int m,double *x1,double *y1) +{ + long i,k; + double arg; + double cosarg,sinarg; + double *x2=NULL,*y2=NULL; + + x2 = (double *)(malloc(m*sizeof(double))); + y2 = (double *)(malloc(m*sizeof(double))); + if (x2 == NULL || y2 == NULL) + return 0; + + for (i=0;i +#include +#include +#include +#include +#include "SndfileWavUtil.h" + +void +generate_wav(const char * pcmfilename, const char * samplewavfilename, const char * outputwavfilename) +{ + char outfilename[2048]; + SNDFILE * outfile ; + SNDFILE * wavfile ; + SNDFILE * pcmfile ; + SF_INFO wavinfo ; + SF_INFO pcminfo ; + int buff; + SF_INSTRUMENT inst ; + + memset (&wavinfo, 0, sizeof (wavinfo)) ; + + + wavfile = sf_open(samplewavfilename, SFM_READ, &wavinfo); + + if (wavfile == NULL){ + printf ("\nERROR : Not able to open wav file named '%s' : %s/\n", samplewavfilename, sf_strerror (NULL)) ; + exit (1) ; + } ; + + printf("WAV format: %x\n", wavinfo.format); + + if (!((wavinfo.format & SF_FORMAT_PCM_16) && (wavinfo.channels == 1) && + (wavinfo.format & SF_FORMAT_WAV))){ + printf("\nERROR : .wav file must be SF_FORMAT_PCM_16 in mono\n"); + } + + pcminfo.format = SF_FORMAT_RAW | SF_FORMAT_PCM_16; + pcminfo.samplerate = wavinfo.samplerate; + pcminfo.channels = wavinfo.channels; + + pcmfile = sf_open(pcmfilename, SFM_READ, &pcminfo); + + if (pcmfile == NULL){ + printf ("\nERROR : Not able to open pcm file named '%s' : %s/\n", pcmfilename, sf_strerror (NULL)) ; + exit (1) ; + } ; + + + + outfile = sf_open(outputwavfilename, SFM_WRITE, &wavinfo); + + memset (&inst, 0, sizeof (inst)) ; + + for(int i = SF_STR_FIRST; i <= SF_STR_LAST; i = i + 1) { + const char * str = sf_get_string(wavfile,i); + if(str != NULL) { + sf_set_string(outfile,i,str); + } + } + + if (outfile == NULL){ + printf ("\nERROR : Not able to create wav file named '%s' : %s/\n", outfilename, sf_strerror (NULL)) ; + exit (1) ; + } ; + + while(sf_read_int(pcmfile, &buff, 1) == 1){ + if(sf_write_int(outfile, &buff, 1) != 1){ + printf("\nERROR : unable to write to '%s' : %s/\n", outfilename, sf_strerror(NULL)); + } + } + + sf_close (wavfile) ; + sf_close (outfile) ; + sf_close (pcmfile) ; + +} + + +void +generate_pcm (const char * wavfilename, const char * pcmfilename) +{ + SNDFILE * wavfile ; + SNDFILE * pcmfile ; + SF_INFO wavinfo ; + SF_INFO pcminfo ; + int buff; + + memset (&wavinfo, 0, sizeof (wavinfo)) ; + memset (&pcminfo, 0, sizeof (pcminfo)) ; + + wavfile = sf_open (wavfilename, SFM_READ, &wavinfo) ; + + if (wavfile == NULL){ + printf ("\nERROR : Not able to open wav file named '%s' : %s/\n", wavfilename, sf_strerror (NULL)) ; + exit (1) ; + } ; + + pcminfo.format = SF_FORMAT_RAW | SF_FORMAT_PCM_16; + pcminfo.samplerate = wavinfo.samplerate; + pcminfo.channels = wavinfo.channels; + + if ((!wavinfo.format & SF_FORMAT_PCM_16) || (!wavinfo.channels == 1)){ + printf("\nERROR : .wav file must be SF_FORMAT_PCM_16 and mono\n"); + } + + pcmfile = sf_open (pcmfilename, SFM_WRITE, &pcminfo) ; + + if (pcmfile == NULL){ + printf ("\nERROR : Not able to create pcm file named '%s' : %s/\n", pcmfilename, sf_strerror (NULL)) ; + exit (1) ; + } ; + + while(sf_read_int(wavfile, &buff, 1) == 1){ + if(sf_write_int(pcmfile, &buff, 1) != 1){ + printf("\nERROR : unable to write to '%s' : %s/\n", pcmfilename, sf_strerror(NULL)); + } + } + + sf_close (wavfile) ; + sf_close (pcmfile) ; +} + + + + diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/common/SndfileWavUtil.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/common/SndfileWavUtil.h Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,9 @@ +#ifndef _SNDFILE_WAV_UTIL_ +#define _SNDFILE_WAV_UTIL_ + +int guess_direction (const char * filename1, const char * filename2) ; +int guess_major_format (const char * filename) ; +void generate_pcm(const char * wavfilename, const char * pcmfilename); +void generate_wav(const char * pcmfilename, const char * samplewavfilename, const char * outputwavfilename); + +#endif diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/common/audio_pipeline_default.awb --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/common/audio_pipeline_default.awb Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,10 @@ +%name Default Audio Pipeline +%desc A basic copy-though audio pipeline + +%provides audio_pipeline + +%attributes 6_375 + +%public AudioPipelineDefault.bsv + + diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/common/audio_processor_hardware_system.awb --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/common/audio_processor_hardware_system.awb Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,19 @@ +%name Audio Processor Application +%desc Top level audio processor. This module wraps an Audio Pipeline, providing communications between host and audio processor + +%provides connected_application + +%requires audio_processor_types +%requires audio_pipeline + +%attributes 6_375 + +%sources -t H -v PUBLIC AudioProcessor.h +%sources -t H -v PUBLIC AudioProcessorRRR.h +%sources -t H -v PUBLIC SndfileWavUtil.h +%sources -t BSV -v PUBLIC AudioProcessor.bsv +%sources -t CPP -v PRIVATE AudioProcessor.cpp +%sources -t CPP -v PRIVATE AudioProcessorRRR.cpp +%sources -t CPP -v PRIVATE SndfileWavUtil.cpp +%sources -t RRR -v PUBLIC AudioProcessorRRR.rrr +%library /usr/lib/libsndfile.so diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/common/audio_processor_software_system.awb --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/common/audio_processor_software_system.awb Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,16 @@ +******************************************************************** +* Awb module specification +******************************************************************** + +%AWB_START + +%name Audio Processor Software +%desc Audio Processor Software +%provides software_system + +%attributes 6_375 + +%public AudioProcessor.cpp +%public AudioProcessor.h + +%AWB_END diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/common/audio_processor_types.awb --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/common/audio_processor_types.awb Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,9 @@ +%name Audio Processor Types +%desc Audio Processing Pipeline Types + +%provides audio_processor_types + +%attributes 6_375 + +%public AudioProcessorTypes.bsv + diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/core/BFIFO.bsv --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/core/BFIFO.bsv Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,222 @@ +import FIFO::*; +import FIFOF::*; +import List::*; +import Assert::*; + +module mkBFIFO1( FIFO#(item_t) ) provisos ( Bits#(item_t,item_sz) ); + + RWire#(item_t) inputWire <- mkRWire(); + PulseWire deqEnabled <- mkPulseWire(); + PulseWire clearEnabled <- mkPulseWire(); + + Reg#(item_t) register <- mkRegU(); + Reg#(Bool) valid <- mkReg(False); + + // If there is an input item on the inputWire wire and dequeue did not + // execute this cycle then we need to store the item in the register + + (*fire_when_enabled*) + rule update ( True ); + case (inputWire.wget()) matches + tagged Invalid: + if (deqEnabled || clearEnabled) + valid <= False; + tagged Valid .x: + begin + register <= x; + valid <= !(deqEnabled || clearEnabled); + end + endcase + endrule + + // On enqueue we write the input item to the inputWire wire + + method Action enq( item_t item ) if ( !valid ); + inputWire.wset(item); + endmethod + + // On dequeue we always invalidate the storage register regardless + // of whether or not the item was actually bypassed or not. We also + // set a combinational signal so that we know not to move the item + // into the register this cycle. + + method Action deq() if ( valid || isValid(inputWire.wget()) ); + deqEnabled.send(); + endmethod + + // We get the item either from the register (if register is valid) or + // from the combinational bypasss (if the rwire is valid). + + method item_t first() if ( valid || isValid(inputWire.wget()) ); + if ( valid ) + return register; + else + return unJust(inputWire.wget()); + endmethod + + method Action clear(); + clearEnabled.send(); + endmethod + +endmodule + +module mkSizedBFIFO#(Integer n) ( FIFO#(item_t) ) provisos ( Bits#(item_t,item_sz) ); + + RWire#(item_t) inputWire <- mkRWire(); + PulseWire deqEnabled <- mkPulseWire(); + PulseWire clearEnabled <- mkPulseWire(); + + List#(Reg#(item_t)) registers <- replicateM(n, mkRegU); + List#(Reg#(Bool)) valids <- replicateM(n, mkReg(False)); + + function Nat getNextFree (List#(Reg#(Bool)) vs); + + Nat res = fromInteger(n - 1); + + for (Integer x = n - 1; x > -1; x = x - 1) + res = !vs[x]._read() ? fromInteger(x) : res; + + return res; + + endfunction + + function Bool notFull(); + + Bool full = True; + + for (Integer x = 0; x < length(valids); x = x + 1) + full = full && valids[x]._read(); + + return !full; + + endfunction + // If there is an input item on the inputWire wire and dequeue did not + // execute this cycle then we need to store the item in the register + + rule update ( True ); + Nat next = getNextFree(valids); + + next = (deqEnabled) ? next - 1 : next; + + (valids[next]) <= isValid(inputWire.wget()); + (registers[next]) <= validValue(inputWire.wget()); + + if (deqEnabled && !clearEnabled) + begin + + for (Nat x = 0; x < (next - 1); x = x + 1) + begin + (valids[x]) <= valids[x+1]._read(); + (registers[x]) <= registers[x+1]._read(); + end + + end + else if (clearEnabled) + begin + + for (Integer x = 0; x < n; x = x + 1) + (valids[x]) <= False; + + end + endrule + + // On enqueue we write the input item to the inputWire wire + + method Action enq( item_t item ) if ( notFull ); + inputWire.wset(item); + endmethod + + // On dequeue we always invalidate the storage register regardless + // of whether or not the item was actually bypassed or not. We also + // set a combinational signal so that we know not to move the item + // into the register this cycle. + + method Action deq() if ( valids[0]._read() || isValid(inputWire.wget()) ); + deqEnabled.send(); + endmethod + + // We get the item either from the register (if register is valid) or + // from the combinational bypasss (if the rwire is valid). + + method item_t first() if ( valids[0]._read() || isValid(inputWire.wget()) ); + if ( valids[0]._read() ) + return registers[0]._read(); + else + return unJust(inputWire.wget()); + endmethod + + + method Action clear(); + clearEnabled.send(); + endmethod + +endmodule + + +module mkBFIFOF1( FIFOF#(item_t) ) provisos ( Bits#(item_t,item_sz) ); + + RWire#(item_t) inputWire <- mkRWire(); + RWire#(Bool) deqEnabled <- mkRWire(); + + Reg#(Maybe#(item_t)) register <- mkReg(Invalid); + + // If there is an input item on the inputWire wire and dequeue did not + // execute this cycle then we need to store the item in the register + + rule noDeq ( isValid(inputWire.wget()) && !isValid(deqEnabled.wget()) ); + register <= inputWire.wget(); + endrule + + // On enqueue we write the input item to the inputWire wire + + method Action enq( item_t item ) if ( !isValid(register) ); + inputWire.wset(item); + endmethod + + // On dequeue we always invalidate the storage register regardless + // of whether or not the item was actually bypassed or not. We also + // set a combinational signal so that we know not to move the item + // into the register this cycle. + + method Action deq() if ( isValid(register) || isValid(inputWire.wget()) ); + register <= Invalid; + deqEnabled.wset(True); + endmethod + + // We get the item either from the register (if register is valid) or + // from the combinational bypasss (if the rwire is valid). + + method item_t first() if ( isValid(register) || isValid(inputWire.wget()) ); + if ( isValid(register) ) + return unJust(register); + else + return unJust(inputWire.wget()); + endmethod + + // FIFOF adds the following two methods + + method Bool notFull(); + return !isValid(register); + endmethod + + method Bool notEmpty(); + return (isValid(register) || isValid(inputWire.wget())); + endmethod + + // Not sure about the clear method ... + + method Action clear(); + dynamicAssert( False, "BFIFO.clear() not implemented yet!" ); + endmethod + +endmodule + +(* synthesize *) +module mkBFIFO_16 (FIFO#(Bit#(16))); + + let f <- mkBFIFO1(); + + return f; + +endmodule + diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/core/BRegFile.bsv --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/core/BRegFile.bsv Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,36 @@ +import RegFile::*; +import RWire::*; +import ProcTypes::*; + +//----------------------------------------------------------- +// Register file module +//----------------------------------------------------------- + +interface BRegFile #(type index_t, type data_t); + method Action upd(index_t addr, data_t data); + method data_t sub(index_t addr); +endinterface + +module mkBRegFile(RegFile#(index_t, data_t)) + provisos (Bits#(index_t, size_index), + Bits#(data_t, size_data), + Eq#(index_t), + Bounded#(index_t) ); + + RegFile#(index_t, data_t) rf <- mkRegFileWCF(minBound, maxBound); + RWire#(Tuple2#(index_t, data_t)) rw <-mkRWire(); + + method Action upd (index_t r, data_t d); + rf.upd(r,d); + rw.wset(tuple2(r,d)); + endmethod + + method data_t sub (index_t r); + case (rw.wget()) matches + tagged Valid {.wr, .d} : + return (wr == r) ? d : rf.sub(r); + tagged Invalid : return rf.sub(r); + endcase + endmethod + +endmodule diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/core/BranchPred.bsv --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/core/BranchPred.bsv Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,41 @@ +import RegFile::*; +import ProcTypes::*; +import FIFO::*; + +typedef Maybe#(Addr) BrPred; +typedef Bit#(4) BPindx; + +typedef struct {Addr brpc; Addr nextpc;} BrPair deriving (Bits,Eq); + +typedef union tagged +{ + BrPair Valid; + void Invalid; +} CBranchPath deriving(Bits, Eq); // have the cache start out invalid and add valid values. + +interface BranchPred; + method BrPred get(Addr pres); //returns a maybe type that is invalid if no predition + method Action upd(Addr pres, Addr next); +endinterface + +module mkBranchPred(BranchPred); + + //state variables + RegFile#(BPindx, CBranchPath) bcache <- mkRegFileFull(); // cache to hold 16 (based on BPindx) + + method Action upd(Addr pres, Addr next); + BrPair brp; + brp = BrPair {brpc:pres, nextpc:next}; + bcache.upd(pres[5:2], tagged Valid brp); + endmethod + + method BrPred get(Addr prespc); + BPindx rd = prespc[5:2]; + let cbp = bcache.sub(rd); + if (cbp matches tagged Valid .bp &&& bp.brpc == prespc) //make sure that the read value was actually put there and the full address matches + return tagged Valid bp.nextpc; + else return Invalid; + endmethod + +endmodule + diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/core/Core.bsv --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/core/Core.bsv Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,81 @@ +// The MIT License + +// Copyright (c) 2009 Massachusetts Institute of Technology + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import Connectable::*; +import GetPut::*; +import ClientServer::*; + +import DataCacheBlocking::*; +import InstCacheBlocking::*; +import Processor::*; +import MemArb::*; +import MemTypes::*; + +interface CoreStats; + interface DCacheStats dcache; + interface ICacheStats icache; + interface ProcStats proc; +endinterface + +interface Core; + + // Interface from core to main memory + interface Client#(MainMemReq,MainMemResp) mmem_client; + + // Statistics + interface CoreStats stats; + + // CPU to Host + interface CPUToHost tohost; + +endinterface + +(* synthesize *) +module mkCore(Core); + + // Instantiate the modules + Proc proc <- mkProc(); + ICache#(InstReq,InstResp) icache <- mkInstCache(); + DCache#(DataReq,DataResp) dcache <- mkDataCache(); + MemArb marb <- mkMemArb(); + + // Internal connections + mkConnection( proc.statsEn_get, icache.statsEn_put ); + mkConnection( proc.statsEn_get, dcache.statsEn_put ); + mkConnection( proc.imem_client, icache.proc_server ); + mkConnection( proc.dmem_client, dcache.proc_server ); + mkConnection( icache.mmem_client, marb.cache0_server ); + mkConnection( dcache.mmem_client, marb.cache1_server ); + + // Methods + interface mmem_client = marb.mmem_client; + + interface CoreStats stats; + interface dcache = dcache.stats; + interface icache = icache.stats; + interface proc = proc.stats; + endinterface + + interface CPUToHost tohost = proc.tohost; + +endmodule + diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/core/DataCache.dic --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/core/DataCache.dic Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,3 @@ +def STATS.DATA_CACHE.NUM_ACCESSES "DATA_CACHE: Number Of Accesses: "; +def STATS.DATA_CACHE.NUM_MISSES "DATA_CACHE: Number Of Misses: "; +def STATS.DATA_CACHE.NUM_WRITEBACKS "DATA_CACHE: Number Of Writebacks: "; \ No newline at end of file diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/core/DataCacheBlocking.bsv --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/core/DataCacheBlocking.bsv Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,295 @@ +// The MIT License + +// Copyright (c) 2009 Massachusetts Institute of Technology + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import Connectable::*; +import GetPut::*; +import ClientServer::*; +import RegFile::*; +import FIFO::*; +import FIFOF::*; + +import BFIFO::*; +import MemTypes::*; +import ProcTypes::*; +import Trace::*; + +interface DCacheStats; + interface Get#(Stat) num_accesses; + interface Get#(Stat) num_misses; + interface Get#(Stat) num_writebacks; +endinterface + +interface DCache#( type req_t, type resp_t ); + + // Interface from processor to cache + interface Server#(req_t,resp_t) proc_server; + + // Interface from cache to main memory + interface Client#(MainMemReq,MainMemResp) mmem_client; + + // Interface for enabling/disabling statistics + interface Put#(Bool) statsEn_put; + + // Interface for collecting statistics + interface DCacheStats stats; + +endinterface + + +//---------------------------------------------------------------------- +// Cache Types +//---------------------------------------------------------------------- + +typedef 10 CacheLineIndexSz; +typedef 20 CacheLineTagSz; +typedef 32 CacheLineSz; + +typedef Bit#(CacheLineIndexSz) CacheLineIndex; +typedef Bit#(CacheLineTagSz) CacheLineTag; +typedef Bit#(CacheLineSz) CacheLine; + +typedef enum +{ + Init, + Access, + RefillReq, + RefillResp +} +CacheStage +deriving (Eq,Bits); + +//---------------------------------------------------------------------- +// Helper functions +//---------------------------------------------------------------------- + +function Bit#(AddrSz) getAddr( DataReq req ); + + Bit#(AddrSz) addr = ?; + case ( req ) matches + tagged LoadReq .ld : addr = ld.addr; + tagged StoreReq .st : addr = st.addr; + endcase + + return addr; + +endfunction + +function CacheLineIndex getCacheLineIndex( DataReq req ); + Bit#(AddrSz) addr = getAddr(req); + Bit#(CacheLineIndexSz) index = truncate( addr >> 2 ); + return index; +endfunction + +function CacheLineTag getCacheLineTag( DataReq req ); + Bit#(AddrSz) addr = getAddr(req); + Bit#(CacheLineTagSz) tag = truncate( addr >> fromInteger(valueOf(CacheLineIndexSz)) >> 2 ); + return tag; +endfunction + +function Bit#(AddrSz) getCacheLineAddr( DataReq req ); + Bit#(AddrSz) addr = getAddr(req); + return ((addr >> 2) << 2); +endfunction + +//---------------------------------------------------------------------- +// Main module +//---------------------------------------------------------------------- + +(* doc = "synthesis attribute ram_style mkDataCache distributed;" *) +(* synthesize *) +module mkDataCache( DCache#(DataReq,DataResp) ); + + //----------------------------------------------------------- + // State + + Reg#(CacheStage) stage <- mkReg(Init); + + RegFile#(CacheLineIndex,Maybe#(CacheLineTag)) cacheTagRam <- mkRegFileFull(); + RegFile#(CacheLineIndex,CacheLine) cacheDataRam <- mkRegFileFull(); + + FIFO#(DataReq) reqQ <- mkFIFO(); + FIFOF#(DataResp) respQ <- mkBFIFOF1(); + + FIFO#(MainMemReq) mainMemReqQ <- mkBFIFO1(); + FIFO#(MainMemResp) mainMemRespQ <- mkFIFO(); + + Reg#(CacheLineIndex) initCounter <- mkReg(1); + + // Statistics state + + Reg#(Bool) statsEn <- mkReg(False); + + Reg#(Stat) num_accesses <- mkReg(0); + Reg#(Stat) num_misses <- mkReg(0); + Reg#(Stat) num_writebacks <- mkReg(0); + + //----------------------------------------------------------- + // Name some wires + + let req = reqQ.first(); + let reqIndex = getCacheLineIndex(req); + let reqTag = getCacheLineTag(req); + let reqCacheLineAddr = getCacheLineAddr(req); + + //----------------------------------------------------------- + // Initialize + + rule init ( stage == Init ); + traceTiny("mkDataCacheBlocking", "stage","i"); + initCounter <= initCounter + 1; + cacheTagRam.upd(initCounter,Invalid); + if ( initCounter == 0 ) + stage <= Access; + endrule + + //----------------------------------------------------------- + // Access cache rule + + rule access ( (stage == Access) && respQ.notFull() ); + + // Statistics + + if ( statsEn ) + num_accesses <= num_accesses + 1; + + + // Get the corresponding tag from the rams + + Maybe#(CacheLineTag) cacheLineTag = cacheTagRam.sub(reqIndex); + + // Handle cache hits ... + + if ( isValid(cacheLineTag) && ( unJust(cacheLineTag) == reqTag ) ) + begin + traceTiny("mkDataCacheBlocking", "hitMiss","h"); + reqQ.deq(); + + case ( req ) matches + + tagged LoadReq .ld : + respQ.enq( LoadResp { tag: ld.tag, data: cacheDataRam.sub(reqIndex) } ); + + tagged StoreReq .st : + begin + respQ.enq( StoreResp { tag : st.tag } ); + cacheDataRam.upd(reqIndex,st.data); + end + + endcase + + end + + // Handle cache misses ... + + else + begin + traceTiny("mkDataCacheBlocking", "hitMiss","m"); + if ( statsEn ) + num_misses <= num_misses + 1; + + // Currently we don't use dirty bits so we always writeback the data if it is valid + + if ( isValid(cacheLineTag) ) + begin + + if ( statsEn ) + num_writebacks <= num_writebacks + 1; + + MainMemReq wbReq + = StoreReq { tag : 0, + addr : { unJust(cacheLineTag), reqIndex, 2'b0 }, + data : cacheDataRam.sub(reqIndex) }; + + mainMemReqQ.enq(wbReq); + stage <= RefillReq; + end + + // Otherwise we can issue the refill request now + + else + begin + mainMemReqQ.enq( LoadReq { tag: 0, addr: reqCacheLineAddr } ); + stage <= RefillResp; + end + + end + + endrule + + //----------------------------------------------------------- + // Refill request rule + + rule refillReq ( stage == RefillReq ); + traceTiny("mkDataCacheBlocking", "stage","r"); + mainMemReqQ.enq( LoadReq { tag: 0, addr: reqCacheLineAddr } ); + stage <= RefillResp; + endrule + + //----------------------------------------------------------- + // Refill response rule + + rule refillResp ( stage == RefillResp ); + traceTiny("mkDataCacheBlocking", "stage","R"); + traceTiny("mkDataCacheBlocking", "refill",mainMemRespQ.first()); + + // Write the new data into the cache and update the tag + + mainMemRespQ.deq(); + case ( mainMemRespQ.first() ) matches + + tagged LoadResp .ld : + begin + cacheTagRam.upd(reqIndex,Valid(reqTag)); + cacheDataRam.upd(reqIndex,ld.data); + end + + tagged StoreResp .st : + noAction; + + endcase + + stage <= Access; + endrule + + //----------------------------------------------------------- + // Methods + + interface Client mmem_client; + interface Get request = toGet(mainMemReqQ); + interface Put response = toPut(mainMemRespQ); + endinterface + + interface Server proc_server; + interface Put request = tracePut("mkDataCacheBlocking", "reqTiny",toPut(reqQ)); + interface Get response = traceGet("mkDataCacheBlocking", "respTiny",toGet(respQ)); + endinterface + + interface Put statsEn_put = toPut(asReg(statsEn)); + + interface DCacheStats stats; + interface Get num_accesses = toGet(asReg(num_accesses)); + interface Get num_misses = toGet(asReg(num_misses)); + interface Get num_writebacks = toGet(asReg(num_writebacks)); + endinterface + +endmodule + diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/core/FIRFilterPipeline.bsv --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/core/FIRFilterPipeline.bsv Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,46 @@ +// The MIT License + +// Copyright (c) 2009 Massachusetts Institute of Technology + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +// Author: Kermin Fleming kfleming@mit.edu + +import Connectable::*; +import GetPut::*; +import ClientServer::*; +import FIFO::*; + +//AWB includes +`include "asim/provides/low_level_platform_interface.bsh" +`include "asim/provides/soft_connections.bsh" +`include "asim/provides/common_services.bsh" + +//Local includes +`include "asim/provides/audio_processor_types.bsh" +`include "asim/provides/audio_pipeline_types.bsh" +`include "asim/provides/fir_filter.bsh" + +module [Connected_Module] mkAudioPipeline (AudioPipeline); + FIRFilter filter <- mkFIRFilter; + + interface sampleInput = filter.sampleInput; + interface sampleOutput = filter.sampleOutput; + +endmodule diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/core/InstCache.dic --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/core/InstCache.dic Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,3 @@ +def STATS.INST_CACHE.NUM_ACCESSES "INST_CACHE: Number Of Accesses: "; +def STATS.INST_CACHE.NUM_MISSES "INST_CACHE: Number Of Misses: "; +def STATS.INST_CACHE.NUM_EVICTIONS "INST_CACHE: Number Of Evictions: "; diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/core/InstCacheBlocking.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/core/InstCacheBlocking.d Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,269 @@ +// The MIT License + +// Copyright (c) 2009 Massachusetts Institute of Technology + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import Connectable::*; +import GetPut::*; +import ClientServer::*; +import RegFile::*; +import FIFO::*; +import FIFOF::*; +import RWire::*; + +import BFIFO::*; +import MemTypes::*; +import ProcTypes::*; +import Trace::*; + +interface ICacheStats; + interface Get#(Stat) num_accesses; + interface Get#(Stat) num_misses; + interface Get#(Stat) num_evictions; +endinterface + +interface ICache#( type req_t, type resp_t ); + + // Interface from processor to cache + interface Server#(req_t,resp_t) proc_server; + + // Interface from cache to main memory + interface Client#(MainMemReq,MainMemResp) mmem_client; + + // Interface for enabling/disabling statistics + interface Put#(Bool) statsEn_put; + + // Interface for collecting statistics + interface ICacheStats stats; + +endinterface + +//---------------------------------------------------------------------- +// Cache Types +//---------------------------------------------------------------------- + +typedef 10 CacheLineIndexSz; +typedef 20 CacheLineTagSz; +typedef 32 CacheLineSz; + +typedef Bit#(CacheLineIndexSz) CacheLineIndex; +typedef Bit#(CacheLineTagSz) CacheLineTag; +typedef Bit#(CacheLineSz) CacheLine; + +typedef enum +{ + Init, + Access, + Evict, + RefillReq, + RefillResp +} +CacheStage +deriving (Eq,Bits); + +//---------------------------------------------------------------------- +// Helper functions +//---------------------------------------------------------------------- + +function Bit#(AddrSz) getAddr( InstReq req ); + + Bit#(AddrSz) addr = ?; + case ( req ) matches + tagged LoadReq .ld : addr = ld.addr; + tagged StoreReq .st : addr = st.addr; + endcase + + return addr; + +endfunction + +function CacheLineIndex getCacheLineIndex( InstReq req ); + Bit#(AddrSz) addr = getAddr(req); + Bit#(CacheLineIndexSz) index = truncate( addr >> 2 ); + return index; +endfunction + +function CacheLineTag getCacheLineTag( InstReq req ); + Bit#(AddrSz) addr = getAddr(req); + Bit#(CacheLineTagSz) tag = truncate( addr >> fromInteger(valueOf(CacheLineIndexSz)) >> 2 ); + return tag; +endfunction + +function Bit#(AddrSz) getCacheLineAddr( InstReq req ); + Bit#(AddrSz) addr = getAddr(req); + return ((addr >> 2) << 2); +endfunction + +//---------------------------------------------------------------------- +// Main module +//---------------------------------------------------------------------- + +(* doc = "synthesis attribute ram_style mkInstCache distributed;" *) +(* synthesize *) +module mkInstCache( ICache#(InstReq,InstResp) ); + + //----------------------------------------------------------- + // State + + Reg#(CacheStage) stage <- mkReg(Init); + + RegFile#(CacheLineIndex,Maybe#(CacheLineTag)) cacheTagRam <- mkRegFileFull(); + RegFile#(CacheLineIndex,CacheLine) cacheDataRam <- mkRegFileFull(); + + FIFO#(InstReq) reqQ <- mkFIFO(); + FIFOF#(InstResp) respQ <- mkBFIFOF1(); + + FIFO#(MainMemReq) mainMemReqQ <- mkBFIFO1(); + FIFO#(MainMemResp) mainMemRespQ <- mkFIFO(); + + Reg#(CacheLineIndex) initCounter <- mkReg(1); + + // Statistics state + + Reg#(Bool) statsEn <- mkReg(False); + + Reg#(Stat) numAccesses <- mkReg(0); + Reg#(Stat) numMisses <- mkReg(0); + Reg#(Stat) numEvictions <- mkReg(0); + + //----------------------------------------------------------- + // Name some wires + + let req = reqQ.first(); + let reqIndex = getCacheLineIndex(req); + let reqTag = getCacheLineTag(req); + let reqCacheLineAddr = getCacheLineAddr(req); + let refill = mainMemRespQ.first(); + + //----------------------------------------------------------- + // Initialize + + rule init ( stage == Init ); + traceTiny("mkInstCacheBlocking", "stage","i"); + initCounter <= initCounter + 1; + cacheTagRam.upd(initCounter,Invalid); + if ( initCounter == 0 ) + stage <= Access; + endrule + + //----------------------------------------------------------- + // Cache access rule + + rule access ( (stage == Access) && respQ.notFull() ); + + // Statistics + + if ( statsEn ) + numAccesses <= numAccesses + 1; + + // Check tag and valid bit to see if this is a hit or a miss + + Maybe#(CacheLineTag) cacheLineTag = cacheTagRam.sub(reqIndex); + + // Handle cache hits ... + + if ( isValid(cacheLineTag) && ( unJust(cacheLineTag) == reqTag ) ) + begin + traceTiny("mkInstCacheBlocking", "hitMiss","h"); + reqQ.deq(); + + case ( req ) matches + + tagged LoadReq .ld : + respQ.enq( LoadResp { tag : ld.tag, data : cacheDataRam.sub(reqIndex) } ); + + tagged StoreReq .st : + $display( " RTL-ERROR : %m : Stores are not allowed on the inst port!" ); + + endcase + + end + + // Handle cache misses - since lines in instruction cache are + // never dirty we can always immediately issue a refill request + + else + begin + traceTiny("mkInstCacheBlocking", "hitMiss","m"); + if ( statsEn ) + numMisses <= numMisses + 1; + if ( statsEn ) + if ( isJust(cacheLineTag) ) + numEvictions <= numEvictions + 1; + + MainMemReq rfReq + = LoadReq { tag : 0, + addr : reqCacheLineAddr }; + + mainMemReqQ.enq(rfReq); + stage <= RefillResp; + end + + endrule + + //----------------------------------------------------------- + // Refill response rule + + rule refillResp ( stage == RefillResp ); + traceTiny("mkInstCacheBlocking", "stage","R"); + traceTiny("mkInstCacheBlocking", "refill",refill); + + // Write the new data into the cache and update the tag + + mainMemRespQ.deq(); + case ( mainMemRespQ.first() ) matches + + tagged LoadResp .ld : + begin + cacheTagRam.upd(reqIndex,Valid(reqTag)); + cacheDataRam.upd(reqIndex,ld.data); + end + + tagged StoreResp .st : + noAction; + + endcase + + stage <= Access; + endrule + + //----------------------------------------------------------- + // Methods + + interface Client mmem_client; + interface Get request = fifoToGet(mainMemReqQ); + interface Put response = fifoToPut(mainMemRespQ); + endinterface + + interface Server proc_server; + interface Put request = tracePut("mkInstCacheBlocking", "reqTiny",toPut(reqQ)); + interface Get response = traceGet("mkInstCacheBlocking", "respTiny",toGet(respQ)); + endinterface + + interface Put statsEn_put = toPut(asReg(statsEn)); + + interface ICacheStats stats; + interface Get num_accesses = toGet(asReg(numAccesses)); + interface Get num_misses = toGet(asReg(numMisses)); + interface Get num_evictions = toGet(asReg(numEvictions)); + endinterface + +endmodule + diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/core/MemArb.bsv --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/core/MemArb.bsv Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,141 @@ +// The MIT License + +// Copyright (c) 2009 Massachusetts Institute of Technology + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import Connectable::*; +import GetPut::*; +import ClientServer::*; +import FIFOF::*; +import FIFO::*; + +import BFIFO::*; +import MemTypes::*; +import Trace::*; + +interface MemArb; + + interface Server#(MainMemReq,MainMemResp) cache0_server; + interface Server#(MainMemReq,MainMemResp) cache1_server; + interface Client#(MainMemReq,MainMemResp) mmem_client; + +endinterface + +typedef enum { REQ0, REQ1 } ReqPtr deriving(Eq,Bits); + +(* synthesize *) +module mkMemArb( MemArb ); + + //----------------------------------------------------------- + // State + + FIFOF#(MainMemReq) req0Q <- mkFIFOF1(); + FIFO#(MainMemResp) resp0Q <- mkFIFO1(); + + FIFOF#(MainMemReq) req1Q <- mkFIFOF1(); + FIFO#(MainMemResp) resp1Q <- mkFIFO1(); + + FIFO#(MainMemReq) mreqQ <- mkFIFO1(); + FIFO#(MainMemResp) mrespQ <- mkFIFO1(); + + Reg#(ReqPtr) nextReq <- mkReg(REQ0); + + //----------------------------------------------------------- + // Some wires + + let req0avail = req0Q.notEmpty(); + let req1avail = req1Q.notEmpty(); + + //----------------------------------------------------------- + // Rules + + rule chooseReq0 ( req0avail && (!req1avail || (nextReq == REQ0)) ); + traceTiny("mkMemArb", "memArb req0",req0Q.first()); + + // Rewrite tag field if this is a load ... + MainMemReq mreq + = case ( req0Q.first() ) matches + tagged LoadReq .ld : return LoadReq { tag:0, addr:ld.addr }; + tagged StoreReq .st : return req0Q.first(); + endcase; + + // Send out the request + mreqQ.enq(mreq); + nextReq <= REQ1; + req0Q.deq(); + + endrule + + rule chooseReq1 ( req1avail && (!req0avail || (nextReq == REQ1)) ); + traceTiny("mkMemArb", "memArb req1",req1Q.first); + + // Rewrite tag field if this is a load ... + MainMemReq mreq + = case ( req1Q.first() ) matches + tagged LoadReq .ld : return LoadReq { tag:1, addr:ld.addr }; + tagged StoreReq .st : return req1Q.first(); + endcase; + + // Send out the request + mreqQ.enq(mreq); + nextReq <= REQ0; + req1Q.deq(); + + endrule + + rule returnResp; + traceTiny("mkMemArb", "resp",mrespQ.first()); + + // Use tag to figure out where to send response + mrespQ.deq(); + let tag + = case ( mrespQ.first() ) matches + tagged LoadResp .ld : return ld.tag; + tagged StoreResp .st : return st.tag; + endcase; + + if ( tag == 0 ) + resp0Q.enq(mrespQ.first()); + else + resp1Q.enq(mrespQ.first()); + + endrule + + //----------------------------------------------------------- + // Methods + + interface Server cache0_server; + interface Put request = toPut(req0Q); + interface Get response = toGet(resp0Q); + endinterface + + interface Server cache1_server; + interface Put request = toPut(req1Q); + interface Get response = toGet(resp1Q); + endinterface + + interface Client mmem_client; + interface Get request = toGet(mreqQ); + interface Put response = toPut(mrespQ); + endinterface + +endmodule + + diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/core/MemTypes.bsv --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/core/MemTypes.bsv Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,93 @@ + +import Trace::*; + +//---------------------------------------------------------------------- +// Basic memory requests and responses +//---------------------------------------------------------------------- + +typedef union tagged +{ + struct { Bit#(addrSz) addr; Bit#(tagSz) tag; } LoadReq; + struct { Bit#(addrSz) addr; Bit#(tagSz) tag; Bit#(dataSz) data; } StoreReq; +} +MemReq#( type addrSz, type tagSz, type dataSz ) +deriving(Eq,Bits); + +typedef union tagged +{ + struct { Bit#(tagSz) tag; Bit#(dataSz) data; } LoadResp; + struct { Bit#(tagSz) tag; } StoreResp; +} +MemResp#( type tagSz, type dataSz ) +deriving(Eq,Bits); + +//---------------------------------------------------------------------- +// Specialized req/resp for inst/data/host +//---------------------------------------------------------------------- + +typedef 32 AddrSz; +typedef 08 TagSz; +typedef 32 DataSz; +typedef 32 InstSz; +typedef 32 HostDataSz; + +typedef MemReq#(AddrSz,TagSz,0) InstReq; +typedef MemResp#(TagSz,InstSz) InstResp; + +typedef MemReq#(AddrSz,TagSz,DataSz) DataReq; +typedef MemResp#(TagSz,DataSz) DataResp; + +typedef MemReq#(AddrSz,TagSz,HostDataSz) HostReq; +typedef MemResp#(TagSz,HostDataSz) HostResp; + +//---------------------------------------------------------------------- +// Specialized req/resp for main memory +//---------------------------------------------------------------------- + +typedef 32 MainMemAddrSz; +typedef 08 MainMemTagSz; +typedef 32 MainMemDataSz; + +typedef MemReq#(MainMemAddrSz,MainMemTagSz,MainMemDataSz) MainMemReq; +typedef MemResp#(MainMemTagSz,MainMemDataSz) MainMemResp; + +//---------------------------------------------------------------------- +// Tracing Functions +//---------------------------------------------------------------------- + +instance Traceable#(MemReq#(a,b,c)); + + function Action traceTiny( String loc, String ttag, MemReq#(a,b,c) req ); + case ( req ) matches + tagged LoadReq .ld : $fdisplay(stderr, " => %s:%s l%2x", loc, ttag, ld.tag ); + tagged StoreReq .st : $fdisplay(stderr, " => %s:%s s%2x", loc, ttag, st.tag ); + endcase + endfunction + + function Action traceFull( String loc, String ttag, MemReq#(a,b,c) req ); + case ( req ) matches + tagged LoadReq .ld : $fdisplay(stderr, " => %s:%s Ld { addr=%x, tag=%x }", loc, ttag, ld.addr, ld.tag ); + tagged StoreReq .st : $fdisplay(stderr, " => %s:%s St { addr=%x, tag=%x, data=%x }", loc, ttag, st.addr, st.tag, st.data ); + endcase + endfunction + +endinstance + +instance Traceable#(MemResp#(a,b)); + + function Action traceTiny( String loc, String ttag, MemResp#(a,b) resp ); + case ( resp ) matches + tagged LoadResp .ld : $fdisplay(stderr, " => %s:%s l%2x", loc, ttag, ld.tag ); + tagged StoreResp .st : $fdisplay(stderr, " => %s:%s s%2x", loc, ttag, st.tag ); + endcase + endfunction + + function Action traceFull( String loc, String ttag, MemResp#(a,b) resp ); + case ( resp ) matches + tagged LoadResp .ld : $fdisplay(stderr, " => %s:%s Ld { tag=%x, data=%x }", loc, ttag, ld.tag, ld.data ); + tagged StoreResp .st : $fdisplay(stderr, " => %s:%s St { tag=%x }", loc, ttag, st.tag ); + endcase + endfunction + +endinstance + diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/core/PathTypes.bsv --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/core/PathTypes.bsv Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,31 @@ +import Trace::*; +import Vector::*; + +`define MAX_VOICES 4 +`define MAX_CORES 16 +`define MAX_PATH_IDS 18 +`define MAX_PATH_LENGTH 8 + +// The path is hardwired and so should never be stored in a register. Therefore int type rather than Bit type + +typedef Bit#(32) MemAddr; +typedef Int#(TLog#(`MAX_PATH_IDS)) PathId; +typedef Int#(24) Sample; +typedef Int#(TLog#(`MAX_VOICES)) VoiceId; + + +//The mixer is identified as PathId 0, path end is max +PathId mixerId = 0; +PathId endId = `MAX_CORES+1; + +// Path is array of path ids +typedef Vector#(`MAX_PATH_LENGTH, PathId) CorePath; +CorePath emptyCore = replicate(endId); + +typedef struct +{ + VoiceId voice; + MemAddr startAddr; + CorePath route; +} FullPath deriving (Bits, Eq); + diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/core/ProcTypes.bsv --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/core/ProcTypes.bsv Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,375 @@ + +import Trace::*; + +//---------------------------------------------------------------------- +// Other typedefs +//---------------------------------------------------------------------- + +typedef Bit#(32) Addr; +typedef Int#(18) Stat; + +//---------------------------------------------------------------------- +// Basic instruction type +//---------------------------------------------------------------------- + +typedef Bit#(5) Rindx; +typedef Bit#(16) Simm; +typedef Bit#(16) Zimm; +typedef Bit#(8) Epoch; +typedef Bit#(5) Shamt; +typedef Bit#(26) Target; +typedef Bit#(5) CP0indx; +typedef Bit#(32) Data; + +typedef enum +{ + Taken, + NotTaken +} + Direction + deriving(Bits,Eq); + + +//---------------------------------------------------------------------- +// Pipeline typedefs +//---------------------------------------------------------------------- + +typedef union tagged +{ + Tuple2#(Rindx,Data) ALUWB; + Rindx MemWB; + Tuple2#(Rindx,Data) CoWB; +} + WritebackType + deriving(Bits,Eq); + +//////////////////////// +// I Add Writeback queue type +//////////// +typedef union tagged +{ + struct {Bit#(32) data; Rindx dest; } WB_ALU; + Bit#(32) WB_Host; + Rindx WB_Load; + void WB_Store; +} +WBResult deriving(Eq, Bits); + +typedef struct{Addr qpc; Addr qnxtpc; Epoch qepoch;} PCStat deriving(Eq, Bits); +//typedef struct{Addr qpc; Epoch qepoch;} PCStat deriving(Eq, Bits); + +typedef union tagged +{ + + struct { Rindx rbase; Rindx rdst; Simm offset; } LW; + struct { Rindx rbase; Rindx rsrc; Simm offset; } SW; + + struct { Rindx rsrc; Rindx rdst; Simm imm; } ADDIU; + struct { Rindx rsrc; Rindx rdst; Simm imm; } SLTI; + struct { Rindx rsrc; Rindx rdst; Simm imm; } SLTIU; + struct { Rindx rsrc; Rindx rdst; Zimm imm; } ANDI; + struct { Rindx rsrc; Rindx rdst; Zimm imm; } ORI; + struct { Rindx rsrc; Rindx rdst; Zimm imm; } XORI; + struct { Rindx rdst; Zimm imm; } LUI; + + struct { Rindx rsrc; Rindx rdst; Shamt shamt; } SLL; + struct { Rindx rsrc; Rindx rdst; Shamt shamt; } SRL; + struct { Rindx rsrc; Rindx rdst; Shamt shamt; } SRA; + struct { Rindx rsrc; Rindx rdst; Rindx rshamt; } SLLV; + struct { Rindx rsrc; Rindx rdst; Rindx rshamt; } SRLV; + struct { Rindx rsrc; Rindx rdst; Rindx rshamt; } SRAV; + struct { Rindx rsrc1; Rindx rsrc2; Rindx rdst; } ADDU; + struct { Rindx rsrc1; Rindx rsrc2; Rindx rdst; } SUBU; + struct { Rindx rsrc1; Rindx rsrc2; Rindx rdst; } AND; + struct { Rindx rsrc1; Rindx rsrc2; Rindx rdst; } OR; + struct { Rindx rsrc1; Rindx rsrc2; Rindx rdst; } XOR; + struct { Rindx rsrc1; Rindx rsrc2; Rindx rdst; } NOR; + struct { Rindx rsrc1; Rindx rsrc2; Rindx rdst; } SLT; + struct { Rindx rsrc1; Rindx rsrc2; Rindx rdst; } SLTU; + + struct { Target target; } J; + struct { Target target; } JAL; + struct { Rindx rsrc; } JR; + struct { Rindx rsrc; Rindx rdst; } JALR; + struct { Rindx rsrc1; Rindx rsrc2; Simm offset; } BEQ; + struct { Rindx rsrc1; Rindx rsrc2; Simm offset; } BNE; + struct { Rindx rsrc; Simm offset; } BLEZ; + struct { Rindx rsrc; Simm offset; } BGTZ; + struct { Rindx rsrc; Simm offset; } BLTZ; + struct { Rindx rsrc; Simm offset; } BGEZ; + + struct { Rindx rdst; CP0indx cop0src; } MFC0; + struct { Rindx rsrc; CP0indx cop0dst; } MTC0; + + void ILLEGAL; + +} +Instr deriving(Eq); + +//---------------------------------------------------------------------- +// Pack and Unpack +//---------------------------------------------------------------------- + +Bit#(6) opFUNC = 6'b000000; Bit#(6) fcSLL = 6'b000000; +Bit#(6) opRT = 6'b000001; Bit#(6) fcSRL = 6'b000010; +Bit#(6) opRS = 6'b010000; Bit#(6) fcSRA = 6'b000011; + Bit#(6) fcSLLV = 6'b000100; +Bit#(6) opLW = 6'b100011; Bit#(6) fcSRLV = 6'b000110; +Bit#(6) opSW = 6'b101011; Bit#(6) fcSRAV = 6'b000111; + Bit#(6) fcADDU = 6'b100001; +Bit#(6) opADDIU = 6'b001001; Bit#(6) fcSUBU = 6'b100011; +Bit#(6) opSLTI = 6'b001010; Bit#(6) fcAND = 6'b100100; +Bit#(6) opSLTIU = 6'b001011; Bit#(6) fcOR = 6'b100101; +Bit#(6) opANDI = 6'b001100; Bit#(6) fcXOR = 6'b100110; +Bit#(6) opORI = 6'b001101; Bit#(6) fcNOR = 6'b100111; +Bit#(6) opXORI = 6'b001110; Bit#(6) fcSLT = 6'b101010; +Bit#(6) opLUI = 6'b001111; Bit#(6) fcSLTU = 6'b101011; + +Bit#(6) opJ = 6'b000010; +Bit#(6) opJAL = 6'b000011; +Bit#(6) fcJR = 6'b001000; +Bit#(6) fcJALR = 6'b001001; +Bit#(6) opBEQ = 6'b000100; +Bit#(6) opBNE = 6'b000101; +Bit#(6) opBLEZ = 6'b000110; +Bit#(6) opBGTZ = 6'b000111; +Bit#(5) rtBLTZ = 5'b00000; +Bit#(5) rtBGEZ = 5'b00001; + +Bit#(5) rsMFC0 = 5'b00000; +Bit#(5) rsMTC0 = 5'b00100; + +instance Bits#(Instr,32); + + // Pack Function + + function Bit#(32) pack( Instr instr ); + + case ( instr ) matches + + tagged LW .it : return { opLW, it.rbase, it.rdst, it.offset }; + tagged SW .it : return { opSW, it.rbase, it.rsrc, it.offset }; + + tagged ADDIU .it : return { opADDIU, it.rsrc, it.rdst, it.imm }; + tagged SLTI .it : return { opSLTI, it.rsrc, it.rdst, it.imm }; + tagged SLTIU .it : return { opSLTIU, it.rsrc, it.rdst, it.imm }; + tagged ANDI .it : return { opANDI, it.rsrc, it.rdst, it.imm }; + tagged ORI .it : return { opORI, it.rsrc, it.rdst, it.imm }; + tagged XORI .it : return { opXORI, it.rsrc, it.rdst, it.imm }; + tagged LUI .it : return { opLUI, 5'b0, it.rdst, it.imm }; + + tagged SLL .it : return { opFUNC, 5'b0, it.rsrc, it.rdst, it.shamt, fcSLL }; + tagged SRL .it : return { opFUNC, 5'b0, it.rsrc, it.rdst, it.shamt, fcSRL }; + tagged SRA .it : return { opFUNC, 5'b0, it.rsrc, it.rdst, it.shamt, fcSRA }; + + tagged SLLV .it : return { opFUNC, it.rshamt, it.rsrc, it.rdst, 5'b0, fcSLLV }; + tagged SRLV .it : return { opFUNC, it.rshamt, it.rsrc, it.rdst, 5'b0, fcSRLV }; + tagged SRAV .it : return { opFUNC, it.rshamt, it.rsrc, it.rdst, 5'b0, fcSRAV }; + + tagged ADDU .it : return { opFUNC, it.rsrc1, it.rsrc2, it.rdst, 5'b0, fcADDU }; + tagged SUBU .it : return { opFUNC, it.rsrc1, it.rsrc2, it.rdst, 5'b0, fcSUBU }; + tagged AND .it : return { opFUNC, it.rsrc1, it.rsrc2, it.rdst, 5'b0, fcAND }; + tagged OR .it : return { opFUNC, it.rsrc1, it.rsrc2, it.rdst, 5'b0, fcOR }; + tagged XOR .it : return { opFUNC, it.rsrc1, it.rsrc2, it.rdst, 5'b0, fcXOR }; + tagged NOR .it : return { opFUNC, it.rsrc1, it.rsrc2, it.rdst, 5'b0, fcNOR }; + tagged SLT .it : return { opFUNC, it.rsrc1, it.rsrc2, it.rdst, 5'b0, fcSLT }; + tagged SLTU .it : return { opFUNC, it.rsrc1, it.rsrc2, it.rdst, 5'b0, fcSLTU }; + + tagged J .it : return { opJ, it.target }; + tagged JAL .it : return { opJAL, it.target }; + tagged JR .it : return { opFUNC, it.rsrc, 5'b0, 5'b0, 5'b0, fcJR }; + tagged JALR .it : return { opFUNC, it.rsrc, 5'b0, it.rdst, 5'b0, fcJALR }; + tagged BEQ .it : return { opBEQ, it.rsrc1, it.rsrc2, it.offset }; + tagged BNE .it : return { opBNE, it.rsrc1, it.rsrc2, it.offset }; + tagged BLEZ .it : return { opBLEZ, it.rsrc, 5'b0, it.offset }; + tagged BGTZ .it : return { opBGTZ, it.rsrc, 5'b0, it.offset }; + tagged BLTZ .it : return { opRT, it.rsrc, rtBLTZ, it.offset }; + tagged BGEZ .it : return { opRT, it.rsrc, rtBGEZ, it.offset }; + + tagged MFC0 .it : return { opRS, rsMFC0, it.rdst, it.cop0src, 11'b0 }; + tagged MTC0 .it : return { opRS, rsMTC0, it.rsrc, it.cop0dst, 11'b0 }; + + endcase + + endfunction + + // Unpack Function + + function Instr unpack( Bit#(32) instrBits ); + + let opcode = instrBits[ 31 : 26 ]; + let rs = instrBits[ 25 : 21 ]; + let rt = instrBits[ 20 : 16 ]; + let rd = instrBits[ 15 : 11 ]; + let shamt = instrBits[ 10 : 6 ]; + let funct = instrBits[ 5 : 0 ]; + let imm = instrBits[ 15 : 0 ]; + let target = instrBits[ 25 : 0 ]; + + case ( opcode ) + + opLW : return LW { rbase:rs, rdst:rt, offset:imm }; + opSW : return SW { rbase:rs, rsrc:rt, offset:imm }; + opADDIU : return ADDIU { rsrc:rs, rdst:rt, imm:imm }; + opSLTI : return SLTI { rsrc:rs, rdst:rt, imm:imm }; + opSLTIU : return SLTIU { rsrc:rs, rdst:rt, imm:imm }; + opANDI : return ANDI { rsrc:rs, rdst:rt, imm:imm }; + opORI : return ORI { rsrc:rs, rdst:rt, imm:imm }; + opXORI : return XORI { rsrc:rs, rdst:rt, imm:imm }; + opLUI : return LUI { rdst:rt, imm:imm }; + opJ : return J { target:target }; + opJAL : return JAL { target:target }; + opBEQ : return BEQ { rsrc1:rs, rsrc2:rt, offset:imm }; + opBNE : return BNE { rsrc1:rs, rsrc2:rt, offset:imm }; + opBLEZ : return BLEZ { rsrc:rs, offset:imm }; + opBGTZ : return BGTZ { rsrc:rs, offset:imm }; + + opFUNC : + case ( funct ) + fcSLL : return SLL { rsrc:rt, rdst:rd, shamt:shamt }; + fcSRL : return SRL { rsrc:rt, rdst:rd, shamt:shamt }; + fcSRA : return SRA { rsrc:rt, rdst:rd, shamt:shamt }; + fcSLLV : return SLLV { rsrc:rt, rdst:rd, rshamt:rs }; + fcSRLV : return SRLV { rsrc:rt, rdst:rd, rshamt:rs }; + fcSRAV : return SRAV { rsrc:rt, rdst:rd, rshamt:rs }; + fcADDU : return ADDU { rsrc1:rs, rsrc2:rt, rdst:rd }; + fcSUBU : return SUBU { rsrc1:rs, rsrc2:rt, rdst:rd }; + fcAND : return AND { rsrc1:rs, rsrc2:rt, rdst:rd }; + fcOR : return OR { rsrc1:rs, rsrc2:rt, rdst:rd }; + fcXOR : return XOR { rsrc1:rs, rsrc2:rt, rdst:rd }; + fcNOR : return NOR { rsrc1:rs, rsrc2:rt, rdst:rd }; + fcSLT : return SLT { rsrc1:rs, rsrc2:rt, rdst:rd }; + fcSLTU : return SLTU { rsrc1:rs, rsrc2:rt, rdst:rd }; + fcJR : return JR { rsrc:rs }; + fcJALR : return JALR { rsrc:rs, rdst:rd }; + default : return ILLEGAL; + endcase + + opRT : + case ( rt ) + rtBLTZ : return BLTZ { rsrc:rs, offset:imm }; + rtBGEZ : return BGEZ { rsrc:rs, offset:imm }; + default : return ILLEGAL; + endcase + + opRS : + case ( rs ) + rsMFC0 : return MFC0 { rdst:rt, cop0src:rd }; + rsMTC0 : return MTC0 { rsrc:rt, cop0dst:rd }; + default : return ILLEGAL; + endcase + + default : return ILLEGAL; + + endcase + + endfunction + +endinstance + +//---------------------------------------------------------------------- +// Trace +//---------------------------------------------------------------------- + +instance Traceable#(Instr); + + function Action traceTiny( String loc, String ttag, Instr inst ); + case ( inst ) matches + + tagged LW .it : $fdisplay(stderr, " => %s:%s lw", loc, ttag ); + tagged SW .it : $fdisplay(stderr, " => %s:%s sw", loc, ttag ); + + tagged ADDIU .it : $fdisplay(stderr, " => %s:%s addi", loc, ttag ); + tagged SLTI .it : $fdisplay(stderr, " => %s:%s sli", loc, ttag ); + tagged SLTIU .it : $fdisplay(stderr, " => %s:%s sliu", loc, ttag ); + tagged ANDI .it : $fdisplay(stderr, " => %s:%s andi", loc, ttag ); + tagged ORI .it : $fdisplay(stderr, " => %s:%s ori", loc, ttag ); + tagged XORI .it : $fdisplay(stderr, " => %s:%s xori", loc, ttag ); + tagged LUI .it : $fdisplay(stderr, " => %s:%s lui", loc, ttag ); + + tagged SLL .it : $fdisplay(stderr, " => %s:%s sll", loc, ttag ); + tagged SRL .it : $fdisplay(stderr, " => %s:%s srl", loc, ttag ); + tagged SRA .it : $fdisplay(stderr, " => %s:%s sra", loc, ttag ); + tagged SLLV .it : $fdisplay(stderr, " => %s:%s sllv", loc, ttag ); + tagged SRLV .it : $fdisplay(stderr, " => %s:%s srlv", loc, ttag ); + tagged SRAV .it : $fdisplay(stderr, " => %s:%s srav", loc, ttag ); + + tagged ADDU .it : $fdisplay(stderr, " => %s:%s addu", loc, ttag ); + tagged SUBU .it : $fdisplay(stderr, " => %s:%s subu", loc, ttag ); + tagged AND .it : $fdisplay(stderr, " => %s:%s and", loc, ttag ); + tagged OR .it : $fdisplay(stderr, " => %s:%s or", loc, ttag ); + tagged XOR .it : $fdisplay(stderr, " => %s:%s xor", loc, ttag ); + tagged NOR .it : $fdisplay(stderr, " => %s:%s nor", loc, ttag ); + tagged SLT .it : $fdisplay(stderr, " => %s:%s slt", loc, ttag ); + tagged SLTU .it : $fdisplay(stderr, " => %s:%s sltu", loc, ttag ); + + tagged J .it : $fdisplay(stderr, " => %s:%s j", loc, ttag ); + tagged JAL .it : $fdisplay(stderr, " => %s:%s jal", loc, ttag ); + tagged JR .it : $fdisplay(stderr, " => %s:%s jr", loc, ttag ); + tagged JALR .it : $fdisplay(stderr, " => %s:%s jalr", loc, ttag ); + tagged BEQ .it : $fdisplay(stderr, " => %s:%s beq", loc, ttag ); + tagged BNE .it : $fdisplay(stderr, " => %s:%s bne", loc, ttag ); + tagged BLEZ .it : $fdisplay(stderr, " => %s:%s blez", loc, ttag ); + tagged BGTZ .it : $fdisplay(stderr, " => %s:%s bgtz", loc, ttag ); + tagged BLTZ .it : $fdisplay(stderr, " => %s:%s bltz", loc, ttag ); + tagged BGEZ .it : $fdisplay(stderr, " => %s:%s bgez", loc, ttag ); + + tagged MFC0 .it : $fdisplay(stderr, " => %s:%s mfc0", loc, ttag ); + tagged MTC0 .it : $fdisplay(stderr, " => %s:%s mtc0", loc, ttag ); + + tagged ILLEGAL : $fdisplay(stderr, " => %s:%s ill", loc, ttag ); + + endcase + endfunction + + function Action traceFull( String loc, String ttag, Instr inst ); + case ( inst ) matches + + tagged LW .it : $fdisplay(stderr, " => %s:%s lw r%0d, 0x%x(r%0d)", loc, ttag, it.rdst, it.offset, it.rbase ); + tagged SW .it : $fdisplay(stderr, " => %s:%s sw r%0d, 0x%x(r%0d)", loc, ttag, it.rsrc, it.offset, it.rbase ); + + tagged ADDIU .it : $fdisplay(stderr, " => %s:%s addiu r%0d, r%0d, 0x%x", loc, ttag, it.rdst, it.rsrc, it.imm ); + tagged SLTI .it : $fdisplay(stderr, " => %s:%s slti r%0d, r%0d, 0x%x", loc, ttag, it.rdst, it.rsrc, it.imm ); + tagged SLTIU .it : $fdisplay(stderr, " => %s:%s sltiu r%0d, r%0d, 0x%x", loc, ttag, it.rdst, it.rsrc, it.imm ); + tagged ANDI .it : $fdisplay(stderr, " => %s:%s andi r%0d, r%0d, 0x%x", loc, ttag, it.rdst, it.rsrc, it.imm ); + tagged ORI .it : $fdisplay(stderr, " => %s:%s ori r%0d, r%0d, 0x%x", loc, ttag, it.rdst, it.rsrc, it.imm ); + tagged XORI .it : $fdisplay(stderr, " => %s:%s xori r%0d, r%0d, 0x%x", loc, ttag, it.rdst, it.rsrc, it.imm ); + tagged LUI .it : $fdisplay(stderr, " => %s:%s lui r%0d, 0x%x", loc, ttag, it.rdst, it.imm ); + + tagged SLL .it : $fdisplay(stderr, " => %s:%s sll r%0d, r%0d, %0d", loc, ttag, it.rdst, it.rsrc, it.shamt ); + tagged SRL .it : $fdisplay(stderr, " => %s:%s srl r%0d, r%0d, %0d", loc, ttag, it.rdst, it.rsrc, it.shamt ); + tagged SRA .it : $fdisplay(stderr, " => %s:%s sra r%0d, r%0d, %0d", loc, ttag, it.rdst, it.rsrc, it.shamt ); + tagged SLLV .it : $fdisplay(stderr, " => %s:%s sllv r%0d, r%0d, r%0d", loc, ttag, it.rdst, it.rsrc, it.rshamt ); + tagged SRLV .it : $fdisplay(stderr, " => %s:%s srlv r%0d, r%0d, r%0d", loc, ttag, it.rdst, it.rsrc, it.rshamt ); + tagged SRAV .it : $fdisplay(stderr, " => %s:%s srav r%0d, r%0d, r%0d", loc, ttag, it.rdst, it.rsrc, it.rshamt ); + + tagged ADDU .it : $fdisplay(stderr, " => %s:%s addu r%0d, r%0d, r%0d", loc, ttag, it.rdst, it.rsrc1, it.rsrc2 ); + tagged SUBU .it : $fdisplay(stderr, " => %s:%s subu r%0d, r%0d, r%0d", loc, ttag, it.rdst, it.rsrc1, it.rsrc2 ); + tagged AND .it : $fdisplay(stderr, " => %s:%s and r%0d, r%0d, r%0d", loc, ttag, it.rdst, it.rsrc1, it.rsrc2 ); + tagged OR .it : $fdisplay(stderr, " => %s:%s or r%0d, r%0d, r%0d", loc, ttag, it.rdst, it.rsrc1, it.rsrc2 ); + tagged XOR .it : $fdisplay(stderr, " => %s:%s xor r%0d, r%0d, r%0d", loc, ttag, it.rdst, it.rsrc1, it.rsrc2 ); + tagged NOR .it : $fdisplay(stderr, " => %s:%s nor r%0d, r%0d, r%0d", loc, ttag, it.rdst, it.rsrc1, it.rsrc2 ); + tagged SLT .it : $fdisplay(stderr, " => %s:%s slt r%0d, r%0d, r%0d", loc, ttag, it.rdst, it.rsrc1, it.rsrc2 ); + tagged SLTU .it : $fdisplay(stderr, " => %s:%s sltu r%0d, r%0d, r%0d", loc, ttag, it.rdst, it.rsrc1, it.rsrc2 ); + + tagged J .it : $fdisplay(stderr, " => %s:%s j 0x%x", loc, ttag, it.target ); + tagged JAL .it : $fdisplay(stderr, " => %s:%s jal 0x%x", loc, ttag, it.target ); + tagged JR .it : $fdisplay(stderr, " => %s:%s jr r%0d", loc, ttag, it.rsrc ); + tagged JALR .it : $fdisplay(stderr, " => %s:%s jalr r%0d", loc, ttag, it.rsrc ); + tagged BEQ .it : $fdisplay(stderr, " => %s:%s beq r%0d, r%0d, 0x%x", loc, ttag, it.rsrc1, it.rsrc2, it.offset ); + tagged BNE .it : $fdisplay(stderr, " => %s:%s bne r%0d, r%0d, 0x%x", loc, ttag, it.rsrc1, it.rsrc2, it.offset ); + tagged BLEZ .it : $fdisplay(stderr, " => %s:%s blez r%0d, 0x%x", loc, ttag, it.rsrc, it.offset ); + tagged BGTZ .it : $fdisplay(stderr, " => %s:%s bgtz r%0d, 0x%x", loc, ttag, it.rsrc, it.offset ); + tagged BLTZ .it : $fdisplay(stderr, " => %s:%s bltz r%0d, 0x%x", loc, ttag, it.rsrc, it.offset ); + tagged BGEZ .it : $fdisplay(stderr, " => %s:%s bgez r%0d, 0x%x", loc, ttag, it.rsrc, it.offset ); + + tagged MFC0 .it : $fdisplay(stderr, " => %s:%s mfc0 r%0d, cpr%0d", loc, ttag, it.rdst, it.cop0src ); + tagged MTC0 .it : $fdisplay(stderr, " => %s:%s mtc0 r%0d, cpr%0d", loc, ttag, it.rsrc, it.cop0dst ); + + tagged ILLEGAL : $fdisplay(stderr, " => %s:%s illegal instruction", loc, ttag ); + + endcase + endfunction + +endinstance + diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/core/Processor.bsv --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/core/Processor.bsv Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,590 @@ +/// The MIT License + +// Copyright (c) 2009 Massachusetts Institute of Technology + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import Connectable::*; +import GetPut::*; +import ClientServer::*; +import RegFile::*; + +import FIFO::*; +import FIFOF::*; +import SFIFO::*; +import RWire::*; + +import BFIFO::*; +import MemTypes::*; +import ProcTypes::*; +import BRegFile::*; +import BranchPred::*; +//import PathTypes::*; This is only there to force the debugging + +import Trace::*; + +//AWB includes +`include "asim/provides/low_level_platform_interface.bsh" +`include "asim/provides/soft_connections.bsh" +`include "asim/provides/common_services.bsh" + +// Local includes +`include "asim/provides/processor_library.bsh" +`include "asim/rrr/remote_server_stub_PROCESSORSYSTEMRRR.bsh" +`include "asim/provides/common_services.bsh" +`include "asim/dict/STATS_PROCESSOR.bsh" + +interface ProcStats; + interface Get#(Stat) num_cycles; + interface Get#(Stat) num_inst; +endinterface + +interface CPUToHost; + method Bit#(32) cpuToHost(int req); +endinterface + +interface Proc; + + // Interface from processor to caches + interface Client#(DataReq,DataResp) dmem_client; + interface Client#(InstReq,InstResp) imem_client; + + // Interface for enabling/disabling statistics on the rest of the core + interface Get#(Bool) statsEn_get; + + // Interface for collecting statistics. + interface ProcStats stats; + + // Interface to host + interface CPUToHost tohost; + +endinterface + + +typedef enum { PCgen, Exec, Writeback } Stage deriving(Eq,Bits); + +//----------------------------------------------------------- +// Register file module +//----------------------------------------------------------- + +interface BRFile; + method Action wr( Rindx rindx, Bit#(32) data ); + method Bit#(32) rd1( Rindx rindx ); + method Bit#(32) rd2( Rindx rindx ); +endinterface + +module mkBRFile( BRFile ); + + RegFile#(Rindx,Bit#(32)) rfile <- mkBRegFile(); + + method Action wr( Rindx rindx, Bit#(32) data ); + rfile.upd( rindx, data ); + endmethod + + method Bit#(32) rd1( Rindx rindx ); + return ( rindx == 0 ) ? 0 : rfile.sub(rindx); + endmethod + + method Bit#(32) rd2( Rindx rindx ); + return ( rindx == 0 ) ? 0 : rfile.sub(rindx); + endmethod + +endmodule + +//----------------------------------------------------------- +// Helper functions +//----------------------------------------------------------- + +function Bit#(32) slt( Bit#(32) val1, Bit#(32) val2 ); + return zeroExtend( pack( signedLT(val1,val2) ) ); +endfunction + +function Bit#(32) sltu( Bit#(32) val1, Bit#(32) val2 ); + return zeroExtend( pack( val1 < val2 ) ); +endfunction + +function Bit#(32) rshft( Bit#(32) val ); + return zeroExtend(val[4:0]); +endfunction + + +//----------------------------------------------------------- +// Find funct for wbQ +//----------------------------------------------------------- +function Bool findwbf(Rindx fVal, WBResult cmpVal); + case (cmpVal) matches + tagged WB_ALU {data:.res, dest:.rd} : + return (fVal == rd); + tagged WB_Load .rd : + return (fVal == rd); + tagged WB_Store .st : + return False; + tagged WB_Host .x : + return False; + endcase +endfunction + + +//----------------------------------------------------------- +// Stall funct for wbQ +//----------------------------------------------------------- +function Bool stall(Instr inst, SFIFO#(WBResult, Rindx) f); + case (inst) matches + // -- Memory Ops ------------------------------------------------ + tagged LW .it : + return f.find(it.rbase); + tagged SW {rsrc:.dreg, rbase:.addr, offset:.o} : + return (f.find(addr) || f.find2(dreg)); + + // -- Simple Ops ------------------------------------------------ + tagged ADDIU .it : return f.find(it.rsrc); + tagged SLTI .it : return f.find(it.rsrc); + tagged SLTIU .it : return f.find(it.rsrc); + tagged ANDI .it : return f.find(it.rsrc); + tagged ORI .it : return f.find(it.rsrc); + tagged XORI .it : return f.find(it.rsrc); + + tagged LUI .it : return f.find(it.rdst); //this rds/wrs itself + tagged SLL .it : return f.find(it.rsrc); + tagged SRL .it : return f.find(it.rsrc); + tagged SRA .it : return f.find(it.rsrc); + tagged SLLV .it : return (f.find(it.rsrc) || f.find(it.rshamt)); + tagged SRLV .it : return (f.find(it.rsrc) || f.find(it.rshamt)); + tagged SRAV .it : return (f.find(it.rsrc) || f.find(it.rshamt)); + tagged ADDU .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2)); + tagged SUBU .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2)); + tagged AND .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2)); + tagged OR .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2)); + tagged XOR .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2)); + tagged NOR .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2)); + tagged SLT .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2)); + tagged SLTU .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2)); + + + // -- Branches -------------------------------------------------- + + tagged BLEZ .it : return (f.find(it.rsrc)); + tagged BGTZ .it : return (f.find(it.rsrc)); + tagged BLTZ .it : return (f.find(it.rsrc)); + tagged BGEZ .it : return (f.find(it.rsrc)); + tagged BEQ .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2)); + tagged BNE .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2)); + + // -- Jumps ----------------------------------------------------- + + tagged J .it : return False; + tagged JR .it : return f.find(it.rsrc); + tagged JALR .it : return f.find(it.rsrc); + tagged JAL .it : return False; + + // -- Cop0 ------------------------------------------------------ + + tagged MTC0 .it : return f.find(it.rsrc); + tagged MFC0 .it : return False; + + // -- Illegal --------------------------------------------------- + + default : return False; + + endcase +endfunction +//----------------------------------------------------------- +// Reference processor +//----------------------------------------------------------- + + +//(* doc = "synthesis attribute ram_style mkProc distributed;" *) +//(* synthesize *) + +module [CONNECTED_MODULE] mkProc( Proc ); + + //----------------------------------------------------------- + // Debug port + + ServerStub_PROCESSORSYSTEMRRR server_stub <- mkServerStub_PROCESSORSYSTEMRRR(); + + + //----------------------------------------------------------- + // State + + // Standard processor state + + Reg#(Addr) pc <- mkReg(32'h00001000); + Reg#(Epoch) epoch <- mkReg(0); + Reg#(Stage) stage <- mkReg(PCgen); + BRFile rf <- mkBRFile; + + // Branch Prediction + BranchPred bp <- mkBranchPred(); + FIFO#(PCStat) execpc <- mkLFIFO(); + + // Pipelines + FIFO#(PCStat) pcQ <-mkSizedFIFO(3); + SFIFO#(WBResult, Rindx) wbQ <-mkSFIFO(findwbf); + + Reg#(Bit#(32)) cp0_tohost <- mkReg(0); + Reg#(Bit#(32)) cp0_fromhost <- mkReg(0); + Reg#(Bool) cp0_statsEn <- mkReg(False); + + // Memory request/response state + + FIFO#(InstReq) instReqQ <- mkBFIFO1(); + FIFO#(InstResp) instRespQ <- mkFIFO(); + + FIFO#(DataReq) dataReqQ <- mkBFIFO1(); + FIFO#(DataResp) dataRespQ <- mkFIFO(); + + // Statistics state + Reg#(Stat) num_cycles <- mkReg(0); + Reg#(Stat) num_inst <- mkReg(0); + + //Or: + // Statistics state + //STAT num_cycles <- mkStatCounter(`STATS_PROCESSOR_CYCLE_COUNT); + //STAT num_inst <- mkStatCounter(`STATS_PROCESSOR_INST_COUNT); + + //----------------------------------------------------------- + // Rules + + (* descending_urgency = "exec, pcgen" *) + rule pcgen; //( stage == PCgen ); + let pc_plus4 = pc + 4; + + traceTiny("mkProc", "pc",pc); + traceTiny("mkProc", "pcgen","P"); + instReqQ.enq( LoadReq{ addr:pc, tag:epoch} ); + + let next_pc = bp.get(pc); + if (next_pc matches tagged Valid .npc) + begin + pcQ.enq(PCStat {qpc:pc, qnxtpc:npc, qepoch:epoch}); + pc <= npc; + end + else + begin + pcQ.enq(PCStat {qpc:pc, qnxtpc:pc_plus4, qepoch:epoch}); + pc <= pc_plus4; + end + + endrule + + rule discard (instRespQ.first() matches tagged LoadResp .ld + &&& ld.tag != epoch); + traceTiny("mkProc", "stage", "D"); + instRespQ.deq(); + endrule + + (* conflict_free = "exec, writeback" *) + rule exec (instRespQ.first() matches tagged LoadResp.ld + &&& (ld.tag == epoch) + &&& unpack(ld.data) matches .inst + &&& !stall(inst, wbQ)); + + // Some abbreviations + let sext = signExtend; + let zext = zeroExtend; + let sra = signedShiftRight; + + // Get the instruction + + instRespQ.deq(); + Instr inst + = case ( instRespQ.first() ) matches + tagged LoadResp .ld : return unpack(ld.data); + tagged StoreResp .st : return ?; + endcase; + + // Get the PC info + let instrpc = pcQ.first().qpc; + let pc_plus4 = instrpc + 4; + + Bool branchTaken = False; + Addr newPC = pc_plus4; + + // Tracing + traceTiny("mkProc", "exec","X"); + traceTiny("mkProc", "exInstTiny",inst); + traceFull("mkProc", "exInstFull",inst); + + case ( inst ) matches + + // -- Memory Ops ------------------------------------------------ + + tagged LW .it : + begin + Addr addr = rf.rd1(it.rbase) + sext(it.offset); + dataReqQ.enq( LoadReq{ addr:addr, tag:zeroExtend(it.rdst) } ); + wbQ.enq(tagged WB_Load it.rdst); + end + + tagged SW .it : + begin + Addr addr = rf.rd1(it.rbase) + sext(it.offset); + dataReqQ.enq( StoreReq{ tag:0, addr:addr, data:rf.rd2(it.rsrc) } ); + wbQ.enq(tagged WB_Store); + end + + // -- Simple Ops ------------------------------------------------ + + tagged ADDIU .it : + begin + Bit#(32) result = rf.rd1(it.rsrc) + sext(it.imm); + wbQ.enq(tagged WB_ALU {data:result, dest:it.rdst}); + end + tagged SLTI .it : wbQ.enq(tagged WB_ALU {dest:it.rdst, data:slt( rf.rd1(it.rsrc), sext(it.imm) )}); + tagged SLTIU .it : wbQ.enq(tagged WB_ALU {dest:it.rdst, data:sltu( rf.rd1(it.rsrc), sext(it.imm) ) }); + tagged ANDI .it : + begin + Bit#(32) zext_it_imm = zext(it.imm); + wbQ.enq(tagged WB_ALU {dest:it.rdst, data:(rf.rd1(it.rsrc) & zext_it_imm)} ); + end + tagged ORI .it : + begin + Bit#(32) zext_it_imm = zext(it.imm); + wbQ.enq(tagged WB_ALU {dest:it.rdst, data:(rf.rd1(it.rsrc) | zext_it_imm)} ); + end + tagged XORI .it : + begin + Bit#(32) zext_it_imm = zext(it.imm); + wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc) ^ zext_it_imm )}); + end + tagged LUI .it : + begin + Bit#(32) zext_it_imm = zext(it.imm); + wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(zext_it_imm << 32'd16) }); + end + + tagged SLL .it : + begin + Bit#(32) zext_it_shamt = zext(it.shamt); + wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc) << zext_it_shamt )} ); + end + tagged SRL .it : + begin + Bit#(32) zext_it_shamt = zext(it.shamt); + wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc) >> zext_it_shamt )}); + end + tagged SRA .it : + begin + Bit#(32) zext_it_shamt = zext(it.shamt); + wbQ.enq(tagged WB_ALU {dest: it.rdst, data:sra( rf.rd1(it.rsrc), zext_it_shamt )}); + end + tagged SLLV .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc) << rshft(rf.rd2(it.rshamt)) )}); + tagged SRLV .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc) >> rshft(rf.rd2(it.rshamt)) )} ); + tagged SRAV .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:sra( rf.rd1(it.rsrc), rshft(rf.rd2(it.rshamt)) ) }); + tagged ADDU .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc1) + rf.rd2(it.rsrc2) )} ); + tagged SUBU .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc1) - rf.rd2(it.rsrc2) )} ); + tagged AND .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc1) & rf.rd2(it.rsrc2) )} ); + tagged OR .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc1) | rf.rd2(it.rsrc2) )} ); + tagged XOR .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc1) ^ rf.rd2(it.rsrc2) )} ); + tagged NOR .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(~(rf.rd1(it.rsrc1) | rf.rd2(it.rsrc2)) )} ); + tagged SLT .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:slt( rf.rd1(it.rsrc1), rf.rd2(it.rsrc2) ) }); + tagged SLTU .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:sltu( rf.rd1(it.rsrc1), rf.rd2(it.rsrc2) ) }); + + // -- Branches -------------------------------------------------- + + tagged BLEZ .it : + if ( signedLE( rf.rd1(it.rsrc), 0 ) ) + begin + newPC = pc_plus4 + (sext(it.offset) << 2); + branchTaken = True; + end + + tagged BGTZ .it : + if ( signedGT( rf.rd1(it.rsrc), 0 ) ) + begin + newPC = pc_plus4 + (sext(it.offset) << 2); + branchTaken = True; + end + + tagged BLTZ .it : + if ( signedLT( rf.rd1(it.rsrc), 0 ) ) + begin + newPC = pc_plus4 + (sext(it.offset) << 2); + branchTaken = True; + end + + tagged BGEZ .it : + if ( signedGE( rf.rd1(it.rsrc), 0 ) ) + begin + newPC = pc_plus4 + (sext(it.offset) << 2); + branchTaken = True; + end + + tagged BEQ .it : + if ( rf.rd1(it.rsrc1) == rf.rd2(it.rsrc2) ) + begin + newPC = pc_plus4 + (sext(it.offset) << 2); + branchTaken = True; + end + + tagged BNE .it : + if ( rf.rd1(it.rsrc1) != rf.rd2(it.rsrc2) ) + begin + newPC = pc_plus4 + (sext(it.offset) << 2); + branchTaken = True; + end + + // -- Jumps ----------------------------------------------------- + + tagged J .it : + begin + newPC = { pc_plus4[31:28], it.target, 2'b0 }; + branchTaken = True; + end + + tagged JR .it : + begin + newPC = rf.rd1(it.rsrc); + branchTaken = True; + end + + tagged JAL .it : + begin + wbQ.enq(tagged WB_ALU {dest:31, data:pc_plus4 }); + newPC = { pc_plus4[31:28], it.target, 2'b0 }; + branchTaken = True; + end + + tagged JALR .it : + begin + wbQ.enq(tagged WB_ALU {dest:it.rdst, data:pc_plus4 }); + newPC = rf.rd1(it.rsrc); + branchTaken = True; + end + + // -- Cop0 ------------------------------------------------------ + + tagged MTC0 .it : + begin + case ( it.cop0dst ) + 5'd10 : cp0_statsEn <= unpack(truncate(rf.rd1(it.rsrc))); + 5'd21 : cp0_tohost <= truncate(rf.rd1(it.rsrc)); + default : + $display( " RTL-ERROR : %m : Illegal MTC0 cop0dst register!" ); + endcase + wbQ.enq(tagged WB_Host 0); //no idea wwhat this actually should be. + end + +//this is host stuff? + tagged MFC0 .it : + begin + case ( it.cop0src ) + // not actually an ALU instruction but don't have the format otherwise + 5'd10 : wbQ.enq(tagged WB_ALU {dest:it.rdst, data:zext(pack(cp0_statsEn)) }); + 5'd20 : wbQ.enq(tagged WB_ALU {dest:it.rdst, data:cp0_fromhost }); + 5'd21 : wbQ.enq(tagged WB_ALU {dest:it.rdst, data:cp0_tohost }); + default : + $display( " RTL-ERROR : %m : Illegal MFC0 cop0src register!" ); + endcase + end + + // -- Illegal --------------------------------------------------- + + default : + $display( " RTL-ERROR : %m : Illegal instruction !" ); + + endcase + +//evaluate branch prediction + Addr ppc = pcQ.first().qnxtpc; //predicted branch + if (ppc != newPC) //prediction wrong + begin + epoch <= pcQ.first().qepoch + 1; + bp.upd(instrpc, newPC); //update branch predictor + pcQ.clear(); + pc <= newPC; + end + else + pcQ.deq(); + + if ( cp0_statsEn ) + num_inst <= num_inst+1; + + endrule + + rule writeback; // ( stage == Writeback ); + traceTiny("mkProc", "writeback","W"); + + + // get what to do off the writeback queue + wbQ.deq(); + case (wbQ.first()) matches + tagged WB_ALU {data:.res, dest:.rdst} : rf.wr(rdst, res); + tagged WB_Load .regWr : + begin + dataRespQ.deq(); + if (dataRespQ.first() matches tagged LoadResp .ld) + rf.wr(truncate(ld.tag), ld.data); // no need to use Rindx from queue? Duplicate? + end + tagged WB_Store : dataRespQ.deq(); + tagged WB_Host .dat : noAction; + endcase + + endrule + + rule inc_num_cycles; + if ( cp0_statsEn ) + num_cycles <= num_cycles+1; + endrule +// THis rule breaks things +// rule handleCPUToHost; +// let req <- server_stub.acceptRequest_ReadCPUToHost(); +// case (req) +// 0: server_stub.sendResponse_ReadCPUToHost(cp0_tohost); +// 1: server_stub.sendResponse_ReadCPUToHost(pc); +// 2: server_stub.sendResponse_ReadCPUToHost(zeroExtend(pack(stage))); +// endcase +// endrule +//----------------------------------------------------------- +// My Adds +//----------------------------------------------------------- + + //----------------------------------------------------------- + // Methods + + interface Client imem_client; + interface Get request = toGet(instReqQ); + interface Put response = toPut(instRespQ); + endinterface + + interface Client dmem_client; + interface Get request = toGet(dataReqQ); + interface Put response = toPut(dataRespQ); + endinterface + + interface Get statsEn_get = toGet(asReg(cp0_statsEn)); + + interface ProcStats stats; + interface Get num_cycles = toGet(asReg(num_cycles)); + interface Get num_inst = toGet(asReg(num_inst)); + endinterface + + interface CPUToHost tohost; + method Bit#(32) cpuToHost(int req); + return (case (req) + 0: cp0_tohost; + 1: pc; + 2: zeroExtend(pack(stage)); + endcase); + endmethod + endinterface + +endmodule + diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/core/Processor.dic --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/core/Processor.dic Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,2 @@ +def STATS.PROCESSOR.CYCLE_COUNT "PROCESSOR: Cycle count: "; +def STATS.PROCESSOR.INST_COUNT "PROCESSOR: Instruction count: "; diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/core/RoutingTable.bsv --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/core/RoutingTable.bsv Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,52 @@ +import Trace::*; +import Vector::*; +import PathTypes::*; + +function FullPath genEmptyPaths (Integer a) ; + FullPath empt = FullPath {voice: fromInteger(a), startAddr: 0, route: emptyCore}; + return (empt); +endfunction + +interface RoutingTable; + method FullPath getPath(Integer voiceNo); +endinterface + +module mkRoutingTable(RoutingTable); + Vector#(`MAX_VOICES, FullPath) routeTable = genWith(genEmptyPaths); + + function CorePath updateVoice0(Integer len, Vector#(len, PathId) cores, CorePath inPath); + CorePath outPath = inPath; + for(Integer i = 0; i < len; i = i+1) + inPath[i] = cores[i]; + return outPath; + endfunction + + //demonstrate two ways of building the routeTable + routeTable[0].startAddr = 0; //where is this really going to come from? + routeTable[0].route[0] = 3; + routeTable[0].route[1] = mixerId; + //rest are already initialized toinvalid + + // or if you just want to update a straight list, this longer emplate works. + function CorePath createVoice1Route(); + CorePath outPath = emptyCore; + + Integer len = 3; + PathId route[len] = {1, 2, mixerId}; //route to update + + for(Integer i = 0; i < len; i = i+1) + outPath[i] = route[i]; + + return outPath; + endfunction + routeTable[1].route = createVoice1Route; + routeTable[1].startAddr = 0; + + //remaining voices are all initialized to empty. + + method FullPath getPath(Integer a); + return routeTable[a]; + endmethod + +endmodule + diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/core/SFIFO.bsv --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/core/SFIFO.bsv Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,213 @@ + +import FIFO::*; +import ConfigReg::*; +import RWire::*; + +import List::*; +import Monad::*; + +interface SFIFO#(type alpha_T, type search_T); + method Action enq(alpha_T x); + method Action deq(); + method alpha_T first(); + method Action clear(); + method Bool find(search_T x); + method Bool find2(search_T x); + +endinterface + +module mkSFIFO#(function Bool searchfunc(search_T s, alpha_T x)) (SFIFO#(alpha_T, search_T)) + provisos + (Bits#(alpha_T,asz)); + + Reg#(alpha_T) f0 <- mkConfigRegU(); + Reg#(alpha_T) f1 <- mkConfigRegU(); + + Reg#(Bool) vf0 <- mkConfigReg(False); + Reg#(Bool) vf1 <- mkConfigReg(False); + + PulseWire edge1 <- mkPulseWire(); + + method Action enq(alpha_T x) if (!(vf0 && vf1)); + if (edge1 || !vf0)//empty or we're dequeueing + begin + vf0 <= True; //True + vf1 <= False; + f0 <= x; + end + else // !vf1 + begin + vf1 <= True; + f1 <= x; + end + endmethod + + method Action deq() if (vf0); + edge1.send(); + vf0 <= vf1; + f0 <= f1; + vf1 <= False; + endmethod + + method alpha_T first() if(vf0); + return (f0); + endmethod + + method Action clear(); + vf0 <= False; + vf1 <= False; + endmethod + + method Bool find(search_T sv); + Bool nvf0 = edge1 ? False: vf0; + Bool nvf1 = vf1; + + return (nvf0 && searchfunc(sv, f0) || + nvf1 && searchfunc(sv, f1)); + endmethod + + method Bool find2(search_T sv); + Bool nvf0 = edge1 ? False: vf0; + Bool nvf1 = vf1; + + return (nvf0 && searchfunc(sv, f0) || + nvf1 && searchfunc(sv, f1)); + endmethod + +endmodule + +module mkSFIFO1#(function Bool searchfunc(search_T s, alpha_T x)) (SFIFO#(alpha_T, search_T)) + provisos + (Bits#(alpha_T,asz), Eq#(alpha_T)); + + Reg#(alpha_T) f0 <- mkConfigRegU; + + Reg#(Bool) vf0 <- mkConfigReg(False); + + PulseWire edge1 <- mkPulseWire(); + + method Action enq(alpha_T x) if (!vf0); + vf0 <= True; //True + f0 <= x; + endmethod + + method Action deq() if (vf0); + edge1.send(); + vf0 <= False; + endmethod + + method alpha_T first() if(vf0); + return (f0); + endmethod + + method Action clear(); + vf0 <= False; + endmethod + + method Bool find(search_T sv); + Bool nvf0 = edge1 ? False: vf0; + + return (nvf0 && searchfunc(sv, f0)); + endmethod + + method Bool find2(search_T sv); + Bool nvf0 = edge1 ? False: vf0; + return (nvf0 && searchfunc(sv, f0)); + endmethod + +endmodule + +module mkSizedSFIFOInternal#(Integer n, + function Bool searchfunc1(search_T s, alpha_T x), + function Bool searchfunc2(search_T s, alpha_T x)) (SFIFO#(alpha_T, search_T)) + + provisos ( Bits#(alpha_T,alpha_SZ) ); + + List#(Reg#(alpha_T)) registers <- replicateM(n, mkRegU); + List#(Reg#(Bool)) valids <- replicateM(n, mkReg(False)); + + function Nat getNextFree (List#(Reg#(Bool)) vs); + + Nat res = fromInteger(n - 1); + + for (Integer x = n - 1; x > -1; x = x - 1) + res = !vs[x]._read() ? fromInteger(x) : res; + + return res; + + endfunction + + function Bool notFull(); + + Bool full = True; + + for (Integer x = 0; x < n; x = x + 1) + full = full && valids[x]._read(); + + return !full; + + endfunction + + method Action enq( alpha_T item ) if ( notFull() ); + + Nat k = getNextFree(valids); + select(valids, k)._write(True); + select(registers, k)._write(item); + + endmethod + + method Action deq() if ( valids[0]._read() ); + + for (Integer x = 0; x < (n-1); x = x + 1) + begin + + (registers[x]) <= registers[x + 1]._read(); + (valids[x]) <= valids[x + 1]._read(); + + end + (valids[n-1]) <= False; + endmethod + + method alpha_T first() if ( valids[0]._read() ); + return registers[0]._read(); + endmethod + + method Bool find(search_T sv); + Bool res = False; + + for (Integer x = 0; x < n; x = x + 1) + if ( valids[x]._read() && searchfunc1(sv, registers[x]._read()) ) + res = True; + + return res; + + endmethod + + method Bool find2(search_T sv); + Bool res = False; + + for (Integer x = 0; x < n; x = x + 1) + if ( valids[x]._read() && searchfunc2(sv, registers[x]._read()) ) + res = True; + + return res; + + endmethod + + method Action clear(); + + for (Integer x = 0; x < n; x = x + 1) + (valids[x]) <= False; + + endmethod + +endmodule + +module mkSizedSFIFO#(Integer n, function Bool searchfunc(search_T s, alpha_T x)) (SFIFO#(alpha_T, search_T)) + provisos + (Bits#(alpha_T,asz)); + + let foo <- mkSizedSFIFOInternal(n, searchfunc, searchfunc); + return foo; + +endmodule diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/core/Trace.bsv --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/core/Trace.bsv Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,92 @@ + +import ClientServer::*; +import GetPut::*; + +//---------------------------------------------------------------------- +// ToString typeclass +//---------------------------------------------------------------------- + +typeclass Traceable#( type item_t ); + function Action traceTiny( String loc, String traceTag, item_t item ); + function Action traceFull( String loc, String traceTag, item_t item ); +endtypeclass + +instance Traceable#(String); + + function Action traceTiny( String loc, String ttag, String str ); + $fdisplay(stderr, " => %s:%s %s", loc, ttag, str ); + endfunction + + function Action traceFull( String loc, String ttag, String str ); + $fdisplay(stderr, " => %s:%s %s", loc, ttag, str ); + endfunction + +endinstance + +instance Traceable#(Bit#(n)); + + function Action traceTiny( String loc, String ttag, Bit#(n) b ); + $fdisplay(stderr, " => %s:%s %x", loc, ttag, b ); + endfunction + + function Action traceFull( String loc, String ttag, Bit#(n) b ); + $fdisplay(stderr, " => %s:%s %x", loc, ttag, b ); + endfunction + +endinstance + +//---------------------------------------------------------------------- +// Tracing interface wrappers +//---------------------------------------------------------------------- + +function Get#(item_t) traceGet( String locStr, String tagStr, Get#(item_t) g ) + provisos ( Traceable#(item_t) ); + return + ( + interface Get + method ActionValue#(item_t) get(); + item_t item <- g.get(); + traceTiny(locStr, tagStr,item); + return item; + endmethod + endinterface + ); +endfunction + +function Put#(item_t) tracePut( String locStr, String tagStr, Put#(item_t) p ) + provisos ( Traceable#(item_t) ); + return + ( + interface Put + method Action put( item_t item ); + traceTiny(locStr, tagStr,item); + p.put(item); + endmethod + endinterface + ); +endfunction + +function Client#(req_t,resp_t) traceClient( String locStr, String reqTagStr, String respTagStr, + Client#(req_t,resp_t) c ) + provisos ( Traceable#(req_t), Traceable#(resp_t) ); + return + ( + interface Client + interface Get request = traceGet(locStr, reqTagStr,c.request); + interface Put response = tracePut(locStr, respTagStr,c.response); + endinterface + ); +endfunction + +function Server#(req_t,resp_t) traceServer( String locStr, String reqTagStr, String respTagStr, + Server#(req_t,resp_t) c ) + provisos ( Traceable#(req_t), Traceable#(resp_t) ); + return + ( + interface Server + interface Put request = tracePut(locStr, reqTagStr,c.request); + interface Get response = traceGet(locStr, respTagStr,c.response); + endinterface + ); +endfunction + diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/core/audio_core.awb --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/core/audio_core.awb Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,16 @@ +%name audio core +%desc Instantiates a soft core used for audio, wrapped in the audio pipeline interface + +%provides audio_pipeline + +%requires audio_pipeline_types +%requires core +%requires funcp_simulated_memory +%requires funcp_base_types +%requires hasim_common + + +%attributes 6_375 + +%public FIRFilterPipeline.bsv + diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/core/core.awb --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/core/core.awb Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,16 @@ +%name Audio Processor Soft Core +%desc Instantiates a processor, some caches, and a memory arbiter + +%provides core + +%requires mem_arb +%requires instruction_cache +%requires data_cache +%requires processor +%requires processor_library + +%attributes 6_375 + +%public Core.bsv + + diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/core/data_cache.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/core/data_cache.d Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,10 @@ +%name Blocking Data Cache +%desc Parametric Blocking Data Cache + +%provides data_cache + +%attributes 6_375 + +%public DataCacheBlocking.bsv +%public DataCache.dic + diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/core/instruction_cache.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/core/instruction_cache.d Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,11 @@ +%name Blocking Instruction Cache +%desc Parametric Blocking Instruction Cache + +%provides instruction_cache + +%attributes 6_375 + +%public InstCacheBlocking.bsv +%public InstCache.dic + + diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/core/mem_arb.awb --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/core/mem_arb.awb Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,10 @@ +%name Round-robin Audio memory arbiter +%desc Round-robin memory arbiter + +%provides mem_arb + +%attributes 6_375 + +%public MemArb.bsv + + diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/core/processor.awb --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/core/processor.awb Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,13 @@ +%name 3-Stage Audio Processor +%desc 3-Stage Processor, one stage per cycle. + +%provides processor + +%attributes 6_375 + +%public Processor.bsv ProcTypes.bsv +%public Processor.dic + + + + diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/core/processor_library.awb --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/core/processor_library.awb Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,9 @@ +%name Processor Audio Library +%desc Some generally useful modules, found in the processor cores + +%provides processor_library + +%attributes 6_375 + +%public Trace.bsv BFIFO.bsv MemTypes.bsv BRegFile.bsv BranchPred.bsv + diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/lab1/FIRFilter.bsv --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/lab1/FIRFilter.bsv Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,21 @@ +import ClientServer::*; +import GetPut::*; +import FIFO::*; + +import AC97Common::*; + +module FIRFilter (Server#(AC97Sample)); + FIFO#(AC97Sample) infifo <- mkFIFO; + FIFO#(AC97Sample) outfifo <- mkFIFO; + + // for now, we don't do anything. + rule connectReqResp; + $display("FIR copies a data"); + outfifo.enq(infifo.first); + outfifo.deq; + endrule + + + interface request = fifoToPut(infifo); + interface response = fifoToGet(outfifo); +endmodule \ No newline at end of file diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/lab1/FIRFilterDefault.bsv --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/lab1/FIRFilterDefault.bsv Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,157 @@ +// The MIT License + +// Copyright (c) 2009 Massachusetts Institute of Technology + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +// Author: Kermin Fleming kfleming@mit.edu + +import Connectable::*; +import GetPut::*; +import ClientServer::*; +import FIFO::*; +import FixedPoint::*; +import Vector::*; + +//AWB includes. These import the structure whcih allow us to communicate +// with the outside world, and are part of the AWB library code + +`include "asim/provides/soft_connections.bsh" +`include "asim/provides/common_services.bsh" + +// Local includes. Look for the correspondingly named .awb files +// workspace/labs/src/mit-6.375/modules/bluespec/mit-6.375/common/ +// to find the actual Bluespec files which are used to generate +// these includes. These files are specific to this audio processing +// pipeline + +`include "asim/provides/audio_pipeline_types.bsh" +`include "asim/provides/audio_processor_types.bsh" + +typedef 8 Taps; + +module [Connected_Module] mkFIRFilter (FIRFilter); + + + // instantiate an input FIFO and an Output FIFO + // mkFIFO returns a fifo of length 2 (by default) + // AudioProcessorUnit is the name given to the packets + // of DATA processed by our audio pipeline. For their + // definition, look in the file + // workspace/labs/src/mit-6.375/modules/bluespec/mit-6.375/common/AudioProcessorTypes.bsv + + FIFO#(AudioProcessorUnit) infifo <- mkFIFO; + FIFO#(AudioProcessorUnit) outfifo <- mkFIFO; + + + // an alternate syntax for instantiating the samples vector + // would have been as follows: + // + // Vector#(Taps,Reg#(Sample)) samples <- replicateM(mkReg(0)); + // + // we have used an explicit loop here, to demonstrate how + // vectors can be instantiated during the static elaboration + // phase, even though replicateM is far more concise. + + Vector#(Taps,Reg#(Sample)) samples = newVector(); + for(Integer i = 0; i < valueof(Taps); i=i+1) + samples[i] <- mkReg(0); + + Vector#(9,Reg#(FixedPoint#(16,16))) pr <- replicateM(mkReg(0)); + + + // fromReal takes a Real number and converts it to a FixedPoint + // representation. The compiler is smart enough to infer the + // type (bit width) of the fixed point (in this case, we have 16 + // bits of integer, and 16 bits of fraction. + + FixedPoint#(16,16) firCoefs [9] = {fromReal(-0.0124), + fromReal(0.0), + fromReal(-0.0133), + fromReal(0.0), + fromReal(0.8181), + fromReal(0.0), + fromReal(-0.0133), + fromReal(0.0), + fromReal(-0.0124)}; + + + // This rule implements a fir filter. We do the fir computations in + // 16.16 fixed point. This preserves the magnitude of the input + // pcm. This code was implemented using for loops so as to be more + // clear. Using the functions map, fold, readVReg, and writeVReg + // would have been more concise. + + rule process (infifo.first matches tagged Sample .sample); + + // Advance the fir filter, by shifting all the elements + // down the Vector of registers (like a shift register) + + samples[0] <= sample; + for(Integer i = 0; i < valueof(Taps) - 1; i = i + 1) + begin + samples[i+1] <= samples[i]; + end + + // Filter the values, using an inefficient adder chain. You will + // need to shorten the combinatorial path, by pipelining this logic. + + FixedPoint#(16,16) accumulate= firCoefs[0] * fromInt(sample); + for(Integer i = 0; i < valueof(Taps); i = i + 1) + begin + accumulate = accumulate + firCoefs[1+i] * fromInt(samples[i]); + end + + outfifo.enq(tagged Sample fxptGetInt(accumulate)); + + infifo.deq; + endrule + + // Handle the end of stream condition. Look at the two rule guards, + // these are obviously mutually exclusive. The definition of + // AudioProcessorUnit shows that it can be tagged only as a Sample, or + // EndOfFile; nothing else! + + rule endOfFile (infifo.first matches tagged EndOfFile); + + $display("FIR got end of file"); + + // Reset state for next invocation + for(Integer i = 0; i < valueof(Taps); i = i + 1) + begin + samples[i] <= 0; + pr[i] <= 0; + end + + // pass the end-of-file token down the pipeline, eventually this will + // make it back to the software side, to notify it that the stream + // has been processed completely + + outfifo.enq(infifo.first); + infifo.deq; + endrule + + + // this section connects the fifos instantiated internally to the + // externally visible interface + + interface sampleInput = fifoToPut(infifo); + interface sampleOutput = fifoToGet(outfifo); + +endmodule diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/lab1/FIRFilterPipeline.bsv --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/lab1/FIRFilterPipeline.bsv Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,46 @@ +// The MIT License + +// Copyright (c) 2009 Massachusetts Institute of Technology + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +// Author: Kermin Fleming kfleming@mit.edu + +import Connectable::*; +import GetPut::*; +import ClientServer::*; +import FIFO::*; + +//AWB includes +`include "asim/provides/low_level_platform_interface.bsh" +`include "asim/provides/soft_connections.bsh" +`include "asim/provides/common_services.bsh" + +//Local includes +`include "asim/provides/audio_processor_types.bsh" +`include "asim/provides/audio_pipeline_types.bsh" +`include "asim/provides/fir_filter.bsh" + +module [Connected_Module] mkAudioPipeline (AudioPipeline); + FIRFilter filter <- mkFIRFilter; + + interface sampleInput = filter.sampleInput; + interface sampleOutput = filter.sampleOutput; + +endmodule diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/lab1/FIRFilterPipelineTypes.bsv --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/lab1/FIRFilterPipelineTypes.bsv Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,32 @@ +// The MIT License + +// Copyright (c) 2009 Massachusetts Institute of Technology + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +// Author: Kermin Fleming kfleming@mit.edu + +import Connectable::*; +import GetPut::*; +import ClientServer::*; +import FIFO::*; + +`include "audio_processor_types.bsh" + +typedef AudioPipeline FIRFilter; diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/lab1/fir_filter_default.awb --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/lab1/fir_filter_default.awb Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,9 @@ +%name FIR Filter Default Implementation +%desc Copy FIR Filter + +%provides fir_filter + +%attributes 6_375 + +%public FIRFilterDefault.bsv + diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/lab1/fir_filter_pipeline.awb --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/lab1/fir_filter_pipeline.awb Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,12 @@ +%name FIR Filter Pipeline +%desc Instantiates a FIRFilter and wraps it in the audio pipeline interface + +%provides audio_pipeline + +%requires audio_pipeline_types +%requires fir_filter + +%attributes 6_375 + +%public FIRFilterPipeline.bsv + diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/lab1/fir_filter_types.awb --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/lab1/fir_filter_types.awb Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,9 @@ +%name FIR Filter Pipeline Types +%desc Types for the fir filter. + +%provides audio_pipeline_types + +%attributes 6_375 + +%public FIRFilterPipelineTypes.bsv + diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/lab4/BFIFO.bsv --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/lab4/BFIFO.bsv Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,222 @@ +import FIFO::*; +import FIFOF::*; +import List::*; +import Assert::*; + +module mkBFIFO1( FIFO#(item_t) ) provisos ( Bits#(item_t,item_sz) ); + + RWire#(item_t) inputWire <- mkRWire(); + PulseWire deqEnabled <- mkPulseWire(); + PulseWire clearEnabled <- mkPulseWire(); + + Reg#(item_t) register <- mkRegU(); + Reg#(Bool) valid <- mkReg(False); + + // If there is an input item on the inputWire wire and dequeue did not + // execute this cycle then we need to store the item in the register + + (*fire_when_enabled*) + rule update ( True ); + case (inputWire.wget()) matches + tagged Invalid: + if (deqEnabled || clearEnabled) + valid <= False; + tagged Valid .x: + begin + register <= x; + valid <= !(deqEnabled || clearEnabled); + end + endcase + endrule + + // On enqueue we write the input item to the inputWire wire + + method Action enq( item_t item ) if ( !valid ); + inputWire.wset(item); + endmethod + + // On dequeue we always invalidate the storage register regardless + // of whether or not the item was actually bypassed or not. We also + // set a combinational signal so that we know not to move the item + // into the register this cycle. + + method Action deq() if ( valid || isValid(inputWire.wget()) ); + deqEnabled.send(); + endmethod + + // We get the item either from the register (if register is valid) or + // from the combinational bypasss (if the rwire is valid). + + method item_t first() if ( valid || isValid(inputWire.wget()) ); + if ( valid ) + return register; + else + return unJust(inputWire.wget()); + endmethod + + method Action clear(); + clearEnabled.send(); + endmethod + +endmodule + +module mkSizedBFIFO#(Integer n) ( FIFO#(item_t) ) provisos ( Bits#(item_t,item_sz) ); + + RWire#(item_t) inputWire <- mkRWire(); + PulseWire deqEnabled <- mkPulseWire(); + PulseWire clearEnabled <- mkPulseWire(); + + List#(Reg#(item_t)) registers <- replicateM(n, mkRegU); + List#(Reg#(Bool)) valids <- replicateM(n, mkReg(False)); + + function Nat getNextFree (List#(Reg#(Bool)) vs); + + Nat res = fromInteger(n - 1); + + for (Integer x = n - 1; x > -1; x = x - 1) + res = !vs[x]._read() ? fromInteger(x) : res; + + return res; + + endfunction + + function Bool notFull(); + + Bool full = True; + + for (Integer x = 0; x < length(valids); x = x + 1) + full = full && valids[x]._read(); + + return !full; + + endfunction + // If there is an input item on the inputWire wire and dequeue did not + // execute this cycle then we need to store the item in the register + + rule update ( True ); + Nat next = getNextFree(valids); + + next = (deqEnabled) ? next - 1 : next; + + (valids[next]) <= isValid(inputWire.wget()); + (registers[next]) <= validValue(inputWire.wget()); + + if (deqEnabled && !clearEnabled) + begin + + for (Nat x = 0; x < (next - 1); x = x + 1) + begin + (valids[x]) <= valids[x+1]._read(); + (registers[x]) <= registers[x+1]._read(); + end + + end + else if (clearEnabled) + begin + + for (Integer x = 0; x < n; x = x + 1) + (valids[x]) <= False; + + end + endrule + + // On enqueue we write the input item to the inputWire wire + + method Action enq( item_t item ) if ( notFull ); + inputWire.wset(item); + endmethod + + // On dequeue we always invalidate the storage register regardless + // of whether or not the item was actually bypassed or not. We also + // set a combinational signal so that we know not to move the item + // into the register this cycle. + + method Action deq() if ( valids[0]._read() || isValid(inputWire.wget()) ); + deqEnabled.send(); + endmethod + + // We get the item either from the register (if register is valid) or + // from the combinational bypasss (if the rwire is valid). + + method item_t first() if ( valids[0]._read() || isValid(inputWire.wget()) ); + if ( valids[0]._read() ) + return registers[0]._read(); + else + return unJust(inputWire.wget()); + endmethod + + + method Action clear(); + clearEnabled.send(); + endmethod + +endmodule + + +module mkBFIFOF1( FIFOF#(item_t) ) provisos ( Bits#(item_t,item_sz) ); + + RWire#(item_t) inputWire <- mkRWire(); + RWire#(Bool) deqEnabled <- mkRWire(); + + Reg#(Maybe#(item_t)) register <- mkReg(Invalid); + + // If there is an input item on the inputWire wire and dequeue did not + // execute this cycle then we need to store the item in the register + + rule noDeq ( isValid(inputWire.wget()) && !isValid(deqEnabled.wget()) ); + register <= inputWire.wget(); + endrule + + // On enqueue we write the input item to the inputWire wire + + method Action enq( item_t item ) if ( !isValid(register) ); + inputWire.wset(item); + endmethod + + // On dequeue we always invalidate the storage register regardless + // of whether or not the item was actually bypassed or not. We also + // set a combinational signal so that we know not to move the item + // into the register this cycle. + + method Action deq() if ( isValid(register) || isValid(inputWire.wget()) ); + register <= Invalid; + deqEnabled.wset(True); + endmethod + + // We get the item either from the register (if register is valid) or + // from the combinational bypasss (if the rwire is valid). + + method item_t first() if ( isValid(register) || isValid(inputWire.wget()) ); + if ( isValid(register) ) + return unJust(register); + else + return unJust(inputWire.wget()); + endmethod + + // FIFOF adds the following two methods + + method Bool notFull(); + return !isValid(register); + endmethod + + method Bool notEmpty(); + return (isValid(register) || isValid(inputWire.wget())); + endmethod + + // Not sure about the clear method ... + + method Action clear(); + dynamicAssert( False, "BFIFO.clear() not implemented yet!" ); + endmethod + +endmodule + +(* synthesize *) +module mkBFIFO_16 (FIFO#(Bit#(16))); + + let f <- mkBFIFO1(); + + return f; + +endmodule + diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/lab4/BRegFile.bsv --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/lab4/BRegFile.bsv Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,36 @@ +import RegFile::*; +import RWire::*; +import ProcTypes::*; + +//----------------------------------------------------------- +// Register file module +//----------------------------------------------------------- + +interface BRegFile #(type index_t, type data_t); + method Action upd(index_t addr, data_t data); + method data_t sub(index_t addr); +endinterface + +module mkBRegFile(RegFile#(index_t, data_t)) + provisos (Bits#(index_t, size_index), + Bits#(data_t, size_data), + Eq#(index_t), + Bounded#(index_t) ); + + RegFile#(index_t, data_t) rf <- mkRegFileWCF(minBound, maxBound); + RWire#(Tuple2#(index_t, data_t)) rw <-mkRWire(); + + method Action upd (index_t r, data_t d); + rf.upd(r,d); + rw.wset(tuple2(r,d)); + endmethod + + method data_t sub (index_t r); + case (rw.wget()) matches + tagged Valid {.wr, .d} : + return (wr == r) ? d : rf.sub(r); + tagged Invalid : return rf.sub(r); + endcase + endmethod + +endmodule diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/lab4/BranchPred.bsv --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/lab4/BranchPred.bsv Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,41 @@ +import RegFile::*; +import ProcTypes::*; +import FIFO::*; + +typedef Maybe#(Addr) BrPred; +typedef Bit#(4) BPindx; + +typedef struct {Addr brpc; Addr nextpc;} BrPair deriving (Bits,Eq); + +typedef union tagged +{ + BrPair Valid; + void Invalid; +} CBranchPath deriving(Bits, Eq); // have the cache start out invalid and add valid values. + +interface BranchPred; + method BrPred get(Addr pres); //returns a maybe type that is invalid if no predition + method Action upd(Addr pres, Addr next); +endinterface + +module mkBranchPred(BranchPred); + + //state variables + RegFile#(BPindx, CBranchPath) bcache <- mkRegFileFull(); // cache to hold 16 (based on BPindx) + + method Action upd(Addr pres, Addr next); + BrPair brp; + brp = BrPair {brpc:pres, nextpc:next}; + bcache.upd(pres[5:2], tagged Valid brp); + endmethod + + method BrPred get(Addr prespc); + BPindx rd = prespc[5:2]; + let cbp = bcache.sub(rd); + if (cbp matches tagged Valid .bp &&& bp.brpc == prespc) //make sure that the read value was actually put there and the full address matches + return tagged Valid bp.nextpc; + else return Invalid; + endmethod + +endmodule + diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/lab4/CBUFF.bsv --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/lab4/CBUFF.bsv Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,44 @@ +import Connectable::*; +import GetPut::*; +import ClientServer::*; + +`include "asim/provides/librl_bsv_storage.bsh" + +typedef SCOREBOARD_FIFO_ENTRY_ID#(t) CBUFFToken#(type t); + +interface CBUFF #(numeric type n, type element_type); + interface Get#(CBUFFToken#(n)) reserve; + interface Put#(Tuple2 #(CBUFFToken#(n), element_type)) complete; + interface Get#(element_type) drain; +endinterface + +module mkCBUFF(CBUFF#(n, element_type)) + provisos(Bits#(element_type,a__)); + + SCOREBOARD_FIFOF#(n,element_type) cbuff <- mkScoreboardFIFOF(); + + let res = interface Get; + method ActionValue#(CBUFFToken#(n)) get(); + let tok <- cbuff.enq(); + return tok; + endmethod + endinterface; + + let comp = interface Put; + method Action put(Tuple2#(CBUFFToken#(n),element_type) t); + cbuff.setValue(tpl_1(t), tpl_2(t)); + endmethod + endinterface; + + let dr = interface Get; + method ActionValue#(element_type) get(); + cbuff.deq(); + return cbuff.first(); + endmethod + endinterface; + + interface Get reserve = res; + interface Put complete = comp; + interface Get drain = dr; + +endmodule \ No newline at end of file diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/lab4/Core.bsv --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/lab4/Core.bsv Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,70 @@ +// The MIT License + +// Copyright (c) 2009 Massachusetts Institute of Technology + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import Connectable::*; +import GetPut::*; +import ClientServer::*; + +//AWB includes +`include "asim/provides/low_level_platform_interface.bsh" +`include "asim/provides/soft_connections.bsh" +`include "asim/provides/common_services.bsh" + +// Local includes +`include "asim/provides/processor_library.bsh" +`include "asim/provides/mem_arb.bsh" +`include "asim/provides/instruction_cache.bsh" +`include "asim/provides/data_cache.bsh" +`include "asim/provides/processor.bsh" + + + +interface Core; + + // Interface from core to main memory + interface Client#(MainMemReq,MainMemResp) mmem_client; + +endinterface + +module [CONNECTED_MODULE] mkCore( Core ); + + // Instantiate the modules + + Proc proc <- mkProc(); + ICache#(InstReq,InstResp) icache <- mkInstCache(); + DCache#(DataReq,DataResp) dcache <- mkDataCache(); + MemArb marb <- mkMemArb(); + + // Internal connections + + mkConnection( proc.statsEn_get, icache.statsEn_put ); + mkConnection( proc.statsEn_get, dcache.statsEn_put ); + mkConnection( proc.imem_client, icache.proc_server ); + mkConnection( proc.dmem_client, dcache.proc_server ); + mkConnection( icache.mmem_client, marb.cache0_server ); + mkConnection( dcache.mmem_client, marb.cache1_server ); + + // Methods + + interface mmem_client = marb.mmem_client; + +endmodule diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/lab4/DataCache.dic --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/lab4/DataCache.dic Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,3 @@ +def STATS.DATA_CACHE.NUM_ACCESSES "DATA_CACHE: Number Of Accesses: "; +def STATS.DATA_CACHE.NUM_MISSES "DATA_CACHE: Number Of Misses: "; +def STATS.DATA_CACHE.NUM_WRITEBACKS "DATA_CACHE: Number Of Writebacks: "; \ No newline at end of file diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/lab4/DataCacheBlocking.bsv --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/lab4/DataCacheBlocking.bsv Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,283 @@ +// The MIT License + +// Copyright (c) 2009 Massachusetts Institute of Technology + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +// Local includes +`include "asim/provides/low_level_platform_interface.bsh" +`include "asim/provides/soft_connections.bsh" +`include "asim/provides/processor_library.bsh" +`include "asim/provides/fpga_components.bsh" +`include "asim/provides/common_services.bsh" +`include "asim/dict/STATS_DATA_CACHE.bsh" + +import Connectable::*; +import GetPut::*; +import ClientServer::*; +import RegFile::*; +import FIFO::*; +import FIFOF::*; + + + + +interface DCache#( type req_t, type resp_t ); + + // Interface from processor to cache + interface Server#(req_t,resp_t) proc_server; + + // Interface from cache to main memory + interface Client#(MainMemReq,MainMemResp) mmem_client; + + // Interface for enabling/disabling statistics + interface Put#(Bool) statsEn_put; + +endinterface + + +//---------------------------------------------------------------------- +// Cache Types +//---------------------------------------------------------------------- + +typedef 10 CacheLineIndexSz; +typedef 20 CacheLineTagSz; +typedef 32 CacheLineSz; + +typedef Bit#(CacheLineIndexSz) CacheLineIndex; +typedef Bit#(CacheLineTagSz) CacheLineTag; +typedef Bit#(CacheLineSz) CacheLine; + +typedef enum +{ + Init, + Access, + RefillReq, + RefillResp +} +CacheStage +deriving (Eq,Bits); + +//---------------------------------------------------------------------- +// Helper functions +//---------------------------------------------------------------------- + +function Bit#(AddrSz) getAddr( DataReq req ); + + Bit#(AddrSz) addr = ?; + case ( req ) matches + tagged LoadReq .ld : addr = ld.addr; + tagged StoreReq .st : addr = st.addr; + endcase + + return addr; + +endfunction + +function CacheLineIndex getCacheLineIndex( DataReq req ); + Bit#(AddrSz) addr = getAddr(req); + Bit#(CacheLineIndexSz) index = truncate( addr >> 2 ); + return index; +endfunction + +function CacheLineTag getCacheLineTag( DataReq req ); + Bit#(AddrSz) addr = getAddr(req); + Bit#(CacheLineTagSz) tag = truncate( addr >> fromInteger(valueOf(CacheLineIndexSz)) >> 2 ); + return tag; +endfunction + +function Bit#(AddrSz) getCacheLineAddr( DataReq req ); + Bit#(AddrSz) addr = getAddr(req); + return ((addr >> 2) << 2); +endfunction + +//---------------------------------------------------------------------- +// Main module +//---------------------------------------------------------------------- + +module [CONNECTED_MODULE] mkDataCache( DCache#(DataReq,DataResp) ); + + //----------------------------------------------------------- + // State + + Reg#(CacheStage) stage <- mkReg(Init); + + LUTRAM#(CacheLineIndex,Maybe#(CacheLineTag)) cacheTagRam <- mkLUTRAMU_RegFile(); + LUTRAM#(CacheLineIndex,CacheLine) cacheDataRam <- mkLUTRAMU_RegFile(); + + FIFO#(DataReq) reqQ <- mkFIFO(); + FIFOF#(DataResp) respQ <- mkBFIFOF1(); + + FIFO#(MainMemReq) mainMemReqQ <- mkBFIFO1(); + FIFO#(MainMemResp) mainMemRespQ <- mkFIFO(); + + Reg#(CacheLineIndex) initCounter <- mkReg(1); + + // Statistics state + + Reg#(Bool) statsEn <- mkReg(False); + + STAT num_accesses <- mkStatCounter(`STATS_DATA_CACHE_NUM_ACCESSES); + STAT num_misses <- mkStatCounter(`STATS_DATA_CACHE_NUM_MISSES); + STAT num_writebacks <- mkStatCounter(`STATS_DATA_CACHE_NUM_WRITEBACKS); + + //----------------------------------------------------------- + // Name some wires + + let req = reqQ.first(); + let reqIndex = getCacheLineIndex(req); + let reqTag = getCacheLineTag(req); + let reqCacheLineAddr = getCacheLineAddr(req); + + //----------------------------------------------------------- + // Initialize + + rule init ( stage == Init ); + traceTiny("mkDataCacheBlocking", "stage","i"); + initCounter <= initCounter + 1; + cacheTagRam.upd(initCounter,Invalid); + if ( initCounter == 0 ) + stage <= Access; + endrule + + //----------------------------------------------------------- + // Access cache rule + + rule access ( (stage == Access) && respQ.notFull() ); + + // Statistics + + if ( statsEn ) + num_accesses.incr(); + + + // Get the corresponding tag from the rams + + Maybe#(CacheLineTag) cacheLineTag = cacheTagRam.sub(reqIndex); + + // Handle cache hits ... + + if ( isValid(cacheLineTag) && ( unJust(cacheLineTag) == reqTag ) ) + begin + traceTiny("mkDataCacheBlocking", "hitMiss","h"); + reqQ.deq(); + + case ( req ) matches + + tagged LoadReq .ld : + respQ.enq( LoadResp { tag: ld.tag, data: cacheDataRam.sub(reqIndex) } ); + + tagged StoreReq .st : + begin + respQ.enq( StoreResp { tag : st.tag } ); + cacheDataRam.upd(reqIndex,st.data); + end + + endcase + + end + + // Handle cache misses ... + + else + begin + traceTiny("mkDataCacheBlocking", "hitMiss","m"); + if ( statsEn ) + num_misses.incr(); + + // Currently we don't use dirty bits so we always writeback the data if it is valid + + if ( isValid(cacheLineTag) ) + begin + + if ( statsEn ) + num_writebacks.incr(); + + MainMemReq wbReq + = StoreReq { tag : 0, + addr : { unJust(cacheLineTag), reqIndex, 2'b0 }, + data : cacheDataRam.sub(reqIndex) }; + + mainMemReqQ.enq(wbReq); + stage <= RefillReq; + end + + // Otherwise we can issue the refill request now + + else + begin + mainMemReqQ.enq( LoadReq { tag: 0, addr: reqCacheLineAddr } ); + stage <= RefillResp; + end + + end + + endrule + + //----------------------------------------------------------- + // Refill request rule + + rule refillReq ( stage == RefillReq ); + traceTiny("mkDataCacheBlocking", "stage","r"); + mainMemReqQ.enq( LoadReq { tag: 0, addr: reqCacheLineAddr } ); + stage <= RefillResp; + endrule + + //----------------------------------------------------------- + // Refill response rule + + rule refillResp ( stage == RefillResp ); + traceTiny("mkDataCacheBlocking", "stage","R"); + traceTiny("mkDataCacheBlocking", "refill",mainMemRespQ.first()); + + // Write the new data into the cache and update the tag + + mainMemRespQ.deq(); + case ( mainMemRespQ.first() ) matches + + tagged LoadResp .ld : + begin + cacheTagRam.upd(reqIndex,Valid(reqTag)); + cacheDataRam.upd(reqIndex,ld.data); + end + + tagged StoreResp .st : + noAction; + + endcase + + stage <= Access; + endrule + + //----------------------------------------------------------- + // Methods + + interface Client mmem_client; + interface Get request = fifoToGet(mainMemReqQ); + interface Put response = fifoToPut(mainMemRespQ); + endinterface + + interface Server proc_server; + interface Put request = tracePut("mkDataCacheBlocking", "reqTiny",fifoToPut(reqQ)); + interface Get response = traceGet("mkDataCacheBlocking", "respTiny",fifofToGet(respQ)); + endinterface + + interface Put statsEn_put = regToPut(statsEn); + +endmodule diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/lab4/FIFOUtility.bsv --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/lab4/FIFOUtility.bsv Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,54 @@ +import FIFO::*; +import FIFOF::*; +import Clocks::*; +import GetPut::*; + +function FIFO#(fifo_type) guardedfifofToFifo( FIFOF#(fifo_type) fifo); + + FIFO#(fifo_type) f = interface FIFO#(fifo_type); + method first = fifo.first; + method enq = fifo.enq; + method deq = fifo.deq; + method clear = fifo.clear; + endinterface; + return f; +endfunction + +function Get#(fifo_type) syncFifoToGet( SyncFIFOIfc#(fifo_type) fifo); + Get#(fifo_type) f = interface Get#(fifo_type); + method ActionValue#(fifo_type) get(); + fifo.deq; + return fifo.first; + endmethod + endinterface; + return f; +endfunction + +function Put#(fifo_type) syncFifoToPut( SyncFIFOIfc#(fifo_type) fifo); + Put#(fifo_type) f = interface Put#(fifo_type); + method Action put(fifo_type data); + fifo.enq(data); + endmethod + endinterface; + return f; +endfunction + +function String fifofState(FIFOF#(data) fifo); + String s = ""; + + if(!fifo.notEmpty) + begin + s = "Empty"; + end + else if (!fifo.notFull) + begin + s = "Full"; + end + else + begin + s = "Neither Empty Nor Full"; + end + + return s; +endfunction + diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/lab4/FPGATypes.bsv --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/lab4/FPGATypes.bsv Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,24 @@ +typedef 30 AvalonAddressWidth; +typedef 32 AvalonDataWidth; + +// need length + 1 spacing between CBusGet/Puts +// Be warned - consider the word size of each address before +// assigning new ones!!! +// These are word addresses +// Multiply by 4 to get byte address +typedef 0 ToHostRegAddr; +typedef 4 FromHostRegAddr; +typedef 8 BreakpointRegAddr; +typedef 12 BreakpointClearedAddr; +typedef 16 PCRegAddr; +typedef 20 StatsEnRegAddr; +typedef 24 DCacheNumAccessesRegAddr; +typedef 28 DCacheNumMissesRegAddr; +typedef 32 DCacheNumWriteBacksRegAddr; +typedef 36 ICacheNumAccessesRegAddr; +typedef 40 ICacheNumMissesRegAddr; +typedef 44 ICacheNumWriteBacksRegAddr; +typedef 48 NumCyclesRegAddr; +typedef 52 NumInstRegAddr; +typedef 256 RegFileAddr; // The regfile is super long. Be careful of assigning conflicting addresses. + diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/lab4/GetPutExt.bsv --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/lab4/GetPutExt.bsv Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,108 @@ +import FIFOF::*; +import RWire::*; +import GetPut::*; + +// Convert a FIFOF into a put interface + +function Put#(item_t) fifofToPut( FIFOF#(item_t) f ) provisos ( ); + return + ( + interface Put + method Action put( item_t item ); + f.enq(item); + endmethod + endinterface + ); +endfunction + +// Convert a FIFOF into a get interface + +function Get#(item_t) fifofToGet( FIFOF#(item_t) f ) provisos ( ); + return + ( + interface Get + method ActionValue#(item_t) get(); + f.deq(); + return f.first(); + endmethod + endinterface + ); +endfunction + +// Convert a register into an (always ready) put interface + +function Put#(item_t) regToPut( Reg#(item_t) r ) provisos ( ); + return + ( + interface Put + method Action put( item_t item ); + r <= item; + endmethod + endinterface + ); +endfunction + +// Convert a register into an (always ready) get interface + +function Get#(item_t) regToGet( Reg#(item_t) r ) provisos ( ); + return + ( + interface Get + method ActionValue#(item_t) get(); + return r; + endmethod + endinterface + ); +endfunction + +// Convert a Wire into a put interface + +function Put#(item_t) wireToPut( Wire#(item_t) w ) provisos ( ); + return + ( + interface Put + method Action put( item_t item ); + w._write(item); + endmethod + endinterface + ); +endfunction + +// Convert a WIREF into a get interface + +function Get#(item_t) wireToGet( Wire#(item_t) w ) provisos ( ); + return + ( + interface Get + method ActionValue#(item_t) get(); + return w._read(); + endmethod + endinterface + ); +endfunction + +// Convert a RWire into a put interface + +function Put#(item_t) rwireToPut( RWire#(item_t) w ) provisos ( ); + return + ( + interface Put + method Action put( item_t item ); + w.wset(item); + endmethod + endinterface + ); +endfunction + +// Convert a RWire into a get interface + +function Get#(item_t) rwireToGet( RWire#(item_t) w ) provisos ( ); + return + ( + interface Get + method ActionValue#(item_t) get() if ( isValid(w.wget()) ); + return unJust(w.wget()); + endmethod + endinterface + ); +endfunction diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/lab4/InstCache.dic --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/lab4/InstCache.dic Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,3 @@ +def STATS.INST_CACHE.NUM_ACCESSES "INST_CACHE: Number Of Accesses: "; +def STATS.INST_CACHE.NUM_MISSES "INST_CACHE: Number Of Misses: "; +def STATS.INST_CACHE.NUM_EVICTIONS "INST_CACHE: Number Of Evictions: "; diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/lab4/InstCacheBlocking.bsv --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/lab4/InstCacheBlocking.bsv Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,255 @@ +// The MIT License + +// Copyright (c) 2009 Massachusetts Institute of Technology + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import Connectable::*; +import GetPut::*; +import ClientServer::*; +import RegFile::*; +import FIFO::*; +import FIFOF::*; +import RWire::*; + +// Local includes +`include "asim/provides/low_level_platform_interface.bsh" +`include "asim/provides/soft_connections.bsh" +`include "asim/provides/processor_library.bsh" +`include "asim/provides/fpga_components.bsh" +`include "asim/provides/common_services.bsh" +`include "asim/dict/STATS_INST_CACHE.bsh" + +interface ICache#( type req_t, type resp_t ); + + // Interface from processor to cache + interface Server#(req_t,resp_t) proc_server; + + // Interface from cache to main memory + interface Client#(MainMemReq,MainMemResp) mmem_client; + + // Interface for enabling/disabling statistics + interface Put#(Bool) statsEn_put; + +endinterface + +//---------------------------------------------------------------------- +// Cache Types +//---------------------------------------------------------------------- + +typedef 10 CacheLineIndexSz; +typedef 20 CacheLineTagSz; +typedef 32 CacheLineSz; + +typedef Bit#(CacheLineIndexSz) CacheLineIndex; +typedef Bit#(CacheLineTagSz) CacheLineTag; +typedef Bit#(CacheLineSz) CacheLine; + +typedef enum +{ + Init, + Access, + Evict, + RefillReq, + RefillResp +} +CacheStage +deriving (Eq,Bits); + +//---------------------------------------------------------------------- +// Helper functions +//---------------------------------------------------------------------- + +function Bit#(AddrSz) getAddr( InstReq req ); + + Bit#(AddrSz) addr = ?; + case ( req ) matches + tagged LoadReq .ld : addr = ld.addr; + tagged StoreReq .st : addr = st.addr; + endcase + + return addr; + +endfunction + +function CacheLineIndex getCacheLineIndex( InstReq req ); + Bit#(AddrSz) addr = getAddr(req); + Bit#(CacheLineIndexSz) index = truncate( addr >> 2 ); + return index; +endfunction + +function CacheLineTag getCacheLineTag( InstReq req ); + Bit#(AddrSz) addr = getAddr(req); + Bit#(CacheLineTagSz) tag = truncate( addr >> fromInteger(valueOf(CacheLineIndexSz)) >> 2 ); + return tag; +endfunction + +function Bit#(AddrSz) getCacheLineAddr( InstReq req ); + Bit#(AddrSz) addr = getAddr(req); + return ((addr >> 2) << 2); +endfunction + +//---------------------------------------------------------------------- +// Main module +//---------------------------------------------------------------------- + +module [CONNECTED_MODULE] mkInstCache( ICache#(InstReq,InstResp) ); + + //----------------------------------------------------------- + // State + + Reg#(CacheStage) stage <- mkReg(Init); + + LUTRAM#(CacheLineIndex,Maybe#(CacheLineTag)) cacheTagRam <- mkLUTRAMU_RegFile(); + LUTRAM#(CacheLineIndex,CacheLine) cacheDataRam <- mkLUTRAMU_RegFile(); + + FIFO#(InstReq) reqQ <- mkFIFO(); + FIFOF#(InstResp) respQ <- mkBFIFOF1(); + + FIFO#(MainMemReq) mainMemReqQ <- mkBFIFO1(); + FIFO#(MainMemResp) mainMemRespQ <- mkFIFO(); + + Reg#(CacheLineIndex) initCounter <- mkReg(1); + + // Statistics state + + Reg#(Bool) statsEn <- mkReg(False); + + STAT num_accesses <- mkStatCounter(`STATS_INST_CACHE_NUM_ACCESSES); + STAT num_misses <- mkStatCounter(`STATS_INST_CACHE_NUM_MISSES); + STAT num_evictions <- mkStatCounter(`STATS_INST_CACHE_NUM_EVICTIONS); + + //----------------------------------------------------------- + // Name some wires + + let req = reqQ.first(); + let reqIndex = getCacheLineIndex(req); + let reqTag = getCacheLineTag(req); + let reqCacheLineAddr = getCacheLineAddr(req); + let refill = mainMemRespQ.first(); + + //----------------------------------------------------------- + // Initialize + + rule init ( stage == Init ); + traceTiny("mkInstCacheBlocking", "stage","i"); + initCounter <= initCounter + 1; + cacheTagRam.upd(initCounter,Invalid); + if ( initCounter == 0 ) + stage <= Access; + endrule + + //----------------------------------------------------------- + // Cache access rule + + rule access ( (stage == Access) && respQ.notFull() ); + + // Statistics + + if ( statsEn ) + num_accesses.incr(); + + // Check tag and valid bit to see if this is a hit or a miss + + Maybe#(CacheLineTag) cacheLineTag = cacheTagRam.sub(reqIndex); + + // Handle cache hits ... + + if ( isValid(cacheLineTag) && ( unJust(cacheLineTag) == reqTag ) ) + begin + traceTiny("mkInstCacheBlocking", "hitMiss","h"); + reqQ.deq(); + + case ( req ) matches + + tagged LoadReq .ld : + respQ.enq( LoadResp { tag : ld.tag, data : cacheDataRam.sub(reqIndex) } ); + + tagged StoreReq .st : + $display( " RTL-ERROR : %m : Stores are not allowed on the inst port!" ); + + endcase + + end + + // Handle cache misses - since lines in instruction cache are + // never dirty we can always immediately issue a refill request + + else + begin + traceTiny("mkInstCacheBlocking", "hitMiss","m"); + if ( statsEn ) + num_misses.incr(); + if ( statsEn ) + if ( isJust(cacheLineTag) ) + num_evictions.incr(); + + MainMemReq rfReq + = LoadReq { tag : 0, + addr : reqCacheLineAddr }; + + mainMemReqQ.enq(rfReq); + stage <= RefillResp; + end + + endrule + + //----------------------------------------------------------- + // Refill response rule + + rule refillResp ( stage == RefillResp ); + traceTiny("mkInstCacheBlocking", "stage","R"); + traceTiny("mkInstCacheBlocking", "refill",refill); + + // Write the new data into the cache and update the tag + + mainMemRespQ.deq(); + case ( mainMemRespQ.first() ) matches + + tagged LoadResp .ld : + begin + cacheTagRam.upd(reqIndex,Valid(reqTag)); + cacheDataRam.upd(reqIndex,ld.data); + end + + tagged StoreResp .st : + noAction; + + endcase + + stage <= Access; + endrule + + //----------------------------------------------------------- + // Methods + + interface Client mmem_client; + interface Get request = fifoToGet(mainMemReqQ); + interface Put response = fifoToPut(mainMemRespQ); + endinterface + + interface Server proc_server; + interface Put request = tracePut("mkInstCacheBlocking", "reqTiny",fifoToPut(reqQ)); + interface Get response = traceGet("mkInstCacheBlocking", "respTiny",fifofToGet(respQ)); + endinterface + + interface Put statsEn_put = regToPut(statsEn); + +endmodule + diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/lab4/MemArb.bsv --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/lab4/MemArb.bsv Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,139 @@ +// The MIT License + +// Copyright (c) 2009 Massachusetts Institute of Technology + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import Connectable::*; +import GetPut::*; +import ClientServer::*; +import FIFOF::*; +import FIFO::*; + +// Local includes +`include "asim/provides/processor_library.bsh" + +interface MemArb; + + interface Server#(MainMemReq,MainMemResp) cache0_server; + interface Server#(MainMemReq,MainMemResp) cache1_server; + interface Client#(MainMemReq,MainMemResp) mmem_client; + +endinterface + +typedef enum { REQ0, REQ1 } ReqPtr deriving(Eq,Bits); + +module mkMemArb( MemArb ); + + //----------------------------------------------------------- + // State + + FIFOF#(MainMemReq) req0Q <- mkBFIFOF1(); + FIFO#(MainMemResp) resp0Q <- mkBFIFO1(); + + FIFOF#(MainMemReq) req1Q <- mkBFIFOF1(); + FIFO#(MainMemResp) resp1Q <- mkBFIFO1(); + + FIFO#(MainMemReq) mreqQ <- mkBFIFO1(); + FIFO#(MainMemResp) mrespQ <- mkBFIFO1(); + + Reg#(ReqPtr) nextReq <- mkReg(REQ0); + + //----------------------------------------------------------- + // Some wires + + let req0avail = req0Q.notEmpty(); + let req1avail = req1Q.notEmpty(); + + //----------------------------------------------------------- + // Rules + + rule chooseReq0 ( req0avail && (!req1avail || (nextReq == REQ0)) ); + traceTiny("mkMemArb", "memArb req0",req0Q.first()); + + // Rewrite tag field if this is a load ... + MainMemReq mreq + = case ( req0Q.first() ) matches + tagged LoadReq .ld : return LoadReq { tag:0, addr:ld.addr }; + tagged StoreReq .st : return req0Q.first(); + endcase; + + // Send out the request + mreqQ.enq(mreq); + nextReq <= REQ1; + req0Q.deq(); + + endrule + + rule chooseReq1 ( req1avail && (!req0avail || (nextReq == REQ1)) ); + traceTiny("mkMemArb", "memArb req1",req1Q.first); + + // Rewrite tag field if this is a load ... + MainMemReq mreq + = case ( req1Q.first() ) matches + tagged LoadReq .ld : return LoadReq { tag:1, addr:ld.addr }; + tagged StoreReq .st : return req1Q.first(); + endcase; + + // Send out the request + mreqQ.enq(mreq); + nextReq <= REQ0; + req1Q.deq(); + + endrule + + rule returnResp; + traceTiny("mkMemArb", "resp",mrespQ.first()); + + // Use tag to figure out where to send response + mrespQ.deq(); + let tag + = case ( mrespQ.first() ) matches + tagged LoadResp .ld : return ld.tag; + tagged StoreResp .st : return st.tag; + endcase; + + if ( tag == 0 ) + resp0Q.enq(mrespQ.first()); + else + resp1Q.enq(mrespQ.first()); + + endrule + + //----------------------------------------------------------- + // Methods + + interface Server cache0_server; + interface Put request = fifofToPut(req0Q); + interface Get response = fifoToGet(resp0Q); + endinterface + + interface Server cache1_server; + interface Put request = fifofToPut(req1Q); + interface Get response = fifoToGet(resp1Q); + endinterface + + interface Client mmem_client; + interface Get request = fifoToGet(mreqQ); + interface Put response = fifoToPut(mrespQ); + endinterface + +endmodule + + diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/lab4/MemTypes.bsv --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/lab4/MemTypes.bsv Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,92 @@ +import Trace::*; + +//---------------------------------------------------------------------- +// Basic memory requests and responses +//---------------------------------------------------------------------- + +typedef union tagged +{ + struct { Bit#(addrSz) addr; Bit#(tagSz) tag; } LoadReq; + struct { Bit#(addrSz) addr; Bit#(tagSz) tag; Bit#(dataSz) data; } StoreReq; +} +MemReq#( type addrSz, type tagSz, type dataSz ) +deriving(Eq,Bits); + +typedef union tagged +{ + struct { Bit#(tagSz) tag; Bit#(dataSz) data; } LoadResp; + struct { Bit#(tagSz) tag; } StoreResp; +} +MemResp#( type tagSz, type dataSz ) +deriving(Eq,Bits); + +//---------------------------------------------------------------------- +// Specialized req/resp for inst/data/host +//---------------------------------------------------------------------- + +typedef 32 AddrSz; +typedef 08 TagSz; +typedef 32 DataSz; +typedef 32 InstSz; +typedef 32 HostDataSz; + +typedef MemReq#(AddrSz,TagSz,0) InstReq; +typedef MemResp#(TagSz,InstSz) InstResp; + +typedef MemReq#(AddrSz,TagSz,DataSz) DataReq; +typedef MemResp#(TagSz,DataSz) DataResp; + +typedef MemReq#(AddrSz,TagSz,HostDataSz) HostReq; +typedef MemResp#(TagSz,HostDataSz) HostResp; + +//---------------------------------------------------------------------- +// Specialized req/resp for main memory +//---------------------------------------------------------------------- + +typedef 32 MainMemAddrSz; +typedef 08 MainMemTagSz; +typedef 32 MainMemDataSz; + +typedef MemReq#(MainMemAddrSz,MainMemTagSz,MainMemDataSz) MainMemReq; +typedef MemResp#(MainMemTagSz,MainMemDataSz) MainMemResp; + +//---------------------------------------------------------------------- +// Tracing Functions +//---------------------------------------------------------------------- + +instance Traceable#(MemReq#(a,b,c)); + + function Action traceTiny( String loc, String ttag, MemReq#(a,b,c) req ); + case ( req ) matches + tagged LoadReq .ld : $fdisplay(stderr, " => %s:%s l%2x", loc, ttag, ld.tag ); + tagged StoreReq .st : $fdisplay(stderr, " => %s:%s s%2x", loc, ttag, st.tag ); + endcase + endfunction + + function Action traceFull( String loc, String ttag, MemReq#(a,b,c) req ); + case ( req ) matches + tagged LoadReq .ld : $fdisplay(stderr, " => %s:%s Ld { addr=%x, tag=%x }", loc, ttag, ld.addr, ld.tag ); + tagged StoreReq .st : $fdisplay(stderr, " => %s:%s St { addr=%x, tag=%x, data=%x }", loc, ttag, st.addr, st.tag, st.data ); + endcase + endfunction + +endinstance + +instance Traceable#(MemResp#(a,b)); + + function Action traceTiny( String loc, String ttag, MemResp#(a,b) resp ); + case ( resp ) matches + tagged LoadResp .ld : $fdisplay(stderr, " => %s:%s l%2x", loc, ttag, ld.tag ); + tagged StoreResp .st : $fdisplay(stderr, " => %s:%s s%2x", loc, ttag, st.tag ); + endcase + endfunction + + function Action traceFull( String loc, String ttag, MemResp#(a,b) resp ); + case ( resp ) matches + tagged LoadResp .ld : $fdisplay(stderr, " => %s:%s Ld { tag=%x, data=%x }", loc, ttag, ld.tag, ld.data ); + tagged StoreResp .st : $fdisplay(stderr, " => %s:%s St { tag=%x }", loc, ttag, st.tag ); + endcase + endfunction + +endinstance + diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/lab4/Proc.bsv --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/lab4/Proc.bsv Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,342 @@ +import CBusUtils::*; +import Register::*; + +import Trace::*; +import MemTypes::*; +import IProc::*; +import ProcTypes::*; +import FPGATypes::*; +import RegFile::*; +import FIFO::*; +import BFIFO::*; +import Assert::*; + +import GetPut::*; +import GetPutExt::*; +import ClientServer::*; +import CBus::*; + + +interface IProc; + + // Interface for testrig + interface Put#(Bit#(8)) testrig_fromhost; + interface Get#(Bit#(8)) testrig_tohost; + + // Interface from processor to caches + interface Client#(DataReq,DataResp) dmem_client; + interface Client#(InstReq,InstResp) imem_client; + + // Interface for enabling/disabling statistics on the rest of the core + interface Get#(Bool) statsEn_get; + +endinterface + + +typedef enum { PCgen, Exec, Writeback } Stage deriving(Eq,Bits); + +//----------------------------------------------------------- +// Register file module +//----------------------------------------------------------- + +interface RFile; + method Action wr( Rindx rindx, Bit#(32) data ); + method Bit#(32) rd1( Rindx rindx ); + method Bit#(32) rd2( Rindx rindx ); +endinterface + +module mkRFile( RFile ); + + RegFile#(Rindx,Bit#(32)) rfile <- mkRegFileFull(); + + method Action wr( Rindx rindx, Bit#(32) data ); + rfile.upd( rindx, data ); + endmethod + + method Bit#(32) rd1( Rindx rindx ); + return ( rindx == 0 ) ? 0 : rfile.sub(rindx); + endmethod + + method Bit#(32) rd2( Rindx rindx ); + return ( rindx == 0 ) ? 0 : rfile.sub(rindx); + endmethod + +endmodule + +//----------------------------------------------------------- +// Helper functions +//----------------------------------------------------------- + +function Bit#(32) slt( Bit#(32) val1, Bit#(32) val2 ); + return zeroExtend( pack( signedLT(val1,val2) ) ); +endfunction + +function Bit#(32) sltu( Bit#(32) val1, Bit#(32) val2 ); + return zeroExtend( pack( val1 < val2 ) ); +endfunction + +function Bit#(32) rshft( Bit#(32) val ); + return zeroExtend(val[4:0]); +endfunction + +//----------------------------------------------------------- +// Reference processor +//----------------------------------------------------------- + + +module [ModWithCBus#(AvalonAddressWidth,AvalonDataWidth)] mkProc( IProc ); + + //----------------------------------------------------------- + // State + + // Standard processor state + + Reg#(Addr) pc <- mkReg(32'h00001000); + Reg#(Stage) stage <- mkReg(PCgen); + RFile rf <- mkRFile; + + // Coprocessor state + + Reg#(Bit#(8)) cp0_tohost <- mkReg(0); + mkCBusWideRegRW(valueof(ToHostRegAddr),cp0_tohost); + Reg#(Bit#(8)) cp0_fromhost <- mkReg(0); + mkCBusWideRegRW(valueof(FromHostRegAddr),cp0_fromhost); + Reg#(Bool) cp0_statsEn <- mkReg(False); + mkCBusWideRegRW(valueof(StatsEnRegAddr),cp0_statsEn); + // Memory request/response state + + FIFO#(InstReq) instReqQ <- mkBFIFO1(); + FIFO#(InstResp) instRespQ <- mkFIFO(); + + FIFO#(DataReq) dataReqQ <- mkBFIFO1(); + FIFO#(DataResp) dataRespQ <- mkFIFO(); + + // Statistics state + + Reg#(Int#(25)) num_cycles <- mkReg(25'h0); + Reg#(Int#(25)) num_inst <- mkReg(25'h0); + + //----------------------------------------------------------- + // Rules + + let pc_plus4 = pc + 4; + + rule pcgen ( stage == PCgen ); + traceTiny("pc",pc); + traceTiny("stage","P"); + instReqQ.enq( LoadReq{ addr:pc, tag:0 } ); + stage <= Exec; + endrule + + rule exec ( stage == Exec ); + + // Some abbreviations + let sext = signExtend; + let zext = zeroExtend; + let sra = signedShiftRight; + + // Get the instruction + + instRespQ.deq(); + Instr inst + = case ( instRespQ.first() ) matches + tagged LoadResp .ld : return unpack(ld.data); + tagged StoreResp .st : return ?; + endcase; + + // Some default variables + Stage next_stage = PCgen; + Addr next_pc = pc_plus4; + + // Tracing + traceTiny("stage","X"); + traceTiny("exInstTiny",inst); + traceFull("exInstFull",inst); + + case ( inst ) matches + + // -- Memory Ops ------------------------------------------------ + + tagged LW .it : + begin + Addr addr = rf.rd1(it.rbase) + sext(it.offset); + dataReqQ.enq( LoadReq{ addr:addr, tag:zeroExtend(it.rdst) } ); + next_stage = Writeback; + end + + tagged SW .it : + begin + Addr addr = rf.rd1(it.rbase) + sext(it.offset); + dataReqQ.enq( StoreReq{ tag:0, addr:addr, data:rf.rd1(it.rsrc) } ); + next_stage = Writeback; + end + + // -- Simple Ops ------------------------------------------------ + + tagged ADDIU .it : rf.wr( it.rdst, rf.rd1(it.rsrc) + sext(it.imm) ); + tagged SLTI .it : rf.wr( it.rdst, slt( rf.rd1(it.rsrc), sext(it.imm) ) ); + tagged SLTIU .it : rf.wr( it.rdst, sltu( rf.rd1(it.rsrc), sext(it.imm) ) ); + tagged ANDI .it : + begin + Bit#(32) zext_it_imm = zext(it.imm); + rf.wr( it.rdst, rf.rd1(it.rsrc) & zext_it_imm ); + end + tagged ORI .it : + begin + Bit#(32) zext_it_imm = zext(it.imm); + rf.wr( it.rdst, rf.rd1(it.rsrc) | zext_it_imm ); + end + tagged XORI .it : + begin + Bit#(32) zext_it_imm = zext(it.imm); + rf.wr( it.rdst, rf.rd1(it.rsrc) ^ zext_it_imm ); + end + tagged LUI .it : + begin + Bit#(32) zext_it_imm = zext(it.imm); + rf.wr( it.rdst, (zext_it_imm << 32'd16) ); + end + + tagged SLL .it : + begin + Bit#(32) zext_it_shamt = zext(it.shamt); + rf.wr( it.rdst, rf.rd1(it.rsrc) << zext_it_shamt ); + end + tagged SRL .it : + begin + Bit#(32) zext_it_shamt = zext(it.shamt); + rf.wr( it.rdst, rf.rd1(it.rsrc) >> zext_it_shamt ); + end + tagged SRA .it : + begin + Bit#(32) zext_it_shamt = zext(it.shamt); + rf.wr( it.rdst, sra( rf.rd1(it.rsrc), zext_it_shamt )); + end + tagged SLLV .it : rf.wr( it.rdst, rf.rd1(it.rsrc) << rshft(rf.rd2(it.rshamt)) ); + tagged SRLV .it : rf.wr( it.rdst, rf.rd1(it.rsrc) >> rshft(rf.rd2(it.rshamt)) ); + tagged SRAV .it : rf.wr( it.rdst, sra( rf.rd1(it.rsrc), rshft(rf.rd2(it.rshamt)) ) ); + tagged ADDU .it : rf.wr( it.rdst, rf.rd1(it.rsrc1) + rf.rd2(it.rsrc2) ); + tagged SUBU .it : rf.wr( it.rdst, rf.rd1(it.rsrc1) - rf.rd2(it.rsrc2) ); + tagged AND .it : rf.wr( it.rdst, rf.rd1(it.rsrc1) & rf.rd2(it.rsrc2) ); + tagged OR .it : rf.wr( it.rdst, rf.rd1(it.rsrc1) | rf.rd2(it.rsrc2) ); + tagged XOR .it : rf.wr( it.rdst, rf.rd1(it.rsrc1) ^ rf.rd2(it.rsrc2) ); + tagged NOR .it : rf.wr( it.rdst, ~(rf.rd1(it.rsrc1) | rf.rd2(it.rsrc2)) ); + tagged SLT .it : rf.wr( it.rdst, slt( rf.rd1(it.rsrc1), rf.rd2(it.rsrc2) ) ); + tagged SLTU .it : rf.wr( it.rdst, sltu( rf.rd1(it.rsrc1), rf.rd2(it.rsrc2) ) ); + + // -- Branches -------------------------------------------------- + + tagged BLEZ .it : + if ( signedLE( rf.rd1(it.rsrc), 0 ) ) + next_pc = pc_plus4 + (sext(it.offset) << 2); + + tagged BGTZ .it : + if ( signedGT( rf.rd1(it.rsrc), 0 ) ) + next_pc = pc_plus4 + (sext(it.offset) << 2); + + tagged BLTZ .it : + if ( signedLT( rf.rd1(it.rsrc), 0 ) ) + next_pc = pc_plus4 + (sext(it.offset) << 2); + + tagged BGEZ .it : + if ( signedGE( rf.rd1(it.rsrc), 0 ) ) + next_pc = pc_plus4 + (sext(it.offset) << 2); + + tagged BEQ .it : + if ( rf.rd1(it.rsrc1) == rf.rd2(it.rsrc2) ) + next_pc = pc_plus4 + (sext(it.offset) << 2); + + tagged BNE .it : + if ( rf.rd1(it.rsrc1) != rf.rd2(it.rsrc2) ) + next_pc = pc_plus4 + (sext(it.offset) << 2); + + // -- Jumps ----------------------------------------------------- + + tagged J .it : + next_pc = { pc_plus4[31:28], it.target, 2'b0 }; + + tagged JR .it : + next_pc = rf.rd1(it.rsrc); + + tagged JAL .it : + begin + rf.wr( 31, pc_plus4 ); + next_pc = { pc_plus4[31:28], it.target, 2'b0 }; + end + + tagged JALR .it : + begin + rf.wr( it.rdst, pc_plus4 ); + next_pc = rf.rd1(it.rsrc); + end + + // -- Cop0 ------------------------------------------------------ + + tagged MTC0 .it : + case ( it.cop0dst ) + 5'd10 : cp0_statsEn <= unpack(truncate(rf.rd1(it.rsrc))); + 5'd21 : cp0_tohost <= truncate(rf.rd1(it.rsrc)); + default : + $display( " RTL-ERROR : %m : Illegal MTC0 cop0dst register!" ); + endcase + + tagged MFC0 .it : + case ( it.cop0src ) + 5'd10 : rf.wr( it.rdst, zext(pack(cp0_statsEn)) ); + 5'd20 : rf.wr( it.rdst, zext(cp0_fromhost) ); + 5'd21 : rf.wr( it.rdst, zext(cp0_tohost) ); + default : + $display( " RTL-ERROR : %m : Illegal MFC0 cop0src register!" ); + endcase + + // -- Illegal --------------------------------------------------- + + default : + $display( " RTL-ERROR : %m : Illegal instruction !" ); + + endcase + + stage <= next_stage; + pc <= next_pc; + + if ( cp0_statsEn ) + num_inst <= num_inst + 1; + + endrule + + rule writeback ( stage == Writeback ); + traceTiny("stage","W"); + + dataRespQ.deq(); + case ( dataRespQ.first() ) matches + tagged LoadResp .ld : rf.wr( truncate(ld.tag), ld.data ); + tagged StoreResp .st : noAction; + endcase + + stage <= PCgen; + endrule + + rule inc_num_cycles; + if ( cp0_statsEn ) + num_cycles <= num_cycles + 1; + endrule + + //----------------------------------------------------------- + // Methods + + interface Client imem_client; + interface Get request = fifoToGet(instReqQ); + interface Put response = fifoToPut(instRespQ); + endinterface + + interface Client dmem_client; + interface Get request = fifoToGet(dataReqQ); + interface Put response = fifoToPut(dataRespQ); + endinterface + + interface Get testrig_tohost = regToGet(cp0_tohost); + interface Put testrig_fromhost = regToPut(cp0_fromhost); + interface Get statsEn_get = regToGet(cp0_statsEn); + +endmodule + diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/lab4/ProcTypes.bsv --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/lab4/ProcTypes.bsv Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,375 @@ + +import Trace::*; + +//---------------------------------------------------------------------- +// Other typedefs +//---------------------------------------------------------------------- + +typedef Bit#(32) Addr; +typedef Int#(18) Stat; + +//---------------------------------------------------------------------- +// Basic instruction type +//---------------------------------------------------------------------- + +typedef Bit#(5) Rindx; +typedef Bit#(16) Simm; +typedef Bit#(16) Zimm; +typedef Bit#(8) Epoch; +typedef Bit#(5) Shamt; +typedef Bit#(26) Target; +typedef Bit#(5) CP0indx; +typedef Bit#(32) Data; + +typedef enum +{ + Taken, + NotTaken +} + Direction + deriving(Bits,Eq); + + +//---------------------------------------------------------------------- +// Pipeline typedefs +//---------------------------------------------------------------------- + +typedef union tagged +{ + Tuple2#(Rindx,Data) ALUWB; + Rindx MemWB; + Tuple2#(Rindx,Data) CoWB; +} + WritebackType + deriving(Bits,Eq); + +//////////////////////// +// I Add Writeback queue type +//////////// +typedef union tagged +{ + struct {Bit#(32) data; Rindx dest; } WB_ALU; + Bit#(32) WB_Host; + Rindx WB_Load; + void WB_Store; +} +WBResult deriving(Eq, Bits); + +typedef struct{Addr qpc; Addr qnxtpc; Epoch qepoch;} PCStat deriving(Eq, Bits); +//typedef struct{Addr qpc; Epoch qepoch;} PCStat deriving(Eq, Bits); + +typedef union tagged +{ + + struct { Rindx rbase; Rindx rdst; Simm offset; } LW; + struct { Rindx rbase; Rindx rsrc; Simm offset; } SW; + + struct { Rindx rsrc; Rindx rdst; Simm imm; } ADDIU; + struct { Rindx rsrc; Rindx rdst; Simm imm; } SLTI; + struct { Rindx rsrc; Rindx rdst; Simm imm; } SLTIU; + struct { Rindx rsrc; Rindx rdst; Zimm imm; } ANDI; + struct { Rindx rsrc; Rindx rdst; Zimm imm; } ORI; + struct { Rindx rsrc; Rindx rdst; Zimm imm; } XORI; + struct { Rindx rdst; Zimm imm; } LUI; + + struct { Rindx rsrc; Rindx rdst; Shamt shamt; } SLL; + struct { Rindx rsrc; Rindx rdst; Shamt shamt; } SRL; + struct { Rindx rsrc; Rindx rdst; Shamt shamt; } SRA; + struct { Rindx rsrc; Rindx rdst; Rindx rshamt; } SLLV; + struct { Rindx rsrc; Rindx rdst; Rindx rshamt; } SRLV; + struct { Rindx rsrc; Rindx rdst; Rindx rshamt; } SRAV; + struct { Rindx rsrc1; Rindx rsrc2; Rindx rdst; } ADDU; + struct { Rindx rsrc1; Rindx rsrc2; Rindx rdst; } SUBU; + struct { Rindx rsrc1; Rindx rsrc2; Rindx rdst; } AND; + struct { Rindx rsrc1; Rindx rsrc2; Rindx rdst; } OR; + struct { Rindx rsrc1; Rindx rsrc2; Rindx rdst; } XOR; + struct { Rindx rsrc1; Rindx rsrc2; Rindx rdst; } NOR; + struct { Rindx rsrc1; Rindx rsrc2; Rindx rdst; } SLT; + struct { Rindx rsrc1; Rindx rsrc2; Rindx rdst; } SLTU; + + struct { Target target; } J; + struct { Target target; } JAL; + struct { Rindx rsrc; } JR; + struct { Rindx rsrc; Rindx rdst; } JALR; + struct { Rindx rsrc1; Rindx rsrc2; Simm offset; } BEQ; + struct { Rindx rsrc1; Rindx rsrc2; Simm offset; } BNE; + struct { Rindx rsrc; Simm offset; } BLEZ; + struct { Rindx rsrc; Simm offset; } BGTZ; + struct { Rindx rsrc; Simm offset; } BLTZ; + struct { Rindx rsrc; Simm offset; } BGEZ; + + struct { Rindx rdst; CP0indx cop0src; } MFC0; + struct { Rindx rsrc; CP0indx cop0dst; } MTC0; + + void ILLEGAL; + +} +Instr deriving(Eq); + +//---------------------------------------------------------------------- +// Pack and Unpack +//---------------------------------------------------------------------- + +Bit#(6) opFUNC = 6'b000000; Bit#(6) fcSLL = 6'b000000; +Bit#(6) opRT = 6'b000001; Bit#(6) fcSRL = 6'b000010; +Bit#(6) opRS = 6'b010000; Bit#(6) fcSRA = 6'b000011; + Bit#(6) fcSLLV = 6'b000100; +Bit#(6) opLW = 6'b100011; Bit#(6) fcSRLV = 6'b000110; +Bit#(6) opSW = 6'b101011; Bit#(6) fcSRAV = 6'b000111; + Bit#(6) fcADDU = 6'b100001; +Bit#(6) opADDIU = 6'b001001; Bit#(6) fcSUBU = 6'b100011; +Bit#(6) opSLTI = 6'b001010; Bit#(6) fcAND = 6'b100100; +Bit#(6) opSLTIU = 6'b001011; Bit#(6) fcOR = 6'b100101; +Bit#(6) opANDI = 6'b001100; Bit#(6) fcXOR = 6'b100110; +Bit#(6) opORI = 6'b001101; Bit#(6) fcNOR = 6'b100111; +Bit#(6) opXORI = 6'b001110; Bit#(6) fcSLT = 6'b101010; +Bit#(6) opLUI = 6'b001111; Bit#(6) fcSLTU = 6'b101011; + +Bit#(6) opJ = 6'b000010; +Bit#(6) opJAL = 6'b000011; +Bit#(6) fcJR = 6'b001000; +Bit#(6) fcJALR = 6'b001001; +Bit#(6) opBEQ = 6'b000100; +Bit#(6) opBNE = 6'b000101; +Bit#(6) opBLEZ = 6'b000110; +Bit#(6) opBGTZ = 6'b000111; +Bit#(5) rtBLTZ = 5'b00000; +Bit#(5) rtBGEZ = 5'b00001; + +Bit#(5) rsMFC0 = 5'b00000; +Bit#(5) rsMTC0 = 5'b00100; + +instance Bits#(Instr,32); + + // Pack Function + + function Bit#(32) pack( Instr instr ); + + case ( instr ) matches + + tagged LW .it : return { opLW, it.rbase, it.rdst, it.offset }; + tagged SW .it : return { opSW, it.rbase, it.rsrc, it.offset }; + + tagged ADDIU .it : return { opADDIU, it.rsrc, it.rdst, it.imm }; + tagged SLTI .it : return { opSLTI, it.rsrc, it.rdst, it.imm }; + tagged SLTIU .it : return { opSLTIU, it.rsrc, it.rdst, it.imm }; + tagged ANDI .it : return { opANDI, it.rsrc, it.rdst, it.imm }; + tagged ORI .it : return { opORI, it.rsrc, it.rdst, it.imm }; + tagged XORI .it : return { opXORI, it.rsrc, it.rdst, it.imm }; + tagged LUI .it : return { opLUI, 5'b0, it.rdst, it.imm }; + + tagged SLL .it : return { opFUNC, 5'b0, it.rsrc, it.rdst, it.shamt, fcSLL }; + tagged SRL .it : return { opFUNC, 5'b0, it.rsrc, it.rdst, it.shamt, fcSRL }; + tagged SRA .it : return { opFUNC, 5'b0, it.rsrc, it.rdst, it.shamt, fcSRA }; + + tagged SLLV .it : return { opFUNC, it.rshamt, it.rsrc, it.rdst, 5'b0, fcSLLV }; + tagged SRLV .it : return { opFUNC, it.rshamt, it.rsrc, it.rdst, 5'b0, fcSRLV }; + tagged SRAV .it : return { opFUNC, it.rshamt, it.rsrc, it.rdst, 5'b0, fcSRAV }; + + tagged ADDU .it : return { opFUNC, it.rsrc1, it.rsrc2, it.rdst, 5'b0, fcADDU }; + tagged SUBU .it : return { opFUNC, it.rsrc1, it.rsrc2, it.rdst, 5'b0, fcSUBU }; + tagged AND .it : return { opFUNC, it.rsrc1, it.rsrc2, it.rdst, 5'b0, fcAND }; + tagged OR .it : return { opFUNC, it.rsrc1, it.rsrc2, it.rdst, 5'b0, fcOR }; + tagged XOR .it : return { opFUNC, it.rsrc1, it.rsrc2, it.rdst, 5'b0, fcXOR }; + tagged NOR .it : return { opFUNC, it.rsrc1, it.rsrc2, it.rdst, 5'b0, fcNOR }; + tagged SLT .it : return { opFUNC, it.rsrc1, it.rsrc2, it.rdst, 5'b0, fcSLT }; + tagged SLTU .it : return { opFUNC, it.rsrc1, it.rsrc2, it.rdst, 5'b0, fcSLTU }; + + tagged J .it : return { opJ, it.target }; + tagged JAL .it : return { opJAL, it.target }; + tagged JR .it : return { opFUNC, it.rsrc, 5'b0, 5'b0, 5'b0, fcJR }; + tagged JALR .it : return { opFUNC, it.rsrc, 5'b0, it.rdst, 5'b0, fcJALR }; + tagged BEQ .it : return { opBEQ, it.rsrc1, it.rsrc2, it.offset }; + tagged BNE .it : return { opBNE, it.rsrc1, it.rsrc2, it.offset }; + tagged BLEZ .it : return { opBLEZ, it.rsrc, 5'b0, it.offset }; + tagged BGTZ .it : return { opBGTZ, it.rsrc, 5'b0, it.offset }; + tagged BLTZ .it : return { opRT, it.rsrc, rtBLTZ, it.offset }; + tagged BGEZ .it : return { opRT, it.rsrc, rtBGEZ, it.offset }; + + tagged MFC0 .it : return { opRS, rsMFC0, it.rdst, it.cop0src, 11'b0 }; + tagged MTC0 .it : return { opRS, rsMTC0, it.rsrc, it.cop0dst, 11'b0 }; + + endcase + + endfunction + + // Unpack Function + + function Instr unpack( Bit#(32) instrBits ); + + let opcode = instrBits[ 31 : 26 ]; + let rs = instrBits[ 25 : 21 ]; + let rt = instrBits[ 20 : 16 ]; + let rd = instrBits[ 15 : 11 ]; + let shamt = instrBits[ 10 : 6 ]; + let funct = instrBits[ 5 : 0 ]; + let imm = instrBits[ 15 : 0 ]; + let target = instrBits[ 25 : 0 ]; + + case ( opcode ) + + opLW : return LW { rbase:rs, rdst:rt, offset:imm }; + opSW : return SW { rbase:rs, rsrc:rt, offset:imm }; + opADDIU : return ADDIU { rsrc:rs, rdst:rt, imm:imm }; + opSLTI : return SLTI { rsrc:rs, rdst:rt, imm:imm }; + opSLTIU : return SLTIU { rsrc:rs, rdst:rt, imm:imm }; + opANDI : return ANDI { rsrc:rs, rdst:rt, imm:imm }; + opORI : return ORI { rsrc:rs, rdst:rt, imm:imm }; + opXORI : return XORI { rsrc:rs, rdst:rt, imm:imm }; + opLUI : return LUI { rdst:rt, imm:imm }; + opJ : return J { target:target }; + opJAL : return JAL { target:target }; + opBEQ : return BEQ { rsrc1:rs, rsrc2:rt, offset:imm }; + opBNE : return BNE { rsrc1:rs, rsrc2:rt, offset:imm }; + opBLEZ : return BLEZ { rsrc:rs, offset:imm }; + opBGTZ : return BGTZ { rsrc:rs, offset:imm }; + + opFUNC : + case ( funct ) + fcSLL : return SLL { rsrc:rt, rdst:rd, shamt:shamt }; + fcSRL : return SRL { rsrc:rt, rdst:rd, shamt:shamt }; + fcSRA : return SRA { rsrc:rt, rdst:rd, shamt:shamt }; + fcSLLV : return SLLV { rsrc:rt, rdst:rd, rshamt:rs }; + fcSRLV : return SRLV { rsrc:rt, rdst:rd, rshamt:rs }; + fcSRAV : return SRAV { rsrc:rt, rdst:rd, rshamt:rs }; + fcADDU : return ADDU { rsrc1:rs, rsrc2:rt, rdst:rd }; + fcSUBU : return SUBU { rsrc1:rs, rsrc2:rt, rdst:rd }; + fcAND : return AND { rsrc1:rs, rsrc2:rt, rdst:rd }; + fcOR : return OR { rsrc1:rs, rsrc2:rt, rdst:rd }; + fcXOR : return XOR { rsrc1:rs, rsrc2:rt, rdst:rd }; + fcNOR : return NOR { rsrc1:rs, rsrc2:rt, rdst:rd }; + fcSLT : return SLT { rsrc1:rs, rsrc2:rt, rdst:rd }; + fcSLTU : return SLTU { rsrc1:rs, rsrc2:rt, rdst:rd }; + fcJR : return JR { rsrc:rs }; + fcJALR : return JALR { rsrc:rs, rdst:rd }; + default : return ILLEGAL; + endcase + + opRT : + case ( rt ) + rtBLTZ : return BLTZ { rsrc:rs, offset:imm }; + rtBGEZ : return BGEZ { rsrc:rs, offset:imm }; + default : return ILLEGAL; + endcase + + opRS : + case ( rs ) + rsMFC0 : return MFC0 { rdst:rt, cop0src:rd }; + rsMTC0 : return MTC0 { rsrc:rt, cop0dst:rd }; + default : return ILLEGAL; + endcase + + default : return ILLEGAL; + + endcase + + endfunction + +endinstance + +//---------------------------------------------------------------------- +// Trace +//---------------------------------------------------------------------- + +instance Traceable#(Instr); + + function Action traceTiny( String loc, String ttag, Instr inst ); + case ( inst ) matches + + tagged LW .it : $fdisplay(stderr, " => %s:%s lw", loc, ttag ); + tagged SW .it : $fdisplay(stderr, " => %s:%s sw", loc, ttag ); + + tagged ADDIU .it : $fdisplay(stderr, " => %s:%s addi", loc, ttag ); + tagged SLTI .it : $fdisplay(stderr, " => %s:%s sli", loc, ttag ); + tagged SLTIU .it : $fdisplay(stderr, " => %s:%s sliu", loc, ttag ); + tagged ANDI .it : $fdisplay(stderr, " => %s:%s andi", loc, ttag ); + tagged ORI .it : $fdisplay(stderr, " => %s:%s ori", loc, ttag ); + tagged XORI .it : $fdisplay(stderr, " => %s:%s xori", loc, ttag ); + tagged LUI .it : $fdisplay(stderr, " => %s:%s lui", loc, ttag ); + + tagged SLL .it : $fdisplay(stderr, " => %s:%s sll", loc, ttag ); + tagged SRL .it : $fdisplay(stderr, " => %s:%s srl", loc, ttag ); + tagged SRA .it : $fdisplay(stderr, " => %s:%s sra", loc, ttag ); + tagged SLLV .it : $fdisplay(stderr, " => %s:%s sllv", loc, ttag ); + tagged SRLV .it : $fdisplay(stderr, " => %s:%s srlv", loc, ttag ); + tagged SRAV .it : $fdisplay(stderr, " => %s:%s srav", loc, ttag ); + + tagged ADDU .it : $fdisplay(stderr, " => %s:%s addu", loc, ttag ); + tagged SUBU .it : $fdisplay(stderr, " => %s:%s subu", loc, ttag ); + tagged AND .it : $fdisplay(stderr, " => %s:%s and", loc, ttag ); + tagged OR .it : $fdisplay(stderr, " => %s:%s or", loc, ttag ); + tagged XOR .it : $fdisplay(stderr, " => %s:%s xor", loc, ttag ); + tagged NOR .it : $fdisplay(stderr, " => %s:%s nor", loc, ttag ); + tagged SLT .it : $fdisplay(stderr, " => %s:%s slt", loc, ttag ); + tagged SLTU .it : $fdisplay(stderr, " => %s:%s sltu", loc, ttag ); + + tagged J .it : $fdisplay(stderr, " => %s:%s j", loc, ttag ); + tagged JAL .it : $fdisplay(stderr, " => %s:%s jal", loc, ttag ); + tagged JR .it : $fdisplay(stderr, " => %s:%s jr", loc, ttag ); + tagged JALR .it : $fdisplay(stderr, " => %s:%s jalr", loc, ttag ); + tagged BEQ .it : $fdisplay(stderr, " => %s:%s beq", loc, ttag ); + tagged BNE .it : $fdisplay(stderr, " => %s:%s bne", loc, ttag ); + tagged BLEZ .it : $fdisplay(stderr, " => %s:%s blez", loc, ttag ); + tagged BGTZ .it : $fdisplay(stderr, " => %s:%s bgtz", loc, ttag ); + tagged BLTZ .it : $fdisplay(stderr, " => %s:%s bltz", loc, ttag ); + tagged BGEZ .it : $fdisplay(stderr, " => %s:%s bgez", loc, ttag ); + + tagged MFC0 .it : $fdisplay(stderr, " => %s:%s mfc0", loc, ttag ); + tagged MTC0 .it : $fdisplay(stderr, " => %s:%s mtc0", loc, ttag ); + + tagged ILLEGAL : $fdisplay(stderr, " => %s:%s ill", loc, ttag ); + + endcase + endfunction + + function Action traceFull( String loc, String ttag, Instr inst ); + case ( inst ) matches + + tagged LW .it : $fdisplay(stderr, " => %s:%s lw r%0d, 0x%x(r%0d)", loc, ttag, it.rdst, it.offset, it.rbase ); + tagged SW .it : $fdisplay(stderr, " => %s:%s sw r%0d, 0x%x(r%0d)", loc, ttag, it.rsrc, it.offset, it.rbase ); + + tagged ADDIU .it : $fdisplay(stderr, " => %s:%s addiu r%0d, r%0d, 0x%x", loc, ttag, it.rdst, it.rsrc, it.imm ); + tagged SLTI .it : $fdisplay(stderr, " => %s:%s slti r%0d, r%0d, 0x%x", loc, ttag, it.rdst, it.rsrc, it.imm ); + tagged SLTIU .it : $fdisplay(stderr, " => %s:%s sltiu r%0d, r%0d, 0x%x", loc, ttag, it.rdst, it.rsrc, it.imm ); + tagged ANDI .it : $fdisplay(stderr, " => %s:%s andi r%0d, r%0d, 0x%x", loc, ttag, it.rdst, it.rsrc, it.imm ); + tagged ORI .it : $fdisplay(stderr, " => %s:%s ori r%0d, r%0d, 0x%x", loc, ttag, it.rdst, it.rsrc, it.imm ); + tagged XORI .it : $fdisplay(stderr, " => %s:%s xori r%0d, r%0d, 0x%x", loc, ttag, it.rdst, it.rsrc, it.imm ); + tagged LUI .it : $fdisplay(stderr, " => %s:%s lui r%0d, 0x%x", loc, ttag, it.rdst, it.imm ); + + tagged SLL .it : $fdisplay(stderr, " => %s:%s sll r%0d, r%0d, %0d", loc, ttag, it.rdst, it.rsrc, it.shamt ); + tagged SRL .it : $fdisplay(stderr, " => %s:%s srl r%0d, r%0d, %0d", loc, ttag, it.rdst, it.rsrc, it.shamt ); + tagged SRA .it : $fdisplay(stderr, " => %s:%s sra r%0d, r%0d, %0d", loc, ttag, it.rdst, it.rsrc, it.shamt ); + tagged SLLV .it : $fdisplay(stderr, " => %s:%s sllv r%0d, r%0d, r%0d", loc, ttag, it.rdst, it.rsrc, it.rshamt ); + tagged SRLV .it : $fdisplay(stderr, " => %s:%s srlv r%0d, r%0d, r%0d", loc, ttag, it.rdst, it.rsrc, it.rshamt ); + tagged SRAV .it : $fdisplay(stderr, " => %s:%s srav r%0d, r%0d, r%0d", loc, ttag, it.rdst, it.rsrc, it.rshamt ); + + tagged ADDU .it : $fdisplay(stderr, " => %s:%s addu r%0d, r%0d, r%0d", loc, ttag, it.rdst, it.rsrc1, it.rsrc2 ); + tagged SUBU .it : $fdisplay(stderr, " => %s:%s subu r%0d, r%0d, r%0d", loc, ttag, it.rdst, it.rsrc1, it.rsrc2 ); + tagged AND .it : $fdisplay(stderr, " => %s:%s and r%0d, r%0d, r%0d", loc, ttag, it.rdst, it.rsrc1, it.rsrc2 ); + tagged OR .it : $fdisplay(stderr, " => %s:%s or r%0d, r%0d, r%0d", loc, ttag, it.rdst, it.rsrc1, it.rsrc2 ); + tagged XOR .it : $fdisplay(stderr, " => %s:%s xor r%0d, r%0d, r%0d", loc, ttag, it.rdst, it.rsrc1, it.rsrc2 ); + tagged NOR .it : $fdisplay(stderr, " => %s:%s nor r%0d, r%0d, r%0d", loc, ttag, it.rdst, it.rsrc1, it.rsrc2 ); + tagged SLT .it : $fdisplay(stderr, " => %s:%s slt r%0d, r%0d, r%0d", loc, ttag, it.rdst, it.rsrc1, it.rsrc2 ); + tagged SLTU .it : $fdisplay(stderr, " => %s:%s sltu r%0d, r%0d, r%0d", loc, ttag, it.rdst, it.rsrc1, it.rsrc2 ); + + tagged J .it : $fdisplay(stderr, " => %s:%s j 0x%x", loc, ttag, it.target ); + tagged JAL .it : $fdisplay(stderr, " => %s:%s jal 0x%x", loc, ttag, it.target ); + tagged JR .it : $fdisplay(stderr, " => %s:%s jr r%0d", loc, ttag, it.rsrc ); + tagged JALR .it : $fdisplay(stderr, " => %s:%s jalr r%0d", loc, ttag, it.rsrc ); + tagged BEQ .it : $fdisplay(stderr, " => %s:%s beq r%0d, r%0d, 0x%x", loc, ttag, it.rsrc1, it.rsrc2, it.offset ); + tagged BNE .it : $fdisplay(stderr, " => %s:%s bne r%0d, r%0d, 0x%x", loc, ttag, it.rsrc1, it.rsrc2, it.offset ); + tagged BLEZ .it : $fdisplay(stderr, " => %s:%s blez r%0d, 0x%x", loc, ttag, it.rsrc, it.offset ); + tagged BGTZ .it : $fdisplay(stderr, " => %s:%s bgtz r%0d, 0x%x", loc, ttag, it.rsrc, it.offset ); + tagged BLTZ .it : $fdisplay(stderr, " => %s:%s bltz r%0d, 0x%x", loc, ttag, it.rsrc, it.offset ); + tagged BGEZ .it : $fdisplay(stderr, " => %s:%s bgez r%0d, 0x%x", loc, ttag, it.rsrc, it.offset ); + + tagged MFC0 .it : $fdisplay(stderr, " => %s:%s mfc0 r%0d, cpr%0d", loc, ttag, it.rdst, it.cop0src ); + tagged MTC0 .it : $fdisplay(stderr, " => %s:%s mtc0 r%0d, cpr%0d", loc, ttag, it.rsrc, it.cop0dst ); + + tagged ILLEGAL : $fdisplay(stderr, " => %s:%s illegal instruction", loc, ttag ); + + endcase + endfunction + +endinstance + diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/lab4/Processor.bsv --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/lab4/Processor.bsv Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,590 @@ +/// The MIT License + +// Copyright (c) 2009 Massachusetts Institute of Technology + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import Connectable::*; +import GetPut::*; +import ClientServer::*; +import RegFile::*; + +import FIFO::*; +import FIFOF::*; +import SFIFO::*; +import RWire::*; + +import BFIFO::*; +import MemTypes::*; +import ProcTypes::*; +import BRegFile::*; +import BranchPred::*; +//import PathTypes::*; This is only there to force the debugging + +import Trace::*; + +//AWB includes +`include "asim/provides/low_level_platform_interface.bsh" +`include "asim/provides/soft_connections.bsh" +`include "asim/provides/common_services.bsh" + +// Local includes +`include "asim/provides/processor_library.bsh" +`include "asim/rrr/remote_server_stub_PROCESSORSYSTEMRRR.bsh" +`include "asim/provides/common_services.bsh" +`include "asim/dict/STATS_PROCESSOR.bsh" + +interface ProcStats; + interface Get#(Stat) num_cycles; + interface Get#(Stat) num_inst; +endinterface + +interface CPUToHost; + method Bit#(32) cpuToHost(int req); +endinterface + +interface Proc; + + // Interface from processor to caches + interface Client#(DataReq,DataResp) dmem_client; + interface Client#(InstReq,InstResp) imem_client; + + // Interface for enabling/disabling statistics on the rest of the core + interface Get#(Bool) statsEn_get; + + // Interface for collecting statistics. + interface ProcStats stats; + + // Interface to host + interface CPUToHost tohost; + +endinterface + + +typedef enum { PCgen, Exec, Writeback } Stage deriving(Eq,Bits); + +//----------------------------------------------------------- +// Register file module +//----------------------------------------------------------- + +interface BRFile; + method Action wr( Rindx rindx, Bit#(32) data ); + method Bit#(32) rd1( Rindx rindx ); + method Bit#(32) rd2( Rindx rindx ); +endinterface + +module mkBRFile( BRFile ); + + RegFile#(Rindx,Bit#(32)) rfile <- mkBRegFile(); + + method Action wr( Rindx rindx, Bit#(32) data ); + rfile.upd( rindx, data ); + endmethod + + method Bit#(32) rd1( Rindx rindx ); + return ( rindx == 0 ) ? 0 : rfile.sub(rindx); + endmethod + + method Bit#(32) rd2( Rindx rindx ); + return ( rindx == 0 ) ? 0 : rfile.sub(rindx); + endmethod + +endmodule + +//----------------------------------------------------------- +// Helper functions +//----------------------------------------------------------- + +function Bit#(32) slt( Bit#(32) val1, Bit#(32) val2 ); + return zeroExtend( pack( signedLT(val1,val2) ) ); +endfunction + +function Bit#(32) sltu( Bit#(32) val1, Bit#(32) val2 ); + return zeroExtend( pack( val1 < val2 ) ); +endfunction + +function Bit#(32) rshft( Bit#(32) val ); + return zeroExtend(val[4:0]); +endfunction + + +//----------------------------------------------------------- +// Find funct for wbQ +//----------------------------------------------------------- +function Bool findwbf(Rindx fVal, WBResult cmpVal); + case (cmpVal) matches + tagged WB_ALU {data:.res, dest:.rd} : + return (fVal == rd); + tagged WB_Load .rd : + return (fVal == rd); + tagged WB_Store .st : + return False; + tagged WB_Host .x : + return False; + endcase +endfunction + + +//----------------------------------------------------------- +// Stall funct for wbQ +//----------------------------------------------------------- +function Bool stall(Instr inst, SFIFO#(WBResult, Rindx) f); + case (inst) matches + // -- Memory Ops ------------------------------------------------ + tagged LW .it : + return f.find(it.rbase); + tagged SW {rsrc:.dreg, rbase:.addr, offset:.o} : + return (f.find(addr) || f.find2(dreg)); + + // -- Simple Ops ------------------------------------------------ + tagged ADDIU .it : return f.find(it.rsrc); + tagged SLTI .it : return f.find(it.rsrc); + tagged SLTIU .it : return f.find(it.rsrc); + tagged ANDI .it : return f.find(it.rsrc); + tagged ORI .it : return f.find(it.rsrc); + tagged XORI .it : return f.find(it.rsrc); + + tagged LUI .it : return f.find(it.rdst); //this rds/wrs itself + tagged SLL .it : return f.find(it.rsrc); + tagged SRL .it : return f.find(it.rsrc); + tagged SRA .it : return f.find(it.rsrc); + tagged SLLV .it : return (f.find(it.rsrc) || f.find(it.rshamt)); + tagged SRLV .it : return (f.find(it.rsrc) || f.find(it.rshamt)); + tagged SRAV .it : return (f.find(it.rsrc) || f.find(it.rshamt)); + tagged ADDU .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2)); + tagged SUBU .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2)); + tagged AND .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2)); + tagged OR .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2)); + tagged XOR .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2)); + tagged NOR .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2)); + tagged SLT .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2)); + tagged SLTU .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2)); + + + // -- Branches -------------------------------------------------- + + tagged BLEZ .it : return (f.find(it.rsrc)); + tagged BGTZ .it : return (f.find(it.rsrc)); + tagged BLTZ .it : return (f.find(it.rsrc)); + tagged BGEZ .it : return (f.find(it.rsrc)); + tagged BEQ .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2)); + tagged BNE .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2)); + + // -- Jumps ----------------------------------------------------- + + tagged J .it : return False; + tagged JR .it : return f.find(it.rsrc); + tagged JALR .it : return f.find(it.rsrc); + tagged JAL .it : return False; + + // -- Cop0 ------------------------------------------------------ + + tagged MTC0 .it : return f.find(it.rsrc); + tagged MFC0 .it : return False; + + // -- Illegal --------------------------------------------------- + + default : return False; + + endcase +endfunction +//----------------------------------------------------------- +// Reference processor +//----------------------------------------------------------- + + +//(* doc = "synthesis attribute ram_style mkProc distributed;" *) +//(* synthesize *) + +module [CONNECTED_MODULE] mkProc( Proc ); + + //----------------------------------------------------------- + // Debug port + + ServerStub_PROCESSORSYSTEMRRR server_stub <- mkServerStub_PROCESSORSYSTEMRRR(); + + + //----------------------------------------------------------- + // State + + // Standard processor state + + Reg#(Addr) pc <- mkReg(32'h00001000); + Reg#(Epoch) epoch <- mkReg(0); + Reg#(Stage) stage <- mkReg(PCgen); + BRFile rf <- mkBRFile; + + // Branch Prediction + BranchPred bp <- mkBranchPred(); + FIFO#(PCStat) execpc <- mkLFIFO(); + + // Pipelines + FIFO#(PCStat) pcQ <-mkSizedFIFO(3); + SFIFO#(WBResult, Rindx) wbQ <-mkSFIFO(findwbf); + + Reg#(Bit#(32)) cp0_tohost <- mkReg(0); + Reg#(Bit#(32)) cp0_fromhost <- mkReg(0); + Reg#(Bool) cp0_statsEn <- mkReg(False); + + // Memory request/response state + + FIFO#(InstReq) instReqQ <- mkBFIFO1(); + FIFO#(InstResp) instRespQ <- mkFIFO(); + + FIFO#(DataReq) dataReqQ <- mkBFIFO1(); + FIFO#(DataResp) dataRespQ <- mkFIFO(); + + // Statistics state + Reg#(Stat) num_cycles <- mkReg(0); + Reg#(Stat) num_inst <- mkReg(0); + + //Or: + // Statistics state + //STAT num_cycles <- mkStatCounter(`STATS_PROCESSOR_CYCLE_COUNT); + //STAT num_inst <- mkStatCounter(`STATS_PROCESSOR_INST_COUNT); + + //----------------------------------------------------------- + // Rules + + (* descending_urgency = "exec, pcgen" *) + rule pcgen; //( stage == PCgen ); + let pc_plus4 = pc + 4; + + traceTiny("mkProc", "pc",pc); + traceTiny("mkProc", "pcgen","P"); + instReqQ.enq( LoadReq{ addr:pc, tag:epoch} ); + + let next_pc = bp.get(pc); + if (next_pc matches tagged Valid .npc) + begin + pcQ.enq(PCStat {qpc:pc, qnxtpc:npc, qepoch:epoch}); + pc <= npc; + end + else + begin + pcQ.enq(PCStat {qpc:pc, qnxtpc:pc_plus4, qepoch:epoch}); + pc <= pc_plus4; + end + + endrule + + rule discard (instRespQ.first() matches tagged LoadResp .ld + &&& ld.tag != epoch); + traceTiny("mkProc", "stage", "D"); + instRespQ.deq(); + endrule + + (* conflict_free = "exec, writeback" *) + rule exec (instRespQ.first() matches tagged LoadResp.ld + &&& (ld.tag == epoch) + &&& unpack(ld.data) matches .inst + &&& !stall(inst, wbQ)); + + // Some abbreviations + let sext = signExtend; + let zext = zeroExtend; + let sra = signedShiftRight; + + // Get the instruction + + instRespQ.deq(); + Instr inst + = case ( instRespQ.first() ) matches + tagged LoadResp .ld : return unpack(ld.data); + tagged StoreResp .st : return ?; + endcase; + + // Get the PC info + let instrpc = pcQ.first().qpc; + let pc_plus4 = instrpc + 4; + + Bool branchTaken = False; + Addr newPC = pc_plus4; + + // Tracing + traceTiny("mkProc", "exec","X"); + traceTiny("mkProc", "exInstTiny",inst); + traceFull("mkProc", "exInstFull",inst); + + case ( inst ) matches + + // -- Memory Ops ------------------------------------------------ + + tagged LW .it : + begin + Addr addr = rf.rd1(it.rbase) + sext(it.offset); + dataReqQ.enq( LoadReq{ addr:addr, tag:zeroExtend(it.rdst) } ); + wbQ.enq(tagged WB_Load it.rdst); + end + + tagged SW .it : + begin + Addr addr = rf.rd1(it.rbase) + sext(it.offset); + dataReqQ.enq( StoreReq{ tag:0, addr:addr, data:rf.rd2(it.rsrc) } ); + wbQ.enq(tagged WB_Store); + end + + // -- Simple Ops ------------------------------------------------ + + tagged ADDIU .it : + begin + Bit#(32) result = rf.rd1(it.rsrc) + sext(it.imm); + wbQ.enq(tagged WB_ALU {data:result, dest:it.rdst}); + end + tagged SLTI .it : wbQ.enq(tagged WB_ALU {dest:it.rdst, data:slt( rf.rd1(it.rsrc), sext(it.imm) )}); + tagged SLTIU .it : wbQ.enq(tagged WB_ALU {dest:it.rdst, data:sltu( rf.rd1(it.rsrc), sext(it.imm) ) }); + tagged ANDI .it : + begin + Bit#(32) zext_it_imm = zext(it.imm); + wbQ.enq(tagged WB_ALU {dest:it.rdst, data:(rf.rd1(it.rsrc) & zext_it_imm)} ); + end + tagged ORI .it : + begin + Bit#(32) zext_it_imm = zext(it.imm); + wbQ.enq(tagged WB_ALU {dest:it.rdst, data:(rf.rd1(it.rsrc) | zext_it_imm)} ); + end + tagged XORI .it : + begin + Bit#(32) zext_it_imm = zext(it.imm); + wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc) ^ zext_it_imm )}); + end + tagged LUI .it : + begin + Bit#(32) zext_it_imm = zext(it.imm); + wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(zext_it_imm << 32'd16) }); + end + + tagged SLL .it : + begin + Bit#(32) zext_it_shamt = zext(it.shamt); + wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc) << zext_it_shamt )} ); + end + tagged SRL .it : + begin + Bit#(32) zext_it_shamt = zext(it.shamt); + wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc) >> zext_it_shamt )}); + end + tagged SRA .it : + begin + Bit#(32) zext_it_shamt = zext(it.shamt); + wbQ.enq(tagged WB_ALU {dest: it.rdst, data:sra( rf.rd1(it.rsrc), zext_it_shamt )}); + end + tagged SLLV .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc) << rshft(rf.rd2(it.rshamt)) )}); + tagged SRLV .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc) >> rshft(rf.rd2(it.rshamt)) )} ); + tagged SRAV .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:sra( rf.rd1(it.rsrc), rshft(rf.rd2(it.rshamt)) ) }); + tagged ADDU .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc1) + rf.rd2(it.rsrc2) )} ); + tagged SUBU .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc1) - rf.rd2(it.rsrc2) )} ); + tagged AND .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc1) & rf.rd2(it.rsrc2) )} ); + tagged OR .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc1) | rf.rd2(it.rsrc2) )} ); + tagged XOR .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc1) ^ rf.rd2(it.rsrc2) )} ); + tagged NOR .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(~(rf.rd1(it.rsrc1) | rf.rd2(it.rsrc2)) )} ); + tagged SLT .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:slt( rf.rd1(it.rsrc1), rf.rd2(it.rsrc2) ) }); + tagged SLTU .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:sltu( rf.rd1(it.rsrc1), rf.rd2(it.rsrc2) ) }); + + // -- Branches -------------------------------------------------- + + tagged BLEZ .it : + if ( signedLE( rf.rd1(it.rsrc), 0 ) ) + begin + newPC = pc_plus4 + (sext(it.offset) << 2); + branchTaken = True; + end + + tagged BGTZ .it : + if ( signedGT( rf.rd1(it.rsrc), 0 ) ) + begin + newPC = pc_plus4 + (sext(it.offset) << 2); + branchTaken = True; + end + + tagged BLTZ .it : + if ( signedLT( rf.rd1(it.rsrc), 0 ) ) + begin + newPC = pc_plus4 + (sext(it.offset) << 2); + branchTaken = True; + end + + tagged BGEZ .it : + if ( signedGE( rf.rd1(it.rsrc), 0 ) ) + begin + newPC = pc_plus4 + (sext(it.offset) << 2); + branchTaken = True; + end + + tagged BEQ .it : + if ( rf.rd1(it.rsrc1) == rf.rd2(it.rsrc2) ) + begin + newPC = pc_plus4 + (sext(it.offset) << 2); + branchTaken = True; + end + + tagged BNE .it : + if ( rf.rd1(it.rsrc1) != rf.rd2(it.rsrc2) ) + begin + newPC = pc_plus4 + (sext(it.offset) << 2); + branchTaken = True; + end + + // -- Jumps ----------------------------------------------------- + + tagged J .it : + begin + newPC = { pc_plus4[31:28], it.target, 2'b0 }; + branchTaken = True; + end + + tagged JR .it : + begin + newPC = rf.rd1(it.rsrc); + branchTaken = True; + end + + tagged JAL .it : + begin + wbQ.enq(tagged WB_ALU {dest:31, data:pc_plus4 }); + newPC = { pc_plus4[31:28], it.target, 2'b0 }; + branchTaken = True; + end + + tagged JALR .it : + begin + wbQ.enq(tagged WB_ALU {dest:it.rdst, data:pc_plus4 }); + newPC = rf.rd1(it.rsrc); + branchTaken = True; + end + + // -- Cop0 ------------------------------------------------------ + + tagged MTC0 .it : + begin + case ( it.cop0dst ) + 5'd10 : cp0_statsEn <= unpack(truncate(rf.rd1(it.rsrc))); + 5'd21 : cp0_tohost <= truncate(rf.rd1(it.rsrc)); + default : + $display( " RTL-ERROR : %m : Illegal MTC0 cop0dst register!" ); + endcase + wbQ.enq(tagged WB_Host 0); //no idea wwhat this actually should be. + end + +//this is host stuff? + tagged MFC0 .it : + begin + case ( it.cop0src ) + // not actually an ALU instruction but don't have the format otherwise + 5'd10 : wbQ.enq(tagged WB_ALU {dest:it.rdst, data:zext(pack(cp0_statsEn)) }); + 5'd20 : wbQ.enq(tagged WB_ALU {dest:it.rdst, data:cp0_fromhost }); + 5'd21 : wbQ.enq(tagged WB_ALU {dest:it.rdst, data:cp0_tohost }); + default : + $display( " RTL-ERROR : %m : Illegal MFC0 cop0src register!" ); + endcase + end + + // -- Illegal --------------------------------------------------- + + default : + $display( " RTL-ERROR : %m : Illegal instruction !" ); + + endcase + +//evaluate branch prediction + Addr ppc = pcQ.first().qnxtpc; //predicted branch + if (ppc != newPC) //prediction wrong + begin + epoch <= pcQ.first().qepoch + 1; + bp.upd(instrpc, newPC); //update branch predictor + pcQ.clear(); + pc <= newPC; + end + else + pcQ.deq(); + + if ( cp0_statsEn ) + num_inst <= num_inst+1; + + endrule + + rule writeback; // ( stage == Writeback ); + traceTiny("mkProc", "writeback","W"); + + + // get what to do off the writeback queue + wbQ.deq(); + case (wbQ.first()) matches + tagged WB_ALU {data:.res, dest:.rdst} : rf.wr(rdst, res); + tagged WB_Load .regWr : + begin + dataRespQ.deq(); + if (dataRespQ.first() matches tagged LoadResp .ld) + rf.wr(truncate(ld.tag), ld.data); // no need to use Rindx from queue? Duplicate? + end + tagged WB_Store : dataRespQ.deq(); + tagged WB_Host .dat : noAction; + endcase + + endrule + + rule inc_num_cycles; + if ( cp0_statsEn ) + num_cycles <= num_cycles+1; + endrule +// THis rule breaks things +// rule handleCPUToHost; +// let req <- server_stub.acceptRequest_ReadCPUToHost(); +// case (req) +// 0: server_stub.sendResponse_ReadCPUToHost(cp0_tohost); +// 1: server_stub.sendResponse_ReadCPUToHost(pc); +// 2: server_stub.sendResponse_ReadCPUToHost(zeroExtend(pack(stage))); +// endcase +// endrule +//----------------------------------------------------------- +// My Adds +//----------------------------------------------------------- + + //----------------------------------------------------------- + // Methods + + interface Client imem_client; + interface Get request = toGet(instReqQ); + interface Put response = toPut(instRespQ); + endinterface + + interface Client dmem_client; + interface Get request = toGet(dataReqQ); + interface Put response = toPut(dataRespQ); + endinterface + + interface Get statsEn_get = toGet(asReg(cp0_statsEn)); + + interface ProcStats stats; + interface Get num_cycles = toGet(asReg(num_cycles)); + interface Get num_inst = toGet(asReg(num_inst)); + endinterface + + interface CPUToHost tohost; + method Bit#(32) cpuToHost(int req); + return (case (req) + 0: cp0_tohost; + 1: pc; + 2: zeroExtend(pack(stage)); + endcase); + endmethod + endinterface + +endmodule + diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/lab4/Processor.dic --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/lab4/Processor.dic Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,2 @@ +def STATS.PROCESSOR.CYCLE_COUNT "PROCESSOR: Cycle count: "; +def STATS.PROCESSOR.INST_COUNT "PROCESSOR: Instruction count: "; diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/lab4/ProcessorSystem.bsv --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/lab4/ProcessorSystem.bsv Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,82 @@ +// The MIT License + +// Copyright (c) 2009 Massachusetts Institute of Technology + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import Connectable::*; +import GetPut::*; +import ClientServer::*; +import FIFO::*; +import SpecialFIFOs::*; + +//AWB includes +`include "asim/provides/low_level_platform_interface.bsh" +`include "asim/provides/soft_connections.bsh" +`include "asim/provides/common_services.bsh" + + +// Local includes +`include "asim/provides/core.bsh" +`include "asim/provides/processor_library.bsh" +`include "asim/provides/processor_library.bsh" +`include "asim/provides/fpga_components.bsh" +`include "asim/rrr/remote_client_stub_PROCESSORSYSTEMRRR.bsh" + +module [CONNECTED_MODULE] mkConnectedApplication (); + + Core core <- mkCore; + Reg#(int) cycle <- mkReg(0); + + //External memory + // I'm not comfortable assuming that the memory subsystem is in order + // So I'll insert a completion buffer here. + ClientStub_PROCESSORSYSTEMRRR client_stub <- mkClientStub_PROCESSORSYSTEMRRR(); + // Make this big enough so that several outstanding requests may be supported + FIFO#(Bit#(MainMemTagSz)) tags <- mkSizedFIFO(8); + + // this is for the tracing + rule printCycles; + cycle <= cycle+1; + $fdisplay(stderr, " => Cycle = %d", cycle); + endrule + + + rule sendMemReq; + let coreReq <- core.mmem_client.request.get; + case (coreReq) matches + tagged LoadReq .load: begin + //Allocate ROB space + client_stub.makeRequest_MemoryRequestLoad(load.addr); + tags.enq(load.tag); + end + tagged StoreReq .store: begin + client_stub.makeRequest_MemoryRequestStore(store.addr,store.data); + end + endcase + endrule + + rule receiveMemResp; + let memResp <- client_stub.getResponse_MemoryRequestLoad(); + tags.deq; + core.mmem_client.response.put(tagged LoadResp {data:memResp, + tag: tags.first}); + endrule + +endmodule \ No newline at end of file diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/lab4/ProcessorSystem.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/lab4/ProcessorSystem.cpp Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,69 @@ +#include +#include +#include + +#include "asim/provides/connected_application.h" +#include "asim/provides/stats_device.h" + + +using namespace std; + +// constructor +CONNECTED_APPLICATION_CLASS::CONNECTED_APPLICATION_CLASS(VIRTUAL_PLATFORM vp) : + clientStub(new PROCESSORSYSTEMRRR_CLIENT_STUB_CLASS(this)) +{ + +} + +// destructor +CONNECTED_APPLICATION_CLASS::~CONNECTED_APPLICATION_CLASS() +{ +} + +// init +void +CONNECTED_APPLICATION_CLASS::Init() +{ + + // enable stats + STATS_DEVICE_SERVER_CLASS::GetInstance()->SetupStats(); + +} + + +// main +void +CONNECTED_APPLICATION_CLASS::Main() +{ + int sleepCount = 0; + int result = 0; + + fflush(stdout); + + while ((result = clientStub->ReadCPUToHost(0)) != 1) { + sleep(1); + //printf("System controller sleeps with result: %d\n", result); + sleepCount++; + if(sleepCount == 100) { + printf("Failed to get response from hardware, bailing\n\n"); + printf("This means that either your hardware is hanging\n"); + printf("or that the software hasn't given it enough time\n"); + printf("to complete. If you think it needs more time, then\n"); + printf("edit CONNECTED_APPLICATION_CLASS::Main() in ProcessorSystem.cpp\n"); + printf("(connected_application)\n"); + exit(0); + } + } + + if(result == 1) { + printf("\n***PASSED***\n"); + } + + // Dump the stats file + + STATS_DEVICE_SERVER_CLASS::GetInstance()->DumpStats(); + STATS_DEVICE_SERVER_CLASS::GetInstance()->EmitFile(); + + fflush(stdout); + exit(0); +} diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/lab4/ProcessorSystem.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/lab4/ProcessorSystem.h Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,44 @@ +// +// INTEL CONFIDENTIAL +// Copyright (c) 2008 Intel Corp. Recipient is granted a non-sublicensable +// copyright license under Intel copyrights to copy and distribute this code +// internally only. This code is provided "AS IS" with no support and with no +// warranties of any kind, including warranties of MERCHANTABILITY, +// FITNESS FOR ANY PARTICULAR PURPOSE or INTELLECTUAL PROPERTY INFRINGEMENT. +// By making any use of this code, Recipient agrees that no other licenses +// to any Intel patents, trade secrets, copyrights or other intellectual +// property rights are granted herein, and no other licenses shall arise by +// estoppel, implication or by operation of law. Recipient accepts all risks +// of use. +// + +// possibly use include paths to hide existing modules? + +#ifndef __PROCESSOR_SYSTEM_CONNECTED_APPLICATION__ +#define __PROCESSOR_SYSTEM_CONNECTED_APPLICATION__ + +#include +#include + +#include "asim/provides/virtual_platform.h" + +#include "asim/rrr/client_stub_PROCESSORSYSTEMRRR.h" + +typedef class CONNECTED_APPLICATION_CLASS* CONNECTED_APPLICATION; +class CONNECTED_APPLICATION_CLASS : public PLATFORMS_MODULE_CLASS +{ + private: + PROCESSORSYSTEMRRR_CLIENT_STUB clientStub; + + public: + CONNECTED_APPLICATION_CLASS(VIRTUAL_PLATFORM vp); + ~CONNECTED_APPLICATION_CLASS(); + + // init + void Init(); + + // main + void Main(); +}; + +#endif diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/lab4/ProcessorSystemRRR.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/lab4/ProcessorSystemRRR.cpp Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,83 @@ +#include +#include +#include +#include +#include +#include + +#include "asim/rrr/service_ids.h" + +#include "asim/provides/connected_application.h" + + + +using namespace std; + +// ===== service instantiation ===== +PROCESSORSYSTEMRRR_SERVER_CLASS PROCESSORSYSTEMRRR_SERVER_CLASS::instance; + +// constructor +PROCESSORSYSTEMRRR_SERVER_CLASS::PROCESSORSYSTEMRRR_SERVER_CLASS() : + serverStub(new PROCESSORSYSTEMRRR_SERVER_STUB_CLASS(this)) +{ + // instantiate stub + memory = NULL; + fflush(stdout); +} + +// destructor +PROCESSORSYSTEMRRR_SERVER_CLASS::~PROCESSORSYSTEMRRR_SERVER_CLASS() +{ + Cleanup(); +} + +// init +void +PROCESSORSYSTEMRRR_SERVER_CLASS::Init(PLATFORMS_MODULE p) +{ + parent = p; +} + +// uninit +void +PROCESSORSYSTEMRRR_SERVER_CLASS::Uninit() +{ + Cleanup(); +} + +// cleanup +void +PROCESSORSYSTEMRRR_SERVER_CLASS::Cleanup() +{ + delete serverStub; +} + + +// +// RRR service methods +// + +UINT32 +PROCESSORSYSTEMRRR_SERVER_CLASS::MemoryRequestLoad (UINT32 address) +{ + UINT32 returnVal; + + if(memory == NULL) { + memory = new FUNCP_SIMULATED_MEMORY_CLASS(); + } + + + + memory->Read(0,(UINT64) address, sizeof(UINT32), &returnVal); + return returnVal; +} + +void +PROCESSORSYSTEMRRR_SERVER_CLASS::MemoryRequestStore (UINT32 address, UINT32 data) +{ + if(memory == NULL) { + memory = new FUNCP_SIMULATED_MEMORY_CLASS(); + } + + memory->Write(0,(UINT64) address, sizeof(UINT32), &data); +} diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/lab4/ProcessorSystemRRR.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/lab4/ProcessorSystemRRR.h Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,53 @@ + +#ifndef _PROCESSORSYSTEMRRR_ +#define _PROCESSORSYSTEMRRR_ + +#include +#include + +#include "asim/provides/low_level_platform_interface.h" +#include "asim/provides/funcp_simulated_memory.h" +#include "asim/provides/rrr.h" + + + +typedef class PROCESSORSYSTEMRRR_SERVER_CLASS* PROCESSORSYSTEMRRR_SERVER; +class PROCESSORSYSTEMRRR_SERVER_CLASS: public RRR_SERVER_CLASS, public PLATFORMS_MODULE_CLASS +{ + private: + // self-instantiation + static PROCESSORSYSTEMRRR_SERVER_CLASS instance; + FUNCP_SIMULATED_MEMORY_CLASS *memory; + + + // server stub + RRR_SERVER_STUB serverStub; + + int count; + + public: + PROCESSORSYSTEMRRR_SERVER_CLASS(); + ~PROCESSORSYSTEMRRR_SERVER_CLASS(); + + // static methods + static PROCESSORSYSTEMRRR_SERVER GetInstance() { return &instance; } + + // required RRR methods + void Init(PLATFORMS_MODULE); + void Uninit(); + void Cleanup(); + + // + // RRR service methods + // + + UINT32 MemoryRequestLoad (UINT32 address); + void MemoryRequestStore (UINT32 address, UINT32 data); +}; + + + +// include server stub +#include "asim/rrr/server_stub_PROCESSORSYSTEMRRR.h" + +#endif diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/lab4/ProcessorSystemRRR.rrr --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/lab4/ProcessorSystemRRR.rrr Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,15 @@ +service PROCESSORSYSTEMRRR +{ + server hw (bsv, connection) <- sw (cpp, method) + { + method ReadCPUToHost (out UINT32[32] regValue, in UINT32[32] dummy); + method WriteHostToCPU (in UINT32[32] regValue); + }; + + server sw (cpp, method) <- hw (bsv, connection) + { + method MemoryRequestLoad (in UINT32[32] address, out UINT32[32] value); + method MemoryRequestStore (in UINT32[32] address, in UINT32[32] value); + }; + + }; diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/lab4/SFIFO.bsv --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/lab4/SFIFO.bsv Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,213 @@ + +import FIFO::*; +import ConfigReg::*; +import RWire::*; + +import List::*; +import Monad::*; + +interface SFIFO#(type alpha_T, type search_T); + method Action enq(alpha_T x); + method Action deq(); + method alpha_T first(); + method Action clear(); + method Bool find(search_T x); + method Bool find2(search_T x); + +endinterface + +module mkSFIFO#(function Bool searchfunc(search_T s, alpha_T x)) (SFIFO#(alpha_T, search_T)) + provisos + (Bits#(alpha_T,asz)); + + Reg#(alpha_T) f0 <- mkConfigRegU(); + Reg#(alpha_T) f1 <- mkConfigRegU(); + + Reg#(Bool) vf0 <- mkConfigReg(False); + Reg#(Bool) vf1 <- mkConfigReg(False); + + PulseWire edge1 <- mkPulseWire(); + + method Action enq(alpha_T x) if (!(vf0 && vf1)); + if (edge1 || !vf0)//empty or we're dequeueing + begin + vf0 <= True; //True + vf1 <= False; + f0 <= x; + end + else // !vf1 + begin + vf1 <= True; + f1 <= x; + end + endmethod + + method Action deq() if (vf0); + edge1.send(); + vf0 <= vf1; + f0 <= f1; + vf1 <= False; + endmethod + + method alpha_T first() if(vf0); + return (f0); + endmethod + + method Action clear(); + vf0 <= False; + vf1 <= False; + endmethod + + method Bool find(search_T sv); + Bool nvf0 = edge1 ? False: vf0; + Bool nvf1 = vf1; + + return (nvf0 && searchfunc(sv, f0) || + nvf1 && searchfunc(sv, f1)); + endmethod + + method Bool find2(search_T sv); + Bool nvf0 = edge1 ? False: vf0; + Bool nvf1 = vf1; + + return (nvf0 && searchfunc(sv, f0) || + nvf1 && searchfunc(sv, f1)); + endmethod + +endmodule + +module mkSFIFO1#(function Bool searchfunc(search_T s, alpha_T x)) (SFIFO#(alpha_T, search_T)) + provisos + (Bits#(alpha_T,asz), Eq#(alpha_T)); + + Reg#(alpha_T) f0 <- mkConfigRegU; + + Reg#(Bool) vf0 <- mkConfigReg(False); + + PulseWire edge1 <- mkPulseWire(); + + method Action enq(alpha_T x) if (!vf0); + vf0 <= True; //True + f0 <= x; + endmethod + + method Action deq() if (vf0); + edge1.send(); + vf0 <= False; + endmethod + + method alpha_T first() if(vf0); + return (f0); + endmethod + + method Action clear(); + vf0 <= False; + endmethod + + method Bool find(search_T sv); + Bool nvf0 = edge1 ? False: vf0; + + return (nvf0 && searchfunc(sv, f0)); + endmethod + + method Bool find2(search_T sv); + Bool nvf0 = edge1 ? False: vf0; + return (nvf0 && searchfunc(sv, f0)); + endmethod + +endmodule + +module mkSizedSFIFOInternal#(Integer n, + function Bool searchfunc1(search_T s, alpha_T x), + function Bool searchfunc2(search_T s, alpha_T x)) (SFIFO#(alpha_T, search_T)) + + provisos ( Bits#(alpha_T,alpha_SZ) ); + + List#(Reg#(alpha_T)) registers <- replicateM(n, mkRegU); + List#(Reg#(Bool)) valids <- replicateM(n, mkReg(False)); + + function Nat getNextFree (List#(Reg#(Bool)) vs); + + Nat res = fromInteger(n - 1); + + for (Integer x = n - 1; x > -1; x = x - 1) + res = !vs[x]._read() ? fromInteger(x) : res; + + return res; + + endfunction + + function Bool notFull(); + + Bool full = True; + + for (Integer x = 0; x < n; x = x + 1) + full = full && valids[x]._read(); + + return !full; + + endfunction + + method Action enq( alpha_T item ) if ( notFull() ); + + Nat k = getNextFree(valids); + select(valids, k)._write(True); + select(registers, k)._write(item); + + endmethod + + method Action deq() if ( valids[0]._read() ); + + for (Integer x = 0; x < (n-1); x = x + 1) + begin + + (registers[x]) <= registers[x + 1]._read(); + (valids[x]) <= valids[x + 1]._read(); + + end + (valids[n-1]) <= False; + endmethod + + method alpha_T first() if ( valids[0]._read() ); + return registers[0]._read(); + endmethod + + method Bool find(search_T sv); + Bool res = False; + + for (Integer x = 0; x < n; x = x + 1) + if ( valids[x]._read() && searchfunc1(sv, registers[x]._read()) ) + res = True; + + return res; + + endmethod + + method Bool find2(search_T sv); + Bool res = False; + + for (Integer x = 0; x < n; x = x + 1) + if ( valids[x]._read() && searchfunc2(sv, registers[x]._read()) ) + res = True; + + return res; + + endmethod + + method Action clear(); + + for (Integer x = 0; x < n; x = x + 1) + (valids[x]) <= False; + + endmethod + +endmodule + +module mkSizedSFIFO#(Integer n, function Bool searchfunc(search_T s, alpha_T x)) (SFIFO#(alpha_T, search_T)) + provisos + (Bits#(alpha_T,asz)); + + let foo <- mkSizedSFIFOInternal(n, searchfunc, searchfunc); + return foo; + +endmodule diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/lab4/Trace.bsv --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/lab4/Trace.bsv Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,92 @@ + +import ClientServer::*; +import GetPut::*; + +//---------------------------------------------------------------------- +// ToString typeclass +//---------------------------------------------------------------------- + +typeclass Traceable#( type item_t ); + function Action traceTiny( String loc, String traceTag, item_t item ); + function Action traceFull( String loc, String traceTag, item_t item ); +endtypeclass + +instance Traceable#(String); + + function Action traceTiny( String loc, String ttag, String str ); + $fdisplay(stderr, " => %s:%s %s", loc, ttag, str ); + endfunction + + function Action traceFull( String loc, String ttag, String str ); + $fdisplay(stderr, " => %s:%s %s", loc, ttag, str ); + endfunction + +endinstance + +instance Traceable#(Bit#(n)); + + function Action traceTiny( String loc, String ttag, Bit#(n) b ); + $fdisplay(stderr, " => %s:%s %x", loc, ttag, b ); + endfunction + + function Action traceFull( String loc, String ttag, Bit#(n) b ); + $fdisplay(stderr, " => %s:%s %x", loc, ttag, b ); + endfunction + +endinstance + +//---------------------------------------------------------------------- +// Tracing interface wrappers +//---------------------------------------------------------------------- + +function Get#(item_t) traceGet( String locStr, String tagStr, Get#(item_t) g ) + provisos ( Traceable#(item_t) ); + return + ( + interface Get + method ActionValue#(item_t) get(); + item_t item <- g.get(); + traceTiny(locStr, tagStr,item); + return item; + endmethod + endinterface + ); +endfunction + +function Put#(item_t) tracePut( String locStr, String tagStr, Put#(item_t) p ) + provisos ( Traceable#(item_t) ); + return + ( + interface Put + method Action put( item_t item ); + traceTiny(locStr, tagStr,item); + p.put(item); + endmethod + endinterface + ); +endfunction + +function Client#(req_t,resp_t) traceClient( String locStr, String reqTagStr, String respTagStr, + Client#(req_t,resp_t) c ) + provisos ( Traceable#(req_t), Traceable#(resp_t) ); + return + ( + interface Client + interface Get request = traceGet(locStr, reqTagStr,c.request); + interface Put response = tracePut(locStr, respTagStr,c.response); + endinterface + ); +endfunction + +function Server#(req_t,resp_t) traceServer( String locStr, String reqTagStr, String respTagStr, + Server#(req_t,resp_t) c ) + provisos ( Traceable#(req_t), Traceable#(resp_t) ); + return + ( + interface Server + interface Put request = tracePut(locStr, reqTagStr,c.request); + interface Get response = traceGet(locStr, respTagStr,c.response); + endinterface + ); +endfunction + diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/lab4/core.awb --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/lab4/core.awb Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,16 @@ +%name Simple Processor Core +%desc Instantiates a processor, some caches, and a memory arbiter + +%provides core + +%requires mem_arb +%requires instruction_cache +%requires data_cache +%requires processor +%requires processor_library + +%attributes 6_375 + +%public Core.bsv + + diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/lab4/data_cache.awb --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/lab4/data_cache.awb Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,10 @@ +%name Blocking Data Cache +%desc Parametric Blocking Data Cache + +%provides data_cache + +%attributes 6_375 + +%public DataCacheBlocking.bsv +%public DataCache.dic + diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/lab4/instruction_cache.awb --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/lab4/instruction_cache.awb Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,11 @@ +%name Blocking Instruction Cache +%desc Parametric Blocking Instruction Cache + +%provides instruction_cache + +%attributes 6_375 + +%public InstCacheBlocking.bsv +%public InstCache.dic + + diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/lab4/mem_arb.awb --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/lab4/mem_arb.awb Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,10 @@ +%name Round-robin memory arbiter +%desc Round-robin memory arbiter + +%provides mem_arb + +%attributes 6_375 + +%public MemArb.bsv + + diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/lab4/oProcTypes.bsv --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/lab4/oProcTypes.bsv Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,335 @@ + +import Trace::*; + +//---------------------------------------------------------------------- +// Other typedefs +//---------------------------------------------------------------------- + +typedef Bit#(32) Addr; + +//---------------------------------------------------------------------- +// Basic instruction type +//---------------------------------------------------------------------- + +typedef Bit#(5) Rindx; +typedef Bit#(16) Simm; +typedef Bit#(16) Zimm; +typedef Bit#(5) Shamt; +typedef Bit#(26) Target; +typedef Bit#(5) CP0indx; + +typedef union tagged +{ + + struct { Rindx rbase; Rindx rdst; Simm offset; } LW; + struct { Rindx rbase; Rindx rsrc; Simm offset; } SW; + + struct { Rindx rsrc; Rindx rdst; Simm imm; } ADDIU; + struct { Rindx rsrc; Rindx rdst; Simm imm; } SLTI; + struct { Rindx rsrc; Rindx rdst; Simm imm; } SLTIU; + struct { Rindx rsrc; Rindx rdst; Zimm imm; } ANDI; + struct { Rindx rsrc; Rindx rdst; Zimm imm; } ORI; + struct { Rindx rsrc; Rindx rdst; Zimm imm; } XORI; + struct { Rindx rdst; Zimm imm; } LUI; + + struct { Rindx rsrc; Rindx rdst; Shamt shamt; } SLL; + struct { Rindx rsrc; Rindx rdst; Shamt shamt; } SRL; + struct { Rindx rsrc; Rindx rdst; Shamt shamt; } SRA; + struct { Rindx rsrc; Rindx rdst; Rindx rshamt; } SLLV; + struct { Rindx rsrc; Rindx rdst; Rindx rshamt; } SRLV; + struct { Rindx rsrc; Rindx rdst; Rindx rshamt; } SRAV; + struct { Rindx rsrc1; Rindx rsrc2; Rindx rdst; } ADDU; + struct { Rindx rsrc1; Rindx rsrc2; Rindx rdst; } SUBU; + struct { Rindx rsrc1; Rindx rsrc2; Rindx rdst; } AND; + struct { Rindx rsrc1; Rindx rsrc2; Rindx rdst; } OR; + struct { Rindx rsrc1; Rindx rsrc2; Rindx rdst; } XOR; + struct { Rindx rsrc1; Rindx rsrc2; Rindx rdst; } NOR; + struct { Rindx rsrc1; Rindx rsrc2; Rindx rdst; } SLT; + struct { Rindx rsrc1; Rindx rsrc2; Rindx rdst; } SLTU; + + struct { Target target; } J; + struct { Target target; } JAL; + struct { Rindx rsrc; } JR; + struct { Rindx rsrc; Rindx rdst; } JALR; + struct { Rindx rsrc1; Rindx rsrc2; Simm offset; } BEQ; + struct { Rindx rsrc1; Rindx rsrc2; Simm offset; } BNE; + struct { Rindx rsrc; Simm offset; } BLEZ; + struct { Rindx rsrc; Simm offset; } BGTZ; + struct { Rindx rsrc; Simm offset; } BLTZ; + struct { Rindx rsrc; Simm offset; } BGEZ; + + struct { Rindx rdst; CP0indx cop0src; } MFC0; + struct { Rindx rsrc; CP0indx cop0dst; } MTC0; + + void ILLEGAL; + +} +Instr deriving(Eq); + +//---------------------------------------------------------------------- +// Pack and Unpack +//---------------------------------------------------------------------- + +Bit#(6) opFUNC = 6'b000000; Bit#(6) fcSLL = 6'b000000; +Bit#(6) opRT = 6'b000001; Bit#(6) fcSRL = 6'b000010; +Bit#(6) opRS = 6'b010000; Bit#(6) fcSRA = 6'b000011; + Bit#(6) fcSLLV = 6'b000100; +Bit#(6) opLW = 6'b100011; Bit#(6) fcSRLV = 6'b000110; +Bit#(6) opSW = 6'b101011; Bit#(6) fcSRAV = 6'b000111; + Bit#(6) fcADDU = 6'b100001; +Bit#(6) opADDIU = 6'b001001; Bit#(6) fcSUBU = 6'b100011; +Bit#(6) opSLTI = 6'b001010; Bit#(6) fcAND = 6'b100100; +Bit#(6) opSLTIU = 6'b001011; Bit#(6) fcOR = 6'b100101; +Bit#(6) opANDI = 6'b001100; Bit#(6) fcXOR = 6'b100110; +Bit#(6) opORI = 6'b001101; Bit#(6) fcNOR = 6'b100111; +Bit#(6) opXORI = 6'b001110; Bit#(6) fcSLT = 6'b101010; +Bit#(6) opLUI = 6'b001111; Bit#(6) fcSLTU = 6'b101011; + +Bit#(6) opJ = 6'b000010; +Bit#(6) opJAL = 6'b000011; +Bit#(6) fcJR = 6'b001000; +Bit#(6) fcJALR = 6'b001001; +Bit#(6) opBEQ = 6'b000100; +Bit#(6) opBNE = 6'b000101; +Bit#(6) opBLEZ = 6'b000110; +Bit#(6) opBGTZ = 6'b000111; +Bit#(5) rtBLTZ = 5'b00000; +Bit#(5) rtBGEZ = 5'b00001; + +Bit#(5) rsMFC0 = 5'b00000; +Bit#(5) rsMTC0 = 5'b00100; + +instance Bits#(Instr,32); + + // Pack Function + + function Bit#(32) pack( Instr instr ); + + case ( instr ) matches + + tagged LW .it : return { opLW, it.rbase, it.rdst, it.offset }; + tagged SW .it : return { opSW, it.rbase, it.rsrc, it.offset }; + + tagged ADDIU .it : return { opADDIU, it.rsrc, it.rdst, it.imm }; + tagged SLTI .it : return { opSLTI, it.rsrc, it.rdst, it.imm }; + tagged SLTIU .it : return { opSLTIU, it.rsrc, it.rdst, it.imm }; + tagged ANDI .it : return { opANDI, it.rsrc, it.rdst, it.imm }; + tagged ORI .it : return { opORI, it.rsrc, it.rdst, it.imm }; + tagged XORI .it : return { opXORI, it.rsrc, it.rdst, it.imm }; + tagged LUI .it : return { opLUI, 5'b0, it.rdst, it.imm }; + + tagged SLL .it : return { opFUNC, 5'b0, it.rsrc, it.rdst, it.shamt, fcSLL }; + tagged SRL .it : return { opFUNC, 5'b0, it.rsrc, it.rdst, it.shamt, fcSRL }; + tagged SRA .it : return { opFUNC, 5'b0, it.rsrc, it.rdst, it.shamt, fcSRA }; + + tagged SLLV .it : return { opFUNC, it.rshamt, it.rsrc, it.rdst, 5'b0, fcSLLV }; + tagged SRLV .it : return { opFUNC, it.rshamt, it.rsrc, it.rdst, 5'b0, fcSRLV }; + tagged SRAV .it : return { opFUNC, it.rshamt, it.rsrc, it.rdst, 5'b0, fcSRAV }; + + tagged ADDU .it : return { opFUNC, it.rsrc1, it.rsrc2, it.rdst, 5'b0, fcADDU }; + tagged SUBU .it : return { opFUNC, it.rsrc1, it.rsrc2, it.rdst, 5'b0, fcSUBU }; + tagged AND .it : return { opFUNC, it.rsrc1, it.rsrc2, it.rdst, 5'b0, fcAND }; + tagged OR .it : return { opFUNC, it.rsrc1, it.rsrc2, it.rdst, 5'b0, fcOR }; + tagged XOR .it : return { opFUNC, it.rsrc1, it.rsrc2, it.rdst, 5'b0, fcXOR }; + tagged NOR .it : return { opFUNC, it.rsrc1, it.rsrc2, it.rdst, 5'b0, fcNOR }; + tagged SLT .it : return { opFUNC, it.rsrc1, it.rsrc2, it.rdst, 5'b0, fcSLT }; + tagged SLTU .it : return { opFUNC, it.rsrc1, it.rsrc2, it.rdst, 5'b0, fcSLTU }; + + tagged J .it : return { opJ, it.target }; + tagged JAL .it : return { opJAL, it.target }; + tagged JR .it : return { opFUNC, it.rsrc, 5'b0, 5'b0, 5'b0, fcJR }; + tagged JALR .it : return { opFUNC, it.rsrc, 5'b0, it.rdst, 5'b0, fcJALR }; + tagged BEQ .it : return { opBEQ, it.rsrc1, it.rsrc2, it.offset }; + tagged BNE .it : return { opBNE, it.rsrc1, it.rsrc2, it.offset }; + tagged BLEZ .it : return { opBLEZ, it.rsrc, 5'b0, it.offset }; + tagged BGTZ .it : return { opBGTZ, it.rsrc, 5'b0, it.offset }; + tagged BLTZ .it : return { opRT, it.rsrc, rtBLTZ, it.offset }; + tagged BGEZ .it : return { opRT, it.rsrc, rtBGEZ, it.offset }; + + tagged MFC0 .it : return { opRS, rsMFC0, it.rdst, it.cop0src, 11'b0 }; + tagged MTC0 .it : return { opRS, rsMTC0, it.rsrc, it.cop0dst, 11'b0 }; + + endcase + + endfunction + + // Unpack Function + + function Instr unpack( Bit#(32) instrBits ); + + let opcode = instrBits[ 31 : 26 ]; + let rs = instrBits[ 25 : 21 ]; + let rt = instrBits[ 20 : 16 ]; + let rd = instrBits[ 15 : 11 ]; + let shamt = instrBits[ 10 : 6 ]; + let funct = instrBits[ 5 : 0 ]; + let imm = instrBits[ 15 : 0 ]; + let target = instrBits[ 25 : 0 ]; + + case ( opcode ) + + opLW : return LW { rbase:rs, rdst:rt, offset:imm }; + opSW : return SW { rbase:rs, rsrc:rt, offset:imm }; + opADDIU : return ADDIU { rsrc:rs, rdst:rt, imm:imm }; + opSLTI : return SLTI { rsrc:rs, rdst:rt, imm:imm }; + opSLTIU : return SLTIU { rsrc:rs, rdst:rt, imm:imm }; + opANDI : return ANDI { rsrc:rs, rdst:rt, imm:imm }; + opORI : return ORI { rsrc:rs, rdst:rt, imm:imm }; + opXORI : return XORI { rsrc:rs, rdst:rt, imm:imm }; + opLUI : return LUI { rdst:rt, imm:imm }; + opJ : return J { target:target }; + opJAL : return JAL { target:target }; + opBEQ : return BEQ { rsrc1:rs, rsrc2:rt, offset:imm }; + opBNE : return BNE { rsrc1:rs, rsrc2:rt, offset:imm }; + opBLEZ : return BLEZ { rsrc:rs, offset:imm }; + opBGTZ : return BGTZ { rsrc:rs, offset:imm }; + + opFUNC : + case ( funct ) + fcSLL : return SLL { rsrc:rt, rdst:rd, shamt:shamt }; + fcSRL : return SRL { rsrc:rt, rdst:rd, shamt:shamt }; + fcSRA : return SRA { rsrc:rt, rdst:rd, shamt:shamt }; + fcSLLV : return SLLV { rsrc:rt, rdst:rd, rshamt:rs }; + fcSRLV : return SRLV { rsrc:rt, rdst:rd, rshamt:rs }; + fcSRAV : return SRAV { rsrc:rt, rdst:rd, rshamt:rs }; + fcADDU : return ADDU { rsrc1:rs, rsrc2:rt, rdst:rd }; + fcSUBU : return SUBU { rsrc1:rs, rsrc2:rt, rdst:rd }; + fcAND : return AND { rsrc1:rs, rsrc2:rt, rdst:rd }; + fcOR : return OR { rsrc1:rs, rsrc2:rt, rdst:rd }; + fcXOR : return XOR { rsrc1:rs, rsrc2:rt, rdst:rd }; + fcNOR : return NOR { rsrc1:rs, rsrc2:rt, rdst:rd }; + fcSLT : return SLT { rsrc1:rs, rsrc2:rt, rdst:rd }; + fcSLTU : return SLTU { rsrc1:rs, rsrc2:rt, rdst:rd }; + fcJR : return JR { rsrc:rs }; + fcJALR : return JALR { rsrc:rs, rdst:rd }; + default : return ILLEGAL; + endcase + + opRT : + case ( rt ) + rtBLTZ : return BLTZ { rsrc:rs, offset:imm }; + rtBGEZ : return BGEZ { rsrc:rs, offset:imm }; + default : return ILLEGAL; + endcase + + opRS : + case ( rs ) + rsMFC0 : return MFC0 { rdst:rt, cop0src:rd }; + rsMTC0 : return MTC0 { rsrc:rt, cop0dst:rd }; + default : return ILLEGAL; + endcase + + default : return ILLEGAL; + + endcase + + endfunction + +endinstance + +//---------------------------------------------------------------------- +// Trace +//---------------------------------------------------------------------- + +instance Traceable#(Instr); + + function Action traceTiny( String loc, String ttag, Instr inst ); + case ( inst ) matches + + tagged LW .it : $fdisplay(stderr, " => %s:%s lw", loc, ttag ); + tagged SW .it : $fdisplay(stderr, " => %s:%s sw", loc, ttag ); + + tagged ADDIU .it : $fdisplay(stderr, " => %s:%s addi", loc, ttag ); + tagged SLTI .it : $fdisplay(stderr, " => %s:%s sli", loc, ttag ); + tagged SLTIU .it : $fdisplay(stderr, " => %s:%s sliu", loc, ttag ); + tagged ANDI .it : $fdisplay(stderr, " => %s:%s andi", loc, ttag ); + tagged ORI .it : $fdisplay(stderr, " => %s:%s ori", loc, ttag ); + tagged XORI .it : $fdisplay(stderr, " => %s:%s xori", loc, ttag ); + tagged LUI .it : $fdisplay(stderr, " => %s:%s lui", loc, ttag ); + + tagged SLL .it : $fdisplay(stderr, " => %s:%s sll", loc, ttag ); + tagged SRL .it : $fdisplay(stderr, " => %s:%s srl", loc, ttag ); + tagged SRA .it : $fdisplay(stderr, " => %s:%s sra", loc, ttag ); + tagged SLLV .it : $fdisplay(stderr, " => %s:%s sllv", loc, ttag ); + tagged SRLV .it : $fdisplay(stderr, " => %s:%s srlv", loc, ttag ); + tagged SRAV .it : $fdisplay(stderr, " => %s:%s srav", loc, ttag ); + + tagged ADDU .it : $fdisplay(stderr, " => %s:%s addu", loc, ttag ); + tagged SUBU .it : $fdisplay(stderr, " => %s:%s subu", loc, ttag ); + tagged AND .it : $fdisplay(stderr, " => %s:%s and", loc, ttag ); + tagged OR .it : $fdisplay(stderr, " => %s:%s or", loc, ttag ); + tagged XOR .it : $fdisplay(stderr, " => %s:%s xor", loc, ttag ); + tagged NOR .it : $fdisplay(stderr, " => %s:%s nor", loc, ttag ); + tagged SLT .it : $fdisplay(stderr, " => %s:%s slt", loc, ttag ); + tagged SLTU .it : $fdisplay(stderr, " => %s:%s sltu", loc, ttag ); + + tagged J .it : $fdisplay(stderr, " => %s:%s j", loc, ttag ); + tagged JAL .it : $fdisplay(stderr, " => %s:%s jal", loc, ttag ); + tagged JR .it : $fdisplay(stderr, " => %s:%s jr", loc, ttag ); + tagged JALR .it : $fdisplay(stderr, " => %s:%s jalr", loc, ttag ); + tagged BEQ .it : $fdisplay(stderr, " => %s:%s beq", loc, ttag ); + tagged BNE .it : $fdisplay(stderr, " => %s:%s bne", loc, ttag ); + tagged BLEZ .it : $fdisplay(stderr, " => %s:%s blez", loc, ttag ); + tagged BGTZ .it : $fdisplay(stderr, " => %s:%s bgtz", loc, ttag ); + tagged BLTZ .it : $fdisplay(stderr, " => %s:%s bltz", loc, ttag ); + tagged BGEZ .it : $fdisplay(stderr, " => %s:%s bgez", loc, ttag ); + + tagged MFC0 .it : $fdisplay(stderr, " => %s:%s mfc0", loc, ttag ); + tagged MTC0 .it : $fdisplay(stderr, " => %s:%s mtc0", loc, ttag ); + + tagged ILLEGAL : $fdisplay(stderr, " => %s:%s ill", loc, ttag ); + + endcase + endfunction + + function Action traceFull( String loc, String ttag, Instr inst ); + case ( inst ) matches + + tagged LW .it : $fdisplay(stderr, " => %s:%s lw r%0d, 0x%x(r%0d)", loc, ttag, it.rdst, it.offset, it.rbase ); + tagged SW .it : $fdisplay(stderr, " => %s:%s sw r%0d, 0x%x(r%0d)", loc, ttag, it.rsrc, it.offset, it.rbase ); + + tagged ADDIU .it : $fdisplay(stderr, " => %s:%s addiu r%0d, r%0d, 0x%x", loc, ttag, it.rdst, it.rsrc, it.imm ); + tagged SLTI .it : $fdisplay(stderr, " => %s:%s slti r%0d, r%0d, 0x%x", loc, ttag, it.rdst, it.rsrc, it.imm ); + tagged SLTIU .it : $fdisplay(stderr, " => %s:%s sltiu r%0d, r%0d, 0x%x", loc, ttag, it.rdst, it.rsrc, it.imm ); + tagged ANDI .it : $fdisplay(stderr, " => %s:%s andi r%0d, r%0d, 0x%x", loc, ttag, it.rdst, it.rsrc, it.imm ); + tagged ORI .it : $fdisplay(stderr, " => %s:%s ori r%0d, r%0d, 0x%x", loc, ttag, it.rdst, it.rsrc, it.imm ); + tagged XORI .it : $fdisplay(stderr, " => %s:%s xori r%0d, r%0d, 0x%x", loc, ttag, it.rdst, it.rsrc, it.imm ); + tagged LUI .it : $fdisplay(stderr, " => %s:%s lui r%0d, 0x%x", loc, ttag, it.rdst, it.imm ); + + tagged SLL .it : $fdisplay(stderr, " => %s:%s sll r%0d, r%0d, %0d", loc, ttag, it.rdst, it.rsrc, it.shamt ); + tagged SRL .it : $fdisplay(stderr, " => %s:%s srl r%0d, r%0d, %0d", loc, ttag, it.rdst, it.rsrc, it.shamt ); + tagged SRA .it : $fdisplay(stderr, " => %s:%s sra r%0d, r%0d, %0d", loc, ttag, it.rdst, it.rsrc, it.shamt ); + tagged SLLV .it : $fdisplay(stderr, " => %s:%s sllv r%0d, r%0d, r%0d", loc, ttag, it.rdst, it.rsrc, it.rshamt ); + tagged SRLV .it : $fdisplay(stderr, " => %s:%s srlv r%0d, r%0d, r%0d", loc, ttag, it.rdst, it.rsrc, it.rshamt ); + tagged SRAV .it : $fdisplay(stderr, " => %s:%s srav r%0d, r%0d, r%0d", loc, ttag, it.rdst, it.rsrc, it.rshamt ); + + tagged ADDU .it : $fdisplay(stderr, " => %s:%s addu r%0d, r%0d, r%0d", loc, ttag, it.rdst, it.rsrc1, it.rsrc2 ); + tagged SUBU .it : $fdisplay(stderr, " => %s:%s subu r%0d, r%0d, r%0d", loc, ttag, it.rdst, it.rsrc1, it.rsrc2 ); + tagged AND .it : $fdisplay(stderr, " => %s:%s and r%0d, r%0d, r%0d", loc, ttag, it.rdst, it.rsrc1, it.rsrc2 ); + tagged OR .it : $fdisplay(stderr, " => %s:%s or r%0d, r%0d, r%0d", loc, ttag, it.rdst, it.rsrc1, it.rsrc2 ); + tagged XOR .it : $fdisplay(stderr, " => %s:%s xor r%0d, r%0d, r%0d", loc, ttag, it.rdst, it.rsrc1, it.rsrc2 ); + tagged NOR .it : $fdisplay(stderr, " => %s:%s nor r%0d, r%0d, r%0d", loc, ttag, it.rdst, it.rsrc1, it.rsrc2 ); + tagged SLT .it : $fdisplay(stderr, " => %s:%s slt r%0d, r%0d, r%0d", loc, ttag, it.rdst, it.rsrc1, it.rsrc2 ); + tagged SLTU .it : $fdisplay(stderr, " => %s:%s sltu r%0d, r%0d, r%0d", loc, ttag, it.rdst, it.rsrc1, it.rsrc2 ); + + tagged J .it : $fdisplay(stderr, " => %s:%s j 0x%x", loc, ttag, it.target ); + tagged JAL .it : $fdisplay(stderr, " => %s:%s jal 0x%x", loc, ttag, it.target ); + tagged JR .it : $fdisplay(stderr, " => %s:%s jr r%0d", loc, ttag, it.rsrc ); + tagged JALR .it : $fdisplay(stderr, " => %s:%s jalr r%0d", loc, ttag, it.rsrc ); + tagged BEQ .it : $fdisplay(stderr, " => %s:%s beq r%0d, r%0d, 0x%x", loc, ttag, it.rsrc1, it.rsrc2, it.offset ); + tagged BNE .it : $fdisplay(stderr, " => %s:%s bne r%0d, r%0d, 0x%x", loc, ttag, it.rsrc1, it.rsrc2, it.offset ); + tagged BLEZ .it : $fdisplay(stderr, " => %s:%s blez r%0d, 0x%x", loc, ttag, it.rsrc, it.offset ); + tagged BGTZ .it : $fdisplay(stderr, " => %s:%s bgtz r%0d, 0x%x", loc, ttag, it.rsrc, it.offset ); + tagged BLTZ .it : $fdisplay(stderr, " => %s:%s bltz r%0d, 0x%x", loc, ttag, it.rsrc, it.offset ); + tagged BGEZ .it : $fdisplay(stderr, " => %s:%s bgez r%0d, 0x%x", loc, ttag, it.rsrc, it.offset ); + + tagged MFC0 .it : $fdisplay(stderr, " => %s:%s mfc0 r%0d, cpr%0d", loc, ttag, it.rdst, it.cop0src ); + tagged MTC0 .it : $fdisplay(stderr, " => %s:%s mtc0 r%0d, cpr%0d", loc, ttag, it.rsrc, it.cop0dst ); + + tagged ILLEGAL : $fdisplay(stderr, " => %s:%s illegal instruction", loc, ttag ); + + endcase + endfunction + +endinstance + diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/lab4/oProcessor.bsv --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/lab4/oProcessor.bsv Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,373 @@ +// The MIT License + +// Copyright (c) 2009 Massachusetts Institute of Technology + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import Connectable::*; +import GetPut::*; +import ClientServer::*; +import RegFile::*; +import FIFO::*; +import FIFOF::*; +import RWire::*; + +//AWB includes +`include "asim/provides/low_level_platform_interface.bsh" +`include "asim/provides/soft_connections.bsh" +`include "asim/provides/common_services.bsh" + +// Local includes +`include "asim/provides/processor_library.bsh" +`include "asim/rrr/remote_server_stub_PROCESSORSYSTEMRRR.bsh" +`include "asim/provides/common_services.bsh" +`include "asim/dict/STATS_PROCESSOR.bsh" + +interface Proc; + + // Interface from processor to caches + interface Client#(DataReq,DataResp) dmem_client; + interface Client#(InstReq,InstResp) imem_client; + + // Interface for enabling/disabling statistics on the rest of the core + interface Get#(Bool) statsEn_get; + +endinterface + + +typedef enum { PCgen, Exec, Writeback } Stage deriving(Eq,Bits); + +//----------------------------------------------------------- +// Register file module +//----------------------------------------------------------- + +interface RFile; + method Action wr( Rindx rindx, Bit#(32) data ); + method Bit#(32) rd1( Rindx rindx ); + method Bit#(32) rd2( Rindx rindx ); +endinterface + +module mkRFile( RFile ); + + RegFile#(Rindx,Bit#(32)) rfile <- mkRegFileFull(); + + method Action wr( Rindx rindx, Bit#(32) data ); + rfile.upd( rindx, data ); + endmethod + + method Bit#(32) rd1( Rindx rindx ); + return ( rindx == 0 ) ? 0 : rfile.sub(rindx); + endmethod + + method Bit#(32) rd2( Rindx rindx ); + return ( rindx == 0 ) ? 0 : rfile.sub(rindx); + endmethod + +endmodule + +//----------------------------------------------------------- +// Helper functions +//----------------------------------------------------------- + +function Bit#(32) slt( Bit#(32) val1, Bit#(32) val2 ); + return zeroExtend( pack( signedLT(val1,val2) ) ); +endfunction + +function Bit#(32) sltu( Bit#(32) val1, Bit#(32) val2 ); + return zeroExtend( pack( val1 < val2 ) ); +endfunction + +function Bit#(32) rshft( Bit#(32) val ); + return zeroExtend(val[4:0]); +endfunction + +//----------------------------------------------------------- +// Reference processor +//----------------------------------------------------------- + + +module [CONNECTED_MODULE] mkProc( Proc ); + + //----------------------------------------------------------- + // Debug port + + ServerStub_PROCESSORSYSTEMRRR server_stub <- mkServerStub_PROCESSORSYSTEMRRR(); + + //----------------------------------------------------------- + // State + + // Standard processor state + + Reg#(Addr) pc <- mkReg(32'h00001000); + Reg#(Stage) stage <- mkReg(PCgen); + RFile rf <- mkRFile; + + // Coprocessor state - connected by way of RRR + + Reg#(Bit#(32)) cp0_tohost <- mkReg(0); + + Reg#(Bit#(32)) cp0_fromhost <- mkReg(0); + + Reg#(Bool) cp0_statsEn <- mkReg(False); + + // Memory request/response state + + FIFO#(InstReq) instReqQ <- mkBFIFO1(); + FIFO#(InstResp) instRespQ <- mkFIFO(); + + FIFO#(DataReq) dataReqQ <- mkBFIFO1(); + FIFO#(DataResp) dataRespQ <- mkFIFO(); + + // Statistics state + STAT num_cycles <- mkStatCounter(`STATS_PROCESSOR_CYCLE_COUNT); + STAT num_inst <- mkStatCounter(`STATS_PROCESSOR_INST_COUNT); + + //----------------------------------------------------------- + // Rules + + let pc_plus4 = pc + 4; + + rule pcgen ( stage == PCgen ); + traceTiny("mkProc", "pc",pc); + traceTiny("mkProc", "pcgen","P"); + instReqQ.enq( LoadReq{ addr:pc, tag:0 } ); + stage <= Exec; + endrule + + rule exec ( stage == Exec ); + + // Some abbreviations + let sext = signExtend; + let zext = zeroExtend; + let sra = signedShiftRight; + + // Get the instruction + + instRespQ.deq(); + Instr inst + = case ( instRespQ.first() ) matches + tagged LoadResp .ld : return unpack(ld.data); + tagged StoreResp .st : return ?; + endcase; + + // Some default variables + Stage next_stage = PCgen; + Addr next_pc = pc_plus4; + + // Tracing + traceTiny("mkProc", "exec","X"); + traceTiny("mkProc", "exInstTiny",inst); + traceFull("mkProc", "exInstFull",inst); + + case ( inst ) matches + + // -- Memory Ops ------------------------------------------------ + + tagged LW .it : + begin + Addr addr = rf.rd1(it.rbase) + sext(it.offset); + dataReqQ.enq( LoadReq{ addr:addr, tag:zeroExtend(it.rdst) } ); + next_stage = Writeback; + end + + tagged SW .it : + begin + Addr addr = rf.rd1(it.rbase) + sext(it.offset); + dataReqQ.enq( StoreReq{ tag:0, addr:addr, data:rf.rd1(it.rsrc) } ); + next_stage = Writeback; + end + + // -- Simple Ops ------------------------------------------------ + + tagged ADDIU .it : rf.wr( it.rdst, rf.rd1(it.rsrc) + sext(it.imm) ); + tagged SLTI .it : rf.wr( it.rdst, slt( rf.rd1(it.rsrc), sext(it.imm) ) ); + tagged SLTIU .it : rf.wr( it.rdst, sltu( rf.rd1(it.rsrc), sext(it.imm) ) ); + tagged ANDI .it : + begin + Bit#(32) zext_it_imm = zext(it.imm); + rf.wr( it.rdst, rf.rd1(it.rsrc) & zext_it_imm ); + end + tagged ORI .it : + begin + Bit#(32) zext_it_imm = zext(it.imm); + rf.wr( it.rdst, rf.rd1(it.rsrc) | zext_it_imm ); + end + tagged XORI .it : + begin + Bit#(32) zext_it_imm = zext(it.imm); + rf.wr( it.rdst, rf.rd1(it.rsrc) ^ zext_it_imm ); + end + tagged LUI .it : + begin + Bit#(32) zext_it_imm = zext(it.imm); + rf.wr( it.rdst, (zext_it_imm << 32'd16) ); + end + + tagged SLL .it : + begin + Bit#(32) zext_it_shamt = zext(it.shamt); + rf.wr( it.rdst, rf.rd1(it.rsrc) << zext_it_shamt ); + end + tagged SRL .it : + begin + Bit#(32) zext_it_shamt = zext(it.shamt); + rf.wr( it.rdst, rf.rd1(it.rsrc) >> zext_it_shamt ); + end + tagged SRA .it : + begin + Bit#(32) zext_it_shamt = zext(it.shamt); + rf.wr( it.rdst, sra( rf.rd1(it.rsrc), zext_it_shamt )); + end + tagged SLLV .it : rf.wr( it.rdst, rf.rd1(it.rsrc) << rshft(rf.rd2(it.rshamt)) ); + tagged SRLV .it : rf.wr( it.rdst, rf.rd1(it.rsrc) >> rshft(rf.rd2(it.rshamt)) ); + tagged SRAV .it : rf.wr( it.rdst, sra( rf.rd1(it.rsrc), rshft(rf.rd2(it.rshamt)) ) ); + tagged ADDU .it : rf.wr( it.rdst, rf.rd1(it.rsrc1) + rf.rd2(it.rsrc2) ); + tagged SUBU .it : rf.wr( it.rdst, rf.rd1(it.rsrc1) - rf.rd2(it.rsrc2) ); + tagged AND .it : rf.wr( it.rdst, rf.rd1(it.rsrc1) & rf.rd2(it.rsrc2) ); + tagged OR .it : rf.wr( it.rdst, rf.rd1(it.rsrc1) | rf.rd2(it.rsrc2) ); + tagged XOR .it : rf.wr( it.rdst, rf.rd1(it.rsrc1) ^ rf.rd2(it.rsrc2) ); + tagged NOR .it : rf.wr( it.rdst, ~(rf.rd1(it.rsrc1) | rf.rd2(it.rsrc2)) ); + tagged SLT .it : rf.wr( it.rdst, slt( rf.rd1(it.rsrc1), rf.rd2(it.rsrc2) ) ); + tagged SLTU .it : rf.wr( it.rdst, sltu( rf.rd1(it.rsrc1), rf.rd2(it.rsrc2) ) ); + + // -- Branches -------------------------------------------------- + + tagged BLEZ .it : + if ( signedLE( rf.rd1(it.rsrc), 0 ) ) + next_pc = pc_plus4 + (sext(it.offset) << 2); + + tagged BGTZ .it : + if ( signedGT( rf.rd1(it.rsrc), 0 ) ) + next_pc = pc_plus4 + (sext(it.offset) << 2); + + tagged BLTZ .it : + if ( signedLT( rf.rd1(it.rsrc), 0 ) ) + next_pc = pc_plus4 + (sext(it.offset) << 2); + + tagged BGEZ .it : + if ( signedGE( rf.rd1(it.rsrc), 0 ) ) + next_pc = pc_plus4 + (sext(it.offset) << 2); + + tagged BEQ .it : + if ( rf.rd1(it.rsrc1) == rf.rd2(it.rsrc2) ) + next_pc = pc_plus4 + (sext(it.offset) << 2); + + tagged BNE .it : + if ( rf.rd1(it.rsrc1) != rf.rd2(it.rsrc2) ) + next_pc = pc_plus4 + (sext(it.offset) << 2); + + // -- Jumps ----------------------------------------------------- + + tagged J .it : + next_pc = { pc_plus4[31:28], it.target, 2'b0 }; + + tagged JR .it : + next_pc = rf.rd1(it.rsrc); + + tagged JAL .it : + begin + rf.wr( 31, pc_plus4 ); + next_pc = { pc_plus4[31:28], it.target, 2'b0 }; + end + + tagged JALR .it : + begin + rf.wr( it.rdst, pc_plus4 ); + next_pc = rf.rd1(it.rsrc); + end + + // -- Cop0 ------------------------------------------------------ + + tagged MTC0 .it : + case ( it.cop0dst ) + 5'd10 : cp0_statsEn <= unpack(truncate(rf.rd1(it.rsrc))); + 5'd21 : cp0_tohost <= truncate(rf.rd1(it.rsrc)); + default : + $display( " RTL-ERROR : %m : Illegal MTC0 cop0dst register!" ); + endcase + + tagged MFC0 .it : + case ( it.cop0src ) + 5'd10 : rf.wr( it.rdst, zext(pack(cp0_statsEn)) ); + 5'd20 : rf.wr( it.rdst, cp0_fromhost ); + 5'd21 : rf.wr( it.rdst, cp0_tohost ); + default : + $display( " RTL-ERROR : %m : Illegal MFC0 cop0src register!" ); + endcase + + // -- Illegal --------------------------------------------------- + + default : + $display( " RTL-ERROR : %m : Illegal instruction !" ); + + endcase + + stage <= next_stage; + pc <= next_pc; + + if ( cp0_statsEn ) + num_inst.incr(); + + endrule + + rule writeback ( stage == Writeback ); + traceTiny("mkProc", "writeback","W"); + + dataRespQ.deq(); + case ( dataRespQ.first() ) matches + tagged LoadResp .ld : rf.wr( truncate(ld.tag), ld.data ); + tagged StoreResp .st : noAction; + endcase + + stage <= PCgen; + endrule + + rule inc_num_cycles; + if ( cp0_statsEn ) + num_cycles.incr(); + endrule + + rule handleCPUToHost; + let req <- server_stub.acceptRequest_ReadCPUToHost(); + case (req) + 0: server_stub.sendResponse_ReadCPUToHost(cp0_tohost); + 1: server_stub.sendResponse_ReadCPUToHost(pc); + 2: server_stub.sendResponse_ReadCPUToHost(zeroExtend(pack(stage))); + endcase + endrule + + + + //----------------------------------------------------------- + // Methods + + interface Client imem_client; + interface Get request = fifoToGet(instReqQ); + interface Put response = fifoToPut(instRespQ); + endinterface + + interface Client dmem_client; + interface Get request = fifoToGet(dataReqQ); + interface Put response = fifoToPut(dataRespQ); + endinterface + + interface Get statsEn_get = regToGet(cp0_statsEn); + +endmodule + diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/lab4/oSFIFO.bsv --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/lab4/oSFIFO.bsv Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,234 @@ + +import FIFO::*; +import ConfigReg::*; +import RWire::*; + +import List::*; +import Monad::*; + +interface SFIFO#(type alpha_T, type search_T); + method Action enq(alpha_T x); + method Action deq(); + method alpha_T first(); + method Action clear(); + method Bool find(search_T x); + method Bool find2(search_T x); + method Bool notEmpty(); + method Bool notFull(); +endinterface + +module mkSFIFO#(function Bool searchfunc(search_T s, alpha_T x)) (SFIFO#(alpha_T, search_T)) + provisos + (Bits#(alpha_T,asz)); + + Reg#(alpha_T) f0 <- mkConfigRegU; + Reg#(alpha_T) f1 <- mkConfigRegU; + + Reg#(Bool) vf0 <- mkConfigReg(False); + Reg#(Bool) vf1 <- mkConfigReg(False); + + PulseWire edge1 <- mkPulseWire(); + + method Action enq(alpha_T x) if (!(vf0 && vf1)); + if (edge1 || !vf0)//empty or we're dequeueing + begin + vf0 <= True; //True + vf1 <= False; + f0 <= x; + end + else // !vf1 + begin + vf1 <= True; + f1 <= x; + end + endmethod + + method Action deq() if (vf0); + edge1.send(); + vf0 <= vf1; + f0 <= f1; + vf1 <= False; + endmethod + + method alpha_T first() if(vf0); + return (f0); + endmethod + + method Action clear(); + vf0 <= False; + vf1 <= False; + endmethod + + method Bool find(search_T sv); + Bool nvf0 = edge1 ? False: vf0; + Bool nvf1 = vf1; + + return (nvf0 && searchfunc(sv, f0) || + nvf1 && searchfunc(sv, f1)); + endmethod + + method Bool find2(search_T sv); + Bool nvf0 = edge1 ? False: vf0; + Bool nvf1 = vf1; + + return (nvf0 && searchfunc(sv, f0) || + nvf1 && searchfunc(sv, f1)); + endmethod + + method notEmpty() = vf0._read; + + method Bool notFull(); + return !(vf0 && vf1); + endmethod + +endmodule + +module mkSFIFO1#(function Bool searchfunc(search_T s, alpha_T x)) (SFIFO#(alpha_T, search_T)) + provisos + (Bits#(alpha_T,asz), Eq#(alpha_T)); + + Reg#(alpha_T) f0 <- mkConfigRegU; + + Reg#(Bool) vf0 <- mkConfigReg(False); + + PulseWire edge1 <- mkPulseWire(); + + method Action enq(alpha_T x) if (!vf0); + vf0 <= True; //True + f0 <= x; + endmethod + + method Action deq() if (vf0); + edge1.send(); + vf0 <= False; + endmethod + + method alpha_T first() if(vf0); + return (f0); + endmethod + + method Action clear(); + vf0 <= False; + endmethod + + method Bool find(search_T sv); + Bool nvf0 = edge1 ? False: vf0; + + return (nvf0 && searchfunc(sv, f0)); + endmethod + + method Bool find2(search_T sv); + Bool nvf0 = edge1 ? False: vf0; + return (nvf0 && searchfunc(sv, f0)); + endmethod + + method notEmpty() = vf0._read; + + method Bool notFull(); + return !vf0; + endmethod + +endmodule + +module mkSizedSFIFOInternal#(Integer n, + function Bool searchfunc1(search_T s, alpha_T x), + function Bool searchfunc2(search_T s, alpha_T x)) (SFIFO#(alpha_T, search_T)) + + provisos ( Bits#(alpha_T,alpha_SZ) ); + + List#(Reg#(alpha_T)) registers <- replicateM(n, mkRegU); + List#(Reg#(Bool)) valids <- replicateM(n, mkReg(False)); + + function Nat getNextFree (List#(Reg#(Bool)) vs); + + Nat res = fromInteger(n - 1); + + for (Integer x = n - 1; x > -1; x = x - 1) + res = !vs[x]._read() ? fromInteger(x) : res; + + return res; + + endfunction + + function Bool notFullHelper(); + + Bool full = True; + + for (Integer x = 0; x < n; x = x + 1) + full = full && valids[x]._read(); + + return !full; + + endfunction + + method Action enq( alpha_T item ) if ( notFullHelper() ); + + Nat k = getNextFree(valids); + select(valids, k)._write(True); + select(registers, k)._write(item); + + endmethod + + method Action deq() if ( valids[0]._read() ); + + for (Integer x = 0; x < (n-1); x = x + 1) + begin + + (registers[x]) <= registers[x + 1]._read(); + (valids[x]) <= valids[x + 1]._read(); + + end + (valids[n-1]) <= False; + endmethod + + method alpha_T first() if ( valids[0]._read() ); + return registers[0]._read(); + endmethod + + method Bool find(search_T sv); + Bool res = False; + + for (Integer x = 0; x < n; x = x + 1) + if ( valids[x]._read() && searchfunc1(sv, registers[x]._read()) ) + res = True; + + return res; + + endmethod + + method Bool find2(search_T sv); + Bool res = False; + + for (Integer x = 0; x < n; x = x + 1) + if ( valids[x]._read() && searchfunc2(sv, registers[x]._read()) ) + res = True; + + return res; + + endmethod + + method Action clear(); + + for (Integer x = 0; x < n; x = x + 1) + (valids[x]) <= False; + + endmethod + + method Bool notEmpty(); + return valids[0]._read(); + endmethod + + method Bool notFull(); + return notFullHelper(); + endmethod + +endmodule + +module mkSizedSFIFO#(Integer n, function Bool searchfunc(search_T s, alpha_T x)) (SFIFO#(alpha_T, search_T)) + provisos + (Bits#(alpha_T,asz)); + + let foo <- mkSizedSFIFOInternal(n, searchfunc, searchfunc); + return foo; + +endmodule \ No newline at end of file diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/lab4/processor.awb --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/lab4/processor.awb Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,13 @@ +%name 3-Stage Processor +%desc 3-Stage Processor, one stage per cycle. + +%provides processor + +%attributes 6_375 + +%public Processor.bsv ProcTypes.bsv +%public Processor.dic + + + + diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/lab4/processor_library.awb --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/lab4/processor_library.awb Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,8 @@ +%name Processor Library +%desc Some generally useful modules, found in the processor cores + +%provides processor_library + +%attributes 6_375 + +%public Trace.bsv BFIFO.bsv MemTypes.bsv FIFOUtility.bsv GetPutExt.bsv SFIFO.bsv CBUFF.bsv BRegFile.bsv BranchPred.bsv \ No newline at end of file diff -r 7393cd19371e -r 74716e9a81cc modules/bluespec/Pygar/lab4/processor_system.awb --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/bluespec/Pygar/lab4/processor_system.awb Fri Apr 23 02:32:05 2010 -0400 @@ -0,0 +1,20 @@ +%name Single Processor Application +%desc Top level processor. This module wraps a processor, which at its highest level is just a memory stream. + +%provides connected_application + +%requires core +%requires funcp_simulated_memory +%requires funcp_base_types +%requires hasim_common + +%attributes 6_375 + +%sources -t BSV -v PUBLIC ProcessorSystem.bsv +%sources -t CPP -v PUBLIC ProcessorSystem.cpp +%sources -t H -v PUBLIC ProcessorSystem.h +%sources -t CPP -v PUBLIC ProcessorSystemRRR.cpp +%sources -t H -v PUBLIC ProcessorSystemRRR.h +%sources -t RRR -v PUBLIC ProcessorSystemRRR.rrr + +