2 Copyright (c) 2013, IIT Madras
5 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
7 * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
8 * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
9 * Neither the name of IIT Madras nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
11 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
12 ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
15 /*===== Package Imports ==== */
21 /*========================== */
22 /*===== Project Imports ======*/
23 `include "core_parameters.bsv"
24 import defined_types::*;
26 /*============================ */
28 interface Ifc_memory_stage;
29 /* ====================== pipe connections ========= */
30 interface RXe#(IE_IMEM_type) rx_in;
31 interface TXe#(IMEM_IWB_type) tx_out;
32 /*================================================== */
33 method Action update_wEpoch;
34 interface Put#(Maybe#(Tuple4#(Bit#(`Reg_width), Trap_type, Bit#(`PERFMONITORS),Bit#(1)))) response_from_dmem;
35 method Action loadtrigger_info(TriggerData tdata);
36 method Action storetrigger_info(TriggerData tdata);
37 method Maybe#(Tuple3#(Bit#(`Reg_width), Bit#(TLog#(`PRFDEPTH)), Bit#(4))) forwarding_data;
41 module mkmemory_stage(Ifc_memory_stage);
42 RX#(IE_IMEM_type) rx <-mkRX; // receive from the execution stage
43 TX#(IMEM_IWB_type) tx <-mkTX; // send to the writeback stage;
44 Wire#(Memout) wr_info_to_dmem <-mkWire;// holds the information to be given to dmem
45 Wire#(TriggerData) wr_loadtrigger<-mkDWire(TriggerData{ttype:tagged None,matchscheme:0});
46 Wire#(TriggerData) wr_storetrigger<-mkDWire(TriggerData{ttype:tagged None,matchscheme:0});
47 Wire#(Maybe#(Tuple4#(Bit#(`Reg_width), Trap_type,Bit#(`PERFMONITORS),Bit#(1)))) wr_response_to_cpu <- mkDWire(tagged Invalid);
48 //Wire#(Maybe#(Operand_forwading_type)) wr_forward_from_MEM <-mkDWire(tagged Invalid);// holds the forwarded data from the memory stage
49 //Reg#(Maybe#(Tuple3#(Bit#(`Reg_width), Bit#(TLog#(`PRFDEPTH)), Bit#(4)))) wr_forward_from_MEM <-mkDReg(tagged Invalid);// holds the forwarded data from the memory stage
50 Wire#(Maybe#(Tuple3#(Bit#(`Reg_width), Bit#(TLog#(`PRFDEPTH)), Bit#(4)))) wr_forward_from_MEM <-mkDWire(tagged Invalid);// holds the forwarded data from the memory stage
51 //Ifc_dcache dcache<-mkdcache;
52 Reg#(Bit#(1)) wEpoch <-mkReg(0);
54 function Bool checktrigger(TriggerData tdata, Bit#(`Reg_width) address, Bit#(`Reg_width) lsdata);
55 if(tdata.ttype matches tagged Address .addr)
56 if(tdata.matchscheme==0 && addr==truncate(address))
58 else if(tdata.matchscheme==2 && addr>=truncate(address))
60 else if(tdata.matchscheme==3 && addr<=truncate(address))
62 else if(tdata.matchscheme==4 && addr[31:0]==(addr[31:0]&address[31:0]))
64 else if(tdata.matchscheme==5 && addr[31:0]==(addr[`VADDR-1:32]&address[`VADDR-1:32]))
68 else if(tdata.ttype matches tagged Data .data)
69 if(tdata.matchscheme==0 && data==lsdata)
71 else if(tdata.matchscheme==2 && data>=lsdata)
73 else if(tdata.matchscheme==3 && data<=lsdata)
75 else if(tdata.matchscheme==4 && data[31:0]==(data[63:32]&lsdata[31:0]))
77 else if(tdata.matchscheme==5 && data[31:0]==(data[63:32]&lsdata[63:32]))
85 //(*conflict_free="receive_info_from_execution_stage,response_to_core"*)
86 rule receive_info_from_execution_stage(rx.u.notEmpty && tx.u.notFull);
87 Bit#(`PERFMONITORS) pm=rx.u.first.perfmonitors;
88 let info=rx.u.first();
89 let pc=rx.u.first.program_counter;
90 let dest=rx.u.first.destination;
91 let rdtype=rx.u.first.rd_type;
92 `ifdef simulate let instr=rx.u.first.instruction; `endif
94 Bit#(`ADDR) baddr = 0;
95 WriteBackType result1=?;
96 `ifdef verbose $display($time,"\t*****************MEMORY STAGE*************************\t PC: %h PRFINDEX: %d PID: %d EPOCHS: %b wEpoch: %b",pc,rx.u.first.index,rx.u.first.pid, rx.u.first.epochs, wEpoch); `endif
98 /* If the instruction is a memory operation (Load/Store/Atomic/Fence) then generate
99 the request to the cache in this rule and expect the response in the consecutive rule*/
100 if(info.execresult matches tagged MEMORY .meminfo)begin
101 Bool lstrigger=False;
102 `ifdef verbose $display($time,"\tMEMORY: load_trigger: ", fshow(wr_loadtrigger)); `endif
103 let exception=rx.u.first.exception;
104 if(wr_response_to_cpu matches tagged Valid .d)begin
105 let {data,e,perfmonitors,epochs}=d;
106 exception=exception matches tagged None?e:exception;
107 Bit#(`Reg_width) fwd_data=0;
108 if(exception matches tagged Exception .exc)begin
109 result1 = tagged RESULT Arithout{aluresult:meminfo.address,fflags:0};
112 else if(meminfo.transfer_size==2 && rx.u.first.rd_type==FloatingRF)begin
113 result1 = tagged RESULT Arithout{aluresult:{'1,data[31:0]},fflags:0};
114 fwd_data={'1,data[31:0]};
118 result1 = tagged RESULT Arithout{aluresult:data,fflags:0};
123 if(epochs==wEpoch)begin
124 `ifdef verbose $display($time,"\tMEMORY: Response from DCACHE: Data: %h Address: %h transfersize: %d epochs: %b wEpochs: %b",data,meminfo.address,meminfo.transfer_size,epochs,wEpoch); `endif
125 tx.u.enq(IMEM_IWB_type{commit_data:result1, index:rx.u.first.index, pid:rx.u.first.pid, debugcause:rx.u.first.debugcause,
126 program_counter:pc, destination:dest, epochs:{rx.u.first.epochs[1],epochs},
127 rd_type:rdtype, exception:exception, perfmonitors:rx.u.first.perfmonitors
128 `ifdef simulate , instruction:instr `endif });
129 if(meminfo.mem_type!=Store &&& ((rdtype==IntegerRF && dest!=0) `ifdef spfpu || rdtype==FloatingRF `endif ) &&& exception matches tagged None)
130 wr_forward_from_MEM <= tagged Valid tuple3(fwd_data, rx.u.first.index, rx.u.first.pid);
133 `ifdef verbose $display($time,"\tMEMORY: Dropping the received response from DCACHE"); `endif
137 /* If the instruction is not a memory operation then bypass this stage
138 and enque into the write-back stage. If this is a CSR operation changing
139 the FCSR register then generate the necessary flag. Also generate the forwarding
140 signal to the decode stage*/
143 if(rx.u.first.epochs[0]!=wEpoch)begin
144 `ifdef verbose $display($time,"\tMEMORY: PC: %h Dropping instructions",rx.u.first.program_counter); `endif
147 `ifdef verbose $display($time,"\tMEMORY: Bypassing Memory Stage"); `endif
148 if(info.execresult matches tagged SYSTEM .res1)begin
149 result1=tagged SYSTEM res1 ;
151 else if(info.execresult matches tagged RESULT .res1)begin
152 result1=tagged RESULT res1;
154 tx.u.enq(IMEM_IWB_type{commit_data:result1, index:rx.u.first.index, pid:rx.u.first.pid, debugcause:rx.u.first.debugcause,
155 program_counter:pc, destination:dest, epochs:rx.u.first.epochs,
156 rd_type:rdtype, exception:info.exception, perfmonitors:rx.u.first.perfmonitors
157 `ifdef simulate , instruction:instr `endif });
163 interface response_from_dmem = interface Put
164 method Action put(Maybe#(Tuple4#(Bit#(`Reg_width), Trap_type, Bit#(`PERFMONITORS),Bit#(1))) resp);
165 wr_response_to_cpu <= resp;
168 method Action loadtrigger_info(TriggerData tdata);
169 wr_loadtrigger<=tdata;
171 method Action storetrigger_info(TriggerData tdata);
172 wr_storetrigger<=tdata;
174 method Maybe#(Tuple3#(Bit#(`Reg_width), Bit#(TLog#(`PRFDEPTH)), Bit#(4))) forwarding_data=wr_forward_from_MEM;
175 method Action update_wEpoch;
179 endpackage:memory_stage