2 Copyright (c) 2013, IIT Madras
5 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
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.
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 ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
15 /*==== Package imports ==== */
20 /*============================ */
21 /*===== Project Imports ===== */
22 import Semi_FIFOF :: *;
23 import AXI4_Lite_Types :: *;
24 /*============================ */
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;
47 method Vector#(`IONum,Bit#(2)) gpio_MUX;
49 interface AXI4_Lite_Slave_IFC#(`ADDR,`DATA,`USER) axi_slave;
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));
68 Vector#(`IONum,ConfigReg#(Bit#(2))) muxer_reg <-replicateM(mkConfigReg(0));
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;
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];
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];
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];
127 b.bresp=AXI4_LITE_SLVERR;
129 s_xactor.i_wr_resp.enq (b);
133 let ar<- pop_o(s_xactor.o_rd_addr);
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);
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);
146 else if(ar.araddr[5:0]=='h8)begin
147 for(Integer i=0;i<`IONum;i=i+1)
149 r.rdata=duplicate(temp);
151 else if(ar.araddr[5:0]=='hC)begin
152 for(Integer i=0;i<`IONum;i=i+1)
154 r.rdata=duplicate(temp);
156 else if(ar.araddr[5:0]=='h10)begin
157 for(Integer i=0;i<`IONum;i=i+1)
159 r.rdata=duplicate(temp);
161 else if(ar.araddr[5:0]=='h14)begin
162 for(Integer i=0;i<`IONum;i=i+1)
164 r.rdata=duplicate(temp);
166 else if(ar.araddr[5:0]=='h18)begin
167 for(Integer i=0;i<`IONum;i=i+1)
169 r.rdata=duplicate(temp);
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);
176 else if(ar.araddr[5:0]=='h20)begin
177 for(Integer i=0;i<`IONum;i=i+1)
179 r.rdata=duplicate(temp);
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);
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);
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];
196 r.rdata=duplicate(temp);
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];
202 r.rdata=duplicate(temp);
206 r.rresp=AXI4_LITE_SLVERR;
208 s_xactor.i_rd_data.enq(r);
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];
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];
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]);
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]);
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]);
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]);
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]);
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]);
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]);
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]);
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]);
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]);
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]);
288 interface to_plic=toplic;