replace defined_parameters with instance_defines
[shakti-peripherals.git] / src / peripherals / dma / tb_DMA_AXI_Memory.bsv
1 /*
2 Copyright (c) 2013, IIT Madras
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6
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.
10
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 ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
13 */
14 //TODO
15 //1. Remove all userid and corresponding registers i.e. rg_memory_user and rg_peripheral_user.
16 package tb_DMA_AXI_Memory;
17 import DMA::*;
18 import Semi_FIFOF :: *;
19 import AXI4_Types :: *;
20 import AXI4_Fabric :: *;
21 import Connectable :: *;
22 import ConfigReg :: *;
23 import RegFile::*;
24 import Clocks :: * ;
25 import DReg ::*;
26 `include "instance_defines.bsv"
27 typedef 2 Num_Masters;
28 typedef 3 Num_Slaves;
29
30 `define Max_index 14
31 typedef enum{Send_req,Get_resp} Mem_state deriving(Bits,Eq);
32 //check with table in pdf
33 /*
34 function Bit#(8) write_strobe_generation(Bit#(3) transfer_size);
35 if(transfer_size==0)
36 return 'b1;
37 else if(transfer_size==1)
38 return 'b11;
39 else if(transfer_size==2)
40 return 'b1111;
41 else
42 return '1;
43 endfunction
44 */
45
46 function Tuple2 #(Bool, Bit#(TLog#(Num_Slaves))) fn_addr_to_slave_num (Bit #(`PADDR) addr);
47 if(addr<='h00000100)
48 return tuple2(True,0); //DMA config registers
49 else if(addr<='hFFFF)
50 return tuple2(True,2); //Peripherals
51 else
52 return tuple2(True,1); //Memory
53 endfunction
54
55 (*synthesize*)
56 //(*mutually_exclusive="get_read_response,get_write_response"*)
57 module mkTb_DMA_AXI_Memory(Empty);
58 /*
59
60 Clock curr_clk<-exposeCurrentClock;
61 Reset curr_reset<-exposeCurrentReset;
62 MakeResetIfc myrst1 <-mkReset(0,False,curr_clk);
63 Reset final_reset<-mkResetEither(myrst1.new_rst,curr_reset);
64
65 */
66 DmaC#(7,12) dma <-mkDMA();//check parameter as DmaC-data type of mkDMA input takes two inputs
67 AXI4_Master_Xactor_IFC #(`PADDR,`Reg_width,`USERSPACE) proc_xactor <- mkAXI4_Master_Xactor();
68 AXI4_Slave_Xactor_IFC #(`PADDR,`Reg_width,`USERSPACE) slave_memory_xactor <- mkAXI4_Slave_Xactor();
69 AXI4_Slave_Xactor_IFC #(`PADDR,`Reg_width,`USERSPACE) slave_peripheral_xactor <- mkAXI4_Slave_Xactor();
70
71 //master testbench to slave dma connection
72 //mkConnection (m_xactor.axi_side, dma.cfg);
73
74 //slave testbench to master dma connection
75 //mkConnection (dma.mmu,s_xactor.axi_side);
76
77
78
79 // Fabric
80 AXI4_Fabric_IFC #(Num_Masters, Num_Slaves, `PADDR, `Reg_width,`USERSPACE)
81 fabric <- mkAXI4_Fabric(fn_addr_to_slave_num);
82
83 // Connect traffic generators to fabric
84 mkConnection (proc_xactor.axi_side, fabric.v_from_masters [0]);
85 mkConnection (dma.mmu, fabric.v_from_masters [1]);
86
87 // Connect fabric to memory slaves
88 mkConnection(fabric.v_to_slaves[0],dma.cfg);
89 mkConnection(fabric.v_to_slaves[1],slave_memory_xactor.axi_side);
90 mkConnection(fabric.v_to_slaves[2],slave_peripheral_xactor.axi_side);
91
92 Reg#(Bit#(6)) index<-mkConfigReg(0); // states 0..7
93 Reg#(Bool) rg_read_flag<-mkConfigReg(False);
94 Reg#(Bool) rg_write_flag<-mkConfigReg(False);
95 RegFile#(Bit#(6),Bit#(136)) input_instructions <-mkRegFileLoad("trial.hex",0,`Max_index);
96 Reg#(Bit#(32)) rg_count <-mkReg(0);
97 //Reg#(Maybe#(AXI4_Rd_Data#(`Reg_width, `USERSPACE))) rg_slave_read_response <- mkReg(tagged Invalid);
98
99 Reg#(Mem_state) rg_memory_state <-mkDReg(Send_req);
100 Reg#(Bit#(8)) rg_memory_readburst_counter<-mkReg(0);
101 Reg#(Bit#(8)) rg_memory_readburst_value<-mkReg(0);
102 Reg#(Bit#(8)) rg_memory_writeburst_counter<-mkReg(0);
103 Reg#(Bit#(`USERSPACE)) rg_memory_user<-mkReg(0);
104 Reg#(Bit#(4)) rg_memory_id<-mkReg(0);
105 Reg#(Bit#(64)) rg_memory_address<-mkReg(0);
106 Reg#(Bit#(3)) rg_memory_transfer_size<-mkReg(0);
107 Reg#(Bit#(`Reg_width)) rg_memory_data <-mkReg(0);
108
109 Reg#(Mem_state) rg_peripheral_state <-mkDReg(Send_req);
110 Reg#(Bit#(8)) rg_peripheral_readburst_counter<-mkReg(0);
111 Reg#(Bit#(8)) rg_peripheral_readburst_value<-mkReg(0);
112 Reg#(Bit#(8)) rg_peripheral_writeburst_counter<-mkReg(0);
113 Reg#(Bit#(`USERSPACE)) rg_peripheral_user<-mkReg(0);
114 Reg#(Bit#(4)) rg_peripheral_id<-mkReg(0);
115 Reg#(Bit#(64)) rg_peripheral_address<-mkReg(0);
116 Reg#(Bit#(3)) rg_peripheral_transfer_size<-mkReg(0);
117 Reg#(Bit#(`Reg_width)) rg_peripheral_data <-mkReg(0);
118
119 rule rl_inc_count;
120 rg_count<= rg_count + 1;
121 $display("\n");
122 $display($time,"\tCount: %d",rg_count);
123 if(rg_count==400)
124 $finish(0);
125 endrule
126
127 rule proc_start_read(!rg_read_flag && index<=`Max_index && input_instructions.sub(truncate(index))[64]==0); //read operation
128 let x = input_instructions.sub(truncate(index));
129 let addr= x[31:0];
130 let wdata= x[63:32];
131 let stop= x[65];
132 let size= 2'd2;
133 $display($time,"\tTBMaster_Processor: Sending Read Request to addr %h",addr);
134 let read_request = AXI4_Rd_Addr {araddr: zeroExtend(addr), arprot: 0, aruser: 0, arsize: zeroExtend(size), arlen: 0 , arburst: 1, // arburst: 00-FIXED 01-INCR 10-WRAP
135 arlock: 0, arcache: 0, arqos: 0,
136 arregion: 0, arid: 0 };
137 proc_xactor.i_rd_addr.enq(read_request);
138 //x[15:0]=fn_decr_cndtr(x[15:0],2,x[50:48]);//CHECK correct this code USE FUNCTION
139 rg_read_flag<= True;
140 endrule
141
142 rule proc_start_write(!rg_write_flag && index<=`Max_index && input_instructions.sub(truncate(index))[64]==1); //write operation
143 let x = input_instructions.sub(truncate(index));
144 let addr= x[31:0];
145 let wdata= x[63:32];
146 let stop= x[65];
147 let size= 2'd2;
148 $display($time,"\tTBMaster_Processor: Sending Write Request");
149 let aw = AXI4_Wr_Addr { awaddr: zeroExtend(addr), awprot:0, awuser:0, awlen: 0, awsize: zeroExtend(size), awburst: 1,
150 awlock: 0, awcache: 0, awqos: 0,
151 awregion: 0, awid: 0 };
152 let w = AXI4_Wr_Data {wdata: zeroExtend(wdata), wstrb: 0, wlast:True, wid: 0};
153 proc_xactor.i_wr_addr.enq(aw);
154 proc_xactor.i_wr_data.enq(w);
155 rg_write_flag<= True;
156 endrule
157
158 rule get_read_response1(rg_read_flag);
159 let response <- pop_o (proc_xactor.o_rd_data);
160 $display($time,"\tTBMaster_Processor: Received read response with data %h",response.rdata);
161 index<= index+1;
162 rg_read_flag<= False;
163 endrule
164
165 rule get_write_response1(rg_write_flag);
166 let response <- pop_o (proc_xactor.o_wr_resp);
167 $display($time,"\tTBMaster_Processor: Received write response");
168 index<= index+1;
169 rg_write_flag<= False;
170 endrule
171
172 ///////////////// ****************** SLAVE MEMORY **************//////////////////////
173 /////// SLAVE MEMORY READ ////////
174 rule rl_dummy_slave_memory_handle_read_request;
175 let ar<- pop_o(slave_memory_xactor.o_rd_addr);
176 Bit#(TSub#(mem_size,2)) index_address=(ar.araddr-fromInteger(valueOf(`Base_addr)))[valueOf(`Addr_space)-1:`byte_offset+1];
177 rg_memory_address<=ar.araddr;
178 rg_memory_transfer_size<=ar.arsize;
179 rg_memory_readburst_value<=ar.arlen;
180 rg_memory_user<=ar.aruser;
181 rg_memory_id<= ar.arid;
182 rg_memory_data<=zeroExtend({16'hbabe,rg_count[15:0]});
183 rg_memory_state<=Get_resp;
184 $display($time,"\tTbSlave_Memory: Recieved Read Request for Address: %h for id: %d",ar.araddr, ar.aruser);
185 endrule
186
187 rule rl_dummy_slave_memory_handle_read_response(rg_memory_state==Get_resp);
188 /*`ifdef RV64
189 Bit#(`Reg_width) data0 = {dmemMSB.a.read(),dmemLSB.a.read()};
190 `else
191 Bit#(`Reg_width) data0 = dmemLSB.a.read();
192 `endif*/
193 Bit#(`Reg_width) data0= rg_memory_data;
194 AXI4_Rd_Data#(`Reg_width,`USERSPACE) r = AXI4_Rd_Data { rresp: AXI4_OKAY, rdata: data0 ,
195 rlast: rg_memory_readburst_counter==rg_memory_readburst_value,
196 ruser: rg_memory_user, rid: rg_memory_id};
197 if(rg_memory_transfer_size==2)begin // 32 bit
198 if(rg_memory_address[`byte_offset:0]==0)
199 r.rdata={data0[31:0],data0[31:0]};
200 else
201 r.rdata={data0[63:32],data0[63:32]};
202 end
203 else if (rg_memory_transfer_size=='d1)begin // half_word
204 if(rg_memory_address[`byte_offset:0] ==0)
205 r.rdata = {data0[15:0],data0[15:0],data0[15:0],data0[15:0]};
206 else if(rg_memory_address[`byte_offset:0] ==2)
207 r.rdata = {data0[31:16],data0[31:16],data0[31:16],data0[31:16]};
208 `ifdef RV64
209 else if(rg_memory_address[`byte_offset:0] ==4)
210 r.rdata = {data0[47:32],data0[47:32],data0[47:32],data0[47:32]};
211 else if(rg_memory_address[`byte_offset:0] ==6)
212 r.rdata = {data0[63:48],data0[63:48],data0[63:48],data0[63:48]};
213 `endif
214 end
215 else if (rg_memory_transfer_size=='d0) begin// one byte
216 if(rg_memory_address[`byte_offset:0] ==0)
217 r.rdata = {data0[7:0],data0[7:0],data0[7:0],data0[7:0],data0[7:0],data0[7:0],data0[7:0],data0[7:0]};
218 else if(rg_memory_address[`byte_offset:0] ==1)
219 r.rdata = {data0[15:8],data0[15:8],data0[15:8],data0[15:8],data0[15:8],data0[15:8],data0[15:8],data0[15:8]};
220 else if(rg_memory_address[`byte_offset:0] ==2)
221 r.rdata = {data0[23:16],data0[23:16],data0[23:16],data0[23:16],data0[23:16],data0[23:16],data0[23:16],data0[23:16]};
222 else if(rg_memory_address[`byte_offset:0] ==3)
223 r.rdata = {data0[31:24],data0[31:24],data0[31:24],data0[31:24],data0[31:24],data0[31:24],data0[31:24],data0[31:24]};
224 `ifdef RV64
225 else if(rg_memory_address[`byte_offset:0] ==4)
226 r.rdata = {data0[39:32],data0[39:32],data0[39:32],data0[39:32],data0[39:32],data0[39:32],data0[39:32],data0[39:32]};
227 else if(rg_memory_address[`byte_offset:0] ==5)
228 r.rdata = {data0[47:40],data0[47:40],data0[47:40],data0[47:40],data0[47:40],data0[47:40],data0[47:40],data0[47:40]};
229 else if(rg_memory_address[`byte_offset:0] ==6)
230 r.rdata = {data0[55:48],data0[55:48],data0[55:48],data0[55:48],data0[55:48],data0[55:48],data0[55:48],data0[55:48]};
231 else if(rg_memory_address[`byte_offset:0] ==7)
232 r.rdata = {data0[63:56],data0[63:56],data0[63:56],data0[63:56],data0[63:56],data0[63:56],data0[63:56],data0[63:56]};
233 `endif
234 end
235 slave_memory_xactor.i_rd_data.enq(r);
236 if(rg_memory_readburst_counter==rg_memory_readburst_value)
237 rg_memory_readburst_counter<=0;
238 else
239 rg_memory_readburst_counter<=rg_memory_readburst_counter+1;
240 $display($time,"\tTBSlave: Responding Read Request with Data: %8h BurstCounter: %d BurstValue: %d for id: %d",r.rdata,rg_memory_readburst_counter,rg_memory_readburst_value,rg_memory_user);
241 endrule
242
243 /////// SLAVE MEMORY WRITE ////////
244 rule rl_wr_respond_memory;
245 // Get the wr request
246 let aw <- pop_o (slave_memory_xactor.o_wr_addr);
247 let w <- pop_o (slave_memory_xactor.o_wr_data);
248 //Bit#(TSub#(mem_size,2)) index_address=(aw.awaddr-fromInteger(valueOf(base_address)))[valueOf(mem_size)-1:`byte_offset+1];
249 //dmemLSB.b.put(w.wstrb[3:0],index_address,truncate(w.wdata));
250 //`ifdef RV64 dmmMSB.b.put(w.wstrb[7:4],index_address,truncateLSB(w.wdata)); `endif
251 let b = AXI4_Wr_Resp {bresp: AXI4_OKAY, buser: aw.awuser, bid:aw.awid};
252 if(rg_memory_writeburst_counter==aw.awlen)begin
253 rg_memory_writeburst_counter<=0;
254 slave_memory_xactor.i_wr_resp.enq (b);
255 end
256 else
257 rg_memory_writeburst_counter<=rg_memory_writeburst_counter+1;
258 $display($time,"\tTBSlave_Memory: Recieved Write Request for Address: %h data: %h strb: %b awlen: %d rg_memory_writeburst_counter: %d",aw.awaddr,w.wdata,w.wstrb,aw.awlen,rg_memory_writeburst_counter);
259 endrule
260
261
262
263
264 ///////////////// ****************** SLAVE PERIPHERAL **************//////////////////////
265 /////// SLAVE PERIPHERAL READ ////////
266 rule rl_dummy_slave_peripheral_handle_read_request;
267 //let ar<- pop_o(slave_peripheral_xactor.o_rd_addr);
268 let ar<- pop_o(slave_peripheral_xactor.o_rd_addr);
269 Bit#(TSub#(mem_size,2)) index_address=(ar.araddr-fromInteger(valueOf(`Base_addr)))[valueOf(`Addr_space)-1:`byte_offset+1];
270 rg_peripheral_address<=ar.araddr;
271 rg_peripheral_transfer_size<=ar.arsize;
272 rg_peripheral_readburst_value<=ar.arlen;
273 rg_peripheral_user<=ar.aruser;
274 rg_peripheral_id<= ar.arid;
275 rg_peripheral_data<=zeroExtend({16'hbabe,rg_count[15:0]});
276 rg_peripheral_state<=Get_resp;
277 $display($time,"\tTbSlave_peripheral: Recieved Read Request for Address: %h for id: %d",ar.araddr, ar.aruser);
278 endrule
279
280 rule rl_dummy_slave_peripheral_handle_read_response(rg_peripheral_state==Get_resp);
281 /*`ifdef RV64
282 Bit#(`Reg_width) data0 = {dmemMSB.a.read(),dmemLSB.a.read()};
283 `else
284 Bit#(`Reg_width) data0 = dmemLSB.a.read();
285 `endif*/
286 Bit#(`Reg_width) data0= rg_peripheral_data;
287 AXI4_Rd_Data#(`Reg_width,`USERSPACE) r = AXI4_Rd_Data { rresp: AXI4_OKAY, rdata: data0 ,
288 rlast: rg_peripheral_readburst_counter==rg_peripheral_readburst_value,
289 ruser: rg_peripheral_user, rid: rg_peripheral_id};
290 if(rg_peripheral_transfer_size==2)begin // 32 bit
291 if(rg_peripheral_address[`byte_offset:0]==0)
292 r.rdata={data0[31:0],data0[31:0]};
293 else
294 r.rdata={data0[63:32],data0[63:32]};
295 end
296 else if (rg_peripheral_transfer_size=='d1)begin // half_word
297 if(rg_peripheral_address[`byte_offset:0] ==0)
298 r.rdata = {data0[15:0],data0[15:0],data0[15:0],data0[15:0]};
299 else if(rg_peripheral_address[`byte_offset:0] ==2)
300 r.rdata = {data0[31:16],data0[31:16],data0[31:16],data0[31:16]};
301 `ifdef RV64
302 else if(rg_peripheral_address[`byte_offset:0] ==4)
303 r.rdata = {data0[47:32],data0[47:32],data0[47:32],data0[47:32]};
304 else if(rg_peripheral_address[`byte_offset:0] ==6)
305 r.rdata = {data0[63:48],data0[63:48],data0[63:48],data0[63:48]};
306 `endif
307 end
308 else if (rg_peripheral_transfer_size=='d0) begin// one byte
309 if(rg_peripheral_address[`byte_offset:0] ==0)
310 r.rdata = {data0[7:0],data0[7:0],data0[7:0],data0[7:0],data0[7:0],data0[7:0],data0[7:0],data0[7:0]};
311 else if(rg_peripheral_address[`byte_offset:0] ==1)
312 r.rdata = {data0[15:8],data0[15:8],data0[15:8],data0[15:8],data0[15:8],data0[15:8],data0[15:8],data0[15:8]};
313 else if(rg_peripheral_address[`byte_offset:0] ==2)
314 r.rdata = {data0[23:16],data0[23:16],data0[23:16],data0[23:16],data0[23:16],data0[23:16],data0[23:16],data0[23:16]};
315 else if(rg_peripheral_address[`byte_offset:0] ==3)
316 r.rdata = {data0[31:24],data0[31:24],data0[31:24],data0[31:24],data0[31:24],data0[31:24],data0[31:24],data0[31:24]};
317 `ifdef RV64
318 else if(rg_peripheral_address[`byte_offset:0] ==4)
319 r.rdata = {data0[39:32],data0[39:32],data0[39:32],data0[39:32],data0[39:32],data0[39:32],data0[39:32],data0[39:32]};
320 else if(rg_peripheral_address[`byte_offset:0] ==5)
321 r.rdata = {data0[47:40],data0[47:40],data0[47:40],data0[47:40],data0[47:40],data0[47:40],data0[47:40],data0[47:40]};
322 else if(rg_peripheral_address[`byte_offset:0] ==6)
323 r.rdata = {data0[55:48],data0[55:48],data0[55:48],data0[55:48],data0[55:48],data0[55:48],data0[55:48],data0[55:48]};
324 else if(rg_peripheral_address[`byte_offset:0] ==7)
325 r.rdata = {data0[63:56],data0[63:56],data0[63:56],data0[63:56],data0[63:56],data0[63:56],data0[63:56],data0[63:56]};
326 `endif
327 end
328 slave_peripheral_xactor.i_rd_data.enq(r);
329 if(rg_peripheral_readburst_counter==rg_peripheral_readburst_value)
330 rg_peripheral_readburst_counter<=0;
331 else
332 rg_peripheral_readburst_counter<=rg_peripheral_readburst_counter+1;
333 $display($time,"\tTBSlave_Peripheral: Responding Read Request with Data: %8h BurstCounter: %d BurstValue: %d for id: %d",r.rdata,rg_peripheral_readburst_counter,rg_peripheral_readburst_value,rg_peripheral_user);
334 endrule
335
336
337 /////// SLAVE PERIPHERAL WRITE ////////
338 rule rl_wr_respond_peripheral;
339 // Get the wr request
340 let aw <- pop_o (slave_peripheral_xactor.o_wr_addr);
341 let w <- pop_o (slave_peripheral_xactor.o_wr_data);
342 //Bit#(TSub#(mem_size,2)) index_address=(aw.awaddr-fromInteger(valueOf(base_address)))[valueOf(mem_size)-1:`byte_offset+1];
343 //dmemLSB.b.put(w.wstrb[3:0],index_address,truncate(w.wdata));
344 //`ifdef RV64 dmmMSB.b.put(w.wstrb[7:4],index_address,truncateLSB(w.wdata)); `endif
345 let b = AXI4_Wr_Resp {bresp: AXI4_OKAY, buser: aw.awuser, bid:aw.awid};
346 if(rg_peripheral_writeburst_counter==aw.awlen)begin
347 rg_peripheral_writeburst_counter<=0;
348 slave_peripheral_xactor.i_wr_resp.enq (b);
349 end
350 else
351 rg_peripheral_writeburst_counter<=rg_peripheral_writeburst_counter+1;
352 $display($time,"\tTBSlave_Peripheral: Recieved Write Request for Address: %h data: %h strb: %b awlen: %d rg_peripheral_writeburst_counter: %d",aw.awaddr,w.wdata,w.wstrb,aw.awlen,rg_peripheral_writeburst_counter);
353 endrule
354
355 ///////////////////////// SEND INTERRUPT FROM PERIPHERAL //////////////////////////////
356 rule rl_send_interrupt;
357 dma.interrupt_from_peripherals('hA01);
358 endrule
359
360 endmodule
361 endpackage