add ClintBase
[shakti-core.git] / src / testbench / FlexBus_Slave_to_AXI4_Master_Fabric_Types.bsv
1
2 package FlexBus_Slave_to_AXI4_Master_Fabric_Types;
3
4 // ================================================================
5 // Exports
6
7 export
8
9 FlexBus_Slave_to_AXI4_Master_Fabric_IFC (..),
10
11 // Transactors from RTL-level interfacecs to FIFO-like interfaces.
12 mkFlexBus_Slave_to_AXI4_Master_Fabric;
13
14 // ================================================================
15 // BSV library imports
16
17 import ConfigReg ::*;
18 import FIFOF :: *;
19 import SpecialFIFOs::*;
20 import Connectable :: *;
21 import TriState ::*;
22 `include "core_parameters.bsv"
23
24 // ----------------
25 // BSV additional libs
26
27 import Semi_FIFOF :: *;
28
29 import FlexBus_Types :: *;
30 import AXI4_Types :: *;
31
32 function Bit#(wd_addr) address_increment(Bit#(8) arlen, Bit#(3) arsize, Bit#(2) arburst, Bit#(wd_addr) address)
33 provisos(
34 Add#(a__, 4, wd_addr),
35 Add#(b__, 3, wd_addr),
36 Add#(c__, 2, wd_addr));
37 // bit_width_size= (2^arsize)*8
38 // arburst = 0(FIXED), 1(INCR) and 2(WRAP)
39 if(arburst==0) // FIXED
40 return address;
41 else if(arburst==1)begin // INCR
42 return address+ (('b1)<<arsize);
43 end
44 else begin // WRAP
45 let new_addr=address;
46 case (arlen)
47 1: new_addr[arsize]=~address[arsize];
48 3: begin
49 if(arsize==0)
50 new_addr[1:0]=new_addr[1:0]+1;
51 else if(arsize==1)
52 new_addr[2:1]=new_addr[2:1]+1;
53 else if(arsize==2)
54 new_addr[3:2]=new_addr[3:2]+1;
55 else if(arsize==3)
56 new_addr[4:3]=new_addr[4:3]+1;
57 end
58 7: begin
59 if(arsize==0)
60 new_addr[2:0]=new_addr[2:0]+1;
61 else if(arsize==1)
62 new_addr[3:1]=new_addr[3:1]+1;
63 else if(arsize==2)
64 new_addr[4:2]=new_addr[4:2]+1;
65 else if(arsize==3)
66 new_addr[5:3]=new_addr[5:3]+1;
67 end
68 15:begin //Bit#(4) x = address[arsize+3:arsize]+1;new_addr[arsize+3:arsize]=x;end
69 if(arsize==0)
70 new_addr[3:0]=new_addr[3:0]+1;
71 else if(arsize==1)
72 new_addr[4:1]=new_addr[4:1]+1;
73 else if(arsize==2)
74 new_addr[5:2]=new_addr[5:2]+1;
75 else if(arsize==3)
76 new_addr[6:3]=new_addr[6:3]+1;
77 end
78 endcase
79 return new_addr;
80 end
81 endfunction
82 // ================================================================
83 /*
84 module mkVerfn_Top (Empty);
85
86 FlexBus_Slave_to_AXI4_Master_Fabric_IFC#(32,32,4) verfn_ifc <- mkFlexBus_Slave_to_AXI4_Master_Fabric;
87
88 AXI4_Slave_to_FlexBus_Master_Xactor_IFC#(32, 32, 4)
89 flexbus_xactor_ifc <- mkAXI4_Slave_to_FlexBus_Master_Xactor;
90
91 mkConnection(flexbus_xactor_ifc.flexbus_side,verfn_ifc.flexbus_side);
92
93 endmodule
94 */
95 // ================================================================
96 // Master Fabric interface
97
98 interface FlexBus_Slave_to_AXI4_Master_Fabric_IFC #(numeric type wd_addr,
99 numeric type wd_data,
100 numeric type wd_user);
101 method Action reset;
102
103 // FlexBus side
104 interface FlexBus_Slave_IFC flexbus_side;
105
106 // AXI side
107 interface AXI4_Master_IFC #(wd_addr, wd_data, wd_user) axi_side;
108
109 endinterface: FlexBus_Slave_to_AXI4_Master_Fabric_IFC
110
111 // ----------------------------------------------------------------
112 // Master transactor
113
114 module mkFlexBus_Slave_to_AXI4_Master_Fabric (FlexBus_Slave_to_AXI4_Master_Fabric_IFC #(wd_addr, wd_data, wd_user))
115 provisos(
116 Add#(a__, 4, wd_addr),
117 Add#(b__, 3, wd_addr),
118 Add#(c__, 2, wd_addr),
119 Bits#(Bit#(32), wd_addr),
120 Bits#(Bit#(64), wd_data));
121
122 ConfigReg#(FlexBus_States) flexbus_state_verfn <- mkConfigReg(FlexBus_S1_ADDR);
123
124 Reg#(Bit#(32)) r_AD <- mkReg(32'h00000000);
125 Reg#(Bit#(1)) r_ALE <- mkReg(1'b0);
126 Reg#(Bit#(1)) r_R_Wn <- mkReg(1'b0);
127 Reg#(Bit#(2)) r_TSIZ <- mkReg(2'b00);
128 Reg#(Bit#(6)) r_FBCSn <- mkReg(6'h00);
129 Reg#(Bit#(4)) r_BE_BWEn <- mkReg(4'h0);
130 Reg#(Bit#(1)) r_TBSTn <- mkReg(1'b0);
131 Reg#(Bit#(1)) r_OEn <- mkReg(1'b0);
132
133 Reg#(Bool) r1_OEn <- mkReg(True);
134
135 Reg#(Bit#(32)) r_din <- mkReg(0);
136 Reg#(Bit#(1)) r_TAn <- mkReg(1'b0);
137
138 Reg#(Bit#(6)) r_WS_val <- mkReg(6'h02);
139 Reg#(Bit#(6)) r_WS <- mkReg(6'h00);
140
141 Bool unguarded = True;
142 Bool guarded = False;
143
144 Reg#(Maybe#(AXI4_Wr_Addr #(wd_addr, wd_user))) f_wr_addr[3] <-mkCReg(3,tagged Invalid);
145 Reg#(Maybe#(AXI4_Wr_Data #(wd_data))) f_wr_data[3] <-mkCReg(3,tagged Invalid);
146 Reg#(Maybe#(AXI4_Wr_Resp #(wd_user))) f_wr_resp[3] <-mkCReg(3,tagged Invalid);
147
148
149 Reg#(Maybe#(AXI4_Rd_Addr #(wd_addr, wd_user))) f_rd_addr[3] <- mkCReg(3,tagged Invalid);
150 Reg#(Maybe#(AXI4_Rd_Data #(wd_data, wd_user))) f_rd_data[3] <- mkCReg(3, tagged Invalid);
151 Reg#(Maybe#(AXI4_Rd_Addr #(wd_addr, wd_user))) rd_req_reg[2] <- mkCReg(2,tagged Invalid);
152 Reg#(Bit#(8)) rg_read_burst_cycle <-mkReg(0);
153
154 // TriState#(Bit#(32)) tri_AD_in <- mkTriState(!r1_OEn,r_din);
155
156 rule rl_OEn;
157 if (r_OEn == 1'b0)
158 r1_OEn <= False;
159 else
160 r1_OEn <= True;
161 endrule
162
163 // rule rl_read_AD_bus;
164 // r_AD <= tri_AD_in._read;
165 // endrule
166
167 rule generate_read_request(rd_req_reg[1] matches tagged Valid .ar &&& f_rd_addr[0] matches tagged Invalid);
168 `ifdef verbose_debug_ver $display("generate_read_request FIRED");`endif
169 `ifdef verbose $display($time,"\tAXI4MasterRead: Generating Read Request for Address: %h BurstSize: %d BurstLength: %d BurstMode: :%d",ar.araddr,ar.arsize,ar.arlen,ar.arburst); `endif
170 f_rd_addr[0]<=tagged Valid ar;
171 let info=ar;
172 if(ar.arlen==rg_read_burst_cycle) begin// end of burst
173 rd_req_reg[1]<= tagged Invalid;
174 rg_read_burst_cycle<=0;
175 end
176 else begin
177 info.araddr=address_increment(ar.arlen,ar.arsize,ar.arburst,ar.araddr);
178 rg_read_burst_cycle<=rg_read_burst_cycle+1;
179 rd_req_reg[1]<=tagged Valid info;
180 end
181 endrule
182
183 Reg#(Maybe#(AXI4_Wr_Addr #(wd_addr, wd_user))) wr_req_reg[2] <- mkCReg(2,tagged Invalid);
184 Reg#(Maybe#(AXI4_Wr_Data #(wd_data))) wr_data_reg[2] <- mkCReg(2,tagged Invalid);
185 Reg#(Bit#(8)) rg_write_burst_cycle <-mkReg(0);
186 rule generate_write_request(wr_req_reg[1] matches tagged Valid .ar &&& wr_data_reg[1] matches tagged Valid .wd &&& f_wr_addr[0] matches tagged Invalid &&& f_wr_data[0] matches tagged Invalid);
187 `ifdef verbose_debug_ver $display("generate_write_request FIRED"); `endif
188 `ifdef verbose $display($time,"\tAXI4MasterWrite: Generating Write Request for Address: %h Data: %h BurstSize: %d BurstLength: %d BurstMode: :%d",ar.awaddr,wd.wdata,ar.awsize,ar.awlen,ar.awburst); `endif
189 f_wr_addr[0]<=tagged Valid ar;
190 f_wr_data[0]<=tagged Valid wd;
191 let info=ar;
192 if(ar.awlen==rg_write_burst_cycle) begin// end of burst
193 wr_req_reg[1]<= tagged Invalid;
194 wr_data_reg[1]<= tagged Invalid;
195 rg_write_burst_cycle<=0;
196 end
197 else begin
198 info.awaddr=address_increment(ar.awlen,ar.awsize,ar.awburst,ar.awaddr);
199 rg_write_burst_cycle<=rg_write_burst_cycle+1;
200 wr_req_reg[1]<=tagged Valid info;
201 end
202 endrule
203
204 rule rl_generate_addr (r_ALE== 1 && flexbus_state_verfn == FlexBus_S1_ADDR );
205 `ifdef verbose_debug_ver $display("STATE S1 ADDR VERFN fired "); `endif
206 r_WS <= r_WS_val;
207 if (r_R_Wn == 1'b1) begin
208 if(rd_req_reg[0] matches tagged Invalid) begin
209 rd_req_reg[0]<=tagged Valid (AXI4_Rd_Addr {araddr : pack({r_AD}),
210 aruser : 0,
211 arsize : 3'h2,
212 arlen : 8'h00,
213 arburst: 2'b00,
214 arid : 0
215 });
216 end
217 end
218 else begin
219 if(wr_req_reg[0] matches tagged Invalid) begin
220 wr_req_reg[0]<=tagged Valid (AXI4_Wr_Addr {awaddr :pack({r_AD}),
221 awuser : 0,
222 awsize : 3'h2,
223 awlen : 8'h00,
224 awburst: 2'b00,
225 awid : 0
226 });
227 end
228 end
229 flexbus_state_verfn <= FlexBus_S2_WRITE;
230 endrule
231 rule rl_state_S2_WRITE (flexbus_state_verfn == FlexBus_S2_WRITE); //Write Phase
232 `ifdef verbose_debug_ver $display("STATE S2 WRITE VERFN FIRED"); `endif
233 if (r_R_Wn == 1'b0) begin
234 if(wr_data_reg[0] matches tagged Invalid) begin
235 wr_data_reg[0]<=tagged Valid (AXI4_Wr_Data{wdata: pack({32'h00000000,r_AD[7:0],r_AD[15:8],r_AD[23:16],r_AD[31:24]}),
236 wstrb : 8'h0F,
237 wid : 0,
238 wlast : True
239 });
240 end
241 end
242 if (r_WS == 0) begin
243 flexbus_state_verfn <= FlexBus_S3_BURST;
244 r_WS <= r_WS_val;
245 end
246 else
247 r_WS <= r_WS -1;
248 endrule
249 rule rl_state_S3_BURST (flexbus_state_verfn == FlexBus_S3_BURST); //Burst Phase
250 `ifdef verbose_debug_ver $display("STATE S3 BURST VERFN FIRED"); `endif
251 if (r_R_Wn == 1'b1) begin
252 if(f_rd_data[1] matches tagged Valid .ar) begin
253 r_din <= ar.rdata[31:0];
254 `ifdef verbose_debug_ver $display("r_din = %h %h", r_din, ar.rdata); `endif
255 f_rd_data[1]<=tagged Invalid;
256 end
257 end
258 flexbus_state_verfn <= FlexBus_S1_ADDR;
259 endrule
260
261 /*
262 // FIFOF side
263 method Action i_wr_addr(AXI4_Wr_Addr#(wd_addr,wd_user) write_address)if(wr_req_reg[0] matches tagged Invalid);
264 wr_req_reg[0]<=tagged Valid write_address;
265 endmethod
266 method Action i_wr_data(AXI4_Wr_Data#(wd_data) write_data);
267 wr_data_reg[0]<=tagged Valid write_data;
268 endmethod
269 method ActionValue#(AXI4_Wr_Resp#(wd_user)) o_wr_resp if(f_wr_resp[1] matches tagged Valid .aresp);
270 f_wr_resp[1]<=tagged Invalid;
271 return aresp;
272 endmethod
273 method Action i_rd_addr(AXI4_Rd_Addr#(wd_addr,wd_user) read_address)if(rd_req_reg[0] matches tagged Invalid);
274 rd_req_reg[0]<=tagged Valid read_address;
275 endmethod
276 method ActionValue#(AXI4_Rd_Data #(wd_data, wd_user)) o_rd_data if(f_rd_data[1] matches tagged Valid .ar);
277 f_rd_data[1]<=tagged Invalid;
278 return ar;
279 endmethod
280 */
281 // ----------------------------------------------------------------
282 // INTERFACE
283
284 method Action reset;
285 f_wr_addr[2]<=tagged Invalid;
286 f_wr_data[2]<=tagged Invalid;
287 f_wr_resp[2]<=tagged Invalid;
288 f_rd_addr[2]<=tagged Invalid;
289 f_rd_data[2]<=tagged Invalid;
290 endmethod
291
292 // AXI side
293 interface axi_side = interface AXI4_Master_IFC;
294 // Wr Addr channel
295 method Bool m_awvalid = isValid(f_wr_addr[1]);
296 method Bit #(wd_addr) m_awaddr = fromMaybe(?,f_wr_addr[1]).awaddr;
297 method Bit #(wd_user) m_awuser = fromMaybe(?,f_wr_addr[1]).awuser;
298 method Bit #(3) m_awsize = fromMaybe(?,f_wr_addr[1]).awsize;
299 method Bit #(8) m_awlen = fromMaybe(?,f_wr_addr[1]).awlen;
300 method Bit #(2) m_awburst = fromMaybe(?,f_wr_addr[1]).awburst;
301 method Bit #(4) m_awid =fromMaybe(?,f_wr_addr[1]).awid;
302 method Action m_awready (Bool awready);
303 if (isValid(f_wr_addr[1]) && awready) f_wr_addr[1]<=tagged Invalid;
304 endmethod
305
306 // Wr Data channel
307 method Bool m_wvalid = isValid(f_wr_data[1]);
308 method Bit #(wd_data) m_wdata = fromMaybe(?,f_wr_data[1]).wdata;
309 method Bit #(TDiv #(wd_data, 8)) m_wstrb = fromMaybe(?,f_wr_data[1]).wstrb;
310 method Bool m_wlast = fromMaybe(?,f_wr_data[1]).wlast;
311 method Bit#(4) m_wid = fromMaybe(?,f_wr_data[1]).wid;
312 method Action m_wready (Bool wready);
313 if (isValid(f_wr_data[1]) && wready) f_wr_data[1]<=tagged Invalid;
314 endmethod
315
316 // Wr Response channel
317 method Action m_bvalid (Bool bvalid, Bit #(2) bresp, Bit #(wd_user) buser, Bit#(4) bid);
318 if (bvalid && !isValid(f_wr_resp[0]))
319 f_wr_resp[0]<=tagged Valid (AXI4_Wr_Resp {bresp: unpack (bresp), buser: buser, bid: bid});
320 endmethod
321
322 method Bool m_bready;
323 return !isValid(f_wr_resp[0]);
324 endmethod
325
326 // Rd Addr channel
327 method Bool m_arvalid = isValid(f_rd_addr[1]);
328 method Bit #(wd_addr) m_araddr = fromMaybe(?,f_rd_addr[1]).araddr;
329 method Bit #(wd_user) m_aruser = fromMaybe(?,f_rd_addr[1]).aruser;
330 method Bit #(3) m_arsize = fromMaybe(?,f_rd_addr[1]).arsize;
331 method Bit #(8) m_arlen = fromMaybe(?,f_rd_addr[1]).arlen;
332 method Bit #(2) m_arburst = fromMaybe(?,f_rd_addr[1]).arburst;
333 method Bit #(4) m_arid =fromMaybe(?,f_rd_addr[1]).arid;
334 method Action m_arready (Bool arready);
335 if (isValid(f_rd_addr[1]) && arready)
336 f_rd_addr[1]<=tagged Invalid;
337 endmethod
338
339 // Rd Data channel
340 method Action m_rvalid (Bool rvalid,
341 Bit #(2) rresp,
342 Bit #(wd_data) rdata,
343 Bool rlast,
344 Bit #(wd_user) ruser,
345 Bit#(4) rid);
346 if (rvalid && !isValid(f_rd_data[0]))
347 f_rd_data[0]<=tagged Valid (AXI4_Rd_Data {rresp: unpack (rresp),
348 rdata: rdata,
349 rlast: rlast,
350 ruser: ruser,
351 rid: rid});
352 endmethod
353
354 method Bool m_rready;
355 return !isValid(f_rd_data[0]);
356 endmethod
357
358 endinterface;
359
360 interface flexbus_side = interface FlexBus_Slave_IFC;
361 // interface io_AD_slave = tri_AD_in.io;
362 method Action m_AD ( Bit #(32) i_AD); // in
363 r_AD <= i_AD;
364 endmethod
365 //interface i_not_AD_s = interface Not_AD_s;
366 method Action m_ALE ( Bit #(1) i_ALE); // in
367 r_ALE <= i_ALE;
368 endmethod
369
370 method Action m_R_Wn ( Bit #(1) i_R_Wn); // in
371 r_R_Wn <= i_R_Wn;
372 endmethod
373 method Action m_TSIZ ( Bit #(2) i_TSIZ); // in
374 r_TSIZ <= i_TSIZ;
375 endmethod
376
377 method Action m_FBCSn ( Bit #(6) i_FBCSn); // in
378 r_FBCSn <= i_FBCSn;
379 endmethod
380 method Action m_BE_BWEn ( Bit #(4) i_BE_BWEn); // in
381 r_BE_BWEn <= i_BE_BWEn;
382 endmethod
383 method Action m_TBSTn ( Bit #(1) i_TBSTn); // in
384 r_TBSTn <= i_TBSTn;
385 endmethod
386 method Action m_OEn ( Bit #(1) i_OEn); // in
387 r_OEn <= i_OEn;
388 endmethod
389
390 method Bit #(32) m_din = r_din; //out
391 method Bit #(1) m_TAn = r_TAn; //out
392 //endinterface;
393 endinterface;
394
395 endmodule: mkFlexBus_Slave_to_AXI4_Master_Fabric
396
397 // ================================================================
398
399 endpackage