<commit_before>// Copyright (c) 2014 Quanta Research Cambridge, Inc.

// 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 FIFO::*;
import FIFOF::*;
import MIMO::*;
import DefaultValue::*;
import SpecialFIFOs::*;
import Vector::*;
import BRAM::*;
import DmaVector::*;
import PortalMemory::*;
import Dma::*;
import FloatingPoint::*;
import Pipe::*;
import FloatOps::*;
import Timer::*;
import RbmTypes::*;

interface DotProdServer#(numeric type n);
   interface Reg#(UInt#(20)) numElts;
   interface Put#(Tuple2#(Vector#(n,Float),Vector#(n,Float))) request;
   interface PipeOut#(Float) pipe;
endinterface

(* synthesize *)
module [Module] mkDotProdServer#(UInt#(TLog#(K)) label)(DotProdServer#(N));

   let n = valueOf(N);
   Bool verbose = False;

   Reg#(UInt#(20)) numEltsReg <- mkReg(0);
   Reg#(UInt#(20)) countInReg <- mkReg(0);
   Vector#(N,FIFOF#(Tuple3#(Bool,Float,Float))) abfifos <- replicateM(mkFIFOF());
   FIFOF#(Bool) lastFifo <- mkFIFOF();
   Vector#(N, PipeOut#(Tuple3#(Bool,Float,Float))) abpipes = map(toPipeOut,abfifos);

   Vector#(N, Server#(Tuple4#(Maybe#(Float), Float, Float, RoundMode), Tuple2#(Float,Exception))) macs <- replicateM(mkFloatMac);
   Vector#(N, FIFO#(Float)) accumFifo <- replicateM(mkFIFO());
   Vector#(N, FIFOF#(Float)) resultFifos <- replicateM(mkFIFOF());

   rule mul;
      for (Integer i = 0; i < valueOf(N); i = i + 1) begin
	 let v = abpipes[i].first;
	 abpipes[i].deq;
	 let isFirst = tpl_1(v);
	 let x = tpl_2(v);
	 let y = tpl_3(v);

	 Maybe#(Float) accum = tagged Invalid;
	 if (!isFirst) begin
	    accum = tagged Valid accumFifo[i].first();
	    accumFifo[i].deq();
	 end
            macs[i].request.put(tuple4(accum, x, y, defaultValue));
	 if (verbose) $display($format(fshow("label=")+fshow(label)+fshow(" dotprod x=") + fshow(x) + fshow(" y=") + fshow(y)
				       + fshow(" isFirst=") + fshow(isFirst) + fshow(" accum=")+fshow(pack(accum))));
      end
   endrule

   rule macout;
      let isLast = lastFifo.first();
      lastFifo.deq();
      for (Integer i = 0; i < valueOf(N); i = i + 1) begin
	 Float vi;
	 let resp <- macs[i].response.get();
	 vi = tpl_1(resp);
	 if (!isLast) begin
	    accumFifo[i].enq(vi);
	 end
	 else begin
	    resultFifos[i].enq(vi);
	    if (verbose) $display(fshow("label=")+fshow(label)+fshow(" isLast=")+fshow(isLast)+fshow(" mul=") + fshow(vi));
	 end
      end
   endrule

   Vector#(N, PipeOut#(Float)) resultPipes = map(toPipeOut, resultFifos);
   PipeOut#(Vector#(N,Float)) resultPipe <- mkJoinVector(id, resultPipes);
   PipeOut#(Float) dotpipe <- mkReducePipe(mkFloatAddPipe, resultPipe);
   PipeOut#(Float) displaydotpipe = (interface PipeOut#(Float);
      method Float first(); return dotpipe.first(); endmethod
      method Action deq(); $display(fshow("label=")+fshow(label)+fshow(" dotpipe=")+fshow(dotpipe.first())); dotpipe.deq(); endmethod
      method Bool notEmpty(); return dotpipe.notEmpty(); endmethod
      endinterface);
   interface Put request;
      method Action put(Tuple2#(Vector#(N,Float),Vector#(N,Float)) tpl);
	 Bool isFirst = (countInReg == 0);
	 UInt#(20) n = fromInteger(valueOf(N));
	 let c = countInReg+n;
	 Bool isLast = (c >= numEltsReg);
	 if (isLast)
	    c = 0;
	 countInReg <= c;
	 for (Integer i = 0; i < valueOf(N); i = i + 1) begin
	    let avec = tpl_1(tpl);
	    let bvec = tpl_2(tpl);
	    abfifos[i].enq(tuple3(isFirst,avec[i], bvec[i]));
	 end
	 lastFifo.enq(isLast);
      endmethod
   endinterface : request<commit_msg>another slight refactoring of mkDotProdServer<commit_after>// Copyright (c) 2014 Quanta Research Cambridge, Inc.

// 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 FIFO::*;
import FIFOF::*;
import MIMO::*;
import DefaultValue::*;
import SpecialFIFOs::*;
import Vector::*;
import BRAM::*;
import DmaVector::*;
import PortalMemory::*;
import Dma::*;
import FloatingPoint::*;
import Pipe::*;
import FloatOps::*;
import Timer::*;
import RbmTypes::*;

interface DotProdServer#(numeric type n);
   interface Reg#(UInt#(20)) numElts;
   interface Put#(Tuple2#(Vector#(n,Float),Vector#(n,Float))) request;
   interface PipeOut#(Float) pipe;
endinterface

(* synthesize *)
module [Module] mkDotProdServer#(UInt#(TLog#(K)) label)(DotProdServer#(N));

   let n = valueOf(N);
   Bool verbose = False;

   Reg#(UInt#(20)) numEltsReg <- mkReg(0);
   Reg#(UInt#(20)) countInReg <- mkReg(0);
   Vector#(N,FIFOF#(Tuple3#(Bool,Float,Float))) abfifos <- replicateM(mkFIFOF());
   Vector#(N,FIFOF#(Bool)) lastFifos <- replicateM(mkFIFOF());
   Vector#(N, PipeOut#(Tuple3#(Bool,Float,Float))) abpipes = map(toPipeOut,abfifos);

   Vector#(N, Server#(Tuple4#(Maybe#(Float), Float, Float, RoundMode), Tuple2#(Float,Exception))) macs <- replicateM(mkFloatMac);
   Vector#(N, FIFO#(Float)) accumFifo <- replicateM(mkFIFO());
   Vector#(N, FIFOF#(Float)) resultFifos <- replicateM(mkFIFOF());

   for (Integer i = 0; i < valueOf(N); i = i + 1) begin
      rule mul;
	 let v = abpipes[i].first;
	 abpipes[i].deq;
	 let isFirst = tpl_1(v);
	 let x = tpl_2(v);
	 let y = tpl_3(v);

	 Maybe#(Float) accum = tagged Invalid;
	 if (!isFirst) begin
	    accum = tagged Valid accumFifo[i].first();
	    accumFifo[i].deq();
	 end
         macs[i].request.put(tuple4(accum, x, y, defaultValue));
	 if (verbose) $display($format(fshow("label=")+fshow(label)+fshow(" dotprod x=") + fshow(x) + fshow(" y=") + fshow(y)
				       + fshow(" isFirst=") + fshow(isFirst) + fshow(" accum=")+fshow(pack(accum))));
      endrule
   end

   for (Integer i = 0; i < valueOf(N); i = i + 1) begin
      rule macout;
	 let isLast = lastFifos[i].first();
	 lastFifos[i].deq();
	 Float vi;
	 let resp <- macs[i].response.get();
	 vi = tpl_1(resp);
	 if (!isLast) begin
	    accumFifo[i].enq(vi);
	 end
	 else begin
	    resultFifos[i].enq(vi);
	    if (verbose) $display(fshow("label=")+fshow(label)+fshow(" isLast=")+fshow(isLast)+fshow(" mul=") + fshow(vi));
	 end
      endrule
   end

   Vector#(N, PipeOut#(Float)) resultPipes = map(toPipeOut, resultFifos);
   PipeOut#(Vector#(N,Float)) resultPipe <- mkJoinVector(id, resultPipes);
   PipeOut#(Float) dotpipe <- mkReducePipe(mkFloatAddPipe, resultPipe);
   PipeOut#(Float) displaydotpipe = (interface PipeOut#(Float);
      method Float first(); return dotpipe.first(); endmethod
      method Action deq(); $display(fshow("label=")+fshow(label)+fshow(" dotpipe=")+fshow(dotpipe.first())); dotpipe.deq(); endmethod
      method Bool notEmpty(); return dotpipe.notEmpty(); endmethod
      endinterface);
   interface Put request;
      method Action put(Tuple2#(Vector#(N,Float),Vector#(N,Float)) tpl);
	 Bool isFirst = (countInReg == 0);
	 UInt#(20) n = fromInteger(valueOf(N));
	 let c = countInReg+n;
	 Bool isLast = (c >= numEltsReg);
	 if (isLast)
	    c = 0;
	 countInReg <= c;
	 for (Integer i = 0; i < valueOf(N); i = i + 1) begin
	    let avec = tpl_1(tpl);
	    let bvec = tpl_2(tpl);
	    abfifos[i].enq(tuple3(isFirst,avec[i], bvec[i]));
	    lastFifos[i].enq(isLast);
	 end
      endmethod
   endinterface : request
{'fraction_non_alphanumeric': 0.1534216335540839, 'fraction_numerical': 0.007947019867549669, 'mean_word_length': 4.314369501466276, 'pattern_counts': {'":': 0, '<': 31, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6149185', 'n_tokens_mistral': 3250, 'n_tokens_neox': 2997, 'n_words': 887}