package AlteraROM;

import GetPut::*;
import ClientServer::*;
import FIFO::*;

interface AlteraROM_Ifc#(type addrT, type dataT);
   method Action read_request(addrT addr);
   method dataT read_response;
endinterface


import "BVI" VerilogAlteraROM =
  module mkAlteraROM #(String filename) (AlteraROM_Ifc#(addrT, dataT))
     provisos(Bits#(addrT, addr_width),
	      Bits#(dataT, data_width));
     parameter FILENAME = filename;
     parameter ADDRESS_WIDTH = valueOf(addr_width);
     parameter DATA_WIDTH = valueof(data_width);
     method read_request (v_addr)
	enable (v_en);
     method v_data read_response;
	default_clock clk(clk, (*unused*) clk_gate);
	default_reset no_reset;
	schedule (read_response) SBR (read_request);
	schedule (read_response) C (read_response);
	schedule (read_request) C (read_request);
  endmodule


module mkAlteraROMServer#(String romfile)(Server#(UInt#(11),UInt#(8)));

   AlteraROM_Ifc#(UInt#(11),UInt#(8)) rom <- mkAlteraROM(romfile);
   FIFO#(Bool) seq_fifo <- mkLFIFO;
   
   interface Put request;
      method Action put(addr);
	 rom.read_request(addr);
	 seq_fifo.enq(True);
      endmethod
   endinterface
   interface Get response;
      method ActionValue#(UInt#(8)) get;
	 seq_fifo.deq;
	 let data = rom.read_response();
	 return data;
      endmethod
   endinterface
endmodule



endpackage
