URL
https://opencores.org/ocsvn/bluespec-h264/bluespec-h264/trunk
Subversion Repositories bluespec-h264
[/] [bluespec-h264/] [trunk/] [src_fpga/] [mkMemClient.bsv] - Rev 100
Compare with Previous | Blame | View Log
// The MIT License// Copyright (c) 2006-2007 Massachusetts Institute of Technology// Permission is hereby granted, free of charge, to any person obtaining a copy// of this software and associated documentation files (the "Software"), to deal// in the Software without restriction, including without limitation the rights// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell// copies of the Software, and to permit persons to whom the Software is// furnished to do so, subject to the following conditions:// The above copyright notice and this permission notice shall be included in// all copies or substantial portions of the Software.// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN// THE SOFTWARE.package mkMemClient;import MemControllerTypes::*;import IMemClient::*;import IMemClientBackend::*;import FIFOF::*;import FIFO::*;import mkSatCounter::*;import FIFO_2::*;`define FIFO_SIZE 2typedef enum {NORMAL,WRITE_AFTER_READ}MemClientStatederiving(Bits, Eq);module mkMemClient#(Integer client_num) (IMemClientBackend#(addr_type, data_type))provisos(Bits#(addr_type, addr_p),Bits#(data_type, data_p),Bits#(MemReq#(addr_type, data_type), mem_req_p));Reg#(PRIORITY_LEVEL) priority_level <- mkReg(0);FIFOF#(MemReq#(addr_type, data_type)) req_fifo <- mkFIFOF();FIFOF#(Maybe#(MemReq#(addr_type, data_type))) read_fifo <- mkFIFOF();FIFOF#(Maybe#(MemReq#(addr_type, data_type))) write_fifo <- mkFIFOF();RWire#(MemReq#(addr_type, data_type)) read_enqueue <- mkRWire();RWire#(MemReq#(addr_type, data_type)) write_enqueue <- mkRWire();FIFO#(data_type) load_responses <- mkSizedFIFO(`FIFO_SIZE);SatCounter#(TAdd#(1, TLog#(`FIFO_SIZE))) counter <- mkSatCounter(0);Reg#(Bool) read_has_priority <- mkReg(True);Reg#(Bool) write_has_priority <- mkReg(False);Reg#(MemClientState) state <- mkReg(NORMAL);rule process_input;Maybe#(MemReq#(addr_type, data_type)) r_enq = read_enqueue.wget;Maybe#(MemReq#(addr_type, data_type)) w_enq = write_enqueue.wget;if(r_enq matches tagged Valid .r)beginread_fifo.enq(r_enq);write_fifo.enq(w_enq);endelse if(w_enq matches tagged Valid .w)beginread_fifo.enq(r_enq);write_fifo.enq(w_enq);endendrulerule process_queues_normal ((state == NORMAL) && (counter.value() < `FIFO_SIZE));if(read_fifo.first() matches tagged Valid .r )beginif(write_fifo.first() matches tagged Valid .w )beginreq_fifo.enq(r);counter.up();state <= WRITE_AFTER_READ;endelsebeginreq_fifo.enq(r);counter.up();read_fifo.deq();write_fifo.deq();endendelsebeginif(write_fifo.first() matches tagged Valid .w )beginreq_fifo.enq(w);read_fifo.deq();write_fifo.deq();endendendrulerule process_queues_war (state == WRITE_AFTER_READ);if(write_fifo.first() matches tagged Valid .w )beginreq_fifo.enq(w);endelsebegin$display("MemClient error, attempting to enqueue invalid write instruction");endread_fifo.deq();write_fifo.deq();state <= NORMAL;endruleinterface IMemClient client_interface;// comment about read_fifo/write_fifo....method Action read_req(addr_type addr_in) if(read_fifo.notFull() && write_fifo.notFull());//$display("MemClient%dReadReq: received read_req, addr:%x", fromInteger(client_num), addr_in);read_enqueue.wset(tagged LoadReq{addr:addr_in});endmethodmethod ActionValue#(data_type) read_resp();let resp = load_responses.first();//$display("MemClient%dReadResp: delivered read_resp, data:%x", fromInteger(client_num), resp);load_responses.deq();if(counter.value() != 0)begincounter.down();endreturn resp;endmethodmethod Action write(addr_type addr_in, data_type data_in) if(read_fifo.notFull() && write_fifo.notFull());//$display("MemClient%d: received write_req, addr:%x, data:%x", client_num , addr_in, data_in);write_enqueue.wset(tagged StoreReq{addr:addr_in, data:data_in});endmethodmethod Action set_priority(PRIORITY_LEVEL prio);priority_level <= prio;endmethodendinterfaceinterface request_fifo = req_fifo; // Does this compile?method PRIORITY_LEVEL get_priority();return priority_level;endmethodmethod Action enqueue_response(data_type data_in);load_responses.enq(data_in);endmethodendmoduleendpackage
