cf44bd42ca00bb5ebdbda85f91b92d99531b449e
[pinmux.git] / src / bsv / bsv_lib / gpio.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 gpio;
15 /*==== Package imports ==== */
16 import TriState ::*;
17 import Vector ::*;
18 import BUtils::*;
19 import ConfigReg ::*;
20 /*============================ */
21 /*===== Project Imports ===== */
22 import Semi_FIFOF :: *;
23 import AXI4_Lite_Types :: *;
24 /*============================ */
25 `define ADDR 32
26 `define DATA 64
27 `define USER 0
28 `define IONum 32
29 `define GPIO_MUX
30
31 interface GPIO;
32 (*always_ready,always_enabled*)
33 method Action gpio_in (Vector#(`IONum,Bit#(1)) inp);
34 method Vector#(`IONum,Bit#(1)) gpio_out;
35 method Vector#(`IONum,Bit#(1)) gpio_out_en;
36 method Vector#(`IONum,Bit#(1)) gpio_DRV0;
37 method Vector#(`IONum,Bit#(1)) gpio_DRV1;
38 method Vector#(`IONum,Bit#(1)) gpio_DRV2;
39 method Vector#(`IONum,Bit#(1)) gpio_PD;
40 method Vector#(`IONum,Bit#(1)) gpio_PPEN;
41 method Vector#(`IONum,Bit#(1)) gpio_PRG_SLEW;
42 method Vector#(`IONum,Bit#(1)) gpio_PUQ;
43 method Vector#(`IONum,Bit#(1)) gpio_PWRUPZHL;
44 method Vector#(`IONum,Bit#(1)) gpio_PWRUP_PULL_EN;
45 interface Vector#(`IONum,Reg#(Bit#(1))) to_plic;
46 `ifdef GPIO_MUX
47 method Vector#(`IONum,Bit#(2)) gpio_MUX;
48 `endif
49 interface AXI4_Lite_Slave_IFC#(`ADDR,`DATA,`USER) axi_slave;
50 endinterface
51
52 (*synthesize*)
53 module mkgpio(GPIO);
54 Vector#(`IONum,ConfigReg#(Bool)) direction_reg <-replicateM(mkConfigReg(False));
55 Vector#(`IONum,ConfigReg#(Bit#(1))) dataout_register <-replicateM(mkConfigReg(0));
56 Vector#(`IONum,ConfigReg#(Bit#(1))) datain_register <-replicateM(mkConfigReg(0));
57 Vector#(`IONum,ConfigReg#(Bit#(1))) drv0_reg <-replicateM(mkConfigReg(1'b1));
58 Vector#(`IONum,ConfigReg#(Bit#(1))) drv1_reg <-replicateM(mkConfigReg(1'b1));
59 Vector#(`IONum,ConfigReg#(Bit#(1))) drv2_reg <-replicateM(mkConfigReg(0));
60 Vector#(`IONum,ConfigReg#(Bit#(1))) pd_reg <-replicateM(mkConfigReg(0));
61 Vector#(`IONum,ConfigReg#(Bit#(1))) ppen_reg <-replicateM(mkConfigReg(0));
62 Vector#(`IONum,ConfigReg#(Bit#(1))) prg_slew_reg <-replicateM(mkConfigReg(1'b1));
63 Vector#(`IONum,ConfigReg#(Bit#(1))) puq_reg <-replicateM(mkConfigReg(0));
64 Vector#(`IONum,ConfigReg#(Bit#(1))) pwrupzhl_reg <-replicateM(mkConfigReg(0));
65 Vector#(`IONum,ConfigReg#(Bit#(1))) pwrup_pull_en_reg <-replicateM(mkConfigReg(0));
66 Vector#(`IONum,ConfigReg#(Bit#(1))) toplic <-replicateM(mkConfigReg(0));
67 `ifdef GPIO_MUX
68 Vector#(`IONum,ConfigReg#(Bit#(2))) muxer_reg <-replicateM(mkConfigReg(0));
69 `endif
70
71 AXI4_Lite_Slave_Xactor_IFC #(`ADDR, `DATA, `USER) s_xactor <- mkAXI4_Lite_Slave_Xactor;
72 let ionum=valueOf(`IONum);
73 rule capture_interrupt;
74 for(Integer i=0;i<`IONum;i=i+1)
75 toplic[i]<=(!direction_reg[i])?datain_register[i]:0;
76 endrule
77
78 rule rl_wr_respond;
79 // Get the wr request
80 let aw <- pop_o (s_xactor.o_wr_addr);
81 let w <- pop_o (s_xactor.o_wr_data);
82 let b = AXI4_Lite_Wr_Resp {bresp: AXI4_LITE_OKAY, buser: aw.awuser};
83 if(aw.awaddr[5:0]=='h0)
84 for(Integer i=0;i<`IONum;i=i+1)
85 direction_reg[i]<=unpack(w.wdata[i]);
86 else if(aw.awaddr[5:0]=='h4)
87 for(Integer i=0;i<`IONum;i=i+1)
88 dataout_register[i]<=w.wdata[i];
89 else if(aw.awaddr[5:0]=='h8)
90 for(Integer i=0;i<`IONum;i=i+1)
91 drv0_reg[i]<=w.wdata[i];
92 else if(aw.awaddr[5:0]=='hC)
93 for(Integer i=0;i<`IONum;i=i+1)
94 drv1_reg[i]<=w.wdata[i];
95 else if(aw.awaddr[5:0]=='h10)
96 for(Integer i=0;i<`IONum;i=i+1)
97 drv2_reg[i]<=w.wdata[i];
98 else if(aw.awaddr[5:0]=='h14)
99 for(Integer i=0;i<`IONum;i=i+1)
100 pd_reg[i]<=w.wdata[i];
101 else if(aw.awaddr[5:0]=='h18)
102 for(Integer i=0;i<`IONum;i=i+1)
103 ppen_reg[i]<=w.wdata[i];
104 else if(aw.awaddr[5:0]=='h1C)
105 for(Integer i=0;i<`IONum;i=i+1)
106 prg_slew_reg[i]<=w.wdata[i];
107 else if(aw.awaddr[5:0]=='h20)
108 for(Integer i=0;i<`IONum;i=i+1)
109 puq_reg[i]<=w.wdata[i];
110 else if(aw.awaddr[5:0]=='h24)
111 for(Integer i=0;i<`IONum;i=i+1)
112 pwrupzhl_reg[i]<=w.wdata[i];
113 else if(aw.awaddr[5:0]=='h28)
114 for(Integer i=0;i<`IONum;i=i+1)
115 pwrup_pull_en_reg[i]<=w.wdata[i];
116 `ifdef GPIO_MUX
117 else if(aw.awaddr[5:0]=='h2c)
118 for(Integer i=0;i<min(`IONum, 16);i=i+1) begin
119 muxer_reg[i]<= w.wdata[i*2+1:i*2];
120 end
121 else if(aw.awaddr[5:0]=='h30 && ionum>=16)
122 for(Integer i=0;i<`IONum-16;i=i+1) begin
123 muxer_reg[i+16]<= w.wdata[i*2+1:i*2];
124 end
125 `endif
126 else
127 b.bresp=AXI4_LITE_SLVERR;
128
129 s_xactor.i_wr_resp.enq (b);
130 endrule
131
132 rule rl_rd_respond;
133 let ar<- pop_o(s_xactor.o_rd_addr);
134 Bit#(32) temp=0;
135 AXI4_Lite_Rd_Data#(`DATA,`USER) r = AXI4_Lite_Rd_Data {rresp: AXI4_LITE_OKAY, rdata: ?, ruser: 0};
136 if(ar.araddr[5:0]=='h0)begin
137 for(Integer i=0;i<`IONum;i=i+1)
138 temp[i]=pack(direction_reg[i]);
139 r.rdata=duplicate(temp);
140 end
141 else if(ar.araddr[5:0]=='h4)begin
142 for(Integer i=0;i<`IONum;i=i+1)
143 temp[i]=datain_register[i];
144 r.rdata=duplicate(temp);
145 end
146 else if(ar.araddr[5:0]=='h8)begin
147 for(Integer i=0;i<`IONum;i=i+1)
148 temp[i]=drv0_reg[i];
149 r.rdata=duplicate(temp);
150 end
151 else if(ar.araddr[5:0]=='hC)begin
152 for(Integer i=0;i<`IONum;i=i+1)
153 temp[i]=drv1_reg[i];
154 r.rdata=duplicate(temp);
155 end
156 else if(ar.araddr[5:0]=='h10)begin
157 for(Integer i=0;i<`IONum;i=i+1)
158 temp[i]=drv2_reg[i];
159 r.rdata=duplicate(temp);
160 end
161 else if(ar.araddr[5:0]=='h14)begin
162 for(Integer i=0;i<`IONum;i=i+1)
163 temp[i]=pd_reg[i];
164 r.rdata=duplicate(temp);
165 end
166 else if(ar.araddr[5:0]=='h18)begin
167 for(Integer i=0;i<`IONum;i=i+1)
168 temp[i]=ppen_reg[i];
169 r.rdata=duplicate(temp);
170 end
171 else if(ar.araddr[5:0]=='h1C)begin
172 for(Integer i=0;i<`IONum;i=i+1)
173 temp[i]=prg_slew_reg[i];
174 r.rdata=duplicate(temp);
175 end
176 else if(ar.araddr[5:0]=='h20)begin
177 for(Integer i=0;i<`IONum;i=i+1)
178 temp[i]=puq_reg[i];
179 r.rdata=duplicate(temp);
180 end
181 else if(ar.araddr[5:0]=='h24)begin
182 for(Integer i=0;i<`IONum;i=i+1)
183 temp[i]=pwrupzhl_reg[i];
184 r.rdata=duplicate(temp);
185 end
186 else if(ar.araddr[5:0]=='h28)begin
187 for(Integer i=0;i<`IONum;i=i+1)
188 temp[i]=pwrup_pull_en_reg[i];
189 r.rdata=duplicate(temp);
190 end
191 `ifdef GPIO_MUX
192 else if(ar.araddr[5:0]=='h2c)begin
193 for(Integer i=0;i<min(`IONum, 16);i=i+1) begin
194 temp[i*2+ 1:i*2]=muxer_reg[i];
195 end
196 r.rdata=duplicate(temp);
197 end
198 else if(ar.araddr[5:0]=='h30 && ionum>=16)begin
199 for(Integer i=0;i<`IONum-16;i=i+1) begin
200 temp[i*2+ 1:i*2]=muxer_reg[i+ 16];
201 end
202 r.rdata=duplicate(temp);
203 end
204 `endif
205 else
206 r.rresp=AXI4_LITE_SLVERR;
207
208 s_xactor.i_rd_data.enq(r);
209 endrule
210
211 interface axi_slave= s_xactor.axi_side;
212 method Action gpio_in (Vector#(`IONum,Bit#(1)) inp);
213 for(Integer i=0;i<`IONum;i=i+1)
214 datain_register[i]<=inp[i];
215 endmethod
216 method Vector#(`IONum,Bit#(1)) gpio_out;
217 Vector#(`IONum,Bit#(1)) temp;
218 for(Integer i=0;i<`IONum;i=i+1)
219 temp[i]=dataout_register[i];
220 return temp;
221 endmethod
222 method Vector#(`IONum,Bit#(1)) gpio_out_en;
223 Vector#(`IONum,Bit#(1)) temp;
224 for(Integer i=0;i<`IONum;i=i+1)
225 temp[i]=pack(direction_reg[i]);
226 return temp;
227 endmethod
228 method Vector#(`IONum,Bit#(1)) gpio_DRV0;
229 Vector#(`IONum,Bit#(1)) temp;
230 for(Integer i=0;i<`IONum;i=i+1)
231 temp[i]=pack(drv0_reg[i]);
232 return temp;
233 endmethod
234 method Vector#(`IONum,Bit#(1)) gpio_DRV1;
235 Vector#(`IONum,Bit#(1)) temp;
236 for(Integer i=0;i<`IONum;i=i+1)
237 temp[i]=pack(drv1_reg[i]);
238 return temp;
239 endmethod
240 method Vector#(`IONum,Bit#(1)) gpio_DRV2;
241 Vector#(`IONum,Bit#(1)) temp;
242 for(Integer i=0;i<`IONum;i=i+1)
243 temp[i]=pack(drv2_reg[i]);
244 return temp;
245 endmethod
246 method Vector#(`IONum,Bit#(1)) gpio_PD;
247 Vector#(`IONum,Bit#(1)) temp;
248 for(Integer i=0;i<`IONum;i=i+1)
249 temp[i]=pack(pd_reg[i]);
250 return temp;
251 endmethod
252 method Vector#(`IONum,Bit#(1)) gpio_PPEN;
253 Vector#(`IONum,Bit#(1)) temp;
254 for(Integer i=0;i<`IONum;i=i+1)
255 temp[i]=pack(ppen_reg[i]);
256 return temp;
257 endmethod
258 method Vector#(`IONum,Bit#(1)) gpio_PRG_SLEW;
259 Vector#(`IONum,Bit#(1)) temp;
260 for(Integer i=0;i<`IONum;i=i+1)
261 temp[i]=pack(prg_slew_reg[i]);
262 return temp;
263 endmethod
264 method Vector#(`IONum,Bit#(1)) gpio_PUQ;
265 Vector#(`IONum,Bit#(1)) temp;
266 for(Integer i=0;i<`IONum;i=i+1)
267 temp[i]=pack(puq_reg[i]);
268 return temp;
269 endmethod
270 method Vector#(`IONum,Bit#(1)) gpio_PWRUPZHL;
271 Vector#(`IONum,Bit#(1)) temp;
272 for(Integer i=0;i<`IONum;i=i+1)
273 temp[i]=pack(pwrupzhl_reg[i]);
274 return temp;
275 endmethod
276 method Vector#(`IONum,Bit#(1)) gpio_PWRUP_PULL_EN;
277 Vector#(`IONum,Bit#(1)) temp;
278 for(Integer i=0;i<`IONum;i=i+1)
279 temp[i]=pack(pwrup_pull_en_reg[i]);
280 return temp;
281 endmethod
282 method Vector#(`IONum,Bit#(2)) gpio_MUX;
283 Vector#(`IONum,Bit#(2)) temp;
284 for(Integer i=0;i<`IONum;i=i+1)
285 temp[i]=pack(muxer_reg[i]);
286 return temp;
287 endmethod
288 interface to_plic=toplic;
289 endmodule
290 endpackage
291