add first peripheral set
[shakti-peripherals.git] / src / uncore / axi4lite / AXI4Lite_AXI4_Bridge.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 package AXI4Lite_AXI4_Bridge;
15 /*=== Project imports ====*/
16 import AXI4_Lite_Fabric::*;
17 import AXI4_Lite_Types::*;
18 import AXI4_Fabric::*;
19 import AXI4_Types ::*;
20 import Semi_FIFOF ::*;
21 import defined_types::*;
22 import axi_addr_generator::*;
23 `include "instance_defines.bsv"
24 /*======================*/
25 /*=== Package imports ===*/
26 import Clocks::*;
27 /*=======================*/
28
29 interface Ifc_AXI4Lite_AXI4_Bridge;
30 interface AXI4_Slave_IFC#(`PADDR,`Reg_width,`USERSPACE) axi_slave;
31 interface AXI4_Lite_Master_IFC#(`PADDR,64,`USERSPACE) axi4_lite_master;
32 endinterface
33
34 typedef enum {RegularReq,BurstReq} BridgeState deriving (Bits,Eq,FShow);
35
36 (*synthesize*)
37 module mkAXI4Lite_AXI4_Bridge#(Clock fast_clock, Reset fast_reset)(Ifc_AXI4Lite_AXI4_Bridge);
38 AXI4_Slave_Xactor_IFC #(`PADDR, `Reg_width, `USERSPACE) s_xactor <- mkAXI4_Slave_Xactor(clocked_by fast_clock, reset_by fast_reset);
39 AXI4_Lite_Master_Xactor_IFC #(`PADDR,`Reg_width,`USERSPACE) m_xactor <- mkAXI4_Lite_Master_Xactor;
40 Reg#(BridgeState) rd_state <-mkReg(RegularReq,clocked_by fast_clock, reset_by fast_reset);
41 Reg#(BridgeState) wr_state <-mkReg(RegularReq,clocked_by fast_clock, reset_by fast_reset);
42 Reg#(Bit#(4)) rd_id<-mkReg(0);
43 Reg#(Bit#(4)) wr_id<-mkReg(0);
44 Reg#(Bit#(8)) request_counter<-mkReg(0,clocked_by fast_clock, reset_by fast_reset);
45 Reg#(Bit#(8)) rd_response_counter<-mkReg(0);
46 Reg#(Bit#(8)) wr_response_counter <- mkReg(0);
47 Reg#(Bit#(8)) sync_rdburst_value <-mkSyncRegToCC(0,fast_clock,fast_reset);
48 Reg#(Bit#(8)) sync_wrburst_value <-mkSyncRegToCC(0,fast_clock,fast_reset);
49 Reg#(AXI4_Rd_Addr #(`PADDR,`USERSPACE)) rg_read_packet <-mkReg(?,clocked_by fast_clock , reset_by fast_reset);
50 Reg#(AXI4_Wr_Addr #(`PADDR,`USERSPACE)) rg_write_packet<-mkReg(?,clocked_by fast_clock , reset_by fast_reset);
51
52 /*=== FIFOs to synchronize data between the two clock domains ====*/
53 SyncFIFOIfc#(AXI4_Rd_Addr #(`PADDR,`USERSPACE)) ff_rd_addr <- mkSyncFIFOToCC(1,fast_clock,fast_reset);
54 SyncFIFOIfc#(AXI4_Wr_Addr #(`PADDR, `USERSPACE)) ff_wr_addr <- mkSyncFIFOToCC(1,fast_clock,fast_reset);
55 SyncFIFOIfc#(AXI4_Wr_Data #(`Reg_width)) ff_wr_data <- mkSyncFIFOToCC(1,fast_clock,fast_reset);
56
57 SyncFIFOIfc#(AXI4_Rd_Data #(`Reg_width,`USERSPACE)) ff_rd_resp <- mkSyncFIFOFromCC(1,fast_clock);
58 SyncFIFOIfc#(AXI4_Wr_Resp #(`USERSPACE)) ff_wr_resp <- mkSyncFIFOFromCC(1,fast_clock);
59 /*=================================================================*/
60
61
62 // These rule will receive the read request from the AXI4 fabric and pass it on to the AXI4Lite fabric.
63 // If the request is a burst then they are broken down to individual axi4lite read requests. These
64 // are carried out in the next rule.
65 rule capture_read_requests_from_Axi4(rd_state==RegularReq);
66 let request<-pop_o(s_xactor.o_rd_addr);
67 ff_rd_addr.enq(request);
68 rg_read_packet<=request;
69 sync_rdburst_value<=request.arlen;
70 if(request.arlen!=0) begin
71 rd_state<=BurstReq;
72 end
73 endrule
74 // In case a read-burst request is received on the fast bus, then the bursts have to broken down into
75 // individual slow-bus read requests.
76 // This is rule is fired after the first read-burst request is sent to the slow_bus. This rule will continue to
77 // fire as long as the slow bus has capacity to receive a new request and the burst is not complete.
78 // the difference between the each individual requests on the slow bus is only the address. All other
79 // parameters remain the same.
80 rule generate_bust_read_requests(rd_state==BurstReq);
81 let request=rg_read_packet;
82 request.araddr=burst_address_generator(request.arlen, request.arsize, request.arburst,request.araddr);
83 rg_read_packet<=request;
84 ff_rd_addr.enq(request);
85 if(request.arlen==request_counter)begin
86 rd_state<=RegularReq;
87 request_counter<=0;
88 end
89 else
90 request_counter<=request_counter+1;
91 endrule
92 rule send_read_request_on_slow_bus;
93 let request=ff_rd_addr.first;
94 ff_rd_addr.deq;
95 let lite_request = AXI4_Lite_Rd_Addr {araddr: request.araddr, arsize:request.arsize,aruser: 0}; // arburst: 00-FIXED 01-INCR 10-WRAP
96 m_xactor.i_rd_addr.enq(lite_request);
97 rd_id<=request.arid;
98 endrule
99 // This rule will capture the write request from the AXI4 fabric and pass it on to the AXI4Lite fabric.
100 // In case of burst requests, they are broken down to individual requests of axi4lite writes. Care
101 // needs to be taken when writes are of different sizes in settin the write-strobe correctly.
102 rule capture_write_requests_from_Axi4(wr_state==RegularReq);
103 let wr_addr_req <- pop_o (s_xactor.o_wr_addr);
104 let wr_data_req <- pop_o (s_xactor.o_wr_data);
105 ff_wr_addr.enq(wr_addr_req);
106 ff_wr_data.enq(wr_data_req);
107 rg_write_packet<=wr_addr_req;
108 sync_wrburst_value <= wr_addr_req.awlen;
109 if(wr_addr_req.awlen!=0) begin
110 wr_state<=BurstReq;
111 end
112 `ifdef verbose $display($time,"\tAXIBRIDGE: Write Request"); `endif
113 `ifdef verbose $display($time,"\tAddress Channel :",fshow(wr_addr_req)); `endif
114 `ifdef verbose $display($time,"\tData Channel :",fshow(wr_data_req)); `endif
115 endrule
116 // In case a write-burst request is received on the fast bus, then the bursts have to broken down into
117 // individual slow-bus write requests.
118 // This is rule is fired after the first write-burst request is sent to the slow_bus. This rule will continue to
119 // fire as long as the slow bus has capacity to receive a new request and the burst is not complete i.e.
120 // fast bust xactor does not send wlast asserted.
121 // The difference between the each individual requests on the slow bus is only the address. All other
122 // parameters remain the same.
123 rule generate_bust_write_requests(wr_state==BurstReq);
124 let request=rg_write_packet;
125 request.awaddr=burst_address_generator(request.awlen, request.awsize, request.awburst,request.awaddr);
126 let wr_data_req <- pop_o (s_xactor.o_wr_data);
127 ff_wr_addr.enq(request);
128 ff_wr_data.enq(wr_data_req);
129 rg_write_packet<=request;
130 if(wr_data_req.wlast)begin
131 wr_state<=RegularReq;
132 end
133 `ifdef verbose $display($time,"\tAXIBRIDGE: Burst Write Request"); `endif
134 `ifdef verbose $display($time,"\tAddress Channel :",fshow(rg_write_packet)); `endif
135 `ifdef verbose $display($time,"\tData Channel :",fshow(wr_data_req)); `endif
136 endrule
137 rule send_write_request_on_slow_bus;
138 let wr_addr_req = ff_wr_addr.first;
139 let wr_data_req = ff_wr_data.first;
140 ff_wr_data.deq;
141 ff_wr_addr.deq;
142 let aw = AXI4_Lite_Wr_Addr {awaddr: wr_addr_req.awaddr, awuser:0, awsize: wr_addr_req.awsize}; // arburst: 00-FIXED 01-INCR 10-WRAP
143 let w = AXI4_Lite_Wr_Data {wdata: wr_data_req.wdata, wstrb: wr_data_req.wstrb};
144 m_xactor.i_wr_addr.enq(aw);
145 m_xactor.i_wr_data.enq(w);
146 wr_id<=wr_addr_req.awid;
147 endrule
148
149 // This rule forwards the read response from the AXI4Lite to the AXI4 fabric.
150 rule capture_read_responses;
151 let response <- pop_o (m_xactor.o_rd_data);
152 AXI4_Resp rresp= case(response.rresp)
153 AXI4_LITE_OKAY : AXI4_OKAY;
154 AXI4_LITE_EXOKAY: AXI4_EXOKAY;
155 AXI4_LITE_SLVERR: AXI4_SLVERR;
156 AXI4_LITE_DECERR: AXI4_DECERR;
157 default: AXI4_SLVERR; endcase;
158 AXI4_Rd_Data#(`Reg_width,0) r = AXI4_Rd_Data {rresp: rresp, rdata: response.rdata ,rlast:rd_response_counter==sync_rdburst_value, ruser: 0, rid:rd_id};
159 if(rd_response_counter==sync_rdburst_value)
160 rd_response_counter<=0;
161 else
162 rd_response_counter<=rd_response_counter+1;
163 ff_rd_resp.enq(r);
164 endrule
165 rule send_read_response_on_fast_bus;
166 ff_rd_resp.deq;
167 s_xactor.i_rd_data.enq(ff_rd_resp.first);
168 endrule
169 rule capture_write_responses;
170 let response<-pop_o(m_xactor.o_wr_resp);
171 AXI4_Resp bresp= case(response.bresp)
172 AXI4_LITE_OKAY : AXI4_OKAY;
173 AXI4_LITE_EXOKAY: AXI4_EXOKAY;
174 AXI4_LITE_SLVERR: AXI4_SLVERR;
175 AXI4_LITE_DECERR: AXI4_DECERR;
176 default: AXI4_SLVERR; endcase;
177 let b = AXI4_Wr_Resp {bresp: bresp, buser:0, bid:wr_id};
178 if(wr_response_counter == sync_wrburst_value) begin
179 ff_wr_resp.enq(b);
180 wr_response_counter <= 0;
181 end
182 else
183 wr_response_counter <= wr_response_counter + 1;
184 endrule
185 rule send_write_response_on_fast_bus;
186 ff_wr_resp.deq;
187 s_xactor.i_wr_resp.enq(ff_wr_resp.first);
188 endrule
189 interface axi_slave=s_xactor.axi_side;
190 interface axi4_lite_master=m_xactor.axi_side;
191 endmodule
192 endpackage