xsim requires FIRST_WORD_FALL_THROUGH = True rather than "TRUE"

// Copyright (c) 2015 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 Clocks::*;
import Vector::*;
import FIFO::*;
import FIFOF::*;
import BRAMFIFO::*;
import CBus::*; // extendNP and truncateNP

`include "ConnectalProjectConfig.bsv"
import Arith::*;
import ConnectalClocks::*;

`ifdef SIMULATION
`ifdef BOARD_xsim
`define USE_XILINX_MACRO
`endif // xsim
`else // not SIMULATION
`ifdef XILINX
`define USE_XILINX_MACRO
`endif // XILINX
`endif // not SIMULATION

`ifdef USE_XILINX_MACRO
(* always_ready, always_enabled *)
interface X7FifoSyncMacro#(numeric type data_width);
   method Bit#(1) empty();
   method Bit#(1) full();
   method Action din(Bit#(data_width) v);
   method Action wren(Bit#(1) wren);
   method Bit#(data_width) dout();
   method Action rden(Bit#(1) rden);
   method Bit#(9) wrcount();
   method Bit#(9) rdcount();
endinterface

import "BVI" FIFO_DUALCLOCK_MACRO =
module  vmkBramFifo#(String fifo_size, Clock wrClock, Reset wrReset, Clock rdClock, Reset rdReset)(X7FifoSyncMacro#(data_width));
`ifndef BSV_POSITIVE_RESET
   let positiveReset <- mkPositiveReset(10, wrReset, wrClock);
   let fifoReset = positiveReset.positiveReset;
`else
   let fifoReset = wrReset;
`endif
   parameter DEVICE = "7SERIES";
   parameter DATA_WIDTH = valueOf(data_width);
   parameter FIFO_SIZE = fifo_size;
   parameter FIRST_WORD_FALL_THROUGH = True;
   default_clock wrClock(WRCLK) = wrClock;
   no_reset;
   input_reset wrReset(RST) = fifoReset;
   input_clock rdClock(RDCLK) = rdClock;
   method EMPTY empty() clocked_by (rdClock) reset_by (wrReset);
   method FULL full() clocked_by (wrClock) reset_by (wrReset);
   method din(DI) enable ((*inhigh*)EN_di) clocked_by (wrClock) reset_by (wrReset);
   method wren(WREN) enable ((*inhigh*)EN_wren) clocked_by (wrClock) reset_by (wrReset);
   method DO dout() clocked_by (rdClock) reset_by (wrReset);
   method rden(RDEN) enable ((*inhigh*)EN_rden) clocked_by (rdClock) reset_by (wrReset);
   // wrcount and rdcount ports are needed for xsim
   method WRCOUNT wrcount() clocked_by (wrClock) reset_by (wrReset);
   method RDCOUNT rdcount() clocked_by (rdClock) reset_by (wrReset);
   schedule (empty, full, dout, din, wren, rden, wrcount, rdcount) CF (empty, full, dout, din, wren, rden, wrcount, rdcount);
endmodule

module mkDualClockBramFIFOF#(Clock srcClock, Reset srcReset, Clock dstClock, Reset dstReset)(FIFOF#(t))
   provisos (Bits#(t,sizet),
	     Add#(1,a__,sizet));
   String fifo_size = "18Kb";
   Vector#(TDiv#(sizet,36),X7FifoSyncMacro#(36)) fifos <- replicateM(vmkBramFifo(fifo_size, srcClock, srcReset, dstClock, dstReset));
   Wire#(Bit#(1)) rdenWire <- mkDWire(0, clocked_by dstClock, reset_by dstReset);
   Wire#(Bit#(1)) wrenWire <- mkDWire(0, clocked_by srcClock, reset_by srcReset);
   Vector#(TDiv#(sizet,36),Wire#(Bit#(36))) dinWires <- replicateM(mkDWire(0, clocked_by srcClock, reset_by srcReset));

   for (Integer i = 0; i < valueOf(TDiv#(sizet,36)); i = i+1) begin
      Reg#(Bit#(9)) rdcount <- mkReg(0, clocked_by dstClock, reset_by dstReset);
      Reg#(Bit#(9)) wrcount <- mkReg(0, clocked_by srcClock, reset_by srcReset);
      rule rdenRule;
	 fifos[i].rden(rdenWire);
      endrule
      rule wrenRule;
	 fifos[i].wren(wrenWire);
      endrule
      rule inputs;
	 fifos[i].din(dinWires[i]);
      endrule
      rule countrds;
	 rdcount <= fifos[i].rdcount();
      endrule
      rule countwrs;
	 wrcount <= fifos[i].wrcount();
      endrule
   end

   method t first() if (fifos[0].empty == 0);
      function Bit#(36) fifoFirst(Integer i); return fifos[i].dout(); endfunction
      Vector#(TDiv#(sizet,36), Bit#(36)) v = genWith(fifoFirst);
      return unpack(truncateNP(pack(v)));
   endmethod
   method Action deq() if (fifos[0].empty == 0);
      rdenWire <= 1;
   endmethod
   method notEmpty = (fifos[0].empty == 0);
   method Action enq(t v) if (fifos[0].full == 0);
      Vector#(TDiv#(sizet,36), Bit#(36)) vs = unpack(extendNP(pack(v)));
      Vector#(TDiv#(sizet,36), Integer) indices = genVector();
      function Action fifoEnq(Integer i); action dinWires[i] <= vs[i]; endaction endfunction
      mapM_(fifoEnq, indices);
      wrenWire <= 1;
   endmethod
   method notFull = (fifos[0].full == 0);
endmodule

module mkDualClockBramFIFO#(Clock srcClock, Reset srcReset, Clock dstClock, Reset dstReset)(FIFO#(t))
   provisos (Bits#(t,sizet),
	     Add#(1,a__,sizet));

   let syncFifo <- mkDualClockBramFIFOF(srcClock, srcReset, dstClock, dstReset);
   method enq = syncFifo.enq;
   method deq = syncFifo.deq;
   method first = syncFifo.first;
endmodule

`else // compatibility mode
module mkDualClockBramFIFOF#(Clock srcClock, Reset srcReset, Clock dstClock, Reset dstReset)(FIFOF#(t))
   provisos (Bits#(t,sizet),
	     Add#(1,a__,sizet));
   let syncFifo <- mkSyncFIFO(512, srcClock, srcReset, dstClock);
   method enq = syncFifo.enq;
   method deq = syncFifo.deq;
   method first = syncFifo.first;
   method notFull = syncFifo.notFull;
   method notEmpty = syncFifo.notEmpty;
endmodule
module mkDualClockBramFIFO#(Clock srcClock, Reset srcReset, Clock dstClock, Reset dstReset)(FIFO#(t))
   provisos (Bits#(t,sizet),
	     Add#(1,a__,sizet));

   let syncFifo <- mkSyncFIFO(512, srcClock, srcReset, dstClock);
   method enq = syncFifo.enq;
   method deq = syncFifo.deq;
   method first = syncFifo.first;
endmodule
`endif

// Copyright (c) 2015 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 Clocks::*;
import Vector::*;
import FIFO::*;
import FIFOF::*;
import BRAMFIFO::*;
import CBus::*; // extendNP and truncateNP

`include "ConnectalProjectConfig.bsv"
import Arith::*;
import ConnectalClocks::*;

`ifdef SIMULATION
`ifdef BOARD_xsim
`define USE_XILINX_MACRO
`endif // xsim
`else // not SIMULATION
`ifdef XILINX
`define USE_XILINX_MACRO
`endif // XILINX
`endif // not SIMULATION

`ifdef USE_XILINX_MACRO
(* always_ready, always_enabled *)
interface X7FifoSyncMacro#(numeric type data_width);
   method Bit#(1) empty();
   method Bit#(1) full();
   method Action din(Bit#(data_width) v);
   method Action wren(Bit#(1) wren);
   method Bit#(data_width) dout();
   method Action rden(Bit#(1) rden);
   method Bit#(9) wrcount();
   method Bit#(9) rdcount();
endinterface

import "BVI" FIFO_DUALCLOCK_MACRO =
module  vmkBramFifo#(String fifo_size, Clock wrClock, Reset wrReset, Clock rdClock, Reset rdReset)(X7FifoSyncMacro#(data_width));
`ifndef BSV_POSITIVE_RESET
   let positiveReset <- mkPositiveReset(10, wrReset, wrClock);
   let fifoReset = positiveReset.positiveReset;
`else
   let fifoReset = wrReset;
`endif
   parameter DEVICE = "7SERIES";
   parameter DATA_WIDTH = valueOf(data_width);
   parameter FIFO_SIZE = fifo_size;
   parameter FIRST_WORD_FALL_THROUGH = "TRUE";
   default_clock wrClock(WRCLK) = wrClock;
   no_reset;
   input_reset wrReset(RST) = fifoReset;
   input_clock rdClock(RDCLK) = rdClock;
   method EMPTY empty() clocked_by (rdClock) reset_by (wrReset);
   method FULL full() clocked_by (wrClock) reset_by (wrReset);
   method din(DI) enable ((*inhigh*)EN_di) clocked_by (wrClock) reset_by (wrReset);
   method wren(WREN) enable ((*inhigh*)EN_wren) clocked_by (wrClock) reset_by (wrReset);
   method DO dout() clocked_by (rdClock) reset_by (wrReset);
   method rden(RDEN) enable ((*inhigh*)EN_rden) clocked_by (rdClock) reset_by (wrReset);
   // wrcount and rdcount ports are needed for xsim
   method WRCOUNT wrcount() clocked_by (wrClock) reset_by (wrReset);
   method RDCOUNT rdcount() clocked_by (rdClock) reset_by (wrReset);
   schedule (empty, full, dout, din, wren, rden, wrcount, rdcount) CF (empty, full, dout, din, wren, rden, wrcount, rdcount);
endmodule

module mkDualClockBramFIFOF#(Clock srcClock, Reset srcReset, Clock dstClock, Reset dstReset)(FIFOF#(t))
   provisos (Bits#(t,sizet),
	     Add#(1,a__,sizet));
   String fifo_size = "18Kb";
   Vector#(TDiv#(sizet,36),X7FifoSyncMacro#(36)) fifos <- replicateM(vmkBramFifo(fifo_size, srcClock, srcReset, dstClock, dstReset));
   Wire#(Bit#(1)) rdenWire <- mkDWire(0, clocked_by dstClock, reset_by dstReset);
   Wire#(Bit#(1)) wrenWire <- mkDWire(0, clocked_by srcClock, reset_by srcReset);
   Vector#(TDiv#(sizet,36),Wire#(Bit#(36))) dinWires <- replicateM(mkDWire(0, clocked_by srcClock, reset_by srcReset));

   for (Integer i = 0; i < valueOf(TDiv#(sizet,36)); i = i+1) begin
      Reg#(Bit#(9)) rdcount <- mkReg(0, clocked_by dstClock, reset_by dstReset);
      Reg#(Bit#(9)) wrcount <- mkReg(0, clocked_by srcClock, reset_by srcReset);
      rule rdenRule;
	 fifos[i].rden(rdenWire);
      endrule
      rule wrenRule;
	 fifos[i].wren(wrenWire);
      endrule
      rule inputs;
	 fifos[i].din(dinWires[i]);
      endrule
      rule countrds;
	 rdcount <= fifos[i].rdcount();
      endrule
      rule countwrs;
	 wrcount <= fifos[i].wrcount();
      endrule
   end

   method t first() if (fifos[0].empty == 0);
      function Bit#(36) fifoFirst(Integer i); return fifos[i].dout(); endfunction
      Vector#(TDiv#(sizet,36), Bit#(36)) v = genWith(fifoFirst);
      return unpack(truncateNP(pack(v)));
   endmethod
   method Action deq() if (fifos[0].empty == 0);
      rdenWire <= 1;
   endmethod
   method notEmpty = (fifos[0].empty == 0);
   method Action enq(t v) if (fifos[0].full == 0);
      Vector#(TDiv#(sizet,36), Bit#(36)) vs = unpack(extendNP(pack(v)));
      Vector#(TDiv#(sizet,36), Integer) indices = genVector();
      function Action fifoEnq(Integer i); action dinWires[i] <= vs[i]; endaction endfunction
      mapM_(fifoEnq, indices);
      wrenWire <= 1;
   endmethod
   method notFull = (fifos[0].full == 0);
endmodule

module mkDualClockBramFIFO#(Clock srcClock, Reset srcReset, Clock dstClock, Reset dstReset)(FIFO#(t))
   provisos (Bits#(t,sizet),
	     Add#(1,a__,sizet));

   let syncFifo <- mkDualClockBramFIFOF(srcClock, srcReset, dstClock, dstReset);
   method enq = syncFifo.enq;
   method deq = syncFifo.deq;
   method first = syncFifo.first;
endmodule

`else // compatibility mode
module mkDualClockBramFIFOF#(Clock srcClock, Reset srcReset, Clock dstClock, Reset dstReset)(FIFOF#(t))
   provisos (Bits#(t,sizet),
	     Add#(1,a__,sizet));
   let syncFifo <- mkSyncFIFO(512, srcClock, srcReset, dstClock);
   method enq = syncFifo.enq;
   method deq = syncFifo.deq;
   method first = syncFifo.first;
   method notFull = syncFifo.notFull;
   method notEmpty = syncFifo.notEmpty;
endmodule
module mkDualClockBramFIFO#(Clock srcClock, Reset srcReset, Clock dstClock, Reset dstReset)(FIFO#(t))
   provisos (Bits#(t,sizet),
	     Add#(1,a__,sizet));

   let syncFifo <- mkSyncFIFO(512, srcClock, srcReset, dstClock);
   method enq = syncFifo.enq;
   method deq = syncFifo.deq;
   method first = syncFifo.first;
endmodule
`endif


changing bypass fifos to normal fifos in mkDmaWriteNoBuffer/mkDmaReadNoBuffer.  I need to take a closer look to see what fifos are needed to maintain full throughput

// Copyright (c) 2013 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 BRAM::*;
import FIFO::*;
import Vector::*;
import Gearbox::*;
import FIFOF::*;
import SpecialFIFOs::*;

import BRAMFIFOFLevel::*;
import GetPutF::*;
import Dma::*;

interface DmaReadServer2BRAM#(type a);
   method Action start(DmaPointer h, a x);
   method ActionValue#(Bool) finished();
endinterface

module mkDmaReadServer2BRAM#(DmaReadServer#(busWidth) rs, BRAMServer#(a,d) br)(DmaReadServer2BRAM#(a))
   provisos(Bits#(d,dsz),
	    Div#(busWidth,dsz,nd),
	    Mul#(nd,dsz,busWidth),
	    Div#(busWidth,8,nb),
	    Eq#(a),
	    Ord#(a),
	    Arith#(a),
	    Bits#(a,b__),
	    Add#(d__,b__,DmaOffsetSize),
	    Add#(1, c__, nd),
	    Add#(a__, dsz, busWidth));

   Clock clk <- exposeCurrentClock;
   Reset rst <- exposeCurrentReset;

   FIFO#(void) f <- mkSizedFIFO(1);
   Gearbox#(nd,1,d) gb <- mkNto1Gearbox(clk,rst,clk,rst);
   Reg#(a) i <- mkReg(0);
   Reg#(Bool) iv <- mkReg(False);
   Reg#(a) j <- mkReg(0);
   Reg#(Bool) jv <- mkReg(False);
   Reg#(a) n <- mkReg(0);
   Reg#(DmaPointer) ptr <- mkReg(0);
   Reg#(Bit#(DmaOffsetSize)) off <- mkReg(0);

   rule loadReq(iv);
      //$display("lloadReq %d %d", ptr, i);
      rs.readReq.put(DmaRequest {pointer: ptr, offset: off, burstLen: 1, tag: 0});
      i <= i+fromInteger(valueOf(nd));
      off <= off+fromInteger(valueOf(nb));
      iv <= (i < n);
   endrule

   rule loadResp;
      let rv <- rs.readData.get();
      Vector#(nd,d) rvv = unpack(rv.data);
      gb.enq(rvv);
   endrule

   rule load(jv);
      //$display("%d %d", ptr, gb.first[0]);
      br.request.put(BRAMRequest{write:True, responseOnWrite:False, address:j, datain:gb.first[0]});
      gb.deq;
      jv <= (j < n);
      j <= j+1;
      if (j == n)
	 f.enq(?);
   endrule

   rule discard(!jv);
      gb.deq;
   endrule

   method Action start(DmaPointer h, a x);
      iv <= True;
      jv <= True;
      i <= 0;
      j <= 0;
      n <= x;
      ptr <= h;
      off <= 0;
   endmethod

   method ActionValue#(Bool) finished();
      f.deq;
      return True;
   endmethod

endmodule

//
// @brief A buffer for reading from a bus of width bsz.
//
// @param bsz The number of bits in the bus.
// @param maxBurst The number of words to buffer
//
interface DmaReadBuffer#(numeric type bsz, numeric type maxBurst);
   interface DmaReadServer #(bsz) dmaServer;
   interface DmaReadClient#(bsz) dmaClient;
endinterface

//
// @brief A buffer for writing to a bus of width bsz.
//
// @param bsz The number of bits in the bus.
// @param maxBurst The number of words to buffer
//
interface DmaWriteBuffer#(numeric type bsz, numeric type maxBurst);
   interface DmaWriteServer#(bsz) dmaServer;
   interface DmaWriteClient#(bsz) dmaClient;
endinterface

//
// @brief Makes a Dma buffer for reading wordSize words from memory.
//
// @param bsz The width of the bus in bits.
// @param maxBurst The max number of words to transfer per request.
//
module mkDmaReadBuffer(DmaReadBuffer#(bsz, maxBurst))
   provisos(Add#(1,a__,bsz),
	    Add#(b__, TAdd#(1,TLog#(maxBurst)), 8));

   FIFOFLevel#(DmaData#(bsz),maxBurst)  readBuffer <- mkBRAMFIFOFLevel;
   FIFOF#(DmaRequest)        reqOutstanding <- mkFIFOF();
   Ratchet#(TAdd#(1,TLog#(maxBurst))) unfulfilled <- mkRatchet(0);

   // only issue the readRequest when sufficient buffering is available.  This includes the bufering we have already comitted.
   Bit#(TAdd#(1,TLog#(maxBurst))) sreq = pack(satPlus(Sat_Bound, unpack(truncate(reqOutstanding.first.burstLen)), unfulfilled.read()));

   interface DmaReadServer dmaServer;
      interface PutF readReq = toPutF(reqOutstanding);
      interface GetF readData = toGetF(readBuffer);
   endinterface
   interface DmaReadClient dmaClient;
      interface GetF readReq;
	 method ActionValue#(DmaRequest) get if (readBuffer.lowWater(sreq));
	    reqOutstanding.deq;
	    unfulfilled.increment(unpack(truncate(reqOutstanding.first.burstLen)));
	    return reqOutstanding.first;
	 endmethod
         method Bool notEmpty();
	    return readBuffer.lowWater(sreq);
	 endmethod
      endinterface
      interface PutF readData;
	 method Action put(DmaData#(bsz) x);
	    readBuffer.fifo.enq(x);
	    unfulfilled.decrement(1);
	 endmethod
	 method notFull();
	    return readBuffer.fifo.notFull();
	 endmethod
      endinterface
   endinterface
endmodule

module mkDmaReadNoBuffer(DmaReadBuffer#(bsz, maxBurst));

   FIFOF#(DmaData#(bsz)) dataFifo <- mkFIFOF;
   FIFOF#(DmaRequest)     reqFifo <- mkFIFOF;
   Reg#(Bit#(32))     outstanding <- mkReg(0);

   interface DmaReadServer dmaServer;
      interface PutF readReq;
	 method Action put(DmaRequest req);
	    reqFifo.enq(req);
	    outstanding <= outstanding+extend(req.burstLen);
	 endmethod
	 method Bool notFull;
	    return reqFifo.notFull;
	 endmethod
      endinterface
      interface GetF readData = toGetF(dataFifo);
   endinterface

   interface DmaReadClient dmaClient;
      interface GetF readReq = toGetF(reqFifo);
      interface PutF readData;
	 method Action put(DmaData#(bsz) data);
	    dataFifo.enq(data);
	    outstanding <= outstanding-1;
	 endmethod
	 method Bool notFull;
	    return outstanding > 0;
	 endmethod
      endinterface
   endinterface

endmodule

//
// @brief Makes a Dma channel for writing wordSize words from memory.
//
// @param bsz The width of the bus in bits.
// @param maxBurst The max number of words to transfer per request.
//
module mkDmaWriteBuffer(DmaWriteBuffer#(bsz, maxBurst))
   provisos(Add#(1,a__,bsz),
	    Add#(b__, TAdd#(1, TLog#(maxBurst)), 8));

   FIFOFLevel#(DmaData#(bsz),maxBurst) writeBuffer <- mkBRAMFIFOFLevel;
   FIFOF#(DmaRequest)        reqOutstanding <- mkFIFOF();
   FIFOF#(Bit#(6))                        doneTags <- mkFIFOF();
   Ratchet#(TAdd#(1,TLog#(maxBurst)))  unfulfilled <- mkRatchet(0);

   // only issue the writeRequest when sufficient data is available.  This includes the data we have already comitted.
   Bit#(TAdd#(1,TLog#(maxBurst))) sreq = pack(satPlus(Sat_Bound, unpack(truncate(reqOutstanding.first.burstLen)), unfulfilled.read()));

   interface DmaWriteServer dmaServer;
      interface PutF writeReq = toPutF(reqOutstanding);
      interface PutF writeData = toPutF(writeBuffer);
      interface GetF writeDone = toGetF(doneTags);
   endinterface
   interface DmaWriteClient dmaClient;
      interface GetF writeReq;
	 method ActionValue#(DmaRequest) get if (writeBuffer.highWater(sreq));
	    reqOutstanding.deq;
	    unfulfilled.increment(unpack(truncate(reqOutstanding.first.burstLen)));
	    return reqOutstanding.first;
	 endmethod
	 method Bool notEmpty();
	    return writeBuffer.highWater(sreq);
	 endmethod
      endinterface
      interface GetF writeData;
	 method ActionValue#(DmaData#(bsz)) get();
	    unfulfilled.decrement(1);
	    writeBuffer.fifo.deq;
	    return writeBuffer.fifo.first;
	 endmethod
	 method Bool notEmpty();
	    return writeBuffer.fifo.notEmpty;
	 endmethod
      endinterface
      interface PutF writeDone = toPutF(doneTags);
   endinterface
endmodule

module mkDmaWriteNoBuffer(DmaWriteBuffer#(bsz, maxBurst));

   FIFOF#(DmaData#(bsz)) dataFifo <- mkFIFOF;
   FIFOF#(DmaRequest)     reqFifo <- mkFIFOF;
   FIFOF#(Bit#(6))       doneFifo <- mkFIFOF;

   interface DmaWriteServer dmaServer;
      interface PutF writeReq  = toPutF(reqFifo);
      interface PutF writeData = toPutF(dataFifo);
      interface GetF writeDone = toGetF(doneFifo);
   endinterface

   interface DmaWriteClient dmaClient;
      interface GetF writeReq = toGetF(reqFifo);
      interface GetF writeData = toGetF(dataFifo);
      interface PutF writeDone = toPutF(doneFifo);
   endinterface

endmodule

// Copyright (c) 2013 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 BRAM::*;
import FIFO::*;
import Vector::*;
import Gearbox::*;
import FIFOF::*;
import SpecialFIFOs::*;

import BRAMFIFOFLevel::*;
import GetPutF::*;
import Dma::*;

interface DmaReadServer2BRAM#(type a);
   method Action start(DmaPointer h, a x);
   method ActionValue#(Bool) finished();
endinterface

module mkDmaReadServer2BRAM#(DmaReadServer#(busWidth) rs, BRAMServer#(a,d) br)(DmaReadServer2BRAM#(a))
   provisos(Bits#(d,dsz),
	    Div#(busWidth,dsz,nd),
	    Mul#(nd,dsz,busWidth),
	    Div#(busWidth,8,nb),
	    Eq#(a),
	    Ord#(a),
	    Arith#(a),
	    Bits#(a,b__),
	    Add#(d__,b__,DmaOffsetSize),
	    Add#(1, c__, nd),
	    Add#(a__, dsz, busWidth));

   Clock clk <- exposeCurrentClock;
   Reset rst <- exposeCurrentReset;

   FIFO#(void) f <- mkSizedFIFO(1);
   Gearbox#(nd,1,d) gb <- mkNto1Gearbox(clk,rst,clk,rst);
   Reg#(a) i <- mkReg(0);
   Reg#(Bool) iv <- mkReg(False);
   Reg#(a) j <- mkReg(0);
   Reg#(Bool) jv <- mkReg(False);
   Reg#(a) n <- mkReg(0);
   Reg#(DmaPointer) ptr <- mkReg(0);
   Reg#(Bit#(DmaOffsetSize)) off <- mkReg(0);

   rule loadReq(iv);
      //$display("lloadReq %d %d", ptr, i);
      rs.readReq.put(DmaRequest {pointer: ptr, offset: off, burstLen: 1, tag: 0});
      i <= i+fromInteger(valueOf(nd));
      off <= off+fromInteger(valueOf(nb));
      iv <= (i < n);
   endrule

   rule loadResp;
      let rv <- rs.readData.get();
      Vector#(nd,d) rvv = unpack(rv.data);
      gb.enq(rvv);
   endrule

   rule load(jv);
      //$display("%d %d", ptr, gb.first[0]);
      br.request.put(BRAMRequest{write:True, responseOnWrite:False, address:j, datain:gb.first[0]});
      gb.deq;
      jv <= (j < n);
      j <= j+1;
      if (j == n)
	 f.enq(?);
   endrule

   rule discard(!jv);
      gb.deq;
   endrule

   method Action start(DmaPointer h, a x);
      iv <= True;
      jv <= True;
      i <= 0;
      j <= 0;
      n <= x;
      ptr <= h;
      off <= 0;
   endmethod

   method ActionValue#(Bool) finished();
      f.deq;
      return True;
   endmethod

endmodule

//
// @brief A buffer for reading from a bus of width bsz.
//
// @param bsz The number of bits in the bus.
// @param maxBurst The number of words to buffer
//
interface DmaReadBuffer#(numeric type bsz, numeric type maxBurst);
   interface DmaReadServer #(bsz) dmaServer;
   interface DmaReadClient#(bsz) dmaClient;
endinterface

//
// @brief A buffer for writing to a bus of width bsz.
//
// @param bsz The number of bits in the bus.
// @param maxBurst The number of words to buffer
//
interface DmaWriteBuffer#(numeric type bsz, numeric type maxBurst);
   interface DmaWriteServer#(bsz) dmaServer;
   interface DmaWriteClient#(bsz) dmaClient;
endinterface

//
// @brief Makes a Dma buffer for reading wordSize words from memory.
//
// @param bsz The width of the bus in bits.
// @param maxBurst The max number of words to transfer per request.
//
module mkDmaReadBuffer(DmaReadBuffer#(bsz, maxBurst))
   provisos(Add#(1,a__,bsz),
	    Add#(b__, TAdd#(1,TLog#(maxBurst)), 8));

   FIFOFLevel#(DmaData#(bsz),maxBurst)  readBuffer <- mkBRAMFIFOFLevel;
   FIFOF#(DmaRequest)        reqOutstanding <- mkFIFOF();
   Ratchet#(TAdd#(1,TLog#(maxBurst))) unfulfilled <- mkRatchet(0);

   // only issue the readRequest when sufficient buffering is available.  This includes the bufering we have already comitted.
   Bit#(TAdd#(1,TLog#(maxBurst))) sreq = pack(satPlus(Sat_Bound, unpack(truncate(reqOutstanding.first.burstLen)), unfulfilled.read()));

   interface DmaReadServer dmaServer;
      interface PutF readReq = toPutF(reqOutstanding);
      interface GetF readData = toGetF(readBuffer);
   endinterface
   interface DmaReadClient dmaClient;
      interface GetF readReq;
	 method ActionValue#(DmaRequest) get if (readBuffer.lowWater(sreq));
	    reqOutstanding.deq;
	    unfulfilled.increment(unpack(truncate(reqOutstanding.first.burstLen)));
	    return reqOutstanding.first;
	 endmethod
         method Bool notEmpty();
	    return readBuffer.lowWater(sreq);
	 endmethod
      endinterface
      interface PutF readData;
	 method Action put(DmaData#(bsz) x);
	    readBuffer.fifo.enq(x);
	    unfulfilled.decrement(1);
	 endmethod
	 method notFull();
	    return readBuffer.fifo.notFull();
	 endmethod
      endinterface
   endinterface
endmodule

module mkDmaReadNoBuffer(DmaReadBuffer#(bsz, maxBurst));

   FIFOF#(DmaData#(bsz)) dataFifo <- mkSizedBypassFIFOF(1);
   FIFOF#(DmaRequest)     reqFifo <- mkSizedBypassFIFOF(1);
   Reg#(Bit#(32))     outstanding <- mkReg(0);

   interface DmaReadServer dmaServer;
      interface PutF readReq;
	 method Action put(DmaRequest req);
	    reqFifo.enq(req);
	    outstanding <= outstanding+extend(req.burstLen);
	 endmethod
	 method Bool notFull;
	    return reqFifo.notFull;
	 endmethod
      endinterface
      interface GetF readData = toGetF(dataFifo);
   endinterface

   interface DmaReadClient dmaClient;
      interface GetF readReq = toGetF(reqFifo);
      interface PutF readData;
	 method Action put(DmaData#(bsz) data);
	    dataFifo.enq(data);
	    outstanding <= outstanding-1;
	 endmethod
	 method Bool notFull;
	    return outstanding > 0;
	 endmethod
      endinterface
   endinterface

endmodule

//
// @brief Makes a Dma channel for writing wordSize words from memory.
//
// @param bsz The width of the bus in bits.
// @param maxBurst The max number of words to transfer per request.
//
module mkDmaWriteBuffer(DmaWriteBuffer#(bsz, maxBurst))
   provisos(Add#(1,a__,bsz),
	    Add#(b__, TAdd#(1, TLog#(maxBurst)), 8));

   FIFOFLevel#(DmaData#(bsz),maxBurst) writeBuffer <- mkBRAMFIFOFLevel;
   FIFOF#(DmaRequest)        reqOutstanding <- mkFIFOF();
   FIFOF#(Bit#(6))                        doneTags <- mkFIFOF();
   Ratchet#(TAdd#(1,TLog#(maxBurst)))  unfulfilled <- mkRatchet(0);

   // only issue the writeRequest when sufficient data is available.  This includes the data we have already comitted.
   Bit#(TAdd#(1,TLog#(maxBurst))) sreq = pack(satPlus(Sat_Bound, unpack(truncate(reqOutstanding.first.burstLen)), unfulfilled.read()));

   interface DmaWriteServer dmaServer;
      interface PutF writeReq = toPutF(reqOutstanding);
      interface PutF writeData = toPutF(writeBuffer);
      interface GetF writeDone = toGetF(doneTags);
   endinterface
   interface DmaWriteClient dmaClient;
      interface GetF writeReq;
	 method ActionValue#(DmaRequest) get if (writeBuffer.highWater(sreq));
	    reqOutstanding.deq;
	    unfulfilled.increment(unpack(truncate(reqOutstanding.first.burstLen)));
	    return reqOutstanding.first;
	 endmethod
	 method Bool notEmpty();
	    return writeBuffer.highWater(sreq);
	 endmethod
      endinterface
      interface GetF writeData;
	 method ActionValue#(DmaData#(bsz)) get();
	    unfulfilled.decrement(1);
	    writeBuffer.fifo.deq;
	    return writeBuffer.fifo.first;
	 endmethod
	 method Bool notEmpty();
	    return writeBuffer.fifo.notEmpty;
	 endmethod
      endinterface
      interface PutF writeDone = toPutF(doneTags);
   endinterface
endmodule

module mkDmaWriteNoBuffer(DmaWriteBuffer#(bsz, maxBurst));

   FIFOF#(DmaData#(bsz)) dataFifo <- mkSizedBypassFIFOF(1);
   FIFOF#(DmaRequest)     reqFifo <- mkSizedBypassFIFOF(1);
   FIFOF#(Bit#(6))       doneFifo <- mkSizedBypassFIFOF(1);

   interface DmaWriteServer dmaServer;
      interface PutF writeReq  = toPutF(reqFifo);
      interface PutF writeData = toPutF(dataFifo);
      interface GetF writeDone = toGetF(doneFifo);
   endinterface

   interface DmaWriteClient dmaClient;
      interface GetF writeReq = toGetF(reqFifo);
      interface GetF writeData = toGetF(dataFifo);
      interface PutF writeDone = toPutF(doneFifo);
   endinterface

endmodule


[RISCV] clean up trailing spaces

[RISCV] clean up trailing spaces

/*

Copyright (C) 2012

Arvind <arvind@csail.mit.edu>
Muralidaran Vijayaraghavan <vmurali@csail.mit.edu>

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 Types::*;
import FShow::*;
import MemTypes::*;

// cpu to host data type
typedef enum {
    ExitCode = 2'd0,
    PrintChar = 2'd1,
    PrintIntLow = 2'd2,
    PrintIntHigh = 2'd3
} CpuToHostType deriving(Bits, Eq, FShow);

typedef struct {
    CpuToHostType c2hType;
    Bit#(16) data;
} CpuToHostData deriving(Bits, Eq, FShow);

interface Proc;
    method ActionValue#(CpuToHostData) cpuToHost;
    method Action hostToCpu(Addr startpc);
endinterface

// general purpose reg index
typedef Bit#(5) RIndx;

// opcode
typedef Bit#(7) Opcode;
Opcode opLoad    = 7'b0000011;
Opcode opMiscMem = 7'b0001111;
Opcode opOpImm   = 7'b0010011;
Opcode opAuipc   = 7'b0010111;
Opcode opStore   = 7'b0100011;
Opcode opAmo     = 7'b0101111;
Opcode opOp      = 7'b0110011;
Opcode opLui     = 7'b0110111;
Opcode opBranch  = 7'b1100011;
Opcode opJalr    = 7'b1100111;
Opcode opJal     = 7'b1101111;
Opcode opSystem  = 7'b1110011;

// CSR index
typedef Bit#(12) CsrIndx;
CsrIndx csrInstret = 12'hc02;
CsrIndx csrCycle   = 12'hc00;
CsrIndx csrMhartid = 12'hf10;
CsrIndx csrMdcsr   = 12'h7b0;

// LR, SC, FENCE not implemented
// LB(U), LH(U), SB, SH not implemented

// For CSR, only following two are implemented
// CSRR rd csr (i.e. CSRRS rd csr x0)
// CSRW csr rs1 (i.e. CSRRW x0 csr rs1)

// SCALL, SBREAK not implemented

typedef enum {
    Unsupported,
    Alu,
    Ld,
    St,
    J,
    Jr,
    Br,
    Csrr,
    Csrw,
    Auipc
} IType deriving(Bits, Eq, FShow);

typedef enum {
    Eq,
    Neq,
    Lt,
    Ltu,
    Ge,
    Geu,
    AT,
    NT
} BrFunc deriving(Bits, Eq, FShow);

typedef enum {
    Add,
    Sub,
    And,
    Or,
    Xor,
    Slt,
    Sltu,
    Sll,
    Sra,
    Srl
} AluFunc deriving(Bits, Eq, FShow);

typedef void Exception;

typedef struct {
    Addr pc;
    Addr nextPc;
    IType brType;
    Bool taken;
    Bool mispredict;
} Redirect deriving (Bits, Eq, FShow);

typedef struct {
    IType            iType;
    AluFunc          aluFunc;
    BrFunc           brFunc;
    Maybe#(RIndx)    dst;
    Maybe#(RIndx)    src1;
    Maybe#(RIndx)    src2;
    Maybe#(CsrIndx)  csr;
    Maybe#(Data)     imm;
} DecodedInst deriving(Bits, Eq, FShow);

typedef struct {
    IType            iType;
    Maybe#(RIndx)    dst;
    Maybe#(CsrIndx)  csr;
    Data             data;
    Addr             addr;
    Bool             mispredict;
    Bool             brTaken;
} ExecInst deriving(Bits, Eq, FShow);

// function code
// ALU
Bit#(3) fnADD   = 3'b000;
Bit#(3) fnSLL   = 3'b001;
Bit#(3) fnSLT   = 3'b010;
Bit#(3) fnSLTU  = 3'b011;
Bit#(3) fnXOR   = 3'b100;
Bit#(3) fnSR    = 3'b101;
Bit#(3) fnOR    = 3'b110;
Bit#(3) fnAND   = 3'b111;
// Branch
Bit#(3) fnBEQ   = 3'b000;
Bit#(3) fnBNE   = 3'b001;
Bit#(3) fnBLT   = 3'b100;
Bit#(3) fnBGE   = 3'b101;
Bit#(3) fnBLTU  = 3'b110;
Bit#(3) fnBGEU  = 3'b111;
// Load
Bit#(3) fnLW    = 3'b010;
//Bit#(3) fnLB    = 3'b000;
//Bit#(3) fnLH    = 3'b001;
Bit#(3) fnLBU   = 3'b100;
//Bit#(3) fnLHU   = 3'b101;
// Store
Bit#(3) fnSW    = 3'b010;
//Bit#(3) fnSB    = 3'b000;
//Bit#(3) fnSH    = 3'b001;
// Amo
Bit#(5) fnLR    = 5'b00010;
Bit#(5) fnSC    = 5'b00011;
//MiscMem
Bit#(3) fnFENCE  = 3'b000;
//Bit#(3) fnFENCEI = 3'b001;
// System
Bit#(3) fnCSRRW  = 3'b001;
Bit#(3) fnCSRRS  = 3'b010;
//Bit#(3) fnCSRRC  = 3'b011;
//Bit#(3) fnCSRRWI = 3'b101;
//Bit#(3) fnCSRRSI = 3'b110;
//Bit#(3) fnCSRRCI = 3'b111;
Bit#(3) fnPRIV   = 3'b000;
Bit#(12) privSCALL    = 12'h000;

function Bool dataHazard(Maybe#(RIndx) src1, Maybe#(RIndx) src2, Maybe#(RIndx) dst);
    return (isValid(dst) && ((isValid(src1) && fromMaybe(?, dst)==fromMaybe(?, src1)) ||
                             (isValid(src2) && fromMaybe(?, dst)==fromMaybe(?, src2))));
endfunction

// pretty print instuction
function Fmt showInst(Instruction inst);
    Fmt ret = $format("");

    Opcode opcode = inst[  6 :  0 ];
    let rd     = inst[ 11 :  7 ];
    let funct3 = inst[ 14 : 12 ];
    let rs1    = inst[ 19 : 15 ];
    let rs2    = inst[ 24 : 20 ];
//    let funct7 = inst[ 31 : 25 ];
    let aluSel = inst[30]; // select between Add/Sub, Srl/Sra

    Bit#(32) immI   = signExtend(inst[31:20]);
    Bit#(32) immS   = signExtend({ inst[31:25], inst[11:7] });
    Bit#(32) immB   = signExtend({ inst[31], inst[7], inst[30:25], inst[11:8], 1'b0});
    Bit#(32) immU   = { inst[31:12], 12'b0 };
    Bit#(32) immJ   = signExtend({ inst[31], inst[19:12], inst[20], inst[30:25], inst[24:21], 1'b0});

    case (opcode)
        opOpImm: begin
            ret = case (funct3)
                fnADD: $format("addi");
                fnSLT: $format("slti");
                fnSLTU: $format("sltiu");
                fnAND: $format("andi");
                fnOR: $format("ori");
                fnXOR: $format("xori");
                fnSLL: $format("slli");
                fnSR: (aluSel == 0 ? $format("srli") : $format("srai"));
                default: $format("unsupport OpImm 0x%0x", inst);
            endcase;
            ret = ret + $format(" r%d = r%d ", rd, rs1);
            ret = ret + (case (funct3)
                fnSLL, fnSR: $format("0x%0x", immI[4:0]); // only low 5 bits for shift
                default: $format("0x%0x", immI);
            endcase);
        end

        opOp: begin
            ret = case (funct3)
                fnADD: (aluSel == 0 ? $format("add") : $format("sub"));
                fnSLT: $format("slt");
                fnSLTU: $format("sltu");
                fnAND: $format("and");
                fnOR: $format("or");
                fnXOR: $format("xor");
                fnSLL: $format("sll");
                fnSR: (aluSel == 0 ? $format("srl") : $format("sra"));
                default: $format("unsupport Op 0x%0x", inst);
            endcase;
            ret = ret + $format(" r%d = r%d r%d", rd, rs1, rs2);
        end

        opLui: begin
            ret = $format("lui r%d 0x%0x", rd, immU);
        end

        opAuipc: begin
            ret = $format("auipc r%d 0x%0x", rd, immU);
        end

        opJal: begin
            ret = $format("jal r%d 0x%0x", rd, immJ);
        end

        opJalr: begin
            ret = $format("jalr r%d [r%d 0x%0x]", rd, rs1, immI);
        end

        opBranch: begin
            ret = case(funct3)
                fnBEQ: $format("beq");
                fnBNE: $format("bne");
                fnBLT: $format("blt");
                fnBLTU: $format("bltu");
                fnBGE: $format("bge");
                fnBGEU: $format("bgeu");
                default: $format("unsupport Branch 0x%0x", inst);
            endcase;
            ret = ret + $format(" r%d r%d 0x%0x", rs1, rs2, immB);
        end

        opLoad: begin
            ret = case(funct3)
                fnLW: $format("lw");
                default: $format("unsupport Load 0x%0x", inst);
            endcase;
            ret = ret + $format(" r%d = [r%d 0x%0x]", rd, rs1, immI);
        end

        opStore: begin
            ret = case(funct3)
                fnSW: $format("sw");
                default: $format("unsupport Store 0x%0x", inst);
            endcase;
            ret = ret + $format(" [r%d 0x%0x] = r%d", rs1, immS, rs2);
        end

        opMiscMem: begin
            ret = case (funct3)
                //fnFENCE: $format("fence");
                //fnFENCEI: $format("fence.i");
                default: $format("unsupport MiscMem 0x%0x", inst);
            endcase;
        end

        opAmo: begin
            ret = $format("unsupport Amo 0x%0x", inst);
        end

        opSystem: begin
            case (funct3)
                fnCSRRW, fnCSRRS: begin //fnCSRRC, fnCSRRWI, fnCSRRSI, fnCSRRCI: begin
                    ret = case(funct3)
                        fnCSRRW: $format("csrrw");
                        fnCSRRS: $format("csrrs");
                    endcase;
                    ret = ret + $format(" r%d csr0x%0x r%d", rd, immI[11:0], rs1);
                end

                fnPRIV: begin
                    ret = case (truncate(immI))
                        //privSCALL: $format("scall");
                        default: $format("unsupport System PRIV 0x%0x", inst);
                    endcase;
                end

                default: begin
                    ret = $format("unsupport System 0x%0x", inst);
                end
            endcase
        end

        default: begin
            ret = $format("unsupport 0x%0x", inst);
        end
    endcase

  return ret;

endfunction

/*

Copyright (C) 2012

Arvind <arvind@csail.mit.edu>
Muralidaran Vijayaraghavan <vmurali@csail.mit.edu>

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 Types::*;
import FShow::*;
import MemTypes::*;

// cpu to host data type
typedef enum {
    ExitCode = 2'd0,
    PrintChar = 2'd1,
    PrintIntLow = 2'd2,
    PrintIntHigh = 2'd3
} CpuToHostType deriving(Bits, Eq, FShow);

typedef struct {
    CpuToHostType c2hType;
    Bit#(16) data;
} CpuToHostData deriving(Bits, Eq, FShow);

interface Proc;
    method ActionValue#(CpuToHostData) cpuToHost;
    method Action hostToCpu(Addr startpc);
endinterface

// general purpose reg index
typedef Bit#(5) RIndx;

// opcode
typedef Bit#(7) Opcode;
Opcode opLoad    = 7'b0000011;
Opcode opMiscMem = 7'b0001111;
Opcode opOpImm   = 7'b0010011;
Opcode opAuipc   = 7'b0010111;
Opcode opStore   = 7'b0100011;
Opcode opAmo     = 7'b0101111;
Opcode opOp      = 7'b0110011;
Opcode opLui     = 7'b0110111;
Opcode opBranch  = 7'b1100011;
Opcode opJalr    = 7'b1100111;
Opcode opJal     = 7'b1101111;
Opcode opSystem  = 7'b1110011;

// CSR index
typedef Bit#(12) CsrIndx;
CsrIndx csrInstret = 12'hc02;
CsrIndx csrCycle   = 12'hc00;
CsrIndx csrMhartid = 12'hf10;
CsrIndx csrMdcsr   = 12'h7b0;

// LR, SC, FENCE not implemented
// LB(U), LH(U), SB, SH not implemented

// For CSR, only following two are implemented
// CSRR rd csr (i.e. CSRRS rd csr x0)
// CSRW csr rs1 (i.e. CSRRW x0 csr rs1)

// SCALL, SBREAK not implemented

typedef enum {
    Unsupported,
    Alu,
    Ld,
    St,
    J,
    Jr,
    Br,
    Csrr,
    Csrw,
    Auipc
} IType deriving(Bits, Eq, FShow);

typedef enum {
    Eq,
    Neq,
    Lt,
    Ltu,
    Ge,
    Geu,
    AT,
    NT
} BrFunc deriving(Bits, Eq, FShow);

typedef enum {
    Add,
    Sub,
    And,
    Or,
    Xor,
    Slt,
    Sltu,
    Sll,
    Sra,
    Srl
} AluFunc deriving(Bits, Eq, FShow);

typedef void Exception;

typedef struct {
    Addr pc;
    Addr nextPc;
    IType brType;
    Bool taken;
    Bool mispredict;
} Redirect deriving (Bits, Eq, FShow);

typedef struct {
    IType            iType;
    AluFunc          aluFunc;
    BrFunc           brFunc;
    Maybe#(RIndx)    dst;
    Maybe#(RIndx)    src1;
    Maybe#(RIndx)    src2;
    Maybe#(CsrIndx)  csr;
    Maybe#(Data)     imm;
} DecodedInst deriving(Bits, Eq, FShow);

typedef struct {
    IType            iType;
    Maybe#(RIndx)    dst;
    Maybe#(CsrIndx)  csr;
    Data             data;
    Addr             addr;
    Bool             mispredict;
    Bool             brTaken;
} ExecInst deriving(Bits, Eq, FShow);

// function code
// ALU
Bit#(3) fnADD   = 3'b000;
Bit#(3) fnSLL   = 3'b001;
Bit#(3) fnSLT   = 3'b010;
Bit#(3) fnSLTU  = 3'b011;
Bit#(3) fnXOR   = 3'b100;
Bit#(3) fnSR    = 3'b101;
Bit#(3) fnOR    = 3'b110;
Bit#(3) fnAND   = 3'b111;
// Branch
Bit#(3) fnBEQ   = 3'b000;
Bit#(3) fnBNE   = 3'b001;
Bit#(3) fnBLT   = 3'b100;
Bit#(3) fnBGE   = 3'b101;
Bit#(3) fnBLTU  = 3'b110;
Bit#(3) fnBGEU  = 3'b111;
// Load
Bit#(3) fnLW    = 3'b010;
//Bit#(3) fnLB    = 3'b000;
//Bit#(3) fnLH    = 3'b001;
//Bit#(3) fnLBU   = 3'b100;
//Bit#(3) fnLHU   = 3'b101;
// Store
Bit#(3) fnSW    = 3'b010;
//Bit#(3) fnSB    = 3'b000;
//Bit#(3) fnSH    = 3'b001;
// Amo
Bit#(5) fnLR    = 5'b00010;
Bit#(5) fnSC    = 5'b00011;
//MiscMem
Bit#(3) fnFENCE  = 3'b000;
//Bit#(3) fnFENCEI = 3'b001;
// System
Bit#(3) fnCSRRW  = 3'b001;
Bit#(3) fnCSRRS  = 3'b010;
//Bit#(3) fnCSRRC  = 3'b011;
//Bit#(3) fnCSRRWI = 3'b101;
//Bit#(3) fnCSRRSI = 3'b110;
//Bit#(3) fnCSRRCI = 3'b111;
Bit#(3) fnPRIV   = 3'b000;
Bit#(12) privSCALL    = 12'h000;

function Bool dataHazard(Maybe#(RIndx) src1, Maybe#(RIndx) src2, Maybe#(RIndx) dst);
    return (isValid(dst) && ((isValid(src1) && fromMaybe(?, dst)==fromMaybe(?, src1)) ||
                             (isValid(src2) && fromMaybe(?, dst)==fromMaybe(?, src2))));
endfunction

// pretty print instuction
function Fmt showInst(Instruction inst);
    Fmt ret = $format("");

    Opcode opcode = inst[  6 :  0 ];
    let rd     = inst[ 11 :  7 ];
    let funct3 = inst[ 14 : 12 ];
    let rs1    = inst[ 19 : 15 ];
    let rs2    = inst[ 24 : 20 ];
//    let funct7 = inst[ 31 : 25 ];
    let aluSel = inst[30]; // select between Add/Sub, Srl/Sra

    Bit#(32) immI   = signExtend(inst[31:20]);
    Bit#(32) immS   = signExtend({ inst[31:25], inst[11:7] });
    Bit#(32) immB   = signExtend({ inst[31], inst[7], inst[30:25], inst[11:8], 1'b0});
    Bit#(32) immU   = { inst[31:12], 12'b0 };
    Bit#(32) immJ   = signExtend({ inst[31], inst[19:12], inst[20], inst[30:25], inst[24:21], 1'b0});

    case (opcode)
        opOpImm: begin
            ret = case (funct3)
                fnADD: $format("addi");
                fnSLT: $format("slti");
                fnSLTU: $format("sltiu");
                fnAND: $format("andi");
                fnOR: $format("ori");
                fnXOR: $format("xori");
                fnSLL: $format("slli");
                fnSR: (aluSel == 0 ? $format("srli") : $format("srai"));
                default: $format("unsupport OpImm 0x%0x", inst);
            endcase;
            ret = ret + $format(" r%d = r%d ", rd, rs1);
            ret = ret + (case (funct3)
                fnSLL, fnSR: $format("0x%0x", immI[4:0]); // only low 5 bits for shift
                default: $format("0x%0x", immI);
            endcase);
        end

        opOp: begin
            ret = case (funct3)
                fnADD: (aluSel == 0 ? $format("add") : $format("sub"));
                fnSLT: $format("slt");
                fnSLTU: $format("sltu");
                fnAND: $format("and");
                fnOR: $format("or");
                fnXOR: $format("xor");
                fnSLL: $format("sll");
                fnSR: (aluSel == 0 ? $format("srl") : $format("sra"));
                default: $format("unsupport Op 0x%0x", inst);
            endcase;
            ret = ret + $format(" r%d = r%d r%d", rd, rs1, rs2);
        end

        opLui: begin
            ret = $format("lui r%d 0x%0x", rd, immU);
        end

        opAuipc: begin
            ret = $format("auipc r%d 0x%0x", rd, immU);
        end

        opJal: begin
            ret = $format("jal r%d 0x%0x", rd, immJ);
        end

        opJalr: begin
            ret = $format("jalr r%d [r%d 0x%0x]", rd, rs1, immI);
        end

        opBranch: begin
            ret = case(funct3)
                fnBEQ: $format("beq");
                fnBNE: $format("bne");
                fnBLT: $format("blt");
                fnBLTU: $format("bltu");
                fnBGE: $format("bge");
                fnBGEU: $format("bgeu");
                default: $format("unsupport Branch 0x%0x", inst);
            endcase;
            ret = ret + $format(" r%d r%d 0x%0x", rs1, rs2, immB);
        end

        opLoad: begin
            ret = case(funct3)
                fnLW: $format("lw");
                default: $format("unsupport Load 0x%0x", inst);
            endcase;
            ret = ret + $format(" r%d = [r%d 0x%0x]", rd, rs1, immI);
        end

        opStore: begin
            ret = case(funct3)
                fnSW: $format("sw");
                default: $format("unsupport Store 0x%0x", inst);
            endcase;
            ret = ret + $format(" [r%d 0x%0x] = r%d", rs1, immS, rs2);
        end

        opMiscMem: begin
            ret = case (funct3)
                //fnFENCE: $format("fence");
                //fnFENCEI: $format("fence.i");
                default: $format("unsupport MiscMem 0x%0x", inst);
            endcase;
        end

        opAmo: begin
            ret = $format("unsupport Amo 0x%0x", inst);
        end

        opSystem: begin
            case (funct3)
                fnCSRRW, fnCSRRS: begin //fnCSRRC, fnCSRRWI, fnCSRRSI, fnCSRRCI: begin
                    ret = case(funct3)
                        fnCSRRW: $format("csrrw");
                        fnCSRRS: $format("csrrs");
                    endcase;
                    ret = ret + $format(" r%d csr0x%0x r%d", rd, immI[11:0], rs1);
                end

                fnPRIV: begin
                    ret = case (truncate(immI))
                        //privSCALL: $format("scall");
                        default: $format("unsupport System PRIV 0x%0x", inst);
                    endcase;
                end

                default: begin
                    ret = $format("unsupport System 0x%0x", inst);
                end
            endcase
        end

        default: begin
            ret = $format("unsupport 0x%0x", inst);
        end
    endcase

  return ret;

endfunction


add setupL

add setupL

// 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 SpecialFIFOs::*;
import GetPut::*;
import StmtFSM::*;
//import Vector::*;
import BRAM::*;
//import Gearbox::*;
import Connectable::*;
import MCSAlgorithm::*;

//import AxiMasterSlave::*;
import Dma::*;
import DmaUtils::*;
import Dma2BRAM::*;

// algorithm
import HirschA::*;
import Hirsch::*;

/* This module solves the maximum common subsequence problem.
 * It finds the longest subsequence of characters present in both input strings
 * the subsequence does not have to be contiguous and the characters can have different locations
 * and offsets in the two strings, just so long as they occur in the same order
 *
 *  To initialize, load string A with request setupA, and wait for indication setup complete
 * Then load string B with request setupB, and wait for indication setup complete
 * To start the unit, signal start, and wait for searchResult, which will tell you the length
 * To retreive the result, use fetch and wait for fetchComplete
 */

/* First pass implements Hirschberg Algorithm A and the fetch call returns the L matrix
 */
interface MaxcommonsubseqRequest;
   method Action setupA(Bit#(32) strPointer, Bit#(32) strLen);
   method Action setupB(Bit#(32) strPointer, Bit#(32) strLen);
   method Action fetch(Bit#(32) strPointer, Bit#(32) dest, Bit#(32) src, Bit#(32) strLen);
   method Action start(Bit#(32) alg);
endinterface

interface MaxcommonsubseqIndication;
   method Action searchResult(Int#(32) v);
   method Action setupAComplete();
   method Action setupBComplete();
   method Action fetchComplete();
endinterface

typedef Bit#(64) DWord;
typedef Bit#(32) Word;

typedef 128 MaxStringLen;
typedef 16384 MaxFetchLen;
typedef TLog#(MaxStringLen) StringIdxWidth;
typedef Bit#(StringIdxWidth) StringIdx;
typedef TLog#(MaxFetchLen) LIdxWidth;
typedef Bit#(LIdxWidth) LIdx;

module mkMaxcommonsubseqRequest#(MaxcommonsubseqIndication indication,
			DmaReadServer#(busWidth)   setupA_read_server,
			DmaReadServer#(busWidth)   setupB_read_server,
			DmaWriteServer#(busWidth)   fetch_write_server )(MaxcommonsubseqRequest)

   provisos(Add#(a__, 8, busWidth),
	    Div#(busWidth,8,nc),
	    Mul#(nc,8,busWidth),
	    Add#(1, b__, nc),
	    Add#(c__, 32, busWidth),
	    Add#(1, d__, TDiv#(busWidth, 32)),
	    Mul#(TDiv#(busWidth, 32), 32, busWidth),
            Mul#(TDiv#(busWidth, 16), 16, busWidth),
            Add#(1, e__, TDiv#(busWidth, 16)),
            Add#(1, f__, TMul#(2, TDiv#(busWidth, 16))),
            Add#(TDiv#(busWidth, 16), g__, TMul#(2, TDiv#(busWidth, 16))));

  Reg#(Bit#(7)) aLenReg <- mkReg(0);
  Reg#(Bit#(7)) bLenReg <- mkReg(0);
  Reg#(Bit#(14)) rLenReg <- mkReg(0);
  Reg#(Bit#(7)) ii <- mkReg(0);
  Reg#(Bit#(7)) jj <- mkReg(0);
   Reg#(Bit#(8)) aData <- mkReg(0);
   Reg#(Bit#(8)) bData <- mkReg(0);
   Reg#(Bit#(16)) lim1jm1 <- mkReg(0);
   Reg#(Bit#(16)) lim1j <- mkReg(0);
   Reg#(Bit#(16)) lijm1 <- mkReg(0);
   BRAM2Port#(StringIdx, Bit#(8)) strA  <- mkBRAM2Server(defaultValue);
   BRAM2Port#(StringIdx, Bit#(8)) strB <- mkBRAM2Server(defaultValue);
   BRAM2Port#(LIdx, Bit#(16)) matL <- mkBRAM2Server(defaultValue);

   BRAMReadClient#(StringIdxWidth,busWidth) n2a <- mkBRAMReadClient(strA.portB);
   mkConnection(n2a.dmaClient, setupA_read_server);
   BRAMReadClient#(StringIdxWidth,busWidth) n2b <- mkBRAMReadClient(strB.portB);
   mkConnection(n2b.dmaClient, setupB_read_server);
   BRAMWriteClient#(LIdxWidth, busWidth) l2n <- mkBRAMWriteClient(matL.portB);
   mkConnection(l2n.dmaClient, fetch_write_server);

   FIFOF#(void) aReady <- mkFIFOF;
   FIFOF#(void) bReady <- mkFIFOF;
   FIFOF#(void) mReady <- mkFIFOF;

   Reg#(Bool) hirschARunning <- mkReg(False);
   Reg#(Bool) hirschBRunning <- mkReg(False);

   MCSAlgorithm hirschA <- mkHirschA(strA.portA, strB.portA, matL.portA);
   MCSAlgorithm hirschB <- mkHirschB(strA.portA, strB.portA, matL.portA);

   // create BRAM Write client for matL

   rule finish_setupA;
      $display("finish setupA");
      let x <- n2a.finish;
      aReady.enq(?);
      indication.setupAComplete();
   endrule

   rule finish_setupB;
      $display("finish setupB");
      let x <- n2b.finish;
      bReady.enq(?);
      indication.setupBComplete();
   endrule

   rule finish_fetch;
      $display("finish fetch");
      let x <- l2n.finish;
      indication.fetchComplete();
   endrule

   rule hirschA_completion (hirschARunning && hirschA.fsm.done);
      hirschARunning <= False;
      indication.searchResult(22);
      endrule

   rule hirschB_completion (hirschBRunning && hirschB.fsm.done);
      hirschBRunning <= False;
      indication.searchResult(23);
      endrule

   method Action setupA(Bit#(32) strPointer, Bit#(32) strLen);
      aLenReg <= truncate(strLen);
      $display("setupA %h %d", strPointer, strLen);
      n2a.start(strPointer, 0, 0, pack(truncate(strLen-1)));
   endmethod

   method Action setupB(Bit#(32) strPointer, Bit#(32) strLen);
      bLenReg <= truncate(strLen);
      $display("setupB %h %d", strPointer, strLen);
      n2b.start(strPointer, 0, 0, pack(truncate(strLen-1)));
   endmethod

   method Action fetch(Bit#(32) strPointer, Bit#(32) dest, Bit#(32) src, Bit#(32) strLen);
      //rLenReg <= truncate(strLen);
      $display("fetch %h %h %h %h", strPointer, dest, src, strLen);
      let bram_start_idx = pack(truncate(src));
      let bram_finish_idx = bram_start_idx+pack(truncate(strLen-1));
      l2n.start(strPointer, zeroExtend(dest), bram_start_idx, bram_finish_idx);
   endmethod

   method Action start(Bit#(32) alg);
      $display ("start %d", alg);
      case (alg)
	 0: begin
	       hirschA.setupA(0, aLenReg);
	       hirschA.setupB(0, bLenReg);
	       hirschA.setupL(0);
	       hirschA.fsm.start();
	       hirschARunning <= True;
	       end
	 1: begin
	       hirschB.setupA(0, aLenReg);
	       hirschB.setupB(0, bLenReg);
	       hirschB.fsm.start();
	       hirschB.setupL(0);
	       hirschBRunning <= True;
	       end
//	 2: hirschC.start();
      endcase
   endmethod

endmodule

// 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 SpecialFIFOs::*;
import GetPut::*;
import StmtFSM::*;
//import Vector::*;
import BRAM::*;
//import Gearbox::*;
import Connectable::*;
import MCSAlgorithm::*;

//import AxiMasterSlave::*;
import Dma::*;
import DmaUtils::*;
import Dma2BRAM::*;

// algorithm
import HirschA::*;
import Hirsch::*;

/* This module solves the maximum common subsequence problem.
 * It finds the longest subsequence of characters present in both input strings
 * the subsequence does not have to be contiguous and the characters can have different locations
 * and offsets in the two strings, just so long as they occur in the same order
 *
 *  To initialize, load string A with request setupA, and wait for indication setup complete
 * Then load string B with request setupB, and wait for indication setup complete
 * To start the unit, signal start, and wait for searchResult, which will tell you the length
 * To retreive the result, use fetch and wait for fetchComplete
 */

/* First pass implements Hirschberg Algorithm A and the fetch call returns the L matrix
 */
interface MaxcommonsubseqRequest;
   method Action setupA(Bit#(32) strPointer, Bit#(32) strLen);
   method Action setupB(Bit#(32) strPointer, Bit#(32) strLen);
   method Action fetch(Bit#(32) strPointer, Bit#(32) dest, Bit#(32) src, Bit#(32) strLen);
   method Action start(Bit#(32) alg);
endinterface

interface MaxcommonsubseqIndication;
   method Action searchResult(Int#(32) v);
   method Action setupAComplete();
   method Action setupBComplete();
   method Action fetchComplete();
endinterface

typedef Bit#(64) DWord;
typedef Bit#(32) Word;

typedef 128 MaxStringLen;
typedef 16384 MaxFetchLen;
typedef TLog#(MaxStringLen) StringIdxWidth;
typedef Bit#(StringIdxWidth) StringIdx;
typedef TLog#(MaxFetchLen) LIdxWidth;
typedef Bit#(LIdxWidth) LIdx;

module mkMaxcommonsubseqRequest#(MaxcommonsubseqIndication indication,
			DmaReadServer#(busWidth)   setupA_read_server,
			DmaReadServer#(busWidth)   setupB_read_server,
			DmaWriteServer#(busWidth)   fetch_write_server )(MaxcommonsubseqRequest)

   provisos(Add#(a__, 8, busWidth),
	    Div#(busWidth,8,nc),
	    Mul#(nc,8,busWidth),
	    Add#(1, b__, nc),
	    Add#(c__, 32, busWidth),
	    Add#(1, d__, TDiv#(busWidth, 32)),
	    Mul#(TDiv#(busWidth, 32), 32, busWidth),
            Mul#(TDiv#(busWidth, 16), 16, busWidth),
            Add#(1, e__, TDiv#(busWidth, 16)),
            Add#(1, f__, TMul#(2, TDiv#(busWidth, 16))),
            Add#(TDiv#(busWidth, 16), g__, TMul#(2, TDiv#(busWidth, 16))));

  Reg#(Bit#(7)) aLenReg <- mkReg(0);
  Reg#(Bit#(7)) bLenReg <- mkReg(0);
  Reg#(Bit#(14)) rLenReg <- mkReg(0);
  Reg#(Bit#(7)) ii <- mkReg(0);
  Reg#(Bit#(7)) jj <- mkReg(0);
   Reg#(Bit#(8)) aData <- mkReg(0);
   Reg#(Bit#(8)) bData <- mkReg(0);
   Reg#(Bit#(16)) lim1jm1 <- mkReg(0);
   Reg#(Bit#(16)) lim1j <- mkReg(0);
   Reg#(Bit#(16)) lijm1 <- mkReg(0);
   BRAM2Port#(StringIdx, Bit#(8)) strA  <- mkBRAM2Server(defaultValue);
   BRAM2Port#(StringIdx, Bit#(8)) strB <- mkBRAM2Server(defaultValue);
   BRAM2Port#(LIdx, Bit#(16)) matL <- mkBRAM2Server(defaultValue);

   BRAMReadClient#(StringIdxWidth,busWidth) n2a <- mkBRAMReadClient(strA.portB);
   mkConnection(n2a.dmaClient, setupA_read_server);
   BRAMReadClient#(StringIdxWidth,busWidth) n2b <- mkBRAMReadClient(strB.portB);
   mkConnection(n2b.dmaClient, setupB_read_server);
   BRAMWriteClient#(LIdxWidth, busWidth) l2n <- mkBRAMWriteClient(matL.portB);
   mkConnection(l2n.dmaClient, fetch_write_server);

   FIFOF#(void) aReady <- mkFIFOF;
   FIFOF#(void) bReady <- mkFIFOF;
   FIFOF#(void) mReady <- mkFIFOF;

   Reg#(Bool) hirschARunning <- mkReg(False);
   Reg#(Bool) hirschBRunning <- mkReg(False);

   MCSAlgorithm hirschA <- mkHirschA(strA.portA, strB.portA, matL.portA);
   MCSAlgorithm hirschB <- mkHirschB(strA.portA, strB.portA, matL.portA);

   // create BRAM Write client for matL

   rule finish_setupA;
      $display("finish setupA");
      let x <- n2a.finish;
      aReady.enq(?);
      indication.setupAComplete();
   endrule

   rule finish_setupB;
      $display("finish setupB");
      let x <- n2b.finish;
      bReady.enq(?);
      indication.setupBComplete();
   endrule

   rule finish_fetch;
      $display("finish fetch");
      let x <- l2n.finish;
      indication.fetchComplete();
   endrule

   rule hirschA_completion (hirschARunning && hirschA.fsm.done);
      hirschARunning <= False;
      indication.searchResult(22);
      endrule

   rule hirschB_completion (hirschBRunning && hirschB.fsm.done);
      hirschBRunning <= False;
      indication.searchResult(23);
      endrule

   method Action setupA(Bit#(32) strPointer, Bit#(32) strLen);
      aLenReg <= truncate(strLen);
      $display("setupA %h %d", strPointer, strLen);
      n2a.start(strPointer, 0, 0, pack(truncate(strLen-1)));
   endmethod

   method Action setupB(Bit#(32) strPointer, Bit#(32) strLen);
      bLenReg <= truncate(strLen);
      $display("setupB %h %d", strPointer, strLen);
      n2b.start(strPointer, 0, 0, pack(truncate(strLen-1)));
   endmethod

   method Action fetch(Bit#(32) strPointer, Bit#(32) dest, Bit#(32) src, Bit#(32) strLen);
      //rLenReg <= truncate(strLen);
      $display("fetch %h %h %h %h", strPointer, dest, src, strLen);
      let bram_start_idx = pack(truncate(src));
      let bram_finish_idx = bram_start_idx+pack(truncate(strLen-1));
      l2n.start(strPointer, zeroExtend(dest), bram_start_idx, bram_finish_idx);
   endmethod

   method Action start(Bit#(32) alg);
      $display ("start %d", alg);
      case (alg)
	 0: begin
	       hirschA.setupA(aLenReg);
	       hirschA.setupB(bLenReg);
	       hirschA.fsm.start();
	       hirschARunning <= True;
	       end
	 1: begin
	       hirschB.setupA(aLenReg);
	       hirschB.setupB(bLenReg);
	       hirschB.fsm.start();
	       hirschBRunning <= True;
	       end
//	 2: hirschC.start();
      endcase
   endmethod

endmodule


Make IRQ emulation an option (+irqemu) in the emulator.

import ClientServer::*;
import GetPut::*;
import BRAM::*;
import FIFO::*;
import Connectable::*;
import AvalonCommon::*;
import AvalonMaster::*;

module mkAvalonMasterEmu(AvalonMaster#(address_width,data_width));
  BRAM_Configure cfg = defaultValue;
  cfg.loadFormat = tagged Hex "program.mem";
  BRAM1Port#(Bit#(address_width), Bit#(data_width)) bram <- mkBRAM1Server(cfg);
  FIFO#(Bit#(data_width)) delay_stage01 <- mkFIFO;
  FIFO#(Bit#(data_width)) delay_stage02 <- mkFIFO;

  Reg#(Bit#(12)) irqEmuCycle <- mkReg(0);

  mkConnection(bram.portA.response,  toPut(delay_stage01));
  mkConnection(toGet(delay_stage01), toPut(delay_stage02));

  rule incCycle;
      let irqEmu <- $test$plusargs("irqemu");
      if(irqEmu)
          irqEmuCycle <= irqEmuCycle + 1;
  endrule

  interface AvalonMasterWires masterWires;
    method Bit#(1) read() = 0;
    method Bit#(1) write() = 0;
    method Bit#(TAdd#(address_width,TSub#(TLog#(data_width),3))) address() = 0;
    method Bit#(data_width) writedata() = 0;
    method Action readdata(Bit#(data_width) readdataNew) = noAction;
    method Action waitrequest(Bit#(1) waitrequestNew) = noAction;
    method Action readdatavalid(Bit#(1) readdatavalidNew) = noAction;
    method Action irq(Bit#(32) irqNew) = noAction;
  endinterface

  interface Server busServer;
    interface Put request;
      method Action put(AvalonRequest#(address_width,data_width) req);
        bram.portA.request.put(BRAMRequest{write: req.command==Write,
                                           responseOnWrite: False,
                                           address: req.addr,
                                           datain: req.data});
      endmethod
    endinterface
    interface Get response = toGet(delay_stage02);
  endinterface

  interface Get irqGet;
    method ActionValue#(Bit#(32)) get() if (irqEmuCycle == 4095);
      $display("[Emu] Simulating IRQ");
      return 32'h01010101;
    endmethod
  endinterface
endmodule

import ClientServer::*;
import GetPut::*;
import BRAM::*;
import FIFO::*;
import Connectable::*;
import AvalonCommon::*;
import AvalonMaster::*;

module mkAvalonMasterEmu(AvalonMaster#(address_width,data_width));
  BRAM_Configure cfg = defaultValue;
  cfg.loadFormat = tagged Hex "program.mem";
  BRAM1Port#(Bit#(address_width), Bit#(data_width)) bram <- mkBRAM1Server(cfg);
  FIFO#(Bit#(data_width)) delay_stage01 <- mkFIFO;
  FIFO#(Bit#(data_width)) delay_stage02 <- mkFIFO;

  Reg#(Bit#(12)) cycle <- mkReg(0);

  mkConnection(bram.portA.response,  toPut(delay_stage01));
  mkConnection(toGet(delay_stage01), toPut(delay_stage02));

  rule incCycle;
      cycle <= cycle + 1;
  endrule

  interface AvalonMasterWires masterWires;
    method Bit#(1) read() = 0;
    method Bit#(1) write() = 0;
    method Bit#(TAdd#(address_width,TSub#(TLog#(data_width),3))) address() = 0;
    method Bit#(data_width) writedata() = 0;
    method Action readdata(Bit#(data_width) readdataNew) = noAction;
    method Action waitrequest(Bit#(1) waitrequestNew) = noAction;
    method Action readdatavalid(Bit#(1) readdatavalidNew) = noAction;
    method Action irq(Bit#(32) irqNew) = noAction;
  endinterface

  interface Server busServer;
    interface Put request;
      method Action put(AvalonRequest#(address_width,data_width) req);
        bram.portA.request.put(BRAMRequest{write: req.command==Write,
                                           responseOnWrite: False,
                                           address: req.addr,
                                           datain: req.data});
      endmethod
    endinterface
    interface Get response = toGet(delay_stage02);
  endinterface

  interface Get irqGet;
    method ActionValue#(Bit#(32)) get() if (cycle == 4095);
      $display("[Emu] Simulating IRQ");
      return 32'hf33dc0f3;
    endmethod
  endinterface
endmodule


connected BlueScope to xsvi

connected BlueScope to xsvi

// Copyright (c) 2013 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 GetPut::*;
import Connectable :: *;
import PCIE :: *; // ConnectableWithClocks
import Clocks :: *;

import GetPutWithClocks :: *;
import Zynq::*;
import Imageon::*;
import HDMI::*;
import AxiDMA::*;
import BlueScope::*;
import SensorToVideo::*;

interface CoreIndication;
    method Action spi_control_value(Bit#(32) v);
    method Action iserdes_control_value(Bit#(32) v);
    method Action decoder_control_value(Bit#(32) v);
    method Action triggen_control_value(Bit#(32) v);
    method Action spi_rxfifo_value(Bit#(32) v);
    method Action debugind(Bit#(32) v);
endinterface

interface CoreRequest;
    method Action set_spi_control(Bit#(32) v);
    method Action get_spi_control();
    method Action set_iserdes_control(Bit#(32) v);
    method Action get_iserdes_control();
    method Action set_decoder_control(Bit#(32) v);
    method Action get_decoder_control();
    method Action set_triggen_control(Bit#(32) v);
    method Action get_triggen_control();

    method Action set_host_vita_reset(Bit#(1) v);
    method Action set_host_oe(Bit#(1) v);

    method Action set_spi_reset(Bit#(1) v);
    method Action set_spi_timing(Bit#(16) v);
    method Action put_spi_txfifo(Bit#(32) v);
    method Action get_spi_rxfifo();

    method Action set_serdes_reset(Bit#(1) v);
    method Action set_serdes_auto_align(Bit#(1) v);
    method Action set_serdes_align_start(Bit#(1) v);
    method Action set_serdes_fifo_enable(Bit#(1) v);
    method Action set_serdes_manual_tap(Bit#(10) v);
    method Action set_serdes_training(Bit#(10) v);
    method Action set_decoder_reset(Bit#(1) v);
    method Action set_decoder_enable(Bit#(1) v);
    method Action set_decoder_code_ls(Bit#(10) v);
    method Action set_decoder_code_le(Bit#(10) v);
    method Action set_decoder_code_fs(Bit#(10) v);
    method Action set_decoder_code_fe(Bit#(10) v);
    method Action set_decoder_code_bl(Bit#(10) v);
    method Action set_decoder_code_img(Bit#(10) v);
    method Action set_trigger_enable(Bit#(3) v);
    method Action set_trigger_default_freq(Bit#(32) v);
    method Action set_trigger_cnt_trigger0high(Bit#(32) v);
    method Action set_trigger_cnt_trigger0low(Bit#(32) v);
    method Action set_syncgen_delay(Bit#(16) v);
    method Action set_syncgen_hactive(Bit#(16) v);
    method Action set_syncgen_hfporch(Bit#(16) v);
    method Action set_syncgen_hsync(Bit#(16) v);
    method Action set_syncgen_hbporch(Bit#(16) v);
    method Action set_syncgen_vactive(Bit#(16) v);
    method Action set_syncgen_vfporch(Bit#(16) v);
    method Action set_syncgen_vsync(Bit#(16) v);
    method Action set_syncgen_vbporch(Bit#(16) v);
    method Action set_debugreq(Bit#(32) v);
    method Action get_debugind();
endinterface

interface ImageCaptureIndication;
    interface CoreIndication coreIndication;
    interface BlueScopeIndication bsIndication;
endinterface

interface ImageCaptureRequest;
   interface CoreRequest coreRequest;
   interface BlueScopeRequest bsRequest;
   interface ImageonVita imageon;
   interface ImageonSensorData sensor_data;
   interface HDMI hdmi;
endinterface

module mkImageCaptureRequest#(Clock hdmi_clock,
    ImageCaptureIndication indication)(ImageCaptureRequest) provisos (Bits#(XsviData,xsviDataWidth));

    Clock defaultClock <- exposeCurrentClock();
    Reset defaultReset <- exposeCurrentReset();
    Reset hdmi_reset <- mkAsyncReset(2, defaultReset, hdmi_clock);

    ImageonVitaController imageonVita <- mkImageonVitaController();
    ImageonControl control = imageonVita.control;
    ImageonXsviFromSensor xsviFromSensor <- mkImageonXsviFromSensor(hdmi_clock, hdmi_reset);

    AxiDMA dma <- mkAxiDMA;
    WriteChan dma_debug_write_chan = dma.write.writeChannels[1];
    BlueScopeInternal bsi <- mkSyncBlueScopeInternal(32, dma_debug_write_chan, indication.bsIndication,
					             hdmi_clock, hdmi_reset, defaultClock, defaultReset);

    SensorToVideo converter <- mkSensorToVideo(clocked_by hdmi_clock, reset_by hdmi_reset);
    HdmiOut hdmiOut <- mkHdmiOut(clocked_by hdmi_clock, reset_by hdmi_reset);

    mkConnection(control.rxfifo_response.get, indication.coreIndication.spi_rxfifo_value);
    // hdmi clock domain
    //mkConnection(xsviFromSensor.out, converter.in);
    rule xsviConnection;
        let xsvi <- xsviFromSensor.out.get();

        bsi.dataIn(extend(pack(xsvi)), extend(pack(xsvi)));
	converter.in.put(xsvi);
    endrule
    // hdmi clock domain
    mkConnection(converter.out, hdmiOut.rgb);

    interface CoreRequest coreRequest;
    method Action set_spi_control(Bit#(32) v);
        control.set_spi_control(v);
    endmethod
    method Action get_spi_control();
        indication.coreIndication.spi_control_value(control.get_spi_control());
    endmethod

    method Action set_iserdes_control(Bit#(32) v);
        control.set_iserdes_control(v);
    endmethod
    method Action get_iserdes_control();
        indication.coreIndication.iserdes_control_value(control.get_iserdes_control());
    endmethod

    method Action set_decoder_control(Bit#(32) v);
        control.set_decoder_control(v);
    endmethod
    method Action get_decoder_control();
        indication.coreIndication.decoder_control_value(control.get_decoder_control());
    endmethod

    method Action set_triggen_control(Bit#(32) v);
        control.set_triggen_control(v);
    endmethod
    method Action get_triggen_control();
        indication.coreIndication.triggen_control_value(control.get_triggen_control());
    endmethod

    method Action set_host_vita_reset(Bit#(1) v);
        control.set_host_vita_reset(v);
    endmethod
    method Action set_host_oe(Bit#(1) v);
        control.set_host_oe(v);
    endmethod

    method Action set_spi_reset(Bit#(1) v);
        control.set_spi_reset(v);
    endmethod
    method Action set_spi_timing(Bit#(16) v);
        control.set_spi_timing(v);
    endmethod
    method Action put_spi_txfifo(Bit#(32) v);
        control.txfifo.put(v);
    endmethod
    method Action get_spi_rxfifo();
        control.rxfifo_request.put(32'hABBAABBA);
    endmethod

    method Action set_serdes_reset(Bit#(1) v);
        control.set_serdes_reset(v);
    endmethod
    method Action set_serdes_auto_align(Bit#(1) v);
        control.set_serdes_auto_align(v);
    endmethod
    method Action set_serdes_align_start(Bit#(1) v);
        control.set_serdes_align_start(v);
    endmethod
    method Action set_serdes_fifo_enable(Bit#(1) v);
        control.set_serdes_fifo_enable(v);
    endmethod
    method Action set_serdes_manual_tap(Bit#(10) v);
        control.set_serdes_manual_tap(v);
    endmethod
    method Action set_serdes_training(Bit#(10) v);
        control.set_serdes_training(v);
    endmethod
    method Action set_decoder_reset(Bit#(1) v);
        control.set_decoder_reset(v);
    endmethod
    method Action set_decoder_enable(Bit#(1) v);
        control.set_decoder_enable(v);
    endmethod
    method Action set_decoder_code_ls(Bit#(10) v);
        control.set_decoder_code_ls(v);
    endmethod
    method Action set_decoder_code_le(Bit#(10) v);
        control.set_decoder_code_le(v);
    endmethod
    method Action set_decoder_code_fs(Bit#(10) v);
        control.set_decoder_code_fs(v);
    endmethod
    method Action set_decoder_code_fe(Bit#(10) v);
        control.set_decoder_code_fe(v);
    endmethod
    method Action set_decoder_code_bl(Bit#(10) v);
        control.set_decoder_code_bl(v);
    endmethod
    method Action set_decoder_code_img(Bit#(10) v);
        control.set_decoder_code_img(v);
    endmethod
    method Action set_trigger_enable(Bit#(3) v);
        control.set_trigger_enable(v);
    endmethod
    method Action set_trigger_default_freq(Bit#(32) v);
        control.set_trigger_default_freq(v);
    endmethod
    method Action set_trigger_cnt_trigger0high(Bit#(32) v);
        control.set_trigger_cnt_trigger0high(v);
    endmethod
    method Action set_trigger_cnt_trigger0low(Bit#(32) v);
        control.set_trigger_cnt_trigger0low(v);
    endmethod
    method Action set_syncgen_delay(Bit#(16) v);
        control.set_syncgen_delay(v);
    endmethod
    method Action set_syncgen_hactive(Bit#(16) v);
        control.set_syncgen_hactive(v);
    endmethod
    method Action set_syncgen_hfporch(Bit#(16) v);
        control.set_syncgen_hfporch(v);
    endmethod
    method Action set_syncgen_hsync(Bit#(16) v);
        control.set_syncgen_hsync(v);
    endmethod
    method Action set_syncgen_hbporch(Bit#(16) v);
        control.set_syncgen_hbporch(v);
    endmethod
    method Action set_syncgen_vactive(Bit#(16) v);
        control.set_syncgen_vactive(v);
    endmethod
    method Action set_syncgen_vfporch(Bit#(16) v);
        control.set_syncgen_vfporch(v);
    endmethod
    method Action set_syncgen_vsync(Bit#(16) v);
        control.set_syncgen_vsync(v);
    endmethod
    method Action set_syncgen_vbporch(Bit#(16) v);
        control.set_syncgen_vbporch(v);
    endmethod
    method Action set_debugreq(Bit#(32) v);
        control.set_debugreq(v);
    endmethod
    method Action get_debugind();
        indication.coreIndication.debugind(control.get_debugind());
    endmethod

    endinterface
   interface BlueScopeRequest bsRequest = bsi.requestIfc;
   interface ImageonVita imageon = imageonVita.host;
   interface ImageonSensorData sensor_data = xsviFromSensor.in;
   interface HDMI hdmi = hdmiOut.hdmi;
endmodule

// Copyright (c) 2013 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 GetPut::*;
import Connectable :: *;
import PCIE :: *; // ConnectableWithClocks
import Clocks :: *;

import GetPutWithClocks :: *;
import Zynq::*;
import Imageon::*;
import HDMI::*;
import AxiDMA::*;
import BlueScope::*;
import SensorToVideo::*;

interface CoreIndication;
    method Action spi_control_value(Bit#(32) v);
    method Action iserdes_control_value(Bit#(32) v);
    method Action decoder_control_value(Bit#(32) v);
    method Action triggen_control_value(Bit#(32) v);
    method Action spi_rxfifo_value(Bit#(32) v);
    method Action debugind(Bit#(32) v);
endinterface

interface CoreRequest;
    method Action set_spi_control(Bit#(32) v);
    method Action get_spi_control();
    method Action set_iserdes_control(Bit#(32) v);
    method Action get_iserdes_control();
    method Action set_decoder_control(Bit#(32) v);
    method Action get_decoder_control();
    method Action set_triggen_control(Bit#(32) v);
    method Action get_triggen_control();

    method Action set_host_vita_reset(Bit#(1) v);
    method Action set_host_oe(Bit#(1) v);

    method Action set_spi_reset(Bit#(1) v);
    method Action set_spi_timing(Bit#(16) v);
    method Action put_spi_txfifo(Bit#(32) v);
    method Action get_spi_rxfifo();

    method Action set_serdes_reset(Bit#(1) v);
    method Action set_serdes_auto_align(Bit#(1) v);
    method Action set_serdes_align_start(Bit#(1) v);
    method Action set_serdes_fifo_enable(Bit#(1) v);
    method Action set_serdes_manual_tap(Bit#(10) v);
    method Action set_serdes_training(Bit#(10) v);
    method Action set_decoder_reset(Bit#(1) v);
    method Action set_decoder_enable(Bit#(1) v);
    method Action set_decoder_code_ls(Bit#(10) v);
    method Action set_decoder_code_le(Bit#(10) v);
    method Action set_decoder_code_fs(Bit#(10) v);
    method Action set_decoder_code_fe(Bit#(10) v);
    method Action set_decoder_code_bl(Bit#(10) v);
    method Action set_decoder_code_img(Bit#(10) v);
    method Action set_trigger_enable(Bit#(3) v);
    method Action set_trigger_default_freq(Bit#(32) v);
    method Action set_trigger_cnt_trigger0high(Bit#(32) v);
    method Action set_trigger_cnt_trigger0low(Bit#(32) v);
    method Action set_syncgen_delay(Bit#(16) v);
    method Action set_syncgen_hactive(Bit#(16) v);
    method Action set_syncgen_hfporch(Bit#(16) v);
    method Action set_syncgen_hsync(Bit#(16) v);
    method Action set_syncgen_hbporch(Bit#(16) v);
    method Action set_syncgen_vactive(Bit#(16) v);
    method Action set_syncgen_vfporch(Bit#(16) v);
    method Action set_syncgen_vsync(Bit#(16) v);
    method Action set_syncgen_vbporch(Bit#(16) v);
    method Action set_debugreq(Bit#(32) v);
    method Action get_debugind();
endinterface

interface ImageCaptureIndication;
    interface CoreIndication coreIndication;
    //interface BlueScopeIndication bsIndication;
endinterface

interface ImageCaptureRequest;
   interface CoreRequest coreRequest;
   //interface BlueScopeRequest bsRequest;
   interface ImageonVita imageon;
   interface ImageonSensorData sensor_data;
   interface HDMI hdmi;
endinterface

module mkImageCaptureRequest#(Clock hdmi_clock,
    ImageCaptureIndication indication)(ImageCaptureRequest) provisos (Bits#(XsviData,xsviDataWidth));

    Clock defaultClock <- exposeCurrentClock();
    Reset defaultReset <- exposeCurrentReset();
    Reset hdmi_reset <- mkAsyncReset(2, defaultReset, hdmi_clock);

    ImageonVitaController imageonVita <- mkImageonVitaController();
    ImageonControl control = imageonVita.control;
    ImageonXsviFromSensor xsviFromSensor <- mkImageonXsviFromSensor(hdmi_clock, hdmi_reset);
    //jcaBlueScope#(64,64) spiBlueScope <- mkBlueScope(1024);

   AxiDMA dma <- mkAxiDMA;
   WriteChan dma_debug_write_chan = dma.write.writeChannels[1];
   //BlueScope#(64,64) spiBlueScope <- mkBlueScope(32, dma_debug_write_chan);
   //module mkSyncBlueScope#(Integer samples, WriteChan wchan, Clock sClk, Reset sRst, Clock dClk, Reset dRst)(BlueScope#(dataWidth, triggerWidth))
   //BlueScopeInternal bsi <- mkBlueScopeInternal(32, dma_debug_write_chan, indication.bsIndication);

    SensorToVideo converter <- mkSensorToVideo(clocked_by hdmi_clock, reset_by hdmi_reset);
    HdmiOut hdmiOut <- mkHdmiOut(clocked_by hdmi_clock, reset_by hdmi_reset);

    mkConnection(control.rxfifo_response.get, indication.coreIndication.spi_rxfifo_value);
    // hdmi clock domain
    mkConnection(xsviFromSensor.out, converter.in);
    // hdmi clock domain
    mkConnection(converter.out, hdmiOut.rgb);

    interface CoreRequest coreRequest;
    method Action set_spi_control(Bit#(32) v);
        control.set_spi_control(v);
    endmethod
    method Action get_spi_control();
        indication.coreIndication.spi_control_value(control.get_spi_control());
    endmethod

    method Action set_iserdes_control(Bit#(32) v);
        control.set_iserdes_control(v);
    endmethod
    method Action get_iserdes_control();
        indication.coreIndication.iserdes_control_value(control.get_iserdes_control());
    endmethod

    method Action set_decoder_control(Bit#(32) v);
        control.set_decoder_control(v);
    endmethod
    method Action get_decoder_control();
        indication.coreIndication.decoder_control_value(control.get_decoder_control());
    endmethod

    method Action set_triggen_control(Bit#(32) v);
        control.set_triggen_control(v);
    endmethod
    method Action get_triggen_control();
        indication.coreIndication.triggen_control_value(control.get_triggen_control());
    endmethod

    method Action set_host_vita_reset(Bit#(1) v);
        control.set_host_vita_reset(v);
    endmethod
    method Action set_host_oe(Bit#(1) v);
        control.set_host_oe(v);
    endmethod

    method Action set_spi_reset(Bit#(1) v);
        control.set_spi_reset(v);
    endmethod
    method Action set_spi_timing(Bit#(16) v);
        control.set_spi_timing(v);
    endmethod
    method Action put_spi_txfifo(Bit#(32) v);
        control.txfifo.put(v);
    endmethod
    method Action get_spi_rxfifo();
        control.rxfifo_request.put(32'hABBAABBA);
    endmethod

    method Action set_serdes_reset(Bit#(1) v);
        control.set_serdes_reset(v);
    endmethod
    method Action set_serdes_auto_align(Bit#(1) v);
        control.set_serdes_auto_align(v);
    endmethod
    method Action set_serdes_align_start(Bit#(1) v);
        control.set_serdes_align_start(v);
    endmethod
    method Action set_serdes_fifo_enable(Bit#(1) v);
        control.set_serdes_fifo_enable(v);
    endmethod
    method Action set_serdes_manual_tap(Bit#(10) v);
        control.set_serdes_manual_tap(v);
    endmethod
    method Action set_serdes_training(Bit#(10) v);
        control.set_serdes_training(v);
    endmethod
    method Action set_decoder_reset(Bit#(1) v);
        control.set_decoder_reset(v);
    endmethod
    method Action set_decoder_enable(Bit#(1) v);
        control.set_decoder_enable(v);
    endmethod
    method Action set_decoder_code_ls(Bit#(10) v);
        control.set_decoder_code_ls(v);
    endmethod
    method Action set_decoder_code_le(Bit#(10) v);
        control.set_decoder_code_le(v);
    endmethod
    method Action set_decoder_code_fs(Bit#(10) v);
        control.set_decoder_code_fs(v);
    endmethod
    method Action set_decoder_code_fe(Bit#(10) v);
        control.set_decoder_code_fe(v);
    endmethod
    method Action set_decoder_code_bl(Bit#(10) v);
        control.set_decoder_code_bl(v);
    endmethod
    method Action set_decoder_code_img(Bit#(10) v);
        control.set_decoder_code_img(v);
    endmethod
    method Action set_trigger_enable(Bit#(3) v);
        control.set_trigger_enable(v);
    endmethod
    method Action set_trigger_default_freq(Bit#(32) v);
        control.set_trigger_default_freq(v);
    endmethod
    method Action set_trigger_cnt_trigger0high(Bit#(32) v);
        control.set_trigger_cnt_trigger0high(v);
    endmethod
    method Action set_trigger_cnt_trigger0low(Bit#(32) v);
        control.set_trigger_cnt_trigger0low(v);
    endmethod
    method Action set_syncgen_delay(Bit#(16) v);
        control.set_syncgen_delay(v);
    endmethod
    method Action set_syncgen_hactive(Bit#(16) v);
        control.set_syncgen_hactive(v);
    endmethod
    method Action set_syncgen_hfporch(Bit#(16) v);
        control.set_syncgen_hfporch(v);
    endmethod
    method Action set_syncgen_hsync(Bit#(16) v);
        control.set_syncgen_hsync(v);
    endmethod
    method Action set_syncgen_hbporch(Bit#(16) v);
        control.set_syncgen_hbporch(v);
    endmethod
    method Action set_syncgen_vactive(Bit#(16) v);
        control.set_syncgen_vactive(v);
    endmethod
    method Action set_syncgen_vfporch(Bit#(16) v);
        control.set_syncgen_vfporch(v);
    endmethod
    method Action set_syncgen_vsync(Bit#(16) v);
        control.set_syncgen_vsync(v);
    endmethod
    method Action set_syncgen_vbporch(Bit#(16) v);
        control.set_syncgen_vbporch(v);
    endmethod
    method Action set_debugreq(Bit#(32) v);
        control.set_debugreq(v);
    endmethod
    method Action get_debugind();
        indication.coreIndication.debugind(control.get_debugind());
    endmethod

    endinterface
   //interface BlueScopeRequest bsRequest = bsi.requestIfc;
   interface ImageonVita imageon = imageonVita.host;
   interface ImageonSensorData sensor_data = xsviFromSensor.in;
   interface HDMI hdmi = hdmiOut.hdmi;

endmodule


fix import

fix import

// 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.

// This module implements a fixed point complex multiplication
// that is intended to map smoothly onto the DSP slices in Xilinx
// FPGAs.  To this end, the signal path is 18 bits (2 bits of integer
// and 16 bits of fraction), the coefficient path is 25 bits (2 bits
// of integer and 23 bits of fraction), and the product is 43 bits
// 4 bits of integer and 39 bits of fraction).  The multiplier
// in a DSP slice is actually 18 x 25 -> 45 bits.  The additional two
// product bits are for overflow, since the complex multipler adds
// four intermediate results.

// Signal inputs and outputs are Pipe datatypes, to provide flow control.
// The module is intended for use in environments where there may be
// one result per cycle, but at slow signal rates, clock cycles may
// be skipped.  Because the logic is pipelined, there are valid
// bits that follow the signal path.  The signal is assumed to be provided
// intermittently, while the coefficients are provided on demand up to
// one per cycle.

// Because one intended application is a Channel Select filter with
// downconversion, the coefficient path supplies a "filter phase" boolean
// which indicates the start of a new sample period at the output
// intermediate frequency.

import SpecialFIFOs::*;
import Complex::*;
import FixedPoint::*;
import Pipe::*;
import FIFOF::*;
import SpecialFIFOs::*;
import SDRTypes::*;

typedef struct {
		Complex#(Coeff) a;
		Bit#(1) filterPhase;
		} CoeffData deriving(Bits);

typedef struct {
		Complex#(Product) y;
		Bit#(1) filterPhase;
		} ProductData deriving(Bits);

typedef struct {
		Product arxr;
		Product arxi;
		Product aixr;
		Product aixi;
		Bit#(1) filterPhase;
		} MulData deriving(Bits);

interface FPCMult;
   interface PipeIn#(Complex#(Signal)) x;
   interface PipeIn#(CoeffData) a;
   interface PipeOut#(ProductData) y;
endinterface

module mkFPCMult(FPCMult)
  provisos(Bits#(CoeffData, a__),
     Bits#(ProductData, b__),
     Bits#(MulData, c__));
   /* input registers */
   FIFOF#(CoeffData) ain <- mkPipelineFIFOF();
   FIFOF#(Complex#(Signal)) xin <- mkPipelineFIFOF();
   /* pipeline registers at output of multipliers */
   Reg#(MulData) ax <- mkReg(?);
   /* result registers */
   FIFOF#(ProductData) yout <- mkPipelineFIFOF();

   rule work;
      /* compute multiplies */
      Product arxr = fxptMult(ain.first().a.rel, xin.first.rel);
      Product aixi = fxptMult(ain.first().a.img, xin.first.img);
      Product arxi = fxptMult(ain.first().a.rel, xin.first.img);
      Product aixr = fxptMult(ain.first().a.img, xin.first.rel);
      ain.deq();
      xin.deq();
      ax <= MulData{arxr: arxr, aixi: aixi, arxi: arxi, aixr: aixr,
	 filterPhase: ain.first().filterPhase};
      /* pipeline and combine into outputs */
      yout.enq(ProductData{y: Complex{rel: ax.arxr - ax.aixi, img: ax.arxi + ax.aixr}, filterPhase: ax.filterPhase});
   endrule

   interface PipeOut y = toPipeOut(yout);
   interface PipeIn x = toPipeIn(xin);
   interface PipeIn a = toPipeIn(ain);

endmodule

// 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.

// This module implements a fixed point complex multiplication
// that is intended to map smoothly onto the DSP slices in Xilinx
// FPGAs.  To this end, the signal path is 18 bits (2 bits of integer
// and 16 bits of fraction), the coefficient path is 25 bits (2 bits
// of integer and 23 bits of fraction), and the product is 43 bits
// 4 bits of integer and 39 bits of fraction).  The multiplier
// in a DSP slice is actually 18 x 25 -> 45 bits.  The additional two
// product bits are for overflow, since the complex multipler adds
// four intermediate results.

// Signal inputs and outputs are Pipe datatypes, to provide flow control.
// The module is intended for use in environments where there may be
// one result per cycle, but at slow signal rates, clock cycles may
// be skipped.  Because the logic is pipelined, there are valid
// bits that follow the signal path.  The signal is assumed to be provided
// intermittently, while the coefficients are provided on demand up to
// one per cycle.

// Because one intended application is a Channel Select filter with
// downconversion, the coefficient path supplies a "filter phase" boolean
// which indicates the start of a new sample period at the output
// intermediate frequency.

import Complex::*;
import FixedPoint::*;
import Pipe::*;
import FIFOF::*;
import SpecialFIFOs::*;
import SDRTypes::*;

typedef struct {
		Complex#(Coeff) a;
		Bit#(1) filterPhase;
		} CoeffData deriving(Bits);

typedef struct {
		Complex#(Product) y;
		Bit#(1) filterPhase;
		} ProductData deriving(Bits);

typedef struct {
		Product arxr;
		Product arxi;
		Product aixr;
		Product aixi;
		Bit#(1) filterPhase;
		} MulData deriving(Bits);

interface FPCMult;
   interface PipeIn#(Complex#(Signal)) x;
   interface PipeIn#(CoeffData) a;
   interface PipeOut#(ProductData) y;
endinterface

module mkFPCMult(FPCMult)
  provisos(Bits#(CoeffData, a__),
     Bits#(ProductData, b__),
     Bits#(MulData, c__));
   /* input registers */
   FIFOF#(CoeffData) ain <- mkPipelineFIFOF();
   FIFOF#(Complex#(Signal)) xin <- mkPipelineFIFOF();
   /* pipeline registers at output of multipliers */
   Reg#(MulData) ax <- mkReg(?);
   /* result registers */
   FIFOF#(ProductData) yout <- mkPipelineFIFOF();

   rule work;
      /* compute multiplies */
      Product arxr = fxptMult(ain.first().a.rel, xin.first.rel);
      Product aixi = fxptMult(ain.first().a.img, xin.first.img);
      Product arxi = fxptMult(ain.first().a.rel, xin.first.img);
      Product aixr = fxptMult(ain.first().a.img, xin.first.rel);
      ain.deq();
      xin.deq();
      ax <= MulData{arxr: arxr, aixi: aixi, arxi: arxi, aixr: aixr,
	 filterPhase: ain.first().filterPhase};
      /* pipeline and combine into outputs */
      yout.enq(ProductData{y: Complex{rel: ax.arxr - ax.aixi, img: ax.arxi + ax.aixr}, filterPhase: ax.filterPhase});
   endrule

   interface PipeOut y = toPipeOut(yout);
   interface PipeIn x = toPipeIn(xin);
   interface PipeIn a = toPipeIn(ain);

endmodule