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